Beruflich Dokumente
Kultur Dokumente
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.
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.
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.
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.
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.
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.
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
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.
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.
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
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.
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>
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.
Por exemplo, o script print 1 x = 2 print 2 produz a sada 1 2 de novo: o comando de atribuio no produz sada.
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.
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.
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
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.
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.
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.
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?
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?
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.
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.
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.
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.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.
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 =>.
Em geral, este tipo de coisa no considerado de bom estilo. Se voc precisa comparar um valor com zero, voc deve faz-lo explicitamente.
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.
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).
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.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.
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.
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.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.