Python II: funciones y colecciones

Tema 2 · Fase 1, Programar con datos · Toda la ruta

Cuaderno del tema. La teoría y los ejercicios con todo su código, listos para ejecutar en Colab sin instalar nada.

Los 21 bloques de código de la teoría, en el mismo orden. Si prefieres armar tu propio cuaderno, cópialos y córrelos en orden; en la ficha Teoría está la explicación de cada uno.

Funciones: código con nombre

def celsius_a_fahrenheit(celsius):
    """Convierte una temperatura de grados Celsius a Fahrenheit."""
    return celsius * 9 / 5 + 32

print(celsius_a_fahrenheit(0))
print(celsius_a_fahrenheit(25))
temperatura = celsius_a_fahrenheit(-10)
print(f"-10 °C son {temperatura} °F")
def nota_final(parcial, examen, peso_examen=0.6):
    """Promedio ponderado: el examen pesa peso_examen."""
    return parcial * (1 - peso_examen) + examen * peso_examen

print(nota_final(70, 80))                    # el examen pesa 0.6
print(nota_final(70, 80, peso_examen=0.5))   # ahora pesa la mitad
def doble_que_imprime(x):
    print(2 * x)

def doble_que_devuelve(x):
    return 2 * x

a = doble_que_imprime(5)
b = doble_que_devuelve(5)
print(a, b)

Listas: muchos valores juntos

notas = [72, 85, 58, 91, 64]

print(notas[0])      # la primera
print(notas[-1])     # la última: los índices negativos cuentan desde atrás
print(notas[1:3])    # una rebanada: de la posición 1 hasta antes de la 3
print(len(notas), sum(notas), min(notas), max(notas))

notas.append(77)     # agrega un valor al final
notas[2] = 60        # cambia el valor de la posición 2
print(notas)
print(91 in notas)   # ¿está el 91 en la lista?
# Sumar 5 puntos de bono a cada nota
con_bono = []
for n in notas:
    con_bono.append(n + 5)
print(con_bono)
con_bono = [n + 5 for n in notas]
altas = [n for n in notas if n >= 80]
print(con_bono)
print(altas)
print(f"{len(altas)} de {len(notas)} notas son de 80 o más")
def promedio(valores):
    """El promedio de una lista de números."""
    return sum(valores) / len(valores)

print(round(promedio(notas), 1))
print(promedio([10, 20]))

Tuplas, diccionarios y conjuntos

edades = {"Ana": 15, "Luis": 16, "Sofía": 14}

print(edades["Luis"])        # buscar por clave
edades["Marco"] = 15         # agregar una clave nueva
edades["Ana"] = 16           # cambiar el valor de una clave
print(len(edades), "personas")

for nombre, edad in edades.items():
    print(f"{nombre}: {edad} años")
colores = ["rojo", "azul", "rojo", "verde", "azul", "rojo"]
distintos = set(colores)
print(len(colores), "colores anotados,", len(distintos), "distintos")
print(sorted(distintos))
print("amarillo" in distintos)

Contar las palabras de un texto

texto = """La panadería del barrio abre temprano. A las seis ya huele a pan,
y a las siete la fila llega a la esquina. El pan de la mañana se acaba
rápido: la gente compra pan para el desayuno y pan para el colegio. Por la
tarde la panadería hace galletas, y los niños del barrio pasan a comprar
galletas al salir del colegio."""
def limpiar(texto):
    """Pasa a minúsculas y cambia la puntuación por espacios."""
    limpio = ""
    for c in texto.lower():
        if c.isalnum() or c.isspace():
            limpio += c
        else:
            limpio += " "
    return limpio

palabras = limpiar(texto).split()   # split corta en los espacios
print(palabras[:8])
print(len(palabras), "palabras")
def contar(palabras):
    """Diccionario con cuántas veces aparece cada palabra."""
    conteo = {}
    for palabra in palabras:
        if palabra in conteo:
            conteo[palabra] += 1
        else:
            conteo[palabra] = 1
    return conteo

