Como comparar idades em lista python

Até aqui, trabalhamos com variáveis simples, capazes de armazenar apenas um tipo, como bool, float e int.

Nessa aula introduziremos o conceito de lista (= tipo list), uma estrutura sequencial indexada muito utilizada e uma das principais estruturas básicas do Python.

Uma lista (= list) em Python é uma sequência ou coleção ordenada de valores de qualquer tipo ou classe tais como int, float, bool, str e mesmo list, entre outros.

Diariamente utilizamos listas para organizar informação, como a lista de coisas a fazer, lista de compras, lista de filmes em cartaz etc.

Existem várias maneiras de criarmos uma lista. A maneira mais simples é envolver os elementos da lista por colchetes ( [ e ]). Podemos criar a lista contendo os 5 primeiros primos da seguinte maneira:

>>> primos = [2, 3, 5, 7, 11]

Podemos criar uma lista de vários objetos de tipos distintos:

>>> uma_lista = [11, "oi", 5.4, True] >>> outra_lista = ["joão", "masculino", 15, 1.78, "brasileira", "solteiro"] >>> fernanda = ["Fernanda", "Montenegro", 1929, "Central do Brasil", 1998, "Atriz", "Rio de Janeiro, RJ"]

Observe o uso de colchetes ([, ]) para marcar o início e o final da lista, e os elementos separados por vígula.

Uma lista pode ser criada vazia, da seguinte forma:

A função len() retorna o comprimento (= o número de elementos ou objetos) de uma lista:

>>> len(primos) 5 >>> len(uma_lista) 4 >>> len(outra_lista) 6 >>> len(fernanda) 7 >>> len(lista_vazia) 0

Cada valor na lista é identificado por um índice.

Dizemos que uma lista é uma estrutura sequencial indexada pois os seus elementos podem ser acessados sequencialmente utilizando índices. O primeiro elemento da lista tem índice 0, o segundo tem índice 1, e assim por diante. Observe que, por começar pelo índice zero, o último elemento da lista primos, o número 11, tem índice 4, sendo que essa lista tem comprimento 5.

Para acessar um elemento de uma lista usamos o operador de indexação []. A expressão dentro dos colchetes especifica o índice. O índice do primeiro elemento é 0. O seguinte programa imprime os valores da lista primos:

primos = [2, 3, 5, 7, 11] i = 0 while i < len(primos): print( "elemento de indice %d = %d"%(i, primos[i]) ) i = i + 1

Simule a execução desse programa e observe que a variável i recebe o valor zero que corresponde ao primeiro índice e, enquanto o índice for menor que o comprimento da lista (= len(primos)), o elemento de índice i é impresso.

Índices negativos indicam elementos da direita para a esquerda ao invés de da esquerda para a direita.

numeros = [17, 123, 87, 34, 66, 8398, 44] print("%3d: %d" %(2,numeros[2])) print("%3d: %d" %(5,numeros[-5])) print("%3d: %d" %(9-8,numeros[9-8])) print("%3d: %d" %(-2,numeros[-2])) print("%3d: %d" %(len(numeros)-1,numeros[len(numeros)-1])) print("%3d: %d" %(-7,numeros[-7]))

Um erro comum em programas é a utilização de índices inválidos (= list index out of range):

numeros = [17, 123, 87, 34, 66, 8398, 44] print("%3d: %d" %(len(numeros),numeros[len(numeros)])) # índice inválido

numeros = [17, 123, 87, 34, 66, 8398, 44] print("3d: %d" %(-8,numeros[-8])) # índice inválido

lista_vazia = [] lista_vazia[0] = 10 # índice inválido

Nota sobre eficiência computacional

Por ser um curso introdutório, utilizaremos nesse curso apenas as operações de concatenação e fatiamento de listas. Nosso objetivo é empoderar os alunos para que eles possam entender, aprender e usar essas estruturas rapidamente em seus programas, independente da eficácia computacional dessas soluções, permitindo que o aluno mantenha foco no problema e não na linguagem. O custo computacional dessas soluções será abordado em cursos mais avançados.

Duas listas podem ser concatenadas utilizando o operador +.

um = [10, 11, 12] dois = [20, 21] tres = um + dois print(tres)

Nesse exemplo, a concatenação da lista um com a lista dois cria uma nova lista formada por cópias dos elementos da lista um e dois.

Uma lista vazia é o elemento neutro da concatenação de listas:

um = [10, 11, 12] dois = [20, 21] tres = um + [] + dois + [] print(tres)

O exemplo abaixo, concatena a lista um três vezes:

um = [10, 11, 12] tres = um + um + um print(tres)

Para concatenar uma lista repetidas vezes, podemos utilizar o operador * para multiplicar uma lista por um inteiro:

um = [10, 11, 12] print("um + um + um", um + um + um) print("3 * um", 3 * um) print("um * 3", um * 3) print("[] * 3", [] * 3)

