from datetime import datetime
from typing import List, Dict
class CuentaBancaria:
"""
Clase que representa una cuenta bancaria con encapsulamiento adecuado.
Atributos:
__saldo (float): Saldo actual de la cuenta (privado)
__transacciones (List[Dict]): Historial de transacciones (privado)
_titular (str): Nombre del titular de la cuenta (protegido)
_numero_cuenta (str): Número de identificación de la cuenta (protegido)
"""
def __init__(self, titular: str, numero_cuenta: str, saldo_inicial: float = 0.0):
"""
Inicializa una cuenta bancaria.
Args:
titular: Nombre del titular de la cuenta
numero_cuenta: Número de identificación de la cuenta
saldo_inicial: Saldo inicial de la cuenta (por defecto 0.0)
"""
self._titular = titular
self._numero_cuenta = numero_cuenta
self.__saldo = saldo_inicial
self.__transacciones = []
# Registrar el saldo inicial si es mayor a 0
if saldo_inicial > 0:
self.__registrar_transaccion("Apertura de cuenta", saldo_inicial, "deposito")
def consultar_saldo(self) -> float:
"""
Método público para consultar el saldo actual.
Returns:
El saldo actual de la cuenta
"""
return self.__saldo
def _actualizar_saldo(self, monto: float, tipo: str) -> bool:
"""
Método protegido para actualizar el saldo de la cuenta.
Puede ser usado por clases derivadas.
Args:
monto: Cantidad a modificar el saldo
tipo: Tipo de operación ('deposito' o 'retiro')
Returns:
True si la operación fue exitosa, False en caso contrario
"""
if tipo == "deposito":
self.__saldo += monto
return True
elif tipo == "retiro":
if self.__saldo >= monto:
self.__saldo -= monto
return True
else:
return False
return False
def __registrar_transaccion(self, descripcion: str, monto: float, tipo: str):
"""
Método privado para registrar las transacciones internamente.
Solo accesible dentro de esta clase.
Args:
descripcion: Descripción de la transacción
monto: Monto de la transacción
tipo: Tipo de transacción ('deposito' o 'retiro')
"""
transaccion = {
'fecha': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'descripcion': descripcion,
'monto': monto,
'tipo': tipo,
'saldo_resultante': self.__saldo
}
self.__transacciones.append(transaccion)
def depositar(self, monto: float, descripcion: str = "Depósito") -> bool:
"""
Método público para realizar un depósito.
Args:
monto: Cantidad a depositar
descripcion: Descripción del depósito
Returns:
True si el depósito fue exitoso, False en caso contrario
"""
if monto <= 0:
print(" Error: El monto debe ser positivo")
return False
if self._actualizar_saldo(monto, "deposito"):
self.__registrar_transaccion(descripcion, monto, "deposito")
print(f" Depósito exitoso: ${monto:.2f}")
return True
return False
def retirar(self, monto: float, descripcion: str = "Retiro") -> bool:
"""
Método público para realizar un retiro.
Args:
monto: Cantidad a retirar
descripcion: Descripción del retiro
Returns:
True si el retiro fue exitoso, False en caso contrario
"""
if monto <= 0:
print(" Error: El monto debe ser positivo")
return False
if self._actualizar_saldo(monto, "retiro"):
self.__registrar_transaccion(descripcion, monto, "retiro")
print(f" Retiro exitoso: ${monto:.2f}")
return True
else:
print(" Error: Saldo insuficiente")
return False
def ver_historial(self, ultimas: int = None):
"""
Muestra el historial de transacciones.
Args:
ultimas: Número de últimas transacciones a mostrar (None para todas)
"""
if not self.__transacciones:
print(" No hay transacciones registradas")
return
transacciones_mostrar = self.__transacciones[-ultimas:] if ultimas else self.__transacciones
print("\n" + "="*70)
print(f" HISTORIAL DE TRANSACCIONES - {self._titular}")
print(f"Cuenta: {self._numero_cuenta}")
print("="*70)
for trans in transacciones_mostrar:
simbolo = "+" if trans['tipo'] == "deposito" else "-"
print(f"\n {trans['fecha']}")
print(f" {trans['descripcion']}")
print(f" Monto: {simbolo}${trans['monto']:.2f}")
print(f" Saldo resultante: ${trans['saldo_resultante']:.2f}")
print("="*70 + "\n")
def ver_resumen(self):
"""
Muestra un resumen de la cuenta bancaria.
"""
total_depositos = sum(t['monto'] for t in self.__transacciones if t['tipo'] == 'deposito')
total_retiros = sum(t['monto'] for t in self.__transacciones if t['tipo'] == 'retiro')
print("\n" + "="*50)
print(" RESUMEN DE CUENTA")
print("="*50)
print(f"Titular: {self._titular}")
print(f"Número de cuenta: {self._numero_cuenta}")
print(f"Saldo actual: ${self.__saldo:.2f}")
print(f"\nTotal depositado: ${total_depositos:.2f}")
print(f"Total retirado: ${total_retiros:.2f}")
print(f"Transacciones realizadas: {len(self.__transacciones)}")
print("="*50 + "\n")
# Ejemplo de uso
if __name__ == "__main__":
# Crear una cuenta bancaria
cuenta = CuentaBancaria("Juan Pérez", "1234567890", 1000.0)
# Mostrar resumen inicial
cuenta.ver_resumen()
# Realizar operaciones
cuenta.depositar(500, "Pago de salario")
cuenta.retirar(200, "Compra en supermercado")
cuenta.depositar(150, "Transferencia recibida")
cuenta.retirar(2000, "Intento de retiro excesivo") # Fallará
# Consultar saldo
print(f"\n Saldo actual: ${cuenta.consultar_saldo():.2f}\n")
# Ver historial completo
cuenta.ver_historial()
# Ver solo las últimas 3 transacciones
cuenta.ver_historial(ultimas=3)
# Ver resumen final
cuenta.ver_resumen()