Introdução à Lógica de Programação

Um curso prático para estudantes das Ciências da Vida


Aula 3. Estruturas Condicionais

Instrutor: Pedro C. de Siracusa

Condicionais são estruturas de decisão fundamentais nas linguagens de programação que permitem que um programa altere seu comportamento em tempo de execução, dependendo do estado em que se encontra. Podemos imaginar um programa em execução como um trem viajando sobre um trilho. Algumas bifurcações podem existir ao longo do percurso, e o caminho tomado pelo trem nestes pontos deve ser selecionado através de manivelas de controle. Dependendo da posição em que se encontra a manivela, o trem pode tomar um ou outro caminho, mas nunca seguir nos dois ao mesmo tempo.

Estruturas condicionais permitem alterar o fluxo de execução de um programa através da verificação de condições, que podem ser codificadas em nosso programa por meio de expressões lógicas.

Objetivos.

Após esta aula você deverá ser capaz de:

  • Reconhecer os principais operadores lógicos e de comparação;
  • Construir e computar expressões lógicas;
  • Construir estruturas condicionais.

1. Expressões lógicas

Expressões lógicas são aquelas cuja avaliação resulta em valores do tipo booleano: verdadeiro (True) ou falso (False). Os dois principais tipos de operadores para construir expressões lógicas são:

  • operadores de comparação: permitem comparar os valores de um par de objetos, e retornam True caso sejam equivalentes e False caso contrário;
  • operadores lógicos: úteis para combinar resultados booleanos obtidos de várias comparações, permitindo construir estruturas de decisão mais complexas.
Operador Descrição
Operadores de comparação
== True se valores de dois operandos são iguais
!= True se valores de dois operandos são diferentes
< True se valor do operando à esquerda é menor que o da direita
<= True se valor do operando à esquerda é menor ou igual ao da direita
> True se valor do operando à esquerda é maior que o da direita
>= True se valor do operando à esquerda é maior ou igual ao da direita
Operadores lógicos
and Operador lógico "E"
or Operador lógico "OU"
not Operador lógico "NÃO"

Vamos escrever algumas expressões lógicas.

Operações de comparação
In [1]:
# A expressão 5=5 é válida?
5==5
Out[1]:
True
In [2]:
# A expressão 5=3 é válida?
5==3
Out[2]:
False
In [3]:
# 5 é diferente de 7?
5 != 7
Out[3]:
True
In [4]:
# 5 é maior ou igual a 5?
5 >= 5
Out[4]:
True
In [5]:
# 7 é menor que 10?
7 < 10
Out[5]:
True
Operações lógicas
In [6]:
p = True
q = True

print("P and Q:", p and q )
print("P or Q:", p or q )
print("not P:", not p )
print("not Q:", not q)
P and Q: True
P or Q: True
not P: False
not Q: False
In [7]:
p = True
q = False

print("P and Q:", p and q )
print("P or Q:", p or q )
print("not P:", not p )
print("not Q:", not q)
P and Q: False
P or Q: True
not P: False
not Q: True
In [8]:
p = False
q = True

print("P and Q:", p and q )
print("P or Q:", p or q )
print("not P:", not p )
print("not Q:", not q)
P and Q: False
P or Q: True
not P: True
not Q: False
In [9]:
p = False
q = False

print("P and Q:", p and q )
print("P or Q:", p or q )
print("not P:", not p )
print("not Q:", not q)
P and Q: False
P or Q: False
not P: True
not Q: True
In [10]:
True and not False and True
Out[10]:
True
In [11]:
True or False and True
Out[11]:
True
Operações lógicas envolvendo comparação
In [12]:
# False and True -> False
(4 > 5) and (3==3)
Out[12]:
False
In [13]:
# True or False -> True
(4 > 5) or (3==3)
Out[13]:
True
In [14]:
# not(True or False) -> False
not( 4>5 or 3==3 )
Out[14]:
False
In [15]:
# True and True and False -> False
4<5 and 3==3 and 5>5
Out[15]:
False
In [16]:
# True or True or False -> True
4<5 or 3==3 or 5>5
Out[16]:
True

