Restructure content and add notes from HolaMundo

Signed-off-by: Manuel Vergara <manuel@vergaracarmona.es>
This commit is contained in:
2023-05-20 09:36:26 +02:00
parent 64ed03f811
commit f4e9797c4b
430 changed files with 889 additions and 24 deletions

View File

@@ -0,0 +1,28 @@
"""
Clases
"""
# La mínima clase es poner pass
class Pajaro:
pass
# mi_pajaro es una instancia de Pajaro,
# que en este punto se considera un objeto
mi_pajaro = Pajaro()
# Si intentamos mostrar la expresión mínima nos dirá
# que es un objeto guardado en cierto espacio de memoria
print(mi_pajaro)
# Si mostramos el tipo nos dirá __main__
print(type(mi_pajaro))
# Podemos crear más objectos y serán distintos de la misma clase
otro_pajaro = Pajaro()
# Mostrando en pantalla nos mostrará que se guarda
# en otro espacio de memoria
print(otro_pajaro)

View File

@@ -0,0 +1,34 @@
"""
Atributos
"""
# Sintaxis:
# def tipo/método (tipo_parámetro, parámetro):
# tipo_parámetro.atributo = parámetro
# Creamos la clase
class Pajaro:
# Atributos de clase
# Para valores comunes entre todos los objetos de la clase
alas = True
# Atributos de instancia
# Constructor de la clase pajaro --> Con el método__init__
def __init__(self, color, especie): # En el paréntesis pasamos dos parámetros
self.color = color # Le damos la instancia que vamos a crear con el atributo
self.especie = especie
# Creamos la instancia. Si dejamos vacios los paréntesis dará error.
# por que pajaro exige un argumento, debe ser un valor para el atributo.
mi_pajaro = Pajaro('negro', 'Tucan')
# Con el punto podremos ver el atributo entre otras propiedades
print(
f'Mi pajaro es de color {mi_pajaro.color} y de la especie {mi_pajaro.especie}')
# Los atributos de clases se pueden dar a la clase y a la instancia:
print(Pajaro.alas, mi_pajaro.alas)

View File

@@ -0,0 +1,61 @@
"""
Métodos
"""
# self es un argumento obligatorio
# hace referencia a cada instancia de la clase
class Pajaro:
alas = True
def __init__(self, color, especie):
self.color = color
self.especie = especie
# Cuando se hace referencia a un atributo se debe poner self por delante
# para que se asocie correctamente
def piar(self):
print('pio, mi color es {}'.format(self.color))
def volar(self, metros):
print(f'El pajaro ha volado {metros} metros')
piolin = Pajaro('amarillo', 'canario')
piolin.piar()
piolin.volar(50)
# Otro ejemplo
class Persona:
especie = "humano"
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def saludar(self):
print(f'Hola, mi nombre es {self.nombre}')
def cumplir_anios(self, estado_humor):
print(f'Cumplir {self.edad + 1} años me pone {estado_humor}')
juan = Persona("Juan", 37)
juan.saludar()
juan.cumplir_anios("feliz")
class Alarma:
def postergar(self, cantidad_minutos):
print(f"La alarma ha sido pospuesta {cantidad_minutos} minutos")
sonar = Alarma()
sonar.postergar(10)

View File

