Comandos Condicionais
Tudo o que vimos até agora consiste em execução sequencial, na qual as instruções são sempre executadas uma após a outra, exatamente na ordem especificada, mas o mundo é mais complicado do que isso e é comum precisarmos avaliar as informações ao nosso redor para, em seguida, escolher uma ação ou outra com base no que observamos. Por exemplo, "Se minha média for maior ou igual a 7, não preciso fazer prova final". Está implícito que, se a média for menor que 7, terei que fazer prova final. O mesmo acontece nos programas que, frequentemente, precisam pular algumas instruções, executar uma série de instruções repetidamente ou escolher entre conjuntos alternativos de instruções para executar. Esse é o objetivo dos comandos/estruturas condicionais: direcionar a ordem de execução das instruções em um programa (conhecido como o fluxo de controle do programa).
Em Python, temos, basicamente, três cláusulas/instruções condicionais: if
, if-else
e if-elif-else
.
Instrução if
Existem situações em que seu programa precisa executar alguma parte do código apenas se uma determinada condição for verdadeira. Uma condição serve para definir quando uma parte do programa deve ser ativada e quando deve ser simplesmente ignorada. A condição é sempre uma expressão booleana, ou seja, seu valor é igual a True
ou False
.
Em um programa Python, a cláusula/instrução if
é usada para executar esse tipo de tomada de decisão. Ela permite a execução condicional de uma instrução ou grupo de instruções com base no valor de uma expressão. Em sua forma mais simples, tem a seguinte aparência:
A expressão booleana depois do if
é chamada de condição. Se for verdadeira, as instruções indentadas (recuadas) são executadas (veja a figura abaixo). Senão, nada acontece. Não há limite para o número de instruções/comandos, mas deve haver pelo menos uma.
Fonte: Learn Python By Example
Perceba que o if
nada mais é que o nosso "se". Podemos então entendê-lo em português da seguinte forma: se a condição for verdadeira, faça alguma(s) coisa(s).
Vamos a um exemplo de como o código com uma expressão condicional deve ser:
- Imprime a média do aluno com duas casas decimais (leia mais detalhes aqui).
Observe que a condição termina com dois-pontos (:
) e uma nova linha começa com um recuo, ou seja, a linha é indentada. Normalmente, quatro espaços são usados para designar cada nível de indentação. Um trecho de código no qual todas as linhas estão no mesmo nível de recuo é chamado de bloco de código. Em Python, apenas indentação é usada para separar diferentes blocos de código, portanto, a indentação mostra quais linhas de código devem ser executadas quando a instrução if
for satisfeita e quais devem ser executadas independentemente da instrução if
. Confira o seguinte exemplo:
Neste exemplo, as linhas 7 e 8 só serão executadas se a média do aluno for menor que 7
. Por outro lado a linha 9 será executada independentemente da média.
O que deveria ser feito (quais as mudanças no código) caso o programador optasse por não criar uma variável que armazena a média?
O código anterior pode ser representado pelo seguinte fluxograma:
Atenção
Não se esqueça da indentação. Uma instrução if
sem indentação gera erro de sintaxe (IndentationError
).
Execute o código abaixo e veja o que acontece.
Vamos agora fazer um programa que leia um inteiro e imprima se o valor lido é par ou ímpar.
Veja o fluxograma do programa anterior:
Para padronizar, na disciplina iremos sempre usar quatro espaços para indentação.
Instrução if
aninhada
Muitas vezes, precisaremos aninhar vários if
para obter o comportamento desejado do programa. Aninhar, nesse caso, é utilizar um if
dentro de outro. Quanto mais instruções if
são aninhadas, mais complexo o código se torna, o que geralmente não é bom. No entanto, isso não significa que precisamos evitar a todo custo instruções if
aninhadas. Vamos dar uma olhada no código abaixo:
O exemplo acima ilustra uma instrução if
aninhada. Se a variável media
for menor que 7
, entramos no bloco da primeira instrução if
. Primeiro imprimimos a mensagem O aluno está de prova final!
, solicitamos o valor da nota da prova final e, se o valor da mediaFinal
for maior ou igual a 5
, uma mensagem dizendo que o alunos foi aprovado, juntamente com sua média, é exibida. Note que também precisamos indentar o bloco de comandos do segundo if
. Veja o fluxograma do código:
Quando se trata de instruções if
aninhadas, uma indentação adequada é crucial, portanto, não se esqueça de indentar cada instrução que começa com a palavra-chave if
.
Execute o código anterior no seu computador com diferentes notas para as provas. Note que:
- Quando o aluno possui média maior ou igual a 7, o programa não avisa que o aluno está aprovado;
- Quando o aluno precisa fazer prova final e a média final é menor que 5, o programa não avisa que o aluno está reprovado.
Vamos deixar o código mais completo?
Instrução if-else
Agora já sabemos como usar uma instrução if
para executar condicionalmente uma única instrução ou um bloco com várias instruções. Entretanto, às vezes, desejamos avaliar uma condição, seguir um caminho se ela for verdadeira e especificar um caminho alternativo se a condição for falsa. Isso é realizado com uma instrução if-else
. Veja a sintaxe:
if <expressão relacional ou lógica>:
<comandos executados se a expressão for verdadeira>
else:
<comandos executados se a expressão for falsa>
A figura abaixo apresenta a estrutura if-else
com mais detalhes:
Fonte: Learn Python By Example
O bloco de código do else
é executado apenas quando a condição de sua instrução if
for falsa. Como uma instrução else
é uma alternativa para uma instrução if
, apenas um bloco de código pode ser executado. Além disso, o else
não requer nenhuma condição. Veja um exemplo simples:
Se o resto quando x
for dividido por 2
for 0
, então sabemos que x
é par e o programa exibe uma mensagem adequada. Se a condição for falsa, o segundo conjunto de instruções é executado. Como a condição deve ser verdadeira ou falsa, exatamente uma das alternativas será executada. As alternativas são chamadas de ramos (branches), porque são ramos no fluxo da execução. O fluxograma abaixo representa o código anterior:
Nosso próximo exemplo imprime o maior e o menor de dois números lidos da entrada.
primeiro = int(input("Enter the primeiro number: "))
segundo = int(input("Enter the segundo number: "))
if primeiro > segundo:
maior = primeiro
menor = segundo
else:
maior = segundo
menor = primeiro
print("Maior:", maior)
print("Menor:", menor)
Exercício
Usando a instrução if-else
refaça o código abaixo:
Instrução if-else
aninhada
Como você pode imaginar as instruções if-else
também podem ser aninhadas da mesma forma que as instruções if
. Uma expressão condicional adicional pode aparecer após a seção if
e também após a seção else
. Mais uma vez, lembre-se de indentar corretamente.
Vamos a um exemplo: uma empresa telefônica oferece planos diferenciados de acordo com a quantidade de minutos usados por mês. Abaixo de 200 minutos, a empresa cobra R$0,20 por minuto. Entre 200 e 400 minutos, o preço é R$0,18. Acima de 400 minutos, o preço por minuto é de R$0,15. O programa abaixo resolve esse problema.
Pergunta
Observe a linha 5, por que a condição do if
não foi minutos >= 200 and minutos < 400
?
Dica
Em Python, a condição minutos >= 200 and minutos < 400
também poderia ser feita da seguinte forma: 200 <= minutos < 400
(mais natural).
Lembre-se
O que define a qual bloco de comandos um conjunto de comandos pertence é a sua indentação!
Vamos a mais um exemplo: faça um programa que leia a categoria de um produto e determine o preço do mesmo de acordo com a tabela abaixo:
Categoria | Preço |
---|---|
1 | R$ 10,00 |
2 | R$ 18,00 |
3 | R$ 23,00 |
4 | R$ 26,00 |
5 | R$ 31,00 |
O programa abaixo resolve este problema:
Observe que o alinhamento se tornou um grande problema, uma vez que temos que deslocar à direita a cada else
.
Vejamos quais linhas, baseado no código apresentado, serão executadas dependendo da categoria digitada:
Categoria | Linhas executadas |
---|---|
1 | 1,2,3,4,19 |
2 | 1,2,3,5,6,7,19 |
3 | 1,2,3,5,6,8,9,10,19 |
4 | 1,2,3,5,6,8,9,11,12,13,19 |
5 | 1,2,3,5,6,8,9,11,12,14,15,16,19 |
outras | 1,2,3,5,6,8,9,11,12,14,15,17,18,19 |
No programa introduzimos o conceito de validação de entrada, ou seja, se o usuário digitar um valor inválido, receberá uma mensagem de erro na tela. No entanto, a linha 19 continua sendo executada, mesmo que seja digitado um valor inválido. Por exemplo, o que acontece se for digitado 6? Faz sentido o programa gerar a saída mostrada quando é digitado um valor inválido?
Exercícios
- Modifique o programa para que o mesmo só imprima o preço do produto (linha 19) se for digitado um valor válido para a categoria.
- Após a modificação anterior, reimplemente o código usando apenas a instrução
if
(não vale usar oif-else
).
Instrução if-elif-else
Note que no código presente em precoProduto.py, assim que um if
for verdadeiro, nenhum dos if
's posteriores serão verificados, pois estes estão dentro do caso else
do if
verdadeiro. Perceba também que só será impresso "Categoria inválida"
quando as condições dos cinco if
's anteriores forem falsas. Este tipo de construção é muito comum em programas, onde só deve ser executada uma opção dentre todas as alternativas possíveis. Este é o caso do programa anterior. Além disso, observe que o alinhamento se tornou um grande problema, uma vez que temos que deslocar à direita a cada else
. Imagine se tivéssemos mais categorias.
Python apresenta uma solução muito interessante ao problema de múltiplos if
's aninhados. A cláusula elif
substitui um par else if
, mas sem criar outro nível de estrutura evitando problemas de deslocamentos desnecessários à direita. Veja a sintaxe:
if <condição1>:
<comandos executados se condição1 for verdadeira>
elif <condição2>:
<comandos executados se a condição1 for falsa e a condição2 for verdadeira>
elif <condição3>:
<comandos executados se a condição1 e condição2 forem falsas e a condição3 for verdadeira>
...
elif <condiçãoN>:
<comandos executados se as condição1, condição2, ..., e condiçãoN-1 forem falsas e a condiçãoN for verdadeira>
else:
<comandos executados se nenhum condição for verdadeira>
A figura abaixo apresenta a estrutura if-elif-else
com mais detalhes:
Fonte: Learn Python By Example
Vamos a um exemplo simples: ler dois números e verificar se o primeiro é maior, menor ou igual ao segundo número. Abaixo temos três soluções:
- Usando apenas a instrução
if
:
x = float(input("Digite o primeiro número: "))
y = float(input("Digite o primeiro número: "))
if x > y:
print("O maior número é o primeiro")
if x < y:
print("O maior número é o segundo")
if x == y:
print("Os dois números são iguais")
- Usando apenas a instrução
if-else
:
x = float(input("Digite o primeiro número: "))
y = float(input("Digite o primeiro número: "))
if x > y:
print("O maior número é o primeiro")
else:
if x < y:
print("O maior número é o segundo")
else:
print("Os dois números são iguais")
- Usando apenas a instrução
if-elif-else
:
x = float(input("Digite o primeiro número: "))
y = float(input("Digite o primeiro número: "))
if x > y:
print("O maior número é o primeiro")
elif x < y:
print("O maior número é o segundo")
else:
print("Os dois números são iguais")
Perceba que apenas um dos print
deve ser executado, por isso a primeira solução (usando apenas if
) não é uma boa estratégia. Por quê? A segunda solução (usando if-else
aninhados), em relação a terceira (usando if-elif-else
), apresenta a desvantagem do uso "excessivo" de indentação.
Vamos voltar ao nosso problema inicial, onde deveríamos ler a categoria de um produto e determinar o preço do mesmo. O código abaixo resolve esse problema, mas agora usando if-elif-else
.
Compare os dois códigos e veja que usar if-elif-else
deixa o código muito mais elegante e legível 😉. Note também que houve uma redução do número de linhas 😀.
Exercício
Caso seja digitado o valor 6 para a categoria, o que seria impresso pelo programa? Modifique o programa para que o mesmo só exiba o preço do produto se for digitado uma categoria válida, ou seja, um valor entre 1 e 5.
Pergunta
A instrução else
é obrigatória em todas as estruturas condicionais? Ou seja, um if
(ou if-elif
) sempre precisa ter um else
?
Expressão ternária
Em diversas situações, o valor a ser atribuído a uma variável, impresso ou retornado por um método depende de uma condição. Por exemplo:
Perceba que o valor de x
depende da condição estabelecida sobre o valor de y
. O código acima pode ser representado através de uma sintaxe mais concisa e de fácil leitura:
A expressão acima poderia ser lida da seguinte forma: Atribua 3 a x se y for 1, caso contrário atribua 2 a x
. Pare este caso os parênteses não são necessários, mas foram usados para melhorar a legibilidade.
Uma expressão ternária (às vezes chamada de "operador ternário" ou "expressão condicional") nos permite selecionar uma das duas declarações, dependendo da condição especificada. A sintaxe da expressão ternária é:
Fonte: Learn Python By Example
Primeiro, a condição é avaliada, se for verdadeira, <expressao1>
é executada e seu valor é retornado; caso contrário, <expressao2>
é executada e seu valor retornado.
Exemplos:
Também é permitido o uso de encadeamento:
Exercício
Transforme a expressão ternária anterior em uma estrutura condicional if-elif-else
.
Variáveis flags
Em algumas situações, precisamos usar uma variável para armazenar um estado do programa. Por exemplo, podemos criar uma variável para indicar se um sistema está funcionando corretamente (ou se apresentou alguma falha) ou se foi digitado, em todas as entradas, valores válidos. Normalmente inicializamos esta variável com um valor padrão (por exemplo, True
) e atualizamos a variável caso uma mudança de estado ocorra (trocando o valor, por exemplo, para False
).
Este tipo de variável, que serve para sinalizar uma situação específica, é chamada de flag. Uma variável flag pode simplificar significativamente a escrita, manutenção e o entendimento de um programa. Vamos a um exemplo hipotético, onde devemos verificar se um programa está funcionando corretamente, ou seja, se nenhuma falha ocorreu. O código abaixo exibe uma solução sem o uso de uma variável flag.
Observe que para sabermos se o sistema está funcionando corretamente, o último if
(linha 12) ficou extremamente grande e a chance de cometermos algum erro (por exemplo, esquecermos de chegar alguma condição) é muito alta. Vamos ver como podemos simplificar esse if
usando uma variável flag.
Material Complementar
Complemente sua leitura e seu conhecimento: