요약 - 은행 계좌 관리 프로그램
Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 16번째.
챌린지
중급클래스 변수, 프라이빗 속성, 프로퍼티, 게터(getters), 세터(setters) 및 메서드를 포함한 객체 지향 프로그래밍 개념을 보여주는 완전한 BankAccount 클래스를 만드세요.
1. 다음을 포함하는 BankAccount 클래스를 생성하세요:
0.02(2%)로 설정된 클래스 변수interest_rate__owner_name및__balance에 대한 프라이빗 인스턴스 속성- 이러한 속성들을 초기화하는 생성자
2. 프로퍼티 게터와 세터를 구현하세요:
- 계좌 소유자의 이름을 반환하는 읽기 전용 프로퍼티
owner_name - 다음을 포함하는 프로퍼티
balance:- 현재 잔액을 반환하는 게터
- 입금을 검증하는 세터 (음수 금액 거부)
- 검증에 실패하면 다음을 출력합니다:
"Balance cannot be negative"
3. 메서드를 구현하세요:
- 다음을 수행하는
deposit(amount):- 금액이 양수이면 잔액에 추가합니다
- 금액이 양수가 아니면
"Deposit amount must be positive"를 출력하고False를 반환합니다 - 성공 시
True를 반환합니다
- 다음을 수행하는
withdraw(amount):- 금액이 양수이고 잔액이 충분하면 잔액에서 차감합니다
- 금액이 양수가 아니면
"Withdrawal amount must be positive"를 출력하고False를 반환합니다 - 금액이 잔액을 초과하면
"Insufficient funds"를 출력하고False를 반환합니다 - 성공 시
True를 반환합니다
- 다음을 수행하는
apply_interest():- 클래스 이자율에 따라 잔액에 이자를 추가합니다
- 이자 금액을 반환합니다
다음 형식으로 계좌 세부 정보를 출력하는
display_info():Account Owner: [owner_name] Balance: $[balance] Interest Rate: [interest_rate]%
출력 형식 요구 사항
- 모든 검증 오류 메시지는 지정된 대로 정확하게 출력되어야 합니다
display_info()메서드는 위에 표시된 것과 정확히 일치하는 형식으로 출력을 생성해야 합니다- 이자율은 백분율로 표시되어야 합니다 (100을 곱함)
치트 시트
객체 지향 프로그래밍 개념을 보여주는 전체 클래스 예시입니다:
class BankAccount:
interest_rate = 0.02 # 클래스 변수
def __init__(self, owner_name, initial_balance):
self.__owner_name = owner_name # 프라이빗 속성
self.__balance = initial_balance # 프라이빗 속성
@property
def owner_name(self): # 읽기 전용 프로퍼티
return self.__owner_name
@property
def balance(self): # 게터(Getter)
return self.__balance
@balance.setter
def balance(self, value): # 유효성 검사가 포함된 세터(Setter)
if value < 0:
print("Balance cannot be negative")
else:
self.__balance = value
def deposit(self, amount):
if amount <= 0:
print("Deposit amount must be positive")
return False
self.__balance += amount
return True
def withdraw(self, amount):
if amount <= 0:
print("Withdrawal amount must be positive")
return False
if amount > self.__balance:
print("Insufficient funds")
return False
self.__balance -= amount
return True
def apply_interest(self):
interest = self.__balance * self.interest_rate
self.__balance += interest
return interest
def display_info(self):
print(f"Account Owner: {self.__owner_name}")
print(f"Balance: ${self.__balance}")
print(f"Interest Rate: {self.interest_rate * 100}%")
주요 개념:
- 클래스 변수: 모든 인스턴스에서 공유됨
- 프라이빗 속성: 이중 밑줄 접두사(
__)를 사용함 - 프로퍼티: 게터를 위해
@property데코레이터를 사용함 - 세터:
@property_name.setter데코레이터를 사용함 - 유효성 검사: 조건을 확인하고 에러 메시지를 제공함
직접 해보기
from bank_account import BankAccount
# 테스트 케이스 핸들러
test_case = input()
if test_case == "account_creation":
# 계좌 생성 테스트
account = BankAccount("Alice", 1000)
print(f"Owner: {account.owner_name}")
print(f"Initial balance: ${account.balance}")
print(f"Interest rate: {BankAccount.interest_rate * 100}%")
elif test_case == "deposit_method":
# 입금 기능 테스트
account = BankAccount("Bob", 500)
print(f"Initial balance: ${account.balance}")
# 유효한 입금
result = account.deposit(300)
print(f"Deposit result: {result}")
print(f"New balance: ${account.balance}")
# 유효하지 않은 입금
result = account.deposit(-50)
print(f"Negative deposit result: {result}")
print(f"Balance after invalid deposit: ${account.balance}")
elif test_case == "withdraw_method":
# 출금 기능 테스트
account = BankAccount("Charlie", 1000)
# 유효한 출금
result = account.withdraw(400)
print(f"Withdrawal result: {result}")
print(f"Balance after withdrawal: ${account.balance}")
# 유효하지 않은 출금 (음수)
result = account.withdraw(-50)
print(f"Negative withdrawal result: {result}")
# 유효하지 않은 출금 (잔액 초과)
result = account.withdraw(1000)
print(f"Excessive withdrawal result: {result}")
print(f"Final balance: ${account.balance}")
elif test_case == "property_access":
# 속성 접근 및 보호 테스트
account = BankAccount("Dave", 800)
print(f"Owner via property: {account.owner_name}")
print(f"Balance via property: ${account.balance}")
# 잔액 설정 시도 (setter를 사용해야 함)
account.balance = 1200
print(f"Balance after valid setter: ${account.balance}")
# 유효하지 않은 잔액 시도
account.balance = -500
print(f"Balance after invalid setter: ${account.balance}")
# 비공개 속성에 직접 접근 시도 (실패해야 함)
try:
print(account.__owner_name)
except AttributeError:
print("Cannot access private owner_name directly")
elif test_case == "apply_interest":
# 이자 적용 테스트
account = BankAccount("Eve", 2000)
# 원금 확인
print(f"Initial balance: ${account.balance}")
# 이자 적용
interest_earned = account.apply_interest()
expected_interest = 2000 * 0.02
print(f"Interest earned: ${interest_earned}")
print(f"New balance after interest: ${account.balance}")
print(f"Interest calculation correct: {interest_earned == expected_interest}")
elif test_case == "display_info":
# display_info 메서드 형식 테스트
account = BankAccount("Frank", 1500)
# 클래스 변수 테스트를 위해 이자율 수정
original_rate = BankAccount.interest_rate
BankAccount.interest_rate = 0.03
print("Display info output:")
account.display_info()
# 원래 이자율로 복구
BankAccount.interest_rate = original_rate
elif test_case == "original_test_case":
# 챌린지의 원본 테스트 코드 실행
account = BankAccount("Coddy", 1000)
# 작업 수행
account.deposit(500)
account.withdraw(200)
account.apply_interest()
# 계좌 정보 표시
account.display_info()
# setter 유효성 검사 테스트
account.balance = 5000
print(f"Balance after setter: ${account.balance}")
# 출금 유효성 검사 테스트
account.withdraw(10000)
print(f"Final balance: ${account.balance}")