Recapitulação - Gerenciador de Conta Bancária
Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 16 de 64.
Desafio
MédioCrie uma classe BankAccount completa que demonstre conceitos de programação orientada a objetos, incluindo variáveis de classe, atributos privados, propriedades, getters, setters e métodos.
1. Crie uma classe BankAccount com:
- Uma variável de classe
interest_ratedefinida como0.02(2%) - Atributos de instância privados para
__owner_namee__balance - Um construtor que inicializa esses atributos
2. Implemente getters e setters de propriedade:
- Uma propriedade somente leitura
owner_nameque retorna o nome do proprietário da conta - Uma propriedade
balancecom:- Um getter que retorna o saldo atual
- Um setter que valida depósitos (rejeitando valores negativos)
- Se a validação falhar, imprima:
"Balance cannot be negative"
3. Implemente os métodos:
deposit(amount)que:- Adiciona ao saldo se o valor for positivo
- Imprime
"Deposit amount must be positive"e retornaFalsese o valor não for positivo - Retorna
Trueem caso de sucesso
withdraw(amount)que:- Subtrai do saldo se o valor for positivo e houver fundos suficientes
- Imprime
"Withdrawal amount must be positive"e retornaFalsese o valor não for positivo - Imprime
"Insufficient funds"e retornaFalsese o valor exceder o saldo - Retorna
Trueem caso de sucesso
apply_interest()que:- Adiciona juros ao saldo com base na taxa de juros da classe
- Retorna o valor dos juros
display_info()que imprime os detalhes da conta neste formato:Account Owner: [owner_name] Balance: $[balance] Interest Rate: [interest_rate]%
Requisitos de Formato de Saída
- Todas as mensagens de erro de validação devem ser impressas exatamente como especificado
- O método
display_info()deve formatar a saída exatamente como mostrado acima - A taxa de juros deve ser exibida como uma porcentagem (multiplicada por 100)
Folha de consulta
Uma classe completa demonstrando conceitos de programação orientada a objetos:
class BankAccount:
interest_rate = 0.02 # Variável de classe
def __init__(self, owner_name, initial_balance):
self.__owner_name = owner_name # Atributo privado
self.__balance = initial_balance # Atributo privado
@property
def owner_name(self): # Propriedade somente leitura
return self.__owner_name
@property
def balance(self): # Getter
return self.__balance
@balance.setter
def balance(self, value): # Setter com validação
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}%")
Conceitos-chave:
- Variáveis de classe: Compartilhadas entre todas as instâncias
- Atributos privados: Use o prefixo de sublinhado duplo (
__) - Propriedades: Use o decorador
@propertypara getters - Setters: Use o decorador
@property_name.setter - Validação: Verifique condições e forneça mensagens de erro
Experimente você mesmo
from bank_account import BankAccount
# Manipulador de casos de teste
test_case = input()
if test_case == "account_creation":
# Testar criação de conta
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":
# Testar funcionalidade de depósito
account = BankAccount("Bob", 500)
print(f"Initial balance: ${account.balance}")
# Depósito válido
result = account.deposit(300)
print(f"Deposit result: {result}")
print(f"New balance: ${account.balance}")
# Depósito inválido
result = account.deposit(-50)
print(f"Negative deposit result: {result}")
print(f"Balance after invalid deposit: ${account.balance}")
elif test_case == "withdraw_method":
# Testar funcionalidade de saque
account = BankAccount("Charlie", 1000)
# Saque válido
result = account.withdraw(400)
print(f"Withdrawal result: {result}")
print(f"Balance after withdrawal: ${account.balance}")
# Saque inválido (negativo)
result = account.withdraw(-50)
print(f"Negative withdrawal result: {result}")
# Saque inválido (excede o saldo)
result = account.withdraw(1000)
print(f"Excessive withdrawal result: {result}")
print(f"Final balance: ${account.balance}")
elif test_case == "property_access":
# Testar acesso a propriedades e proteção
account = BankAccount("Dave", 800)
print(f"Owner via property: {account.owner_name}")
print(f"Balance via property: ${account.balance}")
# Tentar definir o saldo (deve usar o setter)
account.balance = 1200
print(f"Balance after valid setter: ${account.balance}")
# Tentar saldo inválido
account.balance = -500
print(f"Balance after invalid setter: ${account.balance}")
# Tentar acessar atributos privados diretamente (deve falhar)
try:
print(account.__owner_name)
except AttributeError:
print("Cannot access private owner_name directly")
elif test_case == "apply_interest":
# Testar aplicação de juros
account = BankAccount("Eve", 2000)
# Verificar saldo original
print(f"Initial balance: ${account.balance}")
# Aplicar juros
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":
# Testar formato do método display_info
account = BankAccount("Frank", 1500)
# Modificar taxa de juros para testar variável de classe
original_rate = BankAccount.interest_rate
BankAccount.interest_rate = 0.03
print("Display info output:")
account.display_info()
# Restaurar taxa original
BankAccount.interest_rate = original_rate
elif test_case == "original_test_case":
# Executar o código de teste original do desafio
account = BankAccount("Coddy", 1000)
# Realizar operações
account.deposit(500)
account.withdraw(200)
account.apply_interest()
# Exibir informações da conta
account.display_info()
# Testar validação do setter
account.balance = 5000
print(f"Balance after setter: ${account.balance}")
# Testar validação de saque
account.withdraw(10000)
print(f"Final balance: ${account.balance}")Todas as lições de Object Oriented Programming
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosO Parâmetro selfMétodosAtributosMétodo Construtor (__init__)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Função super()Sobrescrita de MétodoHerança MúltiplaOrdem de Resolução de MétodosRecapitulação - Hierarquia de Funcionários7Métodos Especiais
Introdução aos Métodos MágicosSobrecarga de OperadoresMétodos Mágicos de ContêinerRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução a Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy2Decoradores
Introdução aos DecoradoresDecorador de PropriedadeDecorador de Método EstáticoDecorador de Método de Classe5Polimorfismo
Sobrescrita de Método RevisitadaDuck TypingClasses e Métodos AbstratosDesign de InterfacesRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição vs HerançaMixinsMétodos Estáticos e de ClasseDecoradores de ClasseGerenciadores de Contexto11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Propriedades de Classe
Variáveis de Instância vs de ClasseDecoradores de PropriedadeAtributos PrivadosRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Membros Públicos, Protegidos e PrivadosModificadores de AcessoOcultação de InformaçãoProperty Decorators AvançadosRecapitulação - Sistema de Registro de Alunos12Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário