Você está na página 1de 51

Como Pensar como um Cientista da Computao

Aprendendo com Python


Allen Downey Jeffrey Elkner Chris Meyers

Introduo
Por David Beazley Como um educador, pesquisador e autor de livros, regozija-me ver completo este trabalho. Python uma linguagem de programao divertida e extremamente fcil de usar que tem ganho forte popularidade nestes poucos ltimos anos. Desenvolvida dez anos atrs por Guido van Rossun, A sintaxe simples do Python e seu sentido geral so grandemente derivados do ABC, uma linguagem didtica que foi desenvolvida nos anos 80. Entretanto, Python tambm foi criado para solucionar problemas reais e tomou emprestado uma grande quantidade de caractersticas de linguagens de programao como C++, Java, Modula-3, e Scheme. Por causa disso, uma das mais notveis caractersticas do Python o grande apelo que tem junto a desenvolvedores profissionais de software, cientistas, pesquisadores, artistas e educadores. A Despeito deste apelo do Python junto s mais variadas comunidades, voc pode ainda estar pensando por que Python? ou por que ensinar programao com Python? Responder estas perguntas no uma tarefa fcil especialmente se a opinio pblica est do lado de alternativas mais masoquistas como C++ e Java. Entretanto, eu acho que a resposta mais direta que programar com Python um bocado divertido e mais produtivo. Quando ministro cursos de cincias da computao, o que desejo cobrir conceitos importantes alm de tornar a matria interessante e tornar participativos os alunos. Infelizmente, existe uma tendncia entre os cursos introdutrios de programao a focar ateno demais em abstraes matemticas, e de frustrao entre os alunos com problemas enfadonhos e inoportunos relacionados a detalhes de sintaxe em baixo nvel, compilao e a imposio de regras aparentemente misteriosas (enforcement of seemingly arcane rules). Embora alguma abstrao e formalismo seja importante para engenheiros profissionais de software e estudantes que planejam continuar seus estudos em cincias da computao, escolher tal abordagem em um curso introdutrio faz da cincia da computao algo entediante. Quando ministro um curso, no desejo uma sala cheia de alunos sem inspirao. Em vez disso, preferiria muito mais v-los tentando solucionar problemas interessantes explorando idias diferentes, trilhando caminhos no convencionais, quebrando regras, e aprendendo a partir de seus erros. Fazendo assim, no pretendo desperdiar metade de um semestre tentando explicar problemas obscuros de sintaxe, mensagens ininteligveis de compiladores ou as vrias centenas de maneiras pelas quais um programa pode gerar uma falha geral de proteo.

Uma das razes pelas quais eu gosto de Python que ele prov um balano realmente bom entre o prtico e o conceitual. Sendo Python interpretado, os iniciantes podem pegar a linguagem e comear a fazer coisas claras e perfeitas quase imediatamente sem se perderem em problemas de compilao e linkeditagem. Alm disso, Python vem com uma grande biblioteca de mdulos que podem ser utilizados para fazer todo tipo de tarefa, da programao para a web a grficos. Com tal enfoque prtico temos uma bela maneira de alcanar o engajamento dos alunos e permitir que eles finalizem projetos que tenham significado. Entretanto, Python tambm pode servir de excelente embasamento para a introduo de conceitos importantes em cincia da computao. J que Python suporta plenamente procedures e classes, os alunos podem ser gradualmente introduzidos a tpicos como abstrao procedural, estruturas de dados, e programao orientada a objetos todas aplicveis em cursos posteriores de Java ou C++. Python ainda toma emprestado certas caractersticas de linguagens de programao funcionais e pode ser usado para introduzir conceitos cujos detalhes poderiam ser aprofundados em cursos de Scheme e Lisp. Lendo o prefcio de Jeffrey, fiquei impressionado com seu comentrio de que Python o fez ver um maior nvel de sucesso e um menor nvel de frustrao o que lhe permitiu progredir mais depressa com resultados melhores. Embora estes comentrios refiram-se aos seus cursos introdutrios, eu s vezes uso Python pelas mesmas exatas razes em cursos de graduao em cincia da computao na Universidade de Chicago. Nestes cursos, enfrento constantemente a assustadora tarefa de cobrir um monte de matrias difceis em um bimestre (blistering) de nove semanas. Embora me seja possvel infligir um bocado de dor e sofrimento pelo uso de uma linguagem como C++, tenho percebido muitas vezes que este enfoque contraproducente especialmente quando o curso sobre um tpico no relacionado apenas com programar. Acho que usar Python me permite um melhor foco no tpico em questo, enquanto permite que os alunos completem projetos substanciais em classe. Embora Python seja ainda uma linguagem jovem e em evoluo, acredito que tem um futuro brilhante em educao. Este livro um passo importante nessa direo. David Beazley Universidade de Chicago Autor de Python Essencial Reference

Prefcio
Por Jeff Elkner Este livro deve sua existncia colaborao tornada possvel pela Internet e pelo movimento do software livre. Seus trs autores um professor universitrio, um secundrio e um programador profissional ainda no se encontraram pessoalmente, mas temos podido trabalhar bem de perto e temos sido ajudados por muitos colegas maravilhosos que tm dedicado seu tempo e energia em ajudar a fazer deste um livro cada vez melhor. Achamos que este livro um testemunho dos benefcios e possibilidades futuras deste tipo de colaborao, cujo modelo tem sido colocado por Richard Stallman e pela Fundao do Software Livre.

Como e porque eu vim a usar Python

Em 1999, o exame do College Boards Advanced Placement (AP) Computer Science foi aplicado em C++ pela primeira vez. Como em muitas escolas secundrias atravs do pas, a deciso de mudar linguagens teve um impacto direto no currculo de cincia da computao na Yorktown High School em Arlington, Virginia, onde leciono. At ento, Pascal era a linguagem de instruo (?) para ambos de nossos cursos de primeiro ano e AP. Mantendo a prtica corrente de dar aos estudantes dois anos de exposio mesma linguagem, tomamos a deciso de mudar para C++ no curso de primeiro ano para o ano letivo de 1997-98 de modo que estaramos no mesmo passo de mudana do College Boards em relao ao curso AP no ano seguinte. Dois anos depois, eu estava convencido que C++ foi uma escolha infeliz para introduzir os alunos em cincia da computao. Ao mesmo tempo em que certamente uma linguagem de programao muito poderosa, tambm uma linguagem extremamente difcil de aprender e de ensinar. Eu me encontrava constantemente lutando com a sintaxe difcil do C++ e as mltiplas maneiras de fazer a mesma coisa, e estava, como resultado, perdendo muitos alunos desnecessariamente. Convencido de que deveria existir uma linguagem de melhor escolha para a nossa classe de primeiro ano, fui procurar por uma alternativa para C++. Eu precisava de uma linguagem que pudesse rodar nas mquinas em nosso laboratrio Linux bem como nas plataformas Windows e Macintosh que a maioria dos alunos tinha em casa. Eu precisava que ela fosse gratuita e disponvel eletronicamente, assim os alunos poderiam utiliz-la em casa independentemente de suas rendas. Eu queria uma linguagem que fosse utilizada por programadores profissionais, e que tivesse uma comunidade de desenvolvimento ativa em torno dela. Ela teria que suportar ambas, programao procedural e orientada a objetos. E, mais importante, deveria ser fcil de aprender e de ensinar. Quando considerei as alternativas tendo em mente aquelas metas, Python sobressaiu-se como melhor candidata para a tarefa. Pedi para um dos talentosos estudantes de Yorktown, Matt Ahrens, para experimentar Python. Em dois meses ele no s aprendeu a linguagem como tambm escreveu uma aplicao chamada pyTicket que possibilitou nossa equipe reportar problemas tecnolgicos pela Web. Eu sabia que Matt no poderia ter finalizado uma aplicao daquele porte em perodo to curto em C++, esta realizao, combinada com a avaliao positiva do Python dada por Matt, sugeriam que Python era a soluo que eu estava procurando.

Encontrando um livro texto


Tendo decidido usar Python em ambas minhas classes introdutrias de cincia da computao do ano seguinte, o problema mais urgente era a falta de um livro texto disponvel. O contedo livre veio em socorro. Anteriormente naquele ano, Richard Stallman tinha me apresentado a Allen Downey. Ambos havamos escrito a Richard expressando interesse em desenvolver contedo educacional livre. Allen j tinha escrito um livro texto para o primeiro ano de cincia da computao, How to Think Like a Computer Scientist . Quando li este livro, soube imediatamente que queria utiliz-lo com a minha classe. Era o texto mais claro e proveitoso em cincia da computao que eu tinha visto. Ele enfatizava o processo de reflexo envolvido em programao em vez de caractersticas de uma linguagem em particular. L-lo fez de mim imediatamente um melhor professor. How to Think Like a Computer Scientist era no s um excelente livro, como tambm fora lanado sob uma licena pblica GNU, o que significava que ele

poderia ser usado livremente e modificado para atender as necessidades de seu usurio. Uma vez que eu havia decidido usar Python, me ocorreu que eu poderia traduzir a verso original do livro de Allen do Java para a nova linguagem. Apesar de no estar capacitado para escrever eu mesmo um livro texto, tendo o livro de Allen a partir do qual trabalhar tornou possvel para mim faz-lo, ao mesmo tempo demonstrando que o modelo de desenvolvimento cooperativo to bem utilizado em software poderia tambm funcionar para contedo educacional. Trabalhar neste livro pelos ltimos dois anos tem sido recompensador para mim e meus alunos, e eles tiveram uma grande parte no processo. A partir do momento em que eu podia fazer mudanas instantneas assim que algum encontrasse um erro ortogrfico ou um trecho difcil, eu os encorajei a procurar por erros no livro, dando a eles pontos de bonificao cada vez que eles fizessem uma sugesto que resultasse em uma mudana no texto. Isto teve o duplo benefcio de encoraj-los a ler o texto mais cuidadosamente e de ter o texto totalmente revisado por seus crticos mais importantes, alunos utilizando-o para aprender cincia da computao. Para a segunda metade do livro, sobre programao orientada a objetos, eu sabia que seria preciso algum com uma maior experincia do que a minha em programao real para faz-lo corretamente. O livro esteve em estado de inacabado pela melhor parte de um ano at que a comunidade do software livre providenciasse mais uma vez os meios necessrios para sua concluso. Eu recebi um e-mail de Chris Meyers mostrando interesse no livro. Chris um programador profissional que comeou a dar um curso de programao no ano anterior usando Python no Lane Community College em Eugene, Oregon. A perspectiva de dar aquele curso ligou Chris ao livro, e ele comeou a ajudar o trabalho imediatamente. Pelo final do ano letivo ele tinha criado um projeto colaborativo em nosso Website em http://www.ibiblio.org/obp chamado Python for Fun e estava trabalhando com alguns dos meus alunos mais avanados como um professor mestre(master teacher), guiando-os alm de onde eu poderia lev-los.

Introduzindo programao com Python


O processo de traduzir e utilizar How to Think Like a Computer Scientist pelos ltimos dois anos tem confirmado a convenincia de Python no ensino de alunos iniciantes. Python simplifica tremendamente os programas exemplo e torna idias importantes de programao mais fceis de ensinar. O primeiro exemplo do texto ilustra este ponto. o tradicional programa Al mundo, o qual na verso C++ do livro se parece com isto: #include <iostream.h> void main() { cout << "Al, mundo." << endl; } Na verso Python, ele se transforma em: print "Al, Mundo!" Mesmo sendo um exemplo trivial, as vantagens do Python saltam aos olhos. O curso de cincia da computao que ministro em Yorktown no tem pr-requisitos, assim, muitos dos alunos, ao ver este programa, esto olhando para o seu primeiro programa. Alguns deles esto indubitavelmente nervosos, por j terem ouvido falar

