In [1]:
from IPython.display import Image
In [2]:
Image(filename='./clase-16-04_images/img1.jpg')
Out[2]:
En la realidad, todos sabemos que los premios se eligen no en base a la realidad y los votos, sino en base a quien pone mas plata para comprarlos. Pero bueno, suponiendo que esto es asi, podriamos automatizar el proceso de eleccion de ganadores.
Vamos a encarar este problema diciendo que las nominaciones estan en una matriz, donde las columnas son categorias, las filas son las posiciones de nominacion y cada celda es una tupla de la forma (Nombre del nominado, puntaje segun los votos). Planteado de esta forma, el problema de encontrar los ganadores se transforma en encontrar el maximo de cada columna de dicha matriz.
Para hacer esto un poco mas realista, vamos a decir que las posiciones de nominacion sirven para desempatar en caso que dos o mas nominados tengan el mismo puntaje. Si no fueran nominados y fueran solo numeros, seria indistinto.
Supongamos que el proceso de nominacion ocurre de la forma:
In [3]:
PRIMER_NOMINADO = 0
SEGUNDO_NOMINADO = 1
TERCER_NOMINADO = 2
CUARTO_NOMINADO = 3
ANIME = 0
NOVELA_ARGENTINA = 1
NOVELA_KOREANA = 2
NOMBRE = 0
PUNTAJE = 1
mis_nominados = [
[None]*3,
[None]*3,
[None]*3,
[None]*3,
]
mis_nominados
Out[3]:
In [4]:
def nominar(nominados):
nominados[PRIMER_NOMINADO][ANIME] = ("Persona 5: The Animation",10)
nominados[SEGUNDO_NOMINADO][ANIME] = ("Steins;Gate 0",9.9)
nominados[TERCER_NOMINADO][ANIME] = ("Tokyo Ghoul: re",8)
nominados[CUARTO_NOMINADO][ANIME] = ("Magical Girl Site", 8)
nominados[PRIMER_NOMINADO][NOVELA_ARGENTINA] = ("El Sultan",0)
nominados[SEGUNDO_NOMINADO][NOVELA_ARGENTINA] = ("Simona",5)
nominados[TERCER_NOMINADO][NOVELA_ARGENTINA] = ("Golpe al corazon", 2)
nominados[CUARTO_NOMINADO][NOVELA_ARGENTINA] = ("Ojos que no ven", 4)
nominados[PRIMER_NOMINADO][NOVELA_KOREANA] = ("Another Miss Oh",9)
nominados[SEGUNDO_NOMINADO][NOVELA_KOREANA] = ("Beating Again",9.9)
nominados[TERCER_NOMINADO][NOVELA_KOREANA] = ("Goodbye Mr Black",9.9)
nominados[CUARTO_NOMINADO][NOVELA_KOREANA] = ("Nine Time Travels", 8)
mis_nominados
Out[4]:
In [5]:
nominar(mis_nominados)
mis_nominados
Out[5]:
Para ver como funciona esto paso a paso en la memoria, podemos verlo directamente aqui: https://goo.gl/1UpYhM
Ahora si, teniendo la matriz, podemos programar la funcion:
In [6]:
def obtener_ganadores(nominados):
"""Recibe una matriz como lista de listas donde cada fila es un orden de nominacion y cada columna una categoria.
Devuelve una lista con los ganadores de cada categoria (maximo puntaje de cada columna)"""
maximos= nominados[0][:]
for fila in nominados:
for categoria,nominado in enumerate(fila):
_,puntaje = nominado
_,puntaje_anterior = maximos[categoria]
if puntaje > puntaje_anterior:
maximos[categoria] = nominado
return maximos
obtener_ganadores(mis_nominados)
Out[6]:
In [7]:
Image(filename='./clase-16-04_images/img2.jpg')
Out[7]:
Los patovicas suelen ser una version menos glamorosa de Kevin Costner en El Guardaespaldas (si, puse otra vez el link por si no lo vieron en el titulo), y tienen como tarea encargarse de controlar quien entra y quien no a, por ejemplo, una entrega de premios.
De alguna forma podemos simular esto haciendo una funcion que dadas:
devuelva una lista con las personas que efectivamente entraron. Es obvio que alguien no puede entrar 2 veces, asi que la lista de resultados no deberia tener repetidos.
Ya que estamos, hagamoslo general para dos secuencias cualesquiera, total, no vamos a usar nada que no pueda hacer una secuencia
In [8]:
def interseccion(secuencia_a,secuencia_b):
"""Devuelve una lista con los elementos de la secuencia a que se encuentran en la secuencia b, sin repetir"""
resultado = []
for elemento in secuencia_a:
if elemento not in secuencia_b:
continue
if elemento not in resultado:
resultado.append(elemento)
return resultado
interseccion([1,2,3],[2,2,2,3])
Out[8]:
Bueno, si, whatever, es obvio que la funcion lo que hace a fin de cuentas es la interseccion entre 2 conjuntos (para mas informacion, prestar mas atencion en algebra de conjuntos en el CBC). Si bien el ejercicio es bastante trivial en algun punto, recuerden lo que discutimos sobre el hecho de que sean secuencias a secas:
In [9]:
interseccion(["Hola","Chau"] , "Hola como estas")
Out[9]:
Esto se debe a que al hacer in
de una cadena dentro de otra, Python asume que lo que queremos hacer es buscar subcadenas (Como hicimos en la clase del 09/04). Entender este comportamiento es bastante intuitivo si se lo piensa desde el lado de Python como: Las cadenas solo tienen elementos que sean caracteres, si me esta pasando algo que es trivialmente obvio que no esta (duh), supongo que lo que quiere es buscar substrings (o no sabe lo que quiere y ya no es mi problema). En las listas y tuplas como pueden guardar cualquier cosa no vale un razonamiento similar.
En este caso estaria bueno poner en la documentacion que las dos secuencias deben ser del mismo tipo, y asi nos ahorramos comportamientos extraños.