Pular para conteúdo

5. O programa que decide

Nesta aula

Ideia central: um if não pergunta nada a ninguém. Ele olha um valor que já está lá, e a resposta é sempre True ou False.

Ao fim você vai conseguir: escrever uma condição com os seis operadores de comparação; distinguir == de =; usar if e else; e enxergar, pela indentação, o que está dentro e o que está fora do bloco.

De onde paramos

O último programa do capítulo 4 avisava quanto restou da franquia de dados. Ele fazia a conta certa e não sabia fazer mais nada com ela: imprimia o número e encerrava, tivesse sobrado 19 GB ou 0,2 GB.

O que faltava era olhar o resultado e escolher o que dizer. É só isso que um if faz — e é o que separa um programa de uma calculadora.

Condição: a pergunta que vale True ou False

Uma condição é uma expressão como qualquer outra. A diferença é o tipo do resultado: em vez de um número, ela devolve um bool — aquele quarto tipo do capítulo 2 que até agora não tinha serventia nenhuma.

# Uma comparacao nao imprime "sim" ou "nao": ela vale True ou False.
usado_gb = 13.5
franquia_gb = 20

print(usado_gb > franquia_gb)
print(usado_gb < franquia_gb)
print(usado_gb == franquia_gb)
print(usado_gb != franquia_gb)
print(usado_gb >= 13.5)
print(usado_gb <= 13.5)
False
True
False
True
True
True

São seis operadores, e você já os conhece da matemática:

Operador Lê-se Verdadeiro quando
> maior que o da esquerda é maior
< menor que o da esquerda é menor
>= maior ou igual a maior, ou exatamente igual
<= menor ou igual a menor, ou exatamente igual
== é igual a os dois valores são o mesmo
!= é diferente de os dois valores não são o mesmo

Dois detalhes de digitação que custam caro: o símbolo é >=, nunca =>; e os dois caracteres andam colados, sem espaço entre eles.

O resultado de uma comparação é um valor, e pode ser guardado numa variável como qualquer outro:

# O resultado de uma comparacao e um valor, como qualquer outro.
minutos = 137
passou = minutos > 100

print(passou)
print(type(passou))
True
<class 'bool'>

💡 Pense assim: a pergunta de sim ou não

usado_gb > franquia_gb não é um pedido — é uma pergunta fechada, do tipo que só aceita sim ou não: "o que foi usado passou da franquia?".

O Python responde True ou False na hora, com os valores que as variáveis têm naquele momento. Ele não fica vigiando: se o valor mudar na linha seguinte, a resposta que já saiu não muda junto.

== não é =

No capítulo 2 ficou dito que = quer dizer guarde. Ele continua querendo dizer isso. Para comparar, o operador é ==, com dois sinais.

minutos = 100      # guarda 100 em minutos
minutos == 100     # pergunta se minutos vale 100

Trocar um pelo outro dentro de um if não passa despercebido — o Python recusa o programa, e ainda diz o que você provavelmente quis escrever:

minutos = 137

# Dentro de um if a comparacao e ==. O = sozinho nao compara: ele guarda.
if minutos = 100:
    print("Exatamente a franquia.")
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

Este é um erro bem-comportado: ele aparece, tem nome e aponta a linha. Bom começo de unidade — os do próximo capítulo não serão assim.

Cuidado com == entre números com casas decimais

== pergunta se os dois valores são exatamente o mesmo. Com int e com texto, isso é o que você espera. Com float, nem sempre: contas com casas decimais acumulam sobras minúsculas, e 0.1 + 0.2 == 0.3 dá False.

Com valores quebrados, prefira >= e <= — que é o que este semestre usa o tempo todo, porque faixa de consumo e nota de prova são sempre "a partir de".

O if

A forma é sempre esta:

if condição:
    o que fazer quando ela for verdadeira

Duas peças obrigatórias e fáceis de esquecer: os dois-pontos no fim da linha do if, e a indentação das linhas de dentro.

# O if executa o bloco so quando a condicao e verdadeira.
franquia_gb = 20
usado_gb = 17.4

percentual = usado_gb / franquia_gb * 100

print(f"Usado: {percentual:.1f}% da franquia")

if percentual > 80:
    print("ATENCAO: voce ja passou de 80% da franquia.")

print("Fim do relatorio.")
Usado: 87.0% da franquia
ATENCAO: voce ja passou de 80% da franquia.
Fim do relatorio.

Troque usado_gb por 9.0 e rode de novo: o aviso simplesmente não aparece, e o resto do programa segue igual. O bloco do if é a única parte que depende da condição.

A indentação é a sintaxe

Em Python, o que está dentro do if é o que está deslocado para a direita. Não há fim-se, não há chave fechando: o recuo é a marcação, e ele conta para o interpretador exatamente como um parêntese conta.

A convenção é quatro espaços. O OnlineGDB põe os quatro sozinho quando você aperta Enter depois de uma linha terminada em dois-pontos.

# As duas linhas do fim so diferem pela indentacao - e fazem coisas diferentes.
saldo_gb = 9.0

if saldo_gb < 2:
    print("Saldo baixo.")
    print("Dentro do bloco: so sai quando o saldo e baixo.")

print("Fora do bloco: sai sempre.")
Fora do bloco: sai sempre.

saldo_gb vale 9.0, a condição é falsa, e as duas linhas indentadas não rodaram. A terceira rodou — ela nunca esteve dentro do if, ainda que esteja logo embaixo dele.

💡 Pense assim: o parágrafo recuado do contrato

Num contrato, as cláusulas de uma seção ficam recuadas sob o título dela. O que volta à margem esquerda já não pertence àquela seção, mesmo estando na página seguinte.

A indentação do Python é a mesma ideia, e vale para o computador do mesmo jeito que valeria para um juiz: é a margem que diz de quem é a cláusula.

Esquecer o recuo dá erro na hora, e o erro tem nome próprio:

saldo_gb = 1.5

if saldo_gb < 2:
print("Saldo baixo.")
IndentationError: expected an indented block after 'if' statement on line 3

IndentationError: expected an indented block — "eu esperava um bloco recuado aqui". Abrir um if e não pôr nada dentro dele não é uma opção.

Espaço e tabulação não se misturam

Recuar algumas linhas com espaços e outras com Tab produz um programa que parece alinhado na tela e não está. O sintoma é um TabError ou um bloco que teima em não rodar.

Se aparecer, apague a indentação da linha inteira e refaça só com espaços.

O else

if sozinho responde "faço ou não faço". Quando existem dois caminhos e um deles tem de acontecer, entra o else:

# else e o outro caminho: um dos dois blocos sempre roda, nunca os dois.
media = 6.5

if media >= 7:
    print("Aprovado")
else:
    print("Reprovado")

print(f"Media final: {media}")
Reprovado
Media final: 6.5

Três coisas a guardar sobre o else:

  • ele não tem condição — é só else:, e o que ele cobre é "todo o resto";
  • ele é do if imediatamente acima, e fica na mesma margem dele;
  • exatamente um dos dois blocos roda. Nunca os dois, nunca nenhum.

A última linha do exemplo, o print da média, está fora dos dois blocos: ela sai de qualquer jeito.

O % volta, agora como condição

O resto da divisão ganhou um uso no capítulo passado e é aqui que ele rende:

# O % do capitulo 4 volta aqui como condicao.
numero = 137

if numero % 2 == 0:
    print(f"{numero} e par")
else:
    print(f"{numero} e impar")
137 e impar

numero % 2 == 0 é o teste de "é par". Leia a expressão na ordem em que o Python a resolve: primeiro numero % 2, que dá o resto; depois == 0, que compara esse resto com zero. Aritmética antes de comparação, como no capítulo 4.

O mesmo vale para múltiplo de qualquer coisa: n % 5 == 0 pergunta se n é múltiplo de 5.

Decidindo sobre o que a pessoa digitou

Juntando com o capítulo 3, é aqui que o programa fica útil de verdade:

preco_por_minuto = 0.25
minutos_franquia = 100

minutos = int(input("Quantos minutos falados: "))

if minutos > minutos_franquia:
    excedente = minutos - minutos_franquia
    total = excedente * preco_por_minuto
    print(f"Voce passou {excedente} minutos da franquia.")
    print(f"Total a pagar: R$ {total:.2f}")
else:
    print("Dentro da franquia.")
    print("Total a pagar: R$ 0.00")
Quantos minutos falados: Voce passou 37 minutos da franquia.
Total a pagar: R$ 9.25

Repare que o bloco do if tem três linhas, e que a variável excedente só existe lá dentro — ela nem chega a ser criada quando o cliente fica dentro da franquia. Um bloco pode ter quantas linhas você quiser, inclusive contas e novas variáveis; o que o define é o recuo.

E não esqueça o int() em volta do input(). Sem ele, minutos seria o texto "137", e comparar texto com número dá TypeError — desta vez o Python reclama, o que é uma sorte.

O if não volta atrás

Uma última garantia, que parece óbvia e não é: depois que o bloco escolhido roda, o programa segue para a linha seguinte e nunca reavalia a condição. Ele não fica esperando o valor mudar, não repete nada, não tem memória do que decidiu.

Repetir é assunto da Unidade 3. Por enquanto, cada if é uma decisão única, tomada uma vez, no momento em que a linha é executada.

Erros comuns deste capítulo

Mensagem ou sintoma Causa provável
SyntaxError: ... Maybe you meant '==' usou = onde devia ser ==
SyntaxError: expected ':' faltaram os dois-pontos no fim da linha do if
IndentationError: expected an indented block o if abriu e o bloco não foi recuado
IndentationError: unexpected indent uma linha ficou recuada sem if nenhum acima
SyntaxError: invalid syntax na linha do else else com condição, ou else sem if acima
TypeError: '>' not supported between ... 'str' and 'int' faltou int() no input()
a linha de fora saiu junto com a de dentro ela está indentada sem querer
o aviso nunca aparece a condição usa > onde devia ser >=, ou está invertida
o programa roda e a resposta está errada o if testa a coisa certa do lado errado da fronteira

Resumo

  • Uma condição devolve True ou False, e nada mais.
  • Seis operadores: >, <, >=, <=, ==, !=. Colados, e >= nessa ordem.
  • = guarda; == compara. Dentro de um if, é sempre ==.
  • Com float, prefira >= e <= a ==.
  • A forma é if condição: seguida de um bloco indentado com quatro espaços. A indentação é sintaxe, não enfeite.
  • else não tem condição e cobre todo o resto. Um dos dois blocos roda, nunca os dois.
  • n % 2 == 0 é o teste de "é par".

Para praticar

Lista 05 · Condicionais. O formato é o mesmo de sempre: programas inteiros, com a sessão esperada publicada no enunciado. O que muda é que agora cada enunciado traz também uma tabela de outros valores para testar, com a resposta de cada um — porque uma decisão só se prova certa quando você a experimenta nos dois lados da fronteira.

A Parte A continua sendo no papel — e nesta lista ela é a parte que mais ensina.