conteo = contar(palabras)
print(len(conteo), "palabras distintas")
print("pan:", conteo["pan"], "  la:", conteo["la"])
def la_cuenta(par):
    """De un par (palabra, cuenta), devuelve la cuenta."""
    return par[1]

ordenadas = sorted(conteo.items(), key=la_cuenta, reverse=True)
print(ordenadas[:5])
import matplotlib.pyplot as plt

def graficar_frecuentes(pares, titulo):
    """Barras horizontales con los pares (palabra, cuenta)."""
    palabras_top = [p for p, c in pares]
    cuentas_top = [c for p, c in pares]
    # La primera barra (la más frecuente) en otro color
    colores = ["C1"] + ["C0"] * (len(pares) - 1)
    plt.barh(palabras_top, cuentas_top, color=colores)
    plt.gca().invert_yaxis()       # la más frecuente arriba
    plt.xlabel("Veces que aparece")
    plt.title(titulo)
    plt.show()

graficar_frecuentes(ordenadas[:8], "Las 8 palabras más frecuentes")
vacias = {"la", "las", "el", "los", "a", "de", "del", "y", "al",
          "se", "para", "por", "ya"}

conteo_util = {p: c for p, c in conteo.items() if p not in vacias}
ordenadas_util = sorted(conteo_util.items(), key=la_cuenta,
                        reverse=True)
print(ordenadas_util[:5])
graficar_frecuentes(ordenadas_util[:8], "Sin las palabras vacías")

Archivos y CSV

import csv

filas = [
    ["nombre", "matematica", "lenguaje", "ciencias"],
    ["Ana", 78, 85, 90],
    ["Bruno", 55, 62, 48],
    ["Carla", 92, 88, 95],
    ["Diego", 40, 71, 66],
    ["Elena", 67, 59, 73],
    ["Franco", 85, 77, 81],
]

# "w" abre el archivo para escribir (lo crea o lo reemplaza)
with open("notas.csv", "w", newline="", encoding="utf-8") as f:
    escritor = csv.writer(f)
    escritor.writerows(filas)
with open("notas.csv", encoding="utf-8") as f:
    for linea in f:
        print(linea.strip().split(","))
def leer_columna(archivo, columna):
    """Los valores de una columna de un CSV, como números."""
    valores = []
    with open(archivo, encoding="utf-8") as f:
        for fila in csv.DictReader(f):
            valores.append(float(fila[columna]))
    return valores

matematica = leer_columna("notas.csv", "matematica")
print(matematica)
print(f"Promedio: {promedio(matematica):.1f}")
print(f"Mínimo: {min(matematica)}   Máximo: {max(matematica)}")

Módulos, `import` y `pip`

import math
import random
from collections import Counter

print(math.sqrt(81), math.pi)

random.seed(1)              # semilla fija: siempre sale lo mismo
print(random.choice(["piedra", "papel", "tijera"]))

# Counter hace en una línea lo que hizo nuestra función contar
print(Counter(palabras).most_common(3))

Clases: una pista de lo que viene

class Contador:
    """Cuenta cuántas veces aparece cada cosa."""

    def __init__(self):
        # Se ejecuta al crear el objeto: empieza con el conteo vacío
        self.conteo = {}

    def agregar(self, cosa):
        self.conteo[cosa] = self.conteo.get(cosa, 0) + 1

    def agregar_todas(self, cosas):
        for cosa in cosas:
            self.agregar(cosa)

    def mas_comunes(self, k):
        pares = sorted(self.conteo.items(), key=lambda par: par[1],
                       reverse=True)
        return pares[:k]

c = Contador()                 # crear un objeto de la clase
c.agregar_todas(palabras)
c.agregar("pan")
print(c.mas_comunes(3))
print(c.conteo["pan"])
class ModeloPromedio:
    """El modelo más simple: siempre predice el promedio."""

    def fit(self, valores):
        # «Aprender» aquí es guardar el promedio de los datos
        self.media = sum(valores) / len(valores)

    def predict(self, cantidad):
        return [self.media] * cantidad

modelo = ModeloPromedio()
modelo.fit(matematica)
print(modelo.media)
print(modelo.predict(3))