@@ -0,0 +1,90 @@
"""
Tipos de métodos
# Decoradores:
- Métodos de instancia:
def mi_metodo(self):
print('algo')
mi_metodo
- Acceden y modifican atributos del objeto.
- Acceden a otro métodos.
- Pueden modificar el estado de la clase.
- Métodos de clase @classmethod:
def mi_metodo(cls):
print('algo')
- No están asociados a las instancias de la clase, sino a la clase en si misma
- Pueden ser llamados desde la instancia y desde la clase
- No pueden acceder a los atributos de instancia pero si a los de la clase
- Métodos estáticos @staticmethod:
@staticmethod
def mi_metodo():
print('algo')
- No acepta como parámetro ni self ni cls
- No pueden modificar ni el estado de la clase ni de la instancia
- Pueden aceptar parámetros de entrada
"""
class Pajaro:
alas = True
def __init__(self, color, especie):
self.color = color
self.especie = especie
# Cuando se hace referencia a un atributo se debe poner self por delante
# para que se asocie correctamente
def piar(self):
print('pio, mi color es {}'.format(self.color))
def volar(self, metros):
print(f'El pajaro ha volado {metros} metros')
# De instancia - Acceden a otro métodos
self.piar()
# De instancia - Acceden y modifican atributos del objeto
def pintar_negro(self):
self.color = 'negro'
print(f'Ahora el pájaro es {self.color}')
# Métodos de clase. Necesita el decorador
@classmethod
def poner_huevos(cls, cantidad):
print(f'Puso {cantidad} huevos')
# No pueden acceder a los métodos de instancia
# print(f'Es de color {self.color}')
# Pero si que puede acceder a los métodos de clase
cls.alas = False
print(Pajaro.alas)
@staticmethod
def mirar():
# No accede ni a métodos de instancia ni de clase
# self.color = 'rojo'
# cls.alas = 2
# Así te aseguras que no se modifiquen los métodos
print('El pajaro mira')
Pajaro.poner_huevos(3)
Pajaro.mirar()
piolin = Pajaro('amarillo', 'canario')
piolin.pintar_negro()
piolin.volar(45)
# De instancia - Pueden modificar el estado de la clase
piolin.alas = False
print(piolin.alas)

View File

@@ -0,0 +1,57 @@
"""
Herencia
D ONT'T
R EPEAT
Y OURSELF
No repitas el código!
"""
# Ejemplo
class Animal:
# Atributos
def __init__(self, edad, color):
self.edad = edad
self.color = color
# Métodos
def nacer(self):
print("Este animal ha nacido")
def morir(self):
pass
def respirar(self):
pass
class Pajaro(Animal):
pass
class Mamifero(Animal):
pass
class Insecto(Animal):
pass
# Podemos ver de donde vienen las clase con __bases__
print(Pajaro.__bases__)
# Podemos ver las subclases de una clase
print(Animal.__subclasses__())
# Creamos una instancia de pájaro y debe tener los atributos de Animal
piolin = Pajaro(2, "negro")
print(f'Piolin tiene {piolin.edad} años y es de color {piolin.color}')
# La instancia de Pájaro ha heredado los métodos de Animal
piolin.nacer()

View File

@@ -0,0 +1,85 @@
"""
Herencia Extendidad
D ONT'T
R EPEAT
Y OURSELF
No repitas el código!
"""
class Animal:
def __init__(self, edad, color):
self.edad = edad
self.color = color
def nacer(self):
print("Este animal ha nacido")
def hablar(self):
print("Este animal emite un sonido")
class Pajaro(Animal):
def __init__(self, edad, color, altura_vuelo):
super().__init__(edad, color)
self.altura_vuelo = altura_vuelo
def hablar(self):
print("pio")
def volar(self, metros):
print(f'El pájaro vuela {metros} metros')
# Declarar variables
piolin = Pajaro(3, 'amarillo', 500)
mi_animal = Animal(19, 'negro')
piolin.hablar()
piolin.volar(100)
mi_animal.hablar()
# otro ejemplo
class Padre:
def hablar(self):
print('Hola')
class Madre:
def reir(self):
print('ja ja ja')
def hablar(self):
print('Que tal')
class Hijo(Padre, Madre):
pass
class Nieto(Hijo):
pass
# Nieto es capaz de hablar y reir aunque no herede directamente
mi_nieto = Nieto()
mi_nieto.reir()
# El método que hereda es el primero que se encuentra en sus atributos
mi_nieto.hablar()
# Podemos ver el orden de las herencias con __mro__
print(Nieto.__mro__)

