Système bancaire
Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 62 sur 64.
Défi
DifficileDans ce défi, vous allez construire un système bancaire avec plusieurs types de comptes, des transactions et un gestionnaire de banque centrale.
Implémentez le système bancaire en complétant les éléments TODO dans ces fichiers :
transaction.py- Classe Transaction pour l'enregistrement des activités financièresaccount.py- Classe de base abstraite Account avec les fonctionnalités communessavingsaccount.py- Implémentation de SavingsAccount avec intérêts et solde minimumcheckingaccount.py- Implémentation de CheckingAccount avec des capacités de découvertbank.py- Classe Bank pour gérer les comptes et les transferts
Aide-mémoire
Ce défi consiste à construire un système bancaire avec des concepts de programmation orientée objet, notamment :
- Classe Transaction - Enregistre les activités financières
- Classe abstraite Account - Classe de base avec des fonctionnalités de compte communes
- SavingsAccount - Type de compte avec calcul d'intérêts et exigences de solde minimum
- CheckingAccount - Type de compte avec des capacités de protection contre les découverts
- Classe Bank - Gestionnaire central pour les comptes et les transferts d'argent
Les concepts clés incluent l'héritage, l'abstraction, l'encapsulation et le polymorphisme pour créer une architecture de système bancaire modulaire.
Essayez vous-même
from transaction import Transaction
from account import Account
from savingsaccount import SavingsAccount
from checkingaccount import CheckingAccount
from bank import Bank
# Gestionnaire de cas de test complet couvrant tous les scénarios et cas limites
test_case = input()
if test_case == "transaction_class":
# Tester la classe Transaction
transaction = Transaction("deposit", 100.50, None)
print(str(transaction))
transaction = Transaction("withdrawal", 75.25, None)
print(str(transaction))
elif test_case == "account_deposit":
# Tester la fonctionnalité de dépôt
savings = SavingsAccount("S123", "John Doe", 500)
# Montant positif
success, message = savings.deposit(200)
print(f"Success: {success}")
print(f"Message: {message}")
print(f"Balance: ${savings.get_balance():.2f}")
# Montant négatif (devrait échouer)
success, message = savings.deposit(-50)
print(f"Success: {success}")
print(f"Message: {message}")
elif test_case == "savings_withdraw":
# Tester le retrait d'un compte d'épargne
savings = SavingsAccount("S123", "John Doe", 500, min_balance=200)
# Retrait valide
success, message = savings.withdraw(100)
print(f"Success: {success}")
print(f"Message: {message}")
# Invalide (en dessous du solde minimum)
success, message = savings.withdraw(300)
print(f"Success: {success}")
print(f"Message: {message}")
# Montant négatif
success, message = savings.withdraw(-50)
print(f"Success: {success}")
print(f"Message: {message}")
elif test_case == "checking_withdraw":
# Tester le retrait d'un compte courant
checking = CheckingAccount("C123", "Jane Smith", 300, overdraft_limit=200)
# Retrait normal
success, message = checking.withdraw(100)
print(f"Success: {success}")
print(f"Message: {message}")
# Retrait avec découvert
success, message = checking.withdraw(300)
print(f"Success: {success}")
print(f"Message: {message}")
# Dépassement de la limite de découvert
success, message = checking.withdraw(200)
print(f"Success: {success}")
print(f"Message: {message}")
elif test_case == "interest_application":
# Tester l'application des intérêts
savings = SavingsAccount("S123", "John Doe", 1000, interest_rate=0.05)
success, message = savings.apply_interest()
print(f"Success: {success}")
print(f"Message: {message}")
print(f"New Balance: ${savings.get_balance():.2f}")
# Vérifier l'historique des transactions
transactions = savings.get_transaction_history()
print(f"Transaction count: {len(transactions)}")
print(f"Last transaction: {transactions[-1]}")
elif test_case == "bank_create_account":
# Tester la création de compte bancaire
bank = Bank("Test Bank")
# Créer un compte d'épargne
success, message = bank.create_account("savings", "S123", "John Doe", 1000, interest_rate=0.03)
print(f"Success: {success}")
print(f"Message: {message}")
# Créer un compte courant
success, message = bank.create_account("checking", "C456", "Jane Smith", 500, overdraft_limit=300)
print(f"Success: {success}")
print(f"Message: {message}")
# Créer avec un numéro de compte en double
success, message = bank.create_account("savings", "S123", "Another Person", 200)
print(f"Success: {success}")
print(f"Message: {message}")
# Créer avec un type invalide
success, message = bank.create_account("invalid", "I789", "Test Person", 100)
print(f"Success: {success}")
print(f"Message: {message}")
elif test_case == "bank_transfer":
# Tester la fonctionnalité de transfert bancaire
bank = Bank("Transfer Test Bank")
# Créer deux comptes
bank.create_account("savings", "S123", "John Doe", 1000, min_balance=100)
bank.create_account("checking", "C456", "Jane Smith", 500)
# Transfert valide
success, message = bank.transfer("S123", "C456", 300)
print(f"Success: {success}")
print(f"Message: {message}")
print(f"Source balance: ${bank.get_account('S123').get_balance():.2f}")
print(f"Destination balance: ${bank.get_account('C456').get_balance():.2f}")
# Transfert invalide (dépasse le solde minimum)
success, message = bank.transfer("S123", "C456", 700)
print(f"Success: {success}")
print(f"Message: {message}")
# Compte invalide
success, message = bank.transfer("NONEXISTENT", "C456", 100)
print(f"Success: {success}")
print(f"Message: {message}")
elif test_case == "full_banking_workflow":
# Tester un flux de travail complet
bank = Bank("Full Workflow Bank")
# Créer des comptes
bank.create_account("savings", "S123", "John Doe", 1000, interest_rate=0.05, min_balance=200)
bank.create_account("checking", "C456", "Jane Smith", 500, overdraft_limit=250)
# Effectuer des dépôts
savings = bank.get_account("S123")
checking = bank.get_account("C456")
savings.deposit(300)
checking.deposit(200)
# Effectuer un transfert
bank.transfer("S123", "C456", 400)
# Appliquer les intérêts à l'épargne
savings.apply_interest()
# Effectuer un retrait du compte courant avec découvert
checking.withdraw(900)
# Afficher l'état final
print("Final Account States:")
print(f"Savings (S123): ${savings.get_balance():.2f}")
print(f"Checking (C456): ${checking.get_balance():.2f}")
print("\nTransaction History (Savings):")
for transaction in savings.get_transaction_history():
print(f"- {transaction}")
print("\nTransaction History (Checking):")
for transaction in checking.get_transaction_history():
print(f"- {transaction}")
elif test_case == "inheritance_validation_test":
# Validation complète de l'héritage
objects = []
if 'Transaction' in locals():
objects.append(Transaction('test_param', 100, None))
if 'SavingsAccount' in locals():
objects.append(SavingsAccount('test_param', 'Test User'))
if 'CheckingAccount' in locals():
objects.append(CheckingAccount('test_param', 'Test User'))
if 'Bank' in locals():
objects.append(Bank('test_param'))
for obj in objects:
print(f'{type(obj).__name__}:')
print(f' MRO: {[cls.__name__ for cls in type(obj).__mro__]}')
print()
elif test_case == "method_overriding_test":
# Tester le comportement de la redéfinition de méthode
print('Testing method overriding...')
# Créer des instances et tester les méthodes redéfinies
if 'SavingsAccount' in locals():
obj = SavingsAccount('test', 'Test User')
print(f'SavingsAccount methods work correctly')
if 'CheckingAccount' in locals():
obj = CheckingAccount('test', 'Test User')
print(f'CheckingAccount methods work correctly')
elif test_case == "attribute_access_test":
# Tester l'accès aux attributs
print('Testing attribute access...')
if 'Transaction' in locals():
obj = Transaction('test', 100, None)
print(f'Transaction attributes accessible')
if 'SavingsAccount' in locals():
obj = SavingsAccount('test', 'Test User')
print(f'SavingsAccount attributes accessible')
if 'CheckingAccount' in locals():
obj = CheckingAccount('test', 'Test User')
print(f'CheckingAccount attributes accessible')
if 'Bank' in locals():
obj = Bank('test')
print(f'Bank attributes accessible')
elif test_case == "boundary_conditions_test":
# Tester les conditions aux limites et les valeurs critiques
print('Running boundary_conditions_test test...')
print('Test completed successfully')
elif test_case == "error_handling_test":
# Tester la gestion des erreurs et les scénarios d'exception
print('Running error_handling_test test...')
print('Test completed successfully')
elif test_case == "polymorphic_behavior_test":
# Tester le comportement polymorphe avec des objets mixtes
print('Running polymorphic_behavior_test test...')
print('Test completed successfully')
elif test_case == "stress_test":
# Test de charge avec plusieurs objets
import time
start_time = time.time()
objects = []
for i in range(50):
try:
objects.append(Transaction(f'test_{i}', 100, None))
except:
pass # Gérer les erreurs de création avec élégance
try:
objects.append(SavingsAccount(f'test_{i}', f'User_{i}'))
except:
pass # Gérer les erreurs de création avec élégance
try:
objects.append(CheckingAccount(f'test_{i}', f'User_{i}'))
except:
pass # Gérer les erreurs de création avec élégance
try:
objects.append(Bank(f'test_{i}'))
except:
pass # Gérer les erreurs de création avec élégance
end_time = time.time()
print(f'Created {len(objects)} objects')
print(f'Time taken: {end_time - start_time:.4f} seconds')
print('Stress test completed')
elif test_case == "comprehensive_validation":
# Test de validation complet
print('=== Comprehensive Validation Test ===')
# Test 1 : Création d'objets de base
print('1. Basic Object Creation:')
success_count = 0
classes = ['Transaction', 'SavingsAccount', 'CheckingAccount', 'Bank']
try:
obj = Transaction('test', 100, None)
success_count += 1
print(f' Transaction: Created successfully')
except Exception as e:
print(f' Transaction: Creation failed - {e}')
try:
obj = SavingsAccount('test', 'Test User')
success_count += 1
print(f' SavingsAccount: Created successfully')
except Exception as e:
print(f' SavingsAccount: Creation failed - {e}')
try:
obj = CheckingAccount('test', 'Test User')
success_count += 1
print(f' CheckingAccount: Created successfully')
except Exception as e:
print(f' CheckingAccount: Creation failed - {e}')
try:
obj = Bank('test')
success_count += 1
print(f' Bank: Created successfully')
except Exception as e:
print(f' Bank: Creation failed - {e}')
print(f' Successfully created {success_count}/{len(classes)} classes')
print('=== Validation Complete ===')Toutes les leçons de Object Oriented Programming
1Les fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe paramètre selfMéthodesAttributsMéthode constructeur (__init__)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLa fonction super()Redéfinition de méthodeHéritage multipleOrdre de résolution des méthodesRécapitulatif - Hiérarchie des employés7Méthodes spéciales
Introduction aux méthodes magiquesSurcharge d'opérateursMéthodes magiques de conteneurRécapitulatif - Liste personnalisée10Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy13Défis finaux
Plateforme d'e-learningSystème bancaireDéveloppement de personnages de jeuService de location de véhicules2Décorateurs
Introduction aux décorateursDécorateur de propriétéDécorateur de méthode statiqueDécorateur de méthode de classe5Polymorphisme
Retour sur la redéfinition de méthodeDuck TypingClasses et méthodes abstraitesConception d'interfacesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageMixinsMéthodes statiques et de classeDécorateurs de classeGestionnaires de contexte11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Propriétés de classe
Variables d'instance vs variables de classeDécorateurs de propriétéAttributs privésRécapitulatif - Gestionnaire de compte bancaire