은행 시스템
Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 62번째.
챌린지
어려움이 챌린지에서는 여러 계좌 유형, 거래 및 중앙 은행 관리 시스템을 갖춘 뱅킹 시스템을 구축합니다.
다음 파일들의 TODO 항목을 완료하여 뱅킹 시스템을 구현하세요:
transaction.py- 금융 활동 기록을 위한 Transaction 클래스account.py- 공통 기능을 가진 추상 베이스 Account 클래스savingsaccount.py- 이자 및 최소 잔액 기능이 있는 SavingsAccount 구현checkingaccount.py- 마이너스 통장(overdraft) 기능이 있는 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 ===')