In [1]:
from IPython.display import Image

La Magia de la television

Capitulo 1: La television argentina es un template gigante

Parte 0: Repaso general de secuencias

Cadenas Tuplas Listas
Acceso por indice Si Si Si
Recorrer por indices Si Si Si
Recorrer por elemento Si Si Si
Elementos Caracteres Cualquier cosa Cualquier cosa
Mutabilidad Inmutables Inmutables Mutables
Operador + (concatenacion) Copia Copia Copia
Slices Copia Copia Copia
Append No existe No existe Agrega (Modifica)
Buscar un elemento Si Si Si

Parte 1: Simona y el narcisismo en tv


In [2]:
Image(filename='./clase-09-04_images/i1.jpg')


Out[2]:

En psicologia probablemente se harian un festin analizando estas canciones, la protagonista se nombra a si misma tantas veces que no deja lugar a dudas de quien es el programa. Aplicando lo que sabemos de cadenas y secuencias en general, vamos a escribir un poco de codigo para poder ponerle numeros a esta afirmacion, contando cuantas veces dicen "Simona" los temas de Simona.

Si Si Simona


In [3]:
si_si_simona = """Si te vas yo voy con vos a algún lugar
Si jugás yo tengo ganas de jugar
Si te quedas yo me quedo
Y si te alejas yo me muero
Soy quien soy

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si Simona si
Simona es así
Simona

Si, si, si Simona si
Simona es así
Simona

(Si, si, si) Simona
(Si, si, si) Simona

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si
Simona si
Simona es así
Simona
Si, si, si Simona si
Simona es así
Simona

Simona
Simona, si

Si sonríes yo sonrío
Si me mirras yo suspiro
Soy quien soy

Si, si, si Simona si
Simona es así
Simona

Si, si, si Simona si
Simona es así
Simona

Si, si, si Simona si
Simona es así
Simona

Si, si, si Simona si
Simona es así
Simona

(Simona, Simona)
Simona
(Simona, Simona)
Simona"""

Simona Va


In [4]:
simona_va = """Es un lindo día para pedir un deseo
No me importa si se cumple o no
Es un lindo día para jugarnos enteros
Vamos a cantar una canción

Amanece más temprano cuando quiero
Porque dentro mío brilla el sol
Al final siempre consigo lo que quiero
Por que lo hago con amor

Solo hay que cruzar bien los dedos
Y desear que pase con todo el corazón
Vamos a cubrirte los miedos
Vamos que ya llega lo mejor

Simona va, Simona va
Andando se hace el camino
Yo manejo mi destino

Simona va, Simona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va

Es un lindo dia para hacer algo bien bueno
Disfrutando de la sensacion
De animarse aunque no te salga perfecto
Cada vez ira mejor

[?] cuando siento
Que mañana voy a verte a vos
Porque yo siempre consigo lo que quiero
Nadie me dice que no

Solo hay que cruzar bien los dedos
Y desear que pase con todo el corazón
Vamos sacudite los miedos
Vamos que ya llega lo mejor

Simona va, Simona va
Andando se hace el camino
Yo manejo mi destino

Simona va, Simona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va

Ya va, yo tengo mi tiempo
Are you ready for funky?
Verás yo voy con lo puesto
Como no?
No da que no seas sincero
Yo no, no le tengo miedo a na na na na na

Simona va, Simona va
Andando se hace el camino
Yo manejo mi destino

Simona va, Simona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va

Simona va, Simona va
Andando se hace el camino
Yo manejo mi destino

Simona va, Simona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va"""

Soy Como Soy


