Vamos começar a escrever algoritmos com a linguagem de programação Python. Enquanto você lê o texto desta unidade, você deve acompanhar os exemplos utilizando um console Python. Mas não se contente em apenas copiar os exemplos! Experimente escrever outras instruções análogas e vá além do que está escrito. Após a leitura do conteúdo abaixo, você deve ler todos os capítulos de 1 até 3 do tutorial Python. Você pode deixar para ler a subseção 3.1.3 depois de falarmos sobre listas, na próxima unidade.
Variáveis, tipos e operações
Suponha que precisamos somar dois números de vários algarismos, digamos, 124682 e 2468. Esses números são pequenos, então você pode facilmente escrevê-los no papel, alinhados pelo último dígito, e executar o algoritmo de soma tradicional.
124682
+ 2468
--------
127150
Melhor ainda, para esse problema pode ser razoável tomar uma calculadora de mesa. Uma calculadora nada mais é do que um computador que realiza operações aritméticas e em que escrevemos as instruções diretamente no teclado. É muito fácil usar uma calculadora, mas ela tem a desvantagem de que não faz muito mais do que operações aritméticas. Se quisermos utilizar um computador moderno, então precisamos decidir duas coisas:
- Em que linguagem de programação escreveremos nossas instruções?
- Qual o mecanismo utilizaremos para executar essas instruções?
A resposta da primeira pergunta para esta disciplina é Python 3. Como Python é uma linguagem interpretada, a resposta da segunda pergunta é invocando um interpretador. Existem duas maneiras de invocar o interpretador do Python, interativa e não interativa.
Interpretador de comandos interativo
Usamos o interpretador de comandos interativo quando queremos realizar
operações simples e curtas apenas uma vez. Muitas vezes, também
utilizamos esse interpretador para experimentar e explorar a
linguagem, alguns algoritmos ou alguma biblioteca de funções
existente. Para isso, primeiro invocamos o interpretador de comandos
python3
sem argumentos a partir do terminal de comandos de seu
computador.
user@host:~$ python3
Iremos ver o console do Python 3 em que podemos digitar instruções, como
Python 3.7.3 (default, Oct 7 2019, 12:56:13)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Podemos digitar expressões aritméticas usuais (soma, subtração, divisão e multiplicação) nesse console. Experimente várias delas.
>>> 124682 + 2468
127150
Ao contrário do computador moderno, a nossa calculadora é bem limitada. Você deve saber que uma das principais limitações da calculadora é que a memória dela é muito limitada — só armazena os operandos e, normalmente, um resultado anterior. Se você tiver realizando operações com vários números, você precisa anotar cada resultado intermediário no papel. Em Python, podemos criar uma variável. Por exemplo, o índice de massa corporal (IMC) é dado pela fórmula
$$ \mbox{IMC} = \frac{{\mbox{massa}}}{({\mbox{altura}}\cdot {\mbox{altura}})}. $$
Então podemos calcular nosso índice como
>>> peso = 73
>>> altura = 1.75
>>> imc = peso / (altura * altura)
>>> imc
23.836734693877553
Devemos ler “peso recebe 73”, “altura recebe 1.75”, etc. O que as três primeiras linhas fazem é criar variáveis que guardam os valores do lado direto. Lembrem-se: uma variável corresponde a uma caixa na memória que guarda um valor de um determinado tipo. Cada uma dessas três linhas faz o seguinte:
- calcula o valor da expressão no lado direto do símbolo
=
e armazena na memória - associa o nome da variável no lado esquerdo do símbolo
=
ao valor armazenado
Observe que apenas após a última linha, o interpretador mostra algum resultado. O motivo é que o console interativo só mostra o resultado de expressões, e uma atribuição não é uma expressão em Python.
Tipos de variáveis
Você deve se lembrar de que todo valor armazenado na memória do computador tem um tipo associado. Para descobrir o tipo associado a cada uma das variáveis, fazemos o seguinte:
>>> type(peso)
<class 'int'>
>>> type(altura)
<class 'float'>
>>> type(imc)
<class 'float'>
Vemos que peso
tem tipo int
. Um tipo int
corresponde a um número
inteiro (positivo, negativo ou zero). Em Python 3 (mas não em Python
2), um número inteiro pode ter quantos dígitos forem necessários.
Experimente, por exemplo, calcular a décima potência de -99999999
em uma
calculadora comum. Certamente ela terminará com um erro. Em Python,
podemos fazer o seguinte:
>>> -99999999 ** 10
-99999990000000449999988000000209999997480000020999999880000000449999999000000001
Você acabou de aprender que **
corresponde ao operador de
exponenciação de Python. Mas tem algo estranho: a potência par de um
número não pode ser negativa, mas o resultado obtido foi negativo! Na
verdade, o que acabamos de calcular foi -(99999999 ** 10)
. O
operador **
tem precedência ou prioridade sobre o operador de
negação -
. Portanto, deveríamos ter escrito
>>> (-99999999) ** 10
99999990000000449999988000000209999997480000020999999880000000449999999000000001
Já as variáveis altura
e imc
têm tipo float
. Um float
é um
tipo numérico de ponto flutuante, que é utilizada para guardar uma
aproximação de um número real. Observe que falamos ponto, e não
vírgula: ao contrário do português, na maioria das linguagens de
programação, utilizamos um ponto .
para indicar a parte fracionária
de um número.
O fato de que guardamos uma aproximação ao usarmos um número
fracionário é importante. Por exemplo, é evidente que a soma
0.1 + 0.2
deve valer exatamente 0.3
, mas o interpretador Python
parece discordar.
>>> 0.1 + 0.2
0.30000000000000004
Ao contrário dos números inteiros, em que sempre guardamos uma representação exata no número, não é possível guardar uma representação exata de cada número real. Pense, por exemplo, em como representar o número $\pi$ e cada um dos outros números irracionais: não podemos enumerar todos os números irracionais! Para a maioria das aplicações que veremos, usar uma aproximação é mais do que suficiente. Mas devemos tomar muito cuidado sempre que
- compararmos números de ponto flutuante; ou
- armazenarmos números astronomicamente grandes e pequenos.
Para utilizar melhor uma aproximação de ponto flutuante, precisamos entender um pouquinho sobre como esses valores são armazenados. As variáveis de ponto flutuante são armazenadas guardando-se os valores de três números inteiros, sinal, mantissa e expoente, que correspondem ao número racional $$ (-1)^{sinal} \cdot mantissa \cdot 2^{expoente}$$
Por exemplo, podemos reescrever o número $0.5$ como $0.5 = (-1)^0 \cdot 1 \cdot 2^{-1}$. Tente identificar sinal, mantissa e expoente. No entanto, não podemos reescrever o número $0.1$ dessa forma de maneira exata. O motivo é que a mantissa é representada na memória como um número em binário. Qual é o número em binário que corresponde ao número decimal $0.1$? Descubra usando a calculadora de seu computador.
Para a programadora, normalmente é indiferente essa representação, desde que ela se atente ao fato de que cada número de ponto flutuante é uma aproximação de algum número real sendo representado!
É claro que o tipo da variável peso
é inteiro, pois o valor
atribuído é 73
. Podemos forçar a utilização de float
adicionando
um ponto depois do número:
>>> peso_float = 73.
>>> type(peso_float)
<class 'float'>
Mas por que imc
tem tipo float
? O motivo disso é que a expressão
do lado direito é avaliada para um número de ponto flutuante: sempre
que dividimos dois números, obtemos um float em Python 3, mesmo que a
divisão seja exata! Se quisermos obter apenas o quociente inteiro de
uma divisão, usamos o operador //
.
>>> 5 / 2
2.5
>>> 6 / 2
3.0
>>> 6 // 2
3
Quanto vale 5 // 2
?
Erros
Quando programamos, pode ocorrer uma série de erros. Um dos erros mais comuns é o erro de sintaxe e pode acontecer mesmo com operações bem simples como as que aprendermos. Por exemplo, se nos esquecermos de um operador.
>>> imc = peso / (altura altura)
File "<stdin>", line 1
imc = peso / (altura altura)
^
SyntaxError: invalid syntax
Preste atenção na mensagem de erro. O símbolo ^
está apontando para
o elemento do programa (token) que não era esperado naquela posição.
De fato, ali deveríamos ter um símbolo de multiplicação *
.
Outro erro de programação bastante comum é utilizar uma variável não definida, algumas vezes porque escrevemos o nome da variável com a grafia incorreta.
>>> imc = peso / (altura * autura)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'autura' is not defined
Outros erros são chamados erros de execução e acontecem apenas no momento da execução. Por exemplo, se tivéssemos digitado um valor inválido para a altura:
>>> peso = 73
>>> altura = 0
>>> imc = peso / (altura * altura)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
Os erros acima são chamados de exceções. Quando uma exceção ocorre, o interpretador para a execução do seu programa com uma mensagem de erro e se recursa a continuar. Algumas vezes, é preciso tratar exceções, mas por agora não falaremos disso. Nos nossos primeiros programas, as exceções indicam simplesmente que o programa está incorreto é deve ser corrigido.
Finalmente, podemos ter erros de lógica, que são erros que não são detectados pelo interpretadores. Ao contrário dos erros anteriores, pode ser difícil encontrar esse erro e, algumas vezes, um erro de lógica pode passar desapercebido por muito tempo. Já vimos esse problema com a precedência acima. Vamos ver outro caso de descuido com a ordem das operações:
>>> peso = 73
>>> altura = 1.75
>>> imc = peso / altura*altura
>>> imc
73.0
Alguém que tomasse esse resultado como correto iria com certeza estar bastante preocupado com sua saúde!
Um parênteses: módulos
Uma razão comum para se usar uma sessão interativa do interpretador é
experimentar com novos módulos e funções. Não vamos ver como criar
módulos agora, mas podemos desde já utilizá-los. Suponha que queremos
calcular a raiz quadrada de um número. Não existe operador em Python
dedicado para isso, mas podemos importar esse operador de um módulo
math
. Por exemplo, para calcular o tamanho da diagonal de um
retângulo, fazemos o seguinte:
>>> import math
>>> cateto1 = 10
>>> cateto2 = 5
>>> hipotenusa = math.sqrt(cateto1**2 + cateto2**2)
>>> hipotenusa
11.180339887498949
Uma dica que vale ouro. Enquanto estiver explorando nas sessões
interativas, as teclas para cima e para baixo navegam no histórico de
comandos digitados. Além disso, você pode usar o tab para completar
uma palavra, depois de escrever o prefixo. Por exemplo, para ver quais
nomes ou operadores estão disponíveis no módulo importado, digite
math.
e aperte tab duas vezes. Para ver o que cada operação faz, use
help
. Executar help(math.cos)
irá mostrar a documentação dessa
operação. Talvez seja necessário digitar q
para sair da
documentação.
Escrevendo um programa
Embora o modo interativo do interpretador Python seja útil, ele só serve em situações limitadas, quando queremos executar as instruções uma única vez. Na maior parte das vezes, quando queremos executar instruções Python, primeiro escrevemos um programa em Python. Os programas em Python também são chamados de script, em parte porque Python é utilizado muitas vezes com ferramenta de automação de tarefas cotidianas, em parte para distinguir de outros programas já compilados em linguagem de máquina.
Vamos construir um programa que
- pede para o usuário digitar um nome
- imprime uma mensagem de bom dia para o usuário
Criamos o seguinte programa, i.e., criarmos um arquivo
de texto chamado bomdia.py
e digitamos
usuario = input("Digite seu nome: ")
print("Bom dia", usuario)
Após salvar o arquivo, podemos executar o programa invocando o interpretador Python em um terminal de execução. Esse programa irá imprimir uma mensagem pedindo o nome. Ao escrevermos algum texto, digamos, Maria, e apertarmos Enter, obteremos o seguinte terminal
user@host:~/$ python3 bomdia.py
Digite seu nome: Maria
Bom dia Maria
No programa vemos dois comandos que fazem parte da Linguagem Python. A
função input
lê um texto digitado pelo usuário no teclado até o
momento em que ele digita a tecla Enter. O que essa função devolve é
uma variável que guarda a sequência de caracteres digitada pelo
usuário. Essa variável, que é do tipo string, ou str
, é associada ao
identificador usuario
, que é o nome do usuário.
A função print
recebe uma sequência de argumentos, cada um pode ter
um valor e um tipo diferente. O que ela faz é mostrar (ou imprimir) na
tela os valores na forma de texto, isso é, de uma string. Se houver
vários argumentos, a função print
irá mostra um espaço entre eles.
Strings
No código acima, temos "Bom dia"
que é uma string literal. As
strings literais representam valores do tipo str
que não mudam e
correspondem à sequência de caracteres entre as aspas. Se quisermos
inserir um caractere de aspas dentro da string, precisamos escapar do
significado especial que esse caractere tem utilizando uma
contra-barra, ou backslash, antes.
Por exemplo, considere um programa pensamento.py
com o seguinte
conteúdo
frase = "Descartes disse:\n\"penso, logo existo\""
print(frase)
O primeiro comando de pensamento.py
cria uma string com aspas.
Poderíamos também utilizar aspas simples,
frase = 'Descartes disse:\n"penso, logo existo"'
print(frase)
já que o caractere "
não têm significado especial dentro da string
literal. Se executarmos esse programa, iremos obter
Descartes disse:
"penso, logo existo"
Repare que o \n
não foi impresso, mas sim foi mostrada uma quebra de
linha: de fato, \n
é um caractere de controle que instrui o terminal
a saltar uma linha. Se quiséssemos a própria barra, deveríamos escapar
do significado especial da barra, usando
frase = 'Descartes disse:\\n"penso, logo existo"'
print(frase)
que imprimiria
Descartes disse:\n"penso, logo existo"
Operações de string
Assim como podemos fazer operações com números inteiros e números de ponto flutuante, também podemos fazer várias operações com string. Uma operação comum é criar uma substring ou acessar um determinado caractere. Veja o exemplo:
frase = "O essencial é invisível aos olhos"
print("O primeiro caractere é: ", frase[0])
print("O segundo é um espaço: ", frase[1])
print("A segunda palavra é: ", frase[2:11])
print("Um sufixo é:", frase[16:])
print("A última palavra é:", frase[-5:])
Executando o código acima, obtemos
O primeiro caractere é: O
O segundo é um espaço:
A segunda palavra é: essencial
Um sufixo é: visível aos olhos
A última palavra é: olhos
Execute o exemplo, releia o código e reflita. Procure entender porque essa saída é mostrada e procure a documentação se necessário.
Uma outra operação comum com strings é a concatenação. Por exemplo, poderíamos reescrever o exemplo acima da maneira abaixo — dessa vez, usando a pontuação adequadamente.
usuario = input("Digite seu nome: ")
mensagem = "Bom dia, " + usuario + "."
print(mensagem)
Reutilizamos o símbolo +
, mas perceba que nesse caso ambos operandos
são strings. Assim, o significado de +
é concatenar as duas
strings, em ordem. Qual a saída será obtida?
Convertendo tipos
Vamos agora usar o que aprendemos para criar um programa que calcula a hipotenusa de um triângulo retângulo. Escrevemos o seguinte
import math
cateto1 = input()
cateto2 = input()
hipotenusa = math.sqrt(cateto1*cateto1 + cateto2*cateto2)
print("A hipotenusa é " + hipotenusa)
Como você já deve imaginar, esse programa não funciona. Experimente. O
motivo é fácil de entender: ninguém garante que o usuário irá escrever
dois números válidos! E de fato, input
apenas lê uma sequência de
caracteres e não tenta interpretá-la de nenhuma maneira. O tipo de
ambos cateto1
e cateto2
no programa acima é str
. Ou seja, são
strings: não podemos multiplicar duas strings!
Para que nosso programa funcione, precisamos que o valor das variáveis
que representam os catetos sejam números de ponto flutuante. Mas como
transformar uma string, que contém a sequência de dígitos decimais e,
possivelmente um ponto, no número fracionário que ele representa em
ponto flutuante? Para isso, usamos uma função de conversão para
float
.
import math
cateto1 = float(input())
cateto2 = float(input())
hipotenusa = math.sqrt(cateto1*cateto1 + cateto2*cateto2)
print("A hipotenusa é " + hipotenusa)
Agora sim, a hipotenusa será calculada corretamente! Mas o programa
ainda está incorreto. O erro é que tentamos fazer uma concatenação com
um operando que não é uma string! Para converter um valor em uma
string, usamos a função str
. Corrija esse programa usando conversão
de float para string e depois fazendo a concatenação adequada!
Formatando a saída
Em Python 3, existe uma maneira bem conveniente de converter valores em strings, que são as strings de modelo para formatação. A ideia é escrever um texto e deixar marcações, placeholders, para substituir com o valor formatado. Por exemplo, se quiséssemos sempre escrever o valor da hipotenusa com duas casas decimais, poderíamos fazer o seguinte
import math
cateto1 = float(input())
cateto2 = float(input())
hipotenusa = math.sqrt(cateto1*cateto1 + cateto2*cateto2)
print("Os catetos são {} e {}!".format(cateto1, cateto2))
print("A hipotenusa é {:0.2f}.".format(hipotenusa))
Procure na documentação as várias formas de usar format
. Nas versões
mais novas de Python, há também uma maneira mais compacta
de escrever esse código, usando as f-strings:
import math
cateto1 = float(input())
cateto2 = float(input())
hipotenusa = math.sqrt(cateto1*cateto1 + cateto2*cateto2)
print(f"Os catetos são {cateto1} e {cateto2}!")
print(f"A hipotenusa é {hipotenusa:0.2f}.")
Repare que as f-strings começam com um símbolo f
.
Comandos condicionais
Até agora já sabemos ler e escrever dados de entrada e saída, realizar uma sequência de operações sobre esses dados e armazenar esses dados em variáveis. Pode ser que a sequência de operações a serem realizadas dependa dos valores das variáveis, então precisamos também das estruturas condicionais. Vamos resolver o seguinte exercício.
Escreva um programa que lê um número inteiro do teclado e imprime “sim” se o número for par e maior do que 10, ou for ímpar e menor do que 50. Caso contrário o programa deve imprimir “não”.
Primeiro, vamos tentar escrever um algoritmo em português:
numero ← leia um número do teclado
se número for par
se numero > 10
imprima sim
senão
imprima não
do contrário, se for ímpar
se numero < 50
imprima sim
senão
imprima não
Antes de continuar, simulamos o algoritmo rapidamente para verificar se não escrevemos alguma coisa errada. Como esse algoritmo é muito simples, depois de um par de testes, conseguimos nos convencer de que ele está correto. Agora, reescrevemos o algoritmo, dessa vez em Python.
numero = int(input())
if numero % 2 == 0:
if numero > 10:
print("sim")
else:
print("não")
else:
if numero < 50:
print("sim")
else:
print("não")
Há muitas novidades aqui, vamos parte a parte. Primeiro, o recuo em
que os comandos são escritos é fundamental para identificar a
estrutura do algoritmo. Temos duas palavras-chaves novas: if
e
else
. O comando if
significa se e é seguido por uma condição.
Se essa condição for verdadeira, e somente nesse caso, o corpo de
comandos que segue os dois pontos e que está recuado é executado. O
comando else
é opcional; o corpo desse comando é executando sempre
que a condição do if
falhar.
Ah, Python não tem uma instrução nativa para verificar se um número é par: o que fizemos é verificar se o resto da divisão por dois é zero. Como você faria para verificar se um número é múltiplo de três?
Valores booleanos
Para debulhar cada pedaço do programa acima, precisamos entender o que
é uma condição. Uma condição é uma expressão cujo resultado é um valor
do tipo bool
. Um valor do tipo bool
, por sua vez, é um valor de
verdade que pode ser ou True
ou False
e nada mais.
Obtemos valores booleanos normalmente fazendo perguntas! Em uma linguagem de programação, essas perguntas estão na forma de comparações e resultados de funções. Por exemplo, se quisermos verificar se o usuário digitou apenas números decimais, podemos escrever
numero_string = input()
if numero_string.isdigit():
print("O texto contém apenas dígitos decimais.")
numero = int(numero_string)
else:
print("O texto não é um número decimal válido.")
Poderíamos reescrever o programa anterior da seguinte maneira:
numero = int(input())
par = numero % 2 == 0
maior_10 = numero > 10
menor_50 = numero < 50
if par:
if maior_10:
print("sim")
else:
print("não")
else:
if menor_50:
print("sim")
else:
print("não")
O tipo dessas três novas variáveis é bool
. Confira usando um console
Python e digitando
>>> var = True
>>> type(var)
>>> par = numero % 2 == 0
>>> type(var)
Operadores booleanos
Às vezes, queremos fazer duas perguntas ao mesmo tempo, outras vezes precisamos satisfazer apenas uma de várias condições. Pensando nisso, vamos reescrever o programa.
numero = int(input())
par = numero % 2 == 0
maior_10 = numero > 10
menor_50 = numero < 50
if par and maior_10:
print("sim")
elif not par and menor_50:
print("sim")
else:
print("não")
Observamos algumas novas palavras-chaves: a primeira é and
(a
conjunção e escrita em inglês) que significa que queremos que
ambas condições sejam verdadeiras, a da esquerda e a da direita. A
segunda é not
(não em inglês), que nega o valor de verdade de uma
expressão. A última é elif
, que significa, do contrário, verifique a
condição e execute. O elif
vem da contração de else
com if
e
nada mais é do que uma forma mais compacta de escrever um código
equivalente:
numero = int(input())
par = numero % 2 == 0
maior_10 = numero > 10
menor_50 = numero < 50
if par and maior_10:
print("sim")
else:
if par and menor_50:
print("sim")
else:
print("não")
Mas, como essa sequência de if
seguido de else
é bastante comum,
fica mais fácil escrever todos os corpos de comando no mesmo recuo.
Podemos usar quantos elif
após um if
quantos forem necessários.
No nosso exemplo, o corpo de if
e elif
são iguais. Assim, podemos
simplificar ainda mais o programa acima.
numero = int(input())
par = numero % 2 == 0
maior_10 = numero > 10
menor_50 = numero < 50
if par and maior_10 or not par and menor_50:
print("sim")
else:
print("não")
A palavra-chave or
(ou em inglês) é um operador que devolve
verdadeiro bastando que pelo menos um dos seus operandos seja True
.
Nem sempre é fácil entender qual a ordem em que as operações serão
executadas. Para isso, é necessário conhecer a precedência dos
operadores (e um bocado de experiência). No caso do if
acima, not
é executado primeiro e or
é executado por último. Em expressões
complicadas, como a acima, é sempre mais claro (e mais prático), usar
parênteses:
numero = int(input())
par = numero % 2 == 0
maior_10 = numero > 10
menor_50 = numero < 50
if (par and maior_10) or (not par and menor_50):
print("sim")
else:
print("não")
O nome booleano, que em Python corresponde a bool
, é uma homenagem a
um matemático
George Bool, a quem é
frequentemente atribuída a criação da álgebra booleana. Por ora, basta
conhecermos bem as chamadas tabelas-verdades das operações:
A |
not A |
---|---|
True | False |
False | True |
A |
B |
A and B |
---|---|---|
True | True | True |
True | False | False |
False | True | False |
False | False | False |
A |
B |
A or B |
---|---|---|
True | True | True |
True | False | True |
False | True | True |
False | False | False |
Relembrar algumas equivalências bem conhecidas também é importante:
not (a == b)
é equivalente aa != b
not (a != b)
é equivalente aa == b
not (a > b)
é equivalente aa <= b
not (a < b)
é equivalente aa >= b
not (a >= b)
é equivalente aa < b
not (a <= b)
é equivalente aa > b
E refletir sobre algumas formas que às vezes passam desapercebido:
not (a and b)
é equivalente anot a or not b
not (a or b)
é equivalente anot a and not b
Essas últimas duas equivalências são conhecidas como Teoremas de De Morgan.
Repetindo condicionalmente
O corpo de comandos das construções if
e else
pode ser executado
uma ou nenhuma vez dependendo do valor da condição no momento da
execução. Muitas vezes, queremos repetir um conjunto de comandos
enquanto determinada condição é satisfeita.
As várias linguagens de programações têm as mais diversas construções para expressar comandos repetitivos, mas quase sempre identificamos pelo menos duas formas mais comuns que chamamos anteriormente de iteração condicional e iteração limitada. A seguir, vamos ver como utilizar essa primeira forma, mas veremos mais sobre comandos e algoritmos repetitivos depois. Por enquanto, resolvamos um exercício:
Escreva um programa que leia uma sequência de pares de números inteiros e pare apenas quando a soma de ambos for 42.
Aqui está como eu resolveria esse exercício.
print("Escreva dois números")
a = int(input())
b = int(input())
soma = a + b
while soma != 42:
print("Escreva dois números")
a = int(input())
b = int(input())
soma = a + b
print(f"Parabéns, a soma de {a} e {b} é um número fundamental")
Há uma novidade: um comando while
(enquanto em inglês) tem a mesma
forma de um comando if
, mas é um comando repetitivo. Assim como
o if
, o while
precede uma condição e é seguido por um corpo de
comandos recuado à direita. No entanto, o corpo de comandos é
executado repetidamente enquanto a condição avaliada for verdadeira.
Uma consequência disso é que o corpo de comandos do while
deve mudar
o valor das variáveis que afetam a condição.
Enquanto o programa acima executa corretamente, há um aspecto desagradável nesse código: escrevemos as mesmas instruções duas vezes. Como sempre precisamos executar pelo menos uma vez, podemos substituir a expressão da condição por uma variável booleana, assim:
procurando = True
while procurando:
print("Escreva dois números")
a = int(input())
b = int(input())
soma = a + b
if soma == 42:
procurando = False
print(f"Parabéns, a soma de {a} e {b} é um número fundamental")
Utilizamos while
porque não sabemos quantas vezes iremos executar o
corpo de comandos, ou, em outros termos, não sabemos quantas
iterações serão executadas. Pode acontecer também que nenhuma
iteração seja executada.
Escreva um programa que leia dois números e calcule o quociente da divisão usando apenas operações de soma e subtração.
O que queremos nesse exercício é mostrar que mesmo que Python não
tivesse o operador de divisão inteira //
, poderíamos calcular o
quociente — embora de forma muito mais lenta!
print("Escreva dois números")
dividendo = int(input())
divisor = int(input())
quociente = 0
while dividendo >= divisor:
quociente += 1
dividendo -= divisor
print(f"O quociente da divisão é {quociente}.")
Há dois operadores estranhos, mas inofensivos: +=
e -=
. Eles
servem só para simplificar atribuições. Escrevemos quociente += 1
ao
invés de quociente = quociente + 1
e dividendo -= divisor
ao invés
de dividendo = dividendo - divisor
. Beleza, continuemos.
Pare um pouquinho para entender esse algoritmo e tente convencer algum colega (aquele seu amigo cético) de que o algoritmo está correto. Para começar a entender esse algoritmo, temos que testar com alguns números de entrada. Experimente simular tentando dividir 6 por 2, depois 20 por 3. Depois tente 3 por 20.
A operação inversa da divisão é a multiplicação. De novo, vamos fingir que Python não tem operadores de multiplicação.
Escreva um programa que leia dois números e calcule o produto usando apenas a operação de soma.
Não é difícil escrever um algoritmo que faça isso: basta começar com
zero e somar um multiplicando repetidas vezes. A diferença é que agora
nós sabemos precisamente quantas vezes devemos executar uma iteração
antes de começar. Python tem uma estrutura bastante apropriada para
essa situação, mas nada nos impede de usar while
para resolver esse
exercício. Faça isso: escreva um algoritmo em português, traduza esse
algoritmo para Python, depois simule seu algoritmo com alguns exemplos
de entrada, usando lápis e papel.