Baixe o app para aproveitar ainda mais
Prévia do material em texto
Introdução à Programação com Python (Versão 1.3 - para uso no Período Híbrido de Transição (2021-2) da Universidade Federal de Viçosa, de 22/11/2021 a 08/04/2022. O texto, que foi iniciado na segunda semana após a interrupção do semestre 2020-I, não passou por nenhuma revisão profissional. Assim, correções serão muito bem vindas!!! Envie as correções/sugestões para: goulart@ufv.br Meus agradecimentos antecipados!!!) Carlos de Castro Goulart Departamento de Informática Universidade Federal de Viçosa 2020 mailto:goulart@ufv.br Introdução à Programação com Python 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 Introdução à Programação com Python 0 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 Capítulo 3 - Variáveis e Operadores 45 3.1 - Variáveis 45 3.1.1. Comando de Atribuição 48 3.1.2. Tipos de Variáveis 50 3.2 Operadores e Expressões 54 3.2.1. Operadores e Expressões aritméticas 54 3.2.2. Operadores e Expressões Lógicos 58 3.2.2.1 - Operador não (not) 58 3.2.2.2 - Operador e (and) 59 3.2.2.3 - Operador ou (or) 59 3.2.2.4 - Expressões lógicas 60 3.2.2.5 Equivalência de Expressões Lógicas 62 3.3. Exercícios 65 Capítulo 4 - Comandos de Entrada e Saída 68 4.1 - Comando de Saída 68 4.1.1 - Forma básica do comando de saída 68 4.1.2. Comando print() com separador e terminador 70 4.1.3. Comando print() com apenas um parâmetro de texto 72 2 Introdução à Programação com Python 4.1.4. Formatação de dados no comando print() 74 4.2 - Comando de Entrada 77 4.3 - Usando os comandos de entrada e saída em programas simples 79 4.3.1. Cálculo da área de um triângulo 79 4.3.2. Cálculo das raízes de uma equação do segundo grau 82 4.4. Exercícios 83 Capítulo 5 - Comandos Condicionais 89 5.1. Comando if 89 5.2 Comando if-else 92 5.3 Comando if-elif-else 94 5.4 Cálculo de raízes de uma equação do 2⁰ grau 98 5.5. Exercícios 100 Capítulo 6 - Comandos Repetitivos 105 6.1. Comando while 105 6.1.1. Cuidado com o loop infinito 107 6.1.2. Número determinado de repetições com o while 109 6.1.3. Usando while-True 111 6.2. Comando for 112 6.2.1. Comando for 113 6.2.2. Comando for com incremento não unitário 114 6.2.3. Comando for-break 117 6.3. Alguns exemplos de uso de comandos repetitivos 118 6.3.1. Cálculo de média 118 6.3.2. Números Primos 122 6.3.3. Cálculo de raiz quadrada 124 6.4. Exercícios 126 Capítulo 7 - Arranjos 132 7.1. Arranjo unidimensional 133 7.1.1 Arranjos em Python 135 7.1.2 Percorrendo Arranjos 137 7.1.3. Alguns Exemplos 139 7.1.3.1. Cálculo do desvio-padrão 139 7.1.3.2. Relação entre vizinho 141 7.2. Arranjos multidimensionais 143 7.2.1. Definição de arranjos bidimensionais em Python 145 7.2.2. Exemplos usando matrizes 146 7.2.2.1. Pesquisa em matriz 146 7.2.2.2. Verificação de propriedades de uma matriz 149 7.2.3. Arranjos e Processamento de Imagens 153 7.3. Exercícios 158 3 Introdução à Programação com Python Capítulo 8 - Funções 164 8.1. Motivação 164 8.2. Funções em Python 165 8.2.1. Identificando candidato a virar função 166 8.2.2. Função que retorna dois (ou mais) parâmetros 169 8.3. Escopo de Variáveis 170 8.4. Passagem de arranjos como parâmetro 173 8.5. De volta aos algoritmos 173 8.6. Exercícios 176 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, na modalidade remota, no Período Especial de Outono e no Período Especial Remoto (agosto a dezembro de 2020), em função da pandemia da Covid-19. 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. De fato, com a grande quantidade de material sobre a linguagem de programação Python disponível na Internet, talvez a melhor opção seja não gastar recursos públicos para a aquisição de livros. Porém, os estudantes muitas vezes tem dificuldade de “pinçar” a parte que interessa, por estar sendo apresentada na disciplina. Muitos livros e materiais disponíveis na Internet partem do pressuposto de que o leitor já sabe programação. Ou apresentam de início assuntos mais avançados que serão abordados apenas na disciplina INF 101 - Introdução à Programação II. Assim, este material foi elaborado pegando 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. O texto está organizado da seguinte forma: o capítulo 1 apresenta uma breve introdução sobre a programação de computadores e motivação para o seu aprendizado, uma vez que a programação está cada vez mais presente na vida profissional; no capítulo 2 é apresentado o conceito de algoritmo e alguns exemplos não computacionais, para, posteriormente, ser apresentado em pseudo-linguagem já com o intuito de tradução para a linguagem de programação Python; o conceito de variável e os principais operadores da linguagem Python são apresentados no capítulo 3; a estrutura dos comandos condicionais é apresentada no capítulo 4; o capítulo 5 apresenta uma primeira estrutura de comando repetitivo (while); no capítulo 6 a estrutura de dados de arranjos unidimensionais é apresentada juntamente com o comando repetitivo for, que para muitos casos de manipulação de arranjos é mais adequada (principalmente por ser mais sintética); o capítulo 6 trata de arranjos bidimensionais (matrizes) com ênfase em algoritmos para manipulação de imagens; como últimos tópicos abordados na disciplina, as funções e escopo de variáveis são apresentados no capítulo 8. Para ajudar no aprendizado de qualquer linguagem é fundamental a prática pois muitos erros são identificados de forma automática pela ferramenta de programação, como é o caso do interpretador da linguagem Python. Além disso, a implementação de uma solução usando uma ferramenta permitirá a visualização da solução, permitindo conferir sua correção e, eventualmente, sua eficiência. Fica como sugestão uma visita à página do projeto Python Brasil (https://python.org.br) onde você poderá encontrar informações sobre diferentes ambientes de programação para a linguagem Python. Para os alunos 5 https://python.org.br/onde Introdução à Programação com Python matriculados na disciplina INF 100 - Introdução à Programação I, haverá links para 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 1.1. Motivação - por que aprender programaçã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. Vivemos a chamada era da informação, na sociedade da informação,onde a criação, distribuição, uso, integração e manipulação da informação é uma atividade econômica, política e cultural cada vez mais significativa. A evolução das tecnologias digitais de informação e comunicação propiciaram um crescimento exponencial das informações e estão mudando profundamente todos os aspectos da organização social, incluindo a economia, educação, saúde, guerra, governo e democracia. 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. Associados a cada tipo de dispositivo com capacidade de se conectar à Internet, novas aplicações e serviços vão sendo disponibilizados. Hoje estamos entrando na fase em que a Internet ganha um “sobrenome” e passa a ser chamada de Internet das Coisas (IoT - Internet of Things), onde a principal característica é que o usuário precisa conhecer cada vez menos a tecnologia que está cada vez mais presente nas aplicações do dia-a-dia. Supermercados inteligentes nos quais o usuário coloca os produtos em seu carrinho de compras e não precisa passar pelo caixa antes de ir para o estacionamento estão se popularizando em alguns países. Todo o processamento é feito por softwares de identificação facial ou leitura de dados de um cartão inteligente (smart card) para identificar o comprador e sistema de identificação por rádio frequência (RFId) nas etiquetas de cada produto e sensores RFId espalhados pelo supermercado. 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 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. 1.2. Arquitetura do computador e o Sistema Operacional A arquitetura básica de um computador é apresentada na figura 1.1. A execução das instruções ocorre no processador, também chamado de Unidade Central de Processamento (CPU - Central Processing Unit). O processador possui registradores internos (não detalhados na figura) onde armazena temporariamente os operandos de uma determinada instrução. Os operandos geralmente são as variáveis definidas no código do programa de alto nível, conforme veremos em breve. Todas as variáveis e demais objetos definidos no programa ficam armazenados na Memória (também chamada de memória principal ou memória RAM) durante a execução do programa. Pode-se dizer, então, que todo o trabalho de execução de um programa simples envolve apenas o processador e a memória principal além, é claro, do barramento interno que os conecta e compõem a chamada Arquitetura Interna do computador (destacada na parte esquerda da figura 1.1). 8 Introdução à Programação com Python Figura 1.1 - Arquitetura básica de um computador Entretanto, para comandar a execução de um programa e visualizar os resultados gerados é necessário a utilização de Dispositivos de E/S (Entrada e Saída), mostrados no lado direito da figura 1.1. Dentre os dispositivos mais comuns podem ser citados: teclado, mouse e microfone como dispositivos de entrada; monitor de vídeo, impressora e caixa de som como dispositivos de saída; e disco rígido, pendrive e tela sensível ao toque como dispositivos de entrada e saída. 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 forma de utilização do disco rígido e dos demais dispositivos de entrada e saída passa despercebida porque o Sistema Operacional esconde de propósito detalhes que não são importantes para os seres humanos. O Sistema Operacional é um programa que inicia seu funcionamento ao ligar o computador e tem como uma de suas principais tarefas a identificação da quantidade de memória disponível que ele poderá utilizar e a quantidade que ficará disponível para executar os programas dos usuários, além da identificação de todos os dispositivos de E/S conectados ao computador. Ou seja, o sistema operacional identifica e controla todas as partes físicas (o hardware) do computador. A outra tarefa principal dos sistemas operacionais é oferecer uma forma amigável e fácil de utilizar 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 Figura 1.2 - Interface de texto do Lubuntu Linux Neste ambiente, o usuário precisava memorizar os comandos e digitá-los sem erro para que fossem executados. Na figura aparecem dois comandos: o primeiro foi digitado corretamente (ls) e lista os diretórios (ou pastas) e arquivos existentes para o usuário goulart na máquina de nome lubuntu-goulart; o segundo com um erro de digitação (lx) para o qual o sistema operacional responde com uma mensagem de erro (lx: comando não encontrado). Essa simples necessidade de memorizar e digitar comandos tornava o uso de computadores pouco atraente. Além disso, não havia, na época, programas aplicativos de uso geral voltados para o cidadão comum e, por isso, o uso de computador ficava restrito às grandes empresas de tecnologia, a algumas universidades e aos grandes centros de pesquisa. Este tipo de interface foi utilizado nos computadores de grande porte (mainframes) e nos primeiros computadores pessoais, até início da década de 1990. Os principais sistemas operacionais utilizados eram o UNIX e o DOS. A partir do início da década de 1990 começaram a surgir as interfaces gráficas baseadas em janelas, menus e ícones. A Figura 1.3 mostra a interface gráfica de um sistema operacional Linux, similar ao utilizado no Laboratório de Informática onde acontecem as aulas práticas da disciplina de Introdução à Programação I. 10 Introdução à Programação com Python Figura 1.3 - Interface Gráfica do Lubuntu Linux A figura 1.3 apresenta uma janela do Gerenciador de Arquivos mostrando as mesmas pastas exibidas pelo comando ls usado na interface de texto. A exibição desta janela se deu pelo “clique do mouse” no ícone correspondente ao Gerenciador de Arquivos.Diferentemente da interface de texto, na interface gráfica não há como errar o “comando” trocando um ls por um lx. O “clique do mouse” no ícone corresponde ao comando enviado para o sistema operacional, que ocasiona a abertura em uma nova janela o programa relacionado ao ícone. A figura 1.3 mostra ainda alguns ícones que foram colocados na área de trabalho: Lixeira, Navegador Web Firefox, IDLE3, Google Chrome e LX Terminal. O usuário pode personalizar a sua área de trabalho, incluindo ou excluindo ícones de programas. Note que um dos ícones corresponde ao LX 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 esta interface de texto. As interfaces gráficas de diferentes sistemas operacionais possuem bastante similaridade conceitual pois são baseadas nos mesmos elementos: ícones, janelas e menus. Em princípio, o usuário precisa saber qual ícone está associado ao programa que ele deseja utilizar. Desta forma, espera-se que o usuários do sistema operacional Windows não encontrem maiores dificuldades de utilizar o sistema operacional Lubuntu que é uma das versões do sistema operacional Linux. 11 Introdução à Programação com Python Figura 1.4 - Interfaces Gráficas: Windows, Ubuntu e Mac OS X A escolha do Lubuntu para uso no Laboratório de Informática (LBI) se deve ao fato dele ser um software livre. Isso significa que é possível obter o sistema operacional e um grande número de programas aplicativos sem pedir permissão ou autorização de nenhuma empresa. Também é possível modificar, atualizar e/ou instalar qualquer programa que esteja na base da dados do Lubuntu em algum repositório da internet. Além disso, os problemas com vírus e outras pragas virtuais são muito menores do que os do sistema Windows. Tudo isso facilita a manutenção dos sistemas do LBI. 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 Lubuntu no LBI. É provável que muitos estudantes matriculados na disciplina INF 100 - Introdução à Programação I tenham smartphone com o sistema operacional Android, que é o sistema mais usado no mundo neste mercado. O Android e o Lubuntu são exemplos de sistemas operacionais construídos sobre o núcleo (kernel) do sistema operacional Linux. 1.3. Algoritmos e linguagens de programação 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. Como desenvolver um aplicativo? A Figura 1.5 mostra de maneira esquemática as fases de desenvolvimento de uma solução computacional para um problema do mundo real. 12 Introdução à Programação com Python Figura 1.5 - Fases de desenvolvimento de um programa Primeiramente é necessário conhecer qual é o problema que se deseja resolver. Definido o problema, a fase de análise visa obter um conhecimento completo do problema, de forma a permitir a definição das tarefas que devem ser realizadas para resolvê-lo. O passo seguinte é fazer uma descrição sistematizada das tarefas (solução descritiva) que devem ser executadas, atentando para a correta ordem de execução. A solução descritiva geralmente é feita usando a linguagem natural (ex: Português) que pode conter ambiguidade, ou seja, duas pessoas podem interpretar de forma diferente o que uma tarefa faz. Apenas para exemplificar a ambiguidade do Português pode-se utilizar um exemplo não computacional. Na frase “Vejo um homem no alto da montanha usando binóculos”, quem está usando o binóculos? A pessoa que disse a frase pode ter usado binóculos para ver o homem na montanha ou ela pode ter visto que o homem na montanha estava portanto binóculos. Qualquer potencial ambiguidade deve ser eliminada ao transformar a solução descritiva para a forma de algoritmo. Um algoritmo pode ser definido como uma sequência finita de instruções bem definidas e não ambíguas. Este conceito será explorado com mais profundidade no Capítulo 2. No contexto computacional, cada instrução do algoritmo deve estar tão simples e detalhada de forma que poderá ser traduzida para um comando da linguagem de programação. O passo seguinte consiste na tradução de cada instrução do algoritmo para uma instrução da linguagem de alto nível escolhida para a implementação do programa. O 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. Com o programa fonte armazenado em um arquivo, o passo seguinte é fazer a tradução para a linguagem que o computador entende que é a linguagem de máquina. A esta forma dá-se o nome de código executável. Esta tradução pode ser feita diretamente, sem gerar um outro arquivo ou indiretamente, quando é gerado um arquivo executável. No primeiro caso temos as linguagens interpretadas, como é o caso da linguagem Python, na qual o programa é executado diretamente a partir do programa fonte. No caso de outras linguagens, como por exemplo C, é utilizado um compilador que transforma o código fonte em código executável que poderá, então, ser executado. Independente da forma de transformação do código fonte em código executável (interpretada ou compilada), ela sempre é feita por um programa (interpretador ou compilador). De posse do código executável será possível utilizá-lo para verificar se a solução computacional atende aos requisitos especificados na fase de análise do problema. Raramente se conseguirá seguir o diagrama da Figura 1.5 passando uma única vez por cada uma de suas fases. Muitas vezes é no momento da execução do programa que se torna possível verificar os erros da implementação da solução. A correção de um erro vai demandar, necessariamente, a volta a uma das fases anteriores à verificação da solução (execução do programa). 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 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 pretende comparar duas variáveis “a == b“ e acaba atribuindo para a variável “a” o valor da variável “b” ao escrever “a = b”. 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 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. Da mesma forma, os erros de lógica também podem aparecer em diferentes fases do desenvolvimentodo programa. Um erro de lógica em uma condição de parada de um comando repetitivo poderia colocar o programa em uma execução sem fim (loop infinito) e 14 Introdução à Programação com Python este erro, eventualmente, pode se dever apenas a um erro na digitação. Neste caso a correção costuma ser simples com a correção na edição do código fonte. Ou o erro de lógica pode ocorrer na fase de análise com a inversão de duas tarefas que tem que ser feitas em uma ordem pré-determinada. Neste outro caso, a volta seria para a fase de análise do problema. 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. Embora as operações a serem executadas sejam as mesmas, independente do processador, o código Assembly será muito diferente. Para exemplificar serão considerados os processadores x86 (Intel/AMD) e RISC, com os respectivos códigos Assembly mostrados na tabela 1.1. Note que as instruções podem ter nomes diferentes como no caso da movimentação de dados da memória para registrador (mov/lw) e, eventualmente, quando tem mesmo nome como no caso da soma (add) a forma de especificar os operandos são 15 Introdução à Programação com Python diferentes: uma linguagem permite especificar apenas 2 registradores enquanto que a outra permite definir 3 registradores. Mas em ambas, o primeiro registrador armazenará o resultado da operação de soma. Tabela 1.1 - Códigos Assembly de uma soma de duas variáveis. Assembly do Processador x86 Assembly do Processador RISC Significado para x86 (RISC) mov ax, a mov bx, b add ax, bx lw $t0, a lw $t1, b add $t3, $t0, $t1 carrega variável a no registrador ax (t0) carrega variável b no registrador bx (t1) soma registradores ax e bx (t0 e t1), com resultado no registrador ax (t3) 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. 1.4. O ambiente de programação no LBI Como suporte para as aulas práticas da disciplina INF 100 - Introdução à Programação I, o Departamento de Informática da UFV possui o Laboratório de Informática (LBI) localizado no segundo pavimento do prédio da Caixa Econômica Federal. O LBI funciona durante o semestre letivo de segunda a sexta-feira, de 8h às 21h, excetuando-se os feriados e recessos previstos no calendário escolar da UFV. Na modalidade de ensino remoto,o LBI não será utilizado, por razões óbvias. Neste caso, o estudante deverá instalar o ambiente com o editor de programas e interpretador Python (IDLE) em seu computador, seguindo as instruções da seção 1.4.1 - Home Python. 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 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 Lubuntu (Light Ubuntu), que é uma versão leve do Ubuntu. Para a execução das atividades nas salas do LBI, o estudante matriculado na disciplina INF 100 utilizará o navegador de Internet Firefox, o servidor do LBI, um leitor de arquivos PDF (Portable Document Format), o ambiente de desenvolvimento IDLE e o 16 Introdução à Programação com Python gerenciador de arquivos. O estudante utiliza uma conta padrão cujo nome de usuário é “Aluno” e a senha é informada na primeira aula prática. 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. Figura 1.6 - Área de trabalho da conta Alunos no LBI Toda aula prática possui um roteiro e, eventualmente, um ou mais arquivos adicionais que ficam armazenados no servidor do LBI. Um leitor de arquivos PDF é necessário, pois todos os roteiros de aulas práticas são disponibilizados em formato PDF. Existem diversos leitores de PDF gratuitos disponíveis na Internet. Todos os computadores do LBI possuem leitor de PDF. Em geral, a configuração permite abrir o arquivo PDF em uma nova aba do navegador de internet. Mas também é possível que seja aberta uma janela nova com a imagem do arquivo PDF. 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. Os dias e horários que um estudante pode acessar o servidor do LBI é programado de acordo com o seu horário de aula prática na disciplina INF 100 e com o tipo de atividade: presencial ou a distância. Quando o estudante optar por realizar a atividade a distância, ele poderá usar o navegador de internet de sua preferência fornecendo o endereço completo do servidor do LBI: http://linux-server.lbi.ufv.br. Os procedimentos para obter o material (roteiro 17 http://linux-server.lbi.ufv.brIntrodução à Programação com Python e arquivos adicionais) para a realização da aula prática e a entrega do trabalho são os mesmos para quem está no LBI ou para quem está em casa ou outro lugar qualquer. O ambiente de desenvolvimento IDLE possui duas partes principais: uma interface para execução de comandos (shell) e um editor de programas Python integrado. Ao clicar no ícone do IDLE será aberta uma janela como a mostrada na Figura 1.7(a). Para que seja aberta a janela do editor de programas (Figura 1.7(b)) é necessário selecionar, na janela do Shell, no menu de arquivo (File) a opção de criar um novo arquivo (File -> New File) ou abrir um arquivo já existente (File -> Open). (a) Shell (b) Editor de Programas Figura 1.7 - Ambiente de desenvolvimento IDLE 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. Desta forma, a primeira janela que será aberta ao iniciar o uso do ambiente de desenvolvimento IDLE é a janela do Shell. A janela do editor de programas é aberta, a partir da seleção de uma das opções do menu de Arquivo (File) na janela do Shell para criar um novo arquivo (File -> New File) ou abrir um arquivo (File -> Open). 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 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 >>>. 18 Introdução à Programação com Python 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. Figura 1.8 - Exemplo de comandos no Shell do IDLE 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” é 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 = 19 Introdução à Programação com Python 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. Toda a informação digitada no Shell é perdida quando sua janela é fechada ou se o computador for desligado, como no caso de uma queda de energia durante a aula prática. Por isso, o Shell deve ser usado somente para efetuar pequenos testes. E, nas aulas práticas, o Shell deverá ser usado apenas para abrir (ou criar) o arquivo com o programa que será desenvolvido para ser entregue no final do prazo determinado e para visualizar o resultado da execução do programa, conforme será mostrado a seguir. 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. Figura 1.9 - Programa com erro Antes de executar um programa que foi escrito na janela do editor do programa é preciso salvá-lo. Isso pode ser feito utilizando a opção do menu “File -> Save” ou digitando as teclas “Ctrl+S” (significa: manter pressionada a tecla Ctrl e pressionar a tecla S). Porém, se você tentar executar o programa sem salvá-lo, o IDLE exibirá uma mensagem para que você o salve. A ideia é que a versão a ser executada deve ser exatamente a que você está vendo na tela. Note que o arquivo da Figura 1.9 já havia sido salvo (gravado no disco rígido) quando a tela foi capturada, conforme o nome do arquivo que aparece no topo da janela (primeiro.py). 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 do programa será exibida na janela do Shell. No código, o comando para exibir o conteúdo 20 Introdução à Programação com Python 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. Figura 1.10 - Janela do Shell com a saída do programa da Figura 1.9 Note que o interpretador Python lê o programa e vai executando os comandos sequencialmente. A primeira linha é ignorada pois é apenas um comentário. As duas linhas seguintes criam e definem o valor inicial dos objetos A e B, porém não produzem nenhuma saída para o Shell. Na sequência, existem dois comandos de impressão (print()) que geram saídas para o Shell com a exibição dos valores 2 e 3, dos objetos A e B, respectivamente. O terceiro comando de impressão contém um erro pois usa o nome de um objeto que ainda não foi definido. A definição do objeto C está na linha seguinte (linha 7), mas o interpretador não enxerga isso, pois ele tenta executar os comandos na sequência em que eles foram escritos pelo programador. Este erro ocasiona a mensagem de erro na janela do Shell (vide Figura 1.10). Note que, além de indicar o tipo de erro (NameError: name ‘C’ is not defined) o interpretador também informa a localização do erro no dentro do código, neste caso na linha 6 (File "/home/goulart/primeiro.py", line 6, in <module>). Também é informado o nome do arquivo porque programas mais complexos podem ser compostos por mais de um arquivo. A correção, neste caso, consiste em trocar de posição a linha 6 com a linha 7, colocando a definição do objeto C (C = A + B) antes de sua impressão (print(C)). Após qualquer modificaçãono texto do programa, a janela do editor exibe o nome do arquivo entre ‘*’ para indicar que a versão vista na janela é diferente da gravada no disco rígido, como pode ser visto na Figura realizar tal modificação 21 Introdução à Programação com Python Figura 1.11 - Programa sem erros 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 informar 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. Figura 1.12 - Janela do Shell com as duas execuções do programa primeiro.py 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”. Figura 1.13 - Gerenciador de Arquivos mostrando a pasta do usuário “goulart”. 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 Figura 1.14 - Gerenciador de Arquivos mostrando o conteúdo da pasta “Downloads” 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. 1.4.1 - Home Python Em função da pandemia da Covid-19, as atividades presenciais no Laboratório de Informática (LBI) estão vedadas por tempo indeterminado. Assim, para realizar as atividades práticas de programação será necessário a instalação do ambiente de desenvolvimento IDLE-Python e bibliotecas numérica e gráfica em um computador pessoal. Existem versões do IDLE-Python para diversos sistemas operacionais. A seguir são apresentadas as instruções para instalação nos sistemas operacionais Linux e Windows. 24 Introdução à Programação com Python Para instalação no sistema operacional Linux é necessário estar conectado à Internet, pois os arquivos são buscados em repositórios da versão do sistema operacional instalado no computador. Após certificar-se que a conexão está operacional, basta seguir a seguinte sequência de passos: 1) Acesse a página da disciplina INF 100 no PVANet e pegue o arquivo instalaIDLE. 2) Abrir um terminal e entrar no diretório onde o arquivo instalaIDLE foi salvo. 3) Executar no terminal o comando “sudo su” (sem as aspas) e fornecer a senha de administrador. Os comandos a seguir devem ser executados pelo usuário administrador do sistema, ou seja, após a execução do comando deste passo 2. 4) Executar o comando “chmod +x instalaIDLE” (sem as aspas) para incluir a permissão de execução para o arquivo instalaIDLE, que é um arquivo executável (script). 5) Executar o comando “./instalaIDLE” para executar o script que fará o resto do trabalho. O processo de instalação costuma demorar alguns minutos, em função da velocidade de acesso à Internet e carga do servidor onde está localizado o repositório dos arquivos que serão baixados para seu computador. Fique atento para eventuais mensagens de erro, que indicam eventual falha no processo de instalação. Mensagens de advertência (warning) indicam que um problema foi detectado, mas contornado e a instalação terá sido bem sucedida se houver apenas mensagens de advertência. Para quem não está matriculado na disciplina INF 100 e, portanto, não tem acesso ao PVANet, o arquivo instala-IDLE pode ser obtido com este endereço no Google Drive https://drive.google.com/file/d/1VZLDv8kj7vtVcDA16AfU8x3zofLwvPoK/view?usp=sharing. Há ainda um vídeo com tutorial mostrando a instalação no Linux, que pode ser visualizado neste endereço: https://youtu.be/YmI3vQIRMHQ. Para instalação no sistema operacional Windows, é recomendado a instalação do pacote disponível no endereço https://www.python.org/downloads/windows/. Você deve baixar a release mais recente do Python 3. 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 feitonã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). Este instalador não instala as bibliotecas numpy e PIL (bibliotecas de manipulação de arranjos e de processamento de imagens, respectivamente), que serão necessárias para algumas implementações. Assim, os passos seguintes deverão ser feitos mesmo para quem já tem o Python-IDLE instalado. A instalação das bibliotecas citadas pode ser feitas 25 https://drive.google.com/file/d/1VZLDv8kj7vtVcDA16AfU8x3zofLwvPoK/view?usp=sharing https://youtu.be/YmI3vQIRMHQ https://www.python.org/downloads/windows/ Introdução à Programação com Python usando o Shell do Windows (Command ou cmd) com comandos específicos. Para instalar a biblioteca gráfica PIL um dos 3 comandos a seguir resolverá o problema: python3 -m pip install Pillow Ou: python -m pip install Pillow Ou: py -m pip install Pillow O comando correto vai depender de como foi feita a instalação do Python no sistema e como o Windows o conhece: python3, python ou py. Analogamente, para a instalação da biblioteca numérica numpy existem dois comandos possíveis, a saber: python3 -m pip install numpy Ou: py -m pip install numpy Ou: python - m pip install numpy A instalação é feita buscando arquivos na Internet. Logo, o computador deverá estar conectado à rede para a instalação do Anaconda e/ou das bibliotecas. Na página da disciplina INF 100 – Introdução à Programação I no PVANet, há um vídeo que mostra de forma detalhada a instalação do Anaconda. Para quem não está matriculado na disciplina INF 100 e, portanto, sem acesso ao PVANet, o vídeo com tutorial mostrando a instalação no Windows, pode ser visualizado neste endereço: https://youtu.be/MFWTQxUauTw (atualizado em janeiro de 2021). 1.5. Exercícios 1) O vídeo https://www.youtube.com/watch?v=nKIu9yen5nc apresenta depoimentos de figuras como Mark Zuckerberg (Facebbok), Jack Dorsey (Twitter), Bill Gates (Microsoft), Chris Bosh (Jogador de Basquete da NBA), dentre outros, sobre suas primeiras experiências com programação. Após assistir ao vídeo responda as perguntas a seguir. Quem disse as seguintes frases (tradução livre): 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 é?. 26 https://youtu.be/MFWTQxUauTw https://www.youtube.com/watch?v=nKIu9yen5nc Introdução à Programação com Python 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). 2) No vídeo https://www.youtube.com/watch?v=6XvmhE1J9PY, o então presidente dos EUA, Barack Obama, fala sobre a importância estratégica do ensino de programação nas escolas. Você concorda com a visão dele. Escreva um parágrafo com sua opinião sobre a importância estratégica da programação na sua área de atuação como futuro profissional. 3) O vídeo https://www.youtube.com/watch?v=Fkd9TWUtFm0 apresenta um “experiente” desenvolvedor de aplicativos falando de como iniciou sua precoce carreira. Quais foram as linguagens de programação que ele citou já ter utilizado? 4) Identifique no seu computador a quantidade de memória RAM, a velocidade do processador e o tamanho do disco rígido. 5) Suponha que um computador gaste, em média, 8 ciclos de processador para executar cada instrução aritmética de ponto flutuante. Um programa de simulação executa 10 bilhões de instruções de ponto flutuante. Quanto tempo um computador do início da década de 1980 com processador de ciclo de 1 MHz demoraria para executar este programa? 6) Quanto tempo o seu computador demoraria para executar o mesmo programa do exercício 3? 7) Instale o interpretador IDLE-Python em seu computador. Certifique-se de que as bibliotecas numérica (numpy) e gráfica (PIL) estejam instaladas (Execute o programa abaixo, para testar a importação das referidas bibliotecas). Ao final da execução a mensagem “Olá mundo…” (sem as aspas) deverá ser exibida na janela do Shell. import numpy import PIL print(‘Olá mundo...’) 27 https://www.youtube.com/watch?v=6XvmhE1J9PY https://www.youtube.com/watch?v=Fkd9TWUtFm0 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. 2.1 Definição de Algoritmo 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. 2.2 Algoritmo computacional e não computacional 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. 28 Introdução à Programação com Python Tabela 2.1 - Receita de Pão de Queijo Ingredientes Modo de preparo - 4 copos (americano) de polvilho doce (500 g); - 1 colher (sopa) tempero ou sal a gosto - 2 copos (americano) de leite (300 ml) - 1 copo (americano) de óleo (150 ml) - 2 ovos grandes ou 3 pequenos - 4 copos (americano) de queijo minas meia cura ralado - óleo para untar 1. Coloque o polvilho em uma tigela grande. 2. À parte, aqueça o sal, o leite e o óleo. 3. Quando ferver, escalde o polvilho com essa mistura, mexa muito bem para desfazer pelotinhas. 4. Deixe esfriar. 5. Acrescente os ovos, um a um, alternando com o queijo e sovando bem, até a massa ficar homogênea, após cadaadição. 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. O modo de preparo da receita culinária corresponde ao algoritmo propriamente dito, pois ele descreve as ações que devem ser executadas para, usando os ingredientes, se produzir o resultado desejado. Entretanto, as ações que o computador consegue executar são ações muito simples e devem ser definidas de forma que não haja nenhuma dúvida sobre o que se está querendo executar. Da mesma forma, os dados a serem processados pelo computador tem que ser exatos, não podendo ter nenhum tipo de ambiguidade. 2.3. Propriedades de um algoritmo Voltando à definição de algoritmo apresentada é possível destacar algumas das propriedades que todo algoritmo deve ter. Algoritmo é “um conjunto de regras e procedimentos lógicos perfeitamente definidos que levam à solução de um problema em um número finito de etapas”. As propriedades dos algoritmos foram definidas por Knuth (ref): • Finitude: um algoritmo deve sempre terminar após um número finito de ações; • Definição: cada passo de um algoritmo deve ser definido com precisão; as ações a serem executadas deverão ser especificadas rigorosamente e sem ambiguidades; • Entrada: são os valores que são fornecidos ao algoritmo. Essas entradas são tomadas a partir de conjuntos de objetos especificados; • Saída: são os valores resultantes das ações do algoritmo relacionadas com as entradas especificadas; • Eficácia: são todas as operações a serem realizadas no algoritmo devem ser suficientemente básicas e podem, em princípio, ser feitas com precisão e em um período de tempo finito por um homem usando papel e lápis. 29 Introdução à Programação com Python A primeira propriedade (finitude) está relacionada com o tempo esperado para se obter o resultado. Em um tempo finito os pães de queijo tem que sair do forno e ninguém pode morrer de fome enquanto espera. Para alguns problemas computacionais mais complexos é necessário verificar se o problema pode ser resolvido usando o computador que se tem disponível. Por exemplo, uma previsão de tempo baseada em imagens de satélite para o dia seguinte não pode levar mais do que poucas horas. Se demorar, por exemplo, dois dias o resultado seria a previsão do tempo de ontem… No caso da disciplina INF 100 todos os problemas apresentados são relativamente simples e não será feita este tipo de análise. A propriedade de definição está relacionada com a parte do conceito de algoritmo que diz “... e procedimentos lógicos perfeitamente definidos que levam à solução…”. Isto significa que não pode haver ambiguidade (dúvida) sobre o que está escrito no algoritmo, tanto na definição dos ingredientes (conjunto de dados) quanto nas ações ou comandos do modo de preparo ou do algoritmo. A propriedade de entrada está associada com o conjunto de informações necessárias (os ingredientes) para serem processadas e/ou transformadas para se chegar ao resultado esperado. E a propriedade de saída corresponde exatamente ao resultado esperado, quando se pode comprovar a correção do algoritmo. Estão saindo pães de queijo do forno? Ou está saindo um bolo? Finalmente, a propriedade de eficácia está relacionada com o grau de simplicidade de cada ação definida no algoritmo tem. A ação está suficientemente detalhada e simples? É realmente uma única ação? Caso estes requisitos não sejam atendidos é necessário refinar a ação, ainda complexa, quebrando-a em duas ou mais ações. Esta tarefa é chamada de refinamentos sucessivos. É importante lembrar que a versão final de um algoritmo computacional deve ser tal que, cada ação represente um único comando da linguagem de programação que será usada. Na próxima seção, cada ação do algoritmo para fazer pães de queijo deverá ser especificada de forma a representar uma única ação simples. 2.4. Refinamento sucessivo e estruturas de programação Nesta seção serão apresentadas versões sucessivas e refinadas do algoritmo para fazer pães de queijo para exemplificar a eliminação de ambiguidades e a apresentação das três estruturas básicas de programação: sequencial, condicional e repetitiva. Estas três estruturas são suficientes para escrever qualquer programa computacional. Por isso, é importante, desde já, entender tais estruturas mesmo quando aplicadas a um exemplo não computacional. A primeira estrutura é a sequencial. Todo algoritmo (e programa) é composto por uma sequência de ações relacionadas com o que é necessário para poder. Observe que na Tabela 2.1, as ações do modo de preparo estão numeradas, indicando a ordem (sequência) 30 Introdução à Programação com Python em que as ações devem ser executadas. Esta ordem é importante 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). 2.4.1 Eliminando ambiguidades 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. Ao ler na lista de ingredientes “1 colher (sopa) tempero ou sal a gosto” poderão surgir diversas algumas dúvidas: usar tempero ou sal? Qual tempero, pimenta? Qual é a colher de sopa? Qual quantidade corresponde ao “a gosto”? Uma colher de sopa rasa, cheia? Para não haver estas ambiguidades o ingrediente deveria ser algo como “10g de sal”. O que significa um ovo grande? Pode ser ovo de pata? O que significa “meia cura”? 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 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 . Tabela 2.2 - Ingredientes não ambíguos da Receita de Pão de Queijo Ingredientes Comentário - 500g de polvilho doce; # pacote de 500g - 10g sal; # Quantidade extraída de pacote de 1 kg - 300 ml de leite # Quantidade extraída de saco de 1l. - 200 ml de óleo # Quantidade extraída de garrafa de 1l. - 2 ovos de galinha # Quantidade extraída de caixa com 12 - 400g de queijo ralado # Quantidade comprada a granel (minas meia cura) 31 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. Outro detalhe é que em um algoritmo, assim como nas linguagens de programação, é possível adicionar comentários, que não fazem parte do algoritmoem si, mas ajudam a documentá-lo. Na tabela 2.2, o caractere # foi usado para identificar o início de um comentário: tudo o que vem após o #, na mesma linha, não faz parte da lista de ingredientes, mas auxilia um cozinheiro inexperiente a saber como adquirir ou como usar aquele ingrediente. Os comentários são muito úteis como parte da documentação dos algoritmos (e programas), facilitando o entendimento por outras pessoas que tiverem acesso ao algoritmo (código) e ajudando ao próprio autor do algoritmo (código) a lembrar detalhes de sua criação. 2.4.2. Refinamento do Algoritmo 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. O detalhamento de uma operação para eliminação de ambiguidade ou para quebrá-la em duas ou mais ações é chamado de refinamento. A técnica de refinamento deve ser aplicada tantas vezes quantas necessárias para que, ao final, o algoritmo contenha apenas operações triviais. Esta técnica é conhecida como refinamento sucessivo do algoritmo. A Figura 2.1 apresenta uma segunda versão, primeiro refinamento, do algoritmo (modo de preparo) considerando os ingredientes já definidos na Tabela 2.2, com o detalhamento das operações ou ações, em particular, da ação 5 da versão 1, que descreve 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. 32 Introdução à Programação com Python 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. 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 Figura 2.2 - Algoritmo versão 2 A versão 3 do algoritmo apresenta todas as ações refinadas, explicitando ações que antes estavam implícitas, como acender uma das trempes no passo 2 e ligar o forno para que ele esteja pré-aquecido no momento de executar a ação 8. Está sendo suposto que o tempo de pré-aquecimento é o tempo que se gastaria para enrolar os pães de queijo e colocá-los no tabuleiro. Acender o forno para o pré-aquecimento foi inserida como a operação de número 6 e, consequentemente, forçou a renumeração das ações seguintes. A Figura 2.3 apresenta a versão 3 do algoritmo. 33 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 Embora esteja sendo usada a numeração, ela é dispensável. Como se está tratando de estrutura de comandos sequenciais, é suposto que os comandos serão executados na sequência em que eles foram escritos, linha após linha, uma linha de cada vez. Porém, será mantida a numeração por mais algum tempo. 2.5 - Estrutura de comando condicional A versão 3 do algoritmo apresentado na Figura 2.3 possui apenas comandos sequenciais. Entretanto, existe pelo menos um comando que implicitamente é uma estrutura condicional: “7. Unte as mãos com óleo, se necessário”. Note que existe uma condição para que o operador humano unte as mãos. A pessoa só deve untar as mãos se necessário. Note que na lista de ingredientes, a quantidade de óleo é de 200ml e para a mistura são necessários 150 ml. Desta forma, os 50 ml restantes poderiam ser usados para untar as mãos. Mas somente, se necessário. Portanto, é preciso ter uma estrutura que permita executar condicionalmente uma ação. 34 Introdução à Programação com Python Um comando condicional é uma estrutura das linguagens de programação na qual existe um teste de uma condição que é feito antes de executar o comando. O comando somente será executado no caso da condição testada ser verdadeira. A forma geral de um comando condicional é a mostrada na Figura 2.4. se <condição> <Comando> Figura 2.4 - Estrutura do comando condicional A <condição> representa a condição a ser verificada ou o teste a ser feito. O resultado do teste da condição só pode ter dois valores: verdadeiro ou falso. <Comando> representa o comando que será executado somente no caso do resultado do teste ter sido verdadeiro. Note que <Comando> está deslocado para a direita indicando que sua execução está vinculada à cláusula “se”, que corresponde ao caso da condição testada ser verdadeira. Este deslocamento é chamado de indentação. O <Comando> pode ser, na verdade, um bloco com um ou mais comandos, onde todos os comandos do bloco seriam executados somente quando o teste for verdadeiro. De acordo com a regra de indentação, o próximo comando, após o comando condicional, deve ser escrito alinhado com o “se”. Isso indica a sequência de execução do programa. Desta forma, um comando condicional nada mais seria do que um comando sequencial, mas que só será executado quando a condição avaliada for verdadeira. Em outras palavras, a condição sempre é testada (característica de comando sequencial), mas o bloco de comandos será executado apenas quando o resultado do teste for verdadeiro. No caso do algoritmo em discussão, o teste a ser feito é verificar se a massa do pão de queijo ficou grudenta (ou não). Se a massa estiver grudenta (resultado verdadeiro), é necessário que a mão seja untada de óleo para a massa não ficar agarrandona palma da mão, enquanto cada pão de queijo vai sendo enrolado. No caso do teste ser falso (massa não ficou grudenta), a ação de untar a mão não será executada, pois não é necessária. A Figura 2.4 mostra como ficaria o comando 7 da versão 3 do algoritmo. 7. se “massa está grudenta”: 7.1. Unte as mãos com óleo Figura 2.5 - Exemplo de 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 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). 35 Introdução à Programação com Python A Figura 2.6 apresenta a estrutura do comando condicional que também permite a especificação de um comando (ou bloco de comandos) associados ao resultado negativo do teste. se <condição> <comando1> senão <comando2> Figura 2.6 - Estrutura de comando condicional com cláusula “senão” Para este tipo de comando condicional, se a condição for verdadeira apenas o <comando1> será executado e se a condição for falsa apenas o <comando2> será executado. Como o resultado do teste só pode assumir estes dois valores (verdadeiro ou falso), <comando1> e <comando2> nunca serão executados juntos. Ou <comando1> será excutado (se condição for verdadeira) ou <comando2> será executado (caso contrário ou se condição for falsa). A cláusula “senão” deixa explícito que o <comando2> está associado ao caso da condição ser falsa. Note que tanto o comando (ou bloco de comandos) vinculados ao caso do teste verdadeiro (cláusula “se”), como o comando (ou bloco de comandos) do teste falso (cláusula “senão”) ficam deslocados para a direita, indicando a vinculação ao respectivo resultado do teste (verdadeiro ou falso). Este deslocamento (indentação) aparecerá também nos comandos repetitivos que serão vistos na próxima seção. A indentação é importante para deixar claro quais são os comandos que pertencem a cada bloco. Algumas linguagens de programação são mais exigentes com a indentação, como é o caso da linguagem Python, conforme será visto a partir do capítulo 3.. No algoritmo versão 3 ainda há uma ambiguidade que será resolvida para exemplificar o uso da estrutura de comando condicional da Figura 2.6. A ação “5.1. Adicione um ovo” para ser executada por um robô não estaria suficientemente detalhada e poderia resultar em uma massa com fragmentos de casca de ovo. Além disso, para quem costuma fazer ovo frito ou omelete, já pode ter passado pela experiência de quebrar um ovo choco. Desta forma um refinamento necessário seria incluir uma condição para testar se o ovo pode ser usado ou não, como mostrado na Figura 2.7. 5.1.1. Quebre um ovo em uma tigela pequena 5.1.2. Jogue a casca do ovo na lixeira 5.1.3. se “ovo está choco” 5.1.3.1. Jogue o ovo na lixeira 5.1.3.2. Lave a tigela pequena senão 5.1.3.1. Adicione o ovo da tigela pequena Figura 2.7 - Exemplo de comando condicional com cláusula “senão” 36 Introdução à Programação com Python No exemplo da Figura 2.7, se o teste for verdadeiro o bloco de dois comandos (“Jogue o ovo na lixeira” e “Lave a tigela pequena”) será executado. Se o teste for falso, apenas o comando “Adicione o ovo da tigela pequena” será executado. Note que a numeração do primeiro comando de cada bloco é a mesma (5.1.3.1.), exatamente porque um dos dois será executado logo após o teste feito (5.1.3). Cada teste realizado na cláusula “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: 5.1.1. Quebre um ovo em uma tigela pequena 5.1.2. se “ovo está choco” 5.1.2.1. Jogue a casca do ovo na lixeira 5.1.2.2. Jogue o ovo na lixeira 5.1.2.2. Lave a tigela pequena senão 5.1.2.1 Jogue a casca do ovo na lixeira 5.1.2.2. Adicione o ovo da tigela pequena Figura 2.8 - Erro de uso de ação sequencial em comando condicional A ação “Jogue a casca do ovo na lixeira” será executada sempre, independente do resultado da condição testada. E, de fato, a casca do ovo sempre deve ser descartada. Logo, é uma ação sequencial e não deve estar em um comando condicional. Muitos programadores inexperientes costumam cometer este tipo de erro, replicando blocos de comandos, às vezes enormes, nas duas cláusulas (se/senão) de um comando condicional. As estruturas de comando condicional podem ser mais poderosas, permitindo a inclusão de outras cláusulas de teste. Porém, para solucionar o problema de gerar um algoritmo para a receita de pão de queijo, as duas estruturas apresentadas são suficientes. Algumas linguagens de programação implementam essas estruturas de comando condicional compostas, como é o caso da linguagem Python. Essas estruturas serão apresentadas no Capítulo 4. 37 Introdução à Programação com Python 2.6 - Estrutura de comando repetitivo No algoritmo, versões 2 e 3 existe uma sequência de 3 ações que é repetida duas vezes, relacionada com a adição do ovo na receita: “Acrescente um ovo”; “Acrescente 200g de queijo ralado”; e “Bata até a mistura ficar homogênea”. Imagine se a receita precisasse de 10 ovos ao invés de 2 ovos. Ou, em outro problema, em que uma tarefa tivesse que ser executada 1.000 vezes. O algoritmo ficaria imenso. Para resolver este problema utiliza-se a estrutura do comando repetitivo Enquanto, mostrada na Figura 2.9. Apesar de ter sido utilizada uma marcação de final do comando repetitivo, o <comando> deve ser deslocado à direita, seguindo a regra de indentação de blocos. Enquanto <condição> <comando> Fim_Enquanto Figura 2.9 - Estrutura de comando repetitivo Enquanto A <condição> é avaliada antes da execução do comando e, como no caso do comando condicional, o resultado da avaliação só pode ser verdadeiro ou falso. No caso do resultado ser verdadeiro, o <comando> (ou bloco de comandos) é executado uma vez. Após a execução, chegando ao fim do comando repetitivo (marcado pelo “Fim_Enquanto), volta-se ao teste da condição que é feito novamente. No caso do resultado do teste ser verdadeiro, novamente, o comando repetitivo será executado pela segunda vez. Esta execução se repetirá enquanto a condição testada continuar dando resultado verdadeiro. Quando o resultado da condição testada é falso, o comando repetitivo termina, passando para a execução do próximo comando sequencial. Caso o teste da condição dê resultado falso na primeira vez, o comando repetitivo não será executado. Portanto, esta estrutura fará com que o comando repetitivo seja executado zero ou mais vezes. 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. Considerando as 3 ações (“Acrescente um ovo”; “Acrescente 200g de queijo ralado”; e “Bata até a mistura ficar homogênea”) que tem que ser executadas 2 vezes, a informação de controle será o número de ovos adicionados na receita. Inicialmente, o número de ovos na receita é igual a zero e a cada vez que um ovo for acrescentado, o número de ovos da 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. 38 Introdução
Compartilhar