Observe que, assim como o * em operações aritméticas, o operador de repetição * de listas também é comutativo, assim como a repetição de listas vazias resulta em uma lista vazia.

O operador de repetição * é bastante útil para criar uma lista de comprimento N com valor inicial determinado como:

# cria lista de tamanho n com zeros n = int(input("Digite o tamanho da lista: ")) lista = [0] * n print(lista)

Muitas vezes, ao invés de considerar a lista completa, é necessário consider apenas um pedaço contínuo da lista, que podemos definir por 2 índices que marcam o início e o fim desse pedaço, que chamamos de fatia da lista.

Em Python, uma fatia de uma lista é definida colando o ínicio e o fim entre colchetes, separados por :, como:

>>> primos = [2, 3, 5, 7, 11] >>> primos[1:2] [3] >>> primos[2:4] [5, 7] >>> primos[:3] # observe que o início não precisa ser definido [2, 3, 5] >>> primos[3:] # observe que o fim não precisa definido [7, 11] >>> primos[:] [2, 3, 5, 7, 11]

Observe que o intervalo é sempre fechado à esquerda (inclui o primeiro elemento na fatia) e aberto à direita (não inclui o último elemento). A operação de fatiamento devolve uma cópia do pedaço da lista definido pelo intervalo.

Quando uma lista é atribuída a uma variável, dizemos que a variável passa a fazer uma referência a lista. Assim, várias variáveis com nomes distintos podem fazer referência a mesma lista.

CodeLens: (clonar_uma_lista_0)

Nesse exemplo, para que possamos trabalhar com a lista_2 sem alterar os elementos da lista_1, precisamos copiar a lista_1.

A forma mais comum para copiar uma lista é criando uma fatia da lista inteira como:

lista_1 = ["oi", 2, 3.14, True] lista_2 = lista_1[:] # cria uma cópia da lista_1 lista_2[2] = 5 print(lista_1) # observe que o elemento lista_1[2] NÃO foi modificado

Vários problemas envolvendo listas requerem percorrer (varrer) todos os elementos da lista, um a um, do início até o fim. Nesses casos, podemos utilizar o comando for:

CodeLens: (exemplo_percorrer_lista_com_for_elem)

Para usar o comando for, você precisa definir uma variável que vai receber o valor de um elemento da lista a cada iteração. Nesse exemplo, a variável elemento recebe o valor de cada elemento da lista primos, ou seja, primeiro o valor 2, depois 3, 5, e assim por diante, até 13. A repetição termina quando o último elemento da lista primos for utilizado.

Observe também que a varredura da lista pode ser feita usando o comando while. A sequência de índices válidos é gerada variando a variável i de 0 até len(primos).

Muitas vezes é mais conveniente varrer uma lista usando uma variável que assume valores dentro do intervalo dos índices válidos. Com isso, temos mais poder e flexibilidade no acesso aos elementos da lista, como por exemplo, varrer a lista da direita para a esquerda, ou pegar apenas os elementos de índice par.

Nesses casos também, quando queremos ter controle sobre os índices, é muito comum utilizar o comando for em conjunto com a função range(). Basicamente, devemos chamar a função range() para que ela “devolva uma lista” contendo os valores dos índices que queremos utilizar.

A função range() recebe 3 parâmetros: início, fim e passo, que definem a sequência de números a ser criada. Modifique o trecho de programa abaixo para ver como a função range se comporta em conjunto com o for:

inicio = 10 fim = 20 passo = 3 for i in range(inicio, fim, passo): print( i )

Observe que, como na definição de intervalos em fatias de lista, o intervalo de números cobertos pela função range() é fechado no início e aberto no fim.

Quando o passo desejado é 1 (um), o valor não precisa ser passado a função range(), como abaixo:

inicio = 5 fim = 11 for i in range(inicio, fim): print( i )

Para facilitar mais ainda a varredura de listas, quando o início desejado é 0 (zero) e o passo 1 (um), você pode definir apenas o fim, como:

primos = [2, 3, 5, 7, 11, 13] for i in range(len(primos)): print( "%d: %d"%(i,primos[i]) )

Nesse exemplo, usando a função len() o final do intervalo a ser gerado pela função range(). Para saber mais sobre essa função, consulte a documentação da função range().

Para verificar se você entendeu como funciona a função range(), modifique o inicio, fim e passo no trecho de programa abaixo para varrer a lista de forma reversa, ou seja, da direita para a esquerda.

primos = [2, 3, 5, 7, 11, 13] # modifique os valores abaixo inicio = 0 fim = len(primos) passo = 1 for i in range(inicio, fim, passo): print( "%d: %d"%(i,primos[i]) )


Page 2

  • Funções;

  • Variáveis locais;

  • documentação: docstring

O número de combinações possíveis de m elementos em grupos de n elementos (n <= m) é dada pela fórmula de combinação m!/((m-n)!n!).

Escreva um programa que lê dois inteiros m e n e calcula a combinação de m, n a n.

# Escreva o seu programa def main(): #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Clique aqui para ver uma solução.

Observe que o pedaço de código que calcula o fatorial é repetido várias vezes. Uma importante ferramenta computacional é a capacidade de abstrair partes relevantes e/ou que se repetem mais de uma vez na forma de funções.

Para declarar uma função em Python faça o seguinte:

def nome_da_função ( parâmetros ): ''' docstring contendo comentários sobre a função. Embora opcionais são fortemente recomendados. Os comentários devem descrever o papel dos parâmetros e o que a função faz. ''' # corpo da função | | bloco de comandos |

Para nos prevenir de alguns problemas (que serão explicados mais tarde), vamos adotar nesse curso o seguinte esqueleto para escrever programas em Python com funções. Nesse esqueleto, a primeira função sempre será chamada de main e corresponderá a função principal do programa, ou seja, aquela que resolve o problema. As demais funções auxiliares devem ser definidas, em qualquer ordem, após a definição da main e, por fim, para executar o programa, a função main precisa ser chamada.

# função principal def main(): ''' Função principal, será a primeira a ser executado e será a responsável pela chamada de outras funções que por sua vez podem ou não chamar outras funções que por sua vez ... ''' # corpo da função main | | bloco de comandos | # Declaração das funções def f( parâmetros_de_f ): ''' docstring da função f ''' # corpo da função f | | bloco de comandos | def g( parâmetros_de_g ): ''' docstring da função g ''' # corpo da função g | | bloco de comandos | [...] # início da execução do programa #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main() # chamada da função main

O uso do “if __name__ == ‘__main__’” para a chamada da função main permite que esse arquivo contendo uma ou várias funções seja incluído em outros programas (usando “import” e suas variações) sem a necessidade de reescrever ou copiar o código.

Complete a função fatorial abaixo, que recebe como parâmetro um número inteiro k, k >= 0, e retorna k!.

Escreva apenas o corpo da função. Observe que o código já inclui chamadas para a função fatorial, para que você possa testar a função.

def main(): ''' testes da função fatorial ''' print("0! =", fatorial(0)) print("1! =", fatorial(1)) print("5! =", fatorial(5)) print("17! =", fatorial(17)) #----------------------------------------------------- def fatorial(k): '''(int) -> int Recebe um inteiro k e retorna o valor de k! Pre-condição: supõe que k é um número inteiro não negativo. ''' k_fat = 1 # COMPLETE ESSA FUNÇÃO return k_fat #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main() # chamada da função main

Clique aqui para ver uma solução.

Usando a função do exercício 6.2, escreva uma função que recebe dois inteiros, m e n, como parâmetros e retorna a combinação m!/((m-n)!n!).

def main(): ''' Testes da função combincao ''' print("Combinacao(4,2) =", combinacao(4,2)) print("Combinacao(5,2) =", combinacao(5,2)) print("Combinacao(10,4) =", combinacao(10,4)) #----------------------------------------------------- def combinacao(m, n): '''(int, int) -> int Recebe dois inteiros m e n, e retorna o valor de m!/((m-n)! n!) ''' # COMPLETE ESSA FUNÇÃO E MUDE O RETURN ABAIXO return "o resultado" #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Clique aqui para ver uma solução.

Usando as funções fatorial e combinacao dos exercícios anteriores, escreva um programa que lê um inteiro n, n >= 0 e imprime os coeficientes da expansão de (x+y) elevado a n.

Lembre-se de utilizar o esqueleto de programa com funções em Python.

# Escreva o seu programa usando o esqueleto sugerido def main(): ''' Escreva aqui alguns testes ''' print("Vixe! Ainda não fiz esse exercício.") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Clique aqui para ver uma solução.


Page 3

Um número real em um computador é representado na notação de ponto flutuante (do inglês floating point). Dada a limitação de dígitos imposta por essa notação, os resultados dos cálculos realizados pelos computadores são aproximações dos valores reais. Por exemplo, o valor real de Pi tem infinitas casas decimais mas, no computador, é necessário limitar o número de casas decimais, aproximando o valor de Pi.

Para que possamos confiar nos resultados, uma boa prática é tentar minimizar a propagação de erros devido ao uso dessas aproximações. Assim, em geral:

  • Operações de divisão e multiplicação são “seguras”, podem ser executadas em qualquer ordem.

  • Adições e subtrações são “perigosas”, pois quando números de magnitudes muito diferentes são envolvidos, os dígitos menos significativos são perdidos.

  • Essa perda de dígitos pode ser inevitável e sem consequência (quando os dígitos perdidos são insignificantes para o resultado final) ou catastróficos (quando a perda é magnificada e causa um grande erro no resultado).

  • Quanto mais cálculos são realizados (em particular quando os cálculos são feitos de forma iterativa), mais importante é considerar esse problema.

  • O método de cálculo pode ser estável (tende a reduzir os erros de arredondamento) ou instável (tende a magnificar os erros). Frequentemente, há soluções estáveis e instáveis para um problema.

  • Para saber mais dê uma olhada em http://floating-point-gui.de/errors/propagation.

Se você já aprendeu a utilizar funções, você pode escrever as soluções dos problemas a seguir usando funções.

(exercício 2 da lista de exercícios sobre reais). Dado um número inteiro \(n > 0\), determinar o número harmônico \(H_n\) dado por

\[H_n = 1 + \frac{1}{2} + \frac{1}{3} + \frac{1}{4} + \ldots + \frac{1}{n}\]

Imprima cada termo da sequência e o resultado final. Faça 2 implementações:

    1. Da direita para a esquerda e

    1. da esquerda para direita.

Qual dessas formas é estável?

Observe que para \(n = 10\), os resultados são iguais, mas para \(n = 100 \ldots\)

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o problema!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Nota: Questão 6 da lista de exercícios sobre reais do caderno de exercícios.

Dados \(x\) real e \(n\) natural, calcular uma aproximação para \(\cos(x)\) através dos \(n\) primeiros termos da seguinte série

\[\cos(x) = 1-\frac{x^2}{2!}+\frac{x^4}{4!}-\frac{x^6}{6!}+\ldots+(-1)^k \frac{x^{2k}}{2k!} + \ldots\]

Compare com os resultados de sua calculadora!

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o problema!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Nota: Questão 7 da lista de exercícios sobre reais do caderno de exercícios.

Dados \(x\) real e \(\epsilon\) real, \(\epsilon > 0\), calcular uma aproximação para \(\sin(x)\) através da seguinte série infinita:

\[\sin(x) = \frac{x}{1!}-\frac{x^3}{3!}+\frac{x^5}{5!}+\ldots+(-1)^k \frac{x^{2k+1}}{(2k+1)!} + \ldots\]

incluindo todos os termos até que \(\frac{|x^{2k+1}|}{(2k+1)!} < \epsilon\)

Compare com os resultados de sua calculadora!

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o problema!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Nota: Questão 1 da Prova 1 de 2014.

Na figura, no plano cartesiano, a região sombreada não inclui as linhas de bordo. Note que o eixo y cai bem no meio da figura, e usamos o lado do quadrado para indicar as ordenadas correspondentes.

Escreva na página do desenho um programa que lê as coordenadas cartesianas (x, y) de um ponto, ambas do tipo float e imprime dentro se esse ponto está na região, e fora caso contrário.

Como comparar idades em lista python

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o problema!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Clique
  • aqui para ver uma 1a solução.

  • aqui para ver uma 2a solução.

  • aqui para ver uma 3a solução.

  • aqui para ver uma 4a solução.

  • aqui para ver uma 5a solução.

  • aqui para ver uma 6a solução.

Dado um número real \(x\) e um número real \(\text{epsilon} > 0\), calcular uma aproximação de \(e^x\) através da seguinte série infinita:

\[e^x = 1 + x + \frac{x^2} {2!} + \frac{x^3}{3!} + \ldots + \frac{x^k}{k!} + \ldots\]

Inclua na aproximação todos os termos até o primeiro de valor absoluto (módulo) menor do que epsilon.

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o exercicio!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()

Dados números reais \(x >= 0\) e \(\text{epsilon} > 0\), calcular uma aproximação da raiz quadrada de \(x\) através da seguinte sequência:

  • \(r_0 = x\) e

  • \(r_{n+1} = (r_n+ \frac{x}{r_n}) / 2\).

Exemplos:
  • Para \(x = 3, r_0 = 3, r_1 = 2, r_2 = 1.75, r_3 = 1.732143, r_4 = 1.732051\)

  • Para \(x = 4, r_0 = 4, r_1 = 2.5, r_2 = 2.05, r_3 = 2.000610, r_4 = 2.000000\)

  • Para \(x = 5, r_0 = 5, r_1 = 3, r_2 = 2.33, r_3 = 2.238095, r_4 = 2.236068\)

  • Para \(x = 0.81, r_0=0.81, r_1=0.905, r_2=0.9000138122, r_3=0.9000000001\)

A aproximação será o primeiro valor \(r_{n+1}\) tal que \(|r_{n+1}-r_n| < \text{epsilon}\).

def main(): # escreva o seu programa abaixo e remova o print() print("Vixe! Ainda nao fiz o exercicio!") #----------------------------------------------------- if __name__ == '__main__': # chamada da funcao principal main()


Page 4

Vamos considerar apenas os números inteiros no intervalo 0 <= x <= 2 e 0 <= y <= 3. Para gerar todos os pares (x,y) nesse intervalo devemos varrer todos os valores de x e, para cada valor de x, varrer todos os valores de y, algo como:

# varrer todos os valores de x x = 0 while x <=> </=>

para x igual a 0 ( 0 , 0 ) ( 0 , 1 ) ( 0 , 2 ) ( 0 , 3 ) para x igual a 1 ( 1 , 0 ) ( 1 , 1 ) ( 1 , 2 ) ( 1 , 3 ) para x igual a 2 ( 2 , 0 ) ( 2 , 1 ) ( 2 , 2 ) ( 2 , 3 )

