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)
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))
💡 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.
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.")
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:
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.")
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.")
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:
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}")
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
ifimediatamente 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")
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")
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
TrueouFalse, e nada mais. - Seis operadores:
>,<,>=,<=,==,!=. Colados, e>=nessa ordem. =guarda;==compara. Dentro de umif, é 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. elsenã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.