. Questão: Implemente uma função que receba o valor total de uma compra e um código de cupom de desconto. A função deve verificar se o cupom informado existe em uma estrutura previamente definida de cupons válidos e, em caso positivo, aplicar o percentual de desconto correspondente ao valor da compra, retornando o valor final a ser pago. Caso o cupom não exista, a função deve retornar o valor original da compra. Considere, por exemplo, que os cupons DESC10, DESC20 e DESC30 concedem, respectivamente,
e
de desconto.
Passo 1
O que o enunciado pede e o que foi dado.
- Pedido: Implementar uma função que receba o valor total de uma compra e um código de cupom de desconto; verificar se o cupom existe numa estrutura pré-definida de cupons válidos; se existir, aplicar o percentual de desconto correspondente e retornar o valor final a pagar; se não existir, retornar o valor original da compra.
- Informações fornecidas (exemplo de cupons):
- O cupom
DESC10concedede desconto. - O cupom
DESC20concedede desconto. - O cupom
DESC30concedede desconto.
- O cupom
- Entradas esperadas para a função:
- valor total da compra (um número).
- código do cupom (uma string).
- Saída esperada:
- o valor final a ser pago (número), já com o desconto aplicado quando o cupom for válido.
Passo 2
Escolha da estrutura de dados para os cupons e justificativa.
- Precisamos de um jeito rápido de consultar, dado o código do cupom, qual o percentual associado. Uma boa estrutura para isso é um dicionário (mapa) que associa a chave (código do cupom) ao valor (percentual).
- Exemplo de mapeamento (representação conceitual):
-
- Por que usar dicionário:
- A busca pelo cupom é O(1) em média — é rápida.
- É fácil adicionar/remover cupons.
- Observação prática: normalmente guardamos as chaves em uma forma padrão (por exemplo, maiúsculas e sem espaços) para evitar diferenças de caixa/formatos na entrada.
Passo 3
Validação de entrada: o que checar antes de calcular o desconto.
- Verificar se o valor total pode ser tratado como número real (converte-lo para float). Se não puder, sinalizar erro ou lançar exceção.
- Verificar se o valor total é não-negativo. Compras com valor negativo não fazem sentido aqui — tratar como erro.
- Normalizar o código do cupom: remover espaços nas extremidades e tratar em caixa única (por exemplo, converter para maiúsculas) para que entradas como
" desc10 "ou"desc10"sejam reconhecidas. - Decisão de comportamento para cupom inválido: retornar o valor original da compra (conforme enunciado).
Passo 4
Fórmula do desconto e interpretação das variáveis.
- Se
for o percentual de desconto (por exemplo para ) e for o valor antes do desconto, então o valor final é dado por:
- Onde:
-
é o que o usuário passou (ex.: ). -
é o percentual de desconto associado ao cupom (ex.: para ). - O fator
é a fração do valor que permanece após desconto (ex.: para fica ).
-
- Exemplo numérico rápido:
- Se
e , então
- Se
Passo 5
Detalhes de implementação práticos e decisões de projeto (comportamento esperado).
- Caso o cupom não exista na estrutura de cupons, simplesmente retornar
sem alteração. - Tratar cupom com insensibilidade à caixa (usar maiúsculas) e remover espaços em excesso (usar trim).
- Se o percentual de desconto for
, por segurança, limitar o valor final para (não retornar número negativo). - Decidir sobre precisão: normalmente retornar um número de ponto flutuante; se quiser formato monetário, pode-se arredondar para duas casas decimais usando arredondamento explícito (ex.: formatar com duas casas).
- Lidar com entradas inválidas (por exemplo valor não numérico ou negativo) lançando uma exceção (ou retornando erro) — é melhor falhar rápido do que ocultar um bug.
Passo 6
Pseudocódigo / lógica passo a passo antes do código final.
- Definir o dicionário de cupons:
-
.
-
- Receber
e . - Tentar converter
para número real; se falhar, indicar erro. - Se
: erro. - Normalizar
com . - Procurar
nas chaves de . - Se não existir: retornar
. - Se existir: obter
.
- Se não existir: retornar
- Calcular:
- Se
(por conta de ), definir . - Retornar
(possivelmente arredondado para duas casas, se desejado).
Passo 7
Exemplos de uso (casos de teste) com os cupons fornecidos.
- Exemplo 1:
- Entrada:
, . - Esperado:
.
- Entrada:
- Exemplo 2:
- Entrada:
, . - Esperado:
.
- Entrada:
- Exemplo 3:
- Entrada:
, . - Esperado:
(cupom inválido → sem desconto).
- Entrada:
- Exemplo 4 (teste de normalização):
- Entrada:
, . - Esperado:
(espaços e caixa diversa são tratados).
- Entrada:
Passo 8
Observações finais e recomendação para uso em prova/entrega rápida.
- Para a prova, foque em:
- Declarar claramente o dicionário de cupons.
- Fazer a normalização do código (strip + upper).
- Validar o tipo/valor do total.
- Aplicar a fórmula do desconto sem esquecer de dividir por
.
- Se pedir também tratamento de erros, explique que o ideal é lançar exceção quando o valor total não for válido.
- Em implementação real para produção, considere armazenar os cupons em banco de dados e tratar percentuais como decimais seguros (ex.: Decimal em Python) para evitar problemas de precisão monetária. Para a prova, float e arredondamento são suficientes.
Resposta
def aplicar_desconto(valor_total, codigo_cupom):
“”"
Recebe o valor total da compra e um código de cupom.
Se o cupom for válido, aplica o desconto correspondente e retorna o valor final.
Se o cupom for inválido, retorna o valor_total original.
Lança ValueError se valor_total não puder ser convertido para número ou for negativo.
“”"
# Dicionário de cupons válidos (chave -> percentual)
cupons = {
“DESC10”: 10,
“DESC20”: 20,
“DESC30”: 30
}
“”"
Recebe o valor total da compra e um código de cupom.
Se o cupom for válido, aplica o desconto correspondente e retorna o valor final.
Se o cupom for inválido, retorna o valor_total original.
Lança ValueError se valor_total não puder ser convertido para número ou for negativo.
“”"
# Dicionário de cupons válidos (chave -> percentual)
cupons = {
“DESC10”: 10,
“DESC20”: 20,
“DESC30”: 30
}
# Validação e conversão do valor_total
try:
valor = float(valor_total)
except (TypeError, ValueError):
raise ValueError("valor_total deve ser um número válido")
if valor < 0:
raise ValueError("valor_total não pode ser negativo")
# Normalizar o código do cupom
if not isinstance(codigo_cupom, str):
codigo_norm = ""
else:
codigo_norm = codigo_cupom.strip().upper()
# Verificar existência do cupom
percentual = cupons.get(codigo_norm)
if percentual is None:
# Cupom inválido: retorna o valor original
return valor
# Calcular o valor final usando a fórmula:
# valor_final = valor_total * (1 - percentual / 100)
valor_final = valor * (1 - percentual / 100.0)
# Segurança: não retornar valor negativo mesmo que percentual >= 100
if valor_final < 0:
valor_final = 0.0
# Opcional: arredondar para duas casas (comum em valores monetários)
return round(valor_final, 2)