Estude o código acima e verifique que o bloco de comandos que controla a varredura dos valores de x é muito parecido com o de y, como no trecho a seguir.

# comandos que controlam a varredura dos valores de x x_inicial = 0 x_final = 2 x = x_inicial while x <= x_final: x = x + 1

Agora que sabemos varrer todos os pares (x,y), para determinar o ponto de máximo podemos usar a seguinte ideia:

  • No início, não sabemos qual é o ponto de máximo.
    • Assim, vamos assumir que o máximo é um ponto qualquer

    • como o ponto (0,0)

  • O valor máximo é iniciado com o valor da função nesse ponto inicial

  • Varremos agora todos os pontos, um de cada vez
    • calculamos o valor da função nesse ponto (x,y)

    • se o valor no ponto for maior que o valor visto até agora
      • atualizamos o valor com esse novo valor de máximo

Em pseudo código, mais perto de Python, podemos escrever:

# Vamos usar o ponto (0,0) como ponto máximo inicial x_max = 0 y_max = 0 v_max = valor da função no ponto inicial (x_max, y_max) para cada novo par (x,y) no intervalo: valor = valor da função em (x,y) se valor > máximo: v_max = valor x_max = x y_max = y imprima o valor v_max e as coordenadas x_max e y_max

Lembre-se agora que, para varrer os pontos, usamos a repetição encaixada como vimos anteriormente e obtemos o seguinte código em Python:

# Inicialização: intervalo da varredura x_ini = 0 x_fim = 2 y_ini = 0 y_fim = 3 # Inicialização: cálculo do ponto de máximo x_max = 0 y_max = 0 v_max = y_ini + x_ini * y_ini - x_ini * x_ini # Varredura dos pontos no intervalo x = x_ini while x <=> v_max: v_max = valor x_max = x y_max = y y = y + 1 x = x + 1 print('Valor máximo: ', v_max) print('Obtido no ponto: (', x_max, ',', y_max, ')') </=>


Page 5

Um indicador de passagem é um padrão comum em computação que auxilia no controle de um programa.

Uma variável utilizada como indicador de passagem indica se algo ocorreu ou não ocorreu durante a execução de um programa e, portanto, seu valor é ou não é, verdadeiro ou falso. Por essa razão, em Python, essas variáveis são do tipo booleano (bool).

A utilização de um indicador de passagem é bastante simples. Inicialmente a variável deve ser inicializada com um valor True ou False adequado. Em seguida, durante a execução do programa, o valor da variável é alterado apenas se o evento for detectado. Observe que, uma vez detectado o evento, o valor do indicador não deve ser mais alterado.

Dado um número inteiro n > 0 e uma sequência com n números inteiros, verifique se a sequência está em ordem crescente.

Primeira tentativa de solução

n = int(input("Digite o valor de n: ")) anterior = int(input("Digite um número da sequência: ")) i = 1 # i conta quanto números foram lidos. Por isso já começa com 1. while i < n: x = int(input("Digite um número da sequência: ")) if x <=> </=>

Antes de prosseguirmos, leia a tentativa de solução com atenção e entenda o que o programa faz. Em seguida, simule e teste o programa com algumas sequências diferentes, crescentes e não crescentes, para identificar possíveis problemas.

O que esse programa faz?

  • O tamanho da sequência é armazenado na variável n.

  • A variável i é utilizada para controlar o final do while, para que o while pare após ler os n elementos da sequência. Observe que i é incrementada ao final do bloco dentro do while.

  • A variável anterior armazena o valor usado previamente e x a variável atual. A ideia dessa tentativa é comparar x e anterior verificando se o par está ordenado e imprimindo as mensagens supostamente apropriadas em cada caso.

  • Observe que a variável anterior recebe o valor de x no final de cada iteração, já que o valor representado por x assumirá o papel de anterior na próxima iteração.

Essa primeira tentativa tem alguns problemas:

  • imprime uma mensagem em cada iteração, quando apenas uma mensagem deveria ser impressa pelo programa;

  • as mensagens podem ser inconsistentes: pode imprimir que a sequência está ordenada e não ordenada;

  • imprime uma mensagem após verificar cada par, mas a resposta depende de toda a sequência.

Segunda tentativa

Para evitar a impressão de várias mensagens, a impressão deve ocorrer fora do while. Para isso vamos criar uma variável para indicar se a sequência está ou não em ordem crescente, como abaixo.

n = int(input("Digite o valor de n: ")) anterior = int(input("Digite um número da sequência: ")) i = 1 # já lemos o 1o número da sequência crescente = True while i < n: x = int(input("Digite um número da sequência: ")) if x <=> </=>

O uso da variável crescente melhora o controle do programa. Inicialmente, o programa inicializa crescente com True para indicar que a sequência com um elemento é considerada crescente. A seguir, todos os pares consecutivos são testados.