View File

@@ -0,0 +1,55 @@
"""
Polimorfismo
Distintas clases pueden tener el mismo método
pero se aplicará de manera distinta para cada clase
"""
class Vaca:
def __init__(self, nombre):
self.nombre = nombre
def hablar(self):
print(self.nombre + " dice muuu")
class Oveja:
def __init__(self, nombre):
self.nombre = nombre
def hablar(self):
print(self.nombre + " dice beee")
vaca1 = Vaca('Aurora')
oveja1 = Oveja('Jacinta')
# Dos classes distintas con el mismo método
# que dicen cosas distintas
vaca1.hablar()
oveja1.hablar()
print()
# Ahora en una lista para iterar
# Cuidao! Es genial!
animales = [vaca1, oveja1]
for animal in animales:
animal.hablar()
print()
# También en funciones.
# Impresionante!
def animal_habla(animal):
animal.hablar()
animal_habla(vaca1)
animal_habla(oveja1)

View File

@@ -0,0 +1,66 @@
"""
Métodos especiales
Se han visto:
__init__
__mro__
__bases__
__subclasses__
Vamos a ver:
__str__
__len__
"""
mi_lista = [1, 1, 1, 1, 1, 1, 1, 1]
# print(len(mi_lista))
class Objeto:
pass
mi_objeto = Objeto()
# No se puede aplicar len
# print(len(mi_objeto))
# Tampoco podemos ver el objeto
# print(mi_objeto)
# Otro ejemplo
class CD:
def __init__(self, autor, titulo, canciones):
self.autor = autor
self.titulo = titulo
self.canciones = canciones
# Vamos a modif el comportamiento del método especial __str__
# cada vez que se llame para mostrar lo que se quiera
def __str__(self):
return f'Albun: {self.titulo} de {self.autor}'
# Comportamiento de len
def __len__(self):
return self.canciones
# Podemos añadir un mensaje cuando usemos la función del
def __del__(self):
print("Se ha eliminado el cd")
mi_cd = CD('Pink Floyd', 'The Wall', 24)
# Ahora sí que veremos el return modificado
print(mi_cd)
# También len, hemos modificado su uso para
# que muestre el número de canciones
print(len(mi_cd))
# Podemos eliminar con la función del
del mi_cd
# Si lo intentamos imprimir nos dirá que no existe
# print(mi_cd)

View File

