Python II: funciones y colecciones

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

Los 21 bloques de código de la teoría, en el mismo orden. Cópialos y córrelos en tu Python o en Colab; 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))