Итоги — Менеджер банковского счета
Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 16 из 64.
Задание
СреднеСоздайте полный класс BankAccount, который демонстрирует концепции объектно-ориентированного программирования, включая переменные класса, приватные атрибуты, свойства, геттеры, сеттеры и методы.
1. Создайте класс BankAccount с:
- Переменной класса
interest_rate, установленной в0.02(2%) - Приватными атрибутами экземпляра для
__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): # Геттер
return self.__balance
@balance.setter
def balance(self, value): # Сеттер с валидацией
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}")
# Попытка установить баланс (должен использоваться сеттер)
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()
# Тест валидации сеттера
account.balance = 5000
print(f"Balance after setter: ${account.balance}")
# Тест валидации снятия средств
account.withdraw(10000)
print(f"Final balance: ${account.balance}")Все уроки раздела Object Oriented Programming
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — Простой калькулятор4Наследование
Базовое наследованиеФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовИтоги — Иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и User