Clases y Objetos: Taller Integrador
Ya viste class, __init__, self, atributos y métodos como tema separado. Este taller no enseña nada nuevo: te da 10 problemas cortos más un reto final para que combines clases y objetos con todo lo que ya sabías (condicionales, bucles, funciones, listas) resolviendo problemas de verdad — cerrando el arco de fundamentos de esta materia antes de seguir con ideas más avanzadas de POO.
Bienvenido
Este taller es la práctica integradora de Clases y Objetos junto con todo lo anterior: Funciones, Bucles, Condicionales y el resto de guías de POO. No repite la teoría de ninguna — si algo no te suena, es el momento de volver a repasarlo antes de seguir.
Este taller asume que ya completaste Clases y Objetos desde cero y las guías previas. Ningún ejercicio necesita herencia, polimorfismo ni encapsulación (_/__ antes del nombre) — nada de eso se explicó todavía. Tampoco hace falta indexado de listas (lista[0]) ni métodos como .append(): alcanza con for elemento in lista, igual que en los talleres anteriores, aunque ahora esos elementos van a ser objetos en vez de números.
Cada ejercicio trae un editor vacío: el enunciado te dice qué clase o función tenés que escribir, y vos escribís el código Python de cero. Presiona ▶ Ejecutar para correrlo de verdad en tu navegador con Pyodide (Python real compilado a WebAssembly). La primera ejecución tarda unos segundos porque descarga el intérprete. Si estás resolviendo el taller desde un lanzamiento de ATENZA, además aparece el botón 📨 Enviar para revisión una vez que el código corra sin errores, para mandar ese ejercicio al docente (no se autocorrige).
En este taller, copiar y pegar código en los editores está deshabilitado (incluido arrastrar y soltar). La idea es que practiques escribiendo la sintaxis vos mismo, no que la traigas de otro lado.
🧩 Integrador
Cada bloque mezcla clases y objetos con condicionales, bucles, funciones y listas.
🔁 Objetos en listas
La sección 2 recorre listas de objetos con for, igual que antes recorrías listas de números.
🎯 Reto final
Un boletín de notas, pero ahora cada estudiante es un objeto con sus propios métodos.
Zona de pruebas libres
Este bloque queda disponible durante todo el taller. Usalo en cualquier momento para probar una idea suelta, revisar cómo se comporta una clase, o experimentar algo que se te ocurra a mitad de un ejercicio — sin desordenar los bloques numerados.
1. Atributos y métodos que deciden
Tres clases donde un método usa if/elif/else por dentro, leyendo o modificando los atributos de self para decidir qué hacer o qué devolver.
Escribe una clase Estudiante con __init__(self, nombre, nota) que guarde ambos atributos. Agrégale un método aprobo(self) que devuelva True si self.nota es mayor o igual a 51, o False en caso contrario. Crea un objeto Estudiante("Ana", 65) y otro Estudiante("Luis", 40), e imprime el resultado de aprobo() para cada uno.
Escribe una clase CuentaBancaria con __init__(self, saldo). Agrégale un método retirar(self, monto): si monto es mayor que self.saldo, debe devolver el texto "Fondos insuficientes" sin tocar el saldo; si alcanza, debe restar monto de self.saldo y devolver "Retiro exitoso". Crea una cuenta con saldo 500, prueba un retiro de 200 (debería funcionar) y después uno de 1000 (debería fallar), imprimiendo el mensaje de cada intento.
Escribe una clase Termometro con __init__(self, temperatura). Agrégale un método clasificar(self) que devuelva "Frío" si self.temperatura < 15, "Templado" si está entre 15 y 25 (sin incluir 25), o "Caluroso" si es mayor o igual a 25 — usando if/elif/else adentro del método. Prueba con al menos tres objetos distintos, uno para cada categoría.
2. Constructores y listas de objetos
Una lista ya no tiene que ser solo números o textos: también puede guardar objetos. Se recorre exactamente igual, con for objeto in lista, y adentro del for accedés a los atributos y métodos de cada objeto como siempre.
Escribe una clase Empleado con __init__(self, nombre, salario). Crea una lista con al menos 5 objetos Empleado, con nombres y salarios distintos: empleados = [Empleado("...", ...), Empleado("...", ...), ...]. Con un for empleado in empleados, imprime el nombre y el salario de cada uno.
Reutiliza la clase Empleado y la lista del ejercicio anterior. Ahora escribe, fuera de la clase, una función salario_total(lista) que reciba la lista de objetos y devuelva la suma de todos los salarios, recorriéndola con for empleado in lista y accediendo a empleado.salario en cada vuelta. Imprime el resultado.
Escribe una función contar_bien_pagados(lista, minimo) que devuelva cuántos empleados de la lista tienen salario mayor o igual a minimo — el mismo patrón que contar_pares() del taller de repaso anterior, pero ahora comparando empleado.salario dentro del for en vez de un número suelto. Pruébala sobre tu lista de empleados con un par de valores distintos de minimo.
3. Métodos que llaman a otros métodos
Tres problemas con dos ideas nuevas, extensión directa de lo que ya sabés: un método puede llamar a otro método del mismo objeto, y una función común (no un método) puede recibir un objeto como parámetro.
Dentro de un método, usa self.otro_metodo() para llamar a otro método de ese mismo objeto — igual que self.atributo te deja leer un atributo. Así evitás repetir una lógica que ya escribiste en otro método.
Escribe una clase Rectangulo con __init__(self, base, altura), un método area(self) que devuelva self.base * self.altura, y un método perimetro(self) que devuelva 2 * (self.base + self.altura). Agrégale un tercer método resumen(self) que llame a self.area() y self.perimetro() por dentro, y devuelva un texto como "Área: 24, Perímetro: 20". Crea un objeto y prueba print(rect.resumen()).
Un objeto se puede pasar como argumento a una función que no es método de su clase, igual que pasarías un número o una lista. La función recibe el objeto y puede leer sus atributos o llamar a sus métodos con normalidad.
Vuelve a escribir la clase Estudiante del ejercicio 1.1 (con nombre, nota y el método aprobo(self)). Ahora, fuera de la clase, escribe una función mostrar_ficha(estudiante) que reciba un objeto Estudiante como parámetro e imprima su nombre, su nota, y si aprobó o no (llamando a estudiante.aprobo()). Crea dos estudiantes distintos y llama mostrar_ficha() con cada uno.
Escribe una clase Vehiculo con __init__(self, velocidad). Agrégale un método acelerar(self, incremento) que sume incremento a self.velocidad, y un método frenar(self, decremento) que lo reste, pero sin dejar que self.velocidad baje de 0 (si restar daría un número negativo, dejalo en 0 usando if). Por último, un método estado(self) que devuelva "Detenido" si self.velocidad es 0, "Velocidad normal" si es menor a 80, o "Exceso de velocidad" si es 80 o más. Crea un objeto, acelera y frena un par de veces, e imprime estado() después de cada cambio.
Reto final: Boletín de notas, con objetos
El mismo problema del reto final del taller de funciones — pero esta vez cada estudiante es un objeto, con sus propias notas guardadas como atributo, y sus propios métodos para calcular su promedio y saber si aprobó.
__init__(self, nombre, notas)— guarda ambos como atributos.notases una lista de números sobre 20 (por ejemplo[15, 18, 12]).- 1.
promedio(self)— devuelve el promedio deself.notas, recorriéndola confor nota in self.notas. - 2.
aprobo(self)— devuelveTruesiself.promedio()es mayor o igual a 11 (llamando a tu propio métodopromedio(), no recalculando nada). - 3.
resumen(self)— devuelve un texto con el nombre, el promedio (conround(..., 2)) y si aprobó o no, reutilizandoself.promedio()yself.aprobo().
Escribe en el editor una lista con al menos 4 objetos Estudiante, cada uno con su propia lista de notas, por ejemplo:
estudiantes = [Estudiante("Ana", [15, 18, 12]), Estudiante("Luis", [8, 10, 9]), ...]
contar_aprobados(lista) — recibe la lista de estudiantes y devuelve cuántos aprobaron, recorriéndola con for y llamando a estudiante.aprobo() en cada vuelta.
Con un for estudiante in estudiantes, el resumen() de cada uno. Después, llamando a contar_aprobados(), cuántos estudiantes aprobaron en total.
Cheat Sheet del taller
| Herramienta | Para qué la usaste hoy |
|---|---|
class Nombre: + __init__(self, ...) | Definir el molde de un objeto y su constructor. |
if/elif/else dentro de un método | Decidir qué devolver según el estado del propio objeto (self.atributo). |
lista = [Clase(...), Clase(...)] | Una lista puede guardar objetos, no solo números o textos. |
for objeto in lista: | Recorrer objetos y llamar sus métodos, exactamente igual que con cualquier otro dato. |
self.otro_metodo() | Llamar a otro método del mismo objeto desde adentro de un método, sin repetir su lógica. |
funcion(objeto) | Pasar un objeto como parámetro a una función común, no solo a métodos de su clase. |
Atributo que guarda una lista (self.notas) | Un objeto puede tener, entre sus atributos, una lista propia. |
| Función que recibe una lista de objetos | Recorrer y agregar datos de varios objetos a la vez (salario_total(), contar_aprobados()). |
¿Sabías que...?
🖨️ print(objeto) por defecto es feo
Si probás print(estudiante) directo, en vez de print(estudiante.resumen()), vas a ver algo como <__main__.Estudiante object at 0x7f...>. Python no sabe cómo mostrar tu objeto en texto a menos que se lo digas vos — con un método especial llamado __str__, otro "dunder" como __init__, que todavía no viste.
🧬 Cada objeto sigue siendo independiente
Aunque ahora vivan juntos dentro de una lista, cada Estudiante guarda su propio nombre y su propia lista de notas — modificar uno nunca afecta a los demás, la misma idea que ya viste con rex y firulais.
🏗️ Herencia, la siguiente gran idea
Estudiante y Empleado de este taller se parecen: ambos tienen un nombre y un método que decide algo. La herencia permite definir esas partes compartidas una sola vez y que otras clases las hereden — el siguiente paso natural después de dominar clases y objetos por separado.