Desafio Python
Sistema de saque com exceções personalizadas e finally
Enunciado
Implemente uma classe ContaBancaria com atributos titular e saldo. O método sacar(valor) deve lançar SaldoInsuficienteError (personalizada) se o valor for maior que o saldo, e ValueError se o valor for negativo. Use try/except/else/finally para: tentar o saque, capturar SaldoInsuficienteError e ValueError, imprimir mensagens apropriadas, e no finally imprimir "Operação finalizada". O programa deve testar três casos: saque válido, saque com saldo insuficiente e saque com valor negativo.
Requisitos
- A classe
ContaBancariadeve ter os atributostitularesaldo. - O método
sacardeve lançarSaldoInsuficienteErrorsevalor > saldoeValueErrorsevalor < 0. - O bloco
trydeve terexceptpara as duas exceções, umelsepara sucesso e umfinallyque imprime "Operação finalizada". - O programa deve executar os três cenários e imprimir as mensagens correspondentes.
Código inicial
class SaldoInsuficienteError(Exception):
pass
class ContaBancaria:
def __init__(self, titular, saldo):
self.titular = titular
self.saldo = saldo
def sacar(self, valor):
# seu código aqui
pass
# Teste os três casos
conta = ContaBancaria("Ana", 100)
# Caso 1: saque válido
# Caso 2: saldo insuficiente
# Caso 3: valor negativo
Saída esperada
Saque de 50 realizado. Novo saldo: 50
Operação finalizada
Erro: Saldo insuficiente para sacar 200
Operação finalizada
Erro: Valor de saque não pode ser negativo
Operação finalizada
Ver dica
No método sacar, verifique valor < 0 primeiro e levante ValueError. Depois verifique valor > self.saldo e levante SaldoInsuficienteError. No try, chame conta.sacar(...) e trate as exceções.
Mostrar solução
class SaldoInsuficienteError(Exception):
"""Exceção lançada quando o saldo é insuficiente para um saque."""
pass
class ContaBancaria:
def __init__(self, titular, saldo):
self.titular = titular
self.saldo = saldo
def sacar(self, valor):
if valor < 0:
raise ValueError("Valor de saque não pode ser negativo")
if valor > self.saldo:
raise SaldoInsuficienteError(f"Saldo insuficiente para sacar {valor}")
self.saldo -= valor
return self.saldo
conta = ContaBancaria("Ana", 100)
# Caso 1: saque válido
try:
novo_saldo = conta.sacar(50)
except SaldoInsuficienteError as e:
print(f"Erro: {e}")
except ValueError as e:
print(f"Erro: {e}")
else:
print(f"Saque de 50 realizado. Novo saldo: {novo_saldo}")
finally:
print("Operação finalizada")
# Caso 2: saldo insuficiente
try:
conta.sacar(200)
except SaldoInsuficienteError as e:
print(f"Erro: {e}")
except ValueError as e:
print(f"Erro: {e}")
else:
print("Saque realizado com sucesso")
finally:
print("Operação finalizada")
# Caso 3: valor negativo
try:
conta.sacar(-10)
except SaldoInsuficienteError as e:
print(f"Erro: {e}")
except ValueError as e:
print(f"Erro: {e}")
else:
print("Saque realizado com sucesso")
finally:
print("Operação finalizada")
Passo a passo
- Definimos
SaldoInsuficienteErrorherdando deException. - A classe
ContaBancariatem__init__que guarda titular e saldo. - O método
sacarverifica primeiro sevalor < 0, lançandoValueError. - Depois verifica se
valor > self.saldo, lançandoSaldoInsuficienteError. - Se passar, subtrai do saldo e retorna o novo saldo.
- Para cada caso, usamos um bloco
tryque chamasacar. - Os
exceptcapturam as exceções específicas e imprimem mensagens. - O
elseexecuta se não houver exceção, imprimindo o sucesso. - O
finallysempre imprime "Operação finalizada".
Por que funciona
A ordem das verificações garante que valores negativos sejam rejeitados antes de checar saldo. O uso de exceções personalizadas torna o código expressivo. O finally assegura que a mensagem de finalização apareça independentemente do resultado, simulando um log de auditoria.
Erros comuns
- Inverter a ordem das verificações: se checar saldo antes de valor negativo, um valor negativo pode passar se o saldo for alto o suficiente. Ex.:
sacar(-10)com saldo 100 não lançaria erro se a verificação de saldo viesse primeiro. - Esquecer o
finally: a mensagem não seria impressa em todos os casos. - Capturar
Exceptiongenérica: perderia a distinção entre os erros e as mensagens específicas. - Não atualizar o saldo: se esquecer
self.saldo -= valor, o saque não teria efeito.
Outra forma de resolver
Poderia usar um único try com múltiplos except para os três casos, mas a repetição do bloco try deixa claro cada cenário. Uma alternativa é criar uma função auxiliar que executa o saque e trata as exceções, mas para fins didáticos a repetição é aceitável.
Saída esperada
Saque de 50 realizado. Novo saldo: 50
Operação finalizada
Erro: Saldo insuficiente para sacar 200
Operação finalizada
Erro: Valor de saque não pode ser negativo
Operação finalizada