Una posible solución:¶
for i in range(4):
cadena = input("Ingresá una palabra")
if "r" in cadena:
print(f"{cadena} tiene una letra r")
- ¿Se acuerdan qué representa f"{cadena} tiene una letra r"?
for i in range(4):
cadena = input("Ingresá una palabra")
if "r" in cadena:
print("TIENE R")
else:
print("NO TIENE R")
Hay otra forma de escribir estas expresiones condicionales.
Expresión condicional¶
- La forma general es:
A if C else B
- Devuelve A si se cumple la condición C, sino devuelve B.
x = int(input("Ingresá un número"))
y = int(input("Ingresá un número"))
maximo = x if x > y else y
maximo
Escribimos otra solución al desafío¶
for i in range(4):
cadena = input("Ingresá una palabra")
print("TIENE R" if "r" in cadena else "NO TIENE R")
Evaluación del condicional¶
IMPORTANTE: Python utiliza la evaluación con circuito corto para evaluar las condiciones
x = 1
y = 0
if True or x/y:
print("No hay error!!!!")
Iteración condicional¶
- Python tiene una sentencia while.¿Se acuerdan de este ejemplo?
#Adivina adivinador....
import random
numero_aleatorio = random.randrange(5)
gane = False
print("Tenés 5 intentos para adivinar un entre 0 y 99")
intento = 1
while intento < 6 and not gane:
numero_ingresado = int(input('Ingresa tu número: '))
if numero_ingresado == numero_aleatorio:
print(f'Ganaste! y necesitaste {intento} intentos!!!')
gane = True
else:
print('Mmmm ... No.. ese número no es... Seguí intentando.')
intento += 1
if not gane:
print(f'\n Perdiste :(\n El número era: {numero_aleatorio}')
La sentencia while¶
while condicion:
instrucción
instruccion
# Solución al desafío
Ingresar las notas
Calcular el promedio
Calcular cuántos tienen notas menores al promedio
¿Cómo obtenemos las notas menores al promedio? ¿Tenemos que ingresar las notas dos veces?
Obviamente no. Necesitamos tipos de datos que nos permitan guardar muchos valores.
Listas¶
- Una lista es una colección ordenada de elementos.
notas = [ 4, 6, 7, 3, 8, 1, 10, 4]
notas
- Las listas son estructuras heterogéneas, es decir que pueden contener cualquier tipo de datos, inclusive listas.
varios = [1, "dos", [3, "cuatro"], True]
varios
¿Cuántos elementos tiene la lista?
len(varios)
Accediendo a los elementos de una lista¶
- Se accede a través de un índice que indica la posición del elemento dentro de la lista encerrado entre corchetes [].
- IMPORTANTE: al igual que las cadenas los índices comienzan en 0.
varios = [ 17, "hola", [1, "dos"], 5.5, True]
print(varios[0])
print(varios[2][1] )
print(varios[-3])
- Las listas son datos MUTABLES. ¿Qué quiere decir esto?
varios[0] = ["hola", 2]
varios
Recorriendo una lista¶
- ¿Qué estructura les parece que podríamos usar?
for elem in varios:
print(elem)
Otra forma de recorrer:¶
# otra forma
canti_elementos = len(varios)
for indice in range(canti_elementos):
print(varios[indice])
Retomemos el desafío¶
Ingresar las notas
Calcular el promedio
Calcular cuántos tienen notas menores al promedio
Empecemos con el primer proceso: vamos a suponer que ingresamos datos hasta que ingrese una nota -1
- ¿Qué otra cosa nos falta?
lista = [1, 2]
lista.append("algo")
lista.append("otro")
lista
Ahora si resolvamos este proceso¶
#Ingresar las notas
nota = int(input("Ingresá una nota (-1 para finalizar)"))
lista_de_notas = []
while nota != -1:
lista_de_notas.append(nota)
nota = int(input("Ingresá una nota (-1 para finalizar)"))
lista_de_notas
Tarea para el hogar: terminar el desafío¶
Slicing con listas¶
- Al igual que en el caso de las cadenas de caracteres, se puede obtener una porción de una lista usando el operador ":"
vocales = [ "a", "e","i", "o", "u"]
print(vocales[1:3] )
- Si no se pone inicio o fin, se toma por defecto las posiciones de inicio y fin de la lista.
print( vocales[ :2] )
print( vocales[2:] )
- Tarea para el hogar: probar con índices negativos.
# Probamos
Asignación de listas¶
- Observemos el siguiente ejemplo:
rock = ["Riff", "La Renga", "La Torre"]
blues = ["La Mississippi", "Memphis"]
musica = rock
print(musica)
- Recordemos que las variables son referencias a objetos.
- Cada objeto tiene un identificación.
print(id(musica))
print(id(rock))
print(id(blues))
Observemos este código¶
otra_musica = rock[:]
print(id(rock))
print(id(otra_musica))
print(id(musica))
- musica = rock: musica y rock apunten al mismo objeto (misma zona de memoria).
- otra_musica = rock[:]: otra_musica y rock referencian a dos objetos distintos (dos zonas de memoria distintas con el mismo contenido).
# probamos en casa
#mas_musica = rock.copy()
- ¿Qué podemos decir del método copy?
Operaciones con listas¶
- Las listas se pueden concatenar (+) y repetir (*)
rock = ["Riff", "La Renga", "La Torre"]
blues =["La Mississippi", "Memphis"]
musica = rock + blues
mas_rock = rock * 3
musica
Algunas cosas para prestar atención¶
Analicemos el siguiente código:
lista = [[1,2]] * 3
print(lista)
lista [0][1] = 'cambio'
print(lista)
- ¿Qué es lo que sucedió?
- El operador * repite la misma lista, no genera una copia distinta; es el mismo objeto referenciado 3 veces.
- Probar en casa:
# Reemplazar la definición de la lista original con lista = [[1,2], [1, 2], [1, 2]]
Ahora analicemos este otro ejemplo:¶
lista = [[1,2], 8, 9]
lista2 = lista.copy()
print(id(lista), id(lista2))
¿Qué sucedió?
¿Se acuerdan de esta operación con cadenas?¶
palabras = "En esta clase aparecen grandes músicos".split(" ")
palabras
Veamos de qué tipo es palabras ...
import string
digitos = string.digits
codigos = [ord(n) for n in digitos]
codigos
¿Y en este otro caso?
cuadrados = [num**2 for num in range(10) if num % 2 == 0]
cuadrados
Tuplas: otro tipo de secuencias en Python¶
- Al igual que las listas, son colecciones de datos ordenados.
tupla = 1, 2
tupla1 = (1, 2)
tupla2 = (1, ) # OJO con esto
tupla3 = ()
type(tupla2)
¿Cuál es la diferencia con las listas?¶
Veamos las siguientes situaciones.
Tuplas vs. listas¶
tupla = (1, 2)
lista = [1, 2]
elem = tupla[0]
elem
print(len(tupla))
- Se acceden a los elementos de igual manera: usando [] (empezando desde cero)
- La función len retorna la cantidad de elementos en ambos casos.
DIFERENCIA: las tuplas son INMUTABLES¶
- Su tamaño y los valores de las mismas NO pueden cambiar.
tupla = (1, 2)
lista = [1, 2]
#tupla[0] = "uno" # Esto da error
tupla
#tupla.append("algo") # Esto da error
TypeError: 'tuple' object does not support item assignment
Tenemos que acostumbrarnos a leer los errores.¶
Obteniendo subtuplas¶
tupla = (1, 2, 3, "hola")
print(tupla[1:4])
nueva_tupla = ("nueva",) + tupla[1:3]
print(nueva_tupla)
# ¿por qué da error este código?
nueva_tupla = ('nueva, ') + tupla[1:3]
- Deberíamos ingresar no sólo las notas, sino también los nombres de los estudiantes.
- ¿Qué soluciones proponen?
¿Qué les parece esta solución?¶
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
lista = []
while nombre != "FIN":
nota = int(input(f"Ingresa la nota de {nombre}"))
lista.append((nombre, nota))
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
lista
- ¿Qué estructura de datos estoy usando?
- Hay algo mejor...
Diccionarios en Python¶
- Un diccionario es un conjunto no ordenado de pares de datos: clave:valor.
- Se definen con { }.
notas = {"Janis Joplin":10, "Elvis Presley": 9, "Bob Marley": 5, "Jimi Hendrix": 9}
notas["Bob Marley"]
Las claves deben ser únicas e inmutables¶
- Las claves pueden ser cualquier tipo inmutable.
- Las cadenas y números siempre pueden ser claves.
- Las tuplas se pueden usar sólo si no tienen objetos mutables.
# Probar cuáles de las siguientes instrucciones dan error
#dicci = {"uno":1}
#dicci = {1: "uno"}
#dicci = {[1,2]: "lista"}
#dicci = {(1,2): "tupla"}
##dicci
¿Cómo accedemos a los elementos?¶
- Al igual que las listas y tuplas, se accede usando [ ] pero en vez de un índice, usamos la clave.
- Es un error extraer un valor usando una clave no existente.
meses = {"enero": 31, "febrero": 28, "marzo": 31}
meses
¿Cómo agregamos elementos?¶
- Si se usa una clave que ya está en uso para guardar un valor, el valor que estaba asociado con esa clave se pierde, si no está la clave, se agrega.
meses["febrero"] = 29
meses["abril"] = 30
meses
Volviendo al desafío planteado ...¶
- Nos falta saber cómo definir un diccionario vacío para luego ir agregando los valores.
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
dicci = {}
while nombre != "FIN":
nota = int(input(f"Ingresa la nota de {nombre}"))
dicci[nombre] = nota
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
dicci
¿Qué estructura de datos usamos?
¿Cómo recorremos un diccionario?¶
musica = {"rock": ["Riff", "La Renga", "La Torre"],
"blues": ["La Mississippi", "Memphis", "violeta"]}
#las claves
for elem in musica:
print(elem)
print("*" * 10)
# los valores
for elem in musica:
print(musica[elem])
Existen algunos métodos útiles:¶
claves = musica.keys()
valores = musica.values()
items = musica.items()
claves
for elem in valores:
print(elem)
El operador in en diccionarios¶
musica = {"rock": ["Riff", "La Renga", "La Torre"],
"blues": ["La Mississippi", "Memphis", "violeta"]}
"rock" in musica
- ¿Verifica en las claves o los valores?
Observemos este código¶
meses = {"enero": 31, "febrero": 28, "marzo": 31}
meses1 = meses
meses2 = meses.copy()
print(id(meses))
print(id(meses1))
print(id(meses2))
¿Qué significa?
meses1["abril"] = 30
meses2["abril"] = 43
meses
# Probamos del y clear
Otra forma de crear diccionarios¶
- Podemos usar dict().
- Se denomia "constructor" y crea un diccionario directamente desde una secuencia de pares clave-valor.
dicci = dict([("enero", 31), ("febrero", 28), ("marzo", 31)])
dicci
- ¿Qué tipos de datos se pueden usar para la secuencia?
- ¿Y para los pares clave-valor?
Por comprensión¶
dict ([(x, x**2) for x in (2, 4, 6)])
import string
caracteres = dict([(n, ord(n)) for n in string.digits])
caracteres
Funciones en Python: una forma de definir procesos o subprogramas¶
Retomemos el pseudocódigo de la solución del tercer desafío:
Ingresar las notas
Calcular el promedio
Calcular cuántos tienen notas menores al promedio
Podríamos pensar en dividir en tres procesos:
- En Python, usamos funciones para definir estos procesos.
- Las funciones pueden recibir parámetros.
- Y también retornan siempre un valor. Esto puede hacerse en forma implícita o explícita usando la sentencia return.
Ya usamos funciones¶
- float(), int(), str().
- len(), ord()
- range(), randrange()
En estos ejemplos, sólo invocamos a las funciones ya definidas.
Podemos definir nuestras propias funciones¶
def nombre_funcion(parametros):
sentencias
return <expresion>
- IMPORTANTE: el cuerpo de la función debe estar indentado.
La función para el primer proceso del desafío¶
def ingreso_notas():
""" Esta función retorna un diccionario con los nombres y notas de estudiantes """
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
dicci = {}
while nombre != "FIN":
nota = int(input(f"Ingresa la nota de {nombre}"))
dicci[nombre] = nota
nombre = input("Ingresa un nombre (<FIN> para finalizar)")
return dicci
notas_de_estudiantes = ingreso_notas()
notas_de_estudiantes
- Definición vs. invocación.
- ¿Qué pasa si no incluyo el return?
- Pueden definir las otras dos funciones para completar el desafio.
Tarea para el hogar¶
Observar el juego del ahorcado que se presenta en el libro Invent Your Own Computer Games with Python.
Analizar:
- Tipos de datos trabajados.
- Funciones definidas.
- ¿Cómo define los niveles?
- ¿Se respeta la PEP 8?
¿Se animan a modificarlo?
- Agregar pistas sobre el tipo de la palabra a adivinar.
Subir el código modificado y las respuestas al análisis realizado a su repositorio en GitHub.¶
- Compartir el enlace a la cuenta @clauBanchoff