Com isso, apenas uma mensagem é fornecida ao final, ao invés das várias mensagens inconsistentes da primeira tentativa.

Antes de prosseguir, simule e teste essa versão para identificar os problemas dessa solução.

Essa segunda tentativa apresenta o seguinte problema:

  • a mensagem é definida apenas pelo último par da sequência. Assim, se a sequência for não decrescente mas o último par estiver em ordem crescente, a mensagem dada será que a sequência está ordenada.

Tente corrigir esse problema antes de ver a próxima tentativa.

Terceira tentativa de solução

n = int(input("Digite o valor de n: ")) anterior = int(input("Digite um número da sequência: ")) i = 1 # já lemos o 1o número da sequência crescente = True while i < n: x = int(input("Digite um número da sequência: ")) if x <=> </=>

Observe que nessa terceira tentativa retiramos o else. Dessa forma, quando o programa encontra um par fora de ordem, esse evento é marcado na variável crescente. Ao comparar outros pares da sequência, mesmo que eles estiverem em ordem, a variável mantém o seu estado até o final da sequência. Dessa forma, a mensagem correta, que considera o resultado entre todos os pares, é impressa.

Nesse caso, podemos chamar a variável crescente como um indicador de passagem, pois ela muda de valor ao encontrar um par fora de ordem e permanece com esse valor até o final, embora outros pares também fora de ordem podem marcar novamente a variável como False.

Boa prática de programação

Um programa que calcula o mesmo valor várias vezes sem necessidade ou que continua calculando quando o resultado já é conhecido é ineficiente e, portanto, esses trechos devem ser evitados.

No caso da terceira tentativa, não há mais razão para continuar processando a sequência após o indicador de passagem mudar de estado. Veja a próxima tentativa para ver um código um pouco melhor.

Quarta tentativa de solução

n = int(input("Digite o valor de n: ")) anterior = int(input("Digite um número da sequência: ")) i = 1 # já lemos o 1o número da sequência crescente = True while i < n and crescente: x = int(input("Digite um número da sequência: ")) if x <=> </=>

Observe a condição do while. Agora o while é interrompido assim que a variável crescente se torna False, ou seja, assim que o programa identifica que a sequência não é crescente e portanto não há mais razão de continuar verificando.


Page 6

O comando if (que significa se em português) permite que uma parte do programa seja executada apenas quando uma condição for verdadeira. A sintaxe do comando ìf é a seguinte:

if condição_do_if: # bloco executado se a condição for verdadeira comando_1 comando_2 ... comando_m # último comando do bloco comando_após_if

Apenas caso a condição_do_if for verdadeira, o bloco contendo os comandos comando_1 a comando_m é executado. Caso contrário, esse bloco não é executado e a execução do programa continua com o comando comando_após_if.

Dessa forma, o if permite resolver problemas do tipo:

idade = int(input("Digite sua idade: ")) if idade >= 18: print("Parabéns, voce ja tem idade para tirar a sua carteira.") print("fim.")

Como funciona esse trecho?

Após ler a idade (linha 1), o programa testa se a idade é maior ou igual a 18 na linha 3. Se a condição for verdadeira, o programa imprime a mensagem de parabéns (linha 4) e depois imprime “fim”. Caso contrário, o programa pula o bloco dentro do if e imprime “fim” direto.

Em várias ocasiões é necessário executar blocos de forma alternativa. Nesses casos, podemos utilizar o comando if-else (que significa se-senão em português), cuja sintaxe é a seguinte:

if condição: # bloco contendo comandos a serem executados dentro_do_if_1 dentro_do_if_2 ... dentro_do_if_m else: dentro_do_else_1 dentro_do_else_2 ... dentro_do_else_n comando_apos_if

Apenas caso a condição for verdadeira, o bloco contendo os comandos comando_1 a comando_n é executado. Caso contrário, esse bloco não é executado e a execução do programa continua com o comando comando_apos_if.

Esse comando nos ajuda a resolver problemas como, por exemplo, determinar se um número é par ou ímpar:

n = int(input("Digite um numero: ")) if n % 2 == 0: # se n é múltiplo de 2 print(n, "e' par") if n % 2 != 0: # se n não é múltiplo de 2 print(n , "e' impar") print("fim.")

Como funciona esse trecho?

Após n receber um número, o programa testa, na linha 3, se n é múltiplo de 2 usando o operador aritmético %. Esse operador determina o resto da divisão de n por 2. Caso a condição seja verdadeira (= True), o programa imprime que o número é par. Na linha 5 o programa recalcula o resto da divisão de n por 2 e verifica se o resto é diferente de zero, ou seja, se o número não é múltiplo de 2 e, nesse caso, imprime que o número é ímpar.

Observe que a condição dos ifs nas linhas 3 e 5 foram executadas, mesmo quando na linha 3 o número já foi identificado como par, o teste da linha 5 é realizado.

Embora essa solução produza resultados corretos, o uso do comando if-else torna o programa bem mais elegante e seguro:

