Intro Duca o Program a Cao Python
Intro Duca o Program a Cao Python
(Versão 2.0 - Revisada para uso no Semestre 2024-1. O texto não passou por nenhuma
revisão profissional.
Assim, correções serão muito bem vindas!!!
Licença de uso: este texto pode ser copiado e distribuído livremente para uso não
comercial, mantendo sempre a informação sobre a autoria.
1
Introdução à Programação com Python
Prefácio 4
Capítulo 1 - Introdução 6
1.1. Motivação - por que aprender programação? 6
1.2. Arquitetura do computador e o Sistema Operacional 7
1.3. Algoritmos e linguagens de programação 11
1.4. O ambiente de programação no LBI 15
1.4.1 - Home Python 23
1.5. Exercícios 24
Capítulo 2 - Algoritmos 26
2.1 Definição de Algoritmo 26
2.2 Algoritmo computacional e não computacional 26
2.3. Propriedades de um algoritmo 27
2.4. Refinamento sucessivo e estruturas de programação 28
2.4.1 Eliminando ambiguidades 29
2.4.2. Refinamento do Algoritmo 30
2.5 - Estrutura de comando condicional 32
2.6 - Estrutura de comando repetitivo 34
2.7. Comandos aninhados e rastreio do algoritmo 37
2.8. Viva a diferença 42
2.9. Exercícios 43
2
Introdução à Programação com Python
3
Introdução à Programação com Python
4
Introdução à Programação com Python
Prefácio
Este material tem o objetivo de servir de apoio para os estudantes matriculados na
disciplina de Introdução à Programação I, oferecida pelo Departamento de Informática da
UFV, e sua primeira versão foi gerada nos primeiros meses de interrupção das aulas, em
função da pandemia da Covid-19, no ano de 2020. A ideia de elaboração deste material
surgiu a partir da constatação de haver pouquíssimos livros sobre a linguagem de
programação Python em nossas bibliotecas.
Assim, este material foi elaborado para seguir exatamente a sequência de assuntos
apresentados em sala de aula. Por isso, este material terá uma versão eletrônica
disponibilizada no PVANet no espaço reservado para a disciplina INF 100 - Introdução à
Programação I, sem custos para os estudantes da UFV. O objetivo é ter um material de
apoio com texto mais detalhado do que o dos slides exibidos em sala de aula.
5
Introdução à Programação com Python
materiais de apoio como interpretadores Python para instalar em seu computador, páginas
de programação onde você pode enviar e testar seus códigos Python, etc.
6
Introdução à Programação com Python
Capítulo 1 - Introdução
Uma pergunta comum dos estudantes é: onde este assunto da disciplina vai ser
importante na minha vida pós universidade? No caso do assunto de noções de
programação para estudantes de cursos da área de Ciências Exatas é possível afirmar, sem
medo de errar, que o tema tem se tornado cada vez mais importante.
A cada dia, mais e mais produtos são lançados com capacidade de conexão às
redes de computadores. Desde as já consagradas Smart TVs até eletrodomésticos como
geladeiras e fornos de microondas, passando pelos automóveis com computadores e
softwares cada vez mais sofisticados, incluindo os protótipos de carros autônomos, que
dispensam o motorista.
Aplicações nas mais diversas áreas tais como agricultura de precisão, controle de
frota de veículos, monitoramento ambiental, rastreabilidade de produtos para a segurança
alimentar, controle de tráfego em tempo real, controle de distanciamento social em tempos
de pandemia e muitas outras que vão demandar profissionais com diferentes formações,
7
Introdução à Programação com Python
mas que irão precisar de uma característica comum: saber analisar um problema e propor
uma solução descrita utilizando um raciocínio lógico.
E mesmo para quem não irá trabalhar com soluções computacionais, pode
economizar um dinheirinho usando raciocínio lógico. Foi o que aconteceu com o João da
Silva, que na infância era chamado de Joãozinho, quando ligou, no final da tarde, para
cancelar uma consulta médica agendada para as 14h do dia seguinte. A secretária disse:
- Sr. João Silva, infelizmente para cancelamento com menos de 24 horas, no seu
plano de saúde há uma taxa de 80% do valor da consulta. Se o Sr. tivesse ligado antes das
14h não haveria custo para cancelar… Mas o senhor pode optar por reagendá-la.
- Pois não. Então a senhora, por favor, remarque a consulta para a próxima semana,
no mesmo horário.
- Pronto. Consulta reagendada. Deseja mais alguma coisa Sr. João?
- Sim. Eu quero cancelar a consulta da semana que vem.
8
Introdução à Programação com Python
O Disco Rígido é o dispositivo de E/S mais utilizado pois ela armazena de forma
permanente todos os programas instalados no computador e os arquivos que criamos ao
editar o código fonte de um programa escrito em uma linguagem de alto-nível. Ao salvar um
arquivo, o seu conteúdo é gravado no Disco Rígido, sendo possível reutilizá-lo
posteriormente. Ao criar um novo arquivo usando um editor de textos e após adicionar, por
exemplo, 200 linhas de código do programa, caso o computador seja desligado todo o
trabalho será perdido. Isto ocorre porque o arquivo não foi salvo (gravado no disco rígido)
nem uma vez. A memória principal é volátil, ou seja, seu conteúdo é perdido quando o
circuito é desenergizado. Por isso, é importante salvar periodicamente seu arquivo de
trabalho.
A outra tarefa principal dos sistemas operacionais é oferecer uma forma amigável e
fácil de utilizar o computador para o operador humano, chamada de interface
homem-máquina ou, simplesmente, interface. Os primeiros sistemas operacionais
modernos possuíam apenas uma interface de texto, conforme mostrado na figura 1.2.
9
Introdução à Programação com Python
10
Introdução à Programação com Python
A figura 1.3 mostra alguns ícones que foram colocados na área de trabalho:
Gerenciador de Arquivos (Pasta pessoal), Navegador Web Firefox, IDLE, Code Blocks IDE
e Google Chrome. O usuário pode personalizar a sua área de trabalho, incluindo ou
excluindo ícones de programas. A partir desta interface gráfica é possível procurar todos os
programas aplicativos instalados no sistema, clicando no ícone com 9 quadradinhos, no
canto inferior esquerdo da tela. Um desses aplicativos é o Terminal, que é um programa que
executa a interface de texto sobre a interface gráfica. Isso é útil para usuários mais
experientes que conseguem realizar tarefas de forma mais rápida usando os comandos
desta interface de texto.
11
Introdução à Programação com Python
Outra vantagem dos sistemas baseados no Linux é que eles são gratuitos. Para uma
instituição pública como a UFV que é mantida com recursos públicos, impostos oriundos de
todos os contribuintes, esta única razão já seria suficiente para usar o Ubuntu no LBI.
O uso de computador para resolver problemas reais tem sido cada vez mais
frequentes. Se no início da utilização de computadores os problemas estavam relacionados
apenas à área científica, hoje existem aplicativos das mais variadas áreas desenvolvidas
para o cidadão comum. Aplicativos de redes sociais como Facebook e Instagram são
bastante conhecidos, totalizando mais de 6 bilhões de downloads (Fonte: Play Store,
27/03/2020). Dentre outros aplicativos menos conhecidos do público geral, mas que podem
ser úteis para estudantes da UFV, podem ser citados o UFV Eventos e o Cardápio UFV com
mais de 11 mil downloads (Fonte: Play Store, 27/03/2020). Ambos foram desenvolvidos com
participação de estudantes da UFV.
12
Introdução à Programação com Python
13
Introdução à Programação com Python
resultado desta fase será o chamado código fonte que deve seguir rigorosamente a forma
permitida de escrita da linguagem de alto nível, a chamada sintaxe. O código ou programa
fonte vai ficar gravado em um arquivo para ser executado quando demandado pelo
programador.
O tipo mais comum de erro são erros de sintaxe, que ocorrem quando um ou mais
comandos são escritos de forma incorreta. Este tipo de erro também é o mais fácil de
verificar, pois é apontado pelo interpretador ou compilador. No caso da linguagem Python o
interpretador para a execução do programa ao encontrar um erro de sintaxe e uma
mensagem de erro é exibida com informações para a correção. A correção demanda a volta
ao passo de edição do código fonte.
Outro tipo de erro é o de semântica que muitas vezes não é identificado pelo
interpretador Python. Semântica está relacionada com o sentido ou significado de um
comando. Um caso muito comum, em Python, é a troca do operador de comparação “==”
com o operador de atribuição “=”. Ou seja, o usuário pretendia atribuir para a variável a, o
valor da variável b, cujo comando correto seria o comando de atribuição “a = b“, mas acaba
escrevendo “a == b”, usando o comparador de igualdade (==) invés do comando de
atribuição (=). O programa executa normalmente, o comando resultará em um valor True ou
False, que não será armazenado pelo programa, mas a variável a continuará com o mesmo
valor. Para este tipo de erro também é necessário voltar à fase de edição do programa
fonte. Mas pode haver erros de semântica associados à solução descritiva (que geralmente
14
Introdução à Programação com Python
será feita em Português), o que poderia demandar uma volta à fase de análise do problema
e, consequentemente, correção de todas as fases posteriores.
Neste ponto, é importante ressaltar que quando um programa mais complexo vai ser
resolvido, cada tarefa identificada na fase de análise pode dar origem a um módulo de
programa. No final desta disciplina será apresentado o conceito de função que é uma forma
de estruturar o programa e promover a reutilização de código. O desenvolvimento de um
módulo ou uma parte ou uma função de um programa complexo vai seguir os mesmos
passos do diagrama da Figura 1.5.
Para finalizar esta seção, é importante apresentar uma diferença fundamental entre
as linguagens interpretadas e compiladas. No caso da linguagem interpretada, o código
fonte pode ser levado para outro computador que tenha um interpretador da mesma
linguagem que ele será executado. Já o código executável gerado em um computador só
poderá ser executado em um outro computador que tenha um processador com o mesmo
conjunto de instruções do primeiro.
Por isso, costuma-se dizer que uma linguagem interpretada é mais portátil do que
uma linguagem compilada. Isso ocorre porque, na linguagem interpretada, a tradução da
linguagem de alto nível para a linguagem de máquina é feita em tempo de execução. Todo
interpretador Python conhece a linguagem Python, obviamente. Um interpretador Python
feito para um processador precisa conhecer apenas a linguagem de máquina deste
processador. E as linguagens de máquina são diferentes para processadores diferentes. Até
mesmo a linguagem de montagem (Assembly) que é um nível intermediário entre a
linguagem de alto nível e a linguagem de máquina, é diferente para processadores
diferentes.
Considere uma operação de adição que na linguagem Python utiliza o operador “+”
para realizar a soma de duas variáveis (“a” e “b”). A expressão em Python seria algo como
“a + b”. Esta expressão deveria ser completada de alguma forma para formar um comando
válido da linguagem Python, mas para o momento este fato não é importante. Conforme foi
dito, em relação à figura 1.1, o processador executa todas as suas operações usando seus
registradores internos. Assim, para que a operação de soma da linguagem de alto nĩvel
aconteça são necessárias 3 operações: 1) transferir o conteúdo da variável “a” para um
registrador R1; 2) transferir o conteúdo da variável “b” para um outro registrador R2; 3)
executar a operação de soma usando os registradores R1 e R2 como operandos.
15
Introdução à Programação com Python
Felizmente, para todos nós, esta deve ser a última vez que será falado sobre
linguagem de Assembly e linguagem de máquina. De agora em diante, será utilizada
apenas a linguagem de alto nível Python. E, o mais importante, é que usando a linguagem
Python o seu programa vai executar em uma máquina com processador x86 ou RISC sem
nenhum problema, assumindo que exista um interpretador Python instalado nesta máquina.
O LBI possui quatro salas para as aulas práticas sendo duas salas com 24
computadores e 2 salas com 20 computadores. O acesso a uma das quatro salas só é
permitido no horário da aula prática. Há ainda uma sala de monitoria com 12 computadores
e uma bancada sem computadores na qual o estudante poderá utilizar seu próprio
computador portátil, se preferir. O(s) monitor(es) da disciplina INF 100 fazem atendimento
16
Introdução à Programação com Python
em horários que são divulgados na recepção do LBI, no início de cada semestre letivo.
Todos os computadores do LBI possuem o Sistema Operacional Linux, distribuição Ubuntu.
A Figura 1.6 apresenta a tela com a área de trabalho da conta do usuário Alunos,
com a identificação dos ícones relacionados aos programas citados no parágrafo anterior.
Esta conta está programada para apagar todos os arquivos ao final da sessão. Assim, todo
estudante que utilizar esta mesma conta sempre encontrará a sua pasta padrão vazia.
Nas máquinas do LBI, para facilitar a vida do estudante, existe um ícone que está
associado ao navegador de internet Firefox já configurado com a página inicial sendo o
servidor do LBI. Desta forma, basta clicar no referido ícone para abrir a tela de acesso ao
servidor do LBI. Para acessar o servidor do LBI o estudante usa seu número de matrícula
como nome de usuário e sua senha definida na primeira aula prática.
17
Introdução à Programação com Python
Embora as janelas sejam parecidas, o propósito delas é bem diferente. Mas tem
diferenças perceptíveis também. A primeira é que o programa associado ao ícone IDLE na
área de trabalho é o Shell.
Outra diferença é que no topo janela do Shell aparece a informação de que se trata
do Shell da linguagem Python versão 3.5.2 (Python 3.5.2 Shell), enquanto que na janela do
editor de programas aparece Untitled (Sem Título) porque foi usada a opção para criar um
novo arquivo (File -> New File) que ainda não teve seu nome definido (a definição do nome
se dá quando o arquivo for salvo pela primeira vez). Uma outra diferença é que a janela do
editor de programas está vazia (sem texto) à espera de que o usuário comece a escrever o
18
Introdução à Programação com Python
seu programa Python. Já na janela do Shell são exibidas informações sobre o interpretador
Python e, depois, é exibido o prompt de comandos representados pelos caracteres >>>.
Este prompt de comandos (>>>) indica que o Shell está esperando que algum
comando seja digitado e que seja dada a ordem para sua execução, através da digitação da
tecla “Enter”. Considere um exemplo simples onde se deseja atribuir para um objeto de
nome C, a soma de dois outros objetos A e B. A Figura 1.8 apresenta a utilização do Shell
para executar tal tarefa.
Após cada comando, no exemplo da Figura 1.8, foi colocado um comentário (#) na
mesma linha. Tudo o que vem após o caractere “#” é ignorado pelo interpretador Python, ou
seja, não faz parte do comando. Por isso é chamado de comentário. Como será visto, o
comentário é muito útil para que outros programadores possam entender com mais
facilidade o que o código faz e, até mesmo para que o próprio programador se lembre do
que o código faz, se ele ficar muito tempo sem mexer naquele programa. A seguir será
detalhado o significado de cada comando e cada resposta gerada pelo interpretador Python.
Os dois primeiros comandos são para criar os objetos (ou variáveis) A e B, com
valores 2 e 5, respectivamente. Para estes comandos o interpretador Python não gera
nenhuma saída, dando a impressão de que nada ocorreu. O terceiro comando foi o nome
do primeiro objeto (A) e como resposta o Shell exibiu o seu valor 2. Note que na linha de
resposta ao comando não aparece o prompt (>>>), além de exibir a resposta em outra cor
(azul). O quarto comando foi similar ao terceiro, só que para o objeto B.
O comando seguinte gera como resposta uma mensagem de erro, já que o nome do
objeto C, do qual se pretendia exibir o valor armazenado, ainda não havia aparecido e,
portanto, era desconhecido do interpretador Python. A resposta a este comando “inválido” é
19
Introdução à Programação com Python
uma mensagem de erro que informa ter havido um erro de nome, mais explicitamente que o
nome C não está definido: “NameError: name 'C' is not defined”. O comando seguinte (C =
A + B) corrige o erro, definindo o objeto C com valor inicial igual a soma dos valores atuais
de A e B. Agora, na sequência, o comando C exibe o valor 7.
Para que não se perca o trabalho, os comandos do programa Python deverão ser
digitados na janela do editor de programas e deverão ser gravados em um arquivo. Por
convenção, todos os arquivos com programa escrito na linguagem Python devem ter
terminação .py, como por exemplo p01.py, teste.py ou SerieFibonacci.py. Para exemplificar
será usado um pequeno programa com comandos equivalentes aos comandos do Shell
usados na Figura 1.8. Uma diferença é que para exibir o valor de um objeto na linguagem
Python deve-se usar o comando print() fornecendo como parâmetro o nome do objeto a ter
seu valor exibido. Ao invés de escrever simplesmente “A” como foi o comando no Shell, no
programa deve-se escrever o comando “print(A)”. A Figura 1.9 mostra a janela do editor de
programas.
Para executar o programa deve-se usar a opção do menu “Run -> Run Module” ou a
tecla de atalho F5 que fica na parte superior do teclado. A saída ou resultado da execução
20
Introdução à Programação com Python
do programa será exibida na janela do Shell. No código, o comando para exibir o conteúdo
do objeto (variável) C está antes da sua criação e definição do valor. Por isso, a saída
exibida conterá uma mensagem de erro, conforme mostrado na Figura 1.10.
21
Introdução à Programação com Python
Após a correção, usando a tecla de atalho F5, o IDLE pedirá novamente que o
arquivo do programa (primeiro.py) seja salvo e, após confirmação, executará novamente o
programa com a correção feita, gerando a saída exibida na Figura 1.12. Nesta figura
aparecem as saídas da primeira e segunda execuções. Entre cada execução, o
interpretador informa que houve um reinício (Restart) da execução, informando também o
nome do arquivo (primeiro.py) que teve a execução iniciada, com sua localização no
computador (/home/goulart) na mensagem destacada pela sequència de caracteres “=”:
“=================== RESTART: /home/goulart/primeiro.py ====================”.
Como o programa foi corrigido e está sem nenhum erro, a segunda saída apresenta apenas
os três valores impressos pelos três comandos print(), imprimindo na sequência os valores
de A, B e C, respectivamente 2, 5 e 7.
Caso alguma informação apresentada aqui sobre o programa não tenha ficado clara
não se preocupe, pois o conceito de variável e o comando print() serão apresentados de
maneira detalhada nos próximos capítulos. O mais importante desta seção é a informação
de que, nas aulas práticas ou quando for usar o ambiente de desenvolvimento IDLE, o Shell
é usado apenas para abrir ou criar seu(s) arquivo(s) de trabalho e depois disso, verificar as
saídas geradas pelo programa. Os arquivos de trabalho devem ser editados na janela do
editor de programas.
22
Introdução à Programação com Python
Outro programa que pode ser útil é o gerenciador de arquivos que serve para que o
usuário organize seus arquivos e diretórios (ou pastas). Esta organização é muito
importante para permitir a localização rápida de um arquivo no computador. No caso do
sistema instalado no LBI, que é uma versão do Linux, o diretório ou pasta do usuário fica no
diretório de nome “home”. E cada pasta de usuário possui algumas pastas (diretórios)
previamente definidas. A figura 1.13 mostra o gerenciador de arquivos aberto pelo usuário
“goulart” na máquina onde este documento estava sendo editado. Note que na barra de
navegação é mostrada a informação completa do caminho da localização atual
“/home/goulart” que é o diretório padrão do usuário. No caso da conta usada no LBI o
caminho será “/home/alunos”. Na área de visualização são exibidas os ícones associados
às pastas criadas pelo sistema para o usuário (“Área de Trabalho”, “Documentos”,
“Downloads”, “Imagens”, “Modelos”, “Música”, “Público” e “Vídeos”) além do ícone vinculado
ao arquivo Python “primeiro.py”.
Usando o gerenciador de arquivos, o usuário pode criar novas pastas para organizar
seus arquivos da maneira que ele considerar a mais adequada. Entretanto, nas máquinas
do LBI, o usuário não poderá criar suas pastas e deixar seus arquivos guardados lá, pois ao
final de cada sessão todos os arquivos do usuário Alunos são apagados, restaurando as
pastas e arquivos padrão. Assim, no LBI o gerenciador será usado mais frequentemente
para localizar os arquivos baixados do servidor, em geral, o roteiro da aula prática e,
eventualmente, um ou mais arquivos python. Suponha, por exemplo, que após baixar
(realizar o download) o arquivo “p01.pdf” com o roteiro da aula prática 1, ele não tenha
aparecido ao lado do arquivo “primeiro.py” na área da pasta padrão do usuário. O que
fazer?
23
Introdução à Programação com Python
Neste caso o gerenciador de arquivos deve ser usado como um navegador para
percorrer as pastas em busca do arquivo desejado. O mais comum é o arquivo ser baixado
para a pasta “Downloads” que é uma das pastas existentes na área do usuário. Para
acessá-la, basta clicar no ícone da pasta “Downloads” que o gerenciador passará a exibir,
então, o conteúdo da pasta “Downloads”, como mostrado na Figura 1.14. Dentre os
diversos arquivos que o usuário “goulart” já havia baixado se encontra o arquivo “p01.pdf”.
Agora, bastaria clicar sobre o ícone do arquivo “p01.pdf” para abri-lo com o leitor de PDF
padrão do sistema operacional e verificar o seu conteúdo.
Caso o arquivo não estivesse na pasta “Downloads” o processo poderia ser repetido
com qualquer outra pasta, usando os ícones de navegação (< ^ >) na parte superior
esquerda da janela ou clicando diretamente no nome da pasta desejada que aparece na
lista na área esquerda da janela (“Pasta Pessoal”, “Área de Trabalho”, “Documentos”,
“Música”, “Imagens”, “Vídeos” e “Downloads”). Note que na lista, a pasta que está em uso
aparece com o fundo cinza: “Downloads” na Figura 1.14 e “Pasta Pessoal” na Figura 1.13.
“Pasta Pessoal” corresponde à pasta principal de cada usuário: “/home/goulart” no exemplo
usado neste material e “/home/alunos” no caso da conta usada pelos alunos no LBI.
24
Introdução à Programação com Python
instalado no computador. Após certificar-se que a conexão está operacional, basta seguir a
seguinte sequência de passos:
Para quem não está matriculado na disciplina INF 100 e, portanto, não tem acesso
ao PVANet, a instalação pode ser feita com a seguinte sequência de 7 comandos, como
superusuário:
> apt-get update
> apt-get install --upgrade python3-pip -y
> pip3 install --upgrade pip -y
> apt-get install --upgrade libfreetype6-dev build-essential g++ libjpeg8-dev pkg-config
python3-cairocffi libjpeg-dev zlib1g-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev
python-tk -y
> pip3 install --upgrade matplotlib Pillow
> apt-get install --upgrade python3-scipy python3-tk -y
> apt-get install --upgrade idle3
Há ainda um vídeo com tutorial mostrando a instalação no Linux, que pode ser visualizado
neste endereço: https://youtu.be/YmI3vQIRMHQ.
25
Introdução à Programação com Python
Caso este primeiro método não funciona, a instalação pde ser feita manualmente do pacote
disponível no endereço https://www.python.org/downloads/windows/. Você deve baixar a
release mais recente do Python 3, para a versão do seu Windows. Após fazer o download
do instalador e iniciar a instalação do Python é IMPORTANTE selecionar a opção para
incluir o Python na lista de caminhos (PATH) do Windows. Esta opção é apresentada em
uma das janelas exibidas no processo de instalação e deve ser marcada.
Se isso for feito não haverá problemas na execução dos seus códigos. Porém, se
esta opção não for marcada, é possível que o IDLE não seja executado, ou ainda, que ele
não encontre as bibliotecas gráfica, numérica, etc., e como consequência, alguns
programas podem não funcionar porque não conseguiram encontrar as bibliotecas nos
comandos de importação (import).
1.5. Exercícios
26
Introdução à Programação com Python
a. “you don’t have to be a genious to know how to code. You have to be determined.”
(você não precisa ser um gênio para saber como programar. Você deve ser
determinado.)
b. “the programmers of tomorrow are the wizards of the future.” (programadores de
amanhã são os magos do futuro).
c. “Coding is something that can be learned and… I know it can be intimidating… a
lot of things can be intimidating, but, you know, what isn’t.” (Programar é algo que
pode ser aprendido e… eu sei que pode ser intimidador… muitas coisas podem ser
intimidadoras, mas, você sabe, o que não é?.
d. “I think the first program I wrote asked things like, what’s your favourite colour? Or,
how old are you?”. (Eu acho que o primeiro programa que escrevi perguntava coisas
como, qual sua cor favorita? Ou, quantos anos você tem?).
e. “(programming) it’s the closest thing we have to a super power.” ((Programação) é
a coisa mais próxima que temos de super poder).
27
Introdução à Programação com Python
import numpy
import PIL
print(‘Olá mundo...’)
28
Introdução à Programação com Python
Capítulo 2 - Algoritmos
No capítulo 1 foi apresentada a figura 1.5 com as fases de desenvolvimento de um
programa, que se inicia com a análise do problema para se obter uma solução descritiva e,
a seguir, descrever a solução em forma de um algoritmo. Mas o que vem a ser um
algoritmo? É o que será descrito neste capítulo.
Alguns dicionários informam que um algoritmo pode ser definido de forma simples
como uma sequência de ações executáveis. Esta definição genérica abarca a maioria das
situações do cotidiano como será visto nos exemplos a seguir. No contexto computacional
um algoritmo pode ser definido como “um conjunto de regras e procedimentos lógicos
perfeitamente definidos que levam à solução de um problema em um número finito de
etapas” (Fonte: https://www.google.com/search?q=algoritmo).
No nosso dia a dia temos como exemplos de algoritmos uma receita culinária de pão
de queijo, um manual de montagem de um brinquedo ou de equipamento, uma rota definida
por um aplicativo de mapas para se chegar a um destino, etc. Em cada um dos três casos
citados, se as ações definidas forem seguidas à risca, ao final o resultado deveria ser
algumas unidades de pão de queijo para serem degustadas, um brinquedo ou equipamento
montado e a chegada ao destino, respectivamente.
Daqui para frente será utilizado o exemplo da receita, ou do algoritmo, para produzir
pão de queijo mostrando as similaridades e diferenças para um algoritmo computacional. A
tabela 2.1 apresenta uma receita de pão de queijo detalhando em uma coluna a lista de
ingredientes e na outra coluna as instruções para fazer os pães de queijo.
Uma receita, em geral, como mostrado na tabela 2.1, possui duas partes: o conjunto
de ingredientes e o modo de preparo. O conjunto de ingredientes corresponderia ao
conjunto de dados do algoritmo computacional, que compreende as informações que
precisam ser processadas para se chegar ao resultado desejado. Exatamente como se faz
com os ingredientes da receita. No caso computacional, como será visto a partir do Capítulo
3, o programador pode construir novos dados mais complexos (estruturas de dados) usando
os tipos de dados primitivos da linguagem de programação.
29
Introdução à Programação com Python
30
Introdução à Programação com Python
31
Introdução à Programação com Python
Tabela 2.1, as ações do modo de preparo estão numeradas, indicando a ordem (sequência)
em que as ações devem ser executadas. Esta ordem é importante para a correção da
solução. As estruturas condicional e repetitiva serão apresentadas durante o processo de
refinamento do algoritmo.
Será suposto que existe um conjunto de equipamentos para permitir a execução das
ações que aparecerão nas próximas versões do algoritmo em seus refinamentos sucessivos
tais como: panela e tabuleiro (colocar), mixer (misturar), batedeira (bater), fogão (aquecer,
ferver), forno (ligar, regular temperatura, assar), lixeira (descartar), balança (pesar), jarra de
1 litro com gradação de 10 em 10 ml (medir), ralador de queijo (ralar), tigela grande e tigela
pequena (colocar).
Imagine que a receita será feita por um computador ou um robô ou mesmo por um
ser humano que nunca fez nenhuma receita em toda sua vida e muito menos pão de queijo.
O primeiro tipo de ambiguidade aparece na lista de ingredientes. Uma informação que pode
ser muito clara para um cozinheiro experiente pode ser de difícil entendimento para alguém
sem experiência na cozinha.
Os ingredientes serão redefinidos pensando que a receita será feita por um ser
humano sem nenhuma experiência culinária. A ideia é que não haja nenhuma dúvida
sobre o que deverá ser utilizado em cada ação do algoritmo. Para tornar mais claro, foi
inserido um comentário (texto que aparece após o caractere #) para cada ingrediente,
indicando se precisaria ser pesado ou medido, considerando a forma de comercialização.
Por exemplo, será considerado que o queijo meia cura foi comprado já ralado e que o
pacote de polvilho doce é de 500g. Mas o sal teria de ser pesado e o leite e óleo teriam de
ser medidos para .
32
Introdução à Programação com Python
Observe que não está sendo dada mais a opção de usar sal ou tempero. A receita
usa apenas sal e em quantidade específica (10g). Se esta quantidade de sal deixará os
pães de queijo sem sal ou muito salgados, o autor não faz ideia. Mas, não tem mais a
ambiguidade de botar sal a gosto. Ou usar outro tempero no lugar do sal. Sempre que
forem usados estes ingredientes não ambíguos, a sensação de salgado do resultado será a
mesma, para uma mesma pessoa.
Algumas ações também possuem ambiguidades ou não estão definidas com o grau
de detalhamento para permitir que a receita seja feita sem nenhum problema. Considere,
por exemplo, a ação número 5 “Acrescente os ovos, um a um, alternando com o queijo e
sovando bem, até a massa ficar homogênea, após cada adição”. Claramente existem mais
de uma ação neste passo 5, a saber: acrescentar ovo, acrescentar queijo, sovar e verificar
se a massa está homogênea.
Uma possível ambiguidade estaria no verbo “sovar” que, eventualmente, não seria
entendida por algumas pessoas sem a consulta a um dicionário. No algoritmo será feita a
substituição do verbo “sovar” pelo verbo “bater” explicitando que esta ação deve ser
realizada na batedeira. Esta explicitação poderá ser feita com a colocação de comentários
no algoritmo. Um comentário será sempre precedido do caractere “#”, para indicar que não
se trata de um comando.
33
Introdução à Programação com Python
que deve os ovos devem ser acrescentados um a um e alternado com o queijo. Como na
receita são dois ovos, o acréscimo de queijo ralado será feito em duas partes de 200g.
Modo de Preparo
1. Coloque 500g de polvilho em uma tigela grande.
2.1 Misture em uma panela 10g de sal, 300ml de leite e 150ml de óleo.
2.2. Aqueça a mistura até ferver
3.1. Jogue a mistura fervendo sobre o polvilho
3.2. Mexa até desfazer as pelotinhas.
4. Deixe esfriar por 20 minutos.
5.1. Acrescente um ovo
5.2. Acrescente 200g de queijo ralado
5.3. Bata até a mistura ficar homogênea
5.4. Acrescente um ovo
5.5. Acrescente 200g de queijo ralado
5.6. Bata até a mistura ficar homogênea
6. Unte as mãos com óleo, se necessário.
7. Enrole bolinhos de 2 cm de diâmetro e coloque-os em uma assadeira untada.
8. Leve ao forno médio (180º C), preaquecido.
9. Asse até ficarem douradinhos.
Figura 2.1 - Algoritmo versão 2
Note que a versão 2 já está mais detalhada com o refinamento das ações 2, 3 e 5 e,
como consequência, o número de ações quase dobrou. Entretanto, algumas ações ainda
não estão definidas como ações únicas, o que dificultaria a execução do algoritmo por parte
de um robô. Por exemplo, a ação 2 que já foi desmembrada nas ações 2.1 e 2.2 poderia ser
mais refinada ainda, nas seguintes ações mostradas na Figura 2.2.
34
Introdução à Programação com Python
Modo de Preparo
1. Coloque 500g de polvilho em uma tigela grande.
2.1.1. Coloque 300ml na panela
2.1.2. Acrescente 150ml de óleo na panela.
2.1.3. Acrescente 10g de sal
2.1.4.. Misture os ingredientes na panela
2.2.1. Acenda uma das trempes do fogão
2.2.2. Coloque a panela com a mistura na trempe acesa
2.2.3. Aqueça a mistura até ferver
3.1. Jogue a mistura fervendo sobre o polvilho
3.2. Mexa até desfazer as pelotinhas.
4. Deixe esfriar por 20 minutos.
5.1. Acrescente um ovo
5.2. Acrescente 200g de queijo ralado
5.3. Bata até a mistura ficar homogênea
5.4. Acrescente um ovo
5.5. Acrescente 200g de queijo ralado
5.6. Bata até a mistura ficar homogênea
6. Acenda o forno para pré-aquecimento
7. Unte as mãos com óleo, se necessário.
8.1 Untar uma assadeira
8.2 Enrole bolinhos de 2 cm de diâmetro
8.3 Coloque-os em uma assadeira untada.
9. Leve a assadeira ao forno médio (180º C).
10. Asse até ficarem douradinhos.
Figura 2.3 - Algoritmo versão 3
35
Introdução à Programação com Python
mãos. Mas somente, se necessário. Portanto, é preciso ter uma estrutura que permita
executar condicionalmente uma ação.
se <condição>
<Comando>
Figura 2.4 - Estrutura do comando condicional
Em alguns casos é desejado executar uma ação no caso da condição ser verdadeira
ou uma ação diferente no caso da ação ser falsa. Isto não é possível com a estrutura da
36
Introdução à Programação com Python
Figura 2.3 onde existe apenas um comando (ou bloco de comandos) que só é executado no
caso do teste ser verdadeiro. Quando o teste é falso, passa-se para a execução do próximo
comando sequencial (comando 8, no caso do algoritmo da Figura 2.3).
37
Introdução à Programação com Python
“se”, na verdade, é uma execução de operação feita pelo processador, quando se trata de
um programa.
Importante chamar a atenção, mais uma vez, que a sequência de ações sempre é
importante para se chegar à solução correta do problema. Quebrar o ovo na tigela e jogar a
casca fora são tarefas que sempre tem que ser feitas. Portanto são comandos sequenciais.
E devem ser executadas na ordem em que foram escritas! Se inverter a ordem… a massa
não terá ovos.
Também é importante distinguir tarefas (ou ações) que são sequenciais das tarefas
condicionais. Escrever uma mesma ação no bloco “se” e também no bloco “senão” é um
erro do ponto de vista lógico. Considere, por exemplo, que o trecho de algoritmo mostrado
na figura 2.7 fosse reescrito assim:
38
Introdução à Programação com Python
Enquanto <condição>
<comando>
Fim_Enquanto
Figura 2.9 - Estrutura de comando repetitivo Enquanto
Muitas vezes é necessário definir (ou inicializar) uma informação de controle para
forçar a entrada no comando repetitivo e, dentro do bloco de comandos repetitivos modificar
a condição de controle para que o número de repetições do comando seja o desejado.
39
Introdução à Programação com Python
receita deve ser incrementado. A Figura 2.10 mostra um exemplo com um comando
repetitivo para o caso do algoritmo do pão de queijo.
NumeroDeOvosNaReceita = 0
Enquanto NumeroDeOvosNaReceita < 2
Acrescente um ovo
Acrescente 200g de queijo ralado
Bata até a mistura ficar homogênea
Incremente(NumeroDeOvosNaReceita)
Fim_Enquanto
Figura 2.10 - Exemplo de uso do comando repetitivo Enquanto
O comando repetitivo seria executado para sempre, pois o valor inicial da variável de
controle “NumeroDeOvosNaReceita”, não sendo mais incrementado, se manteria sempre
em 0. Desta forma, o teste da condição seria sempre verdadeiro também, o que implicaria
na execução do bloco repetitivo para sempre. No caso da receita, um operador humano
poderia perceber que há algo errado, pois foram reservados apenas 2 ovos e 400g (ou 2
porções de 200g) de queijo ralado. Logo, não existiriam ingredientes para executar as
ações, a partir da terceira execução. Porém, no caso de um programa, às vezes é difícil de
perceber que o programa entrou neste ciclo infinito.
Existe uma outra estrutura de comando repetitivo voltada para situações onde já se
sabe a priori o número de execuções que se pretende. Esta estrutura é mostrada na Figura
2.11. Nesta estrutura o valor de controle faz parte do comando, com definição do valor
inicial e do valor final no cabeçalho do comando. Além disso, o incremento da informação
de controle é automático. A estrutura deste novo tipo de comando repetitivo é apresentado
na Figura 2.11, mostrada a seguir.
40
Introdução à Programação com Python
Conforme foi dito anteriormente, as três estruturas de comando vistas nas seções
anteriores (sequencial, condicional e repetitiva) são suficientes para escrever qualquer
programa. Em geral, uma descrição de alto nível (ou primeira versão) do algoritmo poderia
conter apenas comandos sequenciais. Entretanto, ao detalhar a solução, alguns comandos
que pareciam ser sequenciais são quebrados em dois ou mais comandos e, eventualmente,
em comandos condicionais ou comandos repetitivos.
41
Introdução à Programação com Python
Há também, na Figura 2.10, um comando repetitivo implícito, ou que não foi refinado
ainda: “Bata até a mistura ficar homogêneo”. A operação que é possível executar é bater a
massa usando uma batedeira, enquanto que o “até a mistura ficar homogênea” nada mais é
do que um teste visual para aferir se a operação bater deve prosseguir ou não. A Figura
2.13 apresenta o trecho do algoritmo com os refinamentos discutidos nesta seção.
NumeroDeOvosNaReceita = 0
Enquanto NumeroDeOvosNaReceita < 2
Quebre um ovo em uma tigela pequena
Jogue a casca do ovo na lixeira
se “ovo está choco”
Jogue o ovo na lixeira
Lave a tigela pequena
senão
Adicione o ovo da tigela pequena
Incremente(NumeroDeOvosNaReceita)
Acrescente 200g de queijo ralado
Enquanto “mistura não estiver homogênea”
Bata a mistura
Fim_Enquanto
Fim_Enquanto
Figura 2.13 - Refinamento de parte do algoritmo com comandos aninhados
Note que dentro do comando repetitivo principal existem dois comandos sequenciais
(“Quebre um ovo em uma tigela pequena” e “Jogue a casca do ovo na lixeira”) que são
executados sempre que se entra no comando repetitivo. O que é razoável, pois todo ovo
precisa ser quebrado na tigela pequena e ter sua casca descartada na lixeira.
42
Introdução à Programação com Python
NumeroDeOvosNaReceita = 0 NumeroDeOvosNaReceita = 0
Enquanto NumeroDeOvosNaReceita < 2 Enquanto NumeroDeOvosNaReceita < 2
Quebre um ovo em uma tigela pequena Quebre um ovo em uma tigela pequena
Jogue a casca do ovo na lixeira Jogue a casca do ovo na lixeira
se “ovo está choco” se “ovo está choco”
Jogue o ovo na lixeira Jogue o ovo na lixeira
Lave a tigela pequena Lave a tigela pequena
senão senão
Adicione o ovo da tigela pequena Adicione o ovo da tigela pequena
Incremente(NumeroDeOvosNaReceita) Incremente(NumeroDeOvosNaReceita)
Acrescente 200g de queijo ralado Acrescente 200g de queijo ralado
Enquanto “mistura não homogênea” Enquanto “mistura não homogênea”
Bata a mistura Bata a mistura
Fim_Enquanto Fim_Enquanto
Fim_Enquanto Fim_Enquanto
Figura 2.14 - Possíveis fluxos de execução dependendo da condição “ovo está choco”
43
Introdução à Programação com Python
Na nossa simulação o primeiro ovo está bom (não choco) e o bloco a ser executado
no comando condicional é o bloco “senão”, no qual o ovo será adicionado juntamente com
uma porção de queijo ralado e misturados até que a mistura fique homogênea, conforme
detalhado na Figura 2.14.b. Porém, o comando mais importante do ponto de vista do
rastreio é o que faz o incremento do número de ovos na receita que passará de 0 (zero)
para 1. Este comando é o que poderá, em algum momento, tornar a condição do comando
repetitivo principal (NumeroDeOvosNaReceita < 2) falsa. E quando terminar o comando de
tornar a mistura homogênea, o fluxo de execuções voltará para realizar um novo teste da
condição do comando repetitivo.
Neste momento será verificado que o número de ovos na receita ainda é menor do
que 2 e, neste caso, a condição continua verdadeira e o bloco de comandos repetitivos será
executado mais uma vez.
Agora, na nossa simulação, o segundo ovo está choco. Neste caso, o fluxo de
execução dos comandos será aquele mostrado na Figura 2.14.a. Novamente, os 2
primeiros comandos serão executados para quebrar o ovo e colocá-lo em uma tigela e
testá-lo, no próximo comando. Para este segundo ovo, que está choco, a condição “ovo
está choco” será verdadeira, ocasionando a execução do bloco “se”, que fará com que o
ovo choco seja jogado na lixeira e a tigela lavada para receber um próximo ovo.
O terceiro ovo, em nossa simulação, está bom (não choco), o que levará à execução
do bloco “senão” do comando condicional, com a adição de mais um ovo e outra porção de
queijo, para serem misturados até que a massa fique homogênea novamente. E,
novamente, o NumeroDeOvosNaReceita será incrementado e passará de 1 para 2.
Com o passar do tempo, será notado que a análise dos possíveis fluxos de
execução não precisa ser tão detalhada. Por exemplo, os comandos que alteram o estado
de uma variável de controle são muito mais importantes do que alguns comandos
sequenciais. Por exemplo, se o comando “Jogue a casca do ovo na lixeira” fosse omitido do
rastreio não faria a menor diferença para o entendimento da solução. Mas o valor inicial e
os incrementos da variável “NumeroDeOvosNaReceita” usada na condição do comando
repetitivo e a própria expressão da condição do comando repetitivo são os itens mais
importantes para entender quando o comando repetitivo iria terminar.
44
Introdução à Programação com Python
E o que aconteceria para o caso da condição estar correta, como na figura 2.14,
mas o programador se esquecesse do comando “Incremente(NumeroDeOvosNaReceita)”
no bloco “senão” do comando condicional? Neste segundo caso, o valor da variável
“NumeroDeOvosNaReceita” ficaria sempre com o valor 0 (zero) e o comando repetitivo não
terminaria (loop infinito). Teríamos que ter infinitos ovos e uma quantidade infinita de queijo.
45
Introdução à Programação com Python
2.10. Exercícios
1. Identifique os comandos no Algoritmo do pão de queijo que ainda não estão refinados e
refine-os.
4. Escreva um algoritmo para escolher entre três opções possíveis qual o melhor
apartamento para ser alugado para uma república de 5 pessoas, considerando as
características descritas a seguir.
46
Introdução à Programação com Python
Suites 1 1 2
Vaga Garagem 1 0 1
Andar 1 4 8
NumeroDeOvosNaReceita = 0
Enquanto NumeroDeOvosNaReceita < 2
Quebre um ovo em uma tigela pequena
Jogue a casca do ovo na lixeira
Incremente(NumeroDeOvosNaReceita)
se “ovo está choco”
Jogue o ovo na lixeira
Lave a tigela pequena
senão
Adicione o ovo da tigela pequena
Acrescente 200g de queijo ralado
Enquanto “mistura não homogênea”
Bata a mistura
Fim_Enquanto
Fim_Enquanto
Sabendo que a receita precisa sempre de 2 ovos bons (não chocos), descreva o que
aconteceria nas seguintes situações, considerando cada uma delas de maneira isolada:
a) Os dois primeiros ovos estão bons.
b) O primeiro ovo está choco e o segundo e terceiro ovos estão bons.
c) O primeiro ovo está bom, o segundo ovo está choco e o terceiro ovo está bom.
d) Os dois primeiros ovos estão bons e o terceiro e quarto ovos estão bons.
47
Introdução à Programação com Python
3.1 - Variáveis
48
Introdução à Programação com Python
Internamente a variável idade poderia ter o seu valor 00000000 00000000 00000000
00101000 que corresponde ao valor 40 escrito na notação binária (base 2). Por que lemos
40 como quarenta? Exatamente porque consideramos implicitamente que o número está
representado na base 10, onde os dígitos são 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9. Usando a base 10,
o número 40 pode ser desmembrado como:
4𝑥10¹ + 0𝑥10⁰ = 4𝑥10 + 0𝑥1 = 40 + 0 = 40
Considere, como exemplo, o caractere ‘A’ que tem valor decimal 65. Este valor está
escrito nas demais bases, conforme pode ser observado nos desmembramentos abaixo:
49
Introdução à Programação com Python
O uso das variáveis lembram um pouco dos conceitos matemáticos, mas possuem
também algumas diferenças bastante significativas, conforme serão expostas na sequência.
Suponha, por exemplo, uma equação do segundo grau: 𝑎𝑥² + 𝑏𝑥 + 𝑐 = 0. Na
matemática a equação possui apenas uma variável: x. E os valores a, b e c não são vistos
como variáveis, mas sim como parâmetros ou coeficientes quaisquer de uma equação de
segundo grau.
● Δ = 𝑏² − 4𝑎𝑐
● á𝑟𝑒𝑎 𝑐í𝑟𝑐𝑢𝑙𝑜 = π. 𝑟²
Na programação os nomes de variáveis tem que seguir regras muito mais restritas.
Só podem ser usados um conjunto restrito dos símbolos definidos na linguagem. Por
exemplo, as letras gregas Δ e π usadas nos exemplos não fazem parte dos símbolos da
linguagem Python. Em geral, os nomes de variáveis devem ser iniciados com uma letra
A..Z, a..z, ou _, podendo conter depois os caracteres A..Z, a..z, 0..9, _. Não são permitidos
símbolos como +, -, *, /, =, (, ), [, ], {, }, espaços em branco, caracteres acentuados, dentre
outros. Uma possibilidade de definição de nomes de variáveis e as respectivas expressões
em um programa, similares às dos exemplos acima seriam:
● 𝑑𝑒𝑙𝑡𝑎 = 𝑏 * 𝑏 − 4 * 𝑎 * 𝑐
● 𝐴𝑟𝑒𝑎𝐶𝑖𝑟𝑐𝑢𝑙𝑜 = 𝑝𝑖 * 𝑟 * 𝑟
50
Introdução à Programação com Python
Python, a lista de palavras reservadas pode ser obtida no Shell com o comandos ‘import
keyword’ e ‘keyword.kwlist’, como mostrado na Figura 3.2.
● <identificador> = <expressão>
Importante ressaltar que comando de atribuição não deve ser confundido com uma
equação da matemática. Suponha, por exemplo, que seja necessário atualizar a ‘idade’
51
Introdução à Programação com Python
passando o valor de 40 para 41. Uma possibilidade seria simplesmente executar um novo
comando de atribuição:
● idade = 41
Note que na matemática tal equação não faria sentido. Mas, como se trata de um
comando de atribuição, o seu funcionamento se dá da em três etapas, conforme mostrado
na Figura 3.3, supondo que o valor da variável ‘idade’, anterior à execução do comando,
seja 41. Para avaliação da expressão ‘idade + 1’ é necessário, primeiramente, obter o valor
da variável ‘idade’. Para isso, uma operação de busca na memória será feita, na posição
apontada pelo identificador ‘idade’, com o valor do seu conteúdo (41) sendo armazenado
em um registrador do processador. O segundo operando da expressão, o valor 1, será
carregado em um segundo registrador. O processador realizará a operação de soma dos
dois operandos e o valor resultante (42) será colocado em algum registrador do
processador. Com o término da avaliação da expressão, o seu resultado será atribuído para
a posição de memória associada ao identificador ‘idade’.
Importante chamar a atenção, mais uma vez, que o efeito final de um comando de
atribuição é escrever um valor em uma determinada posição de memória. Portanto, o valor
anterior se perde. Supondo que os três comandos de atribuição foram executados na ordem
apresentada, a variável ‘idade’ foi criada com valor 40 pelo primeiro comando (idade = 40).
O segundo comando (idade = 41) alterou seu valor para 41 e o terceiro comando (idade =
idade + 1) o modificou para 42.
Suponha que um novo comando para modificar o valor da variável ‘idade’ seja
escrito para indicar qual será a idade de uma pessoa daqui a uma década, usando a
seguinte forma:
● idade = idade + uma_decada
52
Introdução à Programação com Python
O interpretador Python, para executar o comando irá fazer a primeira parte da tarefa
que é buscar os operandos (‘idade’ e ‘uma_decada’). A busca do primeiro operando ‘idade’
seria feita com sucesso e o seu valor (42) carregado em algum registrador do processador,
pois a suposição é a de que os 3 comandos de atribuição para a variável ‘idade’
apresentados anteriormente foram executados. Porém, ao tentar buscar o segundo
operando, o interpretador Python apontará um erro de sintaxe, informando que
‘uma_decada’ é um nome desconhecido. E, de fato, esta variável não havia aparecido
anteriormente neste texto.
Na linguagem Python, toda variável precisa ser definida antes de ser usada em uma
expressão. A definição implica em atribuir um valor inicial no momento da criação. Por
exemplo, a variável ‘idade’ foi criada com valor inicial 40, com o primeiro comando de
atribuição (idade = 40). Para corrigir, o erro de sintaxe, o código poderia ser reescrito da
seguinte forma:
● uma_decada = 10 # cria a variável uma_decada com valor 10
● idade = idade + uma_decada # utiliza a variável uma_decada
Note que os dois comandos acima não podem ser invertidos, pois se isso
acontecesse, a mesma situação de erro de sintaxe seria apontada pelo interpretador
Python. Novamente, estaria ocorrendo uma tentativa de utilizar no primeiro comando, uma
variável que só seria criada no segundo comando. Lembre que a sequência correta de
eventos é fundamental para se chegar em uma solução correta de qualquer problema.
Este comando irá atribuir, ao final de sua execução, o valor zero para as quatro
variáveis. A ordem de atribuição é da direita para a esquerda, com a variável d sendo a
primeira a ter o valor definido e a variável a sendo a quarta. Mas, para a lógica da
programação de alto nível pode-se enxergar como as 4 variáveis tendo seus valores
definidos “ao mesmo tempo”.
53
Introdução à Programação com Python
resultar sempre em um destes dois valores. Da mesma forma, comparar se uma variável é
maior do que outra, também resultará em valor verdadeiro ou falso.
Já as variáveis do tipo texto (ou strings) podem ter tamanho variável em função do
número de caracteres do texto. Em algumas linguagens, é feita uma distinção para variável
de apenas um caractere. Mas este não é o caso da linguagem Python, que admite até uma
string vazia, ou seja, um texto de zero caracteres.
Note que no Shell do Python algumas informações aparecem com cores diferentes.
O valor False atribuído para a variável ‘terminou’ está na cor laranja. As strings estão na cor
verde e os comentários na cor vermelha. O comentário é iniciado com o caractere # e
aparece na cor vermelha. Um comentário não tem nenhum significado para o interpretador
54
Introdução à Programação com Python
Python, ou seja, tudo o que aparece após o caractere #, na mesma linha, é ignorado pelo
interpretador Python.
No Shell do Python, para exibir o valor atual de uma variável basta digitar o seu
nome e depois a tecla “Enter”. Caso deseje imprimir o valor de mais de uma variável, basta
digitar a lista de nomes de variáveis separando-as com vírgula. Os valores, neste caso,
aparecerão entre parênteses e separadas por vírgulas. No próximo capítulo será
apresentado o comando de impressão, mas até lá as impressões de valores no Shell serão
feitas da forma descrita anteriormente. A Figura 3.5 apresenta um comando para imprimir o
valor de cada variável, na ordem em que foram definidas. Note que a saída deste comando
de impressão é feita na cor azul.
A seguir, na Figura 3.6, são mostradas algumas alterações de valor feitas com a
utilização de comandos de atribuição e algumas expressões bem simples. Na próxima
seção serão vistos com detalhes os operadores da linguagem Python e alguns exemplos de
expressão um pouco mais elaboradas. Os comandos estão na sequência dos comandos já
apresentados na Figura 3.6, ou seja, com os valores iniciais das variáveis já definidos. Para
maior clareza, o último comando da figura anterior será sempre exibido na figura seguinte.
55
Introdução à Programação com Python
O comando seguinte (k = k + idade) tem uma expressão que soma um valor inteiro
com um valor de ponto flutuante, o que resultará em um valor de ponto flutuante. Portanto, o
resultado ao ser atribuído para a variável k não vai alterar o seu tipo. Entretanto, a forma de
exibição do valor que antes utilizada a notação científica tem que ser alterada para que não
se omita o valor fracionário.
Os comandos seguintes que alteram o valor das variáveis sexo e nome mostram
outra característica dinâmica da linguagem Python. Uma variável do tipo string pode
aumentar ou diminuir de tamanho dinamicamente durante a execução do programa. O texto
56
Introdução à Programação com Python
‘Maria das Dores’ tem um caractere a mais do que ‘Carlos Alberto’, portanto, o espaço na
memória reservado para esta variável teve de aumentar (o interpretador Python faz isso de
forma transparente para o programador). A variável sexo também cresceu de forma mais
fácil de se notar. O comentário no comando de criação indicava que ela era do tipo
caractere, na verdade, não está correto. De fato, sexo é uma variável do tipo string que
recebeu, inicialmente, um texto de apenas 1 caractere (‘M’).
+ Soma
- Subtração
* Multiplicação
/ Divisão
** Potenciação
57
Introdução à Programação com Python
1 resultado = 2+6
2 x = 2*resultado
3 pi = 3.14159
4 UmMega = 1024 * 1024
5 y = (x+3)*x/3
6 y = x+y
7 x=y=0
Para responder a esta pergunta pode-se utilizar uma tabela de rastreio para simular
a execução do código. A tabela terá o nome de cada variável e uma coluna indicando qual
comando foi o mais recentemente executado. A cada comando, as variáveis vão sendo
criadas e os valores atribuídos. Uma variável que ainda não foi criada terá seu valor
representado na tabela de rastreio com um traço ‘-’. Por exemplo, na primeira linha está
sendo suposto que nenhum comando foi executado e, portanto, todos os valores são ‘-’.
- - - - - Nenhum
8 - - - - 1
8 16 - - - 2
8 16 3.14159 - - 3
8 16 3.14159 1048576 - 4
8 0 3.14159 1048576 0 7
58
Introdução à Programação com Python
Suponha, agora, que se deseja usar o Shell para calcular a área de um círculo. A
fórmula para cálculo da área de um círculo é π. 𝑟², onde r é o raio do círculo e π é um valor
constante igual a 3.14159 na representação com 5 casas decimais de precisão.
Nos 3 primeiros comando da Figura 3.9 são usados para: definir o valor da
constante pi; definir o valor do raio; e calcular a área. O valor 12.56636 é exibido, como
resultado do quarto comando, como sendo o valor da área de um círculo de raio 2. A área
depende da unidade do raio. Se o raio fornecido significar 2 cm, a área seria de 12.56636
cm². Porém, se o raio estivesse em metros, a área seria de 12.56636 m².
59
Introdução à Programação com Python
Um absurdo do ponto de vista lógico, pois não existe área negativa. Note que este
valor absurdo, deriva do erro absurdo de definir o valor da constante pi como -1, ao invés de
3.14159. Mas, do ponto de vista da execução do código, para o computador está tudo certo.
O nome pi, para o computador, não tem nenhum significado especial, logo, qualquer valor
atribuído para a variável será aceito. Não há erro na definição das variáveis e nem nas
expressões aritméticas. Importante frisar que o computador não erra. O que ele pode fazer
é executar comandos que contém erro na sua definição e que ele não consegue identificar.
1 () Parênteses
2 ** Potenciação
3 - Negação
5 + - Soma e Subtração
60
Introdução à Programação com Python
● -1**2 = -1
● (-1)**2 = 1
● 8+3*2 = 8+6 = 14
● (8+3)*2 = 11*2 = 22
● 2+4%3 = 2+1 = 3
● (2+4)%3 = 6%3 = 0
● 5-3+1 = 2+1 = 3
● 5-(3+1) = 5-4 = 1
● 1+4/2+2*2 = 1 + 2 + 2*2 = 1 + 2 + 4 = 3 + 4 = 7
A not A
False True
True False
61
Introdução à Programação com Python
2 linhas. A aplicação da função not, portanto, inverte o valor da entrada fornecida, conforme
indicado em sua tabela verdade.
A B not(A)
A tabela verdade para duas entradas, como é o caso da função and mostrada acima
𝑛
terá 4 linhas. O número de linhas de uma tabela verdade será sempre 2 , onde n
corresponde ao número de entradas da função booleana.
A B not(A)
A Tabela 3.5 apresenta os três operadores lógicos com a respectiva notação utilizada na
linguagem Python.
e (and) and
ou (or) or
62
Introdução à Programação com Python
< menor
> maior
== igual
!= diferente
Note que o tipo (booleano) das variáveis a, b e c foram definidos em função do valor
(verdadeiro ou falso) resultante da avaliação das expressões relacionais. O que aconteceria
se, por um erro de digitação, fosse utilizado apenas um caractere ‘=’ para fazer a
comparação entre x e y?
63
Introdução à Programação com Python
1 - negação aritmética
2 ** Potenciação
4 + - Soma e Subtração
7 and E lógico
8 or OU lógico
9 = Atribuição
64
Introdução à Programação com Python
65
Introdução à Programação com Python
𝑛 >= 𝑎 𝐸 𝑛 <= 𝑏
𝑛 < 𝑎 𝑂𝑈 𝑛 > 𝑏
Mas esta expressão representa os números que estão fora do intervalo. Assim,
devemos negá-la para que seja representado os números que pertencem ao intervalo:
66
Introdução à Programação com Python
outros que estão fora (ex: -1 e 230). A Tabela 3.8 apresenta o detalhamento do resultado de
todas as operações relacionais e booleanas, com o valor final das expressões 1 e 2 nas
colunas em negrito, mostrando que são equivalentes.
Tabela 3.8 - Comparação entre (n>=a and n<=b) e not(n<a or n>b) para a=0 e b=100
A B n>=0 and n<=100 C D E not(n<0 or n>100)
Para a sequência, vai ser considerado o intervalo [0, 100], substituindo, então, a por
0 e b por 100. Considere a primeira equivalência do Teorema de Boole que possui a sua
primeira parte escrita com a mesma estrutura da expressão 2, deduzida anteriormente:
𝑛𝑜𝑡(𝑛 < 0 𝑜𝑟 𝑛 > 100) = 𝑛𝑜𝑡(𝑛 < 0) 𝑎𝑛𝑑 𝑛𝑜𝑡(𝑛 > 100)
Mas o que seriam 𝑛𝑜𝑡(𝑛 < 0) e 𝑛𝑜𝑡(𝑛 > 100)? Ora, negar a comparação 𝑛 < 0 é
utilizar a comparação 𝑛 >= 0, pois todo valor que torna a primeira comparação verdadeira
vai tornar a segunda comparação falsa e, vice-versa. Em Português pode-se dizer que “o
que não é menor do que zero”, só pode “ser maior ou igual a zero”. Usando o operador
booleano not pode-se escrever 𝑛𝑜𝑡(𝑛 < 0) "𝑒𝑞𝑢𝑖𝑣𝑎𝑙𝑒 𝑎" 𝑛 >= 0. Analogamente, para
negar a comparação 𝑛 > 100 deve-se utilizar a comparação 𝑛 <= 100. Usando o operador
lógico not pode-se definir a relação 𝑛𝑜𝑡(𝑛 > 100) "𝑒𝑞𝑢𝑖𝑣𝑎𝑙𝑒 𝑎" 𝑛 <= 100. Desta forma,
podemos reescrever a equivalência anterior:
67
Introdução à Programação com Python
3.3. Exercícios
1) Para o código mostrado abaixo, informe o valor que será recebido pela variável em
cada um dos comandos de atribuição. Qual o tipo da variável em cada comando de
atribuição ?
A=5
B=A-7
C=A+B*2
D = A + B ** 2
E = D ** 0.5
F=A/3
G = A // 3
H=A%3
I=A+B*C/2*D
J = A + B * C / (2 * D)
K = I // J
L=I/J
M = int(I / J)
N = float(M)
2) Para o código mostrado abaixo, informe o valor que será recebido pela variável em
cada um dos comandos de atribuição. Qual o tipo da variável em cada comando de
atribuição ?
A=2
B=A+7
C=2*A+B
D=C-B>B-C
E = A + B * C == 120
F = E and A>B or C > B
G = A >= 0 and A <= 100
H = A < 0 or A > 100
I = D and G or E and H
68
Introdução à Programação com Python
J = D and (G or E) and H
K = D or G and E or H
L = (D or G) and (E or H)
M = (K and L) == (not(not(K) or not(L)))
N = (K or L) == (not(not(K) and not(L)))
3) Para o código mostrado abaixo, informe o valor que será recebido pela variável do
tipo texto (string) em cada um dos comandos de atribuição.
nome = 'José'
sexo = 'Masculino'
sobrenome = 'Leôncio da Silva'
nomeCompleto = nome + sobrenome
nomeComplComEspaco = nome + ' ' + sobrenome
nomeTriplo1 = 3*nomeComplComEspaco
nomeTriplo2 = 3*(nomeComplComEspaco+' ')
linha = 'Nome: ' + nomeComplComEspaco + ' Sexo: ' + sexo
5) Escreva uma expressão que dada uma temperatura em graus Fahrenheit, calcule o
𝐶 𝐹−32
valor correspondente em graus Celsius, de acordo com a fórmula: 5 = 9
6) Escreva uma expressão para calcular a área de um círculo, sabendo o valor do raio
(R). A expressão deve atribuir o valor para a variável de nome Area.
69
Introdução à Programação com Python
9) Generalize a solução do exercício anterior para definir uma expressão para atribuir
para uma variável de nome SomaN, o valor dos N primeiros números naturais.
10) Defina uma expressão para calcular a soma dos N primeiros elementos de uma
Progressão Aritmética (PA), cujos valores do primeiro elemento e da razão terão
valores atribuídos para as variáveis a1 e razao, respectivamente. A expressão para
o cálculo da soma deverá ser atribuído para uma variável de nome SomaNPA. Dica:
utilize uma outra expressão para atribuir para uma variável An o valor do n-ésimo
elemento da PA.
11) Use a janela do Shell do ambiente de programação IDLE para verificar a solução do
exercício anterior. Use sequências pequenas para facilitar a verificação do somatório
dos valores da Progressão Aritmética. Por exemplo para a sequência 2, 5, 8 e 11, na
qual a1 = 2 e razao = 3, a soma dos valores é 26.
12) Defina uma expressão para calcular a soma dos N primeiros elementos de uma
Progressão Geométrica (PG), cujos valores do primeiro elemento e da razão terão
valores atribuídos para as variáveis elem1 e razaoPG, respectivamente. A
expressão para o cálculo da soma deverá ser atribuído para uma variável de nome
SomaNPG. Dica: utilize uma outra expressão para atribuir para uma variável elemN
o valor do n-ésimo elemento da PG.
13) Use a janela do Shell do ambiente de programação IDLE para verificar a solução do
exercício anterior. Use sequências pequenas para facilitar a verificação do somatório
dos valores da Progressão Geométrica. Por exemplo para a sequência 2, 4, 8 e 16,
na qual elem1 = 2 e razaoPG = 2, a soma dos valores é 30.
70
Introdução à Programação com Python
Para as seções a seguir está sendo suposto que os comandos de entrada e saída
estão relacionados, respectivamente com o teclado e o monitor de vídeo. Porém, é bom
ressaltar que estes dispositivos padrão podem ser alterados como, por exemplo, para
utilizar arquivos como entrada e/ou saída de dados.
print('Olá UFV...')
O comando print() escreve na tela (monitor de vídeo) o texto (string) que foi usado
como parâmetro. Este é o comando utilizado para escrever uma ou mais informações na
saída padrão do computador. A forma geral do comando print() é mostrada a seguir:
print(<lista de parâmetros>)
71
Introdução à Programação com Python
Os comandos iniciais definem uma variável inteira (idade) e quatro variáveis do tipo
string (sexo, nome, cabo e espessura). Note que para a variável cabo a delimitação da
string que contém uma aspas simples (‘) foi feita com aspas duplas (“). Ou seja, quando a
delimitação de uma string é iniciada com um tipo de aspas, ela deve ter o final de sua
delimitação com o mesmo tipo de aspas.
O primeiro comando print possui dois parâmetros: um texto (string) e a variável
nome. Um texto sempre aparecerá da forma que está escrito entre as aspas. A variável será
sempre substituída pelo seu valor. O resultado deste primeiro comando será: Nome: Carlos
Alberto. Note que o espaço em branco (que é um caractere associado à barra de espaço do
teclado) após Nome: na string (primeiro parâmetro) será exibido. Portanto, adicionar
caracteres de espaço serve para separar duas informações em uma string.
O segundo comando print é muito parecido com o primeiro, mas com 4 parâmetros
ao invés de 2. O primeiro e terceiro parâmetros, que são strings, serão exibidos exatamente
como foram escritos no comando print. Já o segundo (sexo) e quarto (idade) parâmetros
são dois nomes de variáveis que serão substituídos pelo valor atual das respectivas
variáveis presentes na memória (valor da última atribuição feita).
Finalmente, o terceiro comando print possui apenas duas variáveis como
parâmetros. Logo, serão exibidos os dois valores das variáveis cabo e espessura. Note que
o comando print() insere um espaço em branco para separar os parâmetros na exibição. A
Figura 4.2 apresenta a janela do Shell do ambiente IDLE, com o resultado da execução do
programa.
72
Introdução à Programação com Python
73
Introdução à Programação com Python
No primeiro comando da Tabela 4.1 foi utilizada a string vazia (0 caracteres) como
separador e, por isso, as duas strings foram impressas como se não houvesse separação.
No segundo comando o separador foi uma sequência de três asteriscos. Nos dois últimos
comandos os separadores utilizados fazem parte do grupo de caracteres de controle (ou
não imprimíveis). O caractere ’\t’ (lê-se contrabarra t) é o espaçamento de tabulação (tecla
Tab existente nos teclados) que corresponde ao espaço de alguns caracteres (no resultado
da execução do comando parece ser de 4 espaços). Já o caractere ‘\n’ (contrabarra n)
corresponde ao “Carriage Return” (tecla Enter dos teclados) e indica que se deve ir para o
início da próxima linha. Por isso o último comando print() da Tabela 4.1 utilizou duas linhas.
O caractere ‘\n’ é o terminador padrão do comando de saída print(). Este padrão
também pode ser alterado utilizando o parâmetro end=<terminador> onde <terminador>
corresponde à string de zero ou mais caracteres que se deseja usar imediatamente após a
impressão dos parâmetros imprimíveis. A Tabela 4.2 apresenta alguns comandos de
impressão supondo, novamente, as variáveis criadas na Figura 4.1.
Tabela 4.2 - Exemplos de utilização do parâmetro de terminação
Comandos Resultado da Execução
74
Introdução à Programação com Python
"\t" "\n"
\t \n
O caractere de tabulação é definido somente quando aparece a sequência ‘\t’. Uma
sequência de caracteres ‘\\t’ vai imprimir ‘\t’ na tela (sem as aspas). A mesma coisa vale
para o ‘\n’. E, para imprimir as aspas duplas foi utilizada a sequência '\"' (contra barra aspas
dupla) - usada quatro vezes. Certifique-se de que no comando anterior existem apenas 3
tabulações ('\t') e um “pula linha” (\n) - estão em negrito no comando para facilitar o
entendimento.
75
Introdução à Programação com Python
Figura 4.4 - Resultado da Execução dos códigos das Figuras 4.1 e 4.3
76
Introdução à Programação com Python
Figura 4.6 - Trecho da janela do Shell com o resultado da execução do código da Figura 4.5
77
Introdução à Programação com Python
78
Introdução à Programação com Python
do caractere ‘-’, antes do valor numérico que definiu o espaço. O espaço de 3 colunas (ou
caracteres) foi definido para escrever o número inteiro de dois dígitos que representa a
idade do funcionário. Finalmente, para escrever o valor do salário foi escolhido o
espaçamento total de 10 colunas, com duas casas decimais. Estes dois últimos valores tem
alinhamento padrão, à direita.
Para exibir a informação dos outros dois servidores serão usados comandos de
impressão com o mesmo espaçamento deste primeiro. Será colocado um comando
adicional para imprimir um cabeçalho para a tabela, antes dos comandos para imprimir as
informações dos funcionários. Este comando pode ser definido da seguinte maneira:
print('Nome%20s Cargo%7s Idade Salário' %(' ', ' '))
O comando acima importa dois caracteres branco (ou espaço) para a string.
‘Nome… ...Salário’. Para o primeiro caractere foram reservados 20 espaços que juntamente
com os caracteres ‘Nome’ totalizam os mesmos 24 caracteres reservados para imprimir o
nome do funcionário. Ou seja, os espaços escolhidos para a impressão do cabeçalho e para
a impressão das informações dos servidores foram de tal forma a dar a ideia de uma tabela.
A Figura 4.7 mostra o código com os comandos de impressão alterados conforme a
discussão apresentada.
Um detalhe importante a ser observado é que para este efeito de impressão do tipo
tabela pressupõe, neste caso, que o tamanho total das strings sejam o mesmo, pois existe o
alinhamento à esquerda da primeira coluna e o alinhamento à direita da última coluna. Note
que a string do cabeçalho reserva 27 espaços, tem 4 caracteres branco (entre Idade e
Salário são 2) e 21 letras (NomeCargoIdadeSalário) totalizando, portanto, um espaço de 52
caracteres. E cada comando de impressão das informações do funcionário tem três
caracteres branco (separando os formatadores para facilitar o entendimento) e reserva
24+12+3+10=49 espaços, totalizando também um espaço de 52 caracteres. O resultado da
execução do código mostrado na Figura 4.7 é apresentado na Figura 4.8.
79
Introdução à Programação com Python
<variável> representa um nome válido de uma variável Python que receberá o valor
lido. <msg> representa uma mensagem que será exibida na tela. Esta mensagem é útil para
que o usuário seja orientado sobre qual a informação que deverá ser fornecida.
80
Introdução à Programação com Python
O texto em preto ‘José da Silva’ foi fornecido pelo usuário do programa, que após a
digitação deste texto, pressionou a tecla ‘Enter’. Neste momento, o valor da string ‘José da
Silva’ é atribuído para a variável nome. Na sequência, o comando de impressão escreve na
tela a string com a importação do valor da variável nome, resultando no texto em azul ‘Bom
dia, José da Silva!’
Por padrão, na linguagem Python, o valor recebido via teclado é interpretado como
string (uma sequência de caracteres). Se o usuário digitar ‘125’ este valor representa um
texto com os caracteres que representam os algarismos 1, 2 e 5 e não o número 125. Para
que uma entrada seja interpretada como um valor numérico inteiro ou real (ponto flutuante)
é necessário explicitar a transformação usando int ou float, respectivamente. A Figura 4.10
apresenta um pequeno programa exemplificando a transformação para inteiro e ponto
flutuante.
Na Figura 4.10, a variável idade será do tipo inteiro (int) e na execução do programa
lhe foi atribuído o valor 56. Já a variável altura será do tipo ponto flutuante (float) com valor
definido na execução do programa igual a 1.77. Observando, mais uma vez, que na janela
do Shell os valores em azul foram escritos pelo programa e os valores em preto foram
fornecidos pelo usuário.
81
Introdução à Programação com Python
A seguir são apresentados dois problemas simples que, em princípio poderiam ser
resolvidos com as informações vistas até aqui: algoritmos, refinamentos sucessivos,
variáveis, expressões aritméticas e comandos de entrada e saída.
Na sequência será mostrado que para os dois casos a solução correta deve
considerar outra estrutura de programação que será vista no próximo capítulo. Mas que
com o conhecimento de algoritmos já é possível identificar o problema e resolvê-lo em
termos de algoritmo. Porém, como as soluções agora são utilizando a linguagem Python,
elas serão apresentadas no capítulo 5.
82
Introdução à Programação com Python
83
Introdução à Programação com Python
Mas, este erro só ocorreu porque a condição necessária para determinar se com os
valores informados para os lados (a, b e c) seria, de fato, possível formar um triângulo. Esta
84
Introdução à Programação com Python
condição deveria ser verificada antes de se fazer o cálculo da área. E, em caso negativo,
deveria ser informado ao usuário que não é possível representar um triângulo com os
valores fornecidos. No próximo capítulo será apresentada a solução para este caso.
O cálculo das raízes de uma equação de segundo grau pode ser feito utilizando a
fórmula de Bháskara 𝑥 = (− 𝑏 ± 𝑏² − 4𝑎𝑐)/2𝑎.
Porém, se o divisor (2*a) não for colocado entre parênteses no programa Python,
ocorrerá primeiro uma divisão por 2 e depois uma multiplicação por a. A colocação dos
parênteses forçará primeiro a ocorrência da multiplicação 2*a e, depois, a divisão por “2a”.
Observe que a expressão para cálculo da segunda raiz escreve de maneira diferente (e
correta) o divisor “2a”. O cálculo de b² também foi feito de maneira diferente nas duas
expressões, mas ambas corretas.
Para testar o programa foram feitas três execuções para diferentes valores de
coeficientes. Nas duas primeiras execuções o programa respondeu corretamente com as
85
Introdução à Programação com Python
raízes das duas equações. Porém, na terceira execução o Shell apontou um erro de divisão
por zero (ZeroDivisionError: float division by zero), conforme mostrado na Figura 4.14.
A razão do erro está no fato do valor fornecido para o coeficiente a ter sido zero. A
fórmula de Bháskara pressupõe que o coeficiente a será diferente de zero. De fato, se a for
zero, a equação não será de segundo grau. Para a terceira execução, com os coeficientes
informados, a equação seria: 2𝑥 + 1 = 0 uma equação de primeiro grau.
4.4. Exercícios
86
Introdução à Programação com Python
2) Altere os comandos de impressão do exercício anterior para gerar uma saída similar
à mostrada a seguir. A quebra de linha será determinada pela largura da janela do
Shell, por isso o resultado deve ser similar e não exatamente igual ao exibido
abaixo. Na solução deve haver um único comando para imprimir os nomes e valores
das variáveis inteiras e um outro único comando para imprimir os nomes e valores
para as variáveis reais (ou de ponto flutuante). As mensagens de texto devem ser
feitas em comandos de impressão separados, ou seja, deverão existir apenas 4
comandos de impressão no programa.
3) Altere os comandos de impressão do exercício anterior para gerar uma saída igual
à mostrada a seguir, onde os números de ponto flutuante são apresentados com
precisão de 3 casas decimais (use %f para formatar os números reais).
87
Introdução à Programação com Python
7) Mude o comando de atribuição da variável inteira A para que a atribuição seja feita
por um valor fornecido pelo usuário. Note na figura mostrada a seguir que o valor
digitado pelo usuário aparece na cor preta, enquanto que os valores escritos pelo
programa aparecem em azul. Altere também o comando de impressão das variáveis
de ponto flutuante, para que o alinhamento seja feito à direita (alinhando o ponto
decimal dos valores). Na figura é mostrado um exemplo no qual o usuário forneceu o
valor 10.
8) Altere o programa para que sejam lidos dois valores: um inteiro que será atribuído
para a variável A e outro valor real que será atribuído para a variável E. O programa
deve deixar claro para o usuário que o primeiro valor tem que ser inteiro e o segundo
88
Introdução à Programação com Python
10) Altere os comandos de impressão do exercício anterior para gerar a saída similar à
mostrada na figura a seguir. O programa deve usar um único comando para imprimir
os nomes e valores de todas as variáveis inteiras e um outro único comando para
imprimir os nomes e valores de todas as variáveis booleanas. As mensagens de
texto devem ser feitas em comandos de impressão separados, ou seja, deverão
existir apenas 4 comandos de impressão no programa.
89
Introdução à Programação com Python
impressas até 4 variáveis por linha, para gerar uma saída exatamente igual à
mostrada a seguir.
12) Modifique os comandos de impressão da versão anterior para que o programa gere
a saída igual à mostrada a seguir.
13) No programa gerado para resolver o exercício anterior, inclua comandos de leitura
para que o usuário forneça o valor das 3 variáveis inteiras (A, B e C). Com valores
diferentes, algumas das expressões podem gerar resultados diferentes, modificando
os valores das variáveis booleanas. A figura mostrada a seguir apresenta o
resultado da execução na qual o usuário forneceu os valores -10, 13 e 10,
respectivamente, para as variáveis A, B e C.
14) Escreva um programa para imprimir as variáveis tipo texto do exercício 3 do capítulo
3, sendo uma variável em cada linha. No final do programa, inclua os comandos
mostrados a seguir e observe as diferenças entre as saídas.
90
Introdução à Programação com Python
16) Escreva um programa para calcular a área de um círculo, sabendo o valor do raio
(R). O programa deverá gerar uma saída como a mostrada a seguir.
18) Escreva um programa para calcular a soma dos N primeiros elementos de uma
Progressão Geométrica (PG), cujos valores do primeiro elemento e da razão serão
solicitados ao usuário. O programa deverá informar também o valor do N-ésimo
elemento. A figura a seguir mostra um exemplo de como deve ser a execução do
programa. Dica: pesquise na Internet a fórmula da soma dos elementos de uma PG.
91
Introdução à Programação com Python
5.1. Comando if
if <condição> :
<comando>
92
Introdução à Programação com Python
palavra reservada if. Considere a Tabela 5.1 com um código genérico de comandos Ci e o
fluxo de execução para os casos da condição ser verdadeira ou falsa.
Tabela 5.1 - Exemplos dos dois fluxos de execução possíveis de comandos condicionais
Código Sequência de execução quando Sequência de execução quando
<condição> == True <condição> == False
C1 C1 C1
C2 C2 C2
if <condição> : C3 C5
C3 C4 C6
C4 C5
C5 C6
C6
C1 C1 C1
C2 C2 C2
if <condição> : C3 C4
C3 C4 C5
C4 C5 C6
C5 C6
C6
A condição “é triângulo?” consiste em testar, para cada lado se este lado é menor
que a soma dos outros dois lados. A condição tem que ser verdadeira para cada um dos
lados, logo a junção deve ser feita pela função lógica E (and), como a seguir:
93
Introdução à Programação com Python
94
Introdução à Programação com Python
if <condição> :
<comando1>
else:
<comando2>
Figura 5.4 - Estrutura de comando condicional if/else
Tabela 5.2 - Exemplos dos dois fluxos de execução possíveis de comandos condicionais
Código <condição> = True <condição> = False
C1 C1 C1
if <condição> : C2 C4
C2 C3 C5
C3 C6 C6
else:
C4
C5
C6
C1 C1 C1
if <condição> : C2 C4
C2 C3 C5
C3 C5 C6
else: C6
C4
C5
C6
95
Introdução à Programação com Python
Agora, com a cláusula else sempre que os lados informados não puderem formar
um triângulo, a mensagem ‘Os lados informados não formam um triângulo’. será
apresentada ao usuário.
Suponha que o programa tenha sido feito para uso de alunos do ensino fundamental
e que a mensagem de erro não seja considerada adequada. O que se pretende é a
utilização de uma mensagem que mostre a razão da impossibilidade do cálculo. Deverá ser
informado que nenhum dos lados pode ser maior ou igual à soma dos outros dois e, além
disso, apresentar qual lado está violando a condição da formação de triângulo.
96
Introdução à Programação com Python
A linguagem Python possui uma outra forma de comando condicional que permite
resolver este problema. A estrutura if-elif-else é mostrada na Figura 5.7.
97
Introdução à Programação com Python
if <condição1> :
<comando1>
elif <condição2>:
<comando2>
…
elif <condiçãoN>:
<comandoN>
...
else:
<comandoN+1>
Figura 5.7 - Estrutura de comando condicional if/elif/else
Note que, com esta estrutura, todos os blocos do comando condicional estarão com
o mesmo alinhamento ou com a mesma indentação. A Tabela 5.3 exemplifica os possíveis
fluxos de instrução para um comando if-elif-else com duas condições.
C1 C1 C1 C1
if <condição1> : C2 C4 C6
C2 C3 C5 C7
C3 C8 C8 C8
elif <condição2>:
C4
C5
else:
C6
C7
C8
98
Introdução à Programação com Python
No algoritmo a cláusula elif pode ser escrita como “Senãose”. Usando esta notação,
o final do algoritmo que identifica e informa qual o lado do triângulo que está violando a
condição pode ser reescrito como:
Ao analisar o algoritmo, foi percebido que a mensagem do tipo ‘a deve ser menor
que (b+c)’ não representa bem a informação, por exemplo, quando o lado a está violando a
condição de formação do triângulo. Talvez fosse melhor usar algo do tipo ‘a >= (b+c)’. Ou de
forma mais detalhada, usando o potencial da estrutura condicional que permite vários
“senãose” e informar mais precisamente que ‘a > (b+c)’ ou ‘a = (b+c)’. Dessa forma, o final
do algoritmo pode ser reescrito como:
A Figura 5.8 apresenta a versão final do programa completo para cálculo da área de
um triângulo utilizando a estrutura if-elif-else.
99
Introdução à Programação com Python
100
Introdução à Programação com Python
O problema introduzido na seção 4.3.2 trata do cálculo das raízes de uma equação
do segundo grau, na forma 𝑎𝑥² + 𝑏𝑥 + 𝑐 = 0, tendo sido implementado um programa
mostrado na Figura 4.13. Conforme discutido naquela seção, o programa proposto como
solução possui um problema por não testar se o valor fornecido pelo usuário para o
coeficiente a era diferente de zero. A solução para este problema seria trivial com o uso de
comando condicional, para calcular as raízes apenas quando o coeficiente fosse diferente
de zero.
Graficamente, com Δ > 0a curva que representa a equação corta o eixo x em dois
pontos distintos, com Δ = 0 o ponto de máximo (ou mínimo) da curva fica sobre o eixo x
(abcissas) e no caso de Δ < 0 a curva não corta o eixo x. As equações 𝑥² − 2𝑥 + 1 = 0,
𝑥² − 4 = 0 e 𝑥² + 1 = 0 exemplificam, respectivamente, cada um dos casos citados.
Feitas estas considerações, o algoritmo para cálculo das raízes de uma equação de
segundo grau será refinado, a partir da versão apresentada na seção 4.3.2:
101
Introdução à Programação com Python
Leia(b)
Leia(c)
se a == 0:
imprima(‘Com a = 0, não é equação do segundo grau!’)
senão:
delta = b**2 - 4*a*c
se delta < 0:
imprima(‘Equação não possui raízes reais’)
senãose delta == 0:
x1 = -b/(2*a)
imprima(‘Equação possui apenas uma raiz real’, x1)
senão:
x1 = (-b+delta**0.5)/(2*a)
x2 = (-b-delta**0.5)/(2*a)
imprima(‘Equação possui as raizes reais’, x1, x2)
102
Introdução à Programação com Python
5.5. Exercícios
1) Escreva um programa para ler um número inteiro e escrever se ele é par ou ímpar.
4) Faça um programa que leia 2 números inteiros. Se o segundo for diferente de zero,
calcular e imprimir o quociente do primeiro pelo segundo. Caso contrário, imprimir a
mensagem: “DIVISÃO POR ZERO”.
5) Escreva um programa que leia 4 números inteiros e calcule a soma dos que forem
par.
103
Introdução à Programação com Python
7) Faça um programa que leia 3 números inteiros (a, b e c) e diga se eles são números
Pitagóricos, ou seja, se são da forma a² + b² = c².
10) Escreva um programa que leia as medias (a, b e c) dos lados de um suposto
triângulo e escreva se essas medidas podem formar um triângulo ou não. Caso
afirmativo, dizer seu tipo (equilátero ou isósceles ou escaleno). A condição de
existência de um triângulo é dada por:
- |b−c|<a<b+c
- |a−c|<b<a+c
- |a−b|<c<a+b
12) Escreva um programa que leia a velocidade máxima permitida de uma avenida e a
velocidade com que o motorista estava dirigindo nela e calcule a multa que uma
pessoa vai receber, sabendo que são pagos:
a) Nenhuma multa, se não ultrapassou a velocidade máxima;
b) 50 reais se o motorista ultrapassar em até 20km/h da velocidade máxima
permitida;
c) 100 reais, se o motorista ultrapassar de 21km/h a 40 km/h a velocidade máxima
permitida;
d) 200 reais, se estiver acima de 41km/h da velocidade máxima permitida.
104
Introdução à Programação com Python
uma PG com todos os valores iguais. Faça a correção deste problema no programa,
para que a execução se dê sem erros, como mostrado a seguir.
14) Faça um programa que leia o salário base e o código de um funcionário e imprima o
cargo e o salário bruto do funcionário de acordo com o percentual de aumento
mostrado na seguinte tabela:
1 Diretor 75%
2 Secretário 20%
3 Atendente 10%
4 Caixa 30%
5 Gerente 50%
15) Faça um programa que leia duas datas, compostas por dia, mês e ano: uma é a data
de nascimento de alguém, e a outra é a data atual. Em seguida, o programa deve
imprimir a idade da pessoa. Veja os exemplos:
16) Faça um programa para ler o tempo gasto por dois maratonistas para completar uma
prova, informando quem foi o vencedor e calculando a diferença de tempo entre
eles. Todos os valores serão dados em horas, minutos e segundos. Veja os
exemplos:
Tempo do corredor 1: 3 10 20
Tempo do corredor 2: 3 5 10
105
Introdução à Programação com Python
Vencedor: corredor 2
Diferença: 0 horas 5 minutos 10 segundos
Tempo do corredor 1: 3 5 10
Tempo do corredor 2: 2 58 20
Vencedor: corredor 2
Diferença: 0 horas 6 minutos 50 segundos
17) O Dia da Páscoa, por definição, é o primeiro Domingo após a primeira lua cheia que
ocorre depois do equinócio da Primavera (no hemisfério norte, Outono no hemisfério
sul), e pode cair entre 22 de Março e 25 de Abril. As fórmulas existentes calculam o
que se convencionou chamar de "Cálculo Eclesiático", definido pelo Concílio de
Nicea (325 d.C.). Existem diversas fórmulas para se determinar o Domingo de
Páscoa, entretanto uma das mais simples é a fórmula de Gauss, descrita a seguir.
Para calcular o dia da Páscoa (Domingo), usa-se a fórmula abaixo, onde o ANO
deve ser introduzido com 4 dígitos e X e Y são dados pela tabela a seguir.
a = ANO MOD 19
b= ANO MOD 4
c = ANO MOD 7
d = (19 * a + X) MOD 30
e = (2 * b + 4 * c + 6 * d + Y) MOD 7
ANO X Y
1582 a 1699 22 2
1700 a 1799 23 3
1800 a 1899 23 4
1900 a 2099 24 5
2100 a 2199 24 6
2200 a 2299 25 0
2300 a 2399 26 1
2400 a 2499 25 1
Em seguida:
● Calcula-se o valor de P dado por P = (22 + d + e). Se P for menor ou igual a
31, a Páscoa será no dia P de Março. Caso contrário:
○ Calcula-se P'= (d + e – 9). Se P’ for menor ou igual a 25 a Páscoa
será no dia P' de Abril. Caso contrário:
106
Introdução à Programação com Python
Faça um programa que leia um ano e diga o dia e mês que ocorreu (ou ocorrerá) a
Páscoa naquele ano. Lembre-se de verificar se o ano digitado é válido e se está
presente na tabela acima. Veja os exemplos:
107
Introdução à Programação com Python
Leia(a)
enquanto a == 0:
imprima(‘Valor tem que ser diferente de 0 (zero)’)
Leia(a)
while <condição> :
<comando>
108
Introdução à Programação com Python
A Figura 6.2 mostra uma parte da janela do editor de programas e da janela do Shell
com o resultado da execução na qual o usuário fornece o valor zero duas vezes. Na terceira
vez é fornecido o valor 1 e o programa solicita o valor do coeficiente b.
Figura 6.2 - Uso do while para validar uma entrada diferente de zero
109
Introdução à Programação com Python
110
Introdução à Programação com Python
Observe que na primeira execução, o comando repetitivo foi executado zero vezes,
pois para o primeiro valor fornecido para o coeficiente a, igual a 1, a condição do comando
repetitivo, a == 0, resultou no valor False e o comando repetitivo termina, sem entrar
nenhuma vez no bloco de comandos a serem executados repetitivamente. Na sequência, a
partir do comando de leitura para a variável b, o código é idêntico ao mostrado na Figura
5.11 e, então, os valores 3 e -4 são lidos e atribuídos para as variáveis que representam os
coeficientes b e c. O valor 25, resultante da expressão 𝑏 ** 2 − 4 * 𝑎 * 𝑐, é atribuído para
a variável delta. O que fará com que os comandos na cláusula else do comando if-elif-else
seja executado para calcular o valor de duas raízes e imprimir a mensagem vista na Figura
6.3.
O que gerou o laço infinito foi exatamente a supressão do comando de leitura dentro
do bloco de comandos repetitivos. O comando de leitura, antes do comando repetitivo,
atribuiu o valor 0 (zero) para a variável a. Ao testar a condição do comando repetitivo, a==0,
o resultado foi verdadeiro e, por causa disso, será executado o comando repetitivo que
agora tem apenas o comando print(). Ora, se o comando print() não altera o valor da
variável a (quem alterava o valor de a era o comando input(), que virou comentário), então a
condição do comando repetitivo será verdadeira para sempre e o comando repetitivo não
terminará…
Por isso, é importante observar que no bloco de comandos repetitivos deve sempre
haver (pelo menos) um comando que torne, em algum momento, a condição de teste falsa,
para que o comando repetitivo termine e o programa continue a sua execução, terminando
em um tempo finito. Se todos os comandos repetitivos atenderem a este requisito (terminar
em algum tempo), o programa estará mapeando de maneira adequada um algoritmo.
O tempo que um comando repetitivo levará para terminar pode ser indeterminado. É
o caso do exemplo da Figura 6.2. Primeiramente, porque a avaliação da condição no
comando repetitivo depende de um comando de entrada (input()), que só termina a sua
execução após o usuário digitar a informação e apertar a tecla ‘Enter’. Se o usuário iniciar o
programa e, antes de digitar o primeiro valor, parar durante uma hora para fazer qualquer
outra atividade, e depois voltar a usar o programa, uma única iteração do comando
repetitivo vai demorar uma hora.
Em segundo lugar, o número de repetições vai depender dos valores fornecidos para
o coeficiente a da equação do segundo grau. Se o primeiro valor for diferente de zero,
conforme já explicado, o valor é válido e o comando repetitivo será executado zero vezes.
Se o usuário fornecer, no início, uma sequência de N valores zeros antes de fornecer antes
de fornecer um primeiro valor diferente de zero, o comando repetitivo será executado N
vezes. Este evento já foi visto na Figura 6.2, em uma execução onde os valores 0, 0 e 1
foram informados para o coeficiente a, fazendo com que o comando repetitivo fosse
executado 2 vezes (observe na Figura 6.2 que a mensagem de erro seguida de um novo
pedido do coeficiente a foram exibidos 2 vezes).
111
Introdução à Programação com Python
i = <valor inicial>
while i < <valor final> :
<comando>
i=i+1
Figura 6.4 - Forma geral do comando while com contador
i=0
while i < 10:
print('%4d' %i, end='') # bloco de comandos
i=i+1 # repetitivos
print()
print('%4d' %i)
0 1 2 3 4 5 6 7 8 9
10
112
Introdução à Programação com Python
1 2 3 4 5 6 7 8 9 10
10
0 3 6 9
12
+= x += 1 x=x+1
-= x -= 1 x=x-1
*= x *= 2 x=x*2
/= x /= 2 x=x/2
//= x //= 2 x = x // 2
%= x %= 2 x=x%2
**= x **= 2 x = x ** 2
113
Introdução à Programação com Python
interpretador da linguagem Python ao ler o caractere ‘+’ e depois um espaço em branco iria
entender que se trata do operador de adição. Logo, após o espaço em branco deveria vir
obrigatoriamente um número ou o nome de uma variável ou uma expressão. Mas o que
aparece é um caracter de atribuição ‘=’. Assim, tem um erro de escrita (sintaxe) no código.
A solução para este problema seria a de usar os comandos uma única vez, dentro
do bloco de comandos repetitivos. Como os comandos agora só existem dentro do bloco
repetitivo, a condição no início do comando tem que permitir a entrada sempre que se
chegar no comando repetitivo. Por exemplo, sendo o valor fixo e igual a verdadeiro (True).
Mas, como não se pode ter um loop infinito deve ser criada uma forma de se quebrar o loop
se uma determinada condição for alcançada. Em termos de algoritmo, o trecho anterior,
poderia ser reescrito como:
enquanto Verdadeiro:
Leia(a)
se a != 0 :
quebra_loop
imprima(‘Valor tem que ser diferente de 0 (zero)’)
Note que, semanticamente, os dois trechos de algoritmo são idênticos. Vai ter que
ser lido um valor inicial (agora dentro do comando repetitivo). Enquanto o valor lido for igual
a zero, a impressão da mensagem de erro será feita e uma nova iteração do comando
repetitivo irá realizar nova leitura de valor. Quando o valor lido for diferente de zero, o loop
será quebrado, com o valor atribuído para a variável a. Inclusive, se o primeiro valor
fornecido for diferente de zero, a mensagem de erro não será impressa.
114
Introdução à Programação com Python
Posteriormente a uma destas duas ações, o servidor volta para o comando onde ele
fica esperando a chegada de uma nova requisição. Um bom servidor de páginas deve ficar
nesta execução 24 horas por dia, sete dias por semana. Eventualmente ele será parado por
algum comando do administrador (um break será executado) para alguma manutenção
rápida ou problema de segurança ou talvez para dar lugar a uma nova versão.
115
Introdução à Programação com Python
Para resolver este problema, uma outra estrutura de comando repetitivo com
incremento automático do contador está presente na linguagem Python. Nesta estrutura, o
contador é inicializado no próprio comando repetitivo. A Figura 6.6 apresenta uma forma
geral do comando repetitivo for:
A variável a ser usada como contador é definida no próprio comando, não havendo a
necessidade de definição anterior ao comando for. Mas, também é possível utilizar alguma
variável que já tenha sido criada. O <valor inicial> será o primeiro valor da variável contador
e <valor final - 1> será o último valor. O comando for não executa para <contador> = <valor
final>. O incremento padrão do contador é de uma unidade a cada execução ou à cada
iteração.
O trecho de código usado como exemplo na seção 6.1.2, pode ser reescrito com a
substituição do while pelo comando for. Para facilitar a comparação, os dois códigos são
apresentados lado a lado na Tabela 6.2.
Observe que o comando for fica mais compacto porque na linha do cabeçalho é
definido o valor inicial e final do contador e, portanto, o número de repetições. Como o
comando for não executa para o valor final (10) os dois comandos irão executar para os
valores de i variando de 0 a 9. Porém, no caso do comando for, o valor da variável de
116
Introdução à Programação com Python
controle não assume o valor 10, diferentemente do que acontece com o comando while, no
qual a variável i tem que assumir o valor 10, para tornar a condição i<10 falsa. No trecho de
código a seguir, são incluídos os mesmos dois comandos de impressão usados no código
do início da seção 6.1.2:
0 1 2 3 4 5 6 7 8 9
9
Leia(N)
Leia(k)
para i na faixa (k, N+1):
se “i é múltiplo de k”:
imprima(i)
117
Introdução à Programação com Python
GHz de clock. O número exato de repetições é calculado como o <valor final> - <valor final>
ou 100000001 - 50000000 = 50000001.
Uma solução usando o comando repetitivo while seria muito mais eficiente se
utilizasse o valor inicial igual a k e um incremento também igual a k, ao invés de um
incremento unitário. Este incremento eliminaria ainda a necessidade de comparação, pois a
regra de geração definiria a seguinte sequência: k, 2k, 3k…, etc. enquanto o número da
sequência fosse menor do que N. Para o exemplo, a sequência teria apenas dois números
50000000 e 100000000. Aliás, para este caso nem seria necessário escrever um programa.
Esta comparação é para que você se convença de que nem sempre é suficiente ter
uma solução correta. Às vezes, é necessário ter uma solução correta e eficiente. Embora
este aspecto não seja cobrado nas soluções desta disciplina de Introdução à Programação,
é fundamental conhecer este aspecto e tratá-lo de maneira adequada (com uma solução
eficiente) quando ele aparecer.
118
Introdução à Programação com Python
Veja que o número de repetições do comando for foi igual a 6, por causa da faixa
definida: N+1-k = 10+1-5 = 6. O valor inicial de i = 5 (<valor inicial>), com incremento
unitário a cada nova iteração, eliminando o efeito do comando de incremento, i = i + k. Por
isso, uma boa prática de programação é não usar comando de atribuição para alterar a
variável de controle do for.
Lembre-se que, com o decremento unitário, o comando for caminha do maior valor
para o menor valor da faixa especificada e não executa para o valor final da faixa, que deve
ser igual a k-1 e não igual a k, quando se deseja executar para o valor de i = k.
119
Introdução à Programação com Python
Lembrando que a suposição inicial é de que N>k e, portanto, sempre haverá pelo
menos um múltiplo na sequência de 1..N (na verdade a verificação pode se feita apenas na
sub-sequência de k..N). Assim, o maior múltiplo de k encontrado poderá ser utilizado como
o valor inicial da faixa do comando for. O seguinte código poderia ser usado para encontrar
o maior múltiplo de k:
mm = N
while mm % k != 0: # testa se mm não é múltiplo de k
mm = mm - 1 # passa para o “próximo” número da sequência
Na linguagem Python o comando break pode ser utilizado para parar o comando
repetitivo while, como mostrado na seção 6.1.3. Da mesma forma, a comando break pode
ser utilizada no comando for, geralmente associado a uma condição. Por exemplo,
encontrar um número que seja múltiplo de k. Desta forma, um código equivalente ao
mostrado anteriormente pode ser escrito utilizando o comando for:
120
Introdução à Programação com Python
comando repetitivo while. No próximo capítulo serão vistos exemplos onde o uso do
comando for é mais adequado.
Faça um programa que peça para o usuário digitar as notas de uma turma e, então,
calcula a média das notas. O número de alunos da turma deve ser requisitado ao usuário,
antes do programa iniciar a leitura das notas. As notas devem estar no intervalo [0..100] e
valores fora desta faixa não deverão ser aceitos.
A solução para este problema poderia ser descrita nos seguintes passos: 1. obter o
número de alunos da turma; 2. ler uma nota; 3. se a nota for válida, totalizar o valor e
incrementar o número de notas lidas; 4. Voltar ao passo 2 enquanto o número de notas for
menor que o número de alunos da turma; 5. Calcular e informar a média das notas.
Uma primeira versão para este algoritmo, baseada na descrição feita, pode ser
escrita como: 3.2.2.5
121
Introdução à Programação com Python
Também será necessário usar um contador (cont) para controlar o número de notas
lidas. O comando repetitivo deve parar quando o número de notas válidas lidas for igual ao
número de alunos da turma. Portanto, este contador só deve ser incrementado quando uma
nota lida for válida.
Figura 6.8 - Programa para cálculo da média de N notas usando apenas while
122
Introdução à Programação com Python
Esta figura também apresenta a janela do Shell com a execução onde o usuário
informa que a turma tem 4 alunos e entra com a seguinte sequência de notas: 0, 100, 130,
90, -2 e 80. A sequência possui 2 notas inválidas (130 e -2) e 4 notas válidas (0, 100, 90 e
80). É fácil verificar que o somatório das 4 notas será 270 e a média igual a 67.5.
Na solução apresentada foi usada apenas o comando repetitivo while. Poderia ser
usado o comando for? Na verdade, a pergunta que deve ser feita é se seria adequado
utilizar o comando repetitivo for. Em princípio, o comando for é mais adequado quando o
número de repetições é conhecido à priori.
Nesta solução, o número de notas que o usuário deve informar é definido pelo
próprio usuário ao informar o número de alunos da turma. Desta forma, o uso do comando
repetitivo for parece ser adequado. Entretanto, não existe garantia de que o usuário só
entrará com valores válidos para as notas. No exemplo anterior, o usuário forneceu um total
de 6 valores, com 4 notas válidas e 2 inválidas.
Uma estratégia que pode ser adotada é obrigar que o usuário forneça uma nota
válida, antes de passar para o próximo comando do programa. A ideia desta abordagem
levaria a um algoritmo diferente, que pode ser descrito como:
O comando de leitura de notas válidas pode ser traduzido para Python como:
while True:
nota = float(input(‘Nota = ‘)
if nota >= 0 and nota <=100:
break
print(‘Nota inválida’)
Quando o teste da condição for verdadeiro, o comando repetitivo termina, porque foi
fornecido um valor válido. Caso contrário, será impressa a informação de que a nota é
inválida e uma nova nota será solicitada, no primeiro comando de um nova iteração do
comando repetitivo. Neste caso, o comando de impressão para informar que a nota é
inválida não precisa estar vinculado à cláusula else. Mas caso fosse colocada, o resultado
seria o mesmo.
123
Introdução à Programação com Python
Figura 6.9 - Programa para cálculo da média de N notas usando for e while
Faça um programa que peça para o usuário digitar um número inteiro e, então, testa
se o número digitado é um número primo. Como resultado, o programa deve informar se o
número informado é primo ou não. O programa deverá testar a primalidade de vários
números. Use qualquer valor menor ou igual a zero como 'sentinela' para indicar que o
término do programa. Ou seja, quando o usuário não quiser mais testar se um número é
primo. O algoritmo para este problema poderia ser descrito da seguinte forma:
Leia(num)
Se “num é primo”:
Escreva(“num é primo)
Senão:
Escreva(“num não é primo”)
124
Introdução à Programação com Python
Por definição, um número inteiro é primo se ele for divisível apenas por 1 e por ele
próprio. Desta forma, o teste não é um teste simples e que possa ser verificado dentro da
cláusula “Se”. Para verificar se um número é primo, uma possibilidade é testar para todos
os números na sequência de [2..num-1], se algum deles é divisor de num. Se nenhum dos
elementos da sequència [2..num-1] for divisor, num é primo.
Observe que antes do comando repetitivo, o divisor (dv) é inicializado com o valor 2
e a cada repetição, dv é incrementado de uma unidade, para permitir que toda a sequência
de possíveis divisores seja percorrida. Uma das condições de parada do comando repetitivo
é encontrar um divisor, o que torna a segunda cláusula do E lógico falsa.
125
Introdução à Programação com Python
Note que esta solução poderia ser melhorada (tornada mais eficiente), pois se o
número fornecido for muito grande, o número de repetições do comando repetitivo também
será, quando o número for primo. Se for um número não primo, o número de repetições
pode ser pequeno, dependendo do seu menor divisor. Por exemplo, para todo número par o
comando repetitivo não será executado, se for múltiplo de 3 o comando repetitivo será
executado apenas uma vez, se for múltiplo de 5 será repetido 3 vezes e assim por diante.
Observe que na última frase não foi mencionado o caso do número ser divisível por
4. Obvio! Se o número fosse divisível por 4, ele seria par e já teria sido identificado como
não primo quando dv era igual a 2. Uma possível melhoria no algoritmo do programa
poderia ser fazer primeiro o teste se o número é par (divisível por 2). Caso não seja, usar a
mesma lógica de caminhar por uma lista de possíveis divisores, contendo apenas valores
ímpares, iniciando com o divisor 3. Esta alteração, reduziria à metade o número de
repetições quando o número for primo. Outra simplificação seria a de não percorrer a lista
de divisores até se chegar no próprio número. Em princípio, a parada poderia acontecer
quando o divisor for igual à metade do número. Um dos exercícios deste capítulo é para
desenvolver uma solução mais eficiente do que a apresentada aqui.
Escreva um programa que leia um valor x qualquer pelo teclado e calcule o valor da
raiz quadrada de x. O programa deve garantir que o cálculo da raiz quadrada seja feito
126
Introdução à Programação com Python
apenas quando um valor não negativo seja fornecido. Quando for fornecido um valor
negativo, o programa deverá ser encerrado. O cálculo da raiz quadrada de x deve ser feito
de acordo com o método de Heron de Alexandria, descrito a seguir:
1. Chute um valor inicial para a raiz como sendo r (por exemplo, r = x/2).
2. Faça 𝑟 = (𝑟 + 𝑥/𝑟)/2.
3. Se |𝑟² − 𝑥| > ε, retorne ao passo 2.
4. Escreva r.
Obs.: o valor de ε corresponde à precisão desejada para o valor da raiz, por
exemplo, 10⁻⁵.
A Tabela 6.3 mostra os valores estimados pelo algoritmo e o valor do erro, para cada
iteração do comando repetitivo, para cálculos da raiz quadrada de 4, 3, 2 e 1. Todos os
valores estão mostrados com 6 casas decimais, já que a precisão utilizada foi de 10⁻⁵. Em
negrito, foi feito o destaque para o valor considerado como a resposta correta, dentro da
margem de erro para cada cálculo.
Observe que para calcular 4 a primeira estimativa (2) coincide exatamente com o
valor da raiz e o erro é zero. Para os cálculos de 3 e 2 foram necessárias 3 iterações do
algoritmo. Observe que o erro para 3 aparece como se fosse zero, mas isso é devido ao
uso de 6 casas decimais. Caso a impressão tivesse sido feita com 10 casas decimais, os
valores de estimativa para 3 e o erro, na terceira iteração seriam, respectivamente
1.7320508100 e 0.0000000085.
Tabela 6.3 - Estimativas e erro para cálculo de raiz quadrada com precisão 10⁻⁵.
Iteração 4 3 2 1
4 1.000000 0.000000
127
Introdução à Programação com Python
quadrada em bibliotecas matemáticas. No código foi utilizada a função abs(x) que, dado um
número x, informa o seu módulo. Implementar um código para realizar tal tarefa é trivial,
pois bastaria testar se o valor de x é negativo e, se for, multiplicar por -1. O código que
implementa o algoritmo discutido anteriormente é apresentado na Figura 6.11, juntamente
com a exibição do resultado da execução, na janela do Shell, para os valores de raiz
quadrada de 4, 3, 2 e 1.
128
Introdução à Programação com Python
Note, também, que a variável epson foi criada fora do comando repetitivo enquanto
que a variável r foi criada dentro da cláusula else, que está dentro de um comando
repetitivo. Como a precisão (epson) é fixa, ela pode (e deve) ser inicializada uma única vez.
Em outras linguagens de programação seria chamada de constante e não de variável. Já o
valor da variável r deve ser inicializada para cada novo cálculo de raiz a ser feito, com um
valor (x/2) que depende do valor informado pelo usuário.
6.4. Exercícios
1) Faça um programa que imprima a soma dos 100 primeiros números naturais.
3) Escreva um programa que exiba os números divisíveis por 4 e por 5 menores que
200.
5) Escreva um programa para ler o número de alunos existentes em uma turma, ler a
nota de cada aluno e calcular a média aritmética da turma.
6) Escreva um programa para escrever a soma dos números pares e a soma dos
números ímpares de 1 a 200, inclusive.
7) Escreva um programa que verifique a validade de uma senha fornecida pelo usuário.
A senha válida é 1234. Caso a senha informada pelo usuário seja inválida, a
mensagem "ACESSO NEGADO" deve ser impressa e repetida a solicitação de uma
nova senha até que ela seja válida. Caso contrário deve ser impressa a mensagem
"ACESSO PERMITIDO" junto com um número que representa quantas vezes a
senha foi informada.
129
Introdução à Programação com Python
𝑏
10) Faça um programa que receba dois números, inteiros e positivos a e b, e calcule 𝑎 ,
sem usar a função ou o operador **.
11) Escreva um programa para ler 2 notas de um aluno, calcular e imprimir a média final.
Logo após escrever a mensagem "Calcular a média de outro aluno [S]im [N]ao?" e
solicitar uma resposta. Se a resposta for “S” ou “s”, o programa deve ser executado
novamente, caso contrário deve ser encerrado imprimindo a quantidade de alunos
aprovados, reprovados e que ficaram em exame final, considerando o mesmo
critério adotado pela UFV, conforme tabela mostrada a seguir.
Nota Situação
0-39 Reprovado
60-100 Aprovado
OBS: as notas finais na UFV são sempre valores inteiros, com arredondamento para
cima se o valor decimal for maior ou igual a 0,5 e arredondamento para baixo, caso
contrário. Ex: 59.4 vira 59 e 59.5 vira 60.
12) A CBF contratou você para escrever um programa que faça uma estatística do
resultado de vários Fla-Flu. Você deve escrever um programa para ler o número de
gols marcados pelo Flamengo e o número de gols marcados pelo Fluminense em
um Fla-Flu. Logo após escrever a mensagem "Novo Fla-Flu 1.Sim 2.Nao?" e solicitar
uma resposta. Se a resposta for 1, o algoritmo deve ser executado novamente
solicitando o número de gols marcados pelos times em uma nova partida, caso
contrário deve ser encerrado imprimindo:
Quantos Fla-Flu fizeram parte da estatística.
O número de vitórias do Flamengo.
O número de vitórias do Fluminense.
O número de Empates
Uma mensagem indicando qual o time que venceu o maior número de Fla-Flu (ou
NÃO HOUVE VENCEDOR).
Veja os exemplos:
Numero de gols do Flamengo: 2
Numero de gols do Fluminense: 1
Novo Fla-Flu 1.Sim 2.Nao? 2
--Resultado Final--
130
Introdução à Programação com Python
--Resultado Final--
Numero de partidas do Fla-Flu: 3
Numero de vitorias do Flamengo: 1
Numero de vitorias do Fluminense: 1
Numero de empates: 1
Nao houve vencedor
Altere o programa para que ele execute diversas vezes, parando quando o usuário
informar um valor menor ou igual a zero para N.
15) Faça um programa para calcular o produto dos N primeiros elementos de uma série,
conforme mostrado a seguir:
𝑁
𝑖 1 2 3 4 5 𝑁
∏ 𝑖+1
= 2
× 3
× 4
× 5
× 6
×... × 𝑁+1
𝑖=1
O número de elementos do produtório deverá ser informado pelo usuário do
programa. Execute seu programa para diferentes valores de N e certifique-se de
que o produtório é convergente.
131
Introdução à Programação com Python
Altere o programa para que ele execute diversas vezes, parando quando o usuário
informar um valor menor ou igual a zero para N.
16) Uma série conhecida para o cálculo de π foi desenvolvida por Leibniz em 1682,
utilizando-se da série de Taylor para a função arctan(x), tomando-se x=1, e, por
conseguinte, arctan(1) = π/4 (Fonte: https://pt.wikipedia.org/wiki/Pi). Assim, pode-se
escrever que:
𝑁 𝑖
4×(−1) 4 4 4 4 4
π = ∑ 2×𝑖+1
= 4− 3
+ 5
− 7
+ 9
− 11
+...
𝑖=0
Altere o programa para que ele execute diversas vezes, parando quando o usuário
informar um valor menor ou igual a zero para N.
17) Uma outra série conhecida para o cálculo de π foi desenvolvida por Nilakantha e tal
proposição é mostrada a seguir:
∞ 𝑖+1
(−1) ×4 4 4 4 4
π=3 + ∑ (2𝑖)(2𝑖+1)(2𝑖+2)
= 3+ 2×3×4
− 4×5×6
+ 6×7×8
− 8×9×10
𝑖=1
Altere o programa para que ele execute diversas vezes, parando quando o usuário
informar um valor menor ou igual a zero para N.
18) O valor de π também pode ser obtido com o produtório. Uma destas soluções foi
proposta pelo matemático francês François Viète, que estudando o método de
Arquimedes, desenvolveu a seguinte série para o cálculo de em 1593 (Fonte:
https://pt.wikipedia.org/wiki/Pi):
2 2 2+ 2 2+ 2+ 2 2+ 2+ 2+ 2
π
= 2
× 2
× 2
× 2
×...
132
Introdução à Programação com Python
Altere o programa para que ele execute diversas vezes, parando quando o usuário
informar um valor menor ou igual a zero para N.
20) Modifique o programa da questão anterior para permitir que o usuário especifique a
precisão (limitada a 15 casas decimais) e a execução do programa seja feita de
maneira repetitiva, até que o usuário informe que o número de elementos é zero. O
programa deverá, ainda, verificar a diferença entre o valor calculado e o valor exato,
de cada método e informar qual deles teve a menor diferença, ou o melhor, em cada
passo. O valor de πcom 15 casas decimais é 3,141592653589793. O programa
deverá gerar uma saída como a mostrada a seguir:
133
Introdução à Programação com Python
134
Introdução à Programação com Python
Capítulo 7 - Arranjos
Até este ponto foram utilizadas apenas variáveis simples ou escalares. Elas são
muito úteis, mas não permitem realizar alguns tipos de cálculos. Suponha um programa
para ler uma sequência de notas de uma turma de N alunos e informar: a média das notas,
a maior nota, a menor nota, o desvio padrão das notas e o número de notas abaixo da
média. Suponha uma turma com apenas N=4 alunos com a seguinte lista de notas: 65, 92,
87 e 54.
soma = 0
for i in range (0, N):
nota = float(input(‘Nota: ‘))
soma = soma + nota
media = soma/N
print(‘A média das notas é: %.2f’ %media)
A identificação da maior (ou menor) nota poderia ser feita com a informação da faixa
de valores das notas, por exemplo, de [0, 100], utilizando a mesma estrutura do código
acima. A variável maior seria criada antes do comando repetitivo com um valor -1. Com este
valor inicial, qualquer nota lida na faixa [0, 100] será maior do que o valor inicial. Portanto,
dentro do comando repetitivo, basta comparar se a nota lida é maior do que a variável
maior. Se for, a variável maior seria atualizada para receber o valor da nota que acabou de
ser lida. O código poderia ser incrementado para determinar a maior nota, como mostrado a
seguir. Em negrito, os comandos para computar e informar a maior nota:
soma = 0
maior = -1
for i in range (0, N):
nota = float(input(‘Nota: ‘))
soma = soma + nota
if nota > maior:
maior = nota
media = soma/N
print(‘A média das notas é: %.2f’ %media)
print(‘A maior nota é: %.2f’ %maior)
Analogamente, para identificar a menor nota bastaria criar outra variável (por
exemplo menor) com valor inicial acima da faixa. E no comando repetitivo, para cada nota
lida que for menor do que o valor atual da variável menor, o valor da variável menor deverá
receber o valor da nota que acabou de ser lida. Com esta inclusão, o código ficaria como a
seguir. Em negrito, agora, os comandos para calcular e exibir a menor nota:
135
Introdução à Programação com Python
soma = 0
maior = -1
menor = 101
for i in range (0, N):
nota = float(input(‘Nota: ‘))
soma = soma + nota
if nota > maior:
maior = nota
if nota < menor:
menor = nota
media = soma/N
print(‘A média das notas é: %.2f’ %media)
print(‘A maior nota é: %.2f’ %maior)
print(‘A menor nota é: %.2f’ %menor)
𝑛
𝐷𝑒𝑠𝑣𝑖𝑜𝑃𝑎𝑑𝑟𝑎𝑜 = ∑ (𝑥𝑖 − µ)² / 𝑛
𝑖=1
Onde 𝑥𝑖 corresponde a cada uma das notas e µ é a média das notas lidas, que já foi
calculada. O cálculo do somatório poderia ser feito usando a estrutura já conhecida e usada
para o somatório das notas. Porém, cada incremento deste novo somatório seria definido
pela expressão (nota - media)**2. Porém, não é possível fazer este cálculo pois apenas o
valor da última nota lida está disponível na variável nota. Os demais N-1 valores de notas
foram sobrescritos (perdidos) a cada novo comando de leitura (input()). Só existe uma
posição de memória associado à variável nota, onde só “cabe” um único valor.
136
Introdução à Programação com Python
chamada lista, que é bem mais genérica, mas que será objeto de estudo na disciplina INF
101 - Introdução à Programação II. Pode-se dizer que um arranjo seria um tipo particular de
lista na qual todos os elementos são do mesmo tipo. Como um dos objetivos da disciplina
INF 100 - Introdução à Programação I é apresentar os conceitos fundamentais de
programação, habilitando o estudante a usar outras linguagens de programação, neste texto
os arranjos serão apresentados como definido em outras linguagens de programação como
C, C++, Java, etc.
137
Introdução à Programação com Python
usar o nome do arranjo (v) junto com o índice, de modo a definir o deslocamento (em
posições de memória) a partir da posição inicial, chegando ao elemento desejado. Uma
outra forma de visualizar uma arranjo é mostrado na Figura 7.2.
Para criar e manipular arranjos numéricos (vetores e matrizes) em Python, pode ser
usada a biblioteca numpy, pois ela proporciona uma maior facilidade para criar e inicializar
os arranjos, além de possuir características similares a outras linguagens de programação,
permitindo criar arranjos de tipos específicos. Para isso, é preciso importar a biblioteca
usando a diretiva de importação como mostrado a seguir:
import numpy
identificador = numpy.empty(N)
import numpy as np
notas = np.zeros(5) # cria o arranjo notas com 5 posições iguais a 0
alturas = np.zeros(10) # cria o arranjo alturas com 10 posições iguais a 0
138
Introdução à Programação com Python
elementos de outro tipo deve ser usado o parâmetro dtype=<tipo>, onde <tipo> especifica o
tipo dos elementos do arranjo que será criado. Por exemplo, a criação de um arranjo de
números inteiros, já inicializado com zeros poderia ser feita assim:
import numpy as np
idades = np.zeros( 10, dtype=int )
Mas porque o comando print() anterior que referenciou a posição -1 não deu erro de
acesso ou índice fora da faixa? A linguagem Python possui algumas características bem
peculiares. Uma delas é permitir o uso de índices negativos, dentro de uma faixa bem
específica, como no penúltimo comando do trecho de código acima. O comando print(v[-1])
imprime o valor contido na última posição ou a posição N-1 do arranjo. É como se o arranjo
também fosse indexado de trás para frente, com o valor -1 referenciando a posição N-1, o
valor -2 referenciando a posição N-2 e assim por diante, até chegar ao índice -N que
corresponde à posição N-N, ou posição 0. Ou seja, para um arranjo de 5 elementos, como o
do exemplo, são permitidos os índices 0 ou -5, 1 ou -4, 2 ou -3, 3 ou -2 e 4 ou -1, para
139
Introdução à Programação com Python
referenciar da primeira para a última posições do arranjo. Nos exemplos, serão utilizados
sempre os índices positivos.
i=0
while i < len( A ):
print( A[i] )
i=i+1
No entanto, o comando repetitivo for é bem mais apropriado para essas situações
pois a inicialização da variável de controle é feita no cabeçalho do comando e o seu
incremento é automático:
for i in range(len(A)):
print( A[i] )
import numpy as np
n = int( input('Número de elementos: '))
A = np.empty( n ) # Criação do arranjo
# Leitura do arranjo pelo teclado
for i in range(0, n):
A[i] = float( input('Informe o %d⁰ elemento: ' % (i+1)))
# Multiplicando o arranjo por 2
for i in range(0, n):
140
Introdução à Programação com Python
A[i] = A[i] * 2
# Escrita do arranjo na tela
for i in range(0, n):
print( A[i] )
Observe que para solicitar que o usuário forneça cada valor foi usado o índice i+1,
de modo que a mensagem apareça como ‘Informe o 1⁰ elemento: ’, quando o valor de i for
0, referente ao primeiro elemento do arranjo. O usuário do programa não é obrigado a
conhecer programação e para ele pode não fazer sentido falar em elemento da posição
zero.
No exemplo anterior, como os valores do arranjo não são utilizados para nenhuma
outra tarefa posterior, o mesmo resultado (o que o usuário enxerga na execução do
programa) poderia ser obtido com o seguinte código:
import numpy as np
n = int( input('Número de elementos: '))
A = np.empty( n ) # Criação do arranjo
# Leitura do arranjo pelo teclado
for i in range(0, n):
A[i] = float( input('Informe o %do elemento: ' % (i+1)))
# Escrita dos elementos do arranjo multiplicados por 2, na tela
for i in range(0, n):
print( 2*A[i] )
import numpy as np
n = int( input('Número de elementos: '))
A = np.zeros( n ) # Criação do arranjo, preenchido com 0.0
# Preenchimento do arranjo
for i in range(1, n):
A[i] = A[i-1] + 2
# Escrita do arranjo na tela, elementos separados por espaço
for i in range(0, n):
print( A[i], end=' ')
print()
# Escrita do arranjo na tela, elementos separados por tabulação
for i in range(0, n):
print( A[i], end='\t')
print()
# Escrita do arranjo na tela, elementos formatados
for i in range(0, n):
print('%7.3f' % A[i], end='')
141
Introdução à Programação com Python
A criação do arranjo, neste último exemplo, foi feita usando a função zeros da
biblioteca numpy. Inicialmente, então, todas as posições foram preenchidas com o valor 0
na criação do arranjo.
O primeiro comando for foi usado para gerar os elementos das posições 1 a N-1
usando o valor do elemento imediatamente anterior. Observe que a faixa definida para o for
começa em 1. Deve ficar claro que nem sempre será necessário percorrer todo o arranjo,
vai depender da tarefa que se deseja fazer. O elemento da posição i será igual ao elemento
da posição anterior (i-1) incrementado de 2 ou A[i] = A[i-1] + 2, para i de 1 até N-1 ou da
segunda posição do arranjo em diante. O elemento da posição 0 será o elemento base para
a geração de todos os outros. Como o valor da primeira posição é zero, a sequência gerada
será 0, 2, 4, 6,...,2*(N-1). Se o comando A[0] = 5 fosse inserido no código, antes do primeiro
comando for, alterando o elemento base de 0 para 5, a sequência gerada seria: 5, 7, 9,
11,...,2*(N-1)+5. A regra de geração continuou a mesma: cada elemento é igual ao elemento
anterior + 2.
142
Introdução à Programação com Python
para i de 0..N-1:
nota[i] = Leia(‘Nota: ‘) # guarda cada valor em uma posição do arranjo
soma = soma + nota[i]
se nota[i] > maior: # compara se a nota lida é a maior
maior = nota[i]
se nota[i] < menor: # compara se a nota lida é a menor
menor = nota[i]
# fim do comando repetitivo
media = soma/N # cálculo da média
soma = 0 # inicializa o segundo somatório
cnam = 0 # contador de notas abaixo da media
# comando repetitivo: computa somatório (nota[i] - media)² e total de notas < média
para i de 0.. N-1:
soma = soma + (nota[i] - media)**2
se nota[i] < media:
cnam = cnam + 1
# fim do comando repetitivo
dp = (soma / N)**0.5 # cálculo do desvio padrão
# exibição dos resultados
Escreva(‘A média das notas é ‘, %media)
Escreva(‘O desvio padrão das notas é: ‘, dp)
Escreva(‘A maior nota é: ‘, maior)
Escreva(‘A menor nota é: ‘, menor)
Na leitura das notas foi considerado que o valor poderia ser real e que seria
feita a validação, verificando se está na faixa de 0..100. Caso não esteja, o
programa informará que a nota é inválida e repetirá o comando de leitura. Embora
esta validação não tenha sido explicitamente pedida no enunciado, foi mencionado a
faixa para as notas. Além disso, faz parte das boas práticas de programação
prevenir possíveis erros nas informações que o programa irá processar. Já em uma
questão de prova, a abordagem deve ser a de se ater apenas ao que está sendo
pedido explicitamente no enunciado.
Comentários também são úteis para identificar a tarefa executada por certos
trechos do programa. Note que em um mesmo comando repetitivo for foram
executadas as tarefas de ler as notas, calcular o somatório das notas lidas,
identificar a maior e a menor notas lidas. Após o término deste primeiro comando for
é que a média das notas foi calculada.
143
Introdução à Programação com Python
Somente após o cálculo da média das notas é que seria possível calcular
corretamente, o desvio padrão e identificar o número de notas menores que a
média. Estas duas tarefas são feitas no segundo comando repetitivo for, pois
demandam percorrer novamente o arranjo.
144
Introdução à Programação com Python
Observe que no enunciado é apresentada uma determinada saída que deve ser
gerada pelo programa. Porém, a solução pode ser iniciada pelo algoritmo que tem uma
lógica relativamente simples, confome descrito a seguir:
O primeiro elemento deve ser sempre escrito (posição 0), sem nenhuma restrição. A
partir deste elemento, antes de imprimir o próximo elemento do arranjo, deve ser verificado
que relação ele tem com o seu antecessor: maior, menor ou igual. O índice i do comando
repetitivo indicará o próximo elemento a ser escrito o seu antecessor, consequentemente,
será apontado por i-1. Por isso, o comando repetitivo será executado para a faixa de 1..n-1.
O resultado da comparação indicará que símbolo o programa deve imprimir: >, < ou
igual, dependendo da relação entre os valores das posições i e i-1. A seguir, a versão
detalhada do algoritmo:
Escreva(‘msg inicial’)
n = Leia(‘Informe o número de elementos do arranjo: ')
v = arranjo(n)
Escreva('Entre com os valores (um em cada linha):')
para i na faixa (0,n):
v[i] = input(i, '⁰ elemento: ')
Escreva(‘'Relações: ', mesmalinha')
Escreva(v[0], mesmalinha)
para i na faixa (1,n):
se (v[i] > v[i-1]):
print(' < ', mesmalinha)
senãose (v[i] < v[i-1]):
print(' > ', mesmalinha)
senão:
print(' = ', mesmalinha)
imprima(v[i])
145
Introdução à Programação com Python
M
Índices 0 1 2 3
0 1 2.5 0 -4
1 0 1 -2 0.5
2 0 4 1 0.7
146
Introdução à Programação com Python
Cada elemento é identificado pelo nome do arranjo e por dois índices para
referenciar a linha e a coluna do elemento. Por exemplo, o elemento M[i][j] corresponde à
célula posicionada na linha i e na coluna j. Na Figura 7.6, o índice de linha i varia de 0..2 e o
índice de coluna varia de 0..4. Da mesma forma que a primeira posição de um arranjo
unidimensional é referenciada pelo índice 0, em um arranjo bidimensional a primeira linha e
a primeira coluna também são referenciadas pelo índice 0.
Desta forma a matriz vai sendo percorrida por linha. Em algumas situações pode
ser necessário percorrer a matriz por coluna. Para realizar a tarefa desta maneira, bastaria
inverter a ordem dos comando repetitivos, fixando no comando repetitivo externo o índice
da coluna e variando o índice de linha no comando repetitivo interno.
147
Introdução à Programação com Python
O primeiro arranjo seria apenas um arranjo de índices (0..m-1), com cada índice
apontando para um arranjo unidimensional, com os elementos de uma linha da matriz. De
fato, esta estrutura é utilizada na implementação de algumas linguagens de programação,
como Python, por exemplo. Ela é bastante flexível, permitindo a sua recorrência para definir
um arranjo n-dimensional ou para ter estruturas com arranjos de tamanho diferente (mas
isso é assunto para quem for cursar a disciplina INF 101 - Introdução à Programação II).
148
Introdução à Programação com Python
biblioteca numpy, como feito para arranjos unidimensionais, obviamente definindo as duas
dimensões (número de linhas e de colunas), como a seguir:
import numpy as np
A = np.empty( (3, 4) ) # cria o arranjo A com 3 linhas e 4 colunas
O arranjo criado acima, usando a função empty() da biblioteca numpy, não define
valores para os elementos de A. Caso tivesse sido utilizada a função zeros(), todos os
elementos teriam valor 0. Mas a biblioteca numpy também pode ser utilizada quando se
pretende definir valores iniciais para os elementos da matriz, como em:
import numpy as np
mi = np.array( [ [1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12] ] )
# imprime os elementos da matriz mi
for i in range(0, 4):
for j in range(0, 3):
print('%3d' % (mi[i][j]), end='')
print()
O trecho de código acima, além de definir os valores da matriz mi, faz também a
impressão dos elementos da matriz, usando a implementação do algoritmo de percorrer a
matriz por linha. Os elementos de cada linha são impressos pelo comando print() dentro do
comando for interno. Após a impressão de cada elemento, a diretiva ‘end=’ mantém o cursor
na mesma linha, de forma que todos os elementos da linha da matriz sejam impressos na
mesma linha na tela do computador. Na primeira iteração do comando for externo, com i=0,
a primeira linha da matriz foi impressa.
O comando print() dentro do comando for externo (última linha do código), faz pular
para a próxima linha. Após este print() o comando for externo termina uma iteração e
incrementará a variável de controle i. Para i = 1, 2 e 3 o comando for será executado
novamente, imprimindo os elementos das linhas 1, 2 e 3 ou segunda, terceira e quarta linha,
respectivamente. O resultado da impressão será:
1 2 3
4 5 6
7 8 9
10 11 12
Note que o parâmetro de formatação com 3 espaços foi suficiente para separar os
valores inteiros e dar a visão espacial de matriz, como nos livros de matemática, pois os
maiores valores numéricos ocupam 2 posições. Se o programador tivesse esquecido de
colocar o espaçamento, usando apenas '%d' invés de '%3d', a impressão sairia como
mostrada abaixo:
123
456
789
101112
149
Introdução à Programação com Python
O algoritmo acima ainda não está em uma forma que possa ser traduzido para a
linguagem Python. É necessário refinar as ações “Leia os elementos da matriz” e “Pesquise
x na matriz e informe a posição quando encontrar”. A primeira é mais simples e corresponde
à ação de solicitar ao usuário o valor de cada elemento da matriz. Isso pode ser
implementado com o algoritmo de percorrer a matriz por linha:
achou = False
para i na faixa (0, m):
para j na faixa de (0, n):
se A[i][j] == x
150
Introdução à Programação com Python
Imprima(i, j)
achou = True
Figura 7.8 - Programa para encontrar um valor e informar sua posição em uma matriz
A impressão da matriz não foi solicitada no enunciado, mas fica melhor para o
usuário verificar se o programa gerou o resultado correto. A Figura 7.9 apresenta o
resultado de uma execução do programa da Figura 7.8, onde o valor procurado aparece 1
vez.
151
Introdução à Programação com Python
A primeira observação a ser feita é que para uma matriz ser diagonal (e identidade)
a primeira condição necessária é que ela seja uma matriz quadrada, ou seja, o número de
linhas deve ser igual ao número de colunas. Somente as matrizes quadradas possuem uma
152
Introdução à Programação com Python
se m != n:
Escreva(‘A matriz não é quadrada’’)
senão:
“Verifique se a matriz é uma matriz diagonal”
Se “diagonal”
“Verifique se a matriz é uma matriz identidade”
Se “identidade”
Escreva(‘matriz é identidade’)
Senão
Escreva(‘matriz é diagonal’)
Senão:
Escreva(‘matriz não é diagonal’)
Note que a ação “Verifique se a matriz é uma matriz diagonal” foi deslocada e
associada ao teste de uma condição, pois a verificação só precisa ser processada quando
m (número de linhas) for igual a n (número de colunas) - resultado falso do teste m != n. Se
o teste for verdadeiro, o algoritmo termina escrevendo que a matriz não é diagonal.
O algoritmo para percorrer toda a matriz pode ser usado e aplicando o teste apenas
para os elementos que estão fora da diagonal principal. Antes de iniciar o percorrimento da
matriz, pode-se supor que ela é diagonal. Se algum elemento fora da diagonal principal for
diferente de zero, ela não será diagonal. Em termos de algoritmo, isto pode ser escrito
como:
diagonal = True
153
Introdução à Programação com Python
identidade = True
para i de (0, m):
para j de (0, n):
se i == j E A[i][j] != 1
identidade = False
A versão completa do algoritmo refinado, juntando os refinamentos discutidos, é
mostrada a seguir:
154
Introdução à Programação com Python
Escreva(‘matriz é diagonal’)
Senão:
Escreva(‘matriz não é diagonal’)
155
Introdução à Programação com Python
156
Introdução à Programação com Python
trabalhar com o comando repetitivo while. Veja como ficaria o código para a identificação da
propriedade da matriz ser diagonal:
Se “diagonal”
# verifica se é identidade. Todos elementos da diagonal devem ser iguais a 1
identidade = True
# percorre a diagonal principal (i = j) e para quando achar algum elemento
# diferente de 1
i=0
while identidade and i < m :
se A[i][i] != 1:
identidade = False
i=i+1
Se “identidade”:
Escreva(‘matriz é identidade’)
Senão:
Escreva(‘matriz é diagonal’)
157
Introdução à Programação com Python
A Figura 7.11 mostra uma imagem de satélite em preto e branco (ou em tons de
cinza), com a ampliação de um pequeno trecho quadrado de 5x5 pixels. Um pixel é um
ponto da imagem, conforme mostrado no detalhe e pode ser visualizado como o
cruzamento de uma linha com uma coluna da imagem. Ou seja, uma imagem é uma matriz
de pontos.
No caso de uma figura monocromática (em tons de cinza) como a da Figura 7.11, a
cor é codificada em um byte (8 bits) e pode assumir 256 (2⁸) valores diferentes, codificando
tons de cinza variando de 0 (preto) a 255 (branco). Os valores mais baixos representam
tons de cinza mais claros e os valores mais altos codificam os valores mais escuros. Assim,
a matriz de pontos destacada na imagem é codificada como uma matriz 5x5 de números
inteiros, como a que aparece também em destaque na Figura 7.11.
Portanto, uma imagem será representada como uma matriz com o número de linhas
igual ao número de linhas da imagem e o número de colunas igual ao número de colunas
da imagem. No caso de uma imagem em tons de cinza, cada elemento da matriz será um
número inteiro no intervalo de 0 a 255. Um algoritmo para escurecer uma foto
monocromática teria que percorrer a matriz e somar um valor constante, tomando o cuidado
de atribuir 255 (valor máximo permitido), toda vez que a soma der valor maior que 255.
158
Introdução à Programação com Python
Além do padrão RGB, outro padrão utilizado é o CYMK (Cian (ciano), Magenta
(magenta), Yellow (amarelo) e blacK (preto)). Porém, este padrão não será tratado aqui. É
importante lembrar que no caso de usar os códigos feitos para o padrão RGB, com uma
figura codificada como CYMK a execução irá gerar um erro na abertura do arquivo..
r, g, b = imagem[i][j]
Para atribuir um valor de cor para um pixel na imagem (ou um elemento da matriz
imagem), o comando de atribuição deve ser feito no sentido inverso, atribuindo uma tripla
de valores inteiros para um pixel de uma das posições da matriz. No exemplo abaixo, um
ponto azul está sendo atribuído para um pixel.
159
Introdução à Programação com Python
Os valores precisam estar entre parênteses e separados por vírgula e o efeito deste
comando será atribuir zero para os componentes vermelho e verde e o valor máximo (255)
para o componente azul. Desta forma, o comando atribui uma cor azul para o ponto no
canto superior esquerdo de uma imagem (primeira linha, primeira coluna). Mas, a alteração
de apenas um ponto na imagem não causa um efeito perceptível para o usuário.
160
Introdução à Programação com Python
Como pode ser observado na cor da pele, a imagem original possui um tom mais
avermelhado, enquanto que a imagem após o processamento ficou mais amarelada. A cor
de fundo também teve uma alteração substancial pelo processamento feito.
161
Introdução à Programação com Python
Figura 7.14 - Resultado da Execução do programa da Figura 7.13 (Fonte: foto do acervo
pessoal de Paula Cerqueira Goulart)
Uma observação final, apenas para ilustrar, mais uma vez, a importância da
indentação do código Python. Suponha que o programador tivesse alinhado o último
comando com o penúltimo - aliás, este é um erro que acontece muito frequentemente nas
aulas práticas. O efeito desse erro seria exibir a imagem a cada pixel alterado. Isso
provocaria uma demora muito grande para o programa terminar, além de poder utilizar toda
a memória do computador, causando uma pane geral.
7.3. Exercícios
1) Faça um programa que leia um arranjo (ou vetor) de 10 elementos e troque todos os
números negativos por 0, em seguida imprima o vetor modificado.
162
Introdução à Programação com Python
6) Refaça o exercício 2 sem usar um vetor auxiliar (vetor Y). A inversão dos elementos
do vetor X deverá ser feita utilizando uma variável escalar.
10) Faça um programa que leia um vetor e ordene, de modo crescente, o vetor.
163
Introdução à Programação com Python
11) Faça um programa gerar um vetor X de 10 elementos com valores aleatórios entre
10 e 90. Na sequência, o programa deverá exibir os valores do vetor, em uma
mesma linha e solicitar que o usuário forneça um valor P (aceitando apenas valores
entre 0 e 9) que representa a posição de um elemento dentro do vetor X. Imprimir o
valor do elemento que ocupa a posição informada. Logo após excluir esse elemento
do vetor, fazendo com que os elementos subsequentes (se houver) sejam
deslocados uma posição para o início e o valor 0 (zero) seja inserido na última
posição do arranjo contendo elemento válido. O programa deverá exibir o arranjo,
após cada eliminação e ser executado até que todos os elementos sejam
eliminados, imprimindo ao final o arranjo contendo apenas valores 0 (zero). A cada
eliminação, a faixa permitida para o valor P deverá ser compatível com as posições
ocupadas por elementos válidos (diferentes de 0).
12) Criptografia (Do Grego kryptós, "escondido", e gráphein, "escrita") é o estudo dos
princípios e técnicas pelas quais a informação pode ser transformada da sua forma
original para outra ilegível, de forma que possa ser conhecida apenas por seu
destinatário, o que a torna difícil de ser lida por alguém não autorizado
(http://pt.wikipedia.org/wiki/Criptografia).
Uma das mais simples e conhecidas técnicas de criptografia é a Cifra de
César. É um tipo de cifra de substituição na qual cada letra do texto é substituída por
outra. Por exemplo, com uma troca de três posições, A seria substituído por D, B se
tornaria E, e assim por diante. O mesmo se pode aplicar a números, por exemplo,
com uma troca de cinco posições, 0 seria 5, 1 seria 6 e assim por diante. A
criptografia também pode ser representada usando aritmética modular. A criptografia
de um número por uma troca posições pode ser descrita matematicamente como:
En(x) = (x + n)%Y
onde, Y é o maior valor dos números que se deseja aplicar a Cifra de César e n é o
valor da distância. O resultado deve estar entre 0 e Y, ou seja, se x+n ou x–n não
estiverem no intervalo 0...Y, deve-se subtrair ou adicionar Y. Obviamente, após a
decriptografia, a informação deve ser igual à original.
164
Introdução à Programação com Python
14) Implemente um algoritmo de criptografia para uma string (lembre-se que uma string
é um arranjo de caracteres) fornecida pelo usuário, usando o algoritmo do exercício
12 com as devidas adaptações. Para obter o valor decimal correspondente a um
caracter deve ser usada a função ord() e para transformar um valor decimal para
caractere deve ser usada a função chr(). Ambas são funções primitivas da
linguagem Python e não é necessário importar nenhuma biblioteca para usá-las.
Considere o maior valor (Y definido no enunciado do exercício 12) igual a 256,
considerando que os caracteres ASCII variam de 0 a 255. A figura a seguir mostra
um exemplo execução do programa para a distância (número de troca) igual a 3.
OBS: Teste o programa para as entradas da figura acima, pois dependendo do texto
digitado ou da distância (número de troca) coisas estranhas podem acontecer por
causa dos caracteres de controle do ASCII, tais como os já conhecidos “\n” e “\t” ou
como o “/0” que indica fim de uma string.
15) O algoritmo de criptografia do exercício anterior também tem o ponto fraco de gerar
o mesmo caractere cifrado para um dado caractere original. Verifique que a letra “e”
foi sempre cifrada como “h”. Use a mesma ideia do exercício 13 para fazer um
incremento modular do valor n. Implemente esta alteração no programa do exercício
anterior. A Figura abaixo apresenta uma saída onde o valor inicial de n foi 4 (primeiro
valor fornecido pelo usuário) e a cada novo elemento a ser cifrado o valor de n foi
incrementado (modularmente) de 3 unidades. Observe, que nesta implementação, o
valor “e” foi criptografado como “k”, “t”, “}” e “¹”.
165
Introdução à Programação com Python
16) Faça um programa que leia o número de alunos de uma turma, em seguida leia a
matrícula e a nota de cada aluno. Após, calcule a média aritmética da turma e
imprima matrícula e a nota dos alunos reprovados, de exame final e aprovados.
17) Implemente o programa discutido na seção 7.1.2 permitindo que o usuário defina o
valor de N. O programa deverá executar e, ao final, solicitar novamente um valor de
N para nova execução. Se o usuário fornecer um valor 0 ou negativo, o programa
deve terminar. Observe que dependendo da quantidade de números gerados na
sequência, a forma de exibição da saída na tela pode ajudar (ou atrapalhar) a sua
visualização por parte do usuário do programa. Tente encontrar uma solução
genérica para se ter sempre uma boa visualização da saída.
18) Escreva um programa para criar uma matriz A de dimensões m x n, definidas pelo
usuário, que também deverá informar os valores dos elementos da matriz. Em
seguida, o programa deverá:
- Calcular a média dos valores da matriz;
- Calcular o desvio padrão dos valores da matriz;
- Gerar um arranjo B de dimensão m, contendo na posição i o produto dos
elementos da linha i da matriz A;
- Gerar um arranjo C de dimensão n, contendo na posição j a soma dos
elementos da coluna j da matriz A.
O programa deverá imprimir a matriz no formato de linhas e colunas, ou seja, em
uma mesma linha na tela deverão estar todos e somente os elementos daquela linha
da matriz. Vide exemplo a seguir.
19) Refaça o exercício anterior com a geração dos elementos da matriz A usando
números inteiros e aleatórios na faixa de -10 a + 10.
166
Introdução à Programação com Python
se a soma é possível antes de pedir o valor dos elementos ao usuário. Caso a soma
não seja possível, o programa deverá solicitar novamente ao usuário as informações
das dimensões das 2 matrizes. Ao final, o programa deverá imprimir as matrizes A,
B e C.
22) Altere a solução do exercício anterior com a geração dos elementos das matrizes A
e B usando números reais e aleatórios, na faixa entre 0 e 100.
24) Refaça o exercício anterior com a geração dos elementos das matrizes A e B
usando números reais e aleatórios, na faixa entre 0 e 100.
25) Modifique o exercício anterior com a geração dos elementos das matrizes A e B
usando números inteiros e aleatórios, na faixa entre 0 e 1.
26) Faça um programa para gerar uma matriz de dimensões n x m, com valores
aleatórios na faixa entre 0 e 255. Os valores m e n deverão ser informados pelo
usuário. Após a geração dos elementos da matriz, o usuário deverá selecionar uma
região indicando um número de linha e um número de coluna válidos. O programa
deverá, então, calcular o valor médio dos elementos pertencentes à região
selecionada pelo usuário e atribuir este valor médio para todos os elementos da
região. Os demais elementos devem permanecer inalterados. O programa deve
mostrar a matriz original e a matriz após a alteração dos valores da região.
27) Jogo da Velha - Use uma matriz 3x3 para para implementar um tabuleiro de jogo da
velha. Inicialmente, todas as posições devem ser preenchidas com o valor 0 (zero),
indicando que a posição está vazia. O jogo será jogado por dois jogadores. A
marcação de uma jogada do jogador 1 será feita atribuindo o valor 1 para a posição
definida. Para o jogador 2, uma jogada será feita atribuindo o valor 2. O programa
deverá exibir inicialmente o tabuleiro vazio na tela e implementar a solução para este
problema considerando:
- o jogador 1 será o primeiro a preencher uma posição;
- os jogadores 1 e 2 vão alternar o preenchimento das posições;
- os números de linha e coluna válidos são de 1 a 3, portanto o programa não
deve aceitar valores fora desta faixa;
- uma posição já preenchida não pode ser usada novamente, por nenhum dos
dois jogadores. Caso um jogador cometa este erro, o programa deverá
solicitar uma nova posição (ou jogada) para o mesmo jogador;
167
Introdução à Programação com Python
28) Modifique o programa implementado do Jogo da Velha para que o jogador 2 seja o
seu programa. A jogada do programa deverá ser feita escolhendo aleatoriamente
uma posição. Caso a posição esteja ocupada, o programa deverá escolher outra e
repetir o teste de posição ocupada (ou não). A marcação só será efetivada quando a
escolha aleatória for de uma posição válida.
29) Altere a implementação do exercício anterior para que a marcação feita pelo
programa não seja mais aleatória. Ela deverá seguir a seguinte estratégia:
- a primeira marcação do programa deverá ser a posição central (2, 2) ou, se
isso não for possível, a posição deverá ser a do canto superior esquerdo (1,
1);
- a segunda marcação deverá ser feita considerando o sucesso do programa
em ocupar a posição central, na primeira marcação. Em caso positivo, o
programa deverá verificar se o jogador 1 tem duas marcações em uma
mesma linha ou em uma mesma coluna, com a terceira posição vazia e, em
caso afirmativo, o programa deverá marcar esta posição vazia. Caso a
primeira marcação do programa não tenha sido a posição central, a diagonal
secundária também deverá ser verificada e a posição vazia deverá ser
marcada, se as outras duas posições já foram preenchidas pelo jogador 1.
Caso não exista possibilidade do jogador 1 ganhar com o terceiro
movimento, o programa deverá marcar uma posição em uma das
extremidades livres;
- da terceira marcação em diante, o programa deverá verificar se existe
alguma marcação que o faça vencedor e, neste caso, escolher esta
marcação. Caso contrário, deverá verificar se existe alguma opção de
marcação para (tentar) impedir a vitória do jogador 1 e fazer esta marcação.
31) Campo Minado é um popular jogo de computador para um jogador. Foi inventado
por Phil Spencer em 1989 e tem como objectivo revelar um campo de minas sem
que alguma seja detonada (Fonte: https://pt.wikipedia.org/wiki/Campo_minado).
Implemente um programa do jogo Campo Minado considerando um tabuleiro 10x10
e 10 bombas espalhadas aleatoriamente no tabuleiro, pelo programa. Na exibição do
tabuleiro para o usuário do programa devem ser usados os caracteres “X” para
posição ainda não revelada, “-” para posição revelada e não vizinha a nenhuma
bomba, “B” para posição revelada e com bomba (situação em que o jogador perde)
168
Introdução à Programação com Python
e de “1” a “8” para uma posição revelada e que seja vizinha de pelo menos uma
bomba (o caracter deve representar o número de bombas vizinhas àquela posição).
Portanto, o tabuleiro deve ser exibido inicialmente com todas as posições contendo
“X”. Quando o jogador selecionar uma posição, o caractere verdadeiro (“-”, “B” ou o
caractere representando o número de bombas vizinhas) deverá ser exibido. O
programa deverá controlar o número de posiçẽs reveladas. Quando uma posição
selecionada não for vizinha de bombas, o programa deverá exibi-la e todas as
posições adjacentes a ela que também não forem vizinhas de bombas.
32) Implemente um programa para transformar uma foto colorida em uma foto em tons
de cinza. Um algoritmo para fazer tal conversão pode ser a de pegar a intensidade
média de cada pixel RGB e atribuir este valor médio para cada componente RGB. A
figura mostrada a seguir apresenta a foto original à esquerda e a imagem
manipulada, à direita. A foto utilizada neste e em outros exercícios a seguir é do
fotógrafo Christian R. Linder, licenciada pela CC BY-SA 3.0, disponível em
https://pt.wikipedia.org/wiki/Agalychnis_callidryas#/media/Ficheiro:Agalychnis_callidr
yas.jpg. Todos os exercícios seguintes utilizam a mesma foto. Mas, você pode
utilizar qualquer outro arquivo de imagem nos formatos jpg ou png.
169
Introdução à Programação com Python
34) Uma matriz transposta de uma matriz A, é aquela em que as linhas de A viram
colunas na matriz transposta. Se a matriz A tiver dimensões m x n, a matriz
transposta de A terá dimensões n x m. Implemente um programa para pegar um
arquivo de imagem (matriz de pixels) e gerar a matriz transposta (ou imagem
transposta). O resultado, se aplicado na foto da nossa foto de perereca, será como o
mostrado a seguir, com a transposta mostrada no lado direio da figura. OBS: a foto
utilizada é quase quadrada. Possui 480x482 pixels.
35) Faça um programa para inverter horizontalmente uma foto, ou seja, o programa
deve trocar os elementos de primeira coluna com os elementos da última coluna,
trocar os elementos da segunda coluna com os da penúltima e, assim,
sucessivamente, até chegar no meio da foto, quando a inversão estará finalizada. O
resultado da execução deverá ser como o mostrado na figura a seguir.
170
Introdução à Programação com Python
36) Faça um programa para inverter verticalmente uma foto, ou seja, o programa deve
trocar os elementos de primeira linha com os elementos da última linha, trocar os
elementos da segunda linha com os da penúltima e, assim, sucessivamente, até
chegar no meio da foto, quando a inversão estará finalizada. O resultado da
execução deverá ser como o mostrado na figura a seguir.
171
Introdução à Programação com Python
38) Para aumentar a segurança da perereca a sua imagem será toda criptografada para
ser transmitida pela Internet, sendo descriptografada na máquina de destino. O
método de criptografia será o de substituição de César. Cada linha da imagem
original será copiada para uma nova imagem usando um valor de chave definida
pelo usuário, com valor entre 0 e 100. Porém, se a mesma chave for utilizada em
todas as linhas não haverá segurança, pois o resultado seria como o mostrado a
seguir:
Para conseguir uma criptografia mais forte uma pequena alteração pode ser feita,
incrementando modularmente o valor da chave de criptografia a cada linha nova a
ser criptografada. O módulo deve ser o número de colunas da matriz ou o número
de pixels em uma linha. O programa deverá gerar uma terceira imagem, a partir da
imagem criptografada que seja igual à imagem original (lembre-se que no destino só
existirá a imagem criptografada. A chave usada na criptografia será informada por
telefone). As imagens a seguir mostram a imagem criptografada (à esquerda) para
uma chave informada pelo usuário igual a 100 e valor do incremento igual à metade
do valor da chave.
172
Introdução à Programação com Python
39) Redução de Olho vermelho é uma técnica comum desde o surgimento das primeiras
máquinas de fotos digitais, que consiste na identificação de pixels na cor vermelha e
que estejam na área dos olhos e a troca por outra cor, dependendo da cor dos olhos.
Sabendo disso, a rã de olhos vermelhos (Agalychnis callidryas) solicitou a sua ajuda
para ter olhos azuis. Faça um programa para implementar uma solução similar à
mostrada a seguir, onde a foto original está à esquerda e a foto modificada à direita.
40) Altere o programa anterior para que possa ser escolhida uma opção entre olho azul
ou olho verde, bem como diferentes tons (intensidades) de uma destas duas cores.
A figura abaixo mostra o resultado da execução para azul com intensidade 150 e
para verde intensidade 255. Dica: não permita a seleção de intensidades abaixo de
80, pois tanto o azul como o verde começam a ficar muito escuros.
173
Introdução à Programação com Python
174
Introdução à Programação com Python
Capítulo 8 - Funções
Neste capítulo será mostrada a importância do uso de funções e a possibilidade de
criação de novas funções por parte do programador. O uso de funções permite uma melhor
organização do código e reutilização de código, com a criação de bibliotecas próprias.
8.1. Motivação
Na seção 6.3.3 foi discutida a solução para o problema de determinar o valor da raiz
quadrada de um número, utilizando o algoritmo proposto por Heron de Alexandria. Na
solução apresentada o trecho de código que executa o cálculo da raiz quadrada era:
epson = 10e-5
r = x/2
r = (r + x/r)/2
while abs(r**2 - x) > epson:
r = (r + x/r)/2
As cinco linhas de código acima podem ser substituídas por um único comando, se
for utilizada a função sqrt() da biblioteca matemática (math). Esta função calcula a raiz
quadrada de um número x passado como parâmetro e retorna o valor calculado. Assim,
uma maneira correta de usar a função sqrt() é em um comando de atribuição, como
mostrado a seguir:
r = math.sqrt( x )
175
Introdução à Programação com Python
Antes de criar uma nova função, é importante que o programador tenha em mente a
resposta para 3 questões fundamentais. Qual a tarefa que será executada pela função? Se
forem necessários parâmetros (dados de entrada), quais são esses parâmetros?
Finalmente, se a função retornar valores, quais são esses valores?
176
Introdução à Programação com Python
Considere um trecho de código para determinar o dia do mês em que foi ou será o
domingo de páscoa, para um período, por exemplo de 1980 a 1991. O algoritmo só funciona
para o intervalo de 1582 a 2499. O trecho de código implementado para obter o perído çe
mostrado a seguir:
print()
177
Introdução à Programação com Python
def leiaInt(msg):
v = int( input( msg ))
while v < 1582 or v > 2499:
print('Valor deve estar entre 1582 e 2499’)
v = int( input( msg ))
return v
#programa principal
ano1 = leiaInt('Digite o ano inicial (1582 a 2499): ')
print()
Um outro programa feito para ler as notas de uma turma de alunos, também precisa
de executar a tarefa de ler um valor inteiro e testar se o valor se encontra em uma
determinada faixa. Inicialmente, o programa lê a quantidade de alunos e só aceita valores
entre 2 e 50. Depois, o programa lê as notas de cada um do alunos, em um comando
repetitivo, e estas notas devem estar no intervalo de 0 a 100. Finalmente, a média das notas
é calculada, após o comando repetitivo. O programa está mostrado a seguir:
while True:
n = int( input('Entre com a quantidade de alunos: '))
if n < 2 or n > 50:
print('Valor deve estar entre 2 e 50')
else:
break
soma = 0
for i in range(0, n):
while True:
x = int( input('Entre com a nota do próximo aluno: '))
if x < 0 or x > 100:
178
Introdução à Programação com Python
Note que não é possível utilizar a função leiaInt() definida anteriormente porque ela é
específica para testar se o valor está no intervalo 1582 a 2499. Neste último programa é
necessário testar 2 intervalos diferentes. Mas é possível modificar a função leiaInt() para
que ela fique mais genérica, definindo novos parâmetros definindo o valor mínimo e o valor
máximo da faixa de interesse. A segunda versão da função e a sua utilização no segundo
programa são mostrados a seguir:
#programa principal
n = leiaInt('Entre com a quantidade de alunos: ', 2, 50)
soma = 0
for i in range(0, n):
x = leiaInt('Entre com a nota do próximo aluno: ', 0, 100)
soma = soma + x
media = soma / n
print('Média das notas:', media )
print()
ano2 = leiaInt( ‘Digite o ano final (1582 a 2499) : ', 1582, 2499)
179
Introdução à Programação com Python
A documentação de uma função costuma ter estas informações escritas logo após o
cabeçalho e antes do corpo da função. Para esta função, um conjunto de comentários
possíveis seria como o mostrado a seguir, na próxima versão de implementação da função.
O return funcionará de maneira similar ao break para quebrar o loop infinito. Porém,
além de forçar o término do comando repetitivo ele também termina a função. Se fosse
mantido o break na cláusula else, o comando return x deveria ser escrito após o while.
180
Introdução à Programação com Python
Às vezes uma função precisa retornar dois ou mais valores. A linguagem Python
resolve este problema de maneira muito simples, bastando informar a lista de valores,
separados por vírgula, em um comando return. O comando de atribuição deverá usar um
número de variáveis à esquerda do operador de atribuição, separadas por vírgula, igual ao
número de valores retornados pela função. A primeira variável receberá o primeiro valor da
lista de valores retornados, a segunda variável receberá o segundo valor, e assim por
diante.
Suponha uma função para ordenar 2 valores. A função precisa receber como
parâmetros os dois valores a ser ordenados, proceder à ordenação e retornar os valores
ordenados. A função ordena(x, y) e seu uso são ilustrados a seguir:
def ordena( x, y ):
if (x <= y):
return x, y
else:
return y, x
# programa principal
a = float( input('Digite um número: '))
b = float( input('Digite outro número: '))
a, b = ordena( a, b ) # chamada da função ordena
print( a, '<=', b )
E quando o número de valores que a função precisa retornar for muito grande, por
exemplo, um arranjo. Este caso será tratado na seção 8.4.
def f( x, y ):
k = 2*x + y
return k
181
Introdução à Programação com Python
# programa principal
z=2
w=1
print( f( 2*z, w ))
As variáveis locais são internas a cada função bem como os seus parâmetros. Eles
só podem ser usados dentro da função. Os parâmetros passados por valor são
independentes das variáveis, expressões etc. que geraram os valores passados para a
função. Considere este segundo exemplo:
def f( x, y ):
z = 2*x + y
return z
# programa principal
z=2
w=1
print( z )
print( f( 2*z, w ))
print( z )
Neste segundo exemplo existe uma variável z definida no programa principal e uma
variável local de mesmo nome z na função f(). A função f() é a mesma do primeiro exemplo
e, como ela recebeu os mesmos valores, ela retornará novamente o valor 9 (segundo valor
impresso). Quando isso acontece, toda referência ao nome z dentro do código da função f()
diz respeito à sua variável local z. Portanto, o comando de atribuição não altera a variável z
do programa principal. A saída gerada pelo programa será:
2
9
2
182
Introdução à Programação com Python
Neste próximo exemplo, uma variável do programa principal (z) é utilizada em uma
expressão da função f(). O programa imprimirá o valor 11, já que se trata da mesma
expressão acrescida de “ + z” e o valor de z é igual a 2.
def f( x, y ):
k = 2*x + y + z
return k
# programa principal
z=2
w=1
print( f( 2*z, w ))
Embora este uso seja permitido, ele não é recomendado. A ideia é que as variáveis
definidas no programa principal sejam utilizadas apenas no programa principal, criando um
escopo local para o programa principal.
Além disso, pode ocorrer uma ambiguidade se um comando de atribuição for feito
para uma variável global dentro da função como mostrado a seguir:
def f( x, y ):
k = 2*x + y + z
z=1
return k
# programa principal
z=2
w=1
print( f( 2*z, w ))
Este código ao ser analisado pelo interpretador Python gerará uma mensagem de
erro, pois será considerado pelo interpretador que a variável z usada na expressão k = 2*x +
y + z é a variável local definida no comando seguinte (z = 1). O interpretador Python está
entendendo que os dois comandos citados anteriormente estão em ordem trocada, que a
variável local z deveria ter sido definida antes de ser usada.
Uma solução para este problema seria dizer explicitamente que a variável z, usada
na função f() usando o comando global, antes de atribuir valor para z:
Mas, ao usar esta solução uma atribuição feita para a variável global na função será
refletida na variável global do programa principal. Por exemplo, se houvesse um comando
para imprimir o valor de z no programa principal, após a chamada da funçao f(), o valor
exibido seria 1.
183
Introdução à Programação com Python
Em vez disso, ele só passa o endereço da memória onde esse arranjo está
armazenado. Assim, qualquer alteração feita ao arranjo altera a própria variável passada
como parâmetro, e não uma cópia dessa variável. Considere o pequeno programa mostrado
a seguir:
#programa principal
a = numpy.array([4, 3, 2, 1])
print( a )
dobra( a )
print( a )
[4 3 2 1]
[8 6 4 2]
Sim. A linguagem Python permite imprimir um arranjo inteiro usando apenas seu
nome. A primeira linha é o resultado do primeiro comando print() que foi usado antes da
função dobra() ter sido chamada. E a segunda linha foi gerada pelo segundo print() e, como
era de se esperar, cada elemento do arranjo teve o seu valor dobrado pela função dobra().
184
Introdução à Programação com Python
funções. O ponto chave é um projeto com a definição precisa dos requisitos de cada função:
a tarefa que ela deve implementar; os parâmetros que devem ser passados para a função;
e os valores que a função deve retornar.
O programa principal pode ser visto como um algoritmo de alto nível, onde cada
comando seria uma chamada para a função que detalhará a execução daquele passo. Para
ilustrar, será utilizado um exemplo já apresentado na seção 7.2.2 no programa que verifica
as propriedades de uma matriz quadrada.
O algoritmo de alto nível que considerava o caso da matriz não ser quadrada era o
seguinte:
185
Introdução à Programação com Python
Observe que o programa principal utiliza a função leiaInt() que já foi apresentada
neste capítulo (reuso de código). Além dela, precisam ser definidas as seguintes funções:
Nome: leMatriz.
Tarefa: ler os elementos da matriz, solicitando valores ao usuário.
Parâmetros: Matriz (arranjo), número de linhas e número de colunas do arranjo.
Valor retornado: nenhum.
Nome: ehDiagonal.
Tarefa: verificar se a matriz é diagonal (todos os elementos fora da diagonal principal
devem ser iguais a zero).
Parâmetros: Matriz (arranjo), dimensão da matriz*
Valor retornado: Booleano (True se a matriz for diagonal).
(*) só faz sentido testar se a matriz é diagonal quando ela é quadrada (o número de
linhas é igual ao número de colunas). Dimensão é o número de linhas (ou de colunas) da
matriz quadrada.
Nome: ehIdentidade.
Tarefa: verificar se a matriz é identidade (todos os elementos da diagonal principal
são iguais a 1).
Parâmetros: Matriz (arranjo), dimensão do arranjo**.
Valor retornado: Booleano (True se a matriz for identidade).
(**) também só faz sentido testar se a matriz é identidade quando ela é quadrada.
Dimensão é o número de linhas (ou de colunas) da matriz quadrada.
Nome: imprimeMatriz.
Tarefa: imprimir os elementos da matriz, organizados por linha e coluna.
Parâmetros: Matriz (arranjo)***.
Valor retornado: nenhum.
186
Introdução à Programação com Python
(***) nesta função foi definido apenas 1 parâmetro, apenas para mostrar a função
shape da biblioteca numpy, que retorna 2 valores: o número de linhas e o número de
colunas de um arranjo bidimensional.
A implementação das cinco funções usadas pelo programa principal são mostradas
na Figura 8.2.
187
Introdução à Programação com Python
X O X X X O
O X O O X X
X X O O
Figura 8.3 - Representação esquemática de um tabuleiro de Jogo da Velha
188
Introdução à Programação com Python
Obviamente, que nem sempre se consegue esse mapeamento sai na primeira tentativa,
principalmente com relação a quantos e quais parâmetros serão necessários em cada uma
das funções. A Figura 8.4 mostra o código Python do programa principal da implementação
do Jogo da Velha.
Resta agora detalhar a implementação de cada uma das funções usadas pelo
programa principal e codificadas no arquivo auxiliar.py. Pode ser observado que algumas
funções são bem simples e que, em uma primeira análise, talvez nem demandassem uma
implementação como função. Porém, será detalhado como é possível modificar a
implementação de uma função para tornar o programa mais genérico e funcional, sem a
necessidade de mexer no código do programa principal, desde que o nome da função, o
número e ordem dos parâmetros não sejam alterados.
189
Introdução à Programação com Python
numpy. Ao contrário da função empty que não define nenhum valor para um arranjo, a
função full define todos os valores iguais ao valor passado como parâmetro (caractere ‘-’).
Ela retorna o arranjo criado. E, por se tratar de um arranjo, o valor retornado é o endereço
do arranjo criado dentro da função, que continua existindo após a função terminar.
A função imprimeTabuleiro(A) nada mais é do que a função que já foi vista aqui para
imprimir os elementos de um arranjo bidimensional no formato visto nos livros de
matemática. Note que como o único parâmetro da função é o nome do arranjo, ela usa a
função shape da biblioteca numpy para descobrir o número de linhas e o número de
colunas do arranjo.
190
Introdução à Programação com Python
mas apenas dentro do arquivo auxiliar.py. E, não custa ressaltar, mais uma vez a
importância da reutilização de código (que também ocorreu no caso da imprimeTabuleiro()).
191
Introdução à Programação com Python
8.6. Exercícios
1) Implemente uma função que receba 2 números e retorne o maior. Mostre como usar
a função definida no programa principal.
3) Mostre como utilizar a função leiaInt() apresentada neste capítulo, para garantir que
o programa principal passará somente valores válidos quando a função do exercício
2 for chamada.
192
Introdução à Programação com Python
6) Modifique a função do exercício anterior para que a função possa colocar os valores
em ordem crescente ou decrescente. A função deverá receber um valor booleano
como parâmetro e, se o valor for verdadeiro, a ordenação deverá ser crescente.
Caso contrário, a ordenaç!ão deverá ser decrescente.
9) De maneira similar ao que foi feito no exercício anterior, implemente uma solução
para o código apresentado na Figura 7.10 utilizando as mesmas funções, quando
possível, e a implementação da novas funções para determinar se a matriz é
diagonal e para determinar se a matriz é diagonal. A lógica do programa principal
pode seguir a mesma estrutura do programa da figura 7.10
193
Introdução à Programação com Python
194
Introdução à Programação com Python
uma opção para trocar o arquivo de foto e uma opção para encerrar a execução do
programa.
1. Definir o arquivo com a foto a ser processada
2. Transformar em tons de cinza
3. Gerar imagem transposta
4. Inverter na horizontal
5. Inverter na vertical
6. Borrar uma região da imagem
7. Criptografar a imagem
8. Descriptografar uma imagem já criptografada
9. Redução de olho vermelho
10. Sair do programa
195