In [5]:
soy_como_soy = """Soy especial
A veces no me entienden, es normal
Yo digo siempre lo que pienso
Aunque te caiga mal

Ya vez mi personalidad
Tengo la música en la sangre prefiero bailar
No es necesario interpretar, adivinar
Soy lo que siento

Soy Simona
Cantar mi corazón ilusiona
Mi sueño voy de a poco alcanzando
Y no puedo dejar de pensar en tu amor

Cada vez que un recuerdo se asoma
Intento al menos no ser tan obvia
Y que no te des cuenta que muero por vos
Soy como soy pero mi amor
Es mas lindo cuando somos dos

Vuelvo a empezar
No se porque doy tantas vueltas
Si en verdad
Tu amor es todo lo que quiero
Me cuesta tanto disimular

Ya vez mi personalidad
Tengo la música en la sangre prefiero bailar
No es necesario interpretar, adivinar
Soy lo que siento

Soy Simona
Cantar mi corazón ilusiona
Mi sueño voy de a poco alcanzando
Y no puedo dejar de pensar en tu amor

Cada vez que un recuerdo se asoma
Intento al menos no ser tan obvia
Y que no te des cuenta que muero por vos
Soy como soy, pero mi amor
Es mas lindo cuando somos dos

(Cuando somos dos)
(Es mas lindo cuando somos dos)

Soy Simona
Cantar mi corazón ilusiona
Mi sueño voy de a poco alcanzando
Y no puedo dejar de pensar en tu amor

Cada vez que un recuerdo se asoma (se asoma)
Intento al menos no ser tan obvia
Y que no te des cuenta que muero por vos
Soy como soy, pero mi amor
Es mas lindo cuando somos dos"""

Metodos del tipo cadena

Por ahora los metodos son las funciones que puedo llamar para un tipo de datos dado, utilizando . . La forma de verlos todos es utilizando la funcion dir


In [6]:
dir("")


Out[6]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmod__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'capitalize',
 'casefold',
 'center',
 'count',
 'encode',
 'endswith',
 'expandtabs',
 'find',
 'format',
 'format_map',
 'index',
 'isalnum',
 'isalpha',
 'isdecimal',
 'isdigit',
 'isidentifier',
 'islower',
 'isnumeric',
 'isprintable',
 'isspace',
 'istitle',
 'isupper',
 'join',
 'ljust',
 'lower',
 'lstrip',
 'maketrans',
 'partition',
 'replace',
 'rfind',
 'rindex',
 'rjust',
 'rpartition',
 'rsplit',
 'rstrip',
 'split',
 'splitlines',
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

OJO: Notar que hay cosas que arrancan con __, eso nos quiere decir que no debemos tocarlo por ningun motivo (Mas sobre esto algunas clases mas adelante)

Ahora para saber ya la documentacion especifica del metodo que queremos usar, podemos usar help de la forma:


In [7]:
help("".find)


Help on built-in function find:

find(...) method of builtins.str instance
    S.find(sub[, start[, end]]) -> int
    
    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end].  Optional
    arguments start and end are interpreted as in slice notation.
    
    Return -1 on failure.

Si bien quiero solo contar las apariciones, podria hacer una funcion que me devuelva las apariciones y contar cuantos elementos me devolvio. De esa forma, tengo una funcion que sirve para mas de un contexto. Dado que todo lo que vamos a usar son operaciones de secuencias en gral, podemos nombrar la funcion de forma general[1]


In [8]:
def buscar_todas(secuencia,sub_secuencia):
    """
    Recibe una secuencia, devuelve una lista con los indices de todas las apariciones de la sub_secuencia dentro de la secuencia original. 
    """
    ocurrencias =  []
    anterior = secuencia.find(sub_secuencia)
    while anterior != -1:
        ocurrencias.append(anterior)
        anterior = secuencia.find(sub_secuencia , anterior+1)
    return ocurrencias

# Podemos probar que la funcion se comporta como esperamos 
# Si algo de esto imprime False, claramente no anda
print ("Buscar devuelve vacio si no encuentra :",buscar_todas("Hola","pp") == [] )
print ("Buscar devuelve a :",buscar_todas("Hola","Hola") == [0] )

print("\n"*2)

# Ahora a contar
print("Apariciones de Simona en 'Si Si Simona': ",len(buscar_todas(si_si_simona,"Simona")))
print("Apariciones de Simona en 'Simona va': ",len(buscar_todas(simona_va,"Simona")))
print("Apariciones de Simona en 'Soy como soy': ",len(buscar_todas(soy_como_soy,"Simona")))


Buscar devuelve vacio si no encuentra : True
Buscar devuelve a : True



Apariciones de Simona en 'Si Si Simona':  34
Apariciones de Simona en 'Simona va':  16
Apariciones de Simona en 'Soy como soy':  3

Discusiones importantes para recordar:

  • Por que find devuelve -1 y no otra cosa?
  • Devolver una lista o una tupla?
  • Usar internamente una lista o una tupla? Y si tengo que devolver una tupla?