n = int(input("Digite um numero: ")) if n % 2 == 0: # se n é múltiplo de 2 então é par print(n, "e' par") else: # senão o número é ímpar, não precisa fazer outro teste! print(n, "e' impar") print("fim.")

Como funciona esse trecho?

Esse trecho usando if-else é muito semelhante ao anterior usando dois ifs. A grande diferença agora é que na linha 5 temos um else. Nesse caso, a condição do if é testada apenas uma vez e, caso verdadeira, o programa imprime que o número é par e, caso contrário, o programa vai direto para o bloco dentro do else, imprimindo que o número é ímpar, sem precisar perder tempo calculando outro teste.

Essa construção é mais elegante pois evita a computação de “n não é múltiplo de 2” e torna o programa mais fácil de ler, corrigir e modificar.

Um if-else é utilizado quando temos apenas duas alterativas. Quando o número de alternativas é maior, podemos aninhar comandos if-else. Por exemplo, considere o problema de ler a nota de um aluno para verificar se ele está reprovado, está de recuperação ou foi aprovado. Suponha que as notas são números inteiros entre 0 e 100. Um aluno está reprovado se sua nota e menor que 30, está de recuperação se sua nota é um inteiro entre 30 e 49 e está aprovado se sua nota é pelo menos 50. Uma solução aninhando comandos if-else seria:

nota = int(input("Digite uma nota: ")) if nota < 30: print("Reprovado") else: if nota < 50: print("Recuperacao") else: print("Aprovado") print("fim.")

Como funciona esse trecho?

Observe com atenção a tabulação desse programa, que mostra um if-else na mesma coluna da linha 1 e, dentro do primeiro else, vemos um outro comando if-else. Por esse deslocamento sabemos que o segundo if só será testado caso a condição do primeiro if (da linha 3) seja falsa.

Vamos simular esse trecho usando 3 testes: nota 2 (que deve resultar em reprovado), nota 4 (que deve resultar em recuperação) e nota 7 que deve resultar em aprovado.

Quando a nota é 2, a condição do primeiro if é verdadeira e assim o programa imprime “Reprovado”. Quando a condição do if é verdadeira o else correspondente não é executado, e o programa termina imprimindo “fim”.

Quando a nota é 4, a condição do primeiro if é falsa e o bloco dentro do else correspondente (que está na mesma coluna desse if) é executado, ou seja, o segundo if-else é executado. Para isso a condição do if na linha 6 é testada, resultando em verdadeiro. O programa imprime então “Recuperação”, o else correspondente não é executado e o programa termina com “fim”.

Finalmente quando a nota é 7, a condição dos dois ifs é falsa e, nesse caso, o bloco dentro do segundo else (linha 9) é executado. Assim o programa imprime “Aprovado” e em seguida imprime “fim”.

Observe que esse mesmo trecho de código poderia ser escrito apenas com ifs da seguinte forma:

nota = int(input("Digite uma nota: ")) if nota < 30: print("Reprovado") if nota >= 30: if nota < 50: print("Recuperacao") if nota >= 50: print("Aprovado") print("fim.")

Dica de estilo

Embora seja possível utilizar apenas ifs, o uso de if-else é bem mais elegante pois torna o código mais simples, fácil de entender, de encontrar erros e de corrigi-los. Por esses motivos, sempre que possível, prefira usar if-else ao invés de apenas ifs.

Para simplificar ainda mais o código de programas com if-else aninhados, o Python oferece o comando if-elif-else.

Usando esse comando poderíamos escrever o programa para saber a condição de um aluno da seguinte forma:

nota = int(input("Digite uma nota: ")) if nota < 30: print("Reprovado") elif nota < 50: print("Recuperacao") else: print("Aprovado") print("fim.")

O elif portanto é apenas uma contração do else if que torna mais claro o tratamento das várias alternativas, encadeando as condições. Blocos de elif podem ser repetido várias vezes. Suponha por exemplo que gostaríamos de conhecer os alunos aprovados com louvor, ou seja, com nota superior a 90. Nesse caso, o código seria o seguinte.

nota = int(input("Digite uma nota: ")) if nota < 30: print("Reprovado") elif nota < 50: print("Recuperacao") elif nota < 90: print("Aprovado") else: print("Aprovado com louvor!") print("fim.")

A sintaxe do comando if-elif-else é a seguinte:

if condição: # bloco contendo comandos a serem executados dentro_do_if_1 dentro_do_if_2 ... dentro_do_if_p elif condição elif1: dentro_do_elif1_1 dentro_do_elif1_2 ... dentro_do_elif1_m1 elif condição elif2: dentro_do_elif2_1 dentro_do_elif2_2 ... dentro_do_elif2_m2 # outros possíveis blocos de elif, cada um com a sua condição elif condição elifk: dentro_do_elifk_1 dentro_do_elifk_2 ... dentro_do_elifk_mk else: dentro_do_else_1 dentro_do_else_2 ... dentro_do_else_q comando_apos_if

