Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Projeto] Faça como eu fiz: gerador de funções personalizadas

def desconto(porcentagem_desconto):
    def calcular(valor):
        desconto = (valor * (porcentagem_desconto / 100))
        return valor - desconto
    return calcular

while True:
  try:
    porcentagem_desconto = float(input('Digite a porcentagem de desconto: '))
    valor_compra = float(input('Digite o valor da compra: '))
    
    calcular = desconto(porcentagem_desconto)
    preco_final = calcular(valor_compra)
    print(f'Preço final com desconto: {preco_final:.2f}')
    break
  except ValueError:
    print('Por favor, insira números válidos')
2 respostas
solução!

Olá, Marcelo. Como vai?

Excelente código! Você implementou um conceito avançado e muito poderoso no Python chamado Closures (ou funções internas). No seu código, a função desconto atua como uma "fábrica" que gera e retorna uma nova função personalizada (calcular) que se lembra do valor de porcentagem_desconto mesmo depois que a execução da função principal terminou.

O seu tratamento de erros com while True e try/except também ficou ótimo, garantindo que o programa continue rodando até que o usuário insira valores numéricos válidos.

Para complementar o seu projeto e agregar ainda mais valor ao seu aprendizado, vamos analisar como o Python gerencia esse conceito por debaixo dos panos e como você pode explorar ainda mais esse recurso.

Como a Closure funciona na memória?

Quando você faz isso:

calcular = desconto(porcentagem_desconto)

O Python cria um escopo fechado. A função interna calcular guarda uma referência para a variável porcentagem_desconto do escopo externo. Isso é muito útil no desenvolvimento web (como no Django ou Flask) para criar decoradores (decorators), que servem para verificar se um usuário está logado antes de carregar uma página, por exemplo.

Sugestão de Melhoria e Prática: Reaproveitamento

A verdadeira magia das closures acontece quando reaproveitamos a função gerada para múltiplos cálculos, sem precisar pedir a porcentagem toda vez. No seu código atual, o programa calcula o valor e encerra imediatamente devido ao break.

Se mudarmos a estrutura para definir as funções de desconto fixas no início, podemos usá-las como "regras de negócio" pré-definidas em um sistema de vendas. Veja este exemplo prático de como expandir sua ideia:

def criar_desconto(porcentagem_desconto):
    def calcular(valor):
        desconto = valor * (porcentagem_desconto / 100)
        return valor - desconto
    return calcular

# Criamos funções especialistas para a nossa loja
desconto_cliente_vip = criar_desconto(15)  # 15% de desconto
desconto_black_friday = criar_desconto(30) # 30% de desconto

# Agora podemos aplicar essas funções diretamente em qualquer valor
valor_produto = 100.0

print(f"Preço VIP: R$ {desconto_cliente_vip(valor_produto):.2f}")
print(f"Preço Black Friday: R$ {desconto_black_friday(valor_produto):.2f}")

Note que, ao modularizar dessa forma, o código fica muito mais limpo e você ganha a capacidade de criar diferentes regras de desconto dinamicamente.

Seu raciocínio lógico e a sintaxe do Python estão excelentes. Continue praticando essas estruturas de funções aninhadas, pois elas abrirão portas para entender conceitos ainda mais complexos na linguagem!

Espero que possa ter lhe ajudado!

Gostei dessa parte de ficar como regras de negócio, não sei porque isso me lembrou aquelas constantes do C que se definiam no inicio de arquivos. Levei essa ideia pro meu notebook. Obrigaod pelo feedback