Aqui eu criei funções mais simples para o programa, mas deixei com que cada uma trate o dado de forma a garantir que o código não quebre durante a execução, pelo menos é o que eu acredito que fiz.
Essa é a segunda parte do meu programa
# ================================================================================= #
# Funções do Programa #
# ================================================================================= #
'''Função | Tratar Percentual'''
def tratar_percentual(msg: str) -> int:
while True:
txt = input(msg)
# Regra de Tratamento do dado: Remove espaços
txt = txt.strip()
if len(txt) == 0:
print('Erro: campo vazio. Digite um inteiro entre 0 e 100 (ex.: 10, 13, 18).')
continue
# Regra de Tratamento do dado: Não aceitar espaços vazios
if ' ' in txt:
print('Erro: não use espaços vazios.')
continue
# Regra de negócio: Máximo 3 caracteres totais
if len(txt) > 3:
print('Erro: porcentagem deve ter no máximo 3 caracteres (ex.: 9, 10, 100).')
continue
# Regra de negócio: Não aceitar vírgula ou ponto
if ',' in txt or '.' in txt:
print('Erro: a porcentagem deve ser inteira, sem vírgula ou ponto (ex.: 10, 13, 18).')
continue
# Regra de negócio: Apenas dígitos (0–9)
if not txt.isdigit():
print('Erro: digite apenas números inteiros (ex.: 10, 13, 18).')
continue
# Converte para int
valor = int(txt)
# Regra de negócio: Converte e valida intervalo
if valor < 0:
print('Erro: a porcentagem não pode ser negativa.')
continue
if valor > 100:
print('Erro: a porcentagem não pode ser superior a 100.')
continue
# Passou em todas as validações
return valor
'''Função | Tratar Valor da Conta'''
def tratar_valor_conta(msg: str) -> float:
while True:
txt = input(msg)
# Regra de Tratamento do dado: Remove espaços
txt = txt.strip()
# Regra de Tratamento do dado: Não aceitar espaços vazios
if len(txt) == 0:
print('Erro: digite um valor numérico (ex.: 130 ou 130,99).')
continue
# Regra de Tratamento do dado: Não aceitar espaços internos (ex.: '1 20')
if " " in txt:
print('Erro: não use espaços no meio (ex.: 120 50).')
continue
# Regra de Tratamento do dado: Aceitar a vírgula -> ponto para conversão
normalizado = txt.replace(",", ".")
# Regra de negócio: Tentar converter o texto para float
try:
valor = float(normalizado)
except ValueError:
print('Erro: valor inválido. Use apenas números (ex.: 130 ou 130,99).')
continue
# Regras de negócio: = 0 | Não pode ser igual a zero
if valor == 0:
print('Erro: o valor da conta não pode ser igual a zero.')
continue
# Regras de negócio: Não pode ser um número negativo ou igual a Zero
if valor <= 0:
print('Erro: o valor da conta deve ser MAIOR que zero.')
continue
# Tudo certo
return valor
'''Função | Formatar valores em Reais'''
def formatar_brl(valor: float) -> str:
# Formata como '1,234.56' (padrão US)
s = f"{valor:,.2f}"
# , → adiciona separador de milhares usando o padrão “US” (vírgula para milhar).
# .2f → formata como número de ponto flutuante com 2 casas decimais.
# Troca para '1.234,56' (padrão BR)
s = s.replace(",", "X").replace(".", ",").replace("X", ".")
# 1º s.replace(",", "X")
# Troca vírgula por X
# Exemplo: De 1,234.56. Para 1X234.56
# -----------------------------------------
# 2º .replace(".", ",")
# Troca ponto por vírgula
# Exemplo: De 1X234.56 Para 1X234,56
# -----------------------------------------
# 3º .replace("X", ".")
# Troca o marcador X por ponto
# Exemplo: De 1X234.56 Para 1.234,56
# Tudo certo
return f"R$ {s}"