Menu
Coddy logo textTech

Банковская система

Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 62 из 64.

challenge icon

Задание

Сложно

В этом испытании вы создадите банковскую систему с несколькими типами счетов, транзакциями и центральным менеджером банка.

Реализуйте банковскую систему, выполнив задания TODO в следующих файлах:

  • transaction.py — класс Transaction для записи финансовых операций
  • account.py — абстрактный базовый класс Account с общим функционалом
  • savingsaccount.py — реализация SavingsAccount с процентами и минимальным балансом
  • checkingaccount.py — реализация CheckingAccount с возможностью овердрафта
  • bank.py — класс Bank для управления счетами и переводами

Шпаргалка

Этот челлендж включает в себя создание банковской системы с использованием концепций объектно-ориентированного программирования, включая:

  • Transaction class — записывает финансовые операции
  • Abstract Account class — базовый класс с общей функциональностью счета
  • SavingsAccount — тип счета с расчетом процентов и требованиями к минимальному балансу
  • CheckingAccount — тип счета с возможностью защиты от овердрафта
  • Bank class — центральный менеджер для счетов и денежных переводов

Ключевые концепции включают наследование, абстракцию, инкапсуляцию и полиморфизм для создания модульной архитектуры банковской системы.

Попробуйте сами

from transaction import Transaction
from account import Account
from savingsaccount import SavingsAccount
from checkingaccount import CheckingAccount
from bank import Bank

# Комплексный обработчик тестовых случаев, охватывающий все сценарии и граничные условия
test_case = input()

if test_case == "transaction_class":
    # Тест класса Transaction
    transaction = Transaction("deposit", 100.50, None)
    print(str(transaction))
    
    transaction = Transaction("withdrawal", 75.25, None)
    print(str(transaction))

elif test_case == "account_deposit":
    # Тест функциональности депозита
    savings = SavingsAccount("S123", "John Doe", 500)
    
    # Положительная сумма
    success, message = savings.deposit(200)
    print(f"Success: {success}")
    print(f"Message: {message}")
    print(f"Balance: ${savings.get_balance():.2f}")
    
    # Отрицательная сумма (должна завершиться ошибкой)
    success, message = savings.deposit(-50)
    print(f"Success: {success}")
    print(f"Message: {message}")

elif test_case == "savings_withdraw":
    # Тест снятия средств со сберегательного счета
    savings = SavingsAccount("S123", "John Doe", 500, min_balance=200)
    
    # Корректное снятие
    success, message = savings.withdraw(100)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Некорректное снятие (ниже минимального баланса)
    success, message = savings.withdraw(300)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Отрицательная сумма
    success, message = savings.withdraw(-50)
    print(f"Success: {success}")
    print(f"Message: {message}")

elif test_case == "checking_withdraw":
    # Тест снятия средств с чекового счета
    checking = CheckingAccount("C123", "Jane Smith", 300, overdraft_limit=200)
    
    # Обычное снятие
    success, message = checking.withdraw(100)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Снятие с использованием овердрафта
    success, message = checking.withdraw(300)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Превышение лимита овердрафта
    success, message = checking.withdraw(200)
    print(f"Success: {success}")
    print(f"Message: {message}")

elif test_case == "interest_application":
    # Тест начисления процентов
    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}")
    
    # Проверка истории транзакций
    transactions = savings.get_transaction_history()
    print(f"Transaction count: {len(transactions)}")
    print(f"Last transaction: {transactions[-1]}")

elif test_case == "bank_create_account":
    # Тест создания банковского счета
    bank = Bank("Test Bank")
    
    # Создание сберегательного счета
    success, message = bank.create_account("savings", "S123", "John Doe", 1000, interest_rate=0.03)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Создание чекового счета
    success, message = bank.create_account("checking", "C456", "Jane Smith", 500, overdraft_limit=300)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Создание с дублирующимся номером счета
    success, message = bank.create_account("savings", "S123", "Another Person", 200)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Создание с недопустимым типом
    success, message = bank.create_account("invalid", "I789", "Test Person", 100)
    print(f"Success: {success}")
    print(f"Message: {message}")

elif test_case == "bank_transfer":
    # Тест функциональности банковского перевода
    bank = Bank("Transfer Test Bank")
    
    # Создание двух счетов
    bank.create_account("savings", "S123", "John Doe", 1000, min_balance=100)
    bank.create_account("checking", "C456", "Jane Smith", 500)
    
    # Корректный перевод
    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}")
    
    # Некорректный перевод (превышает минимальный баланс)
    success, message = bank.transfer("S123", "C456", 700)
    print(f"Success: {success}")
    print(f"Message: {message}")
    
    # Несуществующий счет
    success, message = bank.transfer("NONEXISTENT", "C456", 100)
    print(f"Success: {success}")
    print(f"Message: {message}")

elif test_case == "full_banking_workflow":
    # Тест полного рабочего процесса
    bank = Bank("Full Workflow Bank")
    
    # Создание счетов
    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)
    
    # Внесение депозитов
    savings = bank.get_account("S123")
    checking = bank.get_account("C456")
    
    savings.deposit(300)
    checking.deposit(200)
    
    # Выполнение перевода
    bank.transfer("S123", "C456", 400)
    
    # Начисление процентов на сбережения
    savings.apply_interest()
    
    # Снятие средств с чекового счета с овердрафтом
    checking.withdraw(900)
    
    # Вывод финального состояния
    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":
    # Комплексная проверка наследования
    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":
    # Тест поведения переопределения методов
    print('Testing method overriding...')
    # Создание экземпляров и тестирование переопределенных методов
    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":
    # Тест доступа к атрибутам
    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":
    # Тест граничных условий и крайних значений
    print('Running boundary_conditions_test test...')
    print('Test completed successfully')

elif test_case == "error_handling_test":
    # Тест обработки ошибок и сценариев исключений
    print('Running error_handling_test test...')
    print('Test completed successfully')

elif test_case == "polymorphic_behavior_test":
    # Тест полиморфного поведения со смешанными объектами
    print('Running polymorphic_behavior_test test...')
    print('Test completed successfully')

elif test_case == "stress_test":
    # Стресс-тест с множеством объектов
    import time
    start_time = time.time()
    
    objects = []
    for i in range(50):
        try:
            objects.append(Transaction(f'test_{i}', 100, None))
        except:
            pass  # Корректная обработка ошибок создания
        try:
            objects.append(SavingsAccount(f'test_{i}', f'User_{i}'))
        except:
            pass  # Корректная обработка ошибок создания
        try:
            objects.append(CheckingAccount(f'test_{i}', f'User_{i}'))
        except:
            pass  # Корректная обработка ошибок создания
        try:
            objects.append(Bank(f'test_{i}'))
        except:
            pass  # Корректная обработка ошибок создания
    
    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":
    # Комплексный тест валидации
    print('=== Comprehensive Validation Test ===')
    
    # Тест 1: Базовое создание объектов
    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 ===')

Все уроки раздела Object Oriented Programming