Ou seja, o if-elif-else pode ter um ou mais blocos com elif, cada um com a sua condição específica. Cada bloco (condição) é testado um de cada vez, até que uma condição seja satisfeita e apenas os comandos dentro desse bloco são executados. Quando nenhuma condição é satisfeita, os comandos dentro do else são executados. Assim, não é necessário que haja um else no final.

Faça experimentos com o trecho de código a seguir.

n = 25 # altere esse valor e simule esse trecho novamente if n < 0: print(n, "< 0") elif n == 0: print(n, "== 0") elif n < 10: print("0 < ", n,"< 10") elif n < 20: print("10 <=",> </=",>


Page 7

Ao final dessa parte do curso você deverá saber:

  • utilizar comandos de repetição na resolução de problemas computacionais;

  • definir condições, com valores iniciais e de parada, para o comando while;

  • simular o processamento do comando while.

O comando de repetição while (= enquanto) permite repetir instruções enquanto uma condição for verdadeira. Para utilizar o comando corretamente você precisa:

  • inicializar as variáveis de controle antes do comando;

  • criar uma condição que usa a variável de controle e se mantenha verdadeira pelo número correto de iterações;

  • modificar a variável de controle para garantir a terminação; e

  • realizar as computações sucessivas para se chegar a resposta correta.

A sintaxe do comando while é a seguinte:

while condição: # sequência de comandos executados no corpo do while comando_1 comando_2 ... comando_n

A condição é em geral definida na forma de uma expressão lógica. O resultado de uma expressão lógica é sempre True ou False.

A sequência de comandos comando_1, comando_2, …, comando_n pode conter qualquer comando do Python como atribuição, entrada ou saída, e outros, até mesmo outro while.

Nota sobre Programação Estruturada

Uma característica importante do Python é que ele força a estruturação do programa em blocos que podem ser facilmente visualizados pela tabulação. Observe que os comandos dentro do while, ou seja, os comandos <comando_1> a <comando_n>, precisam ser deslocados, ou seja, devem começar em uma coluna deslocada para a direita do while. Caso existam comandos a serem executados após o while terminar, esses comandos devem ser escritos usando a mesma tabulação (na mesma coluna) que o while.

O comando while repete a sequência de comandos definida em seu corpo enquanto a condição permanecer verdadeira.

Quando o comando while é executado, a condição é testada e, caso verdadeira, o seu corpo é executado um comando de cada vez, ou seja comando_1 primeiro, depois o comando_2, até o comando_n. Após a execução do comando_n a condição volta a ser testada e, caso verdadeira, o processo se repete. O while termina quando, ao testar a condição, o resultado do teste for False.

Observe o fluxo do programa abaixo, executando-o passo-a-passo:

CodeLens: (Exemplo_de_while)

Esse programa imprime os números de 1 até fim. Procure entender bem as partes desse programa:

  • inicialização das variáveis antes do while

  • condição do while, que define o número de iterações

  • atualização da variável de controle, que garante o fim do while.

Nota sobre Simulação de um Programa

Os programas em Python são constituídos por comandos executados um de cada vez, passo-a-passo. Saber simular um programa é uma habilidade muito importante para entender o que um programa faz, encontrar problemas (bugs) e testar soluções.

Para simular um programa você deve primeiro definir um teste, ou seja, você precisa definir uma entrada e a correspondente saída esperada pelo programa. A “saída” não precisa ser algo impresso mas pode ser uma certa configuração de valores de variáveis. Durante uma simulação devemos executar cada comando e verificar se a evolução dos valores das variáveis está correta.

Ferramentas como o codelens ajudam, mas você deve aprender a simular um programa manualmente, sem o auxílio de um computador.

Dada uma sequência de números inteiros diferentes de zero, terminada por um zero, calcular a sua soma. Por exemplo, para a sequência:

o seu programa deve escrever o número 35.

Tente escrever a sua solução primeiro e, depois, clique aqui para ver uma.

# escreva aqui a sua solução

Exercício 4 da lista sobre inteiros.

Dados números inteiros n e k, com k >= 0, calcular n elevado a k. Por exemplo, dados os números 3 e 4 o seu programa deve escrever o número 81.

Tente escrever a sua solução abaixo primeiro e, depois, clique aqui para ver uma.

# escreva aqui a sua solução

Exercício 8 da lista sobre inteiros.

Dado um número inteiro n >= 0, calcular n!.

Tente escrever a sua solução abaixo primeiro e, depois, clique aqui para ver uma.

# escreva aqui a sua solução

Exercício 9 da lista sobre inteiros.

Dados números inteiros n, i e j, todos maiores do que zero, imprimir em ordem crescente os n primeiros naturais que são múltiplos de i ou de j e ou de ambos.

Por exemplo, para n = 6, i = 2 e j = 3 a saída deverá ser:

# Digite a sua solucao

Clique aqui para ver uma solução.

Para saber mais¶

Next Section - Execução condicional e alternativas: if, if-else e if-elif-else