que programao de computadores difcil de aprender. A verso C++ tem sempre me forado a escolher entre duas opes insatisfatrias: ou explicar os comandos #include, void main(), {, e } e arriscar confundir ou intimidar alguns dos alunos logo assim que iniciam, ou dizer a eles No se preocupem com todas estas coisas agora; falaremos sobre elas mais tarde, e correr o mesmo risco. O objetivo educacional neste ponto do curso introduzir os alunos idia de comando em programao e v-los escrever seu primeiro programa, deste modo introduzindo-os ao ambiente de programao. O programa em Python tem exatamente o que necessrio para conseguir isto, e nada mais. Comparar o texto explicativo do programa em cada verso do livro ilustra ainda mais o que significa para o aluno iniciante. Existem treze pargrafos de explicao do Al, mundo! na verso C++; na verso Python existem apenas dois. Mais importante, os onze pargrafos perdidos no se ocupam das idias chave da programao de computadores, mas com a mincia da sintaxe C++. Vejo a mesma coisa acontecendo atravs de todo o livro. Pargrafos inteiros simplesmente desaparecem da verso do texto para Python porque a sintaxe muito mais clara do Python os torna desnecessrios. Utilizar uma linguagem de to alto nvel como Python, permite ao professor deixar para falar mais tarde sobre os nveis mais baixos, prximos mquina, quando os alunos j tero a experincia necessria para ver com mais sentido os detalhes. Desta maneira ele nos habilita a por em primeiro lugar as primeiras coisas pedagogicamente. Um dos melhores exemplos disto a maneira com que Python lida com variveis. Em C++ uma varivel um nome para um lugar que guarda uma coisa. Variveis tm de ser declaradas com seu tipo pelo menos em parte por que o tamanho do lugar a que se referem precisa ser predeterminado. Assim, a idia de varivel fica amarrada ao hardware da mquina. O conceito poderoso e fundamental de varivel j bastante difcil para o aluno iniciante (em ambas, cincia da computao e lgebra). Bytes e endereos no ajudam neste caso. Em Python uma varivel um nome que se refere a uma coisa. Este um conceito muito mais intuitivo para alunos iniciantes e est muito mais prximo do significado de varivel que eles aprenderam em seus cursos de matemtica. Eu tive muito menos dificuldade em ensinar variveis este ano do que tive no passado, e gastei menos tempo ajudando aos alunos com problemas no uso delas. Um outro exemplo de como Python ajuda no ensino e aprendizagem de programao em sua sintaxe para funo. Meus alunos tm sempre tido grande dificuldade na compreenso de funes. O problema principal gira em torno da diferena entre a definio de uma funo e a chamada de uma funo, e a distino relacionada entre um parmetro e um argumento. Python vem em auxlio com uma sintaxe no apenas curta quanto bela. As definies de funo comeam com def, ento eu simplesmente digo aos meus alunos Quando voc define uma funo, comece com def, seguido do nome da funo que voc est definindo; quando voc chama uma funo, simplesmente chame-a digitando o nome dela. Parmetros vo com definies; argumentos vo nas chamadas. No existem tipos de retorno, tipos de parmetro ou passagem de parmetros por valor ou por referncia no meio do caminho, permitindo-me ensinar funes em menos da metade do tempo que isto me tomava anteriormente, com uma melhor compreenso. A utilizao do Python tem melhorado a efetividade de nosso programa em cincia da computao para todos os estudantes. Eu vejo um nvel geral de sucesso muito mais alto e um nvel mais baixo de frustrao do que experimentei durante os dois anos em que ensinei C++. Eu avano mais rpido com melhores resultados. Mais alunos deixam o curso com a habilidade de criar programas significativos e com uma atitude positiva alcanada pela experincia de transformar suas idias em programas.

Construindo uma comunidade


Tenho recebido e-mails de todo o planeta de pessoas utilizando este livro para aprender ou ensinar programao. Uma comunidade de usurios tem comeado a emergir e muitas pessoas tm contribudo com o projeto enviando seus materiais para o Website cooperativo em: http://www.thinkpython.com Com a publicao do livro em formato impresso, minha expectativa quanto ao crescimento da comunidade de usurios que ela seja contnua e acelerada. O surgimento desta comunidade de usurios e a possibilidade que sugere de colaborao semelhante entre educadores tem sido para mim a parte mais excitante do trabalho neste projeto. Trabalhando juntos, podemos aumentar a qualidade do material disponvel para o nosso uso e poupar tempo valioso. Eu convido voc a se juntar a nossa comunidade e espero ouvir algo de voc. Por favor, escreva para os autores em feedback@thinkpython.com. Jeffrey Elkner Yorktown High School Arlington, Virginia

Lista de contribuidores

Contedo
Introduo Prefcio Lista de contribuidores 1 O caminho do programa (ou A maneira do Programa?) 1.1 A linguagem de programao Python 1.2 O que um programa? 1.3 O que debugging ou debugar? 1.4 Linguagens formais e linguagens naturais 1.5 O primeiro programa 1.6 Glossrio 2 Variveis, expresses e comandos ou instrues 2.1 Valores e tipos 2.2 Variveis 2.3 Nomes de variveis e palavras reservadas 2.4 Instrues ou comandos 2.5 Avaliando expresses 2.6 Operadores e operandos 2.7 Ordem das operaes 2.8 Operaes com strings 2.9 Composio 2.10 Comentrios 2.11 Glossrio 3 Funes 3.1 Chamadas de funo 3.2 Converso entre tipos Coero entre tipos Funes matemticas Composio Adicionando novas funes Definies e utilizao Fluxo de execuo Parmetros e argumentos Variveis e parmetros so locais Diagramas de pilha Funes com resultado Glossrio 4 Condicionais e recursividade O operador mdulo Expresses booleanas Operadores lgicos Execuo condicional Execuo alternativa Cadeia de condicionais Condicionais aninhadas A instruo return Recursividade Diagramas de pilha para funes recursivas Recursividade infinita Entrada pelo teclado Glossrio 5 Funes frutferas

Valores de retorno Desenvolvimento de programas Composio Funes booleanas Mais recursividade Voto de confiana ??? Mais um exemplo Checagem de tipos Glossrio 6 Iterao Atribuio mltipla A instruo while enquanto Tabelas Tabelas bi-dimensionais Encapsulamento e generalizao Mais encapsulameto Variveis locais Mais generalizao Funes Glossrio 7 Strings Um tipo de dado composto Comprimento Traversal e loop for Fatias de strings Comparao de strings Strings so imutveis Uma funo encontre ??? Looping e contagem O mdulo string Classificao de caracteres Glossrio 8 Listas Valores da lista Acessando elementos Comprimento da Lista List membership Listas e loops for Operaes com listas Fatias de lista Listas so mutveis Deleo em listas Objetos e valores Aliasing Clonando listas Parmetros de lista Listas aninhadas Matrizes Strings e listas Glossrio 9 Tuplas Mutabilidade e Tuplas Atribuio de tuplas Tuplas e valores de retorno Nmeros randmicos Contagem Many buckets A single-pass solution

Glossrio 10 Dicionrios Operaes com dicionrios Mtodos com dicionrios Aliasing e cpia Matrizes dispersas Sparse matrices Dicas Inteiros longos Contando letras Glossrio 11 Arquivos e excees Arquivos de texto Writing variables Diretrios Pickling Excees Glossrio 12 Classes e objetos Tipos compostos definidos pelo usurio Atributos Instncias e parmetros Sameness Retngulos Instncias e valores de retorno Objetos so mutveis Cpia Glossrio 13 Classes e funes Tempo Funes puras Modificadores Qual melhor? Desenvolvimento por prottipo x planejamento Generalizao Algoritmos Glossrio 14 Classes e mtodos Caractersticas da orientao a objetos printTime Outro exemplo Um exemplo mais complicado Argumentos opcionais O mtodo de inicializao Revisitando pontos Sobrecarga de operador Polimorfismo Glossrio 15 Conjuntos de objetos Composio Objetos Card Atributos de classe e o mtodo __str__ Comparando cards Decks Imprimindo o deck Shuffling the deck Removing and dealing cards Glossrio 16 Herana

Herana Uma mo de cartas Dealing cards Imprimindo uma mo A classe CardGame A classe OldMaidHand A classe OldMaidGame Glossrio 17 Listas encadeadas (Linked Lists) Referncias embutidas A classe Node Listas e colees Listas e recursividade Listas infinitas O teorema da ambigidade fundamental Modificando listas Wrappers and helpers A classe LinkedList Invariantes Glossrio 18 Pilhas (Stacks) Tipos abstratos de dados (Abstract Data Types) A pilha TAD (DAT) Implementando pilhas com listas Python Pushing and popping Usando uma pilha para calcular notao ps-fixada (postfix) Parsing Calculando notao ps-fixada (postfix) Clientes e provedores Glossrio 19 Filas (Queues) O TAD Fila (The Queue ADT) Filas encadeadas Caractersticas de desempenho Filas encadeadas melhoradas A classe Golfer Glossrio 20 rvores (Trees) Construindo rvores rvores transversais Expression trees Tree traversal Building an expression tree Manipulando erros A rvore animal Glossrio A Debbugging Erros de sintaxe Erros de runtime Erros de semntica B Criando um novo tipo de dado Multiplicao de fraes Adio de fraes O algoritmo de Euclides Comparando fraes Taking if further Glossrio C GNU Free Documentation License

Aplicabilidade e Definies Verbating Copying Cpia em Quantidade Modificaes Combinando Documentos Colees de Documentos Agregao com Trabalhos Independentes Traduo Termination Revises Futuras Desta Licena Adendo: Como Utilizar Esta Licena para Seus Documentos

Captulo 1
O caminho do programa
A meta deste livro ensinar a voc a pensar como um cientista da computao. Esta maneira de pensar combina algumas das melhores caractersticas da matemtica, engenharia e cincias naturais. Como matemticos, os cientistas da computao usam linguagens formais para representar idias (especificamente computaes). Como engenheiros, eles projetam coisas, montando componentes em sistemas e avaliando solues de compromisso entre diferentes alternativas. Como cientistas naturais, eles observam o comportamento de sistemas complexos, formam hipteses e testam previses. A mais importante habilidade para um cientista da computao a soluo de problemas . Solucionar problemas significa a habilidade de formular questes, pensar criativamente sobre solues possveis e expressar clara e precisamente uma soluo. Conforme evolui, o processo de aprendizagem em programao uma excelente oportunidade de praticar as habilidades em soluo de problemas. Este o porque deste captulo ser chamado O caminho do programa. (?) Em um nvel, voc estar aprendendo a programar, uma habilidade til por si mesma. Em outro nvel, voc estar usando a programao como meio para um fim. Conforme formos adiante, este fim se tornar mais claro.

1.1A linguagem de programao Python


A linguagem de programao que voc estar aprendendo Python. Python um exemplo de uma linguagem de programao de alto nvel ; outras linguagens de alto nvel das quais voc pode j ter ouvido falar so C, C++, Perl e Java. Como voc poderia deduzir a partir das palavras linguagem de alto nvel, tambm existem as linguagens de baixo nvel, s vezes chamadas de linguagens de mquina ou linguagem assembler (linguagens de montagem). Dito de maneira simples, computadores s podem executar programas escritos em linguagens de baixo nvel. Deste modo, programas escritos em linguagens de alto nvel tm que ser processados antes que possam rodar. Este processamento extra toma algum tempo, o que uma pequena desvantagem das linguagens de alto nvel. Mas, as vantagens so enormes. Primeiro, muito mais fcil programar em uma linguagem de alto nvel. Programas escritos em uma linguagem de alto nvel levam menos tempo para serem escritos, so mais curtos e fceis de ler, e mais provvel que possam estar corretos. Segundo, as linguagens de alto nvel so portveis , o que significa que elas podem rodar em tipos diferentes de computadores com poucas ou nenhuma modificao. Programas em baixo nvel s podem rodar em um nico tipo de computador e precisam ser re-escritos para rodarem em um de outro tipo. Devido a estas vantagens, quase todos os programas so escritos em linguagens de alto nvel. As de baixo nvel so utilizadas somente para umas poucas aplicaes especializadas. Dois tipos de programas processam linguagens de alto nvel, traduzindo-as em linguagens de baixo nvel: interpretadores e compiladores . Um interpretador l um programa escrito em linguagem de alto nvel e o executa, significando que ele