@@ -0,0 +1,167 @@
"""
Programa día 7 - Cuenta bancaria
ESTAFA BANK
"""
import os
""" Variables """
limpiar = 'clear'
sleep = 'sleep 2'
""" Clases """
class Persona:
# Atributos: nombre y apellido
def __init__(self, nombre, apellido):
self.nombre = nombre
self.apellido = apellido
class Cliente(Persona):
# atributos propios: número de cuenta y balance
# es decir, el saldo que tiene en su cuenta bancaria.
def __init__(self, nombre, apellido, num_cuenta, balance):
super().__init__(nombre, apellido)
self.num_cuenta = num_cuenta
self.balance = float(round(balance, 2))
# tres métodos
# # método especial que permite que podamos imprimir a nuestro cliente
def __str__(self):
return f'*** CLIENTE ESTAFA BANK ***\n\n\tCliente: \t{self.nombre} {self.apellido}\n\tNº Cuenta: \t{self.num_cuenta}\n\tBalance: \t{self.balance} pesos'
# # Método Depositar que permita decidir cuánto dinero quiere agregar a su cuenta
def depositar(self, cantidad_ingreso):
self.balance += cantidad_ingreso
self.balance = round(self.balance, 2)
print(
f'\nHa ingresado {cantidad_ingreso} Pesos.\n')
# # Método llamado Retirar que permita decidir cuánto dinero quiere sacar de su cuenta
def retirar(self, cantidad_a_retirar):
if (self.balance - cantidad_a_retirar) < 0:
print(
f'\nDisculpa, no tienes tanto dinero.\nBalance: {self.balance} pesos')
else:
self.balance -= cantidad_a_retirar
self.balance = round(self.balance, 2)
print(
f'\nHa retirado {cantidad_a_retirar} Pesos.\n')
""" Funciones """
def clearConsole():
# Función limpiar consola
os.system(limpiar)
def bienvenida():
clearConsole()
# bienvenida al usuario
print(
'\n',
'#' * 39,
'\n # Bienvenid@ a tu cuenta bancaria #\n',
'#' * 39)
os.system(sleep)
clearConsole()
# Iniciar programa pidiendo datos del cliente
crear_cliente()
# Pedir operaciones a realizar - PROGRAMA
operaciones()
def despedida():
clearConsole()
print('Gracias por usar los servicios de ESTAFA BANK, su banco sincero.\n\n¡Ciao!\n')
def crear_cliente():
nombre_cliente = input("Dime tu nombre: ")
apellido_cliente = input("Dime tu/s apelludo/s: ")
global cliente1
cliente1 = Cliente(
nombre_cliente,
apellido_cliente,
'324789563417896324',
0)
def operaciones():
# PROGRAMA
# Pedir al usuario que elija si quiere hacer depósitos o retiros.
operacion = ''
while operacion.lower() != 's':
print(
f'\n',
cliente1,
'\n\n Indicar la operación a realizar:\n',
'\n\t- i\t-->\tIngresar'
'\n\t- r\t-->\tRetirar'
'\n\t- s\t-->\tSalir\n')
operacion = input()
operacion = operacion.lower()
if operacion == "i":
cantidad_a_ingresar = preguntar_cantidad('ingresar')
cliente1.depositar(cantidad_a_ingresar)
continue
elif operacion == "r":
cantidad_a_retirar = preguntar_cantidad('retirar')
cliente1.retirar(cantidad_a_retirar)
continue
elif operacion == "s":
break
else:
clearConsole()
print('Disculpa, ingresa un valor valido\n')
continue
despedida()
def preguntar_cantidad(ope):
clearConsole()
print(
f'\nSu balance actual es de {cliente1.balance} Pesos.\n\n',
f'¿Qué cantidad quiere {ope}?')
cantidad = input()
cantidad = round(float(cantidad), 2)
return cantidad
""" Programa - Se inicia a través de la función de bienvenida """
# Bienvenida e iniciar programa
bienvenida()

View File

