Condições aninhadas

Aprenda a colocar uma decisão dentro de outra de forma organizada.

Às vezes, uma decisão na nossa vida depende de outra decisão que tomamos logo antes.

Por exemplo:

  1. Você decide ir ao cinema. (Se você for ao cinema...)
  2. Lá dentro, você precisa decidir o filme. (Se for filme de ação, compra pipoca salgada; senão, compra pipoca doce).

A escolha da pipoca só faz sentido se você já estiver dentro do cinema. Se você decidir ficar em casa, a escolha do filme e da pipoca do cinema nem chega a acontecer.

Na programação, colocar uma tomada de decisão dentro de outra é chamado de condições aninhadas.

O que são condições aninhadas?

Pense nas condições aninhadas como aquelas bonecas russas (Matrioskas), onde abrimos uma boneca maior e encontramos outra menorzinha lá dentro. Ou como gavetas dentro de gavetas.

No Python, nós criamos essa estrutura simplesmente escrevendo um bloco de if/else dentro do bloco de outro if/else.

Veja um exemplo de validação de entrada de um evento:

tem_ingresso = True
idade = 16

if tem_ingresso:    
   # Esta gaveta só abre se 'tem_ingresso' for verdadeiro!
   if idade >= 18:
       print("Acesso liberado à área VIP!")
   else:
       print("Acesso liberado apenas à área comum (Menores).")
else:
   print("Entrada proibida!")

Como o Python interpreta esse código?

  1. Ele lê o primeiro if: "O usuário tem ingresso?" -> Verdadeiro. O Python entra no bloco.
  2. Logo em seguida, ainda dentro do primeiro if, o Python encontra um novo if: "A idade é maior ou igual a 18?" -> Falso (idade é 16).
  3. O Python pula para o else correspondente à idade e imprime "Acesso liberado apenas à área comum...".
  4. O else final (da linha 12) é totalmente ignorado, pois o primeiro if foi verdadeiro.

Observação: na programação, existem diversas maneiras de resolver um mesmo problema. O problema acima também poderia ser resolvido sem aninhamento:

tem_ingresso = True
idade = 16

if tem_ingresso and idade >= 18:
   print("Acesso liberado à área VIP!")
elif tem_ingresso and idade < 18:
   print("Acesso liberado apenas à área comum (Menores).")
else:
   print("Entrada proibida!")

O segredo da indentação duplicada

Como o Python sabe qual else pertence a qual if? A resposta é: pelo alinhamento vertical (indentação).

  • O if e o else principais (linhas 4 e 10) estão alinhados na extrema esquerda.
  • O if e o else internos (linhas 6 e 8) estão recuados 4 espaços para a direita.
  • As mensagens que rodam dentro do if interno (linhas 7 e 9) estão recuadas 8 espaços (ou 2 Tabs) para a direita.

[!IMPORTANT] A indentação é cumulativa. Cada vez que você entra em uma estrutura condicional mais interna, você deve recuar o código mais 4 espaços para a direita.

Dica de ouro: cuidado para não exagerar!

Colocar um if dentro de outro é muito útil, mas se você começar a colocar 4, 5 ou 6 níveis de if um dentro do outro, seu código vai começar a andar tanto para a direita que ficará parecendo uma seta (>). Isso deixa o código muito confuso de ler e é chamado de código espaguete ou efeito pirâmide.

Se você puder, prefira combinar as condições em uma única linha usando os operadores lógicos que aprendemos, como o and. Vimos isso no exemplo do ingresso!

Colocando em prática

Veja mais alguns exemplos de problemas que podemos resolver com aninhamento de condicionais.

  1. Um posto está vendendo combustíveis com a seguinte tabela de descontos:
  • Álcool:
  • até 20 litros: desconto de 3%
  • acima de 20 litros: desconto de 5%
  • Gasolina:
  • até 20 litros: desconto de 4%
  • acima de 20 litros: desconto de 6%

Escreva um programa que leia o número de litros vendidos, o tipo de combustível (A - álcool, G - gasolina) e o preço do litro do combustível. Calcule e imprima o valor a ser pago pelo cliente.

litros = int(input("Digite quantos litros quer abastecer: "))
combustivel = input("Digite o tipo de combustível - A (Álcool), G (Gasolina): ")
preco = float(input("Digite o valor por litro: ")) 

# Primeiro, podemos validar se a opção de combustível é válida. Somente então executamos os cálculos
if combustivel == "A" or combustivel == "G":
   total = litros * preco

   if combustivel == "A":
       if litros <= 20:
           desconto = 3
       else:
           desconto = 5

   # Como o if externo já garantiu que é "A" ou "G",
   # se não for "A", então com certeza é "G"
   else:
       if litros <= 20:
           desconto = 4
       else:
           desconto = 6

   valor_desconto = total * desconto / 100
   total_com_desconto = total - valor_desconto
   print(f"Total a ser pago: {total_com_desconto}")

# Se a opção informada for diferente de A ou G, apenas mostramos uma mensagem
else:
   print("Opção inválida. Informe A (Álcool) ou G (Gasolina)")
  1. Uma fruteira está vendendo frutas com a seguinte tabela de preços:
  • Morango:
  • até 5 kg: R$ 14,90 por kg
  • acima de 5 kg: R$ 13,90 por kg
  • Maçã gala:
  • até 5 kg: R$ 5,90 por kg
  • acima de 5 kg: 4,90 por kg

Além disso, se o cliente fizer uma compra que totalize mais de R$ 50,00, ele receberá um desconto de 10% sobre este total. Escreva um programa para ler:

  • o tipo da fruta: M (Morango) ou G (Maçã gala)
  • a quantidade (em kg)

Mostre o valor a ser pago pelo cliente.

tipo_fruta = input("Digite o tipo da fruta ('M' para Morango ou 'G' para Maçã gala): ")
quantidade = float(input("Digite a quantidade de fruta em kg: ")) 

if tipo_fruta == "M" or tipo_fruta == "G":
   if tipo_fruta == "M":
       if quantidade <= 5:
           valor = 14.9
       else: 
           valor = 13.9
       
   else:
       if quantidade <= 5:
           valor = 5.9
       else:
           valor = 4.9
   
   total = quantidade * valor

   if total > 50:
       desconto = total * 10 / 100
       total_com_desconto = total - desconto
       print(f"Total da compra: {total_com_desconto}")
   else:
       print(f"Total da compra: {total}")

else:
   print("Opção inválida! Digite M ou G")

O que aprendemos nesta lição

Nesta lição, você aprendeu que:

  • Condições aninhadas são estruturas condicionais colocadas dentro de outras estruturas condicionais.
  • As condições internas só são avaliadas se a condição externa correspondente for verdadeira.
  • A indentação é cumulativa (4 espaços para o primeiro nível, 8 espaços para o segundo nível, etc.).
  • O Python associa cada else ao if que estiver exatamente no mesmo alinhamento vertical.
  • Devemos evitar aninhar muitos níveis de if para manter o código limpo e fácil de ler.