faz o que o programa diz. Ele processa o programa um pouco de cada vez, alternadamente: ora lendo algumas linhas, ora realizando computaes.

Um compilador l o programa e o traduz completamente antes que o programa comece a rodar. Neste caso, o programa escrito em linguagem de alto nvel chamado de cdigo fonte, e o programa traduzido chamado de cdigo objeto ou executvel . Uma vez que um programa compilado, voc pode execut-lo repetidamente, sem que precise de nova traduo.

Python considerada uma linguagem interpretada porque os programas em Python so executados por um interpretador. Existem duas maneiras de usar o interpretador: no modo de linha de comando e no modo de script. No modo de linha de comando, voc digita programas em Python e o interpretador mostra o resultado: $ python Python 1.5.2 (#1, Feb 1 2000, 16:32:16) Copyright 1991-1995 Stichting Mathematish Centrum, Amsterdam >>> print 1 + 1 2 A primeira linha deste exemplo o comando que inicia o interpretador Python. As duas linhas seguintes so mensagens do interpretador. A terceira linha comea com >>>, que o prompt usado pelo interpretador para indicar que ele est pronto. Ns digitamos print 1 + 1, e o interpretador respondeu 2. Voc tambm pode escrever um programa em um arquivo e usar o interpretador para executar o contedo deste arquivo. Um arquivo como este chamado de script . Por exemplo, ns usamos um editor de texto para criar um arquivo chamado leticia.py com o seguinte contedo: print 1 + 1 Por conveno, arquivos que contenham programas em Python tm nomes que terminam com .py. Para executar o programa, temos de dizer ao interpretador o nome do script: $ python leticia.py 2 Em outros ambientes de desenvolvimento, os detalhes da execuo de programas podem ser diferentes. Tambm, a maioria dos programas so mais interessantes do que este.

A maioria dos exemplos neste livro so executados a partir da linha de comando. Trabalhar com a linha de comando conveniente para o desenvolvimento de programas e para testes, porque voc pode digitar os programas e execut-los imediatamente. Uma vez que voc tenha um programa que funciona, voc pode guard-lo em um script de modo que possa execut-lo ou modific-lo no futuro.

1.2O que um programa?


Um programa uma seqncia de instrues que especificam como executar uma computao. A computao poderia ser algo matemtico, como solucionar um sistema de equaes ou encontrar as razes de uma polinomial, mas tambm poderia ser uma computao simblica, como procurar e substituir um texto em um documento ou (bastante estranhamente) compilar um programa. Os detalhes so diferentes em diferentes linguagens, mas algumas poucas instrues bsicas aparecem em praticamente todas as linguagens: entrada (input): Pegar um dado do teclado, de um arquivo ou algum outro dispositivo. sada (output): Mostrar dados na tela ou enviar dados para um arquivo ou outro dispositivo. matemtica (math): Executar operaes matemticas bsicas como adio e multiplicao. execuo condicional: apropriada de instrues. Checar certas condies e executar a seqncia

repetio: Executar alguma ao repetidamente, usualmente com alguma variao. Acredite se quiser, isto tudo. Qualquer programa que voc j tenha usado, no importa quo complicado seja, construdo sobre instrues que se parecem mais ou menos com estas. Por isso, ns podemos definir programao como o processo de quebrar uma tarefa grande e complexa em sub-tarefas cada vez menores at que as sub-tarefas sejam simples o suficiente para serem executadas com uma destas instrues bsicas. Isto pode parecer um pouco vago, mas ns vamos voltar a este tpico mais tarde quando falarmos sobre algoritmos .

1.3 O

que debugging (depurao)?

Programar um processo complicado e, porque feito por seres humanos, freqentemente conduz a erros. Por razes caprichosas, erros em programas so chamados de bugs e o processo de encontr-los e corrigi-los chamado de debugging . Trs tipos de erros podem acontecer em um programa: erros de sintaxe, erros em tempo de execuo (runtime errors) e erros de semntica. til distingu-los de modo a lhes seguir as pistas mais rapidamente.

1.3.1 Erros de sintaxe


Python somente pode executar um programa se o programa est sintaticamente correto; de outro modo, o processo falha e retorna uma mensagem de erro.

Sintaxe se refere estrutura de um programa e s regras sobre esta estrutura. Por exemplo, em Portugus, uma sentena deve comear com uma letra maiscula e terminar com um ponto. esta sentena contm um erro de sintaxe. Assim como esta Para a maioria dos leitores, uns poucos erros de sintaxe no so um problema significativo, o que o motivo pelo qual podemos ler a poesia de e. e. cummings sem vomitar mensagens de erro. Python no to indulgente. Se existir um nico erro de sintaxe em qualquer lugar em seu programa, Python exibir uma mensagem de erro e desistir (quit), e voc no poder rodar o seu programa. Durante as primeiras semanas da sua carreira como programador, voc provavelmente perder um bocado de tempo procurando erros de sintaxe. Conforme ganhar experincia, entretanto, cometer menos erros e os encontrar mais rapidamente.

1.3.2 Erros em tempo de execuo (runtime errors)


O segundo tipo de erro o erro de runtime, ou erro em tempo de execuo, assim chamado porque no aparece at o momento em que voc rode o programa. Estes erros so tambm conhecidos como excees porque eles usualmente indicam que alguma coisa excepcional (e ruim) aconteceu. Erros de runtime so raros nos programas simples que voc ver nos primeiros captulos, assim levar algum tempo at que voc encontre um.

1.3.3 Erros de semntica


O terceiro tipo de erro o erro de semntica. Se existe um erro de semntica em seu programa, ele vai rodar com sucesso, no sentido de que o computador no ir gerar quaisquer mensagens de erro, mas ele no far a coisa certa. Far alguma outra coisa. Especificamente, ele far aquilo que voc tiver dito a ele que faa. O problema que o programa que voc escreveu, no aquele que voc queria escrever. O significado do programa (sua semntica) est errado(a). Identificar erros semnticos pode ser cheio de manhas (tricky) porque requer que voc trabalhe de trs para frente, olhando a sada do programa e tentando imaginar o que ele est fazendo.

1.3.4 Debugging experimental


Uma das habilidades mais importantes que voc adquirir debuggar. Embora possa ser frustrante, o debugging uma das partes mais intelectualmente ricas, desafiadoras e interessantes da programao. De certa maneira, debugging como um trabalho de detetive. Voc se depara com pistas, e tem que deduzir os processos e eventos que levaram aos resultados que aparecem. Debugging tambm como uma cincia experimental. Uma vez que voc tem uma idia do que est errado, voc modifica o seu programa e tenta de novo. Se a sua hiptese estava correta, ento voc pode predizer o resultado da modificao e fica um passo mais perto de um programa que funciona. Se a sua hiptese estava errada, voc tem que tentar uma nova. Como Sherlock Holmes mostrou, Quando voc tiver eliminado o impossvel, seja l o que restou, ainda que improvvel, deve ser a verdade.(A. Conan Doyle, The Sign of Four ). Para algumas pessoas, programao e debugging so a mesma coisa. Ou seja, programar o processo de gradualmente debuggar um programa at que ele

faa o que voc quer. A idia que voc deveria comear com um programa que faa alguma coisa e ir fazendo pequenas modificaes, debuggando-as conforme avana, de modo que voc tenha sempre um programa que funciona. Por exemplo, Linux um sistema operacional que contm milhares de linhas de cdigo, mas comeou como um programa simples que Linus Torvalds usou para explorar o chip Intel 80386. De acordo com Larry Greenfield, Um dos primeiros projetos de Linus Torvalds foi um programa que deveria alternar entre imprimir AAAA e BBBB. Isto depois evoluiu at o Linux. (The Linux Users Guide Verso Beta 1) Captulos posteriores faro mais sugestes sobre debugging e outras prticas de programao.

1.4 Linguagens

naturais e linguagens formais

Linguagens naturais so as linguagens que as pessoas falam, como o Portugus, o Ingls e o Espanhol. Elas no foram criadas pelas pessoas (muito embora as pessoas tentem colocar alguma ordem nelas); elas evoluram naturalmente. Linguagens formais so linguagens que foram desenvolvidas por pessoas para aplicaes especficas. Por exemplo, a notao que os matemticos usam uma linguagem formal que particularmente boa em denotar relaes entre nmeros e smbolos. Os qumicos usam uma linguagem formal para representar a estrutura qumica das molculas. E, mais importante: Linguagens de programao so linguagens formais que foram desenvolvidas para expressar computaes. As linguagens formais tendem a ter regras estritas quanto sintaxe. Por exemplo, 3 + 3 = 6 uma instruo matemtica sintaticamente correta, mas 3=+6$ no . H2O um nome qumico sintaticamente correto, mas 2Zz no . As regras de sintaxe so de dois tipos, um relacionado aos tokens , outro estrutura. Tokens so os elementos bsicos da linguagem, como as palavras, nmeros, e elementos qumicos. Um dos problemas com 3=+6$ que $ um token no vlido em linguagem matemtica (pelo menos at onde sabemos). Do mesmo modo, 2Zz invlida porque no existe nenhum elemento cuja abreviatura seja Zz. O segundo tipo de erro de sintaxe est relacionado estrutura de uma instruo quer dizer, ao modo como os tokens esto arrumados. A instruo 3=+6$ estruturalmente invlida porque voc no pode colocar um sinal de mais imediatamente aps um sinal de igual. Do mesmo modo, frmulas moleculares devem ter ndices subscritos colocados depois do nome do elemento, no antes. Como exerccio, crie o que parea ser uma sentena bem estruturada em Portugus com tokens irreconhecveis dentro dela. Depois escreva outra sentena com todos os tokens vlidos, mas com uma estrutura invlida. Quando voc l uma sentena em Portugus ou uma instruo em uma linguagem formal, voc tem de imaginar como a estrutura da seqncia (embora, em uma linguagem natural voc faa isso inconscientemente). Este processo chamado parsing (anlise).

Por exemplo, quando voc ouve a sentena, O outro sapato caiu (?), Voc entende que o outro sapato o sujeito e caiu o verbo. Uma vez que voc analisou (parsed) a sentena, voc pode imaginar o seu significado, ou a semntica da sentena. Assumindo que voc saiba o que um sapato e o que significa cair, voc entender as implicaes gerais desta sentena. Muito embora as linguagens formais e as naturais tenham muitas caractersticas em comum tokens, estrutura, sintaxe e semntica existem muitas diferenas: ambigidade: As linguagens naturais esto cheias de ambigidades, as quais so contornadas pelas pessoas pelo uso de informaes contextuais e outras informaes. J as linguagens formais, so desenvolvidas para ser quase ou totalmente desprovidas de ambigidade, o que significa que qualquer instruo tem exatamente um sentido, independente do contexto. redundncia: Para compensar a ambigidade e reduzir mal-entendidos, as linguagens naturais empregam de muita redundncia. Como resultado, elas so em muitos casos prolixas, empregando palavras em excesso. As linguagens formais so menos redundantes e mais concisas. literalidade: As linguagens naturais esto cheias de formas particulares de expresso e metforas. Se eu digo O outro sapato caiu, (precisamos de outro exemplo aqui... ) provavelmente no existe nenhum sapato e nada caindo. As linguagens formais querem dizer exatamente o que dizem. Pessoas que crescem falando uma linguagem natural todo mundo muitas vezes passam por dificuldades no ajustamento a uma linguagem formal. De vrias maneiras, a diferena entre linguagens formais e naturais como a diferena entre poesia e prosa, but more so: Poesia: As palavras so usadas pela sua sonoridade do mesmo modo que por seus sentidos e o poema como um todo cria um efeito de resposta emocional. A ambigidade no apenas freqente, mas na maioria das vezes proposital. Prosa: O sentido literal das palavras mais importante, e a estrutura contribui mais para o significado. A prosa mais fcil de analisar do que a poesia, mas ainda muitas vezes ambgua. Programas: O significado de um programa de computador no-ambguo e literal, e pode ser inteiramente entendido pela anlise de seus tokens e de sua estrutura. Aqui vo algumas sugestes para a leitura de programas (e de outras linguagens formais). Primeiro, lembre-se que linguagens formais so muito mais densas do que linguagens naturais, por isso, toma mais tempo l-las. A estrutura, tambm, muito importante, logo, geralmente no uma boa idia ler de cima para baixo, da esquerda para a direita. Em vez disso, aprenda a parse (separar, analisar, quebrar) o programa dentro da sua cabea, identificando os tokens (signos, parte-signo) e interpretando a estrutura. Finalmente, os detalhes so importantes. Pequenas coisas como erros ortogrficos e m pontuao, com as quais voc pode get away with nas linguagens naturais, podem fazer uma grande diferena em uma linguagem formal.

1.5O primeiro programa


Tradicionalmente, o primeiro programa escrito em uma nova linguagem de programao chamado de Al, Mundo! porque tudo que ele faz apresentar as palavras Al, Mundo!. Em Python, ele se parece com:

print Al, Mundo! isto um exemplo de um comando print, o qual na realidade no imprime nada em papel. Ele apresenta o valor na tela. Neste caso, o resultado so as palavras Al, Mundo! As aspas no programa marcam o comeo e o fim do valor; elas no aparecem no resultado final. Algumas pessoas julgam a qualidade de uma linguagem de programao pela simplicidade do programa Al, Mundo!. Por este padro, Python se saiu to bem quanto era possvel.

1.6Glossrio
soluo de problemas: O processo de formular um problema, encontrar uma soluo e expressar esta soluo. linguagem de alto nvel: Uma linguagem de programao como Python que desenvolvida para ser fcil para seres humanos lerem e escreverem. linguagem de baixo nvel: Uma linguagem de programao que concebida para ser fcil para um computador executar; tambm chamadas de linguagem de mquina ou de linguagem assembly (linguagem de montagem) portabilidade: Propriedade que um programa tem de poder rodar em mais de um tipo de computador. interpretar: Executar um programa escrito em uma linguagem de alto nvel traduzindo-o uma linha de cada vez. compilar: Traduzir todo um programa escrito em uma linguagem de alto nvel para uma de baixo nvel de um s vez, em preparao para uma execuo posterior. cdigo fonte: Um programa em uma linguagem de alto nvel, antes de ter sido compilado. cdigo objeto: A sada do compilador, depois que ele traduziu o programa. executvel: Um outro nome para cdigo objeto que est pronto para ser executado. script: Um programa guardado em um arquivo (usualmente um que ser interpretado). programa: Um conjunto de instrues que especifica uma computao. algoritmo: Um processo geral para soluo de uma certa categoria de problemas. bug: Um erro em um programa. debugging: debugar: O processo de encontrar e remover qualquer um dos trs tipos de erros de programao. sintaxe: A estrutura de um programa.

erro de sintaxe: Um erro em um programa que torna impossvel a anlise parse (logo, tambm impossvel a interpretao). erro em tempo de execuo: ou erro de runtime: Um erro que no ocorre at que o programa seja executado, mas que impede que o programa continue. exceo: Um outro nome para um erro em tempo de execuo ou erro de runtime. erro de semntica: Um erro em um programa que o leva a fazer algo diferente da inteno do programador. semntica: O significado de um programa. linguagem natural: Qualquer uma das linguagens faladas pelas pessoas e que evoluram naturalmente. linguagem formal: Qualquer uma das linguagens desenvolvidas pelas pessoas para propsitos especficos, tais quais a representao de idias matemticas ou programas de computadores; todas as linguagens de programao so linguagens formais. token: Um dos elementos bsicos da estrutura sinttica de um programa, anlogo a uma palavra em uma linguagem natural. parse: Examinar um programa e analisar sua estrutura sinttica. comando print: Uma instruo que leva o interpretador Python a apresentar um valor na tela.

Captulo 2
Variveis, expresses e instrues
2.1 Valores e tipos
Um valor uma das coisas fundamentais como uma letra ou um nmero a qual um programa manipula. Os valores que j vimos at agora foram o 2 (como resultado quando adicionamos 1 + 1), e Al, Mundo!. Estes valores pertencem a tipos diferentes: 2 um inteiro, e Al, Mundo! uma string , assim chamada porque string em ingls, quer dizer cordo, fio, ou srie, fileira, fila, logo, fileira de letras, ou srie de letras. Voc (e o interpretador) podem identificar strings porque elas esto entre aspas. O comando print tambm funciona para inteiros. >>> print 4 4 Se voc no est seguro sobre qual o tipo de um determinado valor, o interpretador pode mostr-lo para voc. >>> type(Al, Mundo!) <type string> >>> type(17) <type int> Nenhuma surpresa: strings pertencem ao tipo string e inteiros pertencem ao tipo int. Menos obviamente, nmeros com um ponto decimal pertencem a um tipo chamado de float, porque estes nmeros so representados em um formato chamado ponto flutuante . >>> type(3.2) <type float> O que dizer de valores como 17 e 3.2? Eles se parecem com nmeros, mas esto entre aspas, como strings. >>> type(17) <type string> >>> type(3.2) <type string> Eles so strings. Quando voc digita um valor inteiro maior, voc pode ser tentado a usar pontos entre grupos de trs dgitos, como em 1.000.000 (Note que em ingls, se escreve 1,000,000). Este no um inteiro vlido em Python, mas uma expresso vlida: >>> print 1,000,000 1 0 0

Bom, no o que espervamos!! Python interpreta 1,000,000 como uma lista de trs inteiros separados por vrgula, os quais ele printa consecutivamente. Este o primeiro exemplo que vemos de um erro semntico: o cdigo roda sem produzir uma mensagem de erro, mas ele no faz a coisa certa.

2.2 Variveis
Uma das mais poderosas caractersticas de uma linguagem de programao a habilidade de manipular variveis . Uma varivel um nome que se refere a um valor. A instruo de atribuio cria novas variveis e d a elas valores: >>> mensagem = E a, Doutor? >>> n = 17 >>> pi = 3.14159 Este exemplo faz trs atribuies de valores. O primeiro atribui a string E a, Doutor? a uma nova varivel chamada mensagem. A segunda d o valor inteiro 17 a n, e a terceira coloca o nmero em ponto flutuante 3.14159 na varivel chamada pi. Uma maneira comum de representar variveis no papel escrever o nome dela com uma seta apontando para o valor da varivel. Este tipo de figura chamado de diagrama de estado porque mostra em que estado cada varivel est (pense nisso como o estado de esprito da varivel). O seguinte diagrama mostra o resultado das instrues de atribuio:

O comando print tambm funciona com variveis. >>> print mensagem E a, Doutor? >>> print n 17 >>> print pi 3.14159 Em cada um dos casos, o resultado o valor da varivel. Variveis tambm tm tipo; de novo, podemos perguntar ao interpretador quais so eles. >>> type(mensagem) <type string> >>> type(n) <type int> >>> type(pi) <type float>

O tipo de uma varivel o tipo do valor ao qual ela se refere.

2.3 Nomes de variveis e palavras reservadas


Os programadores geralmente escolhem nomes significativos para suas variveis eles documentam para o que a varivel usada. Nomes de variveis podem ser arbitrariamente longos. Eles podem conter tanto letras quanto nmeros, mas tm de comear com uma letra. Embora seja vlida a utilizao de letras maisculas, por conveno no devemos us-las. Se voc o fizer, lembre-se que maisculas e minsculas so diferentes. Bruno e bruno so variveis diferentes. O caracter para sublinhado ( _ ) pode aparecer em um nome. Ele muito utilizado em nomes com mltiplas palavras, tal como em meu_nome ou preo_do_cha_na_china. Se voc der a uma varivel um nome invlido, voc ter um erro de sintaxe: >>> 76trombones = grande parada SyntaxError: invalid syntax >>> muito$ = 1000000 SyntaxError: invalid syntax >>> class = Ciencias da Computacao 101 SyntaxError: invalid syntax 76trombones invalida porque no comea com uma letra. muito$ invlida porque contm um caractere ilegal, o cifro. Mas o que est errado com class? It turns out que class uma das palavras reservadas em Python. Palavras reservadas definem as regras e a estrutura da linguagem, e elas no podem ser usadas como nomes de variveis. Python tem vinte e oito palavras reservadas: and assert break class continue def del elif else except exec finally for from global if import in is lambda not or pass print raise return try while

Voc pode precisar manter esta lista mo. Se o interpretador acusar erro sobre um de seus nomes de varivel e voc no souber porque, veja se o nome est na lista.

2.4 Instrues ou comandos


Um comando uma instruo que o interpretador Python pode executar. Vimos at agora dois tipos de comandos: de impresso (print) e de atribuio. Quando voc digita uma instruo na linha de comando, O Python o executa e mostra o resultado, se houver um. O resultado de um comando de impresso print um valor. Comandos de atribuio no produzem um resultado. Um script usualmente contm uma seqncia de comandos. Se houver mais de um comando, o resultado aparecer um de cada vez, conforme cada comando seja executado.

Por exemplo, o script print 1 x = 2 print 2 produz a sada 1 2 de novo: o comando de atribuio no produz sada.

2.5 Avaliando expresses


Uma expresso uma combinao de valores, variveis e operadores. Se voc digitar uma expresso na linha de comando, o interpretador avalia e exibe o resultado: >>> 1 + 1 2 Embora expresses contenham valores, variveis e operadores, nem toda expresso contm todos estes elementos. Um valor por si mesmo considerado uma expresso, do mesmo modo que uma varivel. >>> 17 17 >>> x x Confusamente, avaliar uma expresso no exatamente a mesma coisa que imprimir um valor. >>> mensagem = E a, Doutor? >>> mensagem E a, Doutor? >>> print mensagem E a, Doutor? Quando Python exibe o valor de uma expresso, usa o mesmo formato que voc deveria usar para entrar com o valor. No caso de strings, isso significa que as aspas so includas. Mas o comando print imprime o valor da expresso, o qual, neste caso o contedo da string. 17 3.2 Al, Mundo! 1 + 1 no produzem qualquer sada. Como voc mudaria o script para exibir os valores destas quatro expresses?

2.6 Operadores e operandos


Operadores so smbolos especiais que representam computaes como adio e multiplicao. Os valores que o operador usa so chamados operandos .

Todas as expresses seguintes so vlidas em Python, cujos significados so mais ou menos claros: 20+32 hora-1 hora*60+minuto minuto/60 5**2 (5+9)*(15-7)

Os smbolos +, -, / e o uso de parnteses para agrupamento, tm o mesmo significado em Python que tm em matemtica. O asterisco (*) o smbolo para multiplicao e ** o smbolo para potenciao. Quando um nome de varivel aparece no lugar de um operando, ela substituda por seu valor antes da operao ser executada. Adio, subtrao, multiplicao e potenciao todas fazem o que voc espera delas, mas voc pode ser surpreendido pela diviso. A operao seguinte tem um resultado inesperado: >>> minuto = 59 >>> minuto/60 0 O valor de minuto 59 e em aritmtica convencional 59 dividido por 60 0,98333, no 0. A razo para a discrepncia e que Python est realizando uma diviso inteira. Quando ambos operandos so inteiros, o resultado tem de ser tambm um inteiro e, por conveno, a diviso inteira sempre arredonda para baixo, mesmo em casos como este em que o inteiro seguinte est muito prximo. >>> minuto*100/60 98 De novo o resultado arredondado para baixo, mas pelo menos agora a resposta aproximadamente correta. A alternativa usar a diviso em ponto flutuante, o que veremos no captulo 3.

2.7 Ordem dos operadores


Quando mais de um operador aparece em uma expresso, a ordem de avaliao depende das regras de precedncia . Python segue as mesmas regras de precedncia para seus operadores matemticos que a matemtica. O acrnimo PEMDAS uma maneira prtica de lembrar a ordem das operaes:

Parnteses tm a mais alta precedncia e podem ser usados para forar uma
expresso a ser avaliada na ordem que voc quiser. J que expresses entre parnteses so avaliadas primeiro, 2 * (3-1) 4, e (1+1)**(5-2) 8. Voc tambm pode usar parnteses para tornar uma expresso mais fcil de ler, como em (minuto * 100) / 60, ainda que isso no altere o resultado.

Exponenciao ou Potenciao tem a prxima precedncia mais alta, assim


2**1+1 3 e no 4, e 3*1**3 3 e no 27.

Multiplicao e Diviso tm a mesma precedncia, a qual mais alta do que a


da Adio e da Subtrao, as quais tambm tm a mesma precedncia. Assim 2*3-1 d 5 em vez de 4, e 2/3-1 -1, no 1 (lembre-se de que na diviso inteira, 2/3=0).

Operadores com a mesma precedncia so avaliados da esquerda para a direita.


Assim, na expresso minuto*100/60, a multiplicao acontece primeiro, resultando em 5900/60, o que se transforma produzindo 98. Se as operaes tivessem sido avaliadas da direita para a esquerda, o resultado poderia ter sido 59*1, que 59, que est errado.

2.8 Operaes com strings


De maneira geral, voc no pode executar operaes matemticas em strings, ainda que as strings se paream com nmeros. O que segue invlido (assumindo que mensagem do tipo string): mensagem-1 Al/123 mensagem*Al 15+2

Interessante o operador +, que funciona com strings, embora ele no faa exatamente o que voc poderia esperar. Para strings, o operador + representa concatenao , que significa juntar os dois operandos ligando-os pelos extremos. Por exemplo: fruta = banana bakedGood = nut bread print fruta + bakedGood A sada deste programa banana nut bread. O espao antes da palavra nut parte da string e necessrio para produzir o espao entre as strings concatenadas. O operador * tambm funciona com strings; ele realiza repetio. Por exemplo, Legal*3 LegalLegaLegal. Um dos operadores tem que ser uma string; o outro tem que ser um inteiro.

2.9 Composio
At agora, vimos os elementos de um programa variveis, expresses, e instrues ou comandos isoladamente, sem mencionar como combin-los. Uma das caractersticas mais prticas das linguagens de programao a possibilidade de pegar pequenos blocos e combin-los numa composio . Por exemplo, ns sabemos como somar nmeros e sabemos como print-los; acontece que podemos fazer as duas coisas ao mesmo tempo: >>> print 17 + 3 20 Na realidade, a soma tem que acontecer antes da impresso, assim, as aes no esto na realidade acontecendo ao mesmo tempo. O ponto que qualquer expresso envolvendo nmeros, strings, e variveis pode ser usada dentro de um comando print. Voc j tinha visto um exemplo como este: print Nmero de minutos desde a meia-noite: , hora*60+minuto Esta habilidade pode no parecer muito impressionante agora, mas voc ver outros exemplos aonde a composio torna possvel expressar computaes complexas de modo limpo de conciso. Cuidado: Existem limites quanto ao lugar onde voc pode usar certos tipos de expresso. Por exemplo, o lado esquerdo de um comando de atribuio tem que ser

um nome de varivel , e no uma expresso. Assim, o seguinte no vlido: minuto+1 = hora.

2.10 Comentrios
Conforme se tornam maiores e mais complicados os programas tornam-se mais difceis de ler. As linguagens formais so densas e muitas vezes difcil olhar para um pedao de cdigo e compreender o que ele est fazendo ou porque. Por esta razo, uma boa idia adicionar notas aos seus programas para explicar em linguagem natural o que o programa est fazendo. Estas notas so chamadas de comentrios , e so marcadas com o smbolo #: # calcula a porcentagem de hora que j passou porcentagem = (minuto * 100) / 60 Neste caso, o comentrio aparece numa linha s dele. Voc tambm pode colocar comentrios no fim de uma linha: porcentagem = (minuto * 100) / 60 #ateno: diviso inteira Tudo, do # at o fim da linha ser ignorado no tem nenhum efeito sobre o programa. A mensagem entendida pelo programador ou por futuros programadores que poderiam usar este cdigo. Neste caso, o comentrio relembra ao leitor sobre o comportamento sempre surpreendente da diviso inteira.

2.11 Glossrio
valor: Um nmero ou uma string (ou outra coisa a ser nomeada mais tarde) que pode ser armazenado numa varivel ou calculado em uma expresso. tipo (type): Um conjunto de valores. O tipo de um valor determina como ele pode ser usado em expresses. At agora, os tipos que voc viu foram inteiros (tipo int), nmeros em ponto flutuante (tipo float) e strings (tipo string). ponto flutuante: Um formato para representao de nmeros com partes fracionrias. varivel: Um nome que se refere a um valor. instruo ou comando (statement): Uma seo de cdigo que representa um comando ou ao. At aqui, as instrues que voc viu foram atribuies e comandos de impresso (print). atribuio: Uma instruo ou comando que atribui um valor a uma varivel. diagrama de estado: Uma representao grfica de um conjunto de variveis e dos valores aos quais elas se referem. palavra reservada: Uma palavra reservada usada pelo compilador para analisar (parse) um programa; voc no pode usar palavras reservadas como if, def e while como nomes de variveis. operador: Um smbolo especial que representa um clculo simples como adio, multiplicao, ou concatenao de string. operando: Um dos valores com os quais um operador opera.

expresso: Uma combinao de variveis, operadores e valores que representam um nico valor de resultado. avaliar (evaluate): Simplificar uma expresso pela realizao das operaes de modo a produzir um nico valor. diviso inteira: Uma operao que divide um inteiro por outro e produz um inteiro. A diviso inteira produz somente o nmero inteiro de vezes que o numerador divisvel pelo denominador e descarta o que quer que reste. regras de precedncia: O conjunto de normas que governam o ordem pela qual as expresses envolvendo mltiplos operadores e operandos so avaliadas. concatenar: Juntar dois operandos ponta com ponta. composio: A habilidade de combinar expresses simples e instrues em instrues compostas e expresses de maneira a representar concisamente computaes complexas. comentrio: Informao em um programa que faz sentido para outros programadores (ou qualquer pessoa lendo o cdigo fonte) e no tem efeitos na execuo do programa.

Captulo 3
Funes
3.1 Chamadas de funes
Voc j viu um exemplo de uma chamada de funo: >>> type(32) <type string> O nome da funo type, e ela exibe o tipo de valor de uma varivel. O valor ou varivel, o qual chamado de argumento da funo, tem que vir entre parnteses. comum se dizer que uma funo recebe um valor e retorna um resultado. O resultado chamado de valor de retorno . Em vez de imprimir um valor de retorno, podemos atribu-lo a uma varivel: >>> beth = type(32) >>> print beth <type string> Como outro exemplo, a funo id recebe um valor ou uma varivel e retorna um inteiro que atua como um identificador nico para aquele valor: >>> id(3) 134882108 >>> beth = 3 >>> id(Beth) 134882108 Todo valor tem um id, que um nmero nico relacionado ao local onde ele est guardado na memria do computador. O id de uma varivel o id de um valor a qual ela se refere.

3.2 Converso entre tipos


Pytho prov uma coleo de funes nativas que convertem valores de um tipo em outro. A funo int recebe um valor e o converte para inteiro, se possvel, ou, se no, reclama: >>> int(32) 32 >>> int(Al) ValueError: invalid literal for int() : Al int tambm pode converter valores em ponto flutuante para inteiro, mas lembre-se que isso trunca a parte fracionria: >>> int(3.99999) 3 >>> int(-2.3) -2

A funo float converte inteiros e strings em nmeros em ponto flutuante: >>> float(32) 32.0 >>> float(3.14159) 3.14159 Finalmente, a funo str converte para o tipo string: >>> str(32) 32 >>> str(3.14149 3.14149 Pode parecer curioso que Python distingua o valor inteiro 1 do valor em ponto flutuante 1.0. Eles podem representar o mesmo nmero, mas pertencem a tipos diferentes. A razo que eles so representados de modo diferente dentro do computador.

3.3 Coero entre tipos


Agora que podemos converter entre tipos, temos outra maneira de lidar com a diviso inteira. Voltando ao exemplo do captulo anterior, suponha que queiramos calcular a frao de hora que j passou. A expresso mais bvia, minuto / 60, faz aritmtica inteira, assim o resultado sempre 0, mesmo aos 59 minutos passados da hora. Uma soluo converter minuto para ponto flutuante e fazer a diviso em ponto flutuante: >>> minuto = 59 >>> float(minuto) / 60 0.983333333333 Alternativamente, podemos tirar vantagem das regras de converso automtica entre tipos, a qual e chamada que coero de tipos . Para os operadores matemticos, se qualquer operando for um float, ou outros so automaticamente convertidos para float: >>> minuto = 59 >>> minuto / 60.0 0.983333333333 Fazendo o denominador um float, foramos Python a fazer a diviso em ponto flutuante.

3.4 Funes matemticas


Em matemtica, voc provavelmente j viu funes como seno (sin) e log, e voc aprendeu a resolver expresses como sin(pi/2) e log(1/x). Primeiro voc resolve e expresso entre parnteses (o argumento). Por exemplo, pi/2 aproximadamente 1,571, e 1/x 0.1 (se x for 10,0). A voc avalia a funo propriamente dita, seja procurando numa tabela ou realizando vrios clculos. O sin de 1,571 1 e o log de 0,1 -1 (assumindo que log indica o logaritmo na base 10).

Este processo pode ser aplicado repetidamente para avaliar expresses mais complicadas, como log(1/sin(pi/2)). Primeiro voc avalia o argumento na funo mais interna, depois voc avalia a funo e assim por diante. Python tem um mdulo matemtico que prov a maioria das funes matemticas mais familiares. Um mdulo um arquivo que contm uma coleo de funes relacionadas agrupadas juntas. Antes de podermos usar as funes contidas em um mdulo, temos de import-lo: >>> import math Para chamar uma das funes, temos que especificar o nome do mdulo e o nome da funo, separados por um ponto. Este formato chamado de notao de ponto. >>> decibel = math.log10(17.0) >>> angulo = 1.5 >>> altura = math.sin(angulo) A primeira instruo atribui a decibel o logaritmo de 17 na base 10. Existe tambm uma funo chamada log que pega o logaritmo na base e. A terceira instruo encontra o seno do valor da varivel angulo. sin e as outras funes trigonomtricas (cos, tan, etc.) recebem argumentos em radianos. Para converter de graus em radianos, divida por 360 e multiplique por 2*pi. Por exemplo, para encontrar o seno de 45 graus, primeiro calcule o ngulo em radianos e depois ache o seno: >>> graus = 45 >>> angulo = graus * 2 * math.pi / 360.0 >>> math.sin(angulo) 0.707106781187 A constante pi tambm e parte do mdulo math. Se voc sabe geometria, voc pode checar o resultado anterior comparando-o com a raiz quadrada de dois dividido por dois: >>> math.sqrt(2) / 2.0 0.707106781187

3.5 Composio
Do mesmo modo como nas funes matemticas, As funes do Python podem ser compostas, significando que voc pode usar uma expresso como parte de outra. Por exemplo, voc pode usar qualquer expresso como um argumento para uma funo: >>> x = math.cos(angulo + pi/2) Esta instruo toma o valor de pi, o divide por 2, e soma o resultado ao valor de angulo. A soma ento passada como um argumento para a funo cos. Voc tambm pode pegar o resultado de uma funo e pass-lo como um argumento para outra: >>> x = math.exp(math.log(10.0))

Esta instruo encontra o logaritmo base e de 10 e ento eleva e quela potncia. O resultado atribudo a x.

3.6 Adicionando novas funes


At aqui, temos utilizado somente as funes que vem com Python, mas tambm possvel adicionar novas funes. Criar novas funes para resolver seus prprios problemas uma das coisas mais teis de uma linguagem de programao de propsito geral. No contexto de programao, uma funo uma seqncia nomeada de instrues ou comandos que realizam uma operao desejada. Esta operao especificada numa definio de funo . As funes que temos usado at agora foram definidas para ns, e estas definies tm estado escondidas. Esta uma coisa boa, porque nos permite usar as funes sem que nos preocupemos com os detalhes de suas definies. A sintaxe para uma definio de funo : def NOME( LISTA DE PARAMETROS ) : COMANDOS Voc pode usar qualquer nome que queira para as funes que voc criar, exceto que voc no pode usar um nome que uma palavra reservada em Python. A lista de parmetros especifica que informao, se houver alguma, voc tem que fornecer para poder usar a nova funo. Pode existir qualquer nmero de comandos dentro de uma funo, mas eles tem que ser endentados a partir da margem esquerda. Nos exemplos deste livro, usaremos uma endentao de dois espaos. As primeiras funes que escreveremos no tero parmetros, assim a sintaxe se parecer com esta: def novaLinha(): print Esta funo chamada de novaLinha. Os parnteses vazios indicam que ela no tem parmetros. Ela contm apenas um nico comando, o qual gera como sada um caractere de nova linha. (Isto o que acontece quando voc usa um comando print sem qualquer argumento.). A sintaxe para a chamada desta nova funo a mesma sintaxe para as funes nativas: print Primeira Linha. novaLinha() print Segunda Linha. A sada deste programa : Primeira Linha. Segunda Linha. Repare o espao extra entre as duas linhas. E se quisssemos mais espao entre as linhas? Poderamos chamar a mesma funo repetidamente:

print Primeira Linha. novaLinha() novaLinha() novaLinha() print Segunda Linha. Ou poderamos escrever uma nova funo chamada tresLinhas que produzisse trs novas linhas: def tresLinhas() : novaLinha() novaLinha() novaLinha() print Primeira Linha. tresLinhas() print Segunda Linha. Esta funo contm trs comandos, todos eles endentados em dois espaos. J que o prximo comando no est endentado, Python reconhece que ele no faz parte da funo. Voc deve tomar nota de algumas coisas sobre este programa: 1. Voc pode chamar o mesmo procedimento repetidamente. De fato, muito comum e til faz-lo.

2. Voc pode ter uma funo chamando outra funo; neste caso tresLinhas
chama novaLinha. At agora, pode no estar claro de que valeria o esforo de se criar todas estas novas funes. Presentemente existe um monte de razes, mas este exemplo demonstra duas: Criar uma nova funo d a voc a oportunidade de colocar um nome em um grupo de comandos. As funes podem simplificar um programa ao ocultar uma computao complexa por trs de um simples comando e pelo uso do Portugus em vez de algum cdigo misterioso.

Criar uma nova funo pode fazer um programa menor ao eliminar cdigo
repetido. Por exemplo, um atalho para de maneira curta printar nove novas linhas consecutivas chamar tresLinhas trs vezes. Como exerccio, escreva uma funo chamada noveLinhas que use tresLinhas para imprimir nove linhas em branco. Como voc poderia imprimir vinte e sete novas linhas?

3.7 Definies e uso


Colocando juntos os fragmentos de cdigo da Seo 3.6, o programa completo se parece com isto: def novaLinha() : print def tresLinhas() : novaLinha()

novaLinha() novaLinha() print Primeira Linha. tresLinhas() print Segunda Linha. Este programa contm duas definies de funes: novaLinha e tresLinhas. Definies de funes so executadas como quaisquer outros comandos, mas o efeito criar a nova funo. Os comando dentro da definio da funo no so executados at que a funo seja chamada, logo a definio da funo no gera nenhuma sada. Como voc poderia esperar, voc tem que criar uma funo antes de poder execut-la. Em outras palavras, a definio da funo tem que ser executada antes que ela seja chamada pela primeira vez. Como exerccio, mova as ltimas trs linhas deste programa para o topo, de modo que a chamada da funo aparea antes das definies. Rode o programa e veja que mensagem de erro voc ter. Como outro exerccio, comece com a verso que funciona do programa e mova a definio de novaLinha para depois da definio de tresLinhas. O que acontece quando voc roda este programa?

3.8 Fluxo de execuo


Para se assegurar que uma funo est definida antes de seu primeiro uso, voc tem que saber a ordem em que os comandos so executados, o que chamado de fluxo de execuo . A execuo sempre comea com o primeiro comando do programa. Os comandos so executados um de cada vez, pela ordem, de cima para baixo. As definies de funo no alteram o fluxo de execuo do programa, mas lembrese que comandos dentro da funo no so executados at a funo ser chamada. Embora no seja comum, voc pode definir uma funo dentro de outra. Neste caso, a definio mais interna no executada at que a funo mais externa seja chamada. Chamadas de funo so como um desvio no fluxo de execuo. Em vez de ir para o prximo comando, o fluxo salta para a primeira linha da funo chamada, executa todos os comandos l e ento volta atrs para retomar de onde havia deixado. Isto soa bastante simples, at que voc se lembra que uma funo pode chamar outra. Enquanto estiver no meio de uma funo, o programa poderia ter de executar os comandos em uma outra funo. Mas enquanto estivesse executando esta nova funo, o programa poderia ter de executar ainda outra funo! Afortunadamente, Python adepto de manter a trilha de onde est, assim cada vez que uma funo se completa, o programa retoma de onde tinha deixado na funo que a chamou. Quando chega ao fim do programa, ele termina. Qual a moral desta histria srdida? Quando voc ler um programa, no o leia de cima para baixo. Em vez disso, siga o fluxo de execuo.

3.9 Parmetros e argumentos

Algumas das funes nativas que voc j usou requerem argumentos, aqueles valores que controlam como a funo faz seu trabalho. Por exemplo, se voc quer achar o seno de um nmero, voc tem que indicar qual nmero . Deste modo, sin recebe um valor numrico como um argumento. Algumas funes recebem mais de um argumento. Por exemplo, pow recebe dois argumentos, a base e o expoente. Dentro da funo, os valores que lhe so passados so atribudos a variveis chamadas parmetros . Aqui est um exemplo de uma funo definida pelo usurio que recebe um parmetro: def imprimeDobrado(bruno): print bruno, bruno Esta funo recebe um nico argumento e o atribui a um parmetro chamado bruno. O valor do parmetro (neste ponto ns no temos qualquer idia de qual ser) impresso duas vezes, seguido de uma nova linha. O nome bruno foi escolhido para sugerir aqui que o nome que voc d a um parmetro problema seu, mas em geral, voc deve escolher algo mais ilustrativo do que bruno. A funo imprimeDobrado funciona para qualquer tipo que possa ser impresso: >>> imprimeDoobrado(Spam) Spam Spam >>> imprimeDobrado(5) 5 5 >>> imprimeDobrado(3.14159) 3.14159 3.14159 Na primeira chamada da funo, o argumento uma string. Na segunda, um inteiro. Na terceira um float. As mesmas regras de composio que se aplicam funes nativas tambm se aplicam s funes definidas pelo usurio, assim podemos usar qualquer tipo de expresso como um argumento para imprimeDobrado: >>> imprimeDobrado(Span*4) SpamSpamSpamSpam SpamSpamSpamSpam >>> imprimeDobrado(math.cos(math.pi)) -1.0 -1.0 Como acontece normalmente, a expresso e avaliada antes da execuo da funo, assim imprimeDobrado imprime SpamSpamSpamSpam SpamSpamSpamSpam em vez de Spam*4 Spam*4. Como exerccio, escreva um chamada a imprimeDobrado que imprima Spam*4 Spam*4. Dica: strings podem ser colocadas tanto entre aspas simples quanto duplas, e o tipo de aspas que no for usado para envolver a string pode ser usado dentro da string como parte dela. Ns tambm podemos usar uma varivel como argumento: >>> miguel = Erico, a metade de uma abelha. >>> imprimeDobrado(miguel) Erico, a metade de uma abelha. Erico, a metade de uma abelha.

Repare numa coisa muito importante aqui. O nome da varivel que passamos como um argumento (miguel) no tem nada a ver com o nome do parmetro (bruce). No importa de que modo o valor foi chamado de onde veio (do chamador); aqui, em imprimeDobrado, chamamos a todo mundo de bruce.

3.10 Variveis e parmetros so locais


Quando voc cria uma varivel local dentro de uma funo, ela s existe dentro da funo e voc no pode us-la fora de l. Por exemplo: def concatDupla(parte1, parte2) concat = parte1 + parte2 imprimeDobrado(concat) Esta funo recebe dois argumentos, concatena-os, e ento imprime o resultado duas vezes. Podemos chamar a funo com duas strings: >>> >>> >>> Pie canto1 = Pie Jesu domine, canto2 = dona eis requiem. concatDupla(canto1, canto2) Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.

Quando a funo concatDupla termina, a varivel concat destruda. Se tentarmos imprimi-la, teremos um erro: >>> print concat NameError: concat Parmetros so sempre locais. Por exemplo, fora da funo imprimeDobrado, no existe alguma coisa chamada bruno. Se voc tentar utiliz-la, Python vai reclamar.

3.11 Diagramas de pilha


Para manter a pista de que variveis podem ser usadas aonde, s vezes til desenhar um diagrama de pilha. Como os diagramas de estado, diagramas de pilha mostram o valor de cada varivel, mas eles tambm mostram a funo a qual cada varivel pertence. Cada funo representada por um frame (quadro). Um frame uma caixa com o nome de uma funo ao lado dela e os parmetros e variveis da funo dentro dela. O diagrama de pilha para o exemplo anterior tem a seguinte aparncia:

A ordem da pilha mostra o fluxo de execuo. imprimeDobrado foi chamado por concatDupla, e concatDupla foi chamado por __main__ (principal), que um nome especial para a funo mais no topo. Quando voc cria uma varivel fora de qualquer funo, ela pertence __main__. Cada parmetro se refere ao mesmo valor como seu argumento correspondente. Assim, parte1 tem o mesmo valor de canto1, parte2 tem o mesmo valor de canto2 e bruce tem o mesmo valor de concat. Se um erro acontece durante uma chamada de funo, Python imprime o nome da funo, e o nome da funo que a chamou e o nome da funo que chamou a que chamou, por todos os caminhos voltando a __main__. Por exemplo, se tentssemos acessar concat de dentro de imprimeDobrado, teramos um NameError: Traceback (innermost last): File "teste.py", line 13, in __main__ concatDupla(canto1, canto2) File "teste.py", line 5, in concatDupla imprimeDobrado(concat) File "teste.py", line 9, in imprimeDobrado print concat NameError: concat Esta lista de funes chamada de um traceback . Ele mostra para voc em qual arquivo de programa o erro ocorreu, e em que linha, e quais funes estavam sendo executadas naquele momento. Ele tambm mostra a linha de cdigo que causou o erro. Note a similaridade entre o traceback e o diagrama de pilha. Isto no uma coincidncia.

3.12 Funes com resultados


Voc pode ter notado por ora que algumas das funes que usamos, tais quais as funes matemticas, produzem resultados. Outras funes, como novaLinha, executam uma ao, mas no retornam um valor. O que levanta algumas questes:

1. O que acontece se voc chama uma funo e no faz nada com o resultado
(por exemplo, no atribui o resultado a uma varivel ou o usa como parte de uma expresso maior)?

2. O que acontece se voc usa uma funo que no produz resultado em uma
expresso tal como novaLinha() + 7?

3. Voc pode escrever funes que produzem resultados, ou est preso a


funes como novaLinha e imprimeDobrado? A resposta para a terceira questo sim e faremos isso no Captulo 5. Como exerccio, responda as outras duas questes experimentandoas. Quando voc tiver uma dvida sobre o que vlido ou invlido em Python, uma boa maneira de encontrar a resposta perguntar ao interpretador.

3.13 Glossrio
chamada de funo: Um comando que executa uma funo. Consistindo no nome da funo seguido de uma lista de argumentos entre parnteses. argumento: Um valor fornecido a uma funo quando a funo chamada. Este valor atribudo ao parmetro correspondente na funo. valor de retorno: O resultado de uma funo. Se uma chamada de funo usada como uma expresso, o valor de retorno o valor da expresso. converso entre tipos: Um comando explcito que pega um valor de um tipo e converte em um valor correspondente de outro tipo. coero entre tipos: Uma converso entre tipos que acontece automaticamente de acordo com as regras de coero do Python. mdulo: Um arquivo que contm uma coleo de funes e classes relacionadas. notao de ponto: A sintaxe para a chamada de uma funo em outro mdulo, especificando o nome do mdulo seguido por um ponto, seguido do nome da funo. funo: Uma seqncia de comandos reconhecida por um nome e que realiza alguma operao til. As funes podem ou no receber parmetros e podem ou no produzir um resultado. definio de funo: Um comando que cria uma nova funo, especificando seu nome, parmetros e os comandos que ela executa. fluxo de execuo: A ordem pela qual os comandos so executados enquanto um programa roda. parmetro: Um nome usado dentro de uma funo para fazer referncia ao valor passado como um argumento. varivel local: Uma varivel definida dentro de uma funo. Uma varivel local s pode ser usada dentro de funo em que foi criada. diagrama de pilha: Uma representao grfica de uma pilha de funes, suas variveis e os valores aos quais se referem.

frame (quadro): Um quadro ou caixa em um diagrama de pilha que representa uma chamada de funo. Ele contm as variveis locais e parmetros da funo. traceback: Uma lista de funes em execuo, impressa quando ocorre um erro de runtime (erro em tempo de execuo).

Captulo 4
Condicionais e recursividade
4.1 O operador mdulo
O operador mdulo trabalha com inteiros (e expresses que tm inteiros como resultado) e produz o resto da diviso do primeiro pelo segundo. Em Python, o operador mdulo e um smbolo de porcentagem (%). A sintaxe a mesma que a de outros operadores: >>> >>> 2 >>> >>> 1 quociente = 7 / 3 print quociente resto = 7 % 3 print resto

Ento, 7 dividido por 3 2 e o resto 1. O operador mdulo se revela surpreendentemente til. Por exemplo, voc pode checar se um nmero divisvel por outro se x % y d zero, ento x divisvel por y. Voc tambm pode extrai o algarismo ou algarismos mais direita de um nmero. Por exemplo, x % 10 resulta o algarismo mais direita de x (na base 10). Similarmente, x % 100 resulta nos dois dgitos mais direita.

4.2 Expresses booleanas


Uma expresso booleana uma expresso que verdadeira (true) ou falsa (false). Em Python, uma expresso que verdadeira tem o valor 1, e uma expresso que falsa tem o valor 0. O operador == compara dois valores e produz uma expresso booleana: >>> 5 == 5 1 >>> 5 == 6 0 No primeiro comando, os dois operadores so iguais, ento a expresso avalia como 1 (verdadeiro ou true); no segundo comando, 5 no igual a 6, ento temos 0 (falso ou false). O operador == um dos operadores de comparao ; os outros so: x x x x x != y > y < y >= y <= y # x no igual a y (ou diferente) # x maior que y # x menor que y # x maior ou igual a y # x menor ou igual a y

Embora estes operadores provavelmente sejam familiares a voc, Os smbolos em Python so diferentes dos smbolos da matemtica. Um erro comum usar um sinal de igual sozinho (=) em vez de um duplo (==). Lembre-se que = um operador de atribuio e == um operador de comparao. Tambm no existem coisas como =< ou =>.

4.3 Operadores lgicos


Existem trs operadores lgicos: and, or e not (e, ou e no). A semntica (significado) destes operadores similar aos seus significados em Portugus. Por exemplo, x > 0 and x < 10 verdadeiro somente se x for maior que 0 e (and ) menor que 10. n%2 == 0 or n%3 == 0 verdadeiro se qualquer das condies for verdadeira, quer dizer, se o nmero n for divisvel por 2 ou (or) por 3. Finalmente o operador lgico not nega uma expresso booleana, assim not(x > y) verdadeiro se (x > y) for falso, quer dizer, se x for menor ou igual a y. Falando estritamente, os operandos de operadores lgicos deveriam ser expresses booleanas, mas Python no muito rigoroso. Qualquer nmero diferente de zero interpretado como verdadeiro (true). >>> >>> 1 >>> >>> 0 x = 5 x and 1 y = 0 y and 1

Em geral, este tipo de coisa no considerado de bom estilo. Se voc precisa comparar um valor com zero, voc deve faz-lo explicitamente.

4.4 Execuo condicional


Para poder escrever programas teis, ns quase sempre precisamos da habilidade de checar condies e mudar o comportamento do programa de acordo com elas. Instrues condicionais nos do esta habilidade. A forma mais simples e a instruo if (se): if x > 0 print x positivo A expresso booleana depois da instruo if chamada de condio . Se ela verdadeira (true), ento a instruo endentada executada. Se no, nada acontece. Assim como outras instrues compostas, a instruo if constituda de um cabealho e de um bloco de instrues: CABEALHO: PRIMEIRO COMANDO ... LTIMO COMANDO O cabealho comea com uma nova linha e termina com dois pontos (:). Os comandos ou instrues endentados que seguem so chamados de bloco . A

primeira instruo no endentada marca o fim do bloco. Um bloco de comandos dentro de um comando composto ou instruo composta chamado de corpo do comando. No existe limite para o nmero de instrues que podem aparecer no corpo de uma instruo if, mas tem que haver pelo menos uma. Ocasionalmente, til ter um corpo sem nenhuma instruo (usualmente como um delimitador de espao para cdigo que voc ainda no escreveu). Neste caso, voc pode usar o comando pass, o qual no faz nada.

4.5 Execuo alternativa


Um segundo formato da instruo if a execuo alternativa, na qual existem duas possibilidades e a condio determina qual delas ser executada. A sintaxe se parece com: if x%2 == 0: print x, par else: print x, impar Se o resto da diviso de x por 2 for 0, ento sabemos que x par, e o programa exibe a mensagem para esta condio. Se a condio falsa, o segundo grupo de instrues executado. Desde que a condio deva ser verdadeira (true) ou falsa (false), precisamente uma das alternativas vai ser executada. As alternativas so chamadas ramos , porque existem ramificaes no fluxo de execuo. As an aside, se voc precisa checar a paridade (par ou mpar) de nmeros com freqncia, voc pode colocar este cdigo dentro de uma funo: def imprimeParidade(x): if x%2 == 0: print x, par else: print x, impar Para qualquer valor de x, imprimeParidade exibe uma mensagem apropriada. Quando voc a chama, voc deve fornecer uma expresso de resultado inteiro como um argumento. >>> imprimeParidade(17) >>> imprimeParidade(y+1)

4.6 Condicionais encadeadas (ou cadeia de condicionais? ou cadeia condicional?)


s vezes existe mais de uma possibilidade e precisamos de mais de dois ramos. Um jeito de expressar uma computao como esta uma cadeia de condicionais : if x < y: print x, menor que, y elif x > y: print x, maior que, y else: print x, e, y, so iguais

elif uma abreviao de else if (ento se). De novo, precisamente um ramo ser executado. No existe limite para o nmero de instrues elif, mas o ltimo ramo tem que ser uma instruo else (ento): if escolha == A: funcaoA() elif escolha == B: funcaoB() elif escolha == C: funcaoC() else: print Escolha invlida. Cada condio checada na ordem. Se a primeira falsa, a prxima checada, e assim por diante. Se uma delas verdadeira, o ramo correspondente executado, e a instruo termina. Mesmo que mais de uma condio seja verdadeira, apenas o primeiro ramo verdadeiro executa. Como exerccio, coloque estes exemplos em funes chamadas compara(x, y) e despacha(escolha).

4.7 Condicionais aninhadas


Uma condicional tambm pode ser aninhada dentro de outra. Poderamos ter escrito o exemplo tricotmico (dividido em trs) como segue: if x == y: print x, "e", y, "so iguais" else: if x < y: print x, " menor que", y else: print x, " maior que", y A condicional mais externa tem dois ramos. O primeiro ramo contm uma nica instruo de sada. O segundo ramo contm outra instruo if, que por sua vez tem dois ramos. Os dois ramos so ambos instrues de sida, embora pudessem conter instrues condicionais tambm. Embora a endentao das instrues torne a estrutura aparente, condicionais aninhadas tornam-se difceis de ler rapidamente. Em geral, uma boa idia evitar o aninhamento quando voc puder. Operadores lgicos muitas vezes fornecem uma maneira de simplificar instrues condicionais aninhadas. Por exemplo, ns podemos reescrever o seguinte cdigo usando uma nica condicional: if 0 < x: if x < 10: print "x um nico algarismo positivo." A instruo print executada somente se a fizermos passar por ambos os condicionais, ento podemos usar um operador and: if 0 < x and x < 10: print "x um nico algarismo positivo."

Estes tipos de condio so comuns, assim Phython prov uma sintaxe alternativa que similar notao matemtica: if 0 < x < 10: print "x um nico algarismo positivo."

4.8 A instruo return


A instruo ou comando return permite a voc terminar a execuo de uma funo antes que ela alcance seu fim. Uma razo para us-lo se voc detetar uma condio de erro: def imprimeLogaritmo(x): if x <= 0: print "Somente nmeros positivos, por favor." return resultado = math.log(x) print "O log de x ", resultado A funo imprimeLogaritmo recebe um parmetro de nome x. A primeira coisa que ela faz checar se x menor ou igual a 0, neste caso ela exibe uma mensagem de erro e ento usa return para sair da funo. O fluxo de execuo imediatamente retorna ao ponto chamador, quer dizer, de onde a funo foi chamada, e as linhas restantes da funo no so executadas. Lembre-se que para usar uma funo do mdulo de matemtica, math, voc tem de import-lo.

4.9 Recursividade
Ns j mencionamos que vlido que uma funo pode chamar outra, e voc tem visto vrios exemplos disto. O que negligenciamos mencionar que tambm vlido para uma funo chamar ela mesma. Pode no ser bvio o porque disso ser uma boa coisa, mas se revela uma das coisas mais mgicas e interessantes que um programa pode fazer. Por exemplo, d uma olhada na seguinte funo: def contagemRegressiva(n): if n == 0: print "Fogo!" else: print n contagemRegressiva(n-1) contagemRegressiva espera que o parmetro, n, seja um inteiro positive. Se n for 0, ela produz como sada a palavra Fogo! (Blastoff!). De outro modo, ela produz com sada n e ento chama uma funo de nome contagemRegressiva ela mesma passando n-1 como argumento. O que acontece se chamarmos esta funo deste maneira: >>> contagemRegressiva(3) A execuo de contagemRegressiva comea com n=3, e desde que n no 0, produz como sada o valor 3, e ento chama a si mesma...

A execuo de contagemRegressiva comea com n=2, e desde que n no 0, produz como sada o valor 2, e ento chama a si mesma... A execuo de contagemRegressiva comea com n=1, e desde que n no 0, produz como sada o valor 1, e ento chama a si mesma... A execuo de contagemRegressiva comea com n=0, e desde que n 0, produz como sada a palavra Fogo! (Blastoff!) e ento retorna. A contagemRegressiva que tem n=1 retorna. A contagemRegressiva que tem n=2 retorna. A contagemRegressiva que tem n=1 retorna. E ento voc est de volta em __main__ (que viagem!). Assim, a sada completa se parece com: 3 2 1 Fogo! Como um segundo exemplo, de uma olhada novamente nas funes novaLinha e tresLinhas: def novaLinha(): print def tresLinhas(): novaLinha() novaLinha() novaLinha() Muito embora isto funcione, no seria de muita ajuda se precisssemos gerar como sada 2 novas linhas, ou 106. Uma alternativa melhor seria esta: def nLinhas(n): if n > 0: print nLinhas(n-1) Este programa similar a contagemRegressiva; sempre que n for maior que 0 ele gera como sada uma nova linha e ento chama a si mesmo para gerar como sada n-1 linhas adicionais. Deste modo, o nmero total de novas linhas 1 + (n - 1) o que, se voc estudou lgebra direitinho, vem a ser n. O processo em que uma funo chama a ela mesma chamado de recursividade , e tais funes so ditas recursivas.

4.10 Diagramas de pilha para funes recursivas


Na Seo 3.11, usamos um diagrama de pilha para representar o estado de um programa durante uma chamada de funo. O mesmo tipo de diagrama pode ajudar a interpretar uma funo recursiva.

Toda vez que uma funo chamada, Python cria um novo quadro (frame) para a funo, o qual contm as variveis locais e parmetros da funo. Para uma funo recursiva, ter que existir mais de um quadro na pilha ao mesmo tempo. Esta figura mostra um diagrama de pilha para contagemRegressiva, chamada com n = 3:

Como de costume, no topo da pilha est o quadro par __main__. Ele est vazio porque no criamos nenhuma varivel em __main__ ou passamos qualquer valor para ele. Os quatro quadros contagemRegressiva tm valores diferentes para o parmetro n. A parte mais em baixo na pilha, onde n=0, chamada de caso base. Ele no faz uma chamada recursiva, ento no h mais quadros. Como exerccio, desenhe um diagrama de pilha para nLinhas chamada com n=4.

4.11 Recursividade infinita


Se uma recursividade nunca chega ao caso base, ela prossegue fazendo chamadas recursivas para sempre, e o programa nunca termina. Isto conhecido como recursividade infinita, geralmente no considerada uma boa idia. Aqui est um programa mnimo com uma recursividade infinita: def recursiva(): recursiva() Na maioria dos ambientes de programao, um programa com recursividade infinita na verdade no roda para sempre. Python reporta uma mensagem de erro quando a profundidade mxima de recursividade alcanada: File "<stdin>", line 2, in recursiva (98 repetitions omitted) File "<stdin>", line 2, in recursiva RuntimeError: Maximum recursion depth exceeded

Este traceback um pouco maior do que aquele que vimos no captulo anterior. Quando o erro ocorre, existem 100 quadros recursiva na pilha! Como exerccio, escreva uma funo com recursividade infinita e rodea no interpretador Python.

4.12 Entrada pelo teclado


Os programas que temos escrito at agora so um pouco crus no sentido de no aceitarem dados entrados pelo usurio. Eles simplesmente fazem a mesma coisa todas s vezes. Python fornece funes nativas que pegam entradas pelo teclado. A mais simples chamada raw_input. Quando esta funo chamada, o programa para e espera que o usurio digite alguma coisa. Quando o usurio aperta as teclas Enter ou Return, o programa reassume e raw_input retorna o que o usurio digitou como uma string: >>> entrada = raw_input() O que voc est esperando? >>> print entrada O que voc est esperando? Antes de chamar raw_input, uma boa idia exibir uma mensagem dizendo ao usurio o que entrar. Esta mensagem chamada um prompt . Podemos suprir um prompt como um argumento para raw_input: >>> nome = raw_input(Qual... o seu nome? ) Qual... o seu nome? Arthur, Rei dos Bretes! >>> print nome Arthur, Rei dos Bretes! Se esperamos que a entrada seja um inteiro, podemos usar a funo input: prompt = Qual... a velocidade de um unladen swallow?\n velocidade = input(prompt) Se o usurio digita uma string de nmeros, ela convertida para um inteiro e atribuda a velocidade. Infelizmente, se o usurio digitar um caractere que no seja um nmero, o programa trava: >>> velociadade = input(prompt) Qual... a velocidade de uma andorinha unladen? De qual voc fala, uma andorinha Africana ou Europia? SyntaxError: invalid syntax Para evitar este tipo de erro, geralmente uma boa idia usar raw_input para pegar uma string e ento usar funes de converso para converter para outros tipos.

4.13 Glossrio
operador mdulo: Um operador, representado com um smbolo de porcentagem (%), que funciona com inteiros e gera o resto da diviso de um nmero por outro. expresso booleana: Uma expresso que ou verdadeira ou falsa.

operador de comparao: Um dos operadores que comparam dois valores: ==, ! =, >, <, >= e <=. operador lgico: Um dos operadores que combinam expresses booleanas: and, or e not (e, ou e no). instruo condicional: Uma instruo ou comando que controla o fluxo de execuo dependendo que alguma condio. condio: A expresso booleana em uma instruo condicional que determina que ramo ser executado. instruo composta: Uma instruo ou comando que consiste de um cabealho e de um corpo. O cabealho termina com dois pontos (:). O corpo endentado relativamente ao cabealho. bloco: Um grupo de instrues consecutivas na mesma endentao. corpo: O bloco em uma instruo composta que se segue ao cabealho. aninhamento: Uma estrutura de programa dentro de outra, tal como uma instruo condicional dentro de um ramo de outra instruo condicional. recursividade: O processo de chamada de uma funo que a que est sendo executada atualmente. caso base: Um ramo de uma instruo condicional em uma funo recursiva que no resulta em uma chamada recursiva; recursividade infinita: Uma funo de chama a si mesma recursivamente sem jamais atingir o caso base. Eventualmente, uma recurso infinita causa um erro de runtime. prompt: uma indicao visual que diz ao usurio para entrar com dados.

Captulo 5
Funes que do frutos
5.1 Valores de retorno
Algumas das funes nativas do Python que temos usado, como as funes matemticas, produziram resultados. Chamar a funo gerou um novo valor, o qual geralmente atribumos a uma varivel ou usamos como parte de uma expresso. e = math.exp(1.0) altura = raio * math.sin(angulo) Mas at agora, nenhuma das funes que ns mesmos escrevemos retornou um valor. Neste captulo, iremos escrever funes que retornam valores, as quais chamaremos de funes frutferas, ou funes que do frutos, na falta de um nome melhor. O primeiro exemplo area, que retorna a rea de um crculo dado o seu raio: import math def area(raio): temp = math.pi * raio**2 return temp J vimos a instruo return antes, mas em uma funo frutfera a instruo return inclui um valor de retorno. Esta instruo significa: Retorne imediatamente desta funo e use a expresso em seguida como um valor de retorno. A expresso fornecida pode ser arbitrariamente complicada, de modo que poderamos ter escrito esta funo de maneira mais concisa: def area(raio): return math.pi * raio**2 Por outro lado, variveis temporrias como temp muitas vezes tornam o debugging mais fcil. s vezes til ter mltiplos comandos return, um em cada ramo de uma condicional: def valorAbsoluto(x): if x < 0: return x else: return x

J que estes comandos return esto em ramos alternativos da condicional, apenas um ser executado. To logo um seja executado, a funo termina sem executar qualquer instruo ou comando subseqente. O cdigo que aparece depois de uma instruo return, ou em qualquer outro lugar que o fluxo de execuo jamais alcance, chamado cdigo morto (dead code). Em uma funo frutfera, uma boa idia assegurar que todo caminho possvel dentro do programa encontre uma instruo return. Por exemplo: def valorAbsoluto(x): if x < 0: return x elif x > 0: return x Este programa no est correto porque se x for 0, nenhuma das condies ser verdadeira, e a funo terminar sem encontrar um comando return. Neste caso, o valor de retorno ser um valor especial chamado None: >>> print valorAbsoluto(0) None Como exerccio, escreva uma funo compare que retorne 1 se x > y, 0 se x == y e -1 se x < y. 5.2 Desenvolvimento de programas Neste ponto, voc deve estar apto a olhar para funes completas e dizer o que elas fazem. Tambm, se voc vem fazendo os exerccios, voc escreveu algumas pequenas funes. Conforme escrever funes maiores, voc pode comear a ter mais dificuldade, especialmente com erros em tempo de execuo (erros de runtime) ou erros semnticos. Para lidar com programas de crescente complexidade, vamos sugerir uma tcnica chamada desenvolvimento incremental. A meta do desenvolvimento incremental evitar sees de debugging muito longas pela adio e teste de somente uma pequena quantidade de cdigo de cada vez. Como exemplo, suponha que voc queira encontrar a distncia entre dois pontos, dados pelas coordenadas (x1,y1) e (x2,y2). Pelo teorema de Pitgoras, a distncia : __________________ distancia = V (x2 x1)2 + (y2 y1)2 (5.1) O primeiro passo considerar como deveria ser uma funo distancia em Python. Em outras palavras, quais so as entradas (parmetros) e qual a sada (valor de retorno)? Neste caso, os dois pontos so as entradas, os quais podemos representar usando quatro parmetros. O valor de retorno a distncia, que um valor em ponto flutuante.

J podemos escrever um esboo da funo: def distancia(x1, y1, x2, y2): return 0.0 Obviamente, esta verso da funo no computa distncias; ela sempre retorna zero. Mas ela est sintaticamente correta, e vai rodar, o que significa que podemos test-la antes de torn-la mais complicada. Para testar a nova funo, vamos cham-la com valores hipotticos: >>> distancia(1, 2, 4, 6) 0.0 Escolhemos estes valores de modo que a distncia horizontal seja igual a 3 e a distncia vertical seja igual a 4; deste modo, o resultado 5 (a hipotenusa de um triangulo 3-4-5). Quando testamos uma funo, til sabermos qual o resultado correto. Neste ponto, j confirmamos que a funo est podemos comear a adicionar linhas de cdigo. adicionada, testamos a funo de novo. Se um ponto, sabemos aonde ele deve estar: nas recentemente. sintaticamente correta, e Depois de cada mudana erro ocorre em qualquer linhas adicionadas mais

Um primeiro passo lgico nesta computao encontrar as diferenas x2 x1 e y2 y1. Ns iremos guardar estes valores em variveis temporrias chamadas dx e dy e imprimi-las. def distancia(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 print dx vale, dx print dy vale, dy return 0.0 Se a funo estiver funcionando, as sadas devero ser 3 e 4. Se assim, sabemos que a funo est recebendo os parmetros corretos e realizando a primeira computao corretamente. Se no, existem poucas linhas para checar. Em seguida, computaremos a soma dos quadrados de dx e dy: def distancia(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 dquadrado = dx**2 + dy**2 print dquadrado vale: , dquadrado return 0.0

Note que removemos os comandos print que havamos escrito no passo anterior. Cdigo como este chamado de andaime (scaffolding) porque ajuda a escrever o programa, mas no parte do produto final. De novo, ns vamos rodar o programa neste estgio e checar a sada (que deveria ser 25). Finalmente, se ns tnhamos importado o mdulo matemtico math, podemos usar a funo sqrt para computar e retornar o resultado: def distancia(x1, x2, y1, y2): dx = x2 - x1 dy = y2 - y1 dquadrado = dx**2 + dy**2 resultado = math.sqrt(dquadrado) return resultado Se isto funcionar corretamente, voc conseguiu. Otherwise, voc poderia precisar imprimir (exibir) o valor de resultado antes da instruo return.