Curso Python. Volumen XII: Solución a las propuestas de programación orientada a objetos
![curso de python online](https://www.redeszone.net/app/uploads-redeszone.net/2017/02/curso-de-python-online.jpg)
Bienvenidos un día más al curso de Python, hoy vamos a dar las soluciones a las propuestas que os hemos ido haciendo desde que nos hemos aventurado en la programación Orientada a Objetos. Hemos explicado la herencia y además también vimos cómo guardar los datos en un fichero, de modo que después podamos recuperarlos. Así que pongámonos manos a la obra.
Empecemos por nuestra clase principal para las cuentas:
class Cuenta(object):
def __init__(self,numeroCuenta,cantidad=0.0):
self._numCuenta=numeroCuenta
self._saldo = cantidad
def sacarDinero(self, cantidad):
self._saldo -= cantidad
def ingresarDinero(self, cantidad):
self._saldo += cantidad
def getSaldo(self):
return self._saldo
def getNumeroCuenta(self):
return self._numCuenta
Hemos tenido que modificar la definición de sus atributos, ahora tiene solo un «_», esto es porque antes tenían doble y así se hacen privadas, y de este modo son protegidas. Os estaréis preguntando: ¿qué es eso de privadas y protegidas?. Cuando definimos los atributos y los métodos en programación orientada objetos podemos definir su visibilidad en el resto de la aplicación, hay tres niveles de visibilidad:
- Público: Lo ve toda la aplicación, los métodos se suelen definir públicos.
- Protegido: Sólo es visible por la propia clase y sus hijas, se suele usar cuando sólo queremos que sea visible mediante la herencia, es decir por las clases hijas.
- Privado: Sólo es visible dentro de la propia clase, para poder acceder a estos atributos lo hacemos mediante los métodos «get» y «set» que habéis visto que he ido creando.
Lo normal es que se creen privadas, y que se utilicen métodos para poder cambiar sus valores de manera controlada, en este caso he preferido hacerlas protegidas ya que estaremos manejando las clases hijas.
Las dos clases hijas quedaron del siguiente modo:
CuentaCorriente
from cuenta import Cuenta
from persona import Persona
class CuentaCorriente(Cuenta):
def __init__(self,nombre,apellidos,numeroCuenta,cantidad, tipo=0.0,tarjetaDebito=False,tarjetaCredito=False,cuota=0.0):
Cuenta.__init__(self, numeroCuenta, cantidad)
self.__tipoInteres = 1 + float(tipo)
self.__tarjetaDebito = tarjetaDebito
self.__tarjetaCredito = tarjetaCredito
self.__cuotaMantenimiento = cuota
self.__persona = Persona(nombre, apellidos)
def getTipoInteres(self):
return self.__tipoInteres
def setTipoInteres(self, interes):
self.__tipoInteres = interes
def getTarjetaDebito(self):
return self.__tarjetaDebito
def setTarjetaDebito(self, tarjeta):
self.__tarjetaDebito = tarjeta
def getTarjetaCredito(self):
return self.__tarjetaCredito
def setTarjetaCredito(self, tarjeta):
self.__tarjetaCredito = tarjeta
def getCuotaMantenimiento(self):
return self.__cuotaMantenimiento
def setCuotaMantenimiento(self, cuota):
self.__cuotaMantenimiento = cuota
def getSaldo(self):
return self._1saldo*self.__tipoInteres
def setNombre(self, nombre):
self.__persona.setNombre(nombre)
def getNombre(self):
return self.__persona.getNombre()
def setApellido(self, apellido):
self.__persona.setApellido(apellido)
def getApellido(self):
return self.__persona.getApellido()
CuentaAhorro
from cuenta import Cuenta
from persona import Persona
class CuentaAhorro(Cuenta):
def __init__(self,nombre,apellidos,numeroCuenta, cantidad, fecha, tipo=0.0):
Cuenta.__init__(self, numeroCuenta, cantidad)
self.__tipoInteres = 1 + tipo
self.__fechaApertura = fecha
self.__persona= Persona(nombre,apellidos)
def getTipoInteres(self):
return self.__tipoInteres
def setTipoInteres(self, interes):
self.__tipoInteres = interes
def getFecha(self):
return self.__fechaApertura
def getTipoInteres(self):
return self.__tipoInteres
def setTipoInteres(self, interes):
self.__tipoInteres = interes
def getSaldo(self):
return self._saldo * self.__tipoInteres
def setNombre(self, nombre):
self.__persona.setNombre(nombre)
def getNombre(self):
return self.__persona.getNombre()
def setApellido(self, apellido):
self.__persona.setApellido(apellido)
def getApellido(self):
return self.__persona.getApellido()
Como podéis comprobar, ahora las cuentas contienen un atributo persona, de modo que damos importancia a la cuenta y el atributo persona es para saber a quién le pertenece. He cambiado el punto de vista ya que realmente el banco tiene cuentas y no personas. A su vez las cuentas pertenecen a personas, de ahí que uno de sus atributos sean personas.
De lo anterior se deduce que la clase «Persona» ha sufrido cambios, ya que ha dejado de tener una cuenta asociada.
class Persona(object):
def __init__(self,nombre,apellido):
self.__nombre = nombre
self.__apellido = apellido
def setNombre(self, nombre):
self.__nombre = nombre
def getNombre(self):
return self.__nombre
def setApellido(self, apellido):
self.__apellido = apellido
def getApellido(self):
return self.__apellido
A efectos de funcionalidad de la aplicación no ha cambiado nada. Lo único que ha cambiado es la manera de ordenar los datos.
Por último os presento el código de la aplicación principal:
from persona import Persona
from cuentaAhorro import CuentaAhorro
from cuentaCorriente import CuentaCorriente
import time
import pickle
import os
import sys
numCuentas = 0
clientes = []
opcion = 0
def abrirCuenta(numCuentas):
opcion = input('''Por favor seleccione un tipo de cuenta:
1 Cuenta Corriente
2 Cuenta de Ahorro
3 Atras
''')
if opcion == '1':
nombre = input('''Nombre: ''')
apellidos = input('''Apellidos: ''')
cantidad= input('''Ingreso inicial: ''')
tipoInteres= input('''Tipo de interes: ''')
tarjetaDeb = input('''Tarjeta de Debito(1-Si,0-No): ''')
if tarjetaDeb==1:
tarjetaDebito=True
else:
tarjetaDebito=False
tarjetaCre = input('''Tarjeta de Credito(1-Si,0-No): ''')
if tarjetaCre == 1:
tarjetaCredito = True
else:
tarjetaCredito = False
cuotaMantenimiento=input('''Cuota de Mantenimiento: ''')
personaAux = CuentaCorriente(nombre, apellidos, numCuentas,float(cantidad),float(tipoInteres),tarjetaDebito,tarjetaCredito,float(cuotaMantenimiento))
return personaAux
elif opcion == '2':
nombre = input('''Nombre: ''')
apellidos = input('''Apellidos: ''')
cantidad = input('''Ingreso inicial: ''')
tipoInteres = input('''Tipo de interes: ''')
fecha=time.strftime("%d/%m/%y")
personaAux = CuentaAhorro(nombre,apellidos,numCuentas, float(cantidad), fecha, float(tipoInteres))
return personaAux
elif opcion == '3':
return
try:
with open('cuentas.txt', 'rb') as f:
clientes = pickle.load(f)
except:
f= open('cuentas.txt', 'wb')
f.close()
while ('6' != opcion):
opcion = input('''Por favor seleccione una operacion:
1 Abrir una cuenta
2 Ver cuentas
3 Ver saldo
4 Hacer ingreso
5 Hacer retirada
6 Exit
''')
if opcion == '1':
clienteAux=abrirCuenta(numCuentas)
if clienteAux is not None:
clientes.append(clienteAux)
numCuentas += 1
elif opcion == '2':
for cliente in clientes:
print('Nombre: ' + cliente.getNombre())
print('Apellido: ' + cliente.getApellido())
print('Numero de Cuenta: ' + str(cliente.getNumeroCuenta()))
print('n')
input("Pulse Enter para continuar...")
elif opcion == '3':
cuenta = input('Por favor indique el numero de cuenta:')
print('El saldo de la cuenta ' +cuenta+' es de: '+str(clientes[int(cuenta)].getSaldo())+' Euros')
input("Pulse Enter para continuar...")
os.system('cls')
elif opcion == '4':
cuenta = input('Por favor indique el numero de cuenta al que desea hacer el ingreso:')
cantidad = input('Por favor indique la cantidad a ingresar:')
clientes[int(cuenta)].ingresarDinero(int(cantidad))
print('Se ha realizado el ingreso')
input("Pulse Enter para continuar...")
os.system('cls')
elif opcion == '5':
cuenta = input('Por favor indique el numero de cuenta al que desea hacer el ingreso:')
cantidad = input('Por favor indique la cantidad a retirar:')
clientes[int(cuenta)].sacarDinero(float (cantidad))
print('Se ha realizado la retirada')
input("Pulse Enter para continuar...")
os.system('cls')
with open('cuentas.txt', 'wb') as f:
pickle.dump(clientes, f)
print('Fin del programa')
Como podéis comprobar hemos vuelto hacer uso de «pickle» para el manejo de ficheros. También hemos añadido un bloque que es un «try…except…» esto se hace para controlar las excepciones, en este caso es porque si el fichero no existe se creé uno. Aunque ya os explicaremos como se utiliza el bloque «try…except»
Esto es todo por hoy, os invitamos a que repaséis la solución de la programación orientada a objetos e intentéis entenderla. Apoyaros en los capítulos anteriores ya que todo lo expuesto ha sido utilizado y explicado anteriormente. Si aun así seguís teniendo dudas sobre el código que os acabamos de presentar, exponerlas en los comentarios e intentaremos contestar a todas ellas.
Os recomendamos visitar nuestro curso online de Python para leer todas y cada una de las entregas que tenemos hasta ahora.