Tarea para el lector:

  • Probar la validez o no de la afirmacion [1] (Ayuda: probar usando listas)

Cosas no tan importantes a modo de conclusion:

  • Notar que hasta en las canciones que no tienen su nombre en el titulo se nombra
  • Queda entonces demostrado lo que sea que se supone que haya querido demostrar con esto

Parte 2: Que hacemos si nos cierran este antro?

¿Que pasa ahora si tienen que terminar la novela por problemas con los actores y hacer una nueva? Claramente alguien que escribe 34 veces el nombre de la protagonista en la letra de una cancion no tiene mucha imaginacion, asi que probablemente cambien los nombres de las personas y sigan con lo mismo. Hagamos algo que pueda reemplazar el nombre de Simona por el de una nueva protagonista en las canciones.

Version usando Split + Join


In [9]:
palabras = si_si_simona.split(" ")

for i in range(len (palabras)):
    if palabras[i] == "Simona":
        palabras[i] = "Ramona"

print(" ".join(palabras))


Si te vas yo voy con vos a algún lugar
Si jugás yo tengo ganas de jugar
Si te quedas yo me quedo
Y si te alejas yo me muero
Soy quien soy

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si Ramona si
Simona es así
Simona

Si, si, si Ramona si
Simona es así
Simona

(Si, si, si) Simona
(Si, si, si) Simona

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si
Simona si
Simona es así
Simona
Si, si, si Ramona si
Simona es así
Simona

Simona
Simona, si

Si sonríes yo sonrío
Si me mirras yo suspiro
Soy quien soy

Si, si, si Ramona si
Simona es así
Simona

Si, si, si Ramona si
Simona es así
Simona

Si, si, si Ramona si
Simona es así
Simona

Si, si, si Ramona si
Simona es así
Simona

(Simona, Simona)
Simona
(Simona, Simona)
Simona

Version abusando de Split y Join


In [10]:
partes_cancion = simona_va.split("Simona")
cancion_nueva = "Ramona".join(partes_cancion)

print(cancion_nueva)


Es un lindo día para pedir un deseo
No me importa si se cumple o no
Es un lindo día para jugarnos enteros
Vamos a cantar una canción

Amanece más temprano cuando quiero
Porque dentro mío brilla el sol
Al final siempre consigo lo que quiero
Por que lo hago con amor

Solo hay que cruzar bien los dedos
Y desear que pase con todo el corazón
Vamos a cubrirte los miedos
Vamos que ya llega lo mejor

Ramona va, Ramona va
Andando se hace el camino
Yo manejo mi destino

Ramona va, Ramona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va

Es un lindo dia para hacer algo bien bueno
Disfrutando de la sensacion
De animarse aunque no te salga perfecto
Cada vez ira mejor

[?] cuando siento
Que mañana voy a verte a vos
Porque yo siempre consigo lo que quiero
Nadie me dice que no

Solo hay que cruzar bien los dedos
Y desear que pase con todo el corazón
Vamos sacudite los miedos
Vamos que ya llega lo mejor

Ramona va, Ramona va
Andando se hace el camino
Yo manejo mi destino

Ramona va, Ramona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va

Ya va, yo tengo mi tiempo
Are you ready for funky?
Verás yo voy con lo puesto
Como no?
No da que no seas sincero
Yo no, no le tengo miedo a na na na na na

Ramona va, Ramona va
Andando se hace el camino
Yo manejo mi destino

Ramona va, Ramona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va

Ramona va, Ramona va
Andando se hace el camino
Yo manejo mi destino

Ramona va, Ramona va
Si piso dejo mi huella
Voy a alcanzar las estrellas
Ella va, va, va, viene y va
Ahora en una sola linea

In [11]:
print("Ramona".join(si_si_simona.split("Simona")))


Si te vas yo voy con vos a algún lugar
Si jugás yo tengo ganas de jugar
Si te quedas yo me quedo
Y si te alejas yo me muero
Soy quien soy

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

(Si, si, si) Ramona
(Si, si, si) Ramona

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si
Ramona si
Ramona es así
Ramona
Si, si, si Ramona si
Ramona es así
Ramona

Ramona
Ramona, si

Si sonríes yo sonrío
Si me mirras yo suspiro
Soy quien soy

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

(Ramona, Ramona)
Ramona
(Ramona, Ramona)
Ramona
Version haciendo templates con format strings

