Você está na página 1de 3

MAC2166 – Turma 04 (semana de 16 a 20 de março de 2020)

Professor: Flávio Soares Corrêa da Silva (fcs@ime.usp.br)

Resolveremos um exercício mais extenso, através do qual repassaremos itens correspondentes


a diversas aulas:

• Condições booleanas compostas usando operadores and, or, not


• A técnica do “indicador de passagem”
• Aninhamento de condições e repetições

Vimos nas aulas anteriores que repetições (while CONDIÇÃO) e condições (if CONDIÇÃO) são
controladas por condições booleanas, ou seja, cujos valores podem ser True ou False em
Python.

Estas condições podem ser combinadas para produzir condições mais elaboradas.

Por exemplo, se quisermos somar números enquanto não recebermos um número que seja
ímpar ou negativo, podemos escrever:
def main():
soma = 0
valor = 0
while valor % 2 == 0 and valor >= 0:
soma = soma + valor
valor = int(input(“Valor: “))
print(soma)
Ou seja, o programa determina “some números enquanto receber valores pares E (and) não-
negativos”.

Apenas como um exemplo complementar a este, se quisermos somar números enquanto não
recebermos um número que seja simultaneamente ímpar e maior do que 10, podemos
escrever:
def main():
soma = 0
valor = 0
while valor % 2 == 0 or valor <= 10:
soma = soma + valor
valor = int(input(“Valor: “))
print(soma)
Ou seja, o programa determina “some números enquanto receber valores que atendam pelo
menos uma das condições: ser par OU ENTÃO (or) não ser maior que 10”.

O conjunto de operadores disponíveis para construir condições é and, or e not, sendo que este
último “inverte” o valor de um teste. Parenteses auxiliares podem ser usados para impedir que
certas expressões fiquem ambíguas. Por exemplo, considere a condição:
(X < 0) or ((X > 100) and not ((X < (Y % 100)) or (X < (Z % 100))))
Esta condição poderia estar sendo usada diante de um if ou de um while. Ela contém muitos
parênteses auxiliares. Alguns são necessários em Python para evitar ambiguidades, outros são
desnecessários, mas ajudam o programador a evitar erros. Você consegue escrever em
português o que esta condição exige para ter valor True?
As condições compostas usando estes operadores booleanos permitem construir programas
eficientes com a técnica conhecida como “indicador de passagem”, que consiste em definir um
teste booleano que possa eliminar a chance de uma condição se encontrada em um conjunto.
Se o teste produzir um determinado valor (True, por exemplo), uma repetição pode ser
encerrada.

Por exemplo, considere uma sequência de N números inteiros: 10, 2, 5, 8, -14, 7, 9. Considere
o seguinte exercício: Construir um programa que receba N (vamos assumir, para simplificar,
que N > 0) e uma sequência de N números inteiros que possa conter alguns valores negativos e
responda quantos valores pares ocorreram antes da primeira ocorrência de um valor negativo.
Ou seja, se a sequência não contiver números negativos, o programa deve devolver a própria
quantidade N, caso contrário ele deve parar já antes de receber todos os N números e
devolver a quantidade obtida até aquele ponto.

Neste caso, o “indicador de passagem” é a recepção de um número negativo.

O programa pode ser escrito assim:


def main():
soma = 0
N = int(input(“N: “))
i = 0
valor = int(input(“valor: “))
while valor >= 0 and i < N:
soma = soma + valor
valor = int(input(“proximo valor: “))
i = i + 1
print(soma)
Vale a pena testar este programa com diferentes sequências de valores de entrada para
verificar o que ele faz. Se ele receber somente valores não negativos, ele irá até o final e
somará todos os N valores fornecidos. Se, em algum momento, ele receber um valor negativo,
ele mudará de estado, ou seja, passará de um estado para outro. O “indicador de passagem” é
o número negativo. Neste caso, o “outro estado” interrompe o programa e já apresenta a
resposta.

Esta técnica permite construir programas eficientes e organizados.

O último item previsto para esta aula é o aninhamento de condições e repetições. Para isso,
finalmente apresentaremos o exercício mais extenso, conforme prometido no início destes
apontamentos.

(cá entre nós, espero que este exercício ajude a resolver o EP...)

Eis o exercício: dados dois números naturais V1 e V2, V1≤V2 que determinam o intervalo [V1,
(V1+1), ..., V2], e dados dois outros números naturais D1 e D2, D1≤D2 que determinam o
intervalo [D1, (D1+1), ..., D2], imprimir os valores no intervalo definido por V1 e V2 que
atendam à condição de não serem divisíveis por nenhum dos números no intervalo definido
por D1 e D2.

Ou seja, precisaremos testar todos os números dentro do intervalo definido por V1 e V2. Para
cada número, o teste corresponderá a testar a divisibilidade por todos os números dentro do
outro intervalo, definido por D1 e D2. Se o número for divisível uma vez que seja, o teste
poderá ser interrompido. Se o número passar por todos os testes, ele deverá ser impresso.
Esmiuçando um pouco mais, precisaremos repetir um teste para todos os números no
intervalo definido por V1 e V2. Cada um destes testes precisará percorrer os valores dentro do
outro intervalo, definido por D1 e D2. Precisaremos, portanto, de uma repetição dentro da
outra, ou seja, uma “repetição aninhada”.

Veja o programa abaixo, depois de ter tentado resolver por sua conta:
def main():
V1 = int(input(“V1: “))
V2 = int(input(“V2: “))
D1 = int(input(“D1: “))
D2 = int(input(“D2: “))
valor = V1
while valor <= V2:
divisor = D1
while valor % divisor != 0 and divisor <= D2:
divisor = divisor + 1
if divisor > D2:
print(valor)
valor = valor + 1
Algumas perguntas:
1. Você consegue entender uma repetição dentro da outra?
2. Você consegue entender a condição depois da repetição mais interna?
3. Você consegue enxergar o indicador de passagem na repetição mais interna?
4. O que acontece se D1 for igual a zero? Será que o exercício precisaria ser ligeiramente
reformulado para evitar esta condição?

Você também pode gostar