Misión 1. Enciende la máquina
▶ Abrir en Colab ▶ Ejecutar en Binder
Colab abre en segundos. Binder, la primera vez, construye el entorno en la nube (10-20 min) y luego queda en caché.
Misión 1. Encargo: «haz que el ordenador te obedezca».
Victoria: tu primer programa corriendo en el navegador.
Insignia en juego: primer contacto.
El encargo
¿Y si el ordenador que tienes delante —o el móvil— pudiera contestarte a una pregunta de verdad? No «¿qué canción suena ahora?», que eso ya lo hace cualquiera, sino una tuya: ¿qué tiene una canción para pegar fuerte?. Spotify mide cada canción con números —su popularidad, su energía, su ritmo— y guarda millones, con esos datos abiertos para quien quiera mirarlos. El problema es que son miles y miles de cifras: nadie las escucha a oído una a una. Para sacarles una respuesta hace falta mandar sobre ellas. Hay que decirle a la máquina, paso a paso y sin que quede ninguna duda, qué mirar, qué contar y qué decir. Eso es programar: no un conjuro misterioso, sino el arte de dar órdenes tan claras que una máquina tonta —y el ordenador es asombrosamente tonto, solo que rapidísimo— las cumpla sin equivocarse ni una vez.
Aquí empieza una campaña larga que te va a convertir en analista de música. Al final serás capaz de descargar un catálogo real, limpiarlo, dibujarlo y hasta adivinar el género de una canción por su sonido. Pero no se empieza la casa por el tejado. Tu primera misión es más humilde y más importante que todas: conseguir que el ordenador te obedezca. Que le digas «cuenta cuántas de estas canciones son populares» y te devuelva un número. Que le des cinco datos en bruto y te conteste con un hecho. Cuando lo logres —al final de estas páginas— tendrás tu primer programa corriendo, y con él la insignia primer contacto. No es una medalla por asistir: es la prueba de que la máquina ha cumplido tu orden.
El mapa de la misión.
No vamos a saltar directamente a la victoria; vamos a construirla pieza a pieza, y cada pieza tiene su propia micro-victoria —un número, una lista, un conteo que puedes enseñar—. Este es el recorrido:
Abrir el taller: un cuaderno en el navegador y tu primera orden.
Guardar cosas en variables y distinguir sus tipos.
Hacer cuentas y comparaciones con operadores.
Agrupar datos en listas y diccionarios.
Que la máquina decida (
if) y repita (for).Empaquetar recetas en funciones reutilizables.
Juntarlo todo en un pequeño analizador de música y superar al jefe de parte.
Cada paso desbloquea el siguiente. No hay prisa: lee, escribe el código tú mismo (no lo copies con los ojos, tecléalo con los dedos) y, sobre todo, cumple la única regla de oro de esta misión —predice antes de ejecutar—. Vamos allá.
La herramienta
Un cuaderno que obedece
No vas a instalar nada. Todo tu taller cabe en una pestaña del navegador: se llama Google Colab, y es un cuaderno. Un cuaderno se parece a una libreta de laboratorio, pero viva: se divide en celdas, y una celda de código no solo se escribe —se ejecuta—. Escribes una orden, pulsas el botón de ejecutar (o Mayús+Intro), y justo debajo aparece lo que la máquina ha hecho. Este formato de cuaderno, nacido del proyecto Jupyter, se ha vuelto el sitio donde de verdad se hace ciencia con datos [@kluyver2016jupyter]; Colab es una versión que corre en la nube y arranca sin que tú montes nada.
Prueba la orden más corta que existe: pedirle que diga algo. Escribe esto en una celda y ejecútala.
genero = "pop"
print("Hola, soy tu ordenador y voy a analizar el genero", genero)Debajo, la máquina responde:
Hola, soy tu ordenador y voy a analizar el genero pop
Acabas de dar tu primera orden y de verla cumplida —esa es tu primera micro-victoria—. La palabra print es la orden «di esto en voz alta»: escribe en pantalla lo que le pongas entre paréntesis. Fíjate en un detalle que parece tonto y no lo es: has escrito genero en la primera línea y lo has vuelto a usar en la segunda, y la máquina ha recordado que valía "pop". Guardó ese texto en la primera línea y lo recuperó en la segunda. Ese recuerdo es la clave de todo, y depende de una cosa: el orden.
Un fallo de verdad: las celdas en desorden.
Un cuaderno tiene una trampa preciosa para aprender de ella. Puedes ejecutar las celdas en el orden que quieras, y la máquina te obedece igual, aunque no tenga sentido. Imagina que, con prisa, ejecutas primero la celda que usa un dato y solo después la que lo guarda:
print("La popularidad media es", media)
media = 41.7La máquina intenta cumplir la primera línea, busca en su memoria una caja llamada media… y todavía no existe, porque la creas en la línea de abajo. Así que se planta y te avisa en rojo:
NameError: name 'media' is not defined
Léelo sin miedo: NameError significa «error de nombre», y el mensaje dice «el nombre media no está definido». No es un castigo: es la máquina siendo honesta —prefiere quejarse a inventarse un número—. La causa no es el código, que es correcto; es el orden en que lo ejecutaste. De aquí sale la regla de oro del cuaderno: ejecuta de arriba abajo, siempre.
Cajas con nombre: las variables
Una variable es una caja con una etiqueta. Le pones un nombre, guardas algo dentro y, a partir de ahí, con solo decir el nombre recuperas lo que guardaste. El signo = no significa «es igual a» como en matemáticas: significa «guarda esto aquí». Se lee de derecha a izquierda: «coge lo de la derecha y mételo en la caja de la izquierda».
genero = "pop"
popularidad = 62
energia = 0.82
es_exito = popularidad > 40
print(genero, popularidad, energia, es_exito)pop 62 0.82 True
Cuatro cajas, y —aquí está lo interesante— cuatro clases distintas de contenido. La caja es_exito ni siquiera la has rellenado tú a mano: la ha rellenado la máquina al calcular popularidad > 40. Como 62 es mayor que 40, la respuesta es «verdadero». Ya estás haciendo que decida por ti.
Un consejo que vale para toda tu vida programando: pon nombres que digan lo que guardan. popularidad se entiende; x no. Tu yo del mes que viene, releyendo este cuaderno, te lo agradecerá.
Cuatro tipos que lo son casi todo
La máquina distingue tipos de dato y trata cada uno según lo que es. Al principio te bastan cuatro. Si alguna vez dudas de qué hay en una caja, pregúntaselo con type:
print(type(genero))
print(type(popularidad))
print(type(energia))
print(type(es_exito))<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
Ahí están tus cuatro tipos básicos, con su nombre técnico:
str(string, «cadena»): texto. Va entre comillas:"Despacito","pop". Sirve para títulos de canción, nombres de artista o de género, cualquier cosa con letras.int(integer, «entero»): número sin decimales. 62 de popularidad, 30 canciones, 0 éxitos. No se cuentan medias canciones.float(«flotante»): número con decimales. 0,82 de energía, o el tempo de una canción, 120,5 pulsaciones por minuto. Ojo: en código el separador decimal es el punto,0.82, nunca la coma.bool(boolean, «booleano»): verdadero o falso, y nada más. SoloTrueoFalse. Es el tipo de las respuestas «sí/no»: ¿supera el umbral?, ¿es explícita la letra?
El texto, además de guardarse, sabe hacer cosas consigo mismo. Prueba:
cancion = "Despacito"
print(cancion.upper())
print("Longitud del nombre:", len(cancion))DESPACITO
Longitud del nombre: 9
.upper() devuelve el texto en mayúsculas, y len (de length, «longitud») cuenta cuántos caracteres tiene: «Despacito» tiene nueve letras. Ese puntito —cancion.upper()— se lee «al texto cancion, aplícale upper»; ya volverás a ver ese punto con las listas.
Convertir de un tipo a otro
A veces un dato llega disfrazado del tipo que no es. El caso más común: un número escrito como texto —"62", con comillas—, porque salió de un teclado o de un fichero. Con comillas no se puede sumar; primero hay que convertirlo. Las órdenes son int (a entero), float (a decimal) y str (a texto). Y, de paso, aprende un símbolo nuevo: todo cuanto escribas tras una almohadilla # es un comentario, una nota para humanos que la máquina ignora por completo.
# esto es un comentario: la maquina lo ignora
texto = "62"
numero = int(texto)
print(numero + 1)
print(str(30) + " canciones")63
30 canciones
int("62") convierte el texto "62" en el número 62, y por eso numero + 1 da 63. Al revés, str(30) convierte el número 30 en el texto "30", que ya se puede pegar a otro texto con +.
Y si te olvidas de convertir, la máquina protesta —y aprender a leer sus quejas es media batalla ganada—. Mira qué pasa al intentar pegar un texto y un número a lo bruto:
print("Canciones: " + 30)TypeError: can only concatenate str (not "int") to str
TypeError es «error de tipo», y el mensaje —«solo puedo pegar texto con texto»— dice exactamente qué pasó: le pediste juntar cosas de tipos incompatibles. No es un fallo grave; es la máquina negándose a adivinar. La solución: convierte antes ("Canciones: " + str(30)) o deja que print lo separe con comas (print("Canciones:", 30)). Leer el nombre del error y su frase es, muchas veces, la mitad de la solución.
El texto se puede cortar
Un adelanto de la Misión 2, para que veas adónde lleva todo esto. Cuando bajes datos reales, cada canción llegará como un texto con sus campos separados por comas, así: "Hold On,Chord Overstreet,acoustic,82". La orden .split(",") corta ese texto por las comas y te devuelve una lista de trozos, lista para trabajar.
linea = "Hold On,Chord Overstreet,acoustic,82"
partes = linea.split(",")
print(partes)
print("Cancion:", partes[0])
print("Popularidad:", int(partes[3]))
artista = "Chord Overstreet"
print(artista.lower())
print(artista.replace(" ", "_"))['Hold On', 'Chord Overstreet', 'acoustic', '82']
Cancion: Hold On
Popularidad: 82
chord overstreet
Chord_Overstreet
.split(",") parte la línea en cuatro trozos —título, artista, género y popularidad—. Cada trozo sigue siendo texto —por eso int(partes[3]) convierte el "82" en un número de verdad—. Y hay más tijeras para el texto: .lower() lo pone en minúsculas, .replace(" ", "_") cambia unos caracteres por otros. Con estas (split, lower, replace y el .upper() de antes) limpiarás datos de verdad muy pronto.
Operadores: hacer cuentas y comparar
Los operadores son los símbolos con los que la máquina calcula. Los de siempre (+, -, * para multiplicar, / para dividir) y tres que quizá no conozcas: ** eleva a una potencia, // divide y se queda solo con la parte entera, y % da el resto de una división.
suma = 28 + 41 + 55
print("Suma:", suma)
print("Media aproximada:", suma / 3)
print("Division entera:", 124 // 3)
print("Resto:", 124 % 3)
print("Al cuadrado:", 4 ** 2)Suma: 124
Media aproximada: 41.333333333333336
Division entera: 41
Resto: 1
Al cuadrado: 16
Mira la segunda línea: 124 / 3 no da un número redondo, sino 41.333333333333336, con una cola larguísima de decimales que además acaba de forma rara. No es un error de la máquina; es cómo guarda los decimales por dentro, y conviene saberlo desde el principio.
Los operadores más útiles para un analista no son los de calcular, sino los de comparar: > (mayor), < (menor), >= y <= (mayor o menor o igual), == (¿son iguales?, con dos signos, porque uno solo ya significa «guarda») y != (¿son distintos?). Cada comparación devuelve un bool. Y se pueden encadenar con and («y»), or («o») y not («no»):
energia = 0.42
print(energia > 0.4)
print(energia > 0.4 and energia < 0.5)
print(energia > 0.6 or energia < 0.2)
print(not energia > 0.4)True
True
False
False
Léelo como frases: «¿0,42 es mayor que 0,4?» sí; «¿mayor que 0,4 y menor que 0,5?» sí (las dos se cumplen); «¿mayor que 0,6 o menor que 0,2?» no (ninguna se cumple); «¿no es mayor que 0,4?» no. Con estas piezas ya puedes expresar cualquier condición sobre una canción.
Listas: una fila de cajas
Una variable guarda una cosa. Pero un género tiene muchas canciones —cada una con su popularidad—, y no vas a crear una caja con nombre para cada una. Para eso está la lista: una fila ordenada de valores, escrita entre corchetes y separada por comas. Es tu primera estructura de datos, y la que más vas a usar.
popularidades = [28, 41, 55, 39, 62]
print("Numero de canciones:", len(popularidades))
print("Primera:", popularidades[0])
print("Ultima:", popularidades[-1])
popularidades.append(30)
print("Tras anadir una:", popularidades)
print("Las tres primeras:", popularidades[:3])Numero de canciones: 5
Primera: 28
Ultima: 62
Tras anadir una: [28, 41, 55, 39, 62, 30]
Las tres primeras: [28, 41, 55]
Hay mucho aquí, y todo útil. len(popularidades) cuenta cuántos elementos hay. popularidades[0] es el primero —y sí, has leído bien: el primero es el número cero, no el uno—. popularidades[-1] es el último, contando desde el final. popularidades.append(30) añade un valor al final (otra vez el puntito: «a la lista, aplícale append»). Y popularidades[:3] es un corte: los tres primeros elementos.
Diccionarios: cajas con etiqueta
La lista guarda valores en fila, y para sacar uno necesitas saber su posición. Pero a veces quieres buscar por nombre, no por posición: «dame la pop de esta canción», no «dame el elemento tercero». Para eso está el diccionario: pares de clave (la etiqueta) y valor (lo guardado), entre llaves.
cancion = {"nombre": "Despacito", "pop": 88, "explicit": False}
print(cancion["nombre"], "tiene popularidad", cancion["pop"])
cancion["genero"] = "pop"
print(cancion)
for clave in cancion:
print(clave, "->", cancion[clave])Despacito tiene popularidad 88
{'nombre': 'Despacito', 'pop': 88, 'explicit': False, 'genero': 'pop'}
nombre -> Despacito
pop -> 88
explicit -> False
genero -> pop
Un diccionario es como una ficha: cada campo tiene su etiqueta. Pides el valor por su clave —cancion["nombre"]—, y puedes añadir campos nuevos sobre la marcha —cancion["genero"] = "pop"—. La lista y el diccionario serán, más adelante, las dos manos con las que sostendrás la música: la lista para las canciones de un género, el diccionario para la ficha de cada canción. Por ahora, quédate con la idea: lista, por posición; diccionario, por nombre.
Recorrer un diccionario
Al diccionario también se le pueden hacer preguntas, y se le puede dar la vuelta entero. Para saber si una clave existe está el operador in («está en»); para recorrer claves y valores a la vez, .items():
cancion = {"nombre": "Despacito", "pop": 88}
print("pop" in cancion)
print("tempo" in cancion)
for clave, valor in cancion.items():
print(clave, "=", valor)True
False
nombre = Despacito
pop = 88
"pop" in cancion pregunta «¿existe esa etiqueta?» y devuelve True o False —perfecto para meterlo en un if—. Y .items() te da, en cada vuelta del bucle, la clave y su valor de golpe. Con esto ya puedes recorrer la ficha entera de una canción sin saberte de memoria qué campos tiene.
Que decida: if, elif, else
Un programa que solo dice cosas fijas aburre enseguida. La máquina se vuelve útil cuando decide. La orden es if («si»): mira una condición y actúa distinto según sea verdadera o falsa. Y cuando hay más de dos caminos, se encadena con elif («si no, si…») y else («si no»). Vamos a clasificar una canción según su popularidad:
pop = 43
if pop > 50:
print("Un exitazo")
elif pop > 40:
print("Cancion popular")
else:
print("Cancion de nicho")Cancion popular
La máquina prueba las condiciones en orden y se queda con la primera que se cumple. Con pop = 43: ¿mayor que 50? no; ¿mayor que 40? sí \(\rightarrow\) dice «Cancion popular» y ya no mira el resto. Cambia el 43 por un 62 y dirá «Un exitazo»; por un 28, «Cancion de nicho». Predice antes de ejecutar: ¿qué saldría con pop = 50 exacto? Piénsalo, cámbialo y compruébalo —la respuesta enseña más que el párrafo—.
Fíjate en la sangría: las líneas de dentro de cada if van desplazadas a la derecha. En Python la sangría no es decoración —es la sintaxis—: le dice a la máquina qué órdenes van «dentro» de la decisión. Colab la pone por ti al pulsar Intro tras los dos puntos; respétala y no la mezcles con espacios sueltos.
Que repita: el bucle for
Decidir una vez está bien; lo potente es decidir muchas veces sin cansarse. Para eso está el bucle for («para cada»): coge una lista y hace lo mismo con cada elemento, uno tras otro, sin saltarse ninguno. Revisemos las cinco canciones y digamos, de cada una, si es popular:
popularidades = [28, 41, 55, 39, 62]
for valor in popularidades:
if valor > 40:
print(valor, "es popular")
else:
print(valor, "no despega")28 no despega
41 es popular
55 es popular
39 no despega
62 es popular
Léelo casi como español: «para cada valor en popularidades, si el valor es mayor que 40, di que es popular; si no, di que no despega». La máquina ha recorrido las cinco canciones y ha decidido cinco veces, sin que tú escribieras la orden cinco veces. Ahí está toda la gracia: el mismo código funciona con cinco canciones o con cinco mil.
A veces no quieres solo el valor, sino también su posición en la lista. Una forma es recorrer las posiciones con range, que genera los números de 0 en adelante:
for i in range(len(popularidades)):
print("Cancion", i, "->", popularidades[i])Cancion 0 -> 28
Cancion 1 -> 41
Cancion 2 -> 55
Cancion 3 -> 39
Cancion 4 -> 62
range(5) son los números 0, 1, 2, 3, 4 —las cinco posiciones de la lista—, y con cada uno pedimos popularidades[i]. Ya tienes la posición y su canción a la vez.
Repetir de otra manera: while, break y continue
El for recorre una lista entera, de principio a fin. Pero a veces no quieres recorrerla toda: quieres repetir hasta que pase algo, o saltarte algunos elementos, o parar en cuanto encuentres lo que buscabas. Tres herramientas para eso.
El bucle while («mientras») repite mientras una condición sea verdadera. Sirve cuando no sabes de antemano cuántas vueltas harán falta —por ejemplo, «recorre la lista hasta encontrar tres canciones populares»—:
objetivo = 3
populares = 0
i = 0
popularidades = [22, 44, 55, 18, 62, 41]
while populares < objetivo:
if popularidades[i] > 40:
populares = populares + 1
i = i + 1
print("Encontradas", objetivo, "populares al llegar a la posicion", i)Encontradas 3 populares al llegar a la posicion 5
Cuidado con el while: si la condición nunca se vuelve falsa, el bucle no para jamás (un bucle infinito, y el cuaderno se queda colgado). Asegúrate siempre de que algo dentro del bucle acerca la condición a su fin —aquí, i sube en cada vuelta—.
Dentro de cualquier bucle, continue salta al siguiente elemento sin terminar la vuelta actual, y break rompe el bucle del todo. Con continue nos saltamos las canciones flojas y solo mostramos las populares:
for valor in [22, 44, 55, 18, 62]:
if valor <= 40:
continue
print("Popular:", valor)Popular: 44
Popular: 55
Popular: 62
Y con break paramos en cuanto encontramos el primer temazo, sin seguir mirando el resto —porque ya tenemos aquello que buscábamos—:
for valor in [22, 44, 55, 18, 62]:
if valor > 50:
print("Primer temazo:", valor)
breakPrimer temazo: 55
break es el «ya está, para» del bucle. Fíjate en que ni el 62, que también es un temazo, llega a imprimirse: el bucle se cortó antes de llegar a él.
Construir una lista nueva
Hasta ahora los bucles miraban una lista. También sirven para fabricar otra, y este patrón es de los que más se repiten en todo el análisis de datos, así que grábatelo: empieza con una lista vacía y ve metiéndole con append solo lo que te interesa. Quedémonos, por ejemplo, con las canciones que superan el umbral:
popularidades = [28, 41, 55, 39, 62]
populares = []
for valor in popularidades:
if valor > 40:
populares.append(valor)
print(populares)[41, 55, 62]
Arrancas populares vacía ([]), recorres las popularidades y añades a la nueva lista solo las que pasan de 40. Al final tienes una lista filtrada: las tres populares, sin las demás. Cambiando la condición filtras lo que quieras; cambiando lo que metes (por ejemplo, valor * 2), transformas. Filtrar y transformar listas es, en el fondo, casi todo cuanto hace un analista con sus datos.
Un hechizo con nombre: la función
Cuando una receta te sirve más de una vez, no la reescribes cada vez: le pones un nombre y la invocas cuando la necesitas. Eso es una función. La defines una sola vez con def y luego la usas todas las que quieras. La función recibe algo (los parámetros, entre paréntesis) y return («devuelve») un resultado.
def es_popular(pop, umbral=40):
return pop > umbral
print(es_popular(55))
print(es_popular(28))True
False
Has fabricado una herramienta nueva: es_popular contesta verdadero o falso a «¿esta canción supera el umbral?». El umbral=40 es un valor por defecto: si no dices otra cosa, vale 40, pero puedes cambiarlo —es_popular(38, umbral=35)— sin tocar la función. Una función bien puesta es como un botón: aprietas y hace su trabajo, y no te importa el mecanismo de dentro mientras funcione.
Las funciones se vuelven imprescindibles cuando la decisión tiene varios caminos. Metamos dentro de una función la clasificación de canciones que hicimos antes:
def clasifica(pop):
if pop > 50:
return "exitazo"
elif pop > 40:
return "popular"
else:
return "de nicho"
print(clasifica(62))
print(clasifica(43))
print(clasifica(28))exitazo
popular
de nicho
Fíjate en que return no solo devuelve: también termina la función ahí mismo. En cuanto una rama devuelve «exitazo», la función se acaba y no sigue mirando. Ahora tienes una etiqueta de popularidad a golpe de una sola palabra: clasifica(valor).
Tres herramientas para la música
Con funciones, bucles y condiciones ya puedes fabricar herramientas de analista de verdad. Vamos a construir tres, y cada una es una micro-victoria: dale una lista de popularidades y te devuelve un hecho.
La más popular.
¿Cuál es la canción más popular de la lista? La receta: guarda un «campeón provisional», recorre la lista y, cada vez que encuentres algo mayor, corónalo campeón.
def mas_popular(valores):
campeon = valores[0]
for valor in valores:
if valor > campeon:
campeon = valor
return campeon
print("La mas popular es", mas_popular([28, 41, 55, 39, 62]))La mas popular es 62
La popularidad media.
Suma todas las popularidades y divide entre cuántas hay. Es el gesto que resume un género entero en un solo número.
def media(valores):
suma = 0
for valor in valores:
suma = suma + valor
return suma / len(valores)
print("Popularidad media:", media([28, 41, 55, 39, 62]))Popularidad media: 45.0
El conteo de populares.
¿Cuántas canciones pasan del umbral? Arranca un contador a cero y súmale uno cada vez que una canción se pase.
def cuenta_populares(valores, umbral=40):
populares = 0
for valor in valores:
if valor > umbral:
populares = populares + 1
return populares
print("Populares:", cuenta_populares([28, 41, 55, 39, 62]))Populares: 3
Tres funciones, tres hechos: la más popular es 62, la popularidad media es 45,0 y hay 3 populares. Guárdalas bien, porque son las piezas con las que, en unas páginas, levantarás tu primer informe musical.
Atajos que ya existen
Acabas de fabricar media y mas_popular con tus propias manos, y eso es justo cuanto quería: ahora entiendes lo que hacen por dentro. Buena noticia: Python ya trae esas herramientas hechas, y varias más. sum suma, max y min dan el mayor y el menor, sorted ordena, y len cuenta (esa ya la conoces).
popularidades = [28, 41, 55, 39, 62]
print("Suma:", sum(popularidades))
print("Maximo:", max(popularidades))
print("Minimo:", min(popularidades))
print("Ordenadas:", sorted(popularidades))
print("Media con atajo:", sum(popularidades) / len(popularidades))Suma: 225
Maximo: 62
Minimo: 28
Ordenadas: [28, 39, 41, 55, 62]
Media con atajo: 45.0
Tu mas_popular y el max de Python dan lo mismo, 62; tu media y sum(popularidades) / len(popularidades) dan lo mismo, 45,0. Entonces, ¿para qué construirlas a mano? Porque un atajo que usas sin entender es una caja negra, y un analista no se fía de cajas negras. Primero entiende el motor; luego, con toda la confianza del mundo, usa el atajo. A partir de aquí puedes tirar de sum, max y min cuando te convenga.
Leer y escribir por pantalla
Ya sabes escribir con print. Merece la pena hacerlo bonito, porque un resultado que se entiende de un vistazo vale el doble. La forma moderna se llama f-string: una f pegada a la comilla te deja meter valores dentro del texto, entre llaves.
cancion = "Despacito"
pop = 88
print(f"La cancion {cancion} tiene popularidad {pop}.")
media_genero = 39.83333
print(f"Popularidad media: {media_genero:.1f}")La cancion Despacito tiene popularidad 88.
Popularidad media: 39.8
Entre las llaves va el nombre de una variable, y la máquina lo sustituye por su valor. El :.1f de la segunda línea es un truco de formato: «muestra este número con un solo decimal». Así conviertes un 39.83333 feo en un limpio 39.8, sin cambiar el dato, solo cómo se enseña.
Predice antes de ejecutar
Aquí va el mejor hábito que puedes coger, y es gratis: antes de pulsar ejecutar, di en voz alta qué va a salir. No es una manía de profesor; es la diferencia entre entender y adivinar. Apuesta primero, ejecuta después. Si aciertas, has entendido; si fallas, acabas de descubrir un hueco justo cuando es más fácil taparlo. Programar bien no es teclear rápido: es no sorprenderte de lo que hace tu propio código. Practícalo ahora mismo con tres apuestas:
¿Cuánto da
cuenta_populares([10, 20, 30])? (Pista: ninguna pasa de 40.)¿Qué devuelve
clasifica(50)? (Ojo al>frente al>=.)¿Y
mas_popular([7]), una lista de un solo número?
Escribe tus tres respuestas en un papel, ejecútalas y compara. Cada fallo es una lección barata.
Reproducibilidad: reabre el cuaderno
Un segundo hábito, hermano del anterior: la reproducibilidad. Suena a palabra de mayores, pero para ti significa una cosa muy concreta —reabre el cuaderno mañana, ejecútalo entero de arriba abajo y tiene que salir exactamente lo mismo—. Si un día sale 3 y otro día sale 4 sin que hayas cambiado nada, no tienes un resultado: tienes una casualidad. Un número en el que no puedes confiar dos veces no sirve para defender nada ante nadie.
Por eso, en esta campaña, tres costumbres serán sagradas. Ejecutar de arriba abajo (nada de celdas sueltas en desorden). Guardar el cuaderno con su resultado dentro. Y desconfiar de cualquier cifra que no sepas volver a obtener. Es la diferencia entre «me salió» y «lo sé» —y esa diferencia es justo lo que separa a un analista de alguien que tuvo suerte una vez—. La honestidad de esta edición empieza aquí: nunca teclees a mano un número que puedas calcular, porque el número tecleado no se puede reproducir; el calculado, sí.
Nombra bien, comenta lo justo
Dos programas pueden hacer exactamente lo mismo y, aun así, uno ser bueno y el otro malo. La diferencia está en si se entienden. Mira estos dos, que cuentan populares igual:
x = [22, 44, 55]
y = 0
for z in x:
if z > 40:
y = y + 1
print(y)2
Funciona, da 2… pero, ¿qué son x, y, z? Ni idea. Ahora el mismo programa con nombres que hablan:
popularidades = [22, 44, 55]
populares = 0
for pop in popularidades:
if pop > 40:
populares = populares + 1
print(populares)2
Mismo resultado, pero este se lee como una frase: «por cada popularidad, si pasa de 40, una popular más». No has añadido ni una línea; solo has puesto nombres honrados. Un buen nombre es el mejor comentario que existe. Y cuando un comentario haga falta —con #—, que explique el porqué, no el qué: el qué ya lo dice el código. Escribir así no es presumir; es la cortesía de que otra persona —o tú mismo dentro de un mes— entienda lo que quisiste hacer.
Errores: tus mejores maestros
Vas a equivocarte mucho, y está bien: cada error es la máquina enseñándote algo, gratis y al instante. Ya has visto dos (NameError, cuando usas un nombre que no existe; TypeError, cuando mezclas tipos incompatibles). Añade tres más a tu colección, porque son los que más te vas a encontrar.
El IndexError salta cuando pides una posición que no existe en una lista. Si la lista tiene tres elementos (posiciones 0, 1 y 2) y pides la 5, ahí no hay nada:
popularidades = [28, 41, 55]
print(popularidades[5])IndexError: list index out of range
«list index out of range»: el índice se sale del rango de la lista. Casi siempre es un despiste de contar desde cero, o un bucle que se pasa una vuelta. Su primo para diccionarios es el KeyError, que salta al pedir una clave que no está:
cancion = {"nombre": "Despacito"}
print(cancion["pop"])KeyError: 'pop'
La máquina hasta te dice qué clave buscaba: ’pop’, que no existe en ese diccionario. Por eso el operador in es tan útil: comprueba antes de pedir. Y uno más, matemático: el ZeroDivisionError, que aparece al dividir entre cero —por ejemplo, si le pides la media a una lista vacía, porque tu media divide entre len(valores), que sería 0—:
print(media([]))ZeroDivisionError: division by zero
La receta para leer cualquier error es siempre la misma. Ve a la última línea (el nombre del error y su frase), mira en qué línea de tu código ocurrió, y pregúntate qué esperaba la máquina que no le diste. Un error leído con calma es una pista; un error leído con pánico es un muro. Tú léelos con calma —son, de verdad, tus mejores maestros—.
La victoria
Tienes todas las piezas: variables, tipos, operadores, listas, diccionarios, decisiones, bucles y funciones. Ha llegado el momento de juntarlas en un solo programa que resuelva un pedazo del encargo. La pregunta concreta de hoy: de estas canciones, ¿cuántas son populares?. Contar es el gesto más básico del análisis de datos, y ya sabes hacerlo entero.
popularidades = [28, 41, 55, 39, 62]
def cuenta_populares(valores, umbral=40):
populares = 0
for valor in valores:
if valor > umbral:
populares = populares + 1
return populares
total = cuenta_populares(popularidades)
print("Hay", total, "canciones populares en la lista.")Hay 3 canciones populares en la lista.
Mira lo que acabas de fabricar. Le has dado a la máquina cinco números en bruto y te ha devuelto un hecho: hay tres. No las has contado tú a ojo —las ha contado el programa—, y esa es toda la gracia: cuando en vez de cinco canciones sean cincuenta mil, tú escribirás exactamente el mismo código y la máquina hará el trabajo pesado sin rechistar.
¿Lo lograste?
Cada misión cierra con una celda de autocomprobación. No te fías de que «parece que va»: lo compruebas. La orden assert («asegura») es un guardián amable: comprueba que algo es verdad y, si lo es, se calla y te deja pasar; si no lo es, te para y te da una pista. Ejecuta esta celda tal cual:
resultado = cuenta_populares([28, 41, 55, 39, 62])
assert resultado == 3, "Casi: revisa el bucle y el umbral."
print("Lo lograste. Insignia desbloqueada: primer contacto.")Lo lograste. Insignia desbloqueada: primer contacto.
Si ves ese mensaje, enhorabuena de verdad: has conseguido que el ordenador te obedezca, has escrito tu primer programa completo y te has ganado la insignia primer contacto —la primera de la campaña «conviértete en analista de música»—. Si en cambio salta el aviso «Casi…», no es un fracaso: es el guardián haciendo su trabajo. Vuelve al bucle, revisa el límite y la suma, y prueba otra vez. Nadie mira; solo tú y el problema.
La bitácora del analista
Un analista de verdad no guarda solo sus resultados: guarda el camino hasta ellos. Abre una celda de texto al final de tu cuaderno —en Colab, el botón «+ Texto»— y ábrete una bitácora: un diario donde, misión a misión, anotas lo que descubres. Al terminar la campaña, esa bitácora será tu primer portafolio, la prueba de todo lo que sabes hacer. Para la Misión 1, anota al menos:
La pregunta que resolviste hoy: «¿cuántas canciones son populares?».
El hecho que obtuviste, con su número: «3 de 5».
Una cosa que te sorprendió al predecir antes de ejecutar (¿fallaste alguna apuesta? ¿cuál?).
Una duda que te llevas —la que sea—; las dudas anotadas son las que luego se resuelven.
No es tarea de relleno: escribir lo que has entendido es la forma más rápida de descubrir lo que no has entendido todavía.
Sube de nivel: un álbum entero
Cinco canciones están bien para aprender, pero un álbum de verdad trae muchas más. Aquí tienes las veinticuatro pistas de un álbum, con la popularidad de cada una (datos de ejemplo, fabricados para esta misión: unos pocos temazos entre muchas canciones discretas). Pégalo en una celda:
album = [22, 20, 19, 18, 21, 27, 35, 44, 52, 48, 41, 38,
36, 34, 33, 37, 43, 51, 58, 55, 46, 39, 31, 25]
print("Canciones del album:", len(album))Canciones del album: 24
Veinticuatro números. A ojo no dicen nada; deja que hablen tus tres herramientas. Como ya las definiste antes —cuenta_populares, mas_popular y media—, solo tienes que llamarlas y mirar el resultado:
print("Album: Amanecer")
print("Canciones:", len(album))
print("Canciones populares:", cuenta_populares(album))
print("Top (posicion):", album.index(mas_popular(album)))
print("Popularidad mas alta:", mas_popular(album))
print("Popularidad media:", round(media(album), 1))
if media(album) > 40:
print("Veredicto: album que pega fuerte.")
else:
print("Veredicto: album discreto.")Album: Amanecer
Canciones: 24
Canciones populares: 9
Top (posicion): 18
Popularidad mas alta: 58
Popularidad media: 36.4
Veredicto: album discreto.
Cuánto acabas de averiguar con seis líneas: de las 24 canciones, 9 son populares; la más popular está en la posición 18, con 58; y, pese a esos temazos, la popularidad media —36,4— se queda por debajo de 40, así que el álbum resulta más bien discreto. La .index(...) de la cuarta línea busca en qué posición está la más popular: te dice cuál es el temazo del álbum, no solo cuánto puntúa. Un mismo álbum, mirado con distintas herramientas, cuenta distintas historias —y todas son ciertas a la vez—.
¿Qué porcentaje son populares?
Un conteo se entiende mejor como proporción. «9 canciones populares» dice poco si no sabes de cuántas; «el 37,5 % del álbum» ya se siente. Sacar un porcentaje es una regla de tres: la parte entre el total, por cien.
album = [22, 20, 19, 18, 21, 27, 35, 44, 52, 48, 41, 38,
36, 34, 33, 37, 43, 51, 58, 55, 46, 39, 31, 25]
pct = 100 * cuenta_populares(album) / len(album)
print("Porcentaje de canciones populares:", round(pct, 1))Porcentaje de canciones populares: 37.5
Multiplicamos por 100 antes de dividir para no perder los decimales, y redondeamos a uno con round. Nueve de veinticuatro es el 37,5 % —más de un tercio del álbum son canciones populares—. Ese número, en un titular, ya cuenta una historia que la lista de cifras escondía.
Dibuja el álbum con caracteres
Y ahora, la micro-victoria más vistosa de la misión: un gráfico. Todavía no sabemos pintar de verdad (eso llega en la Misión 5), pero podemos dibujar una barra por canción usando solo el truco de multiplicar un texto —"#" * 3 da "###"—. Cuanto más alta la popularidad, más larga la barra:
for i, valor in enumerate(album):
barra = "#" * (valor // 5)
print(i, barra, valor)0 #### 22
1 #### 20
2 ### 19
3 ### 18
4 #### 21
5 ##### 27
6 ####### 35
7 ######## 44
8 ########## 52
9 ######### 48
10 ######## 41
11 ####### 38
12 ####### 36
13 ###### 34
14 ###### 33
15 ####### 37
16 ######## 43
17 ########## 51
18 ########### 58
19 ########### 55
20 ######### 46
21 ####### 39
22 ###### 31
23 ##### 25
Mira tu primer gráfico. Sin ninguna herramienta especial, solo con un bucle y una multiplicación de texto, la forma del álbum salta a la vista: muchas canciones de relleno (barras cortas) y dos grandes picos juntos al final —las pistas 18 y 19, los dos singles del álbum, los que más suenan—. Los datos han dejado de ser una lista de números para convertirse en una figura que se lee de un vistazo. Eso, exactamente eso, es a cuanto se dedica un analista.
Compara dos géneros
Un adelanto de la Misión 6, donde aprenderás a medir sin engañarte. La pregunta más natural del mundo: ¿de verdad es más popular el reggaeton que el indie?. Con una función que compare las dos medias, la respondes en el acto:
def mas_popular_de_dos(a, b):
if media(a) > media(b):
return "A"
else:
return "B"
reggaeton = [22, 44, 55, 18, 62, 41]
indie = [30, 33, 38, 29, 40, 35]
print("Media reggaeton:", round(media(reggaeton), 1))
print("Media indie:", round(media(indie), 1))
print("Mas popular:", mas_popular_de_dos(reggaeton, indie))
diferencia = round(media(reggaeton) - media(indie), 1)
print("Diferencia:", diferencia)Media reggaeton: 40.3
Media indie: 34.2
Mas popular: A
Diferencia: 6.2
mas_popular_de_dos mira las dos medias y devuelve la letra del más popular; además calculamos la diferencia para saber cuánto más. El reggaeton, con 40,3 de media, «gana» al indie por 6,2. (¿Ves? \(40{,}3 - 34{,}2\) daría 6,1, pero sale 6,2: la máquina resta las medias sin redondear —\(40{,}33 - 34{,}17\)—. Regla de analista: redondea al final, nunca en medio.) Cuidado, eso sí: una diferencia pequeña entre dos listas cortas puede ser pura casualidad —de eso irá, justamente, la misión de medir con honestidad—. Por ahora quédate con la idea: comparar es restar y decidir, y ya sabes hacer las dos cosas.
Sube otra vez: todo el catálogo
Un género cuenta la historia de un rincón de la música. Pero el catálogo tiene muchos, y la pregunta de verdad interesante es comparativa: ¿qué género es el más popular?. Para responderla necesitas un diccionario cuyos valores sean listas: cada género, con sus popularidades dentro. Es la lista y el diccionario trabajando juntos por primera vez.
catalogo = {
"pop": [28, 41, 55, 39, 62],
"rock": [30, 33, 38, 45, 40],
"jazz": [18, 22, 27, 24, 20],
}
medias = {}
for genero in catalogo:
medias[genero] = round(media(catalogo[genero]), 1)
print(medias){'pop': 45.0, 'rock': 37.2, 'jazz': 22.2}
En un solo bucle has resumido tres géneros enteros: para cada genero del catálogo, calculas la media de su lista y la guardas en un diccionario nuevo, medias. Un número por género, listo para comparar. Y comparar es otro bucle, con la misma receta del «campeón provisional» que ya conoces —solo que ahora el campeón es el género con la media más alta—:
top = None
top_media = 0
for genero in medias:
if medias[genero] > top_media:
top_media = medias[genero]
top = genero
print("El genero mas popular es", top, "con", top_media)El genero mas popular es pop con 45.0
Ahí tienes tu respuesta, con nombre y cifra: pop, con 45,0 de media, es el género más popular de los tres. (None es una palabra especial de Python que significa «nada todavía»; la usamos para arrancar la variable top antes de tener un ganador.) Acabas de hacer, en pequeño, exactamente aquello que harás con el catálogo de verdad: cargar muchos géneros, resumir cada uno y compararlos para encontrar el que importa. Esta es una victoria intermedia de las gordas —apúntala en la bitácora—.
El jefe de parte: tu primer informe musical
Hora de enfrentarte al jefe de parte: el miniproyecto que cierra la misión juntando todo lo aprendido. El encargo del jefe es fabricar una función que, dada la lista de un género, devuelva un parte completo —un diccionario con el resumen— listo para enseñar. Es exactamente aquello que hace un analista cada mañana.
def informe(valores, nombre, umbral=40):
return {
"nombre": nombre,
"canciones": len(valores),
"populares": cuenta_populares(valores, umbral),
"top": mas_popular(valores),
"media": round(media(valores), 1),
}
parte = informe(album, "Amanecer")
for clave in parte:
print(clave, "->", parte[clave])nombre -> Amanecer
canciones -> 24
populares -> 9
top -> 58
media -> 36.4
Ahí está tu informe: una sola función que resume un género entero en cinco hechos, y que servirá igual para cualquier lista que le pases. Has usado todo: una función que devuelve un diccionario, que por dentro llama a otras tres funciones, cada una con su bucle y su condición. Esto ya no es un ejercicio: es una herramienta.
¿Lo lograste? (nivel jefe)
El jefe también se comprueba. Esta celda verifica de una vez las tres cifras importantes del parte; si las tres cuadran, has vencido:
parte = informe(album, "Amanecer")
assert parte["canciones"] == 24, "Faltan o sobran canciones."
assert parte["populares"] == 9, "Revisa cuenta_populares."
assert parte["top"] == 58, "Revisa mas_popular."
print("Parte validado. Eres analista de musica por un dia.")Parte validado. Eres analista de musica por un dia.
Tres guardianes, tres comprobaciones, un solo mensaje de victoria. Si los tres callan, tu informe es sólido: no lo crees porque «parece bien», lo sabes porque lo has comprobado. Ese es, en miniatura, el oficio entero.
Y para todo el catálogo
Como informe devuelve un diccionario, puedes guardar el informe completo de cada género, no solo su media. Un diccionario de informes es un diccionario de diccionarios: la ficha de todo el catálogo en una sola estructura, generada con la función que acabas de vencer.
catalogo = {
"pop": [28, 41, 55, 39, 62],
"rock": [30, 33, 38, 45, 40],
"jazz": [18, 22, 27, 24, 20],
}
partes = {}
for genero in catalogo:
partes[genero] = informe(catalogo[genero], genero)
for genero in partes:
p = partes[genero]
print(genero, "-> populares:", p["populares"], "media:", p["media"])pop -> populares: 3 media: 45.0
rock -> populares: 1 media: 37.2
jazz -> populares: 0 media: 22.2
Con dos bucles cortos has construido y recorrido el parte de tres géneros a la vez. El primero llama a informe para cada género y guarda el resultado; el segundo lo recorre y enseña lo esencial. Añade géneros al diccionario catalogo y el código funcionará igual con tres o con treinta —no has escrito ni una línea que dependa del número de géneros—. Esa indiferencia al tamaño es la superpotencia de un bucle bien puesto, y la razón de que un analista pueda con el catálogo entero sin despeinarse.
Retos: elige tu nivel
Ahora te toca a ti, de verdad. Los retos suben de dificultad: \(\star\) es imprescindible, \(\star\star\) te reta y \(\star\star\star\) es de jefe. Haz al menos todas las de una estrella; sube hasta donde te apetezca. Y en todas, la regla de oro: predice antes de ejecutar.
★ Cambia el umbral. Antes de ejecutar, apuesta: con las cinco popularidades
[28, 41, 55, 39, 62]yumbral=50, ¿cuántas populares saldrán? Escríbelo, ejecutacuenta_populares(popularidades, umbral=50)y comprueba si acertaste.★ Tus propias canciones. Inventa una lista de seis popularidades (las que quieras) y cuenta cuántas pasan de 40. Enséñale el resultado a alguien.
★ Clasifica una canción. Usa
clasificapara etiquetar tres valores distintos como «de nicho», «popular» o «exitazo». Elige un valor de cada clase a propósito.★ La ficha de una canción. Crea un diccionario con las claves
"nombre","pop"y"explicit"para una canción inventada, y luego imprime solo su nombre y su popularidad.★★ La menos popular. Copia
mas_populary conviértela enmenos_popular: que devuelva el valor más bajo de la lista. Solo tienes que cambiar una cosa. ¿Cuál?★★ Solo las que pegan. Escribe un bucle que, en vez de contar,
printsolo las popularidades que superan el umbral. Acabas de fabricar un filtro.★★ Cuenta por franjas. Recorre el álbum de 24 canciones y cuenta cuántas son «de nicho», cuántas «populares» y cuántas «exitazos», usando
clasifica. Pista: tres contadores.★★ Redondea bonito. Repite el informe del álbum usando f-strings para que la media salga siempre con un decimal (
{media_genero:.1f}) y el texto quede alineado y legible.★★ Parte la línea. Dado el texto
"Pano,Zack Tabudlo,acoustic,75", sepáralo con.split(",")e imprime la canción y su popularidad convertida a número conint. Es el gesto con el que empezará la Misión 2.★★★ El jefe: la media a mano. Calcula la media de las popularidades sin usar la función
medianisum: con un bucle, ve sumando en un contador y divide entrelen(popularidades). Compara tu resultado consum(popularidades) / len(popularidades): deben coincidir. Si cuadran, has entendido lo que hace por dentro una función.★★★ El jefe: dos géneros. Fabrica el informe de dos géneros distintos (inventa el segundo, con más éxitos) y escribe un
ifque diga cuál de los dos es más popular, comparando sus medias. Devuelve el nombre del ganador.★★★ El jefe final en miniatura. Amplía
informepara que añada al diccionario una clave"veredicto"con la etiqueta declasificaaplicada a la media del género. Un informe que, además de los números, ya se moja con una conclusión.
¿Te has atascado? En el apéndice C tienes, para cada reto, primero una pista y solo después la solución. Pero el pacto es este: entra ahí después de haberlo intentado de verdad.
Tu caja de herramientas
Mira todo lo que sabes hacer ahora y hace unas páginas no sabías. Esta es tu chuleta: pégala en la bitácora y vuelve a ella cuando dudes.
Decir cosas:
print("hola", valor).Guardar:
pop = 62(variable). Tipos:strtexto,intentero,floatdecimal,boolverdadero/falso.Convertir:
int("62"),float("0.82"),str(30).Calcular:
+ - * /, y//,%,**. Comparar:> < >= <= == !=, yand or not.Listas:
[28, 41, 55],lista[0],lista[-1],lista[:3],lista.append(x),len(lista).Diccionarios:
{"pop": 62},d["pop"],"pop" in d,d.items().Decidir:
if/elif/else. Repetir:for x in listaywhile condicion, cortando conbreakycontinue.Funciones:
def nombre(parametros): return resultado.Atajos:
sum,max,min,sorted,round(x, 1).Texto:
.upper(),.lower(),.split(","), y f-stringsf"media {m:.1f}".Comprobar:
assert resultado == esperado.
No memorices esta lista: úsala. La memoria viene sola de tanto teclear.
Cuando quieras ir en serio
Todo esto lo has hecho en el navegador, sin instalar nada, y para aprender está perfecto. Pero hay un mundo de herramientas «de mayores» esperándote cuando quieras dar el salto: programar en tu propio ordenador con un editor como VS Code, gestionar las versiones exactas de cada biblioteca con uv para que tu proyecto corra idéntico en cualquier máquina, compilar documentos con latexmk, guardar el historial de tu trabajo con git. No lo necesitas para las próximas misiones —el cuaderno te basta—, pero está ahí, y el puente hacia ese mundo es el volumen adulto del que nace este libro.
Por cierto, un último truco de la casa: escribe import this en una celda y ejecútala. Es un guiño de quienes hicieron Python, la filosofía del lenguaje en veinte líneas [@pep20]. Una de ellas dice que «lo explícito es mejor que lo implícito», y ya sabes por qué: un nombre de variable que dice lo que guarda, un número que se calcula en vez de teclearse, una comprobación que confirma la victoria en vez de suponerla. No es solo estilo; es la manera de que otra persona —o tú, dentro de seis meses— pueda confiar en lo que hiciste.
Misión 1 completada. Insignia primer contacto, desbloqueada. Has hecho que el ordenador te obedezca, has escrito y comprobado tu primer informe musical, y tienes tu bitácora empezada. En la Misión 2 dejaremos los datos inventados: bajaremos un catálogo de música real a tu cuaderno. El ordenador ya te obedece; ahora vamos a darle algo de verdad que analizar.