Supongamos que es bastante comun esto de solo cambiar el nombre, andar cortando y haciendo copias de listas, cadenas o lo que sea, no es como una idea muy copada. Usando cadenas con formato, se puede hacer mas amigable.

  • Paso 1: Reemplazar todas las apariciones de Simona por '{0}' para generar el template (usamos replace porque ya viene en Python y no tengo ganas de hacerlo a mano)

In [12]:
template = si_si_simona.replace("Simona","{0}")
print(template)


Si te vas yo voy con vos a algún lugar
Si jugás yo tengo ganas de jugar
Si te quedas yo me quedo
Y si te alejas yo me muero
Soy quien soy

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si {0} si
{0} es así
{0}

Si, si, si {0} si
{0} es así
{0}

(Si, si, si) {0}
(Si, si, si) {0}

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si
{0} si
{0} es así
{0}
Si, si, si {0} si
{0} es así
{0}

{0}
{0}, si

Si sonríes yo sonrío
Si me mirras yo suspiro
Soy quien soy

Si, si, si {0} si
{0} es así
{0}

Si, si, si {0} si
{0} es así
{0}

Si, si, si {0} si
{0} es así
{0}

Si, si, si {0} si
{0} es así
{0}

({0}, {0})
{0}
({0}, {0})
{0}
  • Usando el template que generamos, ahora podemos usar format para obtener nuestras multiples versiones de la cancion

In [13]:
print(template.format("Ramona"))


Si te vas yo voy con vos a algún lugar
Si jugás yo tengo ganas de jugar
Si te quedas yo me quedo
Y si te alejas yo me muero
Soy quien soy

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

(Si, si, si) Ramona
(Si, si, si) Ramona

Si soy algo distraída que mas da
Puede ser que sin querer me fui a soñar
Si sonríes yo sonrío
Si me miras yo suspiro
Soy quien soy

Si, si, si
Ramona si
Ramona es así
Ramona
Si, si, si Ramona si
Ramona es así
Ramona

Ramona
Ramona, si

Si sonríes yo sonrío
Si me mirras yo suspiro
Soy quien soy

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

Si, si, si Ramona si
Ramona es así
Ramona

(Ramona, Ramona)
Ramona
(Ramona, Ramona)
Ramona

Format Strings (Cadenas con formato)

Las cadenas con formato son de la forma blablabla {} blablabla donde {} luego se va a reemplazar por el/los valores que le pasamos como parametro al metodo format. En el ejemplo anterior, utilizamos {0}, porque si no especificamos nada, asume que cada {} corresponde a un parametro distinto. En este caso, el 0 representa al primer parametro.


In [14]:
"Cuando vengo digo {} y cuando me voy digo {}".format("hola","chau")


Out[14]:
'Cuando vengo digo hola y cuando me voy digo chau'

In [15]:
"Cuando vengo digo {1} y cuando me voy digo {0}".format("hola","chau")


Out[15]:
'Cuando vengo digo chau y cuando me voy digo hola'

In [16]:
"Cuando vengo digo {1} y cuando me voy digo {1}".format("hola","chau")


Out[16]:
'Cuando vengo digo chau y cuando me voy digo chau'

Ahora con esto, podemos hasta hacer una funcion hermosa que nos genere premisas de novelas completamente genericas novedosas.


In [17]:
def obtener_nueva_premisa( nombre_protagonista_femenino,
                                                    barrio_del_conurbano,
                                                    nombre_protagonista_masculino,
                                                    razon_de_no_ser_rica,
                                                    razon_de_ser_rico,
                                                    razon_para_ahora_ser_rica):
    """Devuelve una cadena con la premisa para una nueva y exitosa novela argentina, dados los datos pasados como parametro."""
    
    return """Ella es {}, una mucama que vive en {}, y esta enamorada de su jefe {}. 
Su amor no puede ser porque ella es {} y el es {}. 
Pero todo cambia cuando ella descubre que es {} y su amor florece (porque aparentemente no existe el amor en la clase media).""".format(
    nombre_protagonista_femenino,
    barrio_del_conurbano,
    nombre_protagonista_masculino,
    razon_de_no_ser_rica,
    razon_de_ser_rico,
    razon_para_ahora_ser_rica
    )
    
print(obtener_nueva_premisa("Ramona","Quilmes","Esteban","la hija del carnicero","el hijo de Barack Obama","una Rockefeller"))


Ella es Ramona, una mucama que vive en Quilmes, y esta enamorada de su jefe Esteban. 
Su amor no puede ser porque ella es la hija del carnicero y el es el hijo de Barack Obama. 
Pero todo cambia cuando ella descubre que es una Rockefeller y su amor florece (porque aparentemente no existe el amor en la clase media).

Desde Python 3.6 en adelante, hay una forma mucho mas linda de hacer esto, ya que mejora bastante la legibilidad (notar que en el caso anterior no tengo idea de a que parametro representa cada {} a menos que vaya contando, y para mas de un parametro, poner todo con numeros es bastante molesto)


In [18]:
def obtener_nueva_premisa( nombre_protagonista_femenino,
                                                    barrio_del_conurbano,
                                                    nombre_protagonista_masculino,
                                                    razon_de_no_ser_rica,
                                                    razon_de_ser_rico,
                                                    razon_para_ahora_ser_rica):
    """Devuelve una cadena con la premisa para una nueva y exitosa novela argentina, dados los datos pasados como parametro."""
    
    return f"""Ella es {nombre_protagonista_femenino}, una mucama que vive en {barrio_del_conurbano}.
Ella esta enamorada de su jefe {nombre_protagonista_masculino}, pero su amor no puede ser porque ella es {razon_de_no_ser_rica} y el es {razon_de_ser_rico}. 
Pero todo cambia cuando ella descubre que es {razon_para_ahora_ser_rica} y su amor florece (porque aparentemente no existe el amor en la clase media)."""
    
print(obtener_nueva_premisa("Leona","Tigre","Alberto","una persona de bajos ingresos","mucho muy rico","la ganadora del gordo de navidad"))


Ella es Leona, una mucama que vive en Tigre.
Ella esta enamorada de su jefe Alberto, pero su amor no puede ser porque ella es una persona de bajos ingresos y el es mucho muy rico. 
Pero todo cambia cuando ella descubre que es la ganadora del gordo de navidad y su amor florece (porque aparentemente no existe el amor en la clase media).

Para poder lograr este efecto, las cadenas deben tener una letra f justo antes de las comillas al inicio y entre llaves expresiones. Y digo expresiones, porque esto vale:


In [19]:
cantidad_a = 10
cantidad_b = 7
f"Si tengo {cantidad_a} manzanas, y me como {cantidad_b}, cuantas me queda? Rta:({cantidad_a - cantidad_b})"


Out[19]:
'Si tengo 10 manzanas, y me como 7, cuantas me queda? Rta:(3)'

Parte 3: Despues de las 12, azufre y queso tienen las mismas letras aparentemente


In [20]:
Image(filename='./clase-09-04_images/i2.jpg')


Out[20]:

Mas de uno se quedo estudiando hasta tarde y se topó con estos programas donde hay que adivinar que palabra se forma con esas letras. Si bien las reglas dicen que solo se pueden formar palabras conectando letras de celdas contiguas, el 90% de la gente que llama cree que la respuesta es "queso", "mozzarela" o "Estambul" por alguna razon.

Es bastante evidente que la respuesta es azufre se encuentra en alguna rotacion de "freazu" en sentido horario o anti-horario. Escribamos codigo que nos imprima todas las posibles rotaciones de una cadena a ver si encontramos la respuesta


In [21]:
def imprimir_soluciones_posibles(incognita):
    largo = len(incognita) #Lo vamos a usar varias veces, lo "calculamos" una sola
    
    #Recorrido en sentido horario
    for i in range(largo):
        for j in range(i,i+largo):
            print(incognita[j % largo],end="")
        print()
    
    #Recorrido en sentido anti-horario
    for i in range(largo):
        for j in range( i , i-largo , -1 ):
            print(incognita[j % largo],end="")
        print()
        
imprimir_soluciones_posibles("freazu")


freazu
reazuf
eazufr
azufre
zufrea
ufreaz
fuzaer
rfuzae
erfuza
aerfuz
zaerfu
uzaerf

Nota al final de la clase

Los ejercicios realizados en esta clase, reemplazan la realizacion de los ejercicios 4.6 (haciendolo con listas y %), 6.6 y 7.2 ya que cubren los mismos puntos importantes.