@@ -0,0 +1,237 @@
# Día 7 - Programa una cuenta bancaria
Principios de la programación orientada a objetos (POO):
- Herencia
- Polimorfismo
- Cohesión
- Abstracción
- Acoplamiento
- Encapsulamiento
## Índice
- [Día 7 - Programa una cuenta bancaria](#día-7---programa-una-cuenta-bancaria)
- [Índice](#índice)
- [7.1. - Clases](#71---clases)
- [7.2. - Atributos](#72---atributos)
- [7.3. - Métodos](#73---métodos)
- [7.4. - Tipos de métodos](#74---tipos-de-métodos)
- [7.5. - Herencia](#75---herencia)
- [7.6. - Herencia extendida](#76---herencia-extendida)
- [7.7. - Polimorfismo](#77---polimorfismo)
- [7.8. - Pilares de la Programación Orientada a Objetos](#78---pilares-de-la-programación-orientada-a-objetos)
- [7.9. - Métodos especiales](#79---métodos-especiales)
- [7.10. - Proyecto del Día 7](#710---proyecto-del-día-7)
- [Ficheros y documentación](#ficheros-y-documentación)
## 7.1. - Clases
Python es un lenguaje de Programación Orientado a Objetos (POO). Como tal, utiliza y manipula objetos, a través de sus métodos y propiedades. Las clases son las herramientas que nos permiten crear objetos, que "empaquetan" datos y funcionalidad juntos.
Podemos pensar a las clases como el "plano" o "plantilla" a partir del cual podemos crear objetos individuales, con propiedades y métodos asociados:
![](../img/dia07_01.png)
Las clases se definen con la palabra reservada `class`, seguida del nombre de la clase, y dos puntos. Por convención, los nombres de las clases se escriben con la primera letra en mayúscula, y el resto en minúsculas. Por ejemplo, `MiClase`.
## 7.2. - Atributos
Los atributos son variables que pertenecen a la clase. Existen **atributos de clase** (compartidos por todas las instancias de la clase), **y de instancia** (que son distintos en cada instancia de la clase).
![](../img/dia07_02.png)
Todas las clases tienen una función que se ejecuta al instanciarla, llamada `__init__()`, y que se utiliza para asignar valores a las propiedades del objeto que está siendo creado. self: representa a la instancia del objeto que se va a crear.
## 7.3. - Métodos
Los objetos creados a partir de clases también contienen métodos. Dicho de otra manera, los métodos son funciones que pertenecen al objeto.
```python
class Persona:
especie = "humano"
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def saludar(self):
print(f'Hola, mi nombre es {self.nombre}')
def cumplir_anios(self, estado_humor):
print(f'Cumplir {self.edad + 1} años me pone {estado_humor}')
juan = Persona("Juan", 37)
juan.saludar()
juan.cumplir_anios("feliz")
```
Hola, mi nombre es Juan
Cumplir 38 años me pone feliz
Cada vez que un atributo del objeto sea invocado (por ejemplo, en una función), debe incluirse self, que refiere a la instancia en cuestión, indicando la pertenencia de este atributo.
## 7.4. - Tipos de métodos
Los métodos estáticos y de clase anteponen un decorador específico, que indica a Python el tipo de método que se estará definiendo
| | | @classmethod | @staticmethod |
| -------------------------------------------: | :------------------: | :--------------: | :---------------: |
| | Métodos de instancia | Métodos de clase | Métodos estáticos |
| Acceso a métodos y atrbitutos de la clase | Sí | Sí | No |
| Requiere una instancia | Sí | No | No |
| Acceso a métodos y atributos de la instancia | Sí | No | No |
Así como los métodos de instancia requieren del parámetro **self** para acceder a dicha instancia, los métodos de clase requieren del parámetro **cls** para acceder a los atributos de clase. Los métodos estáticos, dado que no pueden acceder a la instancia ni a la clase, no indican un parámetro semejante.
Resumen sobre Decoradores:
- **Métodos de instancia**:
```python
def mi_metodo(self):
print('algo')
mi_metodo
```
- Acceden y modifican atributos del objeto.
- Acceden a otro métodos.
- Pueden modificar el estado de la clase.
- **Métodos de clase** - *@classmethod*:
```python
def mi_metodo(cls):
print('algo')
```
- No están asociados a las instancias de la clase, sino a la clase en si misma
- Pueden ser llamados desde la instancia y desde la clase
- No pueden acceder a los atributos de instancia pero si a los de la clase
- **Métodos estáticos** - *@staticmethod*:
```python
def mi_metodo():
print('algo')
```
- No acepta como parámetro ni self ni cls
- No pueden modificar ni el estado de la clase ni de la instancia
- Pueden aceptar parámetros de entrada
## 7.5. - Herencia
La herencia es el proceso mediante el cual una clase puede tomar métodos y atributos de una clase superior, evitando repetición del código cuando varias clases tienen atributos o métodos en común.
Es posible crear una clase "hija" con tan solo pasar como parámetro la clase de la que queremos heredar:
```python
class Personaje:
def __init__(self, nombre, herramienta):
self.nombre = nombre
self.arma = arma
class Mago(Personaje):
pass
hechicero = Mago("Merlín", "caldero")
```
Una clase "hija" puede sobreescribir los métodos o atributos, así como definir nuevos, que sean específicos para esta clase.
## 7.6. - Herencia extendida
Las clases "hijas" que heredan de las clases superiores, pueden crear nuevos métodos o sobrescribir los de la clase "padre". Asimismo, una clase "hija" puede heredar de una o más clases, y a su vez transmitir herencia a clases "nietas".
Si varias superclases tienen los mismos atributos o métodos, la subclase sólo podrá heredar de una de ellas. En estos casos Python dará prioridad a la clase que se encuentre más a la izquierda.
Del mismo modo, si un mismo método se hereda por parte de la clase "padre", e "hija", la clase "nieta" tendrá preferencia por aquella más próxima ascendente (siguiendo nuestro esquema, la tomará de la clase "hija").
![](../img/dia07_03.png)
**`Clase.__mro__`** - devuelve el orden de resolución de métodos
**`super().__init__(arg1, arg2,...)`** - hereda atributos de las superclases de manera compacta
## 7.7. - Polimorfismo
El polimorfismo es el pilar de la POO mediante el cual un mismo método puede comportarse de diferentes maneras según el objeto sobre el cual esté actuando, en función de cómo dicho método ha sido creado para la clase en particular.
El método len( ) funciona en distintos tipos de objetos: listas, tuplas, strings, entre otros. Esto se debe a que para Python, lo importante no son los tipos de objetos, sino lo que pueden hacer: sus métodos.
```python
class Perro:
def hablar(self):
print("Guau!")
class Gato:
def hablar(self):
print("Miau!")
hachiko = Perro()
garfield = Gato()
for animal in [hachiko, garfield]:
animal.hablar()
```
Guau!
Miau!
## 7.8. - Pilares de la Programación Orientada a Objetos
Se ha visto Herencia y Polimorfismo en las prácticas anteriores. Información conceptual del resto:
- Cohesión: https://escueladirecta-blog.blogspot.com/2021/09/cohesion-pilares-de-la-programacion.html
- Acoplamiento: https://escueladirecta-blog.blogspot.com/2021/10/acoplamiento-pilares-de-la-programacion.html
- Abstracción: https://escueladirecta-blog.blogspot.com/2021/10/abstraccion-pilares-de-la-programacion.html
- Encapsulamiento: https://escueladirecta-blog.blogspot.com/2021/10/encapsulamiento-pilares-de-la.html
## 7.9. - Métodos especiales
Puedes encontrarlos con el nombre de métodos mágicos o dunder methods (del inglés: dunder = double underscore, o doble guión bajo). Pueden ayudarnos a sobrescribir métodos incorporados de Python sobre nuestras clases para controlar el resultado devuelto.
```python
class Libro:
def __init__(self, autor, titulo, cant_paginas):
self.autor = autor
self.titulo = titulo
self.cant_paginas = cant_paginas
def __str__(self):
return f'Título: "{self.titulo}", escrito por {self.autor}'
def __len__(self):
return self.cant_paginas
libro1 = Libro("Stephen King", "It", 1032)
print(str(libro1))
print(len(libro1))
```
Título: "It", escrito por Stephen King
1032
## 7.10. - Proyecto del Día 7
Crear un código que le permita a una persona realizar operaciones en su cuenta bancaria. No te asustes que la consigna va a estar bien definida para que puedas hacerlo en poco tiempo.
Primero vas a crear una clase llamada Persona, y Persona va a tener solo dos atributos: nombre y apellido. Luego, vas a crear una segunda clase llamada Cliente, y Cliente va a heredar de Persona, porque los clientes son personas, por lo que el Cliente va a heredar entonces los atributos de Persona, pero también va a tener atributos propios, como número de cuenta y balance, es decir, el saldo que tiene en su cuenta bancaria.
Pero eso no es todo: Cliente también va a tener tres métodos. El primero va a ser uno de los métodos especiales y es el que permite que podamos imprimir a nuestro cliente. Este método va a permitir que cuando el código pida imprimir Cliente, se muestren todos sus datos, incluyendo el balance de su cuenta. Luego, un método llamado Depositar, que le va a permitir decidir cuánto dinero quiere agregar a su cuenta. Y finalmente, un tercer método llamado Retirar, que le permita decidir cuánto dinero quiere sacar de su cuenta.
Una vez que hayas creado estas dos clases, tienes que crear el código para que tu programa se desarrolle, pidiéndole al usuario que elija si quiere hacer depósitos o retiros. El usuario puede hacer tantas operaciones como quiera hasta que decida salir del programa. Por lo tanto, nuestro código tiene que ir llevando la cuenta de cuánto dinero hay en el balance, y debes procurar, por supuesto, que el cliente nunca pueda retirar más dinero del que posee. Esto no está permitido.
Recuerda que ahora que sabes crear clases y objetos que son estables y que retienen información, no necesitas crear funciones que devuelvan el balance, ya que la instancia de cliente puede saber constantemente cuál es su saldo debido a que puede hacer sus operaciones llamando directamente a este atributo y no a una variable separada.
Para que tu programa funcione, puedes organizar tu código como quieras, hay muchas formas de hacerlo, pero mi recomendación es que básicamente, luego de crear las dos clases que te he mencionado, crees dos funciones una que se encarguen de crear al cliente pidiéndole al usuario toda la información necesaria y devolviendo, a través del return, un objeto cliente ya creado.
La otra función (que puede llamarse inicio, o algo por el estilo), es la función que organiza la ejecución de todo el código: primero llama a la función “crear cliente” y luego se encarga de mantener al usuario en un loop que le pregunte todo el tiempo si quiere depositar, retirar o salir del programa y demostrarle el balance, cada vez que haga una modificación.
Para que este programa no se te haga súper largo o complejo, te propongo que esta vez no nos fijemos tanto en los controles, para ver si el usuario ha puesto opciones permitidas o no, si ha puesto números o no, si ha puesto mayúsculas o minúsculas, y creemos el código confiando en que el usuario va a ingresar siempre información apropiada. Por supuesto que si tú prefieres incluir todos esos controles, está genial.
## Ficheros y documentación
- [01_clases.py](01_clases.py)
- [02_atributos.py](02_atributos.py)
- [03_metodos.py](03_metodos.py)
- [04_tipos_metodos.py](04_tipos_metodos.py)
- [05_herencia.py](05_herencia.py)
- [06_herencia_extendida.py](06_herencia_extendida.py)
- [07_polimorfismo.py](07_polimorfismo.py)
- [08_metodos_especiales.py](08_metodos_especiales.py)
- [09_programa07.py](09_programa07.py)
[Documentación del día](../doc_curso/07_cuenta_bancaria/)
---
Enlaces a todos los días: [dia 1 - creador de nombres](../dia_01/README.md) / [dia 2 - calculador de comisiones](../dia_02/README.md) / [dia 3 - analizador de texto](../dia_03/README.md) / [dia 4 - juego "adivina el número"](../dia_04/README.md) / [dia 5 - juego "El ahorcado"](../dia_05/README.md) / [dia 6 - recetario](../dia_06/README.md) / [dia 7 - cuenta bancaria](../dia_07/README.md) / [dia 8 - consola de turnos](../dia_08/README.md) / [dia 9 - buscador de números de serie](../dia_09/README.md) / [dia 10 - juego "Invasión espacial"](../dia_10/README.md) / [dia 11 - web scraping](../dia_11/README.md) / [dia 12 - gestor de restaurantes](../dia_12/README.md) / [dia 13 - asistente de voz](../dia_13/README.md) / [dia 14 - controlador de asistencia](../dia_14/README.md) / [dia 15 - machine learning](../dia_15/README.md) / [dia 16 - aplicación web de tareas pendientes](../dia_16/README.md)