Agora que já sabemos codificar condições, podemos de fato construir estruturas condicionais.

2. Construindo Condicionais

Estruturas condicionais podem ter diferentes níveis de complexidade, dependendo do conjunto de condições

A construção if

A construção if é a estrutura mais simples de escrevermos um bloco de código $A$ que somente deve ser executado caso uma determinada condição seja satisfeita (ou seja, avaliada como True). Caso contrário, o código $A$ é simplesmente ignorado.

In [17]:
cond = False

print("Antes de chegar na estrutura condicional (sempre executa)")

if cond:
    print("Executo código A")
  
print("Depois da estrutura condicional (sempre executa)")
Antes de chegar na estrutura condicional (sempre executa)
Depois da estrutura condicional (sempre executa)

A construção if else

Um if pode ser associado a um else, contendo um bloco de código que é executado casa a condição do if não seja satisfeita (ou seja, avaliada como False).

In [18]:
cond = False

print("Antes de chegar na estrutura condicional (sempre executa)")

if cond:
    print("Executo código A")
else:
    print("Executo código B")
print("Depois da estrutura condicional (sempre executa)")
Antes de chegar na estrutura condicional (sempre executa)
Executo código B
Depois da estrutura condicional (sempre executa)

As duas construções tratadas acima se baseiam na verificação de apenas uma condição, que dependendo de como for avaliada (True ou False), desencadeia um dentre dois possíveis comportamentos. Mas e se desejarmos construir uma estrutura condicional que permita mais do que apenas dois "caminhos" diferentes? Neste caso precisamos verificar mais do que uma única condição.

Condicionais aninhadas

A primeira forma de incluir mais mais do que uma condição a ser testada na estrutura condicional é por aninhamento. Como resultado, teremos uma estrutura hierárquica, em que a execução de uma segunda condição depende do resultado de uma primeira condição. Não há limites para o número de níveis hierárquicos em uma estrutura condicional, apesar de que muitos níveis hierárquicos podem tornar o código mais difícil de entender.

Cuidado! Em Python é fundamental respeitar o nível de indentação dos blocos de código em cada nível hierárquico!

In [19]:
cond1 = False
cond2 = False

print("Antes de chegar na estrutura condicional (sempre executa)")

if cond1:
    print("Executo código A. Não importa a cond2")
else:
    if cond2:
        print("Executo código B. A cond1 foi False")
    else:
        print("Executo código C. A cond1 foi False")

print("Depois da estrutura condicional (sempre executa)")
Antes de chegar na estrutura condicional (sempre executa)
Executo código C. A cond1 foi False
Depois da estrutura condicional (sempre executa)

A construção if elif else

Uma sequência de vários if e else aninhados pode inserir muitos níveis de indentação no código, tornando-o confuso. Para evitar este problema, usamos a construção podemos inserir novas condições a serem verificadas usando a palavra elif. Pense no elif como uma fusão entre um else e um if. O else no final captura qualquer caso em que nenhuma das condições anteriores foram satisfeitas.

In [20]:
cond1 = False
cond2 = False

print("Antes de chegar na estrutura condicional (sempre executa)")

if cond1:
    print("Executo código A. Não importa a cond2")
elif cond2:
    print("Executo código B. A cond1 foi False")
else:
    print("Executo código C. A cond1 foi False")

print("Depois da estrutura condicional (sempre executa)")
Antes de chegar na estrutura condicional (sempre executa)
Executo código C. A cond1 foi False
Depois da estrutura condicional (sempre executa)

Exercícios

Ex 1. Verifique se as igualdades abaixo são verdadeiras:

(a) $2 \times 2.0 = 4$

In [21]:
2*2.0==4
Out[21]:
True

(b) $2 \times 3 = 5$

In [22]:
2*3==5
Out[22]:
False

(c) $4a + 3 = b$, para $a=3$ e $b=15$ (primeiro declare as variáveis a e b)

In [23]:
a=3
b=15

4*a+3 == b
Out[23]:
True

Ex 2. Complete o código na célula abaixo para imprimir uma mensagem informando se um aluno foi aprovado ou reprovado em uma disciplina com base em sua nota final. A nota mínima necessária para aprovação é $5$.

In [24]:
notaAluno = 5 # insira aqui a nota do aluno

if notaAluno >= 5:
    print("Aprovado! =]")
else:
    print("Reprovado =(")
Aprovado! =]

Ex 3. Construa uma função que calcule a média final e menção dos alunos com base nas notas das três provas (com pesos de 20% para as duas primeiras e 60% para a terceira). Divida o problema em duas etapas. Primeiro, você deverá calcular a média das provas com os devidos pesos. Depois, atribuir a menção conforme a seguinte regra:

$ se \quad média \ final \geq 9 : menção = SS \\ se \quad 7 \leq média \ final < 9 : menção = MS \\ se \quad 5 \leq média \ final < 7 : menção = MM \\ se \quad 3 \leq média \ final < 5 : menção = MI \\ se \quad média \ final < 3 : menção = II \\ $

In [25]:
def calculaMedia(p1,p2,p3):
    return p1*0.2 + p2*0.2 + p3*0.6

def calculaMencao( p1,p2,p3 ):
    media = calculaMedia(p1,p2,p3)
    print("Média foi",media)
    
    if media >= 9:
        return "SS"
    elif media >= 7:
        return "MS"
    elif media >= 5:
        return "MM"
    elif media >= 3:
        return "MI"
    else:
        return "II"
In [26]:
calculaMencao(3,2,3)
Média foi 2.8
Out[26]:
'II'
In [27]:
calculaMencao(3,3,4)
Média foi 3.6
Out[27]:
'MI'
In [28]:
calculaMencao(3,3,7)
Média foi 5.4
Out[28]:
'MM'
In [29]:
calculaMencao(7,8,10)
Média foi 9.0
Out[29]:
'SS'

Ex 4. Construa uma pequena chave dicotômica para identificar uma determinada planta como membro de um dos principais grupos: Bryophyta, Pteridophyta, Gymnospermae ou Angiospermae. A identificação se dá com base na presença (1) ou ausência (0) de três caracteres: vascularização, sementes e flores. Utilize a tabela abaixo como referência.

Grupo Vascularização Sementes Flores
Bryophyta 0 0 0
Pteridophyta 1 0 0
Gymnospermae 1 1 0
Angiospermae 1 1 1
In [30]:
# Estas variáveis armazenam a presença (1) ou ausência (0) de cada caractere
vasc = 1
sem = 1
flor = 0

if vasc==0 and sem==0 and flor==0:
    print("Bryophyta")
elif vasc==1 and sem==0 and flor==0:
    print("Pteridophyta")
elif vasc==1 and sem==1 and flor==0:
    print("Gymnospermae")
elif vasc==1 and sem==1 and flor==1:
    print("Angiospermae")
else:
    print("Não há plantas com estas características")
Gymnospermae

Ex 5. Encapsule o código que você construiu no exercício anterior. Para isso, construa uma função de nome chave, que recebe como argumentos cada um dos caracteres e retorna o nome do devido grupo botânico.

In [31]:
def chave(vasc, sem, flor):
    if vasc==0 and sem==0 and flor==0:
        return "Bryophyta"
    elif vasc==1 and sem==0 and flor==0:
        return "Pteridophyta"
    elif vasc==1 and sem==1 and flor==0:
        return "Gymnospermae"
    elif vasc==1 and sem==1 and flor==1:
        return "Angiospermae"
    else:
        print("Não há plantas com estas características")
        return
    return
In [32]:
chave(vasc=0, sem=0, flor=0)
Out[32]:
'Bryophyta'
In [33]:
chave(vasc=1, sem=0, flor=0)
Out[33]:
'Pteridophyta'
In [34]:
chave(vasc=1, sem=1, flor=0)
Out[34]:
'Gymnospermae'
In [35]:
chave(vasc=1, sem=1, flor=1)
Out[35]:
'Angiospermae'
In [36]:
chave(vasc=0, sem=1, flor=0)
Não há plantas com estas características