You are on page 1of 103

Como pensar como um cientista da Computao usando Python

Allen Downey Je rey Elkner Chris Meyers

Traduo: Equipe do projeto http://pensarpython.incubadora.fapesp.br Edio: Crlisson Galdino

Como pensar como um cientista da Computao usando Python

GNU Free Documentation License #2

Como pensar como um cientista da Computao usando Python

Copyright (c) 2002 Allen Downey, Je rey Elkner, and Chris Meyers. Edited by Shannon Turlington and Lisa Cutler. Cover design by Rebecca Gimenez. Printing history: April 2002: First edition. Green Tea Press 1 Grove St. P.O. Box 812901 Wellesley, MA 02482 Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being Foreword, Preface, and Contributor List, with no Front-Cover Texts, and with no BackCover Texts. A copy of the license is included in the appendix entitled GNU Free Documentation License. The GNU Free Documentation License is available from www.gnu.org or by writing to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

Como pensar como um cientista da Computao usando Python


Verso atual: 1.0 Data de Publicao: 16 de janeiro de 2008 Classificao: Tutorial Autor: Jeffrey Elkner (traduzido pelo http://pensarpython.incubadora.fapesp.br) Publicao: Cyaneus.net

projeto

Pensar

Python

GNU Free Documentation License #3

Como pensar como um cientista da Computao usando Python

ndice
Foreword ........................................................................................................................................................ 5 Apresentao .................................................................................................................................................. 6 Preface ........................................................................................................................................................... 7
How and why I came to use Python ................................................................................................................................ 7 Finding a textb o ok ......................................................................................................................................................... 7 Intro ducing programming with Python........................................................................................................................... 7 Building a community ..................................................................................................................................................... 8

Prefcio .......................................................................................................................................................... 9
Como e porque eu vim a usar Python .............................................................................................................................. 9 Encontrando um livro texto ............................................................................................................................................. 9 Introduzindo programao com Python ......................................................................................................................... 10 Construindo uma comunidade ....................................................................................................................................... 10

Contributor List ........................................................................................................................................... 11 Verso Brasileira .......................................................................................................................................... 13 Captulo 1: O caminho do programa ........................................................................................................... 14
1.1 A linguagem de programao Python ...................................................................................................................... 14 1.2 O que um programa? ............................................................................................................................................. 15 1.3 O que depurao (debugging)? ............................................................................................................................. 15
1.3.1 Erros de sintaxe ....................................................................................................................................... 15 1.3.2 Erros em tempo de execuo (runtime errors) ....................................................................................... 15 1.3.3 Erros de semntica .................................................................................................................................. 15 1.3.4 Depurao experimental (Debugging) .................................................................................................... 16

1.4 Linguagens naturais e linguagens formais ............................................................................................................... 16 1.5 O primeiro programa ............................................................................................................................................... 17 1.6 Glossrio .................................................................................................................................................................. 17

Captulo 2: Variveis, expresses e comandos ............................................................................................ 18


2.1 Valores e tipos .......................................................................................................................................................... 18 2.2 Variveis .................................................................................................................................................................. 18 2.3 Nomes de variveis e palavras reservadas ............................................................................................................... 18 2.4 Comandos ................................................................................................................................................................ 19 2.5 Avaliando expresses ............................................................................................................................................... 19 2.6 Operadores e operandos........................................................................................................................................... 19 2.7 Ordem dos operadores ............................................................................................................................................. 20 2.8 Operaes com strings ............................................................................................................................................. 20 2.9 Composio ............................................................................................................................................................. 20 2.11 Glossrio ................................................................................................................................................................ 20

Captulo 3: Funes ..................................................................................................................................... 22


3.1 Chamadas de funes .............................................................................................................................................. 22 3.2 Converso entre tipos .............................................................................................................................................. 22 3.3 Coero entre tipos .................................................................................................................................................. 22 3.4 Funes matemticas ............................................................................................................................................... 22 3.5 Composio ............................................................................................................................................................. 23 3.6 Adicionando novas funes ..................................................................................................................................... 23 3.7 Definies e uso....................................................................................................................................................... 24 3.8 Fluxo de execuo ................................................................................................................................................... 24 3.9 Parmetros e argumentos ......................................................................................................................................... 24 3.10 Variveis e parmetros so locais .......................................................................................................................... 25 3.11 Diagramas da pilha ................................................................................................................................................ 25 3.12 Funes com resultados ......................................................................................................................................... 25 3.13 Glossrio ................................................................................................................................................................ 26

Captulo 4: Condicionais e recursividade .................................................................................................... 27


4.1 O operador mdulo .................................................................................................................................................. 27 4.2 Expresses booleanas .............................................................................................................................................. 27 4.3 Operadores lgicos .................................................................................................................................................. 27 4.4 Execuo condicional .............................................................................................................................................. 27 4.5 Execuo alternativa ................................................................................................................................................ 28
GNU Free Documentation License #4

Como pensar como um cientista da Computao usando Python

4.6 Condicionais encadeados ......................................................................................................................................... 28 4.7 Condicionais aninhados ........................................................................................................................................... 28 4.8 A instruo return..................................................................................................................................................... 28 4.9 Recursividade .......................................................................................................................................................... 29 4.10 Diagramas de pilha para funes recursivas .......................................................................................................... 29 4.11 Recursividade infinita ............................................................................................................................................ 30 4.12 Entrada pelo teclado .............................................................................................................................................. 30 4.13 Glossrio ................................................................................................................................................................ 30

Captulo 5: Funes frutferas ..................................................................................................................... 31


5.1 Valores de retorno .................................................................................................................................................... 31 5.2 Desenvolvimento de programas .............................................................................................................................. 31 5.3 Composio ............................................................................................................................................................. 32 5.4 Funes booleanas ................................................................................................................................................... 32 5.5 Mais recursividade ................................................................................................................................................... 33 5.6 Voto de confiana (Leap of faith) ............................................................................................................................ 33 5.7 Mais um exemplo .................................................................................................................................................... 34 5.8 Checagem de tipos ................................................................................................................................................... 34 5.9 Glossrio .................................................................................................................................................................. 34

Captulo 6: Iterao ...................................................................................................................................... 36


6.1 Reatribuies ........................................................................................................................................................... 36 6.2 O comando while ..................................................................................................................................................... 36 6.3 Tabelas ..................................................................................................................................................................... 37 6.4 Tabelas de duas dimenses (ou bi-dimensionais) .................................................................................................... 38 6.5 Encapsulamento e generalizao ............................................................................................................................. 38 6.6 Mais encapsulamento............................................................................................................................................... 38 6.7 Variveis locais ........................................................................................................................................................ 38 6.8 Mais generalizao .................................................................................................................................................. 39 6.9 Funes .................................................................................................................................................................... 39 6.10 Glossrio ................................................................................................................................................................ 40

Captulo 7: Strings ....................................................................................................................................... 41


7.1 Um tipo de dado composto ...................................................................................................................................... 41 7.2 Comprimento ........................................................................................................................................................... 41 7.3 Travessia e o loop for............................................................................................................................................... 41 7.4 Fatias de strings ....................................................................................................................................................... 42 7.5 Comparao de strings............................................................................................................................................. 42 7.6 Strings so imutveis ............................................................................................................................................... 42 7.7 Uma funo find (encontrar).................................................................................................................................... 42 7.8 Iterando e contando.................................................................................................................................................. 43 7.9 O mdulo string ....................................................................................................................................................... 43 7.10 Classificao de caracteres .................................................................................................................................... 43 7.11 Glossrio ................................................................................................................................................................ 43 7.11 Glossrio2 .............................................................................................................................................................. 44

Captulo 8: Listas ......................................................................................................................................... 45


8.1 Valores da lista ......................................................................................................................................................... 45 8.2 Acessado elementos ................................................................................................................................................. 45 8.3 Comprimento da lista ............................................................................................................................................... 45 8.4 Membros de uma lista .............................................................................................................................................. 46 8.5 Listas e laos for ...................................................................................................................................................... 46 8.6 Operaes em listas ................................................................................................................................................. 46 8.7 Fatiamento de listas ................................................................................................................................................. 46 8.8 Listas so mutveis .................................................................................................................................................. 46 8.9 Remoo em lista ..................................................................................................................................................... 47 8.10 Ojetos e valores ..................................................................................................................................................... 47 8.11 Apelidos ................................................................................................................................................................. 47 8.12 Clonando listas ...................................................................................................................................................... 48 8.13 Lista como parmetro ............................................................................................................................................ 48 8.14 Lista aninhadas ...................................................................................................................................................... 48 8.15 Matrizes ................................................................................................................................................................. 48 8.16 Strings e listas ........................................................................................................................................................ 49 8.17 Glossrio ................................................................................................................................................................ 49
GNU Free Documentation License #5

Como pensar como um cientista da Computao usando Python

Captulo 9: Tuplas ........................................................................................................................................ 50


9.1 Mutabilidade e tuplas............................................................................................................................................... 50 9.2 Atribuies de tupla ................................................................................................................................................. 50 9.3 Tuplas como valores de retorno ............................................................................................................................... 50 9.4 Nmeros aleatrios .................................................................................................................................................. 50 9.5 Lista de nmeros aleatrios ..................................................................................................................................... 51 9.6 Contando.................................................................................................................................................................. 51 9.7 Vrios intervalos ...................................................................................................................................................... 51 9.8 Uma soluo em um s passo .................................................................................................................................. 52 9.9 Glossrio .................................................................................................................................................................. 52

Captulo 10: Dicionrios .............................................................................................................................. 54


10.1 Operaes dos Dicionrios .................................................................................................................................... 54 10.2 Mtodos dos Dicionrios ....................................................................................................................................... 54 10.3 Aliasing (XXX) e Copiar ....................................................................................................................................... 55 10.4 Matrizes Esparsas .................................................................................................................................................. 55 10.5 Hint ........................................................................................................................................................................ 55 10.6 Inteiros Longos ...................................................................................................................................................... 56 10.7 Contando Letras ..................................................................................................................................................... 56 10.8 Glossrio ................................................................................................................................................................ 56

Captulo 11: Arquivos e excees ................................................................................................................ 58


Arquivos e excees ...................................................................................................................................................... 58 11.1 Arquivos texto ........................................................................................................................................................ 58 11.2 Gravando variveis ................................................................................................................................................ 59 11.3 Diretrios ............................................................................................................................................................... 60 11.4 Pickling .................................................................................................................................................................. 60 11.5 Excees ................................................................................................................................................................ 60 11.6 Glossrio ................................................................................................................................................................ 61

Captulo 12: Classes e objetos ..................................................................................................................... 62


12.1 Tipos compostos definidos pelo usurio ................................................................................................................ 62 12.2 Atributos ................................................................................................................................................................ 62 12.3 Instncias como parmetros ................................................................................................................................... 63 12.4 O significado de "mesmo" ..................................................................................................................................... 63 12.5 Retngulos ............................................................................................................................................................. 63 12.6 Instancias como valores retornados ....................................................................................................................... 64 12.7 Objetos so mutveis ............................................................................................................................................. 64 12.8 Copiando................................................................................................................................................................ 64 12.9 Glossrio ................................................................................................................................................................ 65

Captulo 13: Classes e funes .................................................................................................................... 66


13.1 Horario ................................................................................................................................................................... 66 13.2 Funes Puras ........................................................................................................................................................ 66 13.3 Modificadores ........................................................................................................................................................ 66 13.4 O que melhor ? .................................................................................................................................................... 67 13.5 Desenvolvimento Prototipado versus Desenvolvimento Planejado....................................................................... 67 13.6 Generalizao ........................................................................................................................................................ 67 13.7 Algoritmos ............................................................................................................................................................. 68 13.8 Glossrio ................................................................................................................................................................ 68

Captulo 14: Classes e mtodos ................................................................................................................... 69


14.1 Caractersticas da orientao a objetos .................................................................................................................. 69 14.2 exibeHora (printTime) ........................................................................................................................................... 69 14.3 Um outro exemplo ................................................................................................................................................. 70 14.10 Glossrio .............................................................................................................................................................. 70

Captulo 15: Conjuntos de objetos ............................................................................................................... 71


15.1 Composio ........................................................................................................................................................... 71 15.2 Objetos Carta ......................................................................................................................................................... 71 15.3 Atributos de classe e o mtodo __str__ ................................................................................................................. 71 15.4 Comparando cartas ................................................................................................................................................ 72 15.5 Baralhos ................................................................................................................................................................. 72 15.6 Imprimindo o baralho ............................................................................................................................................ 72 15.7 Embaralhando ........................................................................................................................................................ 73 15.8 Removendo e distribuindo cartas........................................................................................................................... 73
GNU Free Documentation License #6

Como pensar como um cientista da Computao usando Python

15.9 Glossrio ................................................................................................................................................................ 74

Capitulo 16: Herana ................................................................................................................................... 75


16.1 Herana .................................................................................................................................................................. 75 16.2 Uma mo de cartas................................................................................................................................................. 75 16.3 Dando as cartas ...................................................................................................................................................... 75 16.4 Exibindo a mao ...................................................................................................................................................... 76 16.5 A classe JogoDeCartas ........................................................................................................................................... 76 16.6 Classe MaoDeMico ............................................................................................................................................... 76 16.7 Classe Mico ........................................................................................................................................................... 77 16.8 Glossrio ................................................................................................................................................................ 78

Captulo 17: Listas encadeadas .................................................................................................................... 79


17.1 Referncias Embutidas .......................................................................................................................................... 79 17.2 A classe No (Node) ................................................................................................................................................ 79 17.3 Listas como Colees ............................................................................................................................................ 79 17.4 Listas e Recorrncia............................................................................................................................................... 80 17.5 Listas Infinitas ....................................................................................................................................................... 80 17.6 O Teorema da Ambigidade Fundamental............................................................................................................. 80 17.7 Modificando Listas ................................................................................................................................................ 81 17.8 Envoltrios e Ajudadores ....................................................................................................................................... 81 17.9 A Classe ListaLigada ............................................................................................................................................. 81 17.10 Invariantes ........................................................................................................................................................... 82 17.11 Glossrio .............................................................................................................................................................. 82

Captulo 18: Pilhas ....................................................................................................................................... 83


18.1 Tipos abstratos de dados ........................................................................................................................................ 83 18.2 O TAD Pilha .......................................................................................................................................................... 83 18.3 Implementando pilhas com listas de Python.......................................................................................................... 83 18.4 Empilhando e desempilhando ................................................................................................................................ 83 18.5 Usando uma pilha para avaliar expresses ps-fixas ............................................................................................. 84 18.6 Anlise sinttica ..................................................................................................................................................... 84 18.7 Avaliando em ps-fixo. .......................................................................................................................................... 84 18.8 Clientes de fornecedores. ....................................................................................................................................... 84 18.9 Glossrio ................................................................................................................................................................ 85

Captulo 19: Filas ......................................................................................................................................... 86


19.1 Um TDA Fila ......................................................................................................................................................... 86 19.2 Fila encadeada ....................................................................................................................................................... 86 19.3 Caractersticas de performance .............................................................................................................................. 86 19.4 Fila encadeada aprimorada .................................................................................................................................... 86 19.5 Fila por prioridade ................................................................................................................................................. 87 19.6 A classe Golfer ....................................................................................................................................................... 88 19.7 Glossrio ................................................................................................................................................................ 88

Captulo 20: rvores.................................................................................................................................... 89


20.1 Construindo rvores ............................................................................................................................................... 89 20.2 Percorrendo rvores ............................................................................................................................................... 89 20.3 rvores de expresses ........................................................................................................................................... 89 20.4 Percurso de rvores ................................................................................................................................................ 90 20.5 Construindo uma rvore de expresso ................................................................................................................... 90 20.6 Manipulando erros ................................................................................................................................................. 92 20.7 A rvore dos animais .............................................................................................................................................. 92 20.8 Glossrio ................................................................................................................................................................ 93

GNU Free Documentation License ............................................................................................................. 94


0. PREAMBLE ............................................................................................................................................................. 94 1. APPLICABILITY AND DEFINITIONS .................................................................................................................. 94 2. VERBATIM COPYING ........................................................................................................................................... 95 3. COPYING IN QUANTITY ...................................................................................................................................... 95 4. MODIFICATIONS ................................................................................................................................................... 95 5. COMBINING DOCUMENTS ................................................................................................................................. 96 6. COLLECTIONS OF DOCUMENTS ....................................................................................................................... 96 7. AGGREGATION WITH INDEPENDENT WORKS ............................................................................................... 96 8. TRANSLATION ....................................................................................................................................................... 96 9. TERMINATION ....................................................................................................................................................... 96
GNU Free Documentation License #7

Como pensar como um cientista da Computao usando Python

10. FUTURE REVISIONS OF THIS LICENSE ........................................................................................................... 96


How to use this License for your documents .................................................................................................... 96

GNU Free Documentation License #8

Como pensar como um cientista da Computao usando Python

Foreword

By David Beazley As an educator, researcher, and book author, I am delighted to see the completion of this book. Python is a fun and extremely easy-to-use programming language that has steadily gained in popularity over the last few years. Developed over ten years ago by Guido van Rossum, Pythons simple syntax and overall feel is largely derived from ABC, a teaching language that was developed in the 1980s. However, Python was also created to solve real problems and it borrows a wide variety of features from programming languages such as C++, Java, Modula-3, and Scheme. Because of this, one of Pythons most remarkable features is its broad appeal to professional software developers, scientists, researchers, artists, and educators.

Despite Pythons appeal to many di erent communities, you may still wonder why Python? or why teach programming with Python? Answering these questions is no simple taskespecially when popular opinion is on the side of more masochistic alternatives such as C++ and Java. In reading Je reys preface, I am struck by his However, I think the most direct answer is that programming comments that Python allowed him to see a higher level of in Python is simply a lot of fun and more productive. success and a lower level of frustration and that he was able When I teach computer science courses, I want to move faster with better results. Although these comments to cover important concepts in addition to making the material refer to his introductory course, I sometimes use Python for interesting and engaging to students. Unfortunately, there is a these exact same reasons in advanced graduate level computer tendency for introductory programming courses to focus far science courses at the University of Chicago. In these courses, too much attention on mathematical abstraction and for I am constantly faced with the daunting task of covering a lot students to be come frustrated with annoying problems related of dicult course material in a blistering nine week quarter. to low-level details of syntax, compilation, and the Although it is certainly possible for me to inict a lot of pain enforcement of seemingly arcane rules. Although such and su ering by using a language like C++, I have often abstraction and formalism is important to professional found this approach to be counterproductive especially software engineers and students who plan to continue their when the course is about a topic unrelated to just study of computer science, taking such an approach in an programming. I nd that using Python allows me to better introductory course mostly succeeds in making computer focus on the actual topic at hand while allowing students to science boring. When I teach a course, I dont want to have a complete substantial class pro jects. room of uninspired students. I would much rather see them Although Python is still a young and evolving trying to solve interesting problems by exploring di erent language, I believe that it has a bright future in education. This ideas, taking unconventional approaches, breaking the rules, book is an important step in that direction. and learning from their mistakes. In doing so, I dont want to waste half of the semester trying to sort out obscure syntax David Beazley problems, unintelligible compiler error messages, or the University of Chicago several hundred ways that a program might generate a general protection fault. Author of the Python Essential Reference

One of the reasons why I like Python is that it provides a really nice balance between the practical and the conceptual. Since Python is interpreted, beginners can pick up the language and start doing neat things almost immediately without getting lost in the problems of compilation and linking. Furthermore, Python comes with a large library of modules that can be used to do all sorts of tasks ranging from web-programming to graphics. Having such a practical focus is a great way to engage students and it allows them to complete significant pro jects. However, Python can also serve as an excellent foundation for introducing important computer science concepts. Since Python fully supports procedures and classes, students can be gradually introduced to topics such as procedural abstraction, data structures, and ob ject-oriented programmingall of which are applicable to later courses on Java or C++. Python even borrows a number of features from functional programming languages and can be used to introduce concepts that would be covered in more detail in courses on Scheme and Lisp.

GNU Free Documentation License #9

Apresentao
Traduo do captulo anterior, que foi mantido por ter sido marcado como seo invariante pelo autor original.
Como 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 ltimos poucos 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. que ele oferece um equilbrio realmente bom entre o lado prtico e o lado conceitual. Sendo Python interpretado, os iniciantes podem pegar a linguagem e comear a fazer coisas legais quase imediatamente sem se perderem em problemas de compilao e ligao. Alm disso, Python vem com uma grande biblioteca de mdulos que podem ser utilizados para fazer todo tipo de tarefa, desde a programao para a web at grficos. Com tal enfoque prtico temos uma bela maneira de alcanar o engajamento dos alunos e permitir que eles finalizem projetos significativos. Entretanto, Python tambm pode servir de excelente embasamento para a introduo de conceitos importantes em cincia da computao. J que Python suporta plenamente procedimentos (procedures) e classes, os alunos podem ser gradualmente introduzidos a tpicos como abstrao procedural, estruturas de dados, e programao orientada a objetos ? todos 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.

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 Lendo o prefcio de Jeffrey, fiquei divertido e mais produtivo. impressionado com seu comentrio de que Python o fez ver um ?maior nvel de sucesso e um menor nvel de frustrao? o Quando ministro cursos de cincias da que lhe permitiu ?progredir mais depressa com resultados computao, o que desejo cobrir conceitos importantes alm melhores?. Embora estes comentrios refiram-se aos seus de tornar a matria interessante e os alunos participativos. cursos introdutrios, eu s vezes uso Python exatamente pelas Infelizmente, existe uma tendncia entre os cursos mesmas razes em cursos avanados de ps-graduao em introdutrios de programao a focar ateno demais em cincia da computao na Universidade de Chicago. Nestes abstraes matemticas, e de frustrao entre os alunos com cursos, enfrento constantemente a assustadora tarefa de cobrir problemas enfadonhos e inoportunos relacionados a detalhes muitos tpicos difceis em um rapidssimo trimestre de nove de sintaxe em baixo nvel, compilao e a imposio de regras semanas. Embora me seja possvel inflingir um bocado de dor que aparentemente s um expert pode compreender. Embora e sofrimento pelo uso de uma linguagem como C++, tenho alguma abstrao e formalismo sejam importantes para percebido muitas vezes que este enfoque contraproducente ? engenheiros profissionais de software e estudantes que especialmente quando o curso sobre um tpico no planejam continuar seus estudos em cincias da computao, relacionado apenas com ?programar?. Acho que usar Python escolher tal abordagem em um curso introdutrio faz da me permite um melhor foco no tpico em questo, enquanto cincia da computao algo entediante. Quando ministro um permite que os alunos completem projetos substanciais em curso, no desejo uma sala cheia de alunos sem inspirao. Em classe. vez disso, preferiria muito mais v-los tentando solucionar problemas interessantes explorando idias diferentes, trilhando Embora Python seja ainda uma linguagem caminhos no convencionais, quebrando regras, e aprendendo jovem e em evoluo, acredito que tem um futuro brilhante em a partir de seus erros. Fazendo assim, no pretendo educao. Este livro um passo importante nessa direo. desperdiar metade de um semestre tentando explicar David Beazley problemas obscuros de sintaxe, mensagens ininteligveis de compiladores ou as vrias centenas de maneiras pelas quais Universidade de Chicago um programa pode gerar uma falha geral de proteo. Autor de Python Essencial Reference Uma das razes pelas quais eu gosto de Python

Preface

By Je Elkner This book owes its existence to the collaboration made possible by the Internet and the free software movement. Its three authorsa college professor, a high school teacher, and a professional programmerhave yet to meet face to face, but we have been able to work closely together and have been aided by many wonderful folks who have donated their time and energy to helping make this book better.

computer science classes the following year, the most pressing problem was the lack of an available textbook.

Free content came to the rescue. Earlier in the year, Richard Stallman had introduced me to Allen Downey. Both of us had written to Richard expressing an interest in developing free educational content. Allen had already written a rst-year computer science textbook, How to Think Like a Computer Scientist. When I read this book, I knew immediately that I wanted to use it in my class. It was the We think this book is a testament to the benets clearest and most helpful computer science text I had seen. It and future possibilities of this kind of collaboration, the emphasized the processes of thought involved in programming framework for which has been put in place by Richard rather than the features of a particular language. Reading it Stallman and the Free Software Foundation. immediately made me a better teacher.

How and why I came to use Python

In 1999, the College Boards Advanced Placement (AP) Computer Science exam was given in C++ for the rst time. As in many high schools throughout the country, the decision to change languages had a direct impact on the computer science curriculum at Yorktown High School in Arlington, Virginia, where I teach. Up to this point, Pascal was the language of instruction in both our rst-year and AP courses. In keeping with past practice of giving students two years of exposure to the same language, we made the decision to Working on this book for the last two years has switch to C++ in the rst-year course for the 1997-98 school been rewarding for both my students and me, and my students year so that we would be in step with the College Boards played a big part in the process. Since I could make instant change for the AP course the following year. changes whenever someone found a spelling error or dicult Two years later, I was convinced that C++ was a passage, I encouraged them to look for mistakes in the book poor choice to use for introducing students to computer by giving them a bonus point each time they made a science. While it is certainly a very powerful programming suggestion that resulted in a change in the text. This had the language, it is also an extremely dicult language to learn and double benet of encouraging them to read the text more teach. I found myself constantly ghting with C++s dicult carefully and of getting the text thoroughly reviewed by its syntax and multiple ways of doing things, and I was losing most important critics, students using it to learn computer many students unnecessarily as a result. Convinced there had science. to be a better language choice for our rst-year class, I went For the second half of the book on ob jectlooking for an alternative to C++. oriented programming, I knew that someone with more real I needed a language that would run on the programming experience than I had would be needed to do it machines in our Linux lab as well as on the Windows and right. The book sat in an unnished state for the better part of Macintosh platforms most students have at home. I wanted it a year until the free software community once again provided to be free and available electronically, so that students could the needed means for its completion. use it at home regardless of their income. I wanted a language I received an email from Chris Meyers that was used by professional programmers, and one that had expressing interest in the book. Chris is a professional an active developer community around it. It had to support programmer who started teaching a programming course last both procedural and ob ject-oriented programming. And most year using Python at Lane Community College in Eugene, importantly, it had to be easy to learn and teach. When I Oregon. The prospect of teaching the course had led Chris to investigated the choices with these goals in mind, Python the book, and he started helping out with it immediately. By stood out as the best candidate for the job. the end of the school year he had created a companion project I asked one of Yorktowns talented students, on our Website at http://www.ibiblio.org/obp called Python for Matt Ahrens, to give Python a try. In two months he not only Fun and was working with some of my most advanced learned the language but wrote an application called pyTicket students as a master teacher, guiding them beyond where I that enabled our sta to report technology problems via the could take them. Web. I knew that Matt could not have nished an application of that scale in so short a time in C++, and this accomplishment, combined with Matts positive assessment of Intro ducing programming with Python Python, suggested that Python was the solution I was looking for. The process of translating and using How to Think Like a Computer Scientist for the past two years has conrmed Pythons suitability for teaching beginning students. Python greatly simplies programming examples and makes Finding a textb o ok important programming ideas easier to teach. Having decided to use Python in both of my introductory The rst example from the text illustrates this

How to Think Like a Computer Scientist was not just an excellent book, but it had been released under a GNU public license, which meant it could be used freely and modied to meet the needs of its user. Once I decided to use Python, it occurred to me that I could translate Allens original Java version of the book into the new language. While I would not have been able to write a textbook on my own, having Allens book to work from made it possible for me to do so, at the same time demonstrating that the cooperative development model used so well in software could also work for educational content.

Como pensar como um cientista da Computao usando Python point. It is the traditional hello, world program, which in the thing. This is a far more intuitive concept for beginning C++ version of the book looks like this: students and is much closer to the meaning of variable that they learned in their math courses. I had much less diculty #include <iostream.h> teaching variables this year than I did in the past, and I spent less time helping students with problems using them. void main() { Another example of how Python aids in the cout << "Hello, world." << endl; teaching and learning of programming is in its syntax for functions. My students have always had a great deal of } diculty understanding functions. The main problem centers in the Python version it becomes: around the di erence between a function denition and a function call, and the related distinction between a parameter print "Hello, World!" Even though this is a trivial example, the and an argument. Python comes to the rescue with syntax that advantages of Python stand out. Yorktowns Computer Science is nothing short of beautiful. Function denitions begin with I course has no prerequisites, so many of the students seeing the keyword def, so I simply tell my students, When you this example are looking at their rst program. Some of them dene a function, begin with def, followed by the name of the are undoubtedly a little nervous, having heard that computer function that you are dening; when you call a function, programming is dicult to learn. The C++ version has always simply call (type) out its name. Parameters go with forced me to choose between two unsatisfying options: either denitions; arguments go with calls. There are no return types, to explain the #include, void main(), {, and } statements and parameter types, or reference and value parameters to get in risk confusing or intimidating some of the students right at the the way, so I am now able to teach functions in less than half start, or to tell them, Just dont worry about all of that stu the time that it previously took me, with better comprehension. now; we will talk about it later, and risk the same thing. The Using Python has improved the e ectiveness of educational ob jectives at this point in the course are to our computer science program for all students. I see a higher introduce students to the idea of a programming statement and general level of success and a lower level of frustration than I to get them to write their rst program, thereby introducing experienced during the two years I taught C++. I move faster them to the programming environment. The Python program with better results. More students leave the course with the has exactly what is needed to do these things, and nothing ability to create meaningful programs and with the positive more. attitude toward the experience of programming that this Comparing the explanatory text of the program engenders. in each version of the book further illustrates what this means to the beginning student. There are thirteen paragraphs of explanation of Hello, world! in the C++ version; in the Building a community Python version, there are only two. More importantly, the missing eleven paragraphs do not deal with the big ideas in I have received email from all over the globe from people computer programming but with the minutia of C++ syntax. I using this book to learn or to teach programming. A user found this same thing happening throughout the book. Whole community has begun to emerge, and many people have been paragraphs simply disappear from the Python version of the contributing to the pro ject by sending in materials for the text because Pythons much clearer syntax renders them companion Website at http://www.thinkpython.com. unnecessary. With the publication of the book in print form, I Using a very high-level language like Python expect the growth in the user community to continue and allows a teacher to postpone talking about low-level details of accelerate. The emergence of this user community and the the machine until students have the background that they need possibility it suggests for similar collaboration among to better make sense of the details. It thus creates the ability to educators have been the most exciting parts of working on this put rst things rst pedagogically. One of the best examples pro ject for me. By working together, we can increase the of this is the way in which Python handles variables. In C++ a quality of materials available for our use and save valuable variable is a name for a place that holds a thing. Variables have time. I invite you to join our community and look forward to to be declared with types at least in part because the size of the hearing from you. Please write to the authors at place to which they refer needs to be predetermined. Thus, the feedback@thinkpython.com. idea of a variable is bound up with the hardware of the Je rey Elkner machine. The powerful and fundamental concept of a variable is already dicult enough for beginning students (in both Yorktown High School computer science and algebra). Bytes and addresses do not Arlington, Virginia help the matter. In Python a variable is a name that refers to a

GNU Free Documentation License #12

Prefcio
Traduo do captulo anterior, que foi mantido por ter sido marcado como seo invariante pelo autor original.
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 a ajudar a fazer deste um livro cada vez melhor. sugeriam que Python era a soluo que eu estava procurando.

Encontrando um livro texto


Tendo decidido usar Python em ambas as minhas classes introdutrias de cincia da computao do ano seguinte, o problema mais urgente era a falta de um livro texto disponvel.

Achamos que este livro um testemunho dos O contedo livre veio em socorro. benefcios e possibilidades futuras deste tipo de colaborao, Anteriormente naquele ano, Richard Stallman tinha me cujo modelo tem sido colocado por Richard Stallman e pela apresentado a Allen Downey. Ambos havamos escrito a Free Software Foundation. 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 Como e porque eu vim a usar Python Computer Scientist. Quando li este livro, soube imediatamente que queria utiliz-lo nas minhas aulas. Era o texto mais claro e Em 1999, o Exame de Colocao Avanada em Cincia da proveitoso em cincia da computao que eu tinha visto. Ele Computao da Comisso de Faculdades (College Board?s enfatizava o processo de reflexo envolvido em programao Advanced Placement (AP) Computer Science) foi aplicado em em vez de caractersticas de uma linguagem em particular. LC++ pela primeira vez. Como em muitas escolas secundrias lo fez de mim imediatamente um melhor professor. atravs do pas, a deciso de mudar linguagens teve um O How to Think Like a Computer Scientist era impacto direto no currculo de cincia da computao na no s um excelente livro, como tambm fora lanado sob Yorktown High School em Arlington, Virginia, onde leciono. At ento, Pascal era a linguagem didtica para nossos cursos uma licena pblica GNU, o que significava que ele poderia de primeiro ano e avanado. Mantendo a prtica corrente de ser usado livremente e modificado para atender as dar aos estudantes dois anos de exposio mesma linguagem, necessidades de seu usurio. Uma vez que eu havia decidido tomamos a deciso de mudar para C++ no curso de primeiro usar Python, me ocorreu que eu poderia traduzir a verso ano para o ano letivo de 1997-98 de modo que estaramos em original do livro de Allen do Java para a nova linguagem. sincronismo com a mudana da Comisso de Faculdades Apesar de no estar capacitado para escrever eu mesmo um (College Board?s) em relao ao curso avanado para o ano livro texto, tendo o livro de Allen a partir do qual trabalhar tornou possvel para mim faz-lo, ao mesmo tempo seguinte. demonstrando que o modelo de desenvolvimento cooperativo Dois anos depois, eu estava convencido que to bem utilizado em software poderia tambm funcionar para C++ foi uma escolha infeliz para introduzir os alunos em contedo educacional. cincia da computao. Ao mesmo tempo em que certamente Trabalhar neste livro pelos ltimos dois anos uma linguagem de programao muito poderosa, tambm tem sido recompensador para mim e meus alunos, e eles uma linguagem extremamente difcil de aprender e de ensinar. Eu me encontrava constantemente lutando com a sintaxe tiveram um grande papel neste processo. A partir do momento difcil do C++ e as mltiplas maneiras de fazer a mesma coisa, em que eu podia fazer mudanas instantneas assim que e estava, como resultado, perdendo muitos alunos algum encontrasse um erro ortogrfico ou um trecho difcil, desnecessariamente. Convencido de que deveria existir uma eu os encorajei a procurar por erros no livro, dando a eles linguagem melhor para a nossa classe de primeiro ano, fui pontos de bonificao cada vez que eles fizessem uma sugesto que resultasse em uma mudana no texto. Isto teve o procurar por uma alternativa ao C++. duplo benefcio de encoraj-los a ler o texto mais Eu precisava de uma linguagem que pudesse cuidadosamente e de ter o texto totalmente revisado por seus rodar nas mquinas em nosso laboratrio Linux bem como nas crticos mais importantes: alunos utilizando-o para aprender plataformas Windows e Macintosh que a maioria dos alunos cincia da computao. tinha em casa. Eu precisava que ela fosse gratuita e disponvel Para a segunda metade do livro, sobre eletronicamente, assim os alunos poderiam utiliz-la em casa independentemente de suas rendas. Eu queria uma linguagem programao orientada a objetos, eu sabia que seria preciso que fosse utilizada por programadores profissionais, e que algum com uma maior experincia do que a minha em tivesse uma comunidade de desenvolvimento ativa em torno programao real para faz-lo corretamente. O livro esteve em dela. Ela teria que suportar ambas, programao procedural e estado inacabado por quase um ano at que a comunidade de orientada a objetos. E, mais importante, deveria ser fcil de software livre providenciasse mais uma vez os meios aprender e de ensinar. Quando considerei as alternativas tendo necessrios para sua concluso. em mente aquelas metas, Python sobressaiu-se como a melhor Eu recebi um e-mail de Chris Meyers mostrando candidata para a tarefa. interesse no livro. Chris um programador profissional que Pedi para um dos talentosos estudantes de comeou a dar um curso de programao no ano anterior Yorktown, Matt Ahrens, que experimentasse Python. Em dois usando Python no Lane Community College em Eugene, meses ele no s aprendeu a linguagem como tambm Oregon. A perspectiva de dar aquele curso ligou Chris ao livro, escreveu uma aplicao chamada pyTicket que possibilitou e ele comeou a ajudar o trabalho imediatamente. Pelo final do nossa equipe reportar problemas de tecnologia pela Web. Eu ano letivo ele tinha criado um projeto colaborativo em nosso sabia que Matt no poderia ter finalizado uma aplicao Website em http://www.ibiblio.org/obp chamado Python for daquele porte em perodo to curto em C++, esta realizao, Fun e estava trabalhando com alguns dos meus alunos mais combinada com a avaliao positiva do Python dada por Matt, avanados como um guru, guiando-os alm de onde eu poderia

Como pensar como um cientista da Computao usando Python 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 Introduzindo programao com Python e endereos no ajudam neste caso. Em Python uma varivel um nome que se refere a uma coisa. Este um conceito muito O processo de traduzir e utilizar How to Think Like a mais intuitivo para alunos iniciantes e est muito mais Computer Scientist pelos ltimos dois anos tem confirmado a prximo do significado de ?varivel? que eles aprenderam em convenincia de Python no ensino de alunos iniciantes. Python seus cursos de matemtica. Eu tive muito menos dificuldade simplifica tremendamente os programas exemplo e torna em ensinar variveis este ano do que tive no passado, e gastei menos tempo ajudando aos alunos com problemas no uso idias importantes de programao mais fceis de ensinar. delas. O primeiro exemplo do texto ilustra este ponto. Um outro exemplo de como Python ajuda no o tradicional programa ?Al mundo?, do qual na verso C++ ensino e aprendizagem de programao em sua sintaxe para do livro se parece com isto: funo. Meus alunos tm sempre tido grande dificuldade na #include <iostream.h> 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 void main() um argumento. Python vem em auxlio com uma sintaxe no { apenas curta quanto bela. As definies de funo comeam cout << "Al, mundo." << endl; 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 Na verso Python, ele se transforma em: chama uma funo, simplesmente chame-a digitando o nome print "Al, Mundo!" dela?. Parmetros ficam nas definies; argumentos vo com Mesmo sendo um exemplo trivial, as vantagens as chamadas. No existem tipos de retorno, tipos de parmetro do Python saltam aos olhos. O curso de Cincia da ou passagem de parmetros por valor ou por referncia no Computao I que ministro em Yorktown no tem pr- meio do caminho, permitindo-me ensinar funes em menos requisitos, assim, muitos dos alunos que veem esse exemplo da metade do tempo que isto me tomava anteriormente, com esto olhando para o seu primeiro programa. Alguns deles uma melhor compreenso. esto indubitavelmente nervosos, por j terem ouvido falar que A utilizao do Python tem melhorado a programao de computadores difcil de aprender. A verso efetividade de nosso programa em cincia da computao para C++ tem sempre me forado a escolher entre duas opes todos os estudantes. Eu vejo um nvel geral de sucesso muito insatisfatrias: ou explicar os comandos #include, void main(), mais alto e um nvel mais baixo de frustrao do que {, e } e arriscar confundir ou intimidar alguns dos alunos logo experimentei durante os dois anos em que ensinei C++. Eu assim que iniciam, ou dizer a eles ?No se preocupem com avano mais rpido com melhores resultados. Mais alunos todas estas coisas agora; falaremos sobre elas mais tarde?, e deixam o curso com a habilidade de criar programas correr o mesmo risco. O objetivo educacional neste ponto do significativos e com uma atitude positiva em relao a curso introduzir os alunos idia de comando em experincia de programao que isso traz. 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 Construindo uma comunidade conseguir isto, e nada mais. lev-los. 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 podemos ?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 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

GNU Free Documentation License #14

Como pensar como um cientista da Computao usando Python

Contributor List

To paraphrase the philosophy of the Free Software Foundation, this book is free like free speech, but not necessarily free like free pizza. It came about because of a collaboration that would not have been possible without the GNU Free Documentation License. So we thank the Free Software Foundation for developing this license and, of course, making it available to us. We also thank the more than 100 sharp-eyed and thoughtful readers who have sent us suggestions and corrections over the past few years. In the spirit of free software, we decided to express our gratitude in the form of a contributor list. Unfortunately, this list is not complete, but we are doing our best to keep it up to date. If you have a chance to look through the list, you should realize that each person here has spared you and all subsequent readers from the confusion of a technical error or a less-than-transparent explanation, just by sending us a note. Impossible as it may seem after so many corrections, there may still be errors in this book. If you should stumble across one, please check the online version of the book at http://thinkpython.com, which is the most up-todate version. If the error has not been corrected, please take a minute to send us email at feedback@thinkpython.com. If we make a change due to your suggestion, you will appear in the next version of the contributor list (unless you ask to be omitted). Thank you!

unconsciously in Chapter 1 needed to be changed to subconsciously.


Chris McAloon sent in several corrections to Sections 3.9 and 3.10. Matthew J. Moelter has been a long-time contributor who sent in numerous corrections and suggestions to the book. Simon Dicon Montford reported a missing function denition and several typos in Chapter 3. He also found errors in the increment function in Chapter 13. John Ouzts corrected the denition of return value in Chapter 3. Kevin Parks sent in valuable comments and suggestions as to how to improve the distribution of the book. David Pool sent in a typo in the glossary of Chapter 1, as well as kind words of encouragement. Michael Schmitt sent in a correction to the chapter on les and exceptions. Robin Shaw pointed out an error in Section 13.1, where the printTime function was used in an example without being dened. Paul Sleigh found an error in Chapter 7 and a bug in Jonah Cohens Perlscript that generates HTML from LaTeX. Craig T. Snydal is testing the text in a course at Drew University. He has contributed several valuable suggestions and corrections. Ian Thomas and his students are using the text in a programming course. They are the rst ones to test the chapters in the latter half of the book, and they have made numerous corrections and suggestions. Keith Verheyden sent in a correction in Chapter 3. Peter Winstanley let us know about a longstanding error in our Latin in Chapter 3. Chris Wrobel made corrections to the code in the chapter on le I/O and exceptions. Moshe Zadka has made invaluable contributions to this pro ject. In addition to writing the rst draft of the chapter on Dictionaries, he provided continual guidance in the early stages of the book. Christoph Zwerschke sent several corrections and pedagogic suggestions, and explained the di erence between gleich and selbe. James Mayer sent us a whole slew of spelling and typographical errors, including two in the contributor list. Hayden McAfee caught a potentially confusing inconsistency between two examples. Angel Arnal is part of an international team of translators working on the Spanish version of the text. He has also found several errors in the English version. Tauhidul Hoque and Lex Berezhny created the

Lloyd Hugh Allen sent in a correction to Section 8.4. Yvon Boulianne sent in a correction of a semantic error in Chapter 5. Fred Bremmer submitted a correction in Section 2.1. Jonah Cohen wrote the Perl scripts to convert the LaTeX source for this book into beautiful HTML. Michael Conlon sent in a grammar correction in Chapter 2 and an improvement in style in Chapter 1, and he initiated discussion on the technical aspects of interpreters. Benoit Girard sent in a correction to a humorous mistake in Section 5.6. Courtney Gleason and Katherine Smith wrote horsebet.py, which was used as a case study in an earlier version of the book. Their program can now be found on the website. Lee Harr submitted more corrections than we have room to list here, and indeed he should be listed as one of the principal editors of the text. James Kaylin is a student using the text. He has submitted numerous corrections. David Kershaw xed the broken catTwice function in Section 3.10. Eddie Lam has sent in numerous corrections to Chapters 1, 2, and 3. He also xed the Makele so that it creates an index the rst time it is run and helped us set up a versioning scheme. Man-Yong Lee sent in a correction to the example code in Section 2.4. David Mayo pointed out that the word

GNU Free Documentation License #15

Como pensar como um cientista da Computao usando Python illustrations in Chapter 1 and improved many of the with translating the book into HTML. other illustrations. Jason Armstrong saw the missing word in Chapter 2. Dr. Michele Alzetta caught an error in Chapter 8 and Louis Cordier noticed a spot in Chapter 16 where the sent some interesting pedagogic comments and code didnt match the text. suggestions about Fibonacci and Old Maid. Brian Cain suggested several clarications in Andy Mitchell caught a typo in Chapter 1 and a Chapters 2 and 3. broken example in Chapter 2.

Kalin Harvey suggested a clarication in Chapter 7 and caught some typos. Christopher P. Smith caught several typos and is helping us prepare to update the book for Python 2.2. David Hutchins caught a typo in the Foreword. Gregor Lingl is teaching Python at a high school in Vienna, Austria. He is working on a German translation of the book, and he caught a couple of bad errors in Chapter 5. Julie Peters caught a typo in the Preface. Florin Oprina sent in an improvement in makeTime, a correction in printTime, and a nice typo. D. J. Webre suggested a clarication in Chapter 3. Ken found a stful of errors in Chapters 8, 9 and 11. Ivo Wever caught a typo in Chapter 5 and suggested a clarication in Chapter 3. Curtis Yanko suggested a clarication in Chapter 2. Ben Logan sent in a number of typos and problems

Rob Black sent in a passel of corrections, including some changes for Python 2.2. Jean-Philippe Rey at Ecole Centrale Paris sent a number of patches, including some updates for Python 2.2 and other thoughtful improvements. Jason Mader at George Washington University made a number of useful suggestions and corrections. Jan Gundtofte-Bruun reminded us that a error is an error. Abel David and Alexis Dinno reminded us that the plural of matrix is matrices, not matrixes. This error was in the book for years, but two readers with the same initials reported it on the same day. Weird. Charles Thayer encouraged us to get rid of the semicolons we had put at the ends of some statements and to clean up our use of argument and parameter. Roger Sperberg pointed out a twisted piece of logic in Chapter 3.

GNU Free Documentation License #16

Verso Brasileira

A verso traduzida para Portugus Brasileiro foi feita pela equipe do site http://pensarpython.incubadora.fapesp.br, abaixo relacionada:

Adrovane Kade (adrovane) Alex Augusto da Luz dos Santos (nowayx) Claudio Fernando Berrondo Soares (cl-audio) Daniel Rosa Franzini (danielt3) Douglas Soares de Andrade (dsa) Fabio Rizzo Matos (fabrizmat) Imre Simon (imres) Joao Paulo Liberato (jpliberato) Joo Paulo Gomes Vanzuita (taken) Julio Monteiro (jmonteiro) Luciano Ramalho (luciano) Marcus Pereira (mvmendes) Mario O. de Menezes (modemene) Paulo J. S. Silva (pjssilva) Victor Rafael da Paixo Lopes (reije) marta mello (martamello) vitor gurgel (vitor_gurgel)

Esta diagramao foi feita por Crlisson Galdino <bardo@castelodotempo.com>, com algumas modificaes visando a facilitar a publicao em duas colunas. Alguns comentrios de depurao feitos pela equipe de traduo foram omitidos.

Captulo 1: O caminho do programa

O objetivo deste livro ensinar o leitor a pensar como um ora realizando computaes. cientista da computao. Essa maneira de pensar combina algumas das melhores caractersticas da matemtica, da engenharia e das cincias naturais. Como os matemticos, os cientistas da computao usam linguagens formais para representar idias (especificamente, computaes). Como os engenheiros, eles projetam coisas, montando sistemas a partir de componentes e avaliando as vantagens e desvantagens de diferentes alternativas. Como os cientistas naturais, eles O compilador l o programa e o traduz observam o comportamento de sistemas complexos, formulam completamente antes que o programa comece a rodar. Neste hipteses e testam previses. caso, o programa escrito em linguagem de alto nvel A habilidade mais importante de um cientista da chamado de cdigo fonte, e o programa traduzido chamado computao a soluo de problemas. Soluo de problemas de cdigo objeto ou executvel. Uma vez que um programa a habilidade de formular questes, pensar criativamente compilado, voc pode execut-lo repetidamente, sem que sobre solues possveis e expressar uma soluo de forma precise de nova traduo. clara e precisa. Ocorre que aprender a programar uma excelente oportunidade de praticar a habilidade da soluo de problemas. por isso que este captulo se chama "O caminho do programa". Em certo nvel, voc estar aprendendo a programar, habilidade que til em si mesma. Em outro nvel, Python considerada uma linguagem voc usar a programao como um meio para atingir um interpretada, porque os programas em Python so executados objetivo. medida que voc for avanando na leitura, esse por um interpretador. Existem duas maneiras de usar o objetivo ficar mais claro. 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: 1.1 A linguagem de programao Python $ python Python a linguagem de programao que voc vai estudar Python 2.4.3 (#2, Oct 6 2006, 07:49:22) neste livro. Python um exemplo de linguagem de programao de alto nvel; outras linguagens de alto nvel de [GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2 Type "help", "copyright", "credits" or "license" que voc j pode ter ouvido falar so C, C++, Perl e Java. Como voc pode deduzir a partir da expresso for more information. "linguagem de alto nvel", tambm existem as "linguagens de >>> print 1 + 1 baixo nvel", s vezes chamadas de "linguagens de mquina" 2 ou "linguagem assembly" ("linguagens de montagem"). Dito A primeira linha deste exemplo o comando de maneira simples, o computador s consegue executar que inicia o interpretador Python. As trs linhas seguintes so programas escritos em linguagens de baixo nvel. Deste modo, mensagens do interpretador. A quarta linha comea com >>>, programas escritos em linguagens de alto nvel precisam ser que o sinal usado pelo interpretador para indicar que ele est processados antes que possam rodar. Esse processamento pronto. No exemplo anterior, digitamos print 1 + 1 e o extra toma algum tempo, o que uma pequena desvantagem interpretador respondeu 2. em relao s linguagens de alto nvel. Voc tambm pode escrever um programa em Mas as vantagens so enormes. Primeiro, um arquivo e usar o interpretador para executar o contedo muito mais fcil programar em uma linguagem de alto nvel. desse arquivo. Um arquivo como este chamado de script. mais rpido escrever programas em uma linguagem de alto Por exemplo, usamos um editor de texto para criar um arquivo nvel; eles so mais curtos e mais fceis de ler e mais chamado leticia.py com o seguinte contedo: provvel que estejam corretos. Segundo, as linguagens de alto nvel so portveis, o que significa que podem rodar em print 1 + 1 diferentes tipos de computador, com pouca ou nenhuma Por conveno, arquivos que contenham modificao. Programas em baixo nvel s podem rodar em programas em Python tm nomes que terminam com .py. um nico tipo de computador e precisam ser re-escritos para Para executar o programa, temos de dizer ao rodar em outro tipo. interpretador o nome do script: Devido a essas vantagens, quase todos os programas so escritos em linguagens de alto nvel. As de $ python leticia.py baixo nvel so utilizadas somente para umas poucas 2 aplicaes especializadas. Em outros ambientes de desenvolvimento, os detalhes da execuo de programas podem ser diferentes. Dois tipos de programas processam linguagens de alto nvel, traduzindo-as em linguagens de baixo nvel: Alm disso, a maioria dos programas so mais interessantes interpretadores e compiladores. O interpretador l um do que esse... programa escrito em linguagem de alto nvel e o executa, ou A maioria dos exemplos neste livro so seja, faz o que o programa diz. Ele processa o programa um executados a partir da linha de comando. Trabalhar com a pouco de cada vez, alternadamente: ora lendo algumas linhas,

Como pensar como um cientista da Computao usando Python linha de comando conveniente no desenvolvimento e sintaxe no chegam a ser um problema significativo e por testagem de programas, porque voc pode digitar os isso que conseguimos ler a poesia moderna de e. e. cummings programas e execut-los imediatamente. Uma vez que voc sem cuspir mensagens de erro. Python no to indulgente. tem um programa que funciona, deve guard-lo em um script, Se o seu programa tiver um nico erro de sintaxe em algum de forma a poder execut-lo ou modific-lo no futuro. lugar, o interpretador Python vai exibir uma mensagem de erro e vai terminar - e o programa no vai rodar. Durante as primeiras semanas da sua carreira como programador, voc 1.2 O que um programa? provavelmente perder um bocado de tempo procurando erros de sintaxe. Conforme for ganhando experincia, entretanto, Um programa uma seqncia de instrues que especificam cometer menos erros e os localizar mais rpido. como executar uma computao. A computao pode ser algo matemtico, como solucionar um sistema de equaes ou 1.3.2 Erros em tempo de execuo encontrar as razes de um polinmio, mas tambm pode ser uma computao simblica, como buscar e substituir uma (runtime errors) palavra em um documento ou (estranhamente) compilar um O segundo tipo de erro o erro de runtime, ou erro em tempo programa. de execuo, assim chamado porque s aparece quando voc Os detalhes so diferentes em diferentes roda o programa. Esses erros so tambm conhecidos como linguagens, mas algumas instrues bsicas aparecem em excees, porque normalmente indicam que alguma coisa praticamente todas as linguagens: excepcional (e ruim) aconteceu. entrar Pegar dados do teclado, de um arquivo ou de algum outro dispositivo. sair Mostrar dados na tela ou enviar dados para um arquivo ou outro dispositivo. operaes matemticas calcular Executar bsicas, como adio e multiplicao. executar Checar certas condies e executar a condicionalmente seqncia apropriada de instrues. Erros de runtime so raros nos programas simples que voc vai ver nos primeiros captulos - ento, vai demorar um pouco at voc se deparar com um erro desse tipo.

1.3.3 Erros de semntica

O terceiro tipo de erro o erro de semntica (mais comumente chamado erro de lgica). Mesmo que o seu programa tenha um erro de semntica, ele vai rodar com repetir Executar alguma ao repetidamente, sucesso, no sentido de que o computador no vai gerar normalmente com alguma variao. nenhuma mensagem de erro. S que o programa no vai fazer Acredite se quiser: isso praticamente tudo. a coisa certa, vai fazer alguma outra coisa. Especificamente, Todos os programas que voc j usou, no importa quo aquilo que voc tiver dito para ele fazer. complicados, so feitos de instrues mais ou menos O problema que o programa que voc parecidas com essas. Assim, poderamos definir programao escreveu no aquele que voc queria escrever. O significado como o processo de dividir uma tarefa grande e complexa em do programa (sua semntica ou lgica) est errado. Identificar sub-tarefas cada vez menores, at que as sub-tarefas sejam erros semnticos pode ser complicado, porque requer que simples o suficiente para serem executadas com uma dessas voc trabalhe de trs para frente, olhando a sada do programa instrues bsicas. e tentando imaginar o que ele est fazendo. Isso pode parecer um pouco vago, mas vamos voltar a esse tpico mais adiante, quando falarmos sobre 1.3.4 Depurao experimental algoritmos.

(Debugging)

Uma das habilidades mais importantes que voc vai adquirir a de depurar. Embora possa ser frustrante, depurar uma das Programar um processo complicado e, como feito por partes intelectualmente mais ricas, desafiadoras e interessantes seres humanos, freqentemente conduz a erros. Por mero da programao. capricho, erros em programas so chamados de bugs e o De certa maneira, a depurao como um processo de encontr-los e corrigi-los chamado de trabalho de detetive. Voc se depara com pistas, e tem que depurao (debugging). deduzir os processos e eventos que levaram aos resultados que Trs tipos de erro podem acontecer em um aparecem. programa: erros de sintaxe, erros em tempo de execuo Depurar tambm como uma cincia (runtime errors) e erros de semntica. Distinguir os trs tipos experimental. Uma vez que voc tem uma idia do que est ajuda a localiz-los mais rpido: errado, voc modifica o seu programa e tenta de novo. Se a sua hiptese estava correta, ento voc consegue prever o resultado da modificao e fica um passo mais perto de um 1.3.1 Erros de sintaxe programa que funciona. Se a sua hiptese estava errada, voc Python s executa um programa se ele estiver sintaticamente tem que tentar uma nova. Como Sherlock Holmes mostrou, correto; caso contrrio, o processo falha e retorna uma "Quando voc tiver eliminado o impossvel, aquilo que restou, mensagem de erro. Sintaxe se refere estrutura de um ainda que improvvel, deve ser a verdade." (Arthur Conan programa e s regras sobre esta estrutura. Por exemplo, em Doyle, O signo dos quatro). portugus, uma frase deve comear com uma letra maiscula Para algumas pessoas, programao e e terminar com um ponto. depurao so a mesma coisa. Ou seja, programar o esta frase contm um erro de sintaxe. Assim processo de gradualmente depurar um programa, at que ele faa o que voc quer. A idia comear com um programa como esta que faa alguma coisa e ir fazendo pequenas modificaes, Para a maioria dos leitores, uns errinhos de

1.3 O que depurao (debugging)?

GNU Free Documentation License #19

Como pensar como um cientista da Computao usando Python depurando-as conforme avana, de modo que voc tenha ambigidade As linguagens naturais esto cheias de sempre um programa que funciona. ambigidades, que as pessoas contornam usando pistas contextuais e outras Por exemplo, o Linux um sistema operacional informaes. J as linguagens formais so que contm milhares de linhas de cdigo, mas comeou como desenvolvidas para serem quase ou um programa simples, que Linus Torvalds usou para explorar totalmente desprovidas de ambigidade, o o chip Intel 80386. De acordo com Larry Greenfield, "Um dos que significa que qualquer expresso tem primeiros projetos de Linus Torvalds foi um programa que precisamente s um sentido, deveria alternar entre imprimir AAAA e BBBB. Isso depois independentemente do contexto. evoluiu at o Linux". (The Linux User's Guide Verso Beta 1) redundncia Para compensar a ambigidade e reduzir Captulos posteriores faro mais sugestes sobre mal-entendidos, emprega-se muita depurao e outras prticas de programao. redundncia nas linguagens naturais, o que freqentemente as torna prolixas. As linguagens formais so menos redundantes e 1.4 Linguagens naturais e linguagens formais mais concisas. Linguagens naturais so as linguagens que as pessoas falam, literalidade As linguagens naturais esto cheias de como o portugus, o ingls e o espanhol. Elas no foram expresses idiomticas e metforas. Se eu projetadas pelas pessoas (muito embora as pessoas tentem digo "Caiu a ficha", possvel que no exista colocar alguma ordem nelas); elas evoluram naturalmente. ficha nenhuma, nem nada que tenha cado. Nas linguagens formais, no h sentido Linguagens formais so linguagens que foram ambguo. projetadas por pessoas, para aplicaes especficas. Por Pessoas que crescem falando uma linguagem exemplo, a notao que os matemticos usam uma linguagem formal, que particularmente boa em denotar natural -- ou seja, todo mundo - muitas vezes tm dificuldade relaes entre nmeros e smbolos. Os qumicos usam uma de se acostumar com uma linguagem formal. De certa linguagem formal para representar a estrutura qumica das maneira, a diferena entre linguagens formais e naturais como a diferena entre poesia e prosa, porm mais acentuada: 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 expresso 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 $ no um token 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 expresso -- quer dizer, ao modo como os tokens esto arrumados. A expresso 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. Faa este exerccio: crie o que parea ser uma frase bem estruturada em portugus com "tokens" irreconhecveis dentro dela. Depois escreva outra frase com todos os "tokens" vlidos, mas com uma estrutura invlida. Quando voc l uma frase em portugus ou uma expresso em uma linguagem formal, voc tem de imaginar como a estrutura da frase (embora, em uma linguagem natural, voc faa isso inconscientemente). Este processo chamado parsing (anlise sinttica). poesia As palavras so usadas pela sua sonoridade, alm de seus sentidos, e o poema como um todo cria um efeito ou uma reao 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 exato 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, lembrese de que linguagens formais so muito mais densas do que linguagens naturais, por isso, mais demorado 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 analisar o programa na sua cabea, identificando os tokens e interpretando a estrutura. Finalmente, os detalhes so importantes. Pequenas coisas, como, erros ortogrficos e m pontuao, com as quais voc pode se safar nas linguagens naturais, podem fazer uma grande diferena em uma linguagem formal.

1.5 O primeiro programa

Tradicionalmente, o primeiro programa escrito em uma nova linguagem de programao chamado de "Al, Por exemplo, quando voc ouve a frase, "Caiu a Mundo!" porque tudo que ele faz apresentar as palavras ficha", entende que "a ficha" o sujeito e "caiu" o verbo. "Al, Mundo!". Em Python, ele assim: Uma vez que voc analisou a frase, consegue entender o seu significado, ou a semntica da frase. Assumindo que voc print "Al, Mundo!" saiba o que uma ficha e o que significa cair, voc entender Isso um exemplo de um comando print, que, o sentido geral dessa frase. na realidade, no "imprime" nada em papel. Ele apresenta o Muito embora as linguagens formais e as valor na tela. Neste caso, o resultado so as palavras: naturais tenham muitas caractersticas em comum -- tokens, Al, Mundo! estrutura, sintaxe e semntica -- existem muitas diferenas: GNU Free Documentation License #20

Como pensar como um cientista da Computao usando Python As aspas no programa marcam o comeo e o (program) uma computao. fim do valor; elas no aparecem no resultado final. algoritmo Processo geral para soluo de uma certa Algumas pessoas julgam a qualidade de uma (algorithm) categoria de problemas. linguagem de programao pela simplicidade do programa bug Erro em um programa. "Al, Mundo!". Por esse padro, Python se sai to bem quanto possvel. depurao O processo de encontrar e remover (debugging) qualquer um dos trs tipos de erros de programao.

1.6 Glossrio

sintaxe (syntax) A estrutura de um programa. erro de sintaxe Erro em um programa, que torna (syntax error) impossvel a anlise sinttica (logo, tambm impossvel a interpretao). erro em tempo de Erro que no ocorre at que o programa execuo seja executado, mas que impede que o (runtime error) programa continue. exceo Um outro nome para um erro em tempo (exception) de execuo ou erro de runtime. erro de semntica Erro em um programa, que o leva a fazer (semantic error) algo diferente do que pretendia o programador. semntica O significado de um programa. (semantics) linguagem Qualquer lngua falada pelos seres que tenha evoludo natural (natural humanos language) naturalmente. linguagem Qualquer linguagem desenvolvida pelas formal (formal pessoas para propsitos especficos, tais language) como, a representao de idias matemticas ou programas de computadores; todas as linguagens de programao so linguagens formais. tomo (token) Um elemento bsico da estrutura sinttica de um programa, anlogo a uma palavra em uma linguagem natural. anlise sinttica Examinar um programa e analisar sua (parse) estrutura sinttica. comando print Instruo que leva o interpretador Python (`print` a apresentar um valor na tela. statement)

soluo de O processo de formular um problema, problemas encontrar uma soluo e expressar esta (problem solving) soluo. linguagem de alto Uma linguagem de programao como nvel (high-level Python: projetada para ser fcil para os language) seres humanos a utilizarem. linguagem de Uma linguagem de programao que baixo nvel (low- concebida para ser fcil para um level language) computador, tal como a linguagem de mquina ou a linguagem montagem (assembly language) portabilidade Propriedade que um programa tem, de (portability) rodar em mais de um tipo de computador. interpretar Executar um programa escrito em uma (interpret) linguagem de alto nvel, traduzindo-o uma linha de cada vez. compilar Traduzir todo um programa escrito em (compile) 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 (source code) nvel, antes de ter sido compilado. cdigo objeto A sada do compilador, depois que ele (object code) traduziu o programa. executvel Um outro nome para cdigo objeto que (executable) est pronto para ser executado. script Um programa guardado em um arquivo (normalmente um que ser interpretado). programa Conjunto de instrues que especifica

GNU Free Documentation License #21

Captulo 2: Variveis, expresses e comandos

programao a habilidade de manipular variveis. Uma varivel um nome que se refere a um valor.

2.1 Valores e tipos

O valor (por exemplo, letras e nmeros) uma das coisas fundamentais que um programa manipula. Os valores que j >>> mensagem = "E a, Doutor?" vimos at agora foram o 2 (como resultado, quando >>> n = 17 adicionamos 1 + 1) e "Al, Mundo!". >>> pi = 3.14159 Esses valores pertencem a tipos diferentes: 2 Este exemplo faz trs atribuies. A primeira um inteiro, e "Al, Mundo!" uma string, assim chamada atribui a string "E a, Doutor?" a uma nova varivel chamada porque "string", em ingls, quer dizer seqncia, srie, cadeia mensagem. A segunda d o valor inteiro 17 a n, e a terceira (de caracteres), ou neste caso, "srie de letras". Voc (e o atribui o nmero de ponto flutuante 3.14159 varivel interpretador) consegue identificar strings porque elas chamada pi. aparecem entre aspas. Uma maneira comum de representar variveis O comando print tambm funciona com inteiros: no papel escrever o nome delas com uma seta apontando para o valor da varivel. Esse tipo de figura chamado de >>> print 4 diagrama de estado porque mostra em que estado cada 4 varivel est (pense nisso como o estado de esprito da Se voc estiver em dvida sobre qual o tipo de varivel). O diagrama a seguir mostra o resultado das um determinado valor, o interpretador pode revelar: instrues de atribuio: >>> 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 float, porque estes nmeros so representados em um formato chamado ponto flutuante1: O comando print tambm funciona com >>> type(3.2) variveis: <type 'float'> O que dizer de valores como "17" e "3.2"? Eles >>> print mensagem parecem nmeros, mas esto entre aspas, como strings: E a, Doutor? >>> print n >>> type("17") 17 <type 'string'> >>> print pi >>> type("3.2") 3.14159 <type 'string'> Em cada um dos casos, o resultado o valor da Eles so strings. varivel. Variveis tambm tm tipo; novamente, podemos Ao digitar um nmero grande, tentador usar perguntar ao interpretador quais so eles: pontos entre grupos de trs dgitos, assim: 1.000.000. Isso no funciona porque Python usa o ponto como separador decimal. >>> type(mensagem) Usar a vrgula, como se faz em ingls, resulta numa expresso <type 'string'> vlida, mas no no nmero que queramos representar: >>> type(n) <type 'int'> >>> print 1,000,000 >>> type(pi) 1 0 0 No nada do que se esperava! Python <type 'float'> O tipo de uma varivel o tipo do valor ao qual interpreta 1,000,000 como uma tupla, algo que veremos no Captulo 9. Por hora, lembre-se apenas de no colocar vrgulas ela se refere. nos nmeros.

O comando de atribuio cria novas variveis e d a elas valores:

2.2 Variveis

2.3 Nomes de variveis e palavras reservadas

Os programadores geralmente escolhem nomes significativos Uma das caractersticas mais poderosas de uma linguagem de para suas variveis -- eles documentam para o qu a varivel usada.
1

N.T.: Observe o uso de ponto no lugar da vrgula para separar a parte inteira da parte fracionria.

Nomes de variveis podem ser arbitrariamente longos. Eles podem conter tanto letras quanto nmeros, mas

Como pensar como um cientista da Computao usando Python tm de comear com uma letra. Embora seja vlida a operadores. Se voc digitar uma expresso na linha de utilizao de letras maisculas, por conveno, no usamos. comando, o interpretador avalia e exibe o resultado: Se voc o fizer, lembre-se de que maisculas e minsculas so >>> 1 + 1 diferentes. Bruno e bruno so variveis diferentes. 2 O caractere para sublinhado ( _ ) pode aparecer Embora expresses contenham valores, em um nome. Ele muito utilizado em nomes com mltiplas palavras, tal como em meu_nome ou preco_do_cha_na_china. variveis e operadores, nem toda expresso contm todos estes elementos. Um valor por si s considerado uma expresso, Se voc der a uma varivel um nome invlido, do mesmo modo que uma varivel: causar um erro de sintaxe: >>> 17 >>> 76trombones = "grande parada" 17 SyntaxError: invalid syntax >>> x >>> muito$ = 1000000 2 SyntaxError: invalid syntax Avaliar uma expresso no exatamente a mesma coisa que imprimir um valor: >>> class = "Ciencias da Computacao 101" SyntaxError: invalid syntax >>> mensagem = "E a, Doutor?" 76trombones invlida porque no comea com >>> mensagem uma letra. muito$ invlida porque contm um caractere 'E a, Doutor?' ilegal, o cifro. Mas o que est errado com class? >>> print mensagem Ocorre que class uma das palavras reservadas em Python. Palavras reservadas definem as regras E a, Doutor? Quando Python exibe o valor de uma expresso, e a estrutura da linguagem e no podem ser usadas como usa o mesmo formato que voc usaria para entrar com o valor. nomes de variveis. No caso de strings, isso significa que as aspas so includas Python tem 29 palavras reservadas: [#]_. Mas o comando print imprime o valor da expresso, que, neste caso, o contedo da string. and def exec if not return Num script, uma expresso sozinha um assert del finally import or try comando vlido, porm sem efeito. O script: break elif for in pass while class else from is print yield 17 continue except global lambda raise 3.2 Pode ser til ter essa lista mo. Se o "Al, Mundo!" interpretador acusar erro sobre um de seus nomes de varivel e 1 + 1 voc no souber porqu, veja se o nome est na lista. no produz qualquer sada. Como voc mudaria o "script" para exibir os valores destas quatro expresses?

2.4 Comandos
Um comando uma instruo que o interpretador Python pode executar. Vimos at agora dois tipos de comandos: de exibio Operadores so smbolos especiais que representam (print) e de atribuio. computaes como adio e multiplicao. Os valores que o Quando voc digita um comando na linha de operador usa so chamados operandos. comando, o Python o executa e mostra o resultado, se houver Todas as expresses seguintes so vlidas em um. O resultado de um comando print a exibio de um Python e seus significados so mais ou menos claros: valor. Comandos de atribuio no produzem um resultado visvel. 20+32 hora-1 hora*60+minuto minuto/60 5**2 Um script normalmente contm uma seqncia \ de comandos. Se houver mais de um comando, os resultados (5+9)*(15-7) aparecero um de cada vez, conforme cada comando seja Em Python, os smbolos +, -, / e o uso de executado. parnteses para agrupamento tm o mesmo significado que em matemtica. O asterisco (*) o smbolo para multiplicao e Por exemplo, o "script": ** o smbolo para potenciao. print 1 Quando um nome de varivel aparece no lugar x = 2 de um operando, ele substitudo pelo valor da varivel, antes print 2 da operao ser executada. produz a sada: Adio, subtrao, multiplicao e potenciao fazem o que se espera, mas voc pode ficar surpreso com a 1 diviso. A operao seguinte tem um resultado inesperado: 2 Novamente, o comando de atribuio no >>> minuto = 59 produz sada. >>> minuto/60 0 O valor de minuto 59 e, em aritmtica 2.5 Avaliando expresses convencional, 59 dividido por 60 0,98333, no 0. A razo Uma expresso uma combinao de valores, variveis e para a discrepncia que Python est realizando uma diviso GNU Free Documentation License #23

2.6 Operadores e operandos

Como pensar como um cientista da Computao usando Python O operador * tambm funciona com strings; ele realiza repetio. Por exemplo, "Legal"*3 Quando ambos os operandos so inteiros, o "LegalLegaLegal". Um dos operadores tem que ser uma resultado tem de ser tambm um inteiro e, por conveno, a string; o outro tem que ser um inteiro. diviso inteira sempre arredonda para baixo, mesmo em casos como este, em que o inteiro seguinte est muito prximo: Por um lado, esta interpretao de + e * faz sentido pela analogia entre adio e multiplicao. Assim >>> minuto*100/60 como 4*3 equivale a 4+4+4, no de estranhar que "Legal"*3 98 seja o mesmo que "Legal"+"Legal"+"Legal". Por outro lado, De novo, o resultado arredondado para baixo, uma diferena significativa separa concatenao e repetio de mas agora pelo menos a resposta aproximadamente correta. adio e multiplicao. Voc saberia mencionar uma A alternativa usar a diviso em ponto flutuante, o que propriedade da adio e da multiplicao que no ocorre na concatenao e na repetio? veremos no captulo 3. inteira.

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:

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 Parnteses tm a mais alta precedncia e podem ser exemplo, ns sabemos como somar nmeros e sabemos como usados para forar uma expresso a ser avaliada na exibi-los; acontece que podemos fazer as duas coisas ao ordem que voc quiser. J que expresses entre mesmo tempo: parnteses so avaliadas primeiro, 2 * (3-1) 4, e (1+1)**(5-2) 8. Voc tambm pode usar parnteses >>> print 17 + 3 para tornar uma expresso mais fcil de ler, como em 20 (minuto * 100) / 60, ainda que isso no altere o Na realidade, a soma tem que acontecer antes da resultado. impresso, assim, as aes no esto na realidade acontecendo ao mesmo tempo. O ponto que qualquer expresso Exponenciao ou potenciao tem a prxima envolvendo nmeros, strings, e variveis pode ser usada precedncia mais alta, assim 2**1+1 3 e no 4, e dentro de um comando print. Voc j tinha visto um exemplo 3*1**3 3 e no 27. disto: Multiplicao e Diviso tm a mesma precedncia, que mais alta do que a da Adio e da Subtrao, print "Nmero de minutos desde a meia-noite: ", \ que tambm tm a mesma precedncia. Assim 2*3-1 hora*60+minuto d 5 em vez de 4, e 2/3-1 -1, no 1 (lembre-se de Esta possibilidade pode no parecer muito que na diviso inteira, 2/3=0). impressionante agora, mas voc ver outros exemplos em que a composio torna possvel expressar computaes Operadores com a mesma precedncia so avaliados complexas de modo limpo e conciso. da esquerda para a direita. Assim, na expresso minuto*100/60, a multiplicao acontece primeiro, Ateno: Existem limites quanto ao lugar onde resultando em 5900/60, o que se transforma voc pode usar certos tipos de expresso. Por exemplo, o lado produzindo 98. Se as operaes tivessem sido esquerdo de um comando de atribuio tem que ser um nome avaliadas da direita para a esquerda, o resultado de varivel, e no uma expresso. Assim, o seguinte no poderia ter sido 59*1, que 59, que est errado. vlido: minuto+1 = hora.

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" assada = " com canela" print fruta + assada A sada deste programa banana com canela. O espao antes da palavra com parte da string e necessrio para produzir o espao entre as strings concatenadas.

2.11 Glossrio
valor (value) Um nmero ou string (ou outra coisa que ainda vamos conhecer) que pode ser atribuda a uma varivel ou computada 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 vistos so: inteiros (tipo int), nmeros em pontoflutuante (tipo float) e strings (tipo string). ponto-flutuante Formato para representar nmeros que (floating-point) possuem partes fracionrias. varivel Nome que se refere a um valor. (variable) comando Trecho de cdigo que representa uma (statement) instruo ou ao. At agora, os comandos vistos foram de atribuio e exibio.

GNU Free Documentation License #24

Como pensar como um cientista da Computao usando Python atribuio Comando que atribui um valor a uma (assignment) varivel. diagrama de Representao grfica de um conjunto de estado (state variveis e os valores aos quais elas se diagram) referem. palavra-chave Palavra reservada usada pelo compilador (keyword) para analisar o programa; voc no pode usar palavras-chave como if, def, e while como nomes de variveis. operador Smbolo especial que representa uma (operator) computao simples, como adio, multiplicao ou concatenao de strings. operando Um dos valores sobre o qual o operador (operand) opera. expresso Combinao de variveis, operadores e (expression) valores, que representa um resultado nico. avaliar Simplificar uma expresso atravs da (evaluate) realizao de operaes, para produzir um valor nico. diviso inteira Operao que divide um inteiro por outro e (integer resulta em um inteiro. A diviso inteira division) resulta no nmero de vezes que o numerador divisvel pelo denominador e descarta qualquer resto. regras de O conjunto de regras que governa a ordem precedncia em que expresses envolvendo mltiplos (rules of operadores e operandos so avaliadas. precedence) concatenar Juntar dois operandos lado a lado. (concatenate) composio Habilidade de combinar expresses (composition) comandos simples em expresses comandos compostos, de forma representar computaes complexas forma concisa. e e a de

comentrio Informao em um programa dirigida a (comment) outros programadores (ou qualquer pessoa que esteja lendo o cdigo fonte) e que no tem efeito na execuo do programa.

GNU Free Documentation License #25

Captulo 3: Funes

>>> str(32) '32' 3.1 Chamadas de funes >>> str(3.14149) '3.14149' Voc j viu um exemplo de uma chamada de funo: Pode parecer curioso que Python faa distino >>> type('32') entre o valor inteiro 1 e o valor em ponto flutuante 1.0. Eles podem representar o mesmo nmero, mas pertencem a tipos <type 'str'> O nome da funo type e ela exibe o tipo de diferentes. A razo que eles so representados de modo um valor ou varivel. O valor ou varivel, que chamado de diferente dentro do computador. argumento da funo, tem que vir entre parnteses. comum se dizer que uma funo 'recebe' um valor e 'retorna' um 3.3 Coero entre tipos resultado. O resultado chamado de valor de retorno. Em vez de imprimir um valor de retorno, Agora que podemos converter entre tipos, temos outra maneira podemos atribui-lo a uma varivel: de lidar com a diviso inteira. Voltando ao exemplo do captulo anterior, suponha que queiramos calcular a frao de >>> bia = type('32') hora que j passou. A expresso mais bvia, minuto / 60, faz >>> print bia aritmtica inteira, assim, o resultado sempre 0, mesmo aos <type 'str'> 59 minutos passados da hora. Como outro exemplo, a funo id recebe um Uma soluo converter minuto para ponto valor ou uma varivel e retorna um inteiro, que atua como um flutuante e fazer a diviso em ponto flutuante: identificador nico para aquele valor: >>> minuto = 59 >>> id(3) >>> float(minuto) / 60 134882108 0.983333333333 >>> bia = 3 Opcionalmente, podemos tirar vantagem das >>> bia(beth) regras de converso automtica entre tipos, chamada de 134882108 coero de tipos. Para os operadores matemticos, se Todo valor tem um id, que um nmero nico qualquer operando for um float, o outro automaticamente relacionado ao local onde ele est guardado na memria do convertido para float: computador. O id de uma varivel o id do valor a qual ela se >>> minuto = 59 refere. >>> minuto / 60.0 0.983333333333 3.2 Converso entre tipos Fazendo o denominador um float, foramos o Python a fazer a diviso em ponto flutuante. Python 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: 3.4 Funes matemticas >>> int('32') 32 >>> int('Al') ValueError: invalid literal for int() : Al int tambm pode converter valores em ponto flutuante para inteiro, mas lembre que isso trunca a parte fracionria: Em matemtica, voc provavelmente j viu funes como seno (sin) e log, e 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).

>>> int(3.99999) 3 Este processo pode ser aplicado repetidamente >>> int(-2.3) para avaliar expresses mais complicadas, como -2 log(1/sin(pi/2)). Primeiro voc avalia o argumento na funo A funo float converte inteiros e strings em mais interna, depois avalia a funo e assim por diante. nmeros em ponto flutuante: Python tem um mdulo matemtico que prov a >>> float(32) maioria das funes matemticas mais familiares. Um mdulo um arquivo que contm uma coleo de funes 32.0 relacionadas agrupadas juntas. >>> float('3.14159') Antes de podermos usar as funes contidas em 3.14159 Finalmente, a funo str converte para o tipo um mdulo, temos de import-lo: string:

Como pensar como um cientista da Computao usando Python >>> import math COMANDOS Voc pode usar o nome que quiser para as Para chamar uma das funes, temos que especificar o nome do mdulo e o nome da funo, separados funes que criar, exceto as palavras reservadas do Python. A por um ponto. Esse formato chamado de notao de ponto: lista de parmetros especifica que informao, se houver alguma, voc tem que fornecer para poder usar a nova funo. >>> decibel = math.log10(17.0) Uma funo pode ter quantos comandos forem >>> angulo = 1.5 necessrios, mas eles precisam ser endentados a partir da >>> altura = math.sin(angulo) margem esquerda. Nos exemplos deste livro, usaremos uma A primeira instruo atribui a decibel o endentao de dois espaos. logaritmo de 17 na base 10. Existe tambm uma funo As primeiras funes que vamos mostrar no chamada log, que pega o logaritmo na base e. tero parmetros, ento, a sintaxe ter esta aparncia: A terceira instruo encontra o seno do valor da varivel angulo. sin e as outras funes trigonomtricas (cs, def novaLinha(): tan, etc.) recebem argumentos em radianos. Para converter de print graus em radianos, divida por 360 e multiplique por 2*pi. Por Esta funo chamada de novaLinha. Os exemplo, para encontrar o seno de 45 graus, primeiro calcule o parnteses vazios indicam que ela no tem parmetros. ngulo em radianos e depois ache o seno: Contm apenas um nico comando, que gera como sada um caractere de nova linha (isso o que acontece quando voc usa >>> graus = 45 um comando print sem qualquer argumento). >>> angulo = graus * 2 * math.pi / 360.0 A sintaxe para a chamada desta nova funo a >>> math.sin(angulo) mesma sintaxe para as funes nativas: 0.707106781187 A constante pi tambm parte do mdulo math. print 'Primeira Linha.' Se voc sabe geometria, pode checar o resultado anterior novaLinha() comparando-o com a raiz quadrada de dois dividido por dois: print 'Segunda Linha.' A sada deste programa : >>> math.sqrt(2) / 2.0 0.707106781187 Primeira Linha. Segunda Linha. Observe o espao extra entre as duas linhas. E se quisssemos mais espao entre as linhas? Poderamos chamar Do mesmo modo como nas funes matemticas, as funes do Python podem ser compostas, o que significa que voc a mesma funo repetidamente: pode usar uma expresso como parte de outra. Por exemplo, print 'Primeira Linha.' voc pode usar qualquer expresso como um argumento para novaLinha() uma funo: novaLinha() >>> x = math.cos(angulo + pi/2) novaLinha() Esta instruo toma o valor de pi, divide-o por 2, e soma o resultado ao valor de angulo. A soma ento print 'Segunda Linha.' Ou poderamos escrever uma nova funo passada como um argumento para a funo cos. chamada tresLinhas, que produzisse trs novas linhas: Voc tambm pode pegar o resultado de uma def tresLinhas() : funo e pass-lo como um argumento para outra: novaLinha() >>> x = math.exp(math.log(10.0)) novaLinha() Esta instruo encontra o logaritmo base e de 10 novaLinha() e ento eleva e quela potncia. O resultado atribudo a x.

3.5 Composio

3.6 Adicionando novas funes


At aqui, temos utilizado somente as funes que vm 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.

print 'Primeira Linha.' tresLinhas() print 'Segunda Linha.' Esta funo contm trs comandos, todos com recuo de dois espaos a partir da margem esquerda. J que o prximo comando no est endentado, Python reconhece que ele no faz parte da funo.

Algumas coisas que devem ser observadas sobre No contexto de programao, funo uma seqncia nomeada de instrues ou comandos, que realizam este programa: uma operao desejada. Esta operao especificada numa 1. Voc pode chamar o mesmo procedimento definio de funo. At agora, as funes que usamos neste repetidamente. Isso muito comum, alm de til. livro so pr-definidas e suas definies no foram 2. Voc pode ter uma funo chamando outra funo; apresentadas. Isso demonstra que podemos usar funes sem neste caso tresLinhas chama novaLinha. ter que nos preocupar com os detalhes de suas definies. A sintaxe para uma definio de funo : def NOME( LISTA DE PARAMETROS ) : Pode no estar claro, at agora, de que vale o esforo de criar novas funes - existem vrias razes, mas este exemplo demonstra duas delas:

GNU Free Documentation License #27

Como pensar como um cientista da Computao usando Python Criar uma nova funo permite que voc coloque at que a funo mais externa seja chamada. nome em um grupo de comandos. As funes podem Chamadas de funo so como um desvio no simplificar um programa ao ocultar uma computao fluxo de execuo. Em vez de ir para o prximo comando, o complexa por trs de um simples comando cujo nome pode ser uma palavra em portugus, em vez de algum fluxo salta para a primeira linha da funo chamada, executa todos os comandos l e ento volta atrs para retomar de onde cdigo misterioso. havia deixado. Criar uma nova funo pode tornar o programa Parece muito simples, at a hora em que voc menor, por eliminar cdigo repetido. Por exemplo, lembra que uma funo pode chamar outra. Enquanto estiver um atalho para 'imprimir' nove novas linhas no meio de uma funo, o programa poderia ter de executar os consecutivas chamar tresLinhas trs vezes. comandos em uma outra funo. Mas enquanto estivesse Como exerccio, escreva uma funo chamada executando esta nova funo, o programa poderia ter de noveLinhas que use tresLinhas para imprimir nove linhas em executar ainda outra funo! branco. Como voc poderia imprimir vinte e sete novas Felizmente, Python adepto de monitorar a linhas? posio onde est, assim, cada vez que uma funo se completa, o programa retoma de onde tinha parado na funo que a chamou. Quando chega ao fim do programa, ele termina. 3.7 Definies e uso

Qual a moral dessa histria srdida? Quando Reunindo os fragmentos de cdigo da Seo 3.6, o programa voc ler um programa, no o leia de cima para baixo. Em vez disso, siga o fluxo de execuo. completo fica assim: def novaLinha() : print def tresLinhas() : novaLinha() novaLinha() novaLinha() print 'Primeira Linha.' tresLinhas() print 'Segunda Linha.' Esse 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 comandos dentro da definio da funo no so executados at que a funo seja chamada, logo, a definio da funo no gera nenhuma sada.

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. Veja 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 Como voc j deve ter imaginado, preciso (a essa altura, no sabemos qual ser) impresso duas vezes, criar uma funo antes de poder execut-la. Em outras seguido de uma nova linha. Estamos usando bruno para palavras, a definio da funo tem que ser executada antes mostrar que o nome do parmetro deciso sua, mas claro que que ela seja chamada pela primeira vez. melhor escolher um nome que seja mais ilustrativo. Como exerccio, mova as ltimas trs linhas A funo imprimeDobrado funciona para deste programa para o topo, de modo que a chamada da funo qualquer tipo que possa ser impresso: aparea antes das definies. Rode o programa e veja que mensagem de erro voc ter. >>> imprimeDoobrado('Spam') Tambm a ttulo de exerccio, comece com a Spam Spam verso que funciona do programa e mova a definio de >>> imprimeDobrado(5) novaLinha para depois da definio de tresLinhas. O que 5 5 acontece quando voc roda este programa? >>> imprimeDobrado(3.14159) 3.14159 3.14159 Na primeira chamada da funo, o argumento 3.8 Fluxo de execuo uma string. Na segunda, um inteiro. Na terceira um float. Para assegurar que uma funo esteja definida antes do seu As mesmas regras de composio que se primeiro uso, preciso saber em que ordem os comandos so aplicam a funes nativas tambm se aplicam s funes executados, o que chamado de fluxo de execuo. definidas pelo usurio, assim, podemos usar qualquer tipo de A execuo sempre comea com o primeiro expresso como um argumento para imprimeDobrado: comando do programa. Os comandos so executados um de >>> imprimeDobrado('Spam'*4) cada vez, pela ordem, de cima para baixo. SpamSpamSpamSpam SpamSpamSpamSpam As definies de funo no alteram o fluxo de execuo do programa, mas lembre-se que comandos dentro >>> imprimeDobrado(math.cos(math.pi)) da funo no so executados at a funo ser chamada. -1.0 -1.0 Como acontece normalmente, a expresso Embora no seja comum, voc pode definir uma funo dentro de outra. Neste caso, a definio mais interna no executada avaliada antes da execuo da funo, assim imprimeDobrado GNU Free Documentation License #28

Como pensar como um cientista da Computao usando Python 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. Tambm podemos usar uma varivel como argumento: >>> miguel = 'Eric, the half a bee.' >>> imprimeDobrado(miguel) Eric, the half a bee. Eric, the half a bee. N.T.: "Eric, the half a bee" uma msica do grupo humorstico britnico Monty Python. A linguagem Python foi batizada em homenagem ao grupo e, por isso, os programadores gostam de citar piadas deles em seus exemplos.

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 que o Repare numa coisa importante: o nome da varivel que passamos como um argumento (miguel) no tem seu argumento correspondente. Assim, parte1 tem o mesmo nada a ver com o nome do parmetro (bruno). No importa de valor de canto1, parte2 tem o mesmo valor de canto2 e bruno que modo o valor foi chamado de onde veio (do 'chamador'); tem o mesmo valor de concat. aqui, em imprimeDobrado, chamamos a todo mundo de bruno. 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 3.10 Variveis e parmetros so locais chamou, percorrendo todo o caminho de volta a __main__. Por exemplo, se tentssemos acessar concat de Quando voc cria uma varivel local dentro de uma funo, ela s existe dentro da funo e voc no pode us-la fora de dentro de imprimeDobrado, teramos um NameError: l. Por exemplo: Traceback (innermost last): def concatDupla(parte1, parte2) File "teste.py", line 13, in __main__ concat = parte1 + parte2 concatDupla(canto1, canto2) imprimeDobrado(concat) File "teste.py", line 5, in concatDupla Esta funo recebe dois argumentos, concatenaimprimeDobrado(concat) os, e ento imprime o resultado duas vezes. Podemos chamar a File "teste.py", line 9, in imprimeDobrado funo com duas strings: print concat >>> canto1 = 'Pie Jesu domine, ' NameError: concat >>> canto2 = 'dona eis requiem. ' Esta lista de funes chamada de traceback. Ela mostra em qual arquivo de programa o erro ocorreu, em >>> concatDupla(canto1, canto2) que linha, e quais funes estavam sendo executadas naquele Pie Jesu domine, Dona eis requiem. Pie Jesu momento. Mostra tambm a linha de cdigo que causou o domine, \ erro. Dona eis requiem. Note a similaridade entre o traceback e o Quando a funo concatDupla termina, a diagrama da pilha; no coincidncia. 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.12 Funes com resultados


A essa altura, voc deve ter percebido que algumas das funes que estamos usando, tais como 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)? O que acontece se voc usa uma funo que no produz resultado em uma expresso tal como novaLinha() + 7? Voc pode escrever funes que produzem resultados, ou est preso a funes como novaLinha e imprimeDobrado? A resposta para a terceira questo afirmativa e

3.11 Diagramas da pilha


Para entender que variveis podem ser usadas aonde, s vezes til desenhar um diagrama da pilha. Como os diagramas de estado, diagramas da pilha mostram o valor de cada varivel, mas tambm a funo 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:

2.

3.

GNU Free Documentation License #29

Como pensar como um cientista da Computao usando Python ns vamos fazer isso no Captulo 5. A ttulo de exerccio, responda as outras duas questes testando-as. Se tiver dvida sobre o que vlido ou invlido em Python, tente buscar a resposta perguntando ao interpretador.

3.13 Glossrio
chamada de Comando que executa uma funo. funo Consiste do nome da funo seguido de (function call) uma lista de argumentos entre parnteses. argumento Valor fornecido a uma funo quando ela (argument) chamada. Este valor atribudo ao parmetro correspondente na funo. valor de retorno O resultado da funo. Se uma chamada (return value) de funo usada como expresso, o valor de retorno o valor da expresso. converso de Comando explcito que pega um valor de tipo (type um tipo e devolve o valor correspondente conversion) em outro tipo. coercividade de Uma converso de tipo que ocorre tipo (type automaticamente, de acordo com as regras coercion) de coercividade do Python. mdulo Arquivo que contm uma coleo de (module) funes e classes relacionadas entre si. notao de A sintaxe para chamar uma funo que ponto (dot est em outro mdulo, especificando o notation) nome do mdulo, seguido por um ponto (.) e o nome da funo. funo Seqncia de comandos nomeada, que (function) realiza alguma tarefa til. As funes podem ou no receber parmetros e podem ou no retornar valores. definio de Comando que cria uma nova funo, funo especificando seu nome, parmetros e (function comandos que ela executa. definition) fluxo de A ordem na qual os comandos so execuo (flow executados durante a execuo do of execution) programa. parmetro Nome usado numa funo para referir-se (parameter) ao valor passado como argumento. varivel local Varivel definida dentro da funo. Uma (local variable) varivel local s pode ser usada dentro da funo onde foi definida. diagrama da Representao grfica da pilha de funes, pilha (stack suas variveis e os valores aos quais elas diagram) se referem. frame Retngulo no diagrama da pilha que representa uma chamada de funo. Contm as variveis locais e os parmetros da funo. traceback Lista de funes que esto em execuo, impressa quando um erro de execuo ocorre.

GNU Free Documentation License #30

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 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.

4.3 Operadores lgicos


Existem trs operadores lgicos: and, or, not (e, ou, no). A semntica (significado) destes operadores similar aos seus significados em ingls (ou portugus). Por exemplo, x > 0 and x < 10 verdadeiro somente se x for maior que 0 e 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 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.

A rigor, os operandos de operadores lgicos deveriam ser expresses booleanas, mas Python no muito rigoroso. Qualquer nmero diferente de zero interpretado O operador mdulo se revela como verdadeiro (True): surpreendentemente til. Por exemplo, voc pode checar se um nmero divisvel por outro - se x % y d zero, ento x >>> x = 5 divisvel por y. >>> x and 1 Voc tambm pode extrair o algarismo ou 1 algarismos mais direita de um nmero. Por exemplo, x % 10 >>> y = 0 resulta o algarismo mais direita de x (na base 10). Similarmente, x % 100 resulta nos dois dgitos mais direita. >>> y and 1 0 Em geral, esse tipo de coisa no considerado de bom estilo. Se voc precisa comparar um valor com zero, 4.2 Expresses booleanas deve faz-lo explicitamente. 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 4.4 Execuo condicional valor 0. Para poder escrever programas teis, quase sempre precisamos O operador == compara dois valores e produz da habilidade de checar condies e mudar o comportamento uma expresso booleana: do programa de acordo com elas. As instrues condicionais nos do essa habilidade. A forma mais simples a instruo if >>> 5 == 5 (se): True if x > 0 >>> 5 == 6 print "x positivo" False A expresso booleana depois da instruo if No primeiro comando, os dois operadores so iguais, ento a expresso avalia como True (verdadeiro); no chamada de condio. Se ela verdadeira (true), ento a segundo comando, 5 no igual a 6, ento temos False (falso). instruo endentada executada. Se no, nada acontece. Assim como outras instrues compostas, a O operador == um dos operadores de instruo if constituda de um cabealho e de um bloco de comparao; os outros so: instrues: x != y # x diferente de y CABECALHO: x > y # x maior que y PRIMEIRO COMANDO x < y # x menor que y ... x >= y # x maior ou igual a y ULTIMO COMANDO x <= y # x menor ou igual a y O cabealho comea com uma nova linha e Embora esses operadores provavelmente sejam termina com dois pontos (:). Os comandos ou instrues familiares a voc, os smbolos em Python so diferentes dos smbolos da matemtica. Um erro comum usar um sinal de endentados que seguem so chamados de bloco. A primeira igual sozinho (=) em vez de um duplo (==). Lembre-se de que instruo no endentada marca o fim do bloco. Um bloco de = um operador de atribuio e == um operador de comandos dentro de um comando composto ou instruo composta chamado de corpo do comando. comparao. Tambm no existem coisas como =< ou =>. 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

Como pensar como um cientista da Computao usando Python corpo sem nenhuma instruo (usualmente, como um print "Escolha invlida." delimitador de espao para cdigo que voc ainda no Cada condio checada na ordem. Se a escreveu). Nesse caso, voc pode usar o comando pass, que primeira falsa, a prxima checada, e assim por diante. Se no faz nada. 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.

4.5 Execuo alternativa

Como exerccio, coloque os exemplos acima em Um segundo formato da instruo if a execuo alternativa, funes chamadas comparar(x, y) e executar(escolha). 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 (branches), porque existem ramificaes no fluxo de execuo.

4.7 Condicionais aninhados

Um condicional tambm pode ser aninhado 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 Por sinal, se voc precisa checar a paridade de O condicional mais externo tem dois ramos. O nmeros com freqncia, pode colocar este cdigo dentro de primeiro ramo contm uma nica instruo de sada. O uma funo: segundo ramo contm outra instruo if, que por sua vez tem dois ramos. Os dois ramos so ambos instrues de sada, def imprimeParidade(x): embora pudessem conter instrues condicionais tambm. if x % 2 == 0: Embora a endentao das instrues torne a print x, " par" estrutura aparente, condicionais aninhados tornam-se difceis else: de ler rapidamente. Em geral, uma boa idia evitar o aninhamento quando for possvel. print x, " impar" Para qualquer valor de x, imprimeParidade Operadores lgicos freqentemente fornecem exibe uma mensagem apropriada. Quando voc a chama, pode uma maneira de simplificar instrues condicionais aninhadas. fornecer uma expresso de resultado inteiro como um Por exemplo, podemos reescrever o cdigo a seguir usando argumento: uma nica condicional: >>> imprimeParidade(17) >>> imprimeParidade(y+1) if 0 < x: if x < 10: print "x um nmero positivo de um s algarismo." 4.6 Condicionais encadeados A instruo print executada somente se a s vezes existem mais de duas possibilidades e precisamos de fizermos passar por ambos os condicionais, ento, podemos mais que dois ramos. Uma condicional encadeada uma usar um operador and: maneira de expressar uma computao dessas: if 0 < x and x < 10: print "x um nmero positivo de um s if x < y: algarismo." print x, " menor que", y Esses tipos de condio so comuns, assim, elif x > y: Phython prov uma sintaxe alternativa que similar notao print x, " maior que", y matemtica: else: if 0 < x < 10: print x, "e", y, "so iguais" print "x um nmero positivo de um s elif uma abreviao de "else if" ("ento se"). De novo, precisamente um ramo ser executado. No existe algarismo." limite para o nmero de instrues elif, mas se existir uma instruo else ela tem que vir por ltimo: if escolha == 'A': funcaoA() elif escolha == 'B': funcaoB() elif escolha == 'C': funcaoC() else:

4.8 A instruo return


O comando return permite terminar a execuo de uma funo antes que ela alcance seu fim. Uma razo para us-lo se voc detectar uma condio de erro: import math def imprimeLogaritmo(x): GNU Free Documentation License #32

Como pensar como um cientista da Computao usando Python if x <= 0: Fogo! Como um segundo exemplo, d uma olhada print "Somente nmeros positivos, por favor." novamente nas funes novaLinha e tresLinhas: return def novaLinha(): resultado = math.log(x) print print "O log de x ", resultado A funo imprimeLogaritmo recebe um def tresLinhas(): parmetro de nome x. A primeira coisa que ela faz checar se novaLinha() x menor ou igual a 0, neste caso ela exibe uma mensagem de novaLinha() erro e ento usa return para sair da funo. O fluxo de novaLinha() execuo imediatamente retorna ao ponto chamador, quer dizer, de onde a funo foi chamada, e as linhas restantes da Muito embora isso funcione, no seria muito til funo no so executadas. se precisssemos gerar como sada 2 novas linhas, ou 106. Lembre-se que para usar uma funo do mdulo Uma alternativa melhor seria esta: de matemtica, math, voc tem de import-lo. def nLinhas(n): if n > 0: print nLinhas(n-1) Esse 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) que, se voc estudou lgebra direitinho, vem a ser o prprio n. O processo de uma funo chamando a si mesma chamado de recursividade, e tais funes so ditas recursivas.

4.9 Recursividade
J mencionamos que vlido uma funo chamar outra funo, e voc viu vrios exemplos disso. Mas ainda no tnhamos dito que tambm vlido uma funo chamar a si mesma. Talvez no seja bvio porque isso bom, mas trata-se de 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 positivo. Se n for 0, ela produz como sada a palavra "Fogo!". De outro modo, ela produz como sada n e ento chama uma funo de nome contagemRegressiva -- ela mesma -- passando n-1 como argumento.

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, que contm as O que acontece se chamarmos essa funo da variveis locais e parmetros da funo. Para uma funo recursiva, ter que existir mais de um quadro na pilha ao seguinte maneira: mesmo tempo. >>> contagemRegressiva(3) Esta figura mostra um diagrama de pilha para A execuo de contagemRegressiva comea contagemRegressiva, chamada com n = 3: 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!" 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 estamos de volta em __main__ (que viagem!). Assim, a sada completa se parece com: 3 2 1

Como de costume, no topo da pilha est o quadro para __main__. Ele est vazio porque nem criamos qualquer varivel em __main__ nem passamos qualquer valor para ele.

GNU Free Documentation License #33

Como pensar como um cientista da Computao usando Python Os quatro quadros contagemRegressiva tm Se o usurio digita uma string de nmeros, ela valores diferentes para o parmetro n. A parte mais em baixo convertida para um inteiro e atribuda a velocidade. na pilha, onde n=0, chamada de caso base. Ele no faz uma Infelizmente, se o usurio digitar um caractere que no seja chamada recursiva, ento no h mais quadros. um nmero, o programa trava: Como exerccio, desenhe um diagrama de pilha >>> velocidade = input(deixa) para nLinhas chamada com n=4. Qual... a velocidade de vo de uma andorinha? De qual voc fala, uma andorinha Africana ou uma \ Europia? 4.11 Recursividade infinita SyntaxError: invalid syntax Se uma recursividade nunca chega ao caso base, ela prossegue Para evitar esse tipo de erro, geralmente bom fazendo chamadas recursivas para sempre, e o programa nunca usar raw_input para pegar uma string e, ento, usar funes de termina. Isto conhecido como recursividade infinita, e converso para converter para outros tipos. 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 operador mdulo (modulus programa com recursividade infinita na verdade no roda para operator) sempre. Python reporta uma mensagem de erro quando a profundidade mxima de recursividade alcanada: expresso File "<stdin>", line 2, in recursiva booleana (98 repetitions omitted) (boolean expression) File "<stdin>", line 2, in recursiva RuntimeError: Maximum recursion depth exceeded operador de comparao (comparison Este traceback um pouco maior do que aquele operator) que vimos no captulo anterior. Quando o erro ocorre, existem 100 quadros recursiva na pilha! operador lgico (logical Como exerccio, escreva uma funo com operator) recursividade infinita e rode-a no interpretador Python. comando condicional (conditional 4.12 Entrada pelo teclado statement) Os programas que temos escrito at agora so um pouco crus, condio no sentido de no aceitarem dados entrados pelo usurio. Eles (condition) simplesmente fazem a mesma coisa todas as vezes. Python fornece funes nativas que pegam entradas pelo teclado. A mais simples chamada raw_input. Quando esta funo chamada, o programa pra e espera que o usurio digite alguma coisa. Quando o usurio aperta a tecla Enter ou Return, o programa prossegue e a funo 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 ele deve entrar. Esta mensagem uma deixa (prompt). Podemos suprir uma deixa 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: deixa = "Qual... a velocidade de vo de uma \ andorinha?\n" velocidade = input(deixa) comando composto (compound statement)

4.13 Glossrio

Operador denotado por um smbolo de porcentagem (%), que trabalha com inteiros e retorna o resto da diviso de um nmero por outro. Uma expresso que verdadeira ou falsa.

Um dos operadores que compara dois valores: ==, !=, >, <, >=, e <=.

Um dos operadores que combina expresses booleanas: and, or, e not. Comando que controla o fluxo de execuo dependendo de alguma condio. A expresso booleana que determina qual bloco ser executado num comando condicional. Comando que consiste de um cabealho e um corpo. O cabealho termina com um dois-pontos (:). O corpo endentado em relao ao cabealho.

bloco (block) Grupo de comandos consecutivos com a mesma endentao. corpo (body) O bloco que se segue ao cabealho em um comando composto. aninhamento Estrutura de programa dentro da outra, (nesting) como um comando condicional dentro de um bloco de outro comando condicional. recursividade O processo de chamar a prpria funo (recursion) que est sendo executada. caso base (base Bloco de comando condicional numa case) funo recursiva que no resulta em uma chamada recursiva. recurso infinita Funo que chama a si mesma (infinite recursivamente sem nunca chegar ao caso recursion) base. Aps algum tempo, uma recurso infinita causa um erro de execuo. deixa (prompt) Indicao visual que diz ao usurio que o programa est esperando uma entrada de dados.

GNU Free Documentation License #34

Captulo 5: Funes frutferas

5.1 Valores de retorno

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:

Algumas das funes nativas do Python que temos usado, como as funes matemticas, produziram resultados. Chamar >>> print valorAbsoluto(0) a funo gerou um novo valor, o qual geralmente atribumos None Como exerccio, escreva uma funo compare uma varivel ou usamos como parte de uma expresso: que retorne 1 se x > y, 0 se x == y e -1 se x < y. e = math.exp(1.0) altura = raio * math.sin(angulo) Mas at agora, nenhuma das funes que ns 5.2 Desenvolvimento de programas mesmos escrevemos retornou um valor. Neste ponto, voc deve estar apto a olhar para funes Neste captulo, iremos escrever funes que completas e dizer o que elas fazem. Tambm, se voc vem retornam valores, as quais chamaremos de funes frutferas, fazendo os exerccios, voc escreveu algumas pequenas ou funes que do frutos, na falta de um nome melhor. O funes. Conforme escrever funes maiores, voc pode primeiro exemplo area, que retorna a rea de um crculo comear a ter mais dificuldade, especialmente com erros em dado o seu raio: tempo de execuo (erros de runtime) ou erros semnticos. import math Para lidar com programas de crescente complexidade, vamos sugerir uma tcnica chamada desenvolvimento incremental. A meta do desenvolvimento def area(raio): incremental evitar sees de depurao (debugging) muito temp = math.pi * raio**2 longas pela adio e teste de somente uma pequena quantidade return temp de cdigo de cada vez. J vimos a instruo return antes, mas em uma Como exemplo, suponha que voc queira funo frutfera a instruo return inclui um valor de retorno. encontrar a distncia entre dois pontos, dados pelas Esta instruo significa: "Retorne imediatamente desta funo e use a expresso em seguida como um valor de retorno". A coordenadas (x1,y1) e (x2,y2). Pelo teorema de Pitgoras, a expresso fornecida pode ser arbitrariamente complicada, de distncia : modo que poderamos ter escrito esta funo de maneira mais distancia = ((x2 x1)2 + (y2 y1)2 ) concisa: O primeiro passo considerar como deveria ser def area(raio): uma funo distancia em Python. Em outras palavras, quais return math.pi * raio**2 so as entradas (parmetros) e qual a sada (valor de Por outro lado, variveis temporrias como temp retorno)? muitas vezes tornam a depurao mais fcil. Neste caso, os dois pontos so as entradas, os s vezes til ter mltiplos comandos return, quais podemos representar usando quatro parmetros. O valor um em cada ramo de uma condicional: de retorno a distncia, que um valor em ponto flutuante. 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. 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:

O cdigo que aparece depois de uma instruo return, ou em qualquer outro lugar que o fluxo de execuo >>> distancia(1, 2, 4, 6) 0.0 jamais alcance, chamado cdigo morto (dead code). Escolhemos estes valores de modo que a Em uma funo frutfera, uma boa idia distncia horizontal seja igual a 3 e a distncia vertical seja assegurar que todo caminho possvel dentro do programa igual a 4; deste modo, o resultado 5 (a hipotenusa de um encontre uma instruo return. Por exemplo: tringulo 3-4-5). Quando testamos uma funo, til sabermos qual o resultado correto. def valorAbsoluto(x): if x < 0: Neste ponto, j confirmamos que a funo est sintaticamente correta, e podemos comear a adicionar linhas return -x de cdigo. Depois de cada mudana adicionada, testamos a elif x > 0: funo de novo. Se um erro ocorre em qualquer ponto, return x sabemos aonde ele deve estar: nas linhas adicionadas mais

recentemente.

Como pensar como um cientista da Computao usando Python no tornar o programa difcil de ler.

Um primeiro passo lgico nesta computao Como um exerccio, use o desenvolvimento encontrar as diferenas x2 - x1 e y2 - y1. Ns iremos guardar incremental para escrever uma funo chamada hipotenusa estes valores em variveis temporrias chamadas dx e dy e que retorna a medida da hipotenusa de um tringulo retngulo imprimi-las: dadas as medidas dos dois catetos como parmetros. Registre cada estgio do desenvolvimento incremental conforme voc def distancia(x1, y1, x2, y2): avance. dx = x2 - x1 dy = y2 - y1 5.3 Composio print "dx vale", dx print "dy vale", dy Conforme voc poderia esperar agora, voc pode chamar uma return 0.0 funo de dentro de outra. Esta habilidade chamada de Se a funo estiver funcionando, as sadas composio. devero ser 3 e 4. Se assim, sabemos que a funo est Como um exemplo, vamos escrever uma funo recebendo os parmetros corretos e realizando a primeira que recebe dois pontos, o centro de um crculo e um ponto em computao corretamente. Se no, existem poucas linhas para seu permetro, e calcula a rea do crculo. checar. Assuma que o ponto do centro est guardado nas Em seguida, computaremos a soma dos variveis xc e yc, e que o ponto do permetro est nas quadrados de dx e dy: variveis xp e yp. O primeiro passo encontrar o raio do crculo, o qual a distncia entre os dois pontos. Felizmente, def distancia(x1, y1, x2, y2): temos uma funo, distancia, que faz isto: 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 porque ajuda a escrever o programa, mas no parte do produto final. Raio = distancia(xc, yc, xp, yp) O segundo passo encontrar a rea de um crculo com o raio dado e retorn-la: resultado = area(raio) return resultado Juntando tudo numa funo, temos:

def area2(xc, yc, xp, yp): raio = distancia(xc, yc, xp, yp) De novo, ns vamos rodar o programa neste estgio e checar a sada (que deveria ser 25). resultado = area(raio) return resultado Finalmente, se ns tnhamos importado o Chamamos esta funo de area2 para mdulo matemtico math, podemos usar a funo sqrt para distinguir da funo area, definida anteriormente. S pode computar e retornar o resultado: existir uma nica funo com um determinado nome em um def distancia(x1, x2, y1, y2): determinado mdulo. dx = x2 - x1 As variveis temporrias raio e resultado so dy = y2 - y1 teis para o desenvolvimento e para depurao (debugging), mas uma vez que o programa esteja funcionando, podemos dquadrado = dx**2 + dy**2 torn-lo mais conciso atravs da composio das chamadas de resultado = math.sqrt(dquadrado) funo: return resultado Se isto funcionar corretamente, voc conseguiu. def area2(xc, yc, xp, yp): Caso contrrio, talvez fosse preciso imprimir (exibir) o valor return area(distancia(xc, yc, xp, yp)) de resultado antes da instruo return. Como exerccio, escreva uma funo Enquanto for iniciante, voc deve acrescentar inclinacao(x1, y1, x2, y2) que retorne a inclinao (ou apenas uma ou duas linhas de cdigo de cada vez. Conforme coeficienteAngular?) de uma linha dados os pontos (x1, y1) e ganhar mais experincia, voc se ver escrevendo e depurando (x2, y2). Depois use esta funo em uma funo chamada pedaos maiores. De qualquer modo, o processo de cortaY(x1, y1, x2, y2) que retorne a interseo da linha com o desenvolvimento incremental pode poupar um bocado de eixo y, dados os pontos (x1, y1) e (x2, y2). tempo de depurao. Os aspectos chave do processo so: 1.

5.4 Funes booleanas

Comece com um programa que funciona e faa pequenas mudanas incrementais. Em qualquer ponto Funes podem retornar valores booleanos, o que muitas do processo, se houver um erro, voc saber vezes conveniente por ocultar testes complicados dentro de funes. Por exemplo: exatamente onde ele est. Use variveis temporrias para manter valores def ehDivisivel(x, y): intermedirios de modo que voc possa exibi-los e If x % y == 0: chec-los. return True # verdadeiro (true), Uma vez que o programa funcione, voc pode querer divisvel remover algum cdigo muleta, ou andaime else: (scaffolding) ou consolidar mltiplos comandos return False # falso (false), no dentro de expresses compostas, mas somente se isto GNU Free Documentation License #36

2.

3.

Como pensar como um cientista da Computao usando Python Esta definio diz que o fatorial de 0 1, e que o fatorial de qualquer outro valor, n, n multiplicado pelo O nome desta funo ehDivisivel (" divisvel"). comum dar a uma funo booleana nomes que fatorial de n-1. soem como perguntas sim/no. ehDivisivel retorna ou True ou Assim, 3! (l-se "3 fatorial" ou "fatorial de 3") False para indicar se x ou no divisvel por y. 3 vezes 2!, o qual 2 vezes 1!, o qual 1 vezes 0!. Colocando Podemos tornar a funo mais concisa se tudo isso junto, 3! igual 3 vezes 2 vezes 1 vezes 1, o que 6. tirarmos vantagem do fato de a condio da instruo if ser ela Se voc pode escrever uma definio recursiva mesma uma expresso booleana. Podemos retorn-la de alguma coisa, voc geralmente pode escrever um programa diretamente, evitando totalmente o if: em Python para execut-la. O primeiro passo decidir quais so os parmetros para esta funo. Com pouco esforo, voc def ehDivisivel(x, y): dever concluir que fatorial recebe um nico parmetro: return x % y == 0 def fatorial(n): Esta sesso mostra a nova funo em ao: Se acontece de o argumento ser 0, tudo o que >>> ehDivisivel(6, 4) temos de fazer retornar 1: False def fatorial(n): >>> ehDivisivel(6, 3) if n == 0: True return 1 Funes booleanas so freqentemente usadas Por outro lado, e esta a parte interessante, em comandos condicionais: temos que fazer uma chamada recursiva para encontrar o if ehDivisivel(x, y): fatorial de n-1 e ento multiplic-lo por n: print "x divisvel por y" def fatorial(n): else: if n == 0: print "x no divisvel por y" return 1 Mas a comparao extra desnecessria. else: Como exerccio, escreva uma funo recursivo = fatorial(n-1) estaEntre(x, y, z) que retorne True se y < x < z ou False se no. resultado = n * recursivo return resultado O fluxo de execuo para este programa 5.5 Mais recursividade similar ao fluxo de contagemRegressiva na Seo 4.9. Se At aqui, voc aprendeu apenas um pequeno subconjunto da chamarmos fatorial com o valor 3: linguagem Python, mas pode ser que te interesse saber que J que 3 no 0, tomamos o segundo ramo e este pequeno subconjunto uma linguagem de programao calculamos o fatorial de n-1 ... completa, o que significa que qualquer coisa que possa ser J que 2 no 0, tomamos o segundo ramo e computada pode ser expressa nesta linguagem. Qualquer programa j escrito pode ser reescrito usando somente os calculamos o fatorial de n-1 ... aspectos da linguagem que voc aprendeu at agora J que 1 no 0, tomamos o segundo ramo e (usualmente, voc precisaria de uns poucos comandos para calculamos o fatorial de n-1 ... controlar dispositivos como o teclado, mouse, discos, etc., mas isto tudo). J que 0 0, tomamos o primeiro ramo e retornamos 1 sem fazer mais qualquer chamada recursiva. Provar esta afirmao um exerccio nada trivial, que foi alcanado pela primeira vez por Alan Turing, O valor retornado (1) multiplicado por n, que um dos primeiros cientistas da computao (algum poderia 1, e o resultado retornado. dizer que ele foi um matemtico, mas muitos dos primeiros O valor retornado (1) multiplicado por n, que cientistas da computao comearam como matemticos). Por 2, e o resultado retornado. isso, ficou conhecido como Tese de Turing. Se voc fizer um curso em Teoria da Computao, voc ter chance de ver a O valor retornado (2) multiplicado por n, que prova. 1, e o resultado, 6, se torna o valor de retorno da chamada de Para te dar uma idia do que voc pode fazer funo que iniciou todo o processo. com as ferramentas que aprendeu a usar at agora, vamos Eis o diagrama de pilha para esta seqncia de avaliar algumas funes matemticas recursivamente chamadas de funo: definidas. Uma definio recursiva similar uma definio circular, no sentido de que a definio faz referncia coisa que est sendo definida. Uma verdadeira definio circular no muito til: divisvel vorpal: adjetivo usado para descrever algo que vorpal. Se voc visse esta definio em um dicionrio, ficaria confuso. Por outro lado, se voc procurasse pela definio da funo matemtica fatorial, voc encontraria algo assim: 0! = 1 n! = n.(n-1)! Os valores de retorno so mostrados sendo passados de volta para cima da pilha. Em cada quadro, o valor GNU Free Documentation License #37

Como pensar como um cientista da Computao usando Python de retorno o valor de resultado, o qual o produto de n por else: recursivo. return fibonacci(n-1) + fibonacci(n-2) Se voc tentar seguir o fluxo de execuo aqui, mesmo para valores bem pequenos de n, sua cabea explodir. 5.6 Voto de confiana (Leap of faith) Mas, de acordo com o voto de confiana, se voc assume que as duas chamadas recursivas funcionam corretamente, ento Seguir o fluxo de execuo uma maneira de ler programas, claro que voc ter o resultado correto ao junt-las. mas que pode rapidamente se transformar em um labirinto. Uma alternativa o que chamamos de "voto de confiana". Quando voc tem uma chamada de funo, em vez de seguir o 5.8 Checagem de tipos fluxo de execuo, voc assume que a funo funciona corretamente e retorna o valor apropriado. O que acontece se chamamos fatorial e damos a ela 1.5 como De fato, voc est agora mesmo praticando este argumento?: voto de confiana ao usar as funes nativas. Quando voc chama math.cos ou math.exp, voc no examina a >>> fatorial (1.5) implementao destas funes. Voc apenas assume que elas RuntimeError: Maximum recursion depth exceeded funcionam porque as pessoas que escreveram as bibliotecas Parece um caso de recursividade infinita. Mas o nativas eram bons programadores. que ser que de fato? Existe um caso base -- quando n == 0. O mesmo tambm verdade quando voc O problema que o valor de n nunca encontra o caso base. chama uma de suas prprias funes. Por exemplo, na Seo Na primeira chamada recursiva, o valor de n 5.4, escrevemos a funo chamada ehDivisivel que determina 0.5. Na prxima, ele igual a -0.5. Da em diante, ele se torna se um nmero divisvel por outro. Uma vez que nos cada vez menor, mas jamais ser 0. convencemos que esta funo est correta -- ao testar e Temos ento duas alternativas. Podemos tentar examinar o cdigo -- podemos usar a funo sem examinar o generalizar a funo fatorial para que funcione com nmeros cdigo novamente. em ponto flutuante, ou fazemos fatorial realizar a checagem de O mesmo tambm verdadeiro para programas tipo de seus parmetros. A primeira chamada funo gamma recursivos. Quando voc tem uma chamada recursiva, em vez e est um pouco alm do escopo deste livro. Sendo assim, de seguir o fluxo de execuo, voc poderia assumir que a ficaremos com a segunda. chamada recursiva funciona (produz o resultado correto) e Podemos usar type para comparar o tipo do ento perguntar-se, "Assumindo que eu possa encontrar o parmetro com o tipo de um valor inteiro conhecido (como 1). fatorial de n-1, posso calcular o fatorial de n?" Neste caso, Ao mesmo tempo em que fazemos isto, podemos nos certificar claro que voc pode, multiplicando por n. tambm de que o parmetro seja positivo: Naturalmente, um pouco estranho que uma funo funcione corretamente se voc ainda nem terminou de def fatorial (n): escrev-la, mas por isso que se chama voto de confiana! if type(n) != type(1): print "Fatorial somente definido para inteiros." 5.7 Mais um exemplo return -1 elif n < 0: No exemplo anterior, usamos variveis temporrias para explicitar (spell out XXX) os passos e tornar o cdigo mais print "Fatorial somente definido para fcil de depurar, mas poderamos ter economizado algumas inteiros\ linhas: positivos." def fatorial(n): return -1 if n == 0: elif n ==0: return 1 return 1 else: else: return n * fatorial(n-1) return n * fatorial(n-1) De agora em diante, tenderemos a utilizar um Agora temos trs casos base. O primeiro pega os formato mais conciso, mas recomendamos que voc use a no-inteiros. O segundo pega os inteiros negativos. Em ambos verso mais explcita enquanto estiver desenvolvendo cdigo. os casos, o programa exibe uma mensagem de erro e retorna Quando ele estiver funcionando, voc pode enxug-lo se um valor especial, -1, para indicar que alguma coisa saiu estiver se sentindo inspirado. errada: Depois de fatorial, o exemplo mais comum de >>> fatorial ("Fred") uma funo matemtica definida recursivamente fibonacci, a Fatorial somente definido para inteiros. qual tem a seguinte definio: -1 fibonacci(0) = 1 >>> fatorial (-2) fibonacci(1) = 1 Fatorial somente definido para inteiros fibonacci(n) = fibonacci(n-1) + fibonacci(n-2); positivos. Traduzido em Python, parecer assim: -1 Se passarmos pelas duas checagens, ento def fibonacci(n): saberemos que n um inteiro positivo, e poderemos provar if n == 0 or n == 1: que a recursividade encontra seu trmino. return 1 Este programa demonstra um padro (pattern) GNU Free Documentation License #38

Como pensar como um cientista da Computao usando Python chamado s vezes de guardio. As duas primeiras condicionais atuam como guardis, protegendo o cdigo que vem em seguida de valores que poderiam causar um erro. Os guardies tornam possvel garantir a correo do cdigo.

5.9 Glossrio
funo frutfera Uma funo que produz um valor de (fruitful function) retorno. valor de retorno O valor entregue como resultado de uma (return value) chamada de funo. varivel Uma varivel usada para guardar um temporria valor intermedirio em um clculo (temporary complexo. variable) cdigo morto Parte de um programa que nunca pode (dead code) ser executada, muitas vezes por que ela aparece depois de uma instruo return. None Um valor especial em Python, retornado por funes que no possuem uma instruo return ou tm uma instruo return sem argumento. desenvolvimento incremental (incremental development) Uma estratgia de desenvolvimento de programas que evita a depurao ao adicionar e testar somente uma pequena quantidade de cdigo de cada vez.

usado durante o andaime Cdigo (scaffolding) desenvolvimento do programa, mas que no faz parte do produto final. guardio Uma condio que checa e manipula (guardian) circunstncias que poderiam causar um erro.

GNU Free Documentation License #39

Captulo 6: Iterao

Vimos dois programas, nLinhas e contagemRegressiva, que usam recursividade (recurso) para fazer a repetio, que tambm chamada iterao. Porque a 6.1 Reatribuies iterao muito comum, Python tem vrias caractersticas Como voc talvez j tenha descoberto, permitido fazer mais para torn-la mais fcil. A primeira delas em que vamos dar de uma atribuio mesma varivel. Uma nova atribuio faz uma olhada o comando while. uma varivel existente referir-se a um novo valor (sem se Aqui est como fica contagemRegressiva com referir mais ao antigo).: um comando while: bruno = 5 def contagemRegressiva(n): print bruno, while n > 0: bruno = 7 print n print bruno n = n-1 A sada deste programa 5 7, porque na print "Fogo!" primeira vez que bruno impresso, seu valor 5 e na segunda vez, seu valor 7. A vrgula no final do primeiro comando print suprime a nova linha no final da sada, que o motivo Desde que removemos a chamada recursiva, pelo qual as duas sadas aparecem na mesma linha. esta funo no recursiva. Veja uma reatribuio em um diagrama de Voc quase pode ler o comando while como se estado: fosse Ingls. Ele significa, "Enquanto (while) n for maior do que 0, siga exibindo o valor de n e diminuindo 1 do valor de n. Quando chegar a 0, exiba a palavra Fogo!". Mais formalmente, aqui est o fluxo de execuo para um comando while: 1. Com a reatribuio torna-se ainda mais importante distinguir entre uma operao de atribuio e um comando de igualdade. Como Python usa o sinal de igual ( = ) para atribuio, existe a tendncia de lermos um comando como a = b como um comando de igualdade. Mas no ! 2. 3. Teste a condio, resultando 0 ou 1. Se a condio for falsa (0), saia do comando while e continue a execuo a partir do prximo comando. Se a condio for verdadeira (1), execute cada um dos comandos dentro do corpo e volte ao passo 1.

O corpo consiste de todos os comandos abaixo Em primeiro lugar, igualdade comutativa e do cabealho, com a mesma endentao. atribuio no . Por exemplo, em matemtica, se a = 7 ento Este tipo de fluxo chamado de um loop (ou 7 = a. Mas em Python, o comando a = 7 permitido e 7 = a lao) porque o terceiro passo cria um "loop" ou um lao de no . volta ao topo. Note que se a condio for falsa na primeira vez Alm disso, em matemtica, uma expresso de que entrarmos no loop, os comandos dentro do loop jamais igualdade sempre verdadeira. Se a = b agora, ento, a ser sero executados. sempre igual a b. Em Python, um comando de atribuio pode O corpo do loop poderia alterar o valor de uma tornar duas variveis iguais, mas elas no tm que permanecer ou mais variveis de modo que eventualmente a condio se assim: torne falsa e o loop termine. Se no for assim, o loop se repetir para sempre, o que chamado de um loop infinito. a = 5 Uma fonte de diverso sem fim para os cientistas da b = a # a e b agora so iguais computao a observao de que as instrues da b = 3 # a e b no so mais iguais embalagem de shampoo, "Lave, enxge, repita" um loop A terceira linha muda o valor de a mas no infinito. muda o valor de b, ento, elas no so mais iguais. (Em No caso de contagemRegressiva, podemos algumas linguagens de programao, um smbolo diferente provar que o loop terminar porque sabemos que o valor de n usado para atribuio, como <- ou :=, para evitar confuso.) finito, e podemos ver que o valor de n diminui dentro de Embora a reatribuio seja freqentemente til, cada repetio (iterao) do loop, ento, eventualmente voc deve us-la com cautela. Se o valor das variveis muda chegaremos ao 0. Em outros casos, isto no to simples de freqentemente, isto pode fazer o cdigo difcil de ler e de afirmar: depurar. def sequencia(n): while n != 1: 6.2 O comando while print n, if n%2 == 0: # n par Os computadores so muito utilizados para automatizar tarefas n = n/2 repetitivas. Repetir tarefas idnticas ou similares sem cometer else: # n impar erros uma coisa que os computadores fazem bem e que as pessoas fazem poorly. n = n*3+1

Como pensar como um cientista da Computao usando Python A condio para este loop n != 1, ento o loop Tabulao til para fazer colunas de texto line up, como na vai continuar at que n seja 1, o que tornar a condio falsa. sada do programa anterior: Dentro de cada repetio (iterao) do loop, o programa gera o valor de n e ento checa se ele par ou impar. Se ele for par, o valor de n dividido por 2. Se ele for impar, o valor substitudo por n*3+1. Por exemplo, se o valor inicial (o argumento passado para seqncia) for 3, a seqncia resultante ser 3, 10, 5, 16, 8, 4, 2, 1. J que n s vezes aumenta e s vezes diminui, no existe uma prova bvia de que n jamais venha a alcanar 1, ou de que o programa termine. Para alguns valores particulares de n, podemos provar o trmino. Por exemplo, se o valor inicial for uma potncia de dois, ento o valor de n ser par dentro de cada repetio (iterao) do loop at que alcance 1. O exemplo anterior termina com uma dessas seqncias comeando em 16. Valores especficos parte, A questo interessante se h como provarmos que este programa termina para todos os valores de n. At hoje, ningum foi capaz de provar que sim ou que no! Como um exerccio, reescreva a funo nLinhas da seo 4.9 usando iterao em vez de recurso. 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 0.0 0.69314718056 1.09861228867 1.38629436112 1.60943791243 1.79175946923 1.94591014906 2.07944154168 2.19722457734 Se estes valores parecem odd, lembre-se que a funo log usa a base e. J que potncias de dois so to importantes em cincia da computao, ns freqentemente temos que achar logaritmos referentes base 2. Para fazermos isso, podemos usar a seguinte frmula:

Alterando o comando de sada para: print x, '\t', math.log(x)/math.log(2.0) o que resultar em:

6.3 Tabelas
Uma das coisas para qual os loops so bons para gerar dados tabulares. Antes que os computadores estivessem readily disponveis, as pessoas tinham que calcular logaritmos, senos, cossenos e outras funes matemticas mo. Para tornar isto mais fcil, os livros de matemtica continham longas tabelas listando os valores destas funes. Criar as tabelas era demorado e entediante, e elas tendiam a ser cheias de erros.

1.0 0.0 2.0 1.0 3.0 1.58496250072 4.0 2.0 5.0 2.32192809489 6.0 2.58496250072 7.0 2.80735492206 Quando os computadores entraram em cena, 8.0 3.0 uma das reaes iniciais foi "Isto timo! Podemos usar computadores para geras as tabelas, assim no haver erros." 9.0 3.16992500144 Isto veio a se tornar verdade (na maioria das vezes) mas Podemos ver que 1, 2, 4 e 8 so potncias de shortsighted. Rapidamente, porm, computadores e dois porque seus logaritmos na base 2 so nmeros redondos. calculadoras tornaram-se to pervasivos que as tabelas ficaram Se precisssemos encontrar os logaritmos de outras potncias obsoletas. de dois, poderamos modificar o programa deste modo: Bem, quase. Para algumas operaes, os x = 1.0 computadores usam tabelas de valores para conseguir uma resposta aproximada e ento realizar clculos para melhorar a while x < 100.0: print x, '\t', math.log(x)/math.log(2.0) aproximao. Em alguns casos, tm havido erros nas tabelas underlying, o caso mais famoso sendo o da tabela usada pelo x = x * 2.0 processador Pentium da Intel para executar a diviso em Agora, em vez de somar algo a x a cada iterao ponto-flutuante. do loop, o que resulta numa seqncia aritmtica, ns Embora uma tabela de logaritmos no seja mais multiplicamos x por algo, resultando numa seqncia to til quanto j foi um dia, ela ainda d um bom exemplo de geomtrica. O resultado : iterao. O seguinte programa gera uma seqncia de valores 1.0 0.0 na coluna da esquerda e seus respectivos logaritmos na coluna 2.0 1.0 da direita: 4.0 2.0 x = 1.0 8.0 3.0 while x < 10.0: 16.0 4.0 print x, '\t', math.log(x) 32.0 5.0 x = x + 1.0 64.0 6.0 A string '\t' representa um caracter de tabulao. Por causa do caractere de tabulao entre as Conforme caracteres e strings vo sendo colunas, a posio da segunda coluna no depende do nmero mostrados na tela, um ponteiro invisvel chamado cursor de dgitos na primeira coluna. marca aonde aparecer o prximo caractere. Depois de um Tabelas de logaritmos podem no ser mais teis, comando print, o cursor normalmente vai para o incio de uma mas para cientistas da computao, conhecer as potncias de nova linha. dois ! O caractere de tabulao desloca o cursor para a Como um exerccio, modifique este programa direita at que ele encontre uma das marcas de tabulao. de modo que ele produza as potncias de dois acima de 65.535 GNU Free Documentation License #41

Como pensar como um cientista da Computao usando Python (ou seja, 216). Imprima e memorize-as. print n*i, '\t ', i = i + 1 O caractere de barra invertida em '\t' indica o incio de uma seqncia de escape. Seqncias de escape so print usadas para representar caracteres invisveis como de Para encapsular, tudo o que tivemos que fazer tabulao e de nova linha. A seqncia \n representa uma nova foi adicionar a primeira linha, que declara o nome de uma linha. funo e sua lista de parmetros. Para generalizar, tudo o que Uma seqncia de escape pode aparecer em tivemos que fazer foi substituir o valor 2 pelo parmetro n. qualquer lugar em uma string; no exemplo, a seqncia de Se chamarmos esta funo com o argumento 2, escape de tabulao a nica coisa dentro da string. teremos a mesma sada que antes. Com o argumento 3, a sada Como voc acha que se representa uma barra : invertida em uma string? 3 6 9 12 15 18 Como um exerccio, escreva um nica string que produza esta sada. 4 8 Com o argumento 4, a sada : 12 16 20 24 Agora voc provavelmente pode adivinhar como imprimir uma tabela de multiplicao - chamando imprimeMultiplos repetidamente com argumentos diferentes. De fato, podemos usar um outro loop:

6.4 Tabelas de duas dimenses (ou bi-dimensionais) i = 1


while i <= 6: imprimeMultiplos(i) i = i + 1 Note o quanto este loop parecido com aquele dentro de imprimeMultiplos. Tudo o que fiz foi substituir o Uma boa maneira de comear escrever um comando print pela chamada funo. loop que imprima os mltiplos de 2, todos em uma linha: A sada deste programa uma tabela de i = 1 multiplicao: while i <= 6: 1 2 3 4 5 6 print 2*i, ' ', 2 4 6 8 10 12 i = i + 1 3 6 9 12 15 18 print 4 8 12 16 20 24 A primeira linha inicializa a varivel chamada i, 10 15 20 25 30 a qual age como um contador ou varivel de controle do 5 loop. Conforme o loop executado, o valor de i 6 12 18 24 30 36 incrementado de 1 a 6. Quando i for 7, o loop termina. A cada repetio (iterao) do loop, mostrado o valor de 2*i, seguido de trs espaos. 6.6 Mais encapsulamento Uma tabela de duas dimenses uma tabela em que voc l o valor na interseo entre uma linha e uma coluna. Uma tabela de multiplicao um bom exemplo. Digamos que voc queira imprimir uma tabela de multiplicao de 1 a 6. De novo, a vrgula no comando print suprime a nova linha. Depois que o loop se completa, o segundo Para demonstrar de novo o encapsulamento, vamos pegar o cdigo do final da seo 6.5 e acondicion-lo, envolv-lo em comando print inicia uma nova linha. uma funo: A sada do programa : def imprimeTabMult(): 2 4 6 8 10 12 i = 1 At aqui, tudo bem. O prximo passo while i <= 6: encapsular e generalizar. imprimeMultiplos(i) i = i + 1 6.5 Encapsulamento e generalizao Este processo um plano de desenvolvimento comum. Ns desenvolvemos cdigo escrevendo linhas de Encapsulamento o processo de wrapping um pedao de cdigo fora de qualquer funo, ou digitando-as no cdigo em uma funo, permitindo que voc tire vantagem de interpretador. Quando temos o cdigo funcionando, extramos todas as coisas para as quais as funes so boas. Voc j viu ele e o embalamos em uma funo. dois exemplos de encapsulamento: imprimeParidade na seo Este plano de desenvolvimento 4.5; e eDivisivel na seo 5.4 particularmente til se voc no sabe, quando voc comea a Generalizao significa tomar algo que escrever, como dividir o programa em funes. Esta tcnica especfico, tal como imprimir os mltiplos de 2, e torn-lo permite a voc projetar enquanto desenvolve. mais geral, tal como imprimir os mltiplos de qualquer inteiro. Esta funo encapsula o loop anterior e generaliza-o para imprimir mltiplos de n: def imprimeMultiplos(n): i = 1 while i <= 6:

6.7 Variveis locais


Voc pode estar pensando como podemos utilizar a mesma varivel, i, em ambos, imprimeMultiplos e imprimeTabMult. Isto no causaria problemas quando uma das funes mudasse o valor da varivel?

GNU Free Documentation License #42

Como pensar como um cientista da Computao usando Python A resposta no, porque o i em 7 14 21 28 35 42 imprimeMultiplos e o i em imprimeTabMult no so a mesma Isto bom, exceto que ns provavelmente varivel. quereramos que a tabela fosse quadrada - com o mesmo Variveis criadas dentro de uma definio de nmero de linhas e colunas. Para fazer isso, adicionamos outro funo so locais; voc no pode acessar uma varivel local de parmetro a imprimeMultiplos para especificar quantas fora da funo em que ela "mora". Isto significa que voc colunas a tabela deveria ter. livre para ter mltiplas variveis com o mesmo nome, desde S para confundir, chamamos este novo que elas no estejam dentro da mesma funo. parmetro de altura, demonstrando que diferentes funes O diagrama de pilha para este programa mostra podem ter parmetros com o mesmo nome (como acontece que duas variveis chamadas i no so a mesma varivel. Elas com as variveis locais). Aqui est o programa completo: podem se referir a valores diferentes e alterar o valor de uma def imprimeMultiplos(n, altura): no afeta outra. i = 1 while i <= altura: print n*i, 't', i = i + 1 print def imprimeTabMult(altura): i = 1 while i <= altura: imprimeMultiplos(i, altura) i = i + 1 Note que quando adicionamos um novo parmetro, temos que mudar a primeira linha da funo (o cabealho da funo), e ns tambm temos que mudar o lugar O valor de i em imprimeTabMult vai de 1 a 6. de onde a funo chamada em imprimeTabMult. No diagrama, i agora 3. Na prxima iterao do loop i ser 4. Como esperado, este programa gera uma tabela A cada iterao do loop, imprimeTabMult chama imprimeMultiplos com o valor corrente de i como argumento. quadrada de sete por sete: O valor atribudo ao parmetro n. 1 2 3 4 5 6 7 Dentro de imprimeMultiplos, o valor de i vai de 2 4 6 8 10 12 14 1 a 6. No diagrama, i agora 2. Mudar esta varivel no tem 3 6 9 12 15 18 21 efeito sobre o valor de i em imprimeTabMult. 4 8 12 16 20 24 28 comum e perfeitamente legal ter variveis 5 10 15 20 25 30 35 locais diferentes com o mesmo nome. Em particular, nomes 6 12 18 24 30 36 42 como i e j so muito usados para variveis de controle de loop. 7 14 21 28 35 42 49 Se voc evitar utiliz-los em uma funo s porque voc j os Quando voc generaliza uma funo usou em outro lugar, voc provavelmente tornar seu apropriadamente, voc muitas vezes tem um programa com programa mais difcil de ler. capacidades que voc no planejou. Por exemplo, voc pode ter notado que, porque ab = ba, todas as entradas na tabela aparecem duas vezes. Voc poderia economizar tinta 6.8 Mais generalizao imprimindo somente a metade da tabela. Para fazer isso, voc Como um outro exemplo de generalizao, imagine que voc tem que mudar apenas uma linha em imprimeTabMult. Mude: precise de um programa que possa imprimir uma tabela de multiplicao de qualquer tamanho, no apenas uma tabela de imprimeTabMult(i, altura) para: seis por seis. Voc poderia adicionar um parmetro a imprimeTabMult: imprimeTabMult(i, i) e voc ter: def imprimeTabMult(altura): i = 1 1 while i <= altura: 2 4 imprimeMultiplos(i) 3 6 9 i = i + 1 4 8 12 16 Ns substitumos o valor 6 pelo parmetro 5 10 15 20 25 altura. Se chamarmos imprimeTabMult com o argumento 7, 6 12 18 24 30 36 ela mostra: 7 14 21 28 35 42 49 1 2 3 4 5 6 Como um exerccio, trace a execuo desta verso de imprimeTabMult e explique como ela funciona. 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 5 10 15 20 25 30 6 12 18 24 30 36 GNU Free Documentation License #43

6.9 Funes

Como pensar como um cientista da Computao usando Python Generalizaes do maior versatilidade ao cdigo, maior possibilidade de reuso, e em algumas situaes at mesmo maior H pouco tempo mencionamos "todas as coisas para facilidade para escrev-lo. as quais as funes so boas." Agora, voc pode estar pensando que coisas exatamente so estas. Aqui esto processo definido para plano de um algumas delas: desenvolvimento desenvolvimento de um programa. Neste (development captulo, ns demonstramos um estilo de Dar um nome para uma seqncia de comandos torna plan) desenvolvimento baseado em escrever seu programa mais fcil de ler e de depurar. cdigo para executar tarefas simples e Dividir um programa longo em funes permite que especficas, usando encapsulamento e voc separe partes do programa, depure-as generalizao. isoladamente, e ento as componha em um todo.

Funes facilitam tanto recurso quanto iterao. Funes bem projetadas so freqentemente teis para muitos programas. Uma vez que voc escreva e depure uma, voc pode reutiliz-la.

6.10 Glossrio
reatribuio quando mais de um valor atribudo a (multiple mesma varivel durante a execuo do assignment 1) programa. iterao execuo repetida de um conjunto de (iteration) comandos/instrues (statements) usando uma chamada recursiva de funo ou um lao (loop). lao (loop) um comando/instruo ou conjunto de comandos/instrues que executam repetidamente at que uma condio de interrupo seja atingida. lao infinito um lao em que a condio de interrupo (infinite loop) nunca ser atingida. corpo (body) o conjunto de comandos/instrues que pertencem a um lao. varivel de lao uma varivel usada como parte da (loop variable) condio de interrupo do lao. tabulao (tab) um carcter especial que faz com que o cursor mova-se para a prxima parada estabelecida de tabulao na linha atual. nova-linha um carcter especial que faz com que o (newline) cursor mova-se para o incio da prxima linha. cursor (cursor) um marcador invisvel que determina onde o prximo carcter var ser impresso. sequncia de um carcter de escape () seguido por um escape (escape ou mais caracteres imprimveis, usados sequence) para definir um carcter no imprimvel. encapsular quando um programa grande e complexo (encapsulate) dividido em componentes (como funes) e estes so isolados um do outro (pelo uso de variveis locais, por exemplo). generalizar quando algo que desnecessariamente (generalize) especfico (como um valor constante) substitudo por algo apropriadamente geral (como uma varivel ou um parmetro).
1

N.T.: O termo multiple assignment (ou atribuio mltipla) usado com mais frequncia para descrever a sintaxe a = b = c. Por este motivo optamos pelo termo reatribuio no contexto da seo 6.1 desse captulo. GNU Free Documentation License #44

Captulo 7: Strings

de 0 a 5. Para pegar o ltimo caractere, temos que subtrair 1 de comprimento:

7.1 Um tipo de dado composto


At aqui, vimos trs diferentes tipos de dado: int, float e string. Strings so qualitativamente diferentes dos outros dois tipos porque so feitas de pedaos menores - caracteres. Tipos que consistem de pedaos menores so chamados tipos de dados compostos. Dependendo do que estejamos fazendo, pode ser que precisemos tratar um tipo de dado composto como uma coisa nica, ou pode ser que queiramos acessar suas partes. Esta ambigidade til.

comprimento = len(fruta) ultima = fruta[comprimento-1] Como alternativa, podemos usar ndices negativos, os quais contam de trs pra frente os elementos da string. A expresso fruta[-1] resulta a ltima letra, fruta[-2] resulta a penltima (a segunda de trs para frente), e assim por diante.

7.3 Travessia e o loop for

O operador colchete seleciona um nico caractere de uma string.: Vrias computaes envolvem o processamento de uma string um caractere de cada vez. Muitas vezes elas comeam com o >>> fruta = "banana" primeiro, selecionam um de cada vez, fazem alguma coisa >>> letra = fruta[1] com ele, e continuam at o fim. Este padro de processamento chamado uma travessia (traversal, com a idia de >>> print letra A expresso fruta[1] seleciona o caractere "percorrimento"). Uma maneira de codificar uma travessia nmero 1 de fruta. A varivel letra referencia ou refere-se ao com um comando while: resultado da expresso. Quando exibimos letra, temos uma indice = 0 surpresa: while indice < len(fruta): a letra = fruta[indice] A primeira letra de "banana" no a. A menos print letra que voc seja um cientista da computao. Neste caso, voc indice = indice + 1 deve entender a expresso dentro dos colchetes como um Este loop percorre a string e exibe cada letra em deslocamento (offset,) a partir do comeo da string, e o deslocamento da primeira letra zero. Assim, b a 0 ("zero- sua prpria linha. A condio do loop indice < len(fruta), sima") letra de "banana", a a 1 ("um-sima", diferente de assim, quando ndice igual ao comprimento da string, a primeira), e n a 2 ("dois-sima", diferente de segunda) letra. condio se torna falsa, e o corpo do loop no executado. O ltimo caractere acessado aquele com o ndice len(fruta)-1, Para pegar a primeira letra de uma string, voc que vem a ser o ltimo caractere da string. simplesmente pe 0, ou qualquer expresso que resulte o valor Como um exerccio, escreva uma funo que 0, dentro dos colchetes: tome uma string como argumento e devolva suas letras de trs para frente, uma por linha. >>> letra = fruta[0] >>> print letra Usar um ndice para percorrer um conjunto de valores to comum que Python oferece uma sintaxe b A expresso entre colchetes chamada de alternativa simplificada - o loop for: ndice. Um ndice especifica um membro de um conjunto ordenado, neste caso o conjunto de caracteres da string. O for char in fruta: print char ndice indica aquele membro que voc quer, da seu nome. Ele A cada vez atravs do loop, o prximo caractere pode ser qualquer expresso inteira. da string atribudo varivel char. O loop continua at que no reste mais caracteres.

7.2 Comprimento

O exemplo seguinte mostra como usar concatenao e um loop for para gerar uma srie abecedrio. A funo len retorna o nmero de caracteres de uma string: "Abecedrio" se refere a uma srie ou lista na qual os elementos aparecem em ordem alfabtica. Por exemplo, no >>> fruta = "banana" livro de Robert McCloskey's Make Way for Ducklings, os >>> len(fruta) nomes dos "ducklings" so Jack, Kack, Lack, Mack, Nack, 6 Ouack, Pack e Quack. O loop seguinte, produz como sada Para pegar a ltima letra de uma string, voc aqueles nomes, em ordem: pode ficar tentado a fazer alguma coisa assim: prefixos = "JKLMNOPQ" comprimento = len(fruta) sufixo = "ack" ultima = fruta[comprimento] # ERRO! No vai funcionar. Isto vai causar o seguinte for letra in prefixos: erro em tempo de execuo (runtime error): IndexError: string print letra + sufixo index out of range. (ErroDeIndice: ndice da string fora do A sada deste programa : intervalo). A razo que no existe 6 letra em "banana". J que comeamos a contar do zero, as seis letras so numeradas

Como pensar como um cientista da Computao usando Python de\ banana." elif palavra > "banana": print "Sua palavra," + palavra + ", vem depois \ de banana." else: print "Sim, ns no temos bananas!" Entretanto, voc deve atentar para o fato de que Naturalmente, esta sada no est cem por cento certa porque "Ouack" e "Quack" esto escritos de maneira Pyhton no manipula letras maisculas e minsculas da mesma maneira que as pessoas o fazem. Todas as letras errada. maisculas vm antes das minsculas. Como resultado: Como um exerccio, modifique o programa para corrigir este erro. Sua palavra, Zebra, vem antes de banana. Uma maneira comum de resolver este problema converter as strings para um formato padro, seja todas 7.4 Fatias de strings minsculas, ou todas maisculas, antes de realizar a comparao. Um problema mais difcil fazer o programa Um segmento de uma string chamado de uma fatia. perceber que zebras no so frutas. Selecionar uma fatia similar a selecionar um caractere: Jack Kack Lack Mack Nack Oack Pack Qack >>> s = "Pedro, Paulo e Maria" >>> print s[0:5] Pedro >>> print s[7:12] Paulo >>> print s[16:21] Maria O operador [n:m] retorna a parte da string do "nsimo" caractere ao "m-simo" caractere, incluindo o primeiro mas excluindo o ltimo. Este comportamento no intuitivo; ele faz mais sentido se voc imaginar os ndices apontando para os intervalos entre os caracteres, como no seguinte diagrama:

7.6 Strings so imutveis


tentador usar o operador [] no lado esquerdo de uma expresso de atribuio, com a inteno de alterar um caractere em uma string. Por exemplo: saudacao = "Al, mundo!" saudacao[0] = 'E' # ERRO! print saudacao Em vez de produzir a sada El, Mundo!, este cdigo produz o erro em tempo de execuo (runtime error): TypeError: object doesn't support item assignment (ErroDeTipo: objeto no d suporte atribuio de item.) Strings so imutveis, o que significa que voc no pode mudar uma string que j existe. O melhor que voc pode fazer criar uma nova string que seja uma variao da original:

saudacao = "Al, mundo!" novaSaudacao = 'E' + saudao[1:] print novaSaudacao A soluo aqui concatenar uma nova primeira Se voc omitir o primeiro ndice (antes dos dois pontos ":"), a fatia comea do incio da string. Se voc omitir o letra com uma fatia de saudao. Esta operao no tem nenhum efeito sobre a string original. segundo ndice, a fatia vai at o final da string. Assim: >>> fruta = "banana" >>> fruta[:3] 'ban' >>> fruta[3:] 'ana' O que voc acha de s[:] significa?

7.7 Uma funo find (encontrar)


O que faz a seguinte funo?:

def find(str, ch): indice = 0 while indice < len(str): if str[indice] == ch: 7.5 Comparao de strings return indice indice = indice + 1 O operador de comparao funciona com strings. Para ver se return -1 duas strings so iguais: Num certo sentido, find (encontrar) o oposto if palavra == "banana": do operador []. Em vez de pegar um ndice e extrair o print "Sim, ns no temos bananas!" caractere correspondente, ela pega um caractere e encontra Outras operaes de comparao so teis para (finds) em qual ndice aquele caractere aparece. Se o caractere no encontrado, a funo retorna -1. colocar palavras em ordem alfabtica: if palavra < "banana": print "Sua palavra," + palavra + ", vem antes Este o primeiro exemplo que vemos de uma instruo return dentro de um loop. Se str[indice] == ch, a funo retorna imediatamente, abandonando o loop

GNU Free Documentation License #46

Como pensar como um cientista da Computao usando Python Alm disso, ela recebe um argumento adicional que especifica o ndice pelo qual ela deve comear sua Se o caractere no aparece na string, ento o procura: programa sai do loop normalmente e retorna -1. Este padro de computao s vezes chamado >>> string.find("banana", "na", 3) de travessia "eureka", porque to logo ele encontra (find) o 4 que est procurando, ele pode gritar "Eureka!" e parar de Ou ela pode receber dois argumentos adicionais procurar. que especificam o intervalo de ndices: prematuramente. Como um exerccio, modifique a funo find >>> string.find("bob", "b", 1, 2) (encontrar) de modo que ela receba um terceiro parmetro, o -1 ndice da string por onde ela deve comear sua procura. Neste exemplo, a busca falha porque a letra b no aparece no intervalo entre 1 e 2 (no incluindo o 2) do ndice. 7.8 Iterando e contando O programa seguinte conta o nmero e vezes que a letra a aparece em uma string: fruta = "banana" contador = 0 for letra in fruta: if letra == 'a' contador = contador + 1 print contador Este programa demonstra um outro padro de computao chamado de contador. A varivel contador inicializada em 0 e ento incrementada cada vez que um a encontrado. (Incrementar o mesmo que aumentar em um; o oposto de decrementar, e no tem relao com excremento, que um substantivo.) Quando se sai do loop, contador guarda o resultado - o nmero total de a's.

7.10 Classificao de caracteres


Muitas vezes til examinar um caractere e testar se ele maisculo ou minsculo, ou se ele um caractere ou um dgito. O mdulo string oferece vrias constantes que so teis para esses propsitos. A string string.lowercase contm todas as letras que o sistema considera como sendo minsculas. Similarmente, string.uppercase contm todas as letras maisculas. Tente o seguinte e veja o que voc obtm:

>>> print string.lowercase >>> print string.uppercase >>> print string.digits Ns podemos usar essas constantes e find (encontrar) para classificar caracteres. Por exemplo, se Como um exerccio, encapsule este cdigo em find(lowercase, ch) retorna um valor outro que no -1, ento uma funo chamada contaLetras, e generalize-a de modo que ch deve ser minsculo: possa aceitar uma string e uma letra como parmetros. def eMinusculo(ch): Como um segundo exerccio, reescreva esta return string.find(string.lowercase, ch) != -1 funo de modo que em vez de percorrer a string, ela use a Como uma alternativa, podemos tirar vantagem verso com trs parmetros de find (encontrar) da seo do operador in, que determina se um caractere aparece em anterior. uma string: def eMinusculo(ch): return ch in string.lowercase Ainda, como uma outra alternativa, podemos O mdulo string contm funes teis que manipulam strings. usar o operador de comparao: Conforme usual, ns temos que importar o mdulo antes que possamos utiliz-lo: def eMinusculo(ch): return 'a' <= ch <= 'z' >>> import string Se ch estiver entre a e z, ele deve ser uma letra O mdulo string inclui uma funo chamada find (encontrar) que faz a mesma coisa que a funo que minscula. escrevemos. Para cham-la, temos que especificar o nome do Como um exerccio, discuta que verso de mdulo e o nome da funo usando a notao de ponto.: eMinusculo voc acha que ser a mais rpida. Voc pode pensar em outras razes alm da velocidade para preferir uma >>> fruta = "banana" em vez de outra? >>> indice = string.find(fruta, "a") Outra constante definida no mdulo string pode >>> print indice te surpreender quando voc executar um print sobre ela: 1 Este exemplo demonstra um dos benefcios dos >>> print string.whitespace Caracteres de espaamento (ou espaos em mdulos - eles ajudam a evitar colises entre nomes de funes nativas e nomes de funes definidas pelo usurio. branco) movem o cursor sem "imprimir" qualquer coisa. Eles Usando a notao de ponto podemos especificar que verso de criam os espaos em branco entre os caracteres visveis (pelo menos numa folha de papel branco). A string constante find (encontrar) ns queremos. string.whitespace contm todos os caracteres de espaamento, De fato, string.find mais generalizada que a incluindo espao, tabulao (\t) e nova linha (\n). nossa verso. Primeiramente, ela pode encontrar substrings, Existem outras funes teis no mdulo string, no apenas caracteres: mas este livro no pretende ser um manual de referncia. Por >>> string.find("banana", "na") outro lado, Python Library Reference exatamente isto. Em meio a uma abundante documentao, ele est disponvel no 2

7.9 O mdulo string

GNU Free Documentation License #47

Como pensar como um cientista da Computao usando Python site da web do Python, www.python.org.

7.11 Glossrio
tipo de dado Um tipo de dado no qual o valor consiste de composto componentes, ou elementos, que so eles (compound mesmos valores. data type) travessia Iterar atravs dos elementos de um conjunto, (traverse) realizando uma operao similar em cada um deles. ndice (index) Uma varivel ou valor usados para selecionar um membro de um conjunto ordenado, como um caractere em uma string. fatia (slice) Uma parte de uma string especificada por um intervalo de ndices. mutvel Um tipo de dado composto a cujos (mutable) elementos podem ser atribudos novos valores. contador Uma varivel utilizada para contar alguma (counter) coisa, usualmente inicializada em zero e ento incrementada. incrementar aumentar o valor de uma varivel em 1. (increment) decrementar diminuir o valor de uma varivel em 1. (decrement) espaamento Qualquer um dos caracteres que move o (whitespace) cursor sem imprimir caracteres visveis. A constante string.whitespace contm todos os caracteres de espaamento.

7.11 Glossrio2
tipo de dado composto (compound data type) Um tipo de dado em que os valores so compostos de componentes, ou elementos, que podem ser tratados como valores separados.

atravessar Iterar atravs dos elementos definidos, (traverse) executando uma operao similar em cada. ndice (index) Uma varivel ou valor usado para selecionar um membro de uma definio ordenada, como um caractere de uma string. fatia (slice) Uma parte da string especificada por um intervalo de ndice. mutvel Um tipo de dado composto do qual (mutable) elementos podem atribuir novos valores. contador Uma varivel usada para contar alguma (counter) coisa, geralmente iniciada em zero e incrementada. incremento Para aumentar o valor da varivel. (increment) decremento Para dimiuir o valor da varivel. (decrement) espao em Qualquer caractere que move o cursor sem branco imprimir caracteres visveis. A constante (whitespace) string.whitespace contm todos os caracteres de espao em branco.

GNU Free Documentation License #48

Captulo 8: Listas

Uma lista um conjunto ordenado de valores, onde cada valor identificado por um ndice. Os valores que compem uma lista so chamados elementos. Listas so similares a strings, 8.2 Acessado elementos que so conjuntos ordenados de caracteres, com a diferena que os elementos de uma lista podem possuir qualquer tipo. A sintaxe para acessar os elementos de uma lista a mesma Listas e strings XXX e outras coisas que se comportam como que a sintaxe para acessar os caracteres de uma string XXX o conjuntos ordenados XXX so chamados seqncias. operator colchete ([]). A expresso dentro dos colchetes especifica o ndice. Lembre-se que os ndices iniciam em 0: >>> print numeros[0] >>> numeros[1]= 5 Existem vrias maneiras de criar uma nova lista; a mais O operador colchete pode aparecer em qualquer simples envolver os elementos em colchetes ([ e ]): lugar em uma expresso. Quando ele aparece no lado esquerdo de uma atribuio, ele modifica um dos elementos em uma >>> [10, 20, 30, 40] lista, de forma que o um-simo elemento de numeros, que era >>> ['spam', 'bungee', 'swallow'] 123, agora 5. O primeiro exemplo uma lista de quatro Qualquer expresso inteira pode ser utilizada inteiros. O segundo uma lista de trs strings. Os elementos de uma lista no necessitam ser do mesmo tipo. A lista a seguir como um ndice: contm uma string, um valor float, um valor inteiro, e mirabile >>> numeros[3-2] dictu uma outra lista: 5 >>> ['alo', 2.0, 5, [10,20]] >>> numeros[1.0] Uma lista dentro de outra lista dita estar TypeError: sequence index must be integer aninhada. Se voc tentar ler ou escrever um elemento que Listas que contm inteiros consecutivos so no existe, voc recebe um erro de tempo de execuo comuns, ento Python fornece uma maneira simples de cri- (runtime error): los: >>> numeros[2]=5 >>> range(1,5) IndexError: list assignment index out of range Se um ndice possui um valor negativo, ele [1, 2, 3, 4] A funo range pega dois argumentos e devolve conta ao contrrio a partir do final da lista: uma lista que contm todos os inteiros do primeiro at o >>> numeros[-1] segundo, incluindo o primeiro mas no incluindo o segundo! 5 Existem outras formas de range. Com um >>> numeros[-2] argumento simples, ela cria uma lista que inicia em 0: 17 >>> range(10) >>> numeros[-3] [0,1, 2, 3, 4, 5, 6, 7, 8, 9] IndexError: list index out of range Se existe um terceiro argumento, ele especifica numeros[-1] o ltimo elemento da lista, o espao entre os valores sucessivos, que chamado de numeros[-2] o penltimo e numeros[-3] no existe. tamanho do passo. Este exemplo conta de 1 at 10 em passos comum utilizar uma varivel de lao como um de 2: ndice da lista: >>> range(1, 10, 2) >>> cavaleiros = ['guerra', 'fome', 'peste', [1, 3, 5, 7, 9] Finalmente, existe uma lista especial que no 'morte'] contm elementos. Ela chamada lista vazia, e sua notao i = 0 []. while i < 4: print cavaleiros[i] Com todas estas formas de criar listas, seria decepcionante se no pudssemos atribuir valores de listas a i = i + 1 variveis ou passar listas como parmetros a funes. Este lao while conta de 0 at 4. Quando a Felizmente, podemos. varivel do lao i 4, a condio falha e o lao se encerra. Desta forma o corpo do lao executado somente quando i >>> vocabulario = ['melhorar', 'castigar', \ 0, 1, 2 e 3. 'defenestrar'] Em cada vez dentro do lao, a varivel i >>> numeros = [17, 123] utilizada como um ndice para a lista, exibindo o i-simo >>> vazio = [] elemento. Este padro de computao chamado de percurso >>> print vocabulario, numeros, vazio na lista. ['melhorar', 'castigar', 'defenestrar'] [17, 123] []

8.1 Valores da lista

Como pensar como um cientista da Computao usando Python VARIABLE = LIST[i] XXX BODY A funo len devolve o comprimento de uma lista. uma boa i = i + 1 idia utilizar este valor como o limite superior de um lao ao O lao for mais conciso porque podemos invs de uma constante. Desta forma, se o tamanho da lista eliminar a varivel do lao, i. Aqui est o lao anterior escrito mudar, voc no precisar ir atravs de todo o programa com um`lao for: modificando todos os laos; eles funcionaro corretamente para qualquer tamanho de lista: >>> for cavaleiro in cavaleiros: print cavaleiro >>> cavaleiros = ['guerra', 'fome', 'peste', Quase se l como Portugus: "For (para cada) 'morte'] cavaleiro in (na lista de) cavaleiros, print (imprima o nome do) i = 0 cavaleiro." while i < len(cavaleiros): Qualquer expresso de lista pode ser utilizada print cavaleiros[i] num lao for: i = i + 1 A ltima vez que o corpo do lao executado, i >>> for numero in range(20): if numero % 2 == 0: len(cavaleiros) - 1, que o ndice do ltimo elemento. Quando i igual a len(cavaleiros), a condio falha e o corpo print numero no executado, o que uma boa coisa, porque len(cavaleiros) no um ndice legal. >>> for fruta in ["banana", "abacaxi", "laranja"]: Embora uma lista possa conter uma outra lista, a print "Eu gosto de comer " + fruta + "s!" lista aninhada ainda conta como um elemento simples. O O primeiro exemplo exibe todos os nmeros comprimento desta lista quatro: pares entre zero e dezenove. O segundo exemplo expressa o entusiasmo por vrias frutas. >>> [`spam!', 1, ['Brie', 'Roquefort', \

8.3 Comprimento da lista

'Pol l Veq'], [1, 2 3]] Como um exerccio, escreva um lao que 8.6 Operaes em listas percorra a lista anterior e exiba o comprimento de cada elemento. O que acontece se voc manda um inteiro para len? O operador + concatena listas: >>> a = [1, 2, 3] >>> b = [4, 5, 6] in um operador lgico que testa se um elemento membro >>> c = a + b de uma seqncia. Ns o utilizamos na Seo 7.10 com >>> print c strings, mas ele tambm funciona com listas e outras [1, 2, 3, 4, 5, 6] seqncias: Similarmente, o operador * repete uma lista um nmero dado de vezes: >>> cavaleiros = ['guerra', 'fome', 'peste', >>> [0] * 4 'morte'] [0, 0, 0, 0] >>> 'peste' in cavaleiros >>> [1, 2, 3] * 3 True [1, 2, 3, 1, 2, 3, 1, 2, 3] >>> 'depravao' in cavaleiros O primeiro exemplo repete [0] quatro vezes. O False Uma vez que 'peste' um membro da lista segundo exemplo repete a lista [1, 2, 3] trs vezes. cavaleiros, o operador in devolve verdadeiro. Uma vez que depravao no est na lista, in devolve falso.

8.4 Membros de uma lista

Podemos utilizar tambm o not em combinao com o in para testar se um elemento no um membro de uma A operao de fatiamento que vimos na Seo 7.4 tambm lista: funciona sobre listas: >>> ``depravao`` not in cavaleiros True >>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] >>> lista[1:3] ['b', 'c'] >>> lista[:4] 8.5 Listas e laos for ['a', 'b', 'c', 'd'] O lao for que vimos na Seo 7.3 tambm funciona com >>> lista[3:] listas. A sintaxe generalizada de um lao for : ['d', 'e', 'f'] >>> lista[:] for VARIVEL in LISTA: ['a', 'b', 'c', 'd', 'e', 'f'] CORPO Esta declarao equivalente a: >>> i = 0 while i < len(LIST):

8.7 Fatiamento de listas

8.8 Listas so mutveis


Diferente das strings, as listas so mutveis, o que significa GNU Free Documentation License #50

Como pensar como um cientista da Computao usando Python que podemos modificar seus elementos. Utilizando o operador >>> b = "banana" colchete no lado esquerdo de uma atribuio, podemos sabemos que a e b se referem a uma string com atualizar um de seus elementos: as letras banana. Mas no podemos dizer se elas apontam para a mesma string. >>> fruta = ["banana", "abacaxi", "laranja"] >>> fruta[0] = "abacate" >>> fruta[-1] = "tangerina" >>> print fruta ['abacate', 'abacaxi', 'tangerina'] Com o operador de fatiamento podemos atualizar vrios elementos de uma vez: Existem dois possveis estados:

Em um caso, a e b se referem a duas coisas >>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] diferentes que possuem o mesmo valor. No segundo caso, elas >>> lista[1:3] = ['x', 'y'] se referem mesma coisa. Estas "coisas" possume nomes >>> print lista elas so chamadas objetos. Um objeto algo ao qual uma varivel pode se referenciar. ['a', 'x', 'y', 'd', 'e', 'f'] Tambm podemos remover elementos de uma Todo objeto possui um identificador nico, que lista atribuindo a lista vazia a eles: podemos obter com a funo id. Exibindo o identificador de a e b, podemos dizer se elas se referem ao mesmo objeto. >>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] >>> lista[1:3] = [] >>> id(a) >>> print lista 135044008 ['a', 'd', 'e', 'f'] >>> id(b) E podemos adicionar elementos a uma lista 135044008 enfiando-os numa fatia vazia na posio desejada: De fato, obtivemos o mesmo identificador duas vezes, o que significa que Python criou apenas uma string, e >>> lista = ['a', 'd', 'f'] tanto a quanto b se referem a ela. >>> lista[1:1] = ['b', 'c'] Interessantemente, listas se comportam de forma >>> print lista diferente. Quando criamos duas listas, obtemos dois objetos: ['a', 'b', 'c', 'd', 'f'] >>> a = [1, 2, 3] >>> lista[4:4] = ['e'] >>> b = [1, 2, 3] >>> print lista >>> id(a) ['a', 'b', 'c', 'd', 'e', 'f'] 135045528 >>> id(b) 8.9 Remoo em lista 135041704 Ento o diagrama de estado fica assim: Utilizando fatias para remover elementos pode ser complicado, e desta forma propenso a erro. Python fornece uma alternativa que mais legvel. del remove um elemento de uma lista: >>> a = ['um', 'dois', 'tres'] >>> del a[1] >>> a a e b possuem o mesmo valor mas no se ['um', 'tres'] referem ao mesmo objeto. Como voc deveria esperar, del trata valores negativos e causa erros de tempo de execuo se o ndice estiver fora da faixa. 8.11 Apelidos Voc tambm pode utilizar uma faixa como um Uma vez que variveis se referem a objetos, se atribuimos ndice para del: uma varivel a uma outra, ambas as variveis se referem ao mesmo objeto: >>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] >>> del lista[1:5] >>> a = [1, 2, 3] >>> print lista >>> b = a ['a', 'f'] Neste caso, o diagrama de estado se parece com Como de costume, fatias selecionam todos os isto: elementos at, mas no incluindo, o segundo ndice.

8.10 Ojetos e valores


Se executamos estas declaraes de atribuio: >>> a = "banana" GNU Free Documentation License #51

Como pensar como um cientista da Computao usando Python Uma vez que a lista possui dois nomes dois quadros, o desenhamos entre eles. diferentes, a e b, dizemos que ela est "apelidada" (aliased). Se a funo modifica um parmetro da lista, a Mudanas feitas em um apelido afetam o outro nome: funo chamadora v a mudana. Por exemplo, removeCabeca remove o primeiro elemento da lista: >>> b[0] = 5 >>> print a [5, 2, 3] >>> def removecabeca(lista): del lista[0] Embora este comportamento possa ser til, ele Aqui est a maneira como ela utilizada: s vezes inesperado e indesejado. Em geral, mais seguro evitar os apelidos quando voc est trabalhando com objetos >>> numeros = [1, 2, 3] mutveis. claro, para objetos imutveis, no h problema. >>> removeCabeca(numeros) por isto que Python livre para apelidar cadeias de caracteres >>> print numeros quando v uma oportunidade de economizar. [2, 3] Se uma funo devolve uma lista, ela devolve uma referncia lista. Por exemplo, cauda devolve uma lista 8.12 Clonando listas que contm todos menos o primeiro elemento de uma Se queremos modificar uma lista e tambm manter uma cpia determinada lista: da original, preciamos ter condies de fazer uma cpia da prpria lista, no apenas uma referncia. Este processo >>> def cauda(lista): return lista[1:] algumas vezes chamado clonagem, para evitar a ambigidade Aqui est a maneira como ela utilizada: da palavra "cpia". A maneira mas fcil de clonar uma lista >>> numeros = [1, 2, 3] utilizar o operador de fatia: >>> resto = cauda(numeros) >>> print resto >>> a = [1, 2, 3] [2, 3] >>> b = a[:] Uma vez que o valor de retorno foi criado com o >>> print b operador de fatia, ele uma nova lista. A criao de resto, e [1, 2, 3] qualquer alterao subseqente a resto, no tem efeito sobre Pegar qualquer fatia de a cria uma nova lista. numeros. Neste caso acontece da fatia consistir da lista inteira. Agora estamos livres para fazer alteraes a b sem nos preocuparmos com``a``:

8.14 Lista aninhadas

>>> b[0] = 5 Uma lista aninhada uma lista que aparece como um elemento de uma outra lista. Nesta lista, o terceiro elemento uma lista >>> print a aninhada: [1, 2, 3] Como exerccio, desenhe um diagrama de >>> lista = ["alo", 2.0, 5, [10, 20]] estado para``a`` e b antes e depois desta mudana. Se exibimos lista[3], obtemos [10, 20]. Para extrairmos um elemento de uma lista aninhada, podemos agir em duas etapas:

8.13 Lista como parmetro

>>> elem = lista[3] Passar uma lista como um argumento passa realmente uma >>> elem[0] referncia lista, no uma cpia da lista. Por exemplo, a funo cabeca pega uma lista como parmetro e devolve a 10 Ou podemos combin-las: cabea da lista, ou seja, seu primeiro elemento: >>> lista[3][1] >>> def cabeca(lista): 20 return lista[0] Os operadores colchete avaliam da esquerda Eis como ela utilizada: para a direita, ento a expresso pega o terceiro elemento de lista e extrai o primeiro elemento dela. >>> numeros = [1, 2, 3] >>> cabeca(numeros) 1 8.15 Matrizes O parmetro lista e a varivel numeros so apelidos para o mesmo objeto. O diagrama de estado se parece Listas aninhadas so freqentemente utilizadas para com isto: representar matrizes. Por exemplo, a matriz:

poderia ser representada como: Uma vez que o objeto compartilhado pelos >>> matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] GNU Free Documentation License #52

Como pensar como um cientista da Computao usando Python matriz uma lista com trs elementos, onde 'O orvalho no carvalho...' cada elemento uma linha da matriz. Podemos selecionar uma Como split, join recebe um delimitador que linha inteira da matriz da maneira habitual: inserido entre os elementos: >>> matriz[1] >>> string.join(lista, '_') [4, 5, 6] 'O_orvalho_no_carvalho...' Ou podemos extrair um nico elemento da Como um execcio, descreva o relacionamento matriz utilinado a forma de duplo ndice: entre string.join(string.split(poesia)) e poesia. Eles so o mesmo para qualquer string? Quando eles seriam diferentes? >>> matriz[1][1] 5 O primeiro ndice seleciona a linha, e o segundo 8.17 Glossrio ndice seleciona a coluna. Embora esta maneira de representar matrizes seja comum, ela no a nica possibilidade. Uma lista (list) Uma coleo denominada de objetos, onde pequena variao utilizar uma lista de colunas ao invs de cada objeto identificado por um ndice. uma lista de linhas. Mais adiante veremos uma alternativa mais ndice (index) Uma varivel inteira ou valor que indica um elemento de uma lista. radical utilizando um dicionrio. elemento Um dos valores em uma lista(ou outra (element) seqncia). O operador colchete seleciona 8.16 Strings e listas elementos de uma lista. Duas das mais teis funes no mdulo string envolvem listas de strings. A funo split (separar) quebra uma string em uma lista de palavras. Por padro, qualquer nmero de caracteres espao em branco considerado um limite de uma palavra: >>> import string >>> poesia = "O orvalho no carvalho..." >>> string.split(poesia) ['O', 'orvalho', 'no', 'carvalho...'] Um argumento opcional chamado um delimitador pode ser utilizado para especificar qual caracter utilizar como limites da palavra. O exemplo a seguir utiliza a string va: >>> string.split(poesia, 'va') ['O or', 'lho no car', 'lho...'] Perceba que o delimitador no aparece na lista. A funo join (juntar) o inverso de split. Ela pega uma lista de strings e concatena os elementos com um espao entre cada par: >>> lista = ['O', 'orvalho', 'no', 'carvalho...'] >>> string.join(lista) seqncia Qualquer um dos tipos de dados que (sequence) consiste de um conjunto ordenado de elementos, com cada elemento identificado por um ndice. lista aninhada Uma lista que um elemento de uma outra (nested list) lista. percurso na O acesso seqencial de cada elemento em lista (list uma lista. traversal) objeto (object) Um coisa a qual uma varivel pode se referir. apelidos Mltiplas variveis que contm referncias (aliases) ao mesmo objeto. clonar (clone) Criar um novo objeto que possui o mesmo valor de um objeto existente. Copiar a referncia a um objeto cria um apelido (alias) mas no clona o objeto. delimitador Um caracter uma string utilizados para (delimiter) indicar onde uma string deveria ser dividida(split).

GNU Free Documentation License #53

Captulo 9: Tuplas

fazer a troca entre a e b: >>> temp = a >>> a = b At agora, voc tem visto dois tipos compostos: strings, que >>> b = temp so compostos de caracteres; e listas, que so compostas de Se voc tiver que fazer isso com frequncia, esta elementos de qualquer tipo. Uma das diferenas que notamos abordagem se torna incmoda. Python fornece uma forma de que os elementos de uma lista podem ser modificados, mas os atribuio de tupla que resolve esse problema elegantemente: caracteres em uma string no. Em outras palavras, strings so imutveis e listas so mutveis. >>> a, b = b, a O lado esquedo uma tupla de variveis; o lado H um outro tipo em Python chamado tupla (tuple) que similar a uma lista exceto por ele ser imutvel. direito uma tupla de valores. Cada valor atribudo sua Sintaticamente, uma tupla uma lista de valores separados por respectiva varivel. Todas as expresses do lado direito so avaliadas antes de qualquer das atribuies. Esta caracterstica vrgulas: torna as atribuies de tupla bastante versteis. >>> tupla = 'a', 'b', 'c', 'd', 'e' Naturalmente, o nmero de variveis na Embora no seja necessrio, convencional esquerda e o nmero de valores na direita deve ser igual: colocar tuplas entre parnteses: >>> a, b, c, d = 1, 2, 3 >>> tupla = ('a', 'b', 'c', 'd', 'e') ValueError: unpack tuple of wrong size Para criar uma tupla com um nico elemento, temos que incluir uma vrgula final:

9.1 Mutabilidade e tuplas

9.3 Tuplas como valores de retorno >>> t1 = ('a',) >>> type(t1) Funes podem retornar tuplas como valor de retorno. Por <type 'tuple'> Exemplo, ns poderamos escrever uma funo que troca dois Sem a vrgula, Python entende ('a') como uma parmetros entre si: string entre parnteses: def troca(x, y): >>> t2 = ('a') return y, x >>> type(t2) Ento ns poderamos atribuir o valor de retorno <type 'string'> para uma tupla com duas variveis: Questes de sintaxe de lado, as operaes em tuplas so as mesmas operaes das listas. O operador ndice a, b = troca(a, b) Neste caso, no existe uma grande vantagem em seleciona um elemento da tupla. fazer de troca (swap) uma funo. De fato, existe um perigo >>> tupla = ('a', 'b', 'c', 'd', 'e') em tentar encapsular troca, o qual a tentao de cometer o seguinte erro: >>> tupla[0] 'a' def troca(x, y): # versao incorreta E o operador slice (fatia) seleciona uma "faixa" x, y = y, x (range) de elementos. Se ns chamarmos esta funo desta forma: >>> tupla[1:3] troca(a, b) ('b', 'c') ento a e x so apelidos para um mesmo valor. Mas se tentarmos modificar um dos elementos Mudar x dentro da funo troca, faz com que x se referencie a de uma tupla, teremos um erro: um valor diferente, mas sem efeito sobre a dentro de __main__. Do mesmo modo, a mudana em y no tem efeito >>> tupla[0] = 'A' sobre b. TypeError: object doesn't support item assignment Esta funo roda sem produzir uma mensagem Naturalmente, mesmo que no possamos modificar os elementos de uma tupla, podemos substitu-la por de erro, mas ela no faz o que pretendemos. Este um exemplo de um erro semntico. uma tupla diferente:
>>> tupla = ('A',) + tupla[1:] >>> tupla ('A', 'b', 'c', 'd', 'e') Como exerccio, desenhe um diagrama de estado pra esta funo de modo que voc possa ver porque ela no funciona.

9.2 Atribuies de tupla

9.4 Nmeros aleatrios

A maioria dos programas de computador fazem a mesma coisa De vez em quando, necessrio trocar entre si os valores de sempre que so executados, ento, podemos dizer que eles so duas variveis. Com operaes de atribuio convencionais, determinsticos. Determinismo em geral uma coisa boa, se temos que utilizar uma varivel temporria. Por exemplo, para ns esperamos que um clculo d sempre o mesmo resultado.

Como pensar como um cientista da Computao usando Python Entretanto, para algumas aplicaes queremos que o aproximado de valores em cada um dos intervalos. computador se torne imprevisvel. Jogos so um exemplo Ns podemos testar esta teoria escrevendo um bvio, mas existem outros. programa que divida a faixa de valores em intervalos e conte o Fazer um programa realmente no- nmero de valores de cada intervalo. determinstico se mostra no ser to fcil, mas existem maneiras de faz-lo ao menos parecer no-determinstico. Uma dessas maneiras gerar nmeros aleatrios e us-los para 9.6 Contando determinar o resultado de um programa. Python tem uma funo nativa que gera nmeros pseudo aleatrios, os quais Uma boa maneira de abordar problemas como esse dividir o no so verdadeiramente aleatrios no sentido matemtico, problema em subproblemas, e encontrar um subproblema que mas para os nossos propsitos eles so. se enquadre em um padro de soluo computacional que voc O mdulo random contm uma funo chamada j tenha visto antes. random que retorna um nmero em ponto flutuante (floatingNeste caso, queremos percorrer uma lista de point number) entre 0.0 e 1.0. Cada vez que voc chama nmeros e contar o nmero de vezes que valor se encaixa em random, voc recebe o prximo nmero de uma longa srie. um determinado intervalo. Isso soa familiar. Na Seo 7.8, ns Para ver uma amostra, execute este loop: escrevemos um programa que percorria uma string e contava o nmero de vezes que uma determinada letra aparecia. import random Assim, podemos prosseguir copiando o programa original e adaptando-o para o problema atual. O for i in range(10): programa original era: x = random.random() contador = 0 print x Para gerar um nmero aleatrio ente 0.0 e um for letra in fruta: limite superior, digamos superior, multiplique x por superior. if letra == 'a': contador = contador + 1 Como exerccio, gere um nmero aleatrio entre 'inferior' e 'superior'. print contador O primeiro passo substituir fruta por lista e Como exerccio adicional, gere um nmero inteiro aleatrio entre 'inferior' e 'superior', inclusive os dois letra por numero. Isso no muda o programa, apenas o ajusta para que ele se torne mais fcil de ler e entender. extremos. O segundo passo mudar o teste. Ns no estamos interessados em procurar letras. Ns queremos ver se 9.5 Lista de nmeros aleatrios numero est entre inferior e superior.: O primeiro passo gerar uma lista aleatria de valores. contador = 0 listaAleatoria pega um parmetro inteiro e retorna uma lista de for numero in lista nmeros aleatrios com o comprimento dado. Inicia-se com if inferior < numero < superior: uma lista de n zeros. A cada iterao do loop, ele substitui um contador = contador + 1 dos elementos por um nmero aleatrio. O valor retornado print contador uma referncia para a lista completa: O ltimo passo encapsular este cdigo em uma def listaAleatoria(n): funo chamada noIntervalo. Os parmetros so a lista e os valores inferior e superior: s = [0] * n for i in range(n): def noIntervalo(lista, inferior, superior): s[i] = random.random() contador = 0 return s for numero in lista: Vamos realizar um teste desta funo com uma if inferior < numero < superior: lista de oito elementos. Para efeitos de depurao, uma boa contador = contador + 1 idia comear com uma lista pequena. return contador >>> listaAleatoria(8) Atravs da cpia e da modificao de um 0.15156642489 programa existente, estamos aptos a escrever esta funo rapidamente e economizar um bocado de tempo de depurao. 0.498048560109 Este plano de desenvolvimento chamado de casamento de 0.810894847068 padres. Se voc se encontrar trabalhando em um problema 0.360371157682 que voc j solucionou antes, reuse a soluo. 0.275119183077 0.328578797631 9.7 Vrios intervalos 0.759199803101 0.800367163582 Conforme o nmero de intervalos aumenta, noIntervalo tornaOs nmeros gerados por random so se intragvel. Com dois intervalos, no to ruim: supostamente uniformemente distribudos, o que significa que cada valor tem uma probabilidade igual de acontecer. inferior = noIntervalo(a, 0.0, 0.5) Se ns dividirmos a faixa de valores possveis superior = noIntervalo(a, 0.5, 1) Mas com quatro intervalos, comea a ficar em intervalos do mesmo tamanho, e contarmos o nmero de vezes que um determinado valor aleatrio caiu em seu desconfortvel.: respectivo intervalo, ns devemos obter o mesmo nmero GNU Free Documentation License #55

Como pensar como um cientista da Computao usando Python Como exerccio, teste esta funo com algumas = noIntervalo(a, 0.0, 0.25) listas longas, e veja se o nmero de valores em cada um dos = noIntervalo(a, 0.25, 0.5) intervalos tendem a uma distribuio nivelada. = noIntervalo(a, 0.5, 0.75) = noIntervalo(a, 0.75, 1.0) Existem aqui dois problemas. Um que temos 9.8 Uma soluo em um s passo que criar novos nomes de varivel para cada resultado. O outro que temos que calcular os limites de cada intervalo. Embora este programa funcione, ele no to eficiente quanto poderia ser. Toda vez que ele chama noIntervalo, ele percorre a Vamos resolver o segundo problema primeiro. lista inteira. Conforme o nmero de intervalos aumenta, a lista Se o nmero de intervalos numeroDeIntervalos, ento a ser percorrida um bocado de vezes. largura de cada intervalo 1.0 / numeroDeIntervalos. Seria melhor fazer uma nica passagem pela Vamos usar um lao (loop) para calcular a faixa, lista e calcular para cada valor o ndice do intervalo ao qual o ou largura, de cada intervalo. A varivel do loop, i, conta de 0 valor pertena. Ento podemos incrementar o contador at numeroDeIntervalos-1: apropriado. larguraDoIntervalo = 1.0 / numeroDeIntervalos Na seo anterior, pegamos um ndice, i, e o for i in range(numeroDeIntervalos): multiplicamos pela larguraDoIntervalo para encontrar o limite inferior daquele intervalo. Agora queremos pegar um valor inferior = i * larguraDoIntervalo entre 0.0 e 1.0 e encontrar o ndice do intervalo ao qual ele se superior = inferior + larguraDoIntervalo encaixa. print "do" inferior, "ao", superior J que este problema o inverso do problema Para calcular o limite inferior (inferior) de cada intervalo, ns multiplicamos a varivel do loop (i) pela largura anterior, podemos imaginar que deveramos dividir por do intervalo (larguraDoIntervalo). O limite superior (superior) larguraDoIntervalo em vez de multiplicar. Esta suposio est correta. est exatamente uma "largura de intervalo" acima. intervalo1 intervalo2 intervalo3 intervalo4 Com numeroDeIntervalos = 8, o resultado : 0.0 to 0.125 0.125 to 0.25 0.25 to 0.375 0.375 to 0.5 0.5 to 0.625 0.625 to 0.75 numeroDeIntervalos = 8 0.75 to 0.875 intervalos = [0] * numeroDeIntervalos 0.875 to 1.0 for i in lista: Voc pode confirmar que cada intervalo tem a indice = int(i * numeroDeIntervalos) mesma largura, que eles no se sobrepe, e que eles cobrem intervalos[indice] = intervalos[indice] + 1 toda a faixa de valores de 0.0 a 1.0. Usamos a funo int para converter um nmero Agora, de volta ao primeiro problema. Ns em ponto flutuante (float) para um inteiro. precisamos de uma maneira de guardar oito inteiros, usando a Existe a possibilidade deste clculo produzir um vriavel do loop para indicar cada um destes inteiros. Voc ndice que esteja fora dos limites (seja negativo ou maior que deve estar pensando, "Lista!" len(intervalos)-1)? Ns temos que criar a lista de intervalos fora do Uma lista como intervalos que contm uma loop, porque queremos fazer isto apenas uma vez. Dentro do loop, ns vamos chamar noIntervalo repetidamente e atualizar contagem do nmero de valores em cada intervalo chamada de histograma. o i-simo elemento da lista: J que larguraDoIntervalo = 1.0 / numeroDeIntervalos, dividir por larguraDoIntervalo o mesmo que multiplicar por numeroDeIntervalos. Se multiplicarmos um nmero na faixa entre 0.0 e 1.0 por numeroDeIntervalos, obtemos um nmero na faixa entre 0.0 e numeroDeIntervalos. Se arredondarmos este nmero para baixo, ou seja, para o menor inteiro mais prximo, obtemos exatamente o que estamos procurando - o ndice do intervalo:

Como exerccio, escreva uma funo chamada numeroDeIntervalos = 8 ``histograma`` que receba uma lista e um nmero de intervalos intervalos = [0] * numeroDeIntervalos como argumentos e retorne um histograma com o nmero de larguraDoIntervalo = 1.0 / numeroDeIntervalos intervalos solicitado. for i in range(numeroDeIntervalos): inferior = i * larguraDoIntervalo 9.9 Glossrio superior = inferior + larguraDoIntervalo intervalos[i] = noIntervalo(lista, inferior, tipo imutvel Um tipo de elemento que no pode ser superior) (immutable modificado. Atribuies a um elemento ou print intervalos type) "fatiamento (slices)" XXX aos tipos Com uma lista de 1000 valores, este cdigo vai imutveis causaro erro. produzir esta lista de quantidades de valores em cada tipo mutvel Tipo de dados onde os elementos podem ser intervalo: (mutable type) modificados. Todos os tipos mutveis, so tipos compostos. Listas e dicionrios so [138, 124, 128, 118, 130, 117, 114, 131] exemplos de tipos de dados mutveis. Esses nmeros esto razoavelmente pximos de String e tuplas no so. 125, o que era o que espervamos. Pelo menos eles esto prximos o bastante para nos fazer acreditar que o gerador de tupla (tuple) Tipo sequencial similar as listas com nmero aleatrios est funcionando. GNU Free Documentation License #56

Como pensar como um cientista da Computao usando Python exceo de que ele imutvel. Podem ser usadas Tuplas sempre que um tipo imutvel for necessrio, por exemplo uma "chave (key)" em um dicionrio Atribuio a Atribuio a todos os elementos de uma tupla (tuple tupla feita num nico comando de assignment) atribuo. A atribuio aos elementos ocorre em paralelo, e no em sequncia, tornando esta operao til para swap, ou troca recproca de valores entre variveis (ex: a,b=b,a). determinstico Um programa que realiza a mesma coisa (deterministic) sempre que executado. pseudo aleatrio (pseudorandom ) Uma sequncia de nmeros que parecem ser aleatrios mas so na verdade o resultado de uma computao "determinstica"

histograma Uma lista de inteiros na qual cada elemento (histogram) conta o nmero de vezes que algo acontece.

GNU Free Documentation License #57

Captulo 10: Dicionrios

Os tipos compostos que voce aprendeu - strings, listas e tuplas 'bananas': 312} - utilizam inteiros como indices. Se voce tentar utilizar Se alguem comprar todas as peras, podemos qualquer outro tipo como indice, voce receber um erro. remover a entrada do dicionrio: Dicionrios sao similiares a outros tipos >>> del inventario['peras'] compostos exceto por eles poderem user qualquer tipo imutavel de dados como indice. Como exemplo, nos criaremos >>> print inventario um dicionrio para traduzir palavras em Ingls para Espanhol. {'laranjas': 525, 'abacaxis': 430, 'bananas': 312} Para esse dicionrio, os indices sero strings. Ou se ns esperamos por mais peras em breve, nos podemos simplesmente trocar o valor associoado as peras: Uma maneira de criar um dicionario comecando com um dicionrio vazio e depois adiconando >>> inventario['peras'] = 0 elementos. Um dicionrio vazio denotado assim {}: >>> print inventario >>> ing2esp = {} {'laranjas': 525, 'abacaxis': 430, 'peras': 0, \ >>> ing2esp['one'] = 'uno' 'bananas': 312} A funo len tambm funciona com dicionrios; >>> ing2esp['two'] = 'dos' A primeira atribuio cria um dicionario retornando o nmero de pares chave-valor: chamado ing2esp; as outras atribuies adicionam novos elementos para o dicionrio. Nos podemos imprimir o valor >>> len(inventario) 4 corrente de um dicionario da maneira usual: >>> print ing2esp {'one': 'uno', 'two': 'dos'} Os elementos de um dicionrio aparecem em uma lista separada por vrgulas. Cada entrada contm um indice e um valor separado por dois-pontos. Em um dicionrio, os ndices sao chamados de chaves, entao os elementos so chamados de pares chave-valor.

10.2 Mtodos dos Dicionrios

Um mtodo parecido com uma funo - possui parametros e retorna valores - mas a sintaxe diferente. Por exemplo, o metodo keys recebe um dicionrio e retorna uma lista com as chaves, mas em vez de usarmos a sintaxe de funo keys(ing2esp), nos usamos a sintaxe de mtodo Outra maneira de criar dicionrios fornecendo ing2esp.keys(): uma lista de pares chaves-valor utilizando a mesma sintaxe da ltima sada. >>> ing2esp.keys() ['one', 'three', 'two'] >>> ing2esp = {'one': 'uno', 'two': 'dos', \ Dessa forma o ponto especifica o nome da 'three': 'tres'} funo, keys, e o nome do objeto em que deve ser aplicada a Se nos imprimirmos o valor de ing2esp funo, ing2esp. Os parenteses indicam que esse mtodo no novamente, nos teremos uma surpresa: possui parameteros. >>> print ing2esp Ao invs de chamarmos um mtodo, dizemos que ele invocado, nesse caso, ns podemos dizer que ns {'one': 'uno', 'three': 'tres', 'two': 'dos'} Os pares chave-valor no esto em ordem! estamos invocando keys do objeto ing2esp. Felizmente, no a motivos para se preocupar com a ordem, O mtodo values parecido; retorna a lista de desde que os elementos do dicionrio nunca sejam indexados valores de um dicionrio: com indices inteiros. Podemos usar as chaves para buscar os valores correspondentes: >>> ing2esp.values() ['uno', 'tres', 'dos'] >>> print ing2esp['two'] O mtodo items retorna os dois, na forma de 'dos' uma lista de tuplas - cada tupla com um par chave-valor: A chave 'two' retornou o valor 'dos' mesmo pensando que retornaria o terceiro par chave-valor. >>> ing2esp.items() [('one','uno'), ('three','tres'), ('two','dos')] A sintaxe fornece uma informao util. Os 10.1 Operaes dos Dicionrios colchetes indicam que isso uma lista. Os parentses indicam que os elementos da lista so tuplas. O comando del remove um par chave-valor de um dicionrio. Se o mtodo recebe de algum parmetro, se Por exemplo, o dicionrio abaixo contem os nomes de varias utiliza a mesma sintaxe das funes. Por exemplo, o mtodo frutas e o numero de cada fruta em no estoque: has_key recebe uma chave e retorna verdadeiro (1) se a chave >>> inventario = {'abacaxis': 430, 'bananas': 312, existe no dicionrio: \ >>> ing2esp.has_key('one') 'laranjas': 525, 'peras': 217} True >>> print inventario >>> ing2esp.has_key('deux') {'laranjas': 525, 'abacaxis': 430, 'peras': 217, \ False

Como pensar como um cientista da Computao usando Python Se voce tentar chamar um mtodo sem Ns precisamos apenas de trs pares chaveespecificar em qual objeto, voce obter um erro. Nesse caso, a valor, cada um sendo um elemento diferente de zero da matriz. mensagem de erro no muito til: Cada chave uma tupla, e cada valor um nmero inteiro. >>> has_key('one') NameError: has_key Para acessarmos um elemento da matriz, nos utilizamos o operador []:

>>> matriz[0,3] 1 10.3 Aliasing (XXX) e Copiar Note que a sintaxe da representao de um dicionrio no a mesma que a sintaxe usada pela Uma vez que os dicionrios so mutveis, voce precisa saber representao pelas listas. Em vez de usarmos dois ndices sobre Aliasing. Sempre que duas variveis referenciarem o inteiros, ns usamos apenas um ndice, que uma tupla de mesmo objeto, quando uma alterada, afeta a outra. inteiros. Se voc quer modificar um dicionrio e Mas existe um problema. Se tentarmos buscar continuar com uma copia original, utilize o mtodo copy. Por um elemento zero, obteremos um erro, pois no existe uma exemplo, opposites um dicionrio que contm pares de entrada no dicionrio para a chave especificada: antnimos: >>> matriz[1,3] >>> opposites = {'up': 'down', 'right': 'wrong', \ KeyError: (1,3) 'true': 'false'} O mtodo get resolve esse problema: >>> alias = opposities >>> matriz.get((0,3), 0) >>> copy = opposities.copy() alias e opposites se referem ao mesmo objeto; 1 copy se refere a um novo objeto igual ao dicionrio opposites. O primeiro parmetro a chave; o segundo o Se voc modificar o alias, opposites tambm ser alterado. valor que get retornar caso no existe a chave no dicionrio: >>> alias['right'] = 'left' >>> matriz.get((1,3), 0) >>> opossites['right'] 0 get definitivamente melhora a semntica e a 'left' Se modificarmos copy, opposites no ser sintaxe do acesso a matrizes esparsas. modificado: >>> copy['right'] = 'privilege' >>> opposites['right'] 'left'

10.5 Hint

Se voc brincou com a funo fibonacci da seo 5.7, provvel que voc notou que quanto maior o nmero passado para a funo, mais tempo a funo demora para executar. Alm disso, o tempo da execuo aumenta rapidamente. Em 10.4 Matrizes Esparsas uma das nossas mquinas, fibonacci(20) executa instantaneamente, fibonacci(30) demora cerca de um segundo, Na seo 8.14, ns usamos uma lista de listas para representar e fibonacci(40) demora uma eternidade. uma matriz. Essa uma boa escolha se a matriz for Para entender o porque, considere o grfico de principalmente de valores diferentes de zero, mas chamadas para fibonacci com n=4: considerando uma matriz esparsa como essa:

Uma representao usando uma lista contem muitos zeros: >>> matriz = [ [0,0,0,1,0], [0,0,0,0,0], [0,2,0,0,0], [0,0,0,0,0], [0,0,0,3,0] ] Uma alternativa usarmos um dicionrio. Para O grfico mostra a estrutura da funo, com as chaves, ns podemos usar tuplas que contm os nmeros da linhas conectando cada execuo com a execuo que a linha e a coluna. Abaixo uma representao em um dicinario chamou. No topo do grfico, fibonacci tem n=4, que chama da mesma matriz: fibonacci com n=3 e n=2. Em seguida, fibonacci com n=3 chama fibonacci com n=2 e n=1. E assim por diante. >>> matriz = {(0,3): 1, (2, 1): 2, (4, 3): 3} GNU Free Documentation License #59

Como pensar como um cientista da Computao usando Python Conte quantas vezes fibonacci(0) e fibonacci(1) 57L so chamadas. Essa uma soluo ineficiente para o Todas as operaes matemticas funcionam com problema, e torna-se pior quando o parmetro recebido um long int s, ento no precisamos modificar muito para adaptar nmero maior. fibonacci: Uma boa soluo guardar os valores que j >>> previous = {0: 1L, 1:1L} foram calculados armazenando-os em um dicionrio. Um valor previamente calculado que guardado para ser utilizado >>> fibonacci(50) mais tarde chamado de hint. Abaixo uma implementao de 20365011074L fibonacci usando hints: Somente trocando os valores iniciais de previous, conseguimos mudar o comportamento da fibonacci. >>> previous = {0:1, 1:1} Os dois primeiros numeros da sequncia so long ints, ento >>> def fibonacci(n): todos os nmeros subsequentes da sequncia tambm sero. if previous.has_key(n): Como exerccio, converta fatorial para produzir return previous[n] um inteiro longo como resultado. else: newValue = fibonacci(n-1) + \ 10.7 Contando Letras fibonacci(n-2) previous[n] = newValue No captulo 7, escrevemos uma funo que contava o nmero de ocorrncias de uma letra em uma string. A verso mais return newValue O dicionrio chamado previous guarda os comum desse problema fazer um histograma das letras da nmeros de Fibonacci que ns ja conhecemos. Ele comea string, ou seja, quantas vezes cada letra aparece na string. com apenas dois pares: 0 possui 1; e 1 possui 1. Um histograma pode ser util para comprimir um Sempre que fibonacci chamada, ela verifica o arquivo de texto. Pois diferentes letras aparecem com dicionrio para determinar se ele j possui o resultado. Se o diferentes frequncias, podemos comprimir um arquivo resultado estiver ali, a funo pode retornar imediatamente usando pequenos cdigos para letras comuns e longos cdigos sempre precisar fazer mais chamadas recursivas. Se o para letras que aparecem em menor frequncia. resultado no estiver ali, ele calculado no newValue. O valor Dicionrios fornecem uma maneira elegante de de newValue adicionado no dicionrio antes da funo gerar um histograma: retornar. Usando essa verso de fibonacci, nossa >>> letterCounts = {} mquina consegue calcular fibonacci(40) em um piscar de >>> for letter in "Mississippi": olhos. Mas quando tentamos calcular fibonacci(50), ns ... letterCounts[letter] = veremos um problema diferente: letterCounts.get(letter,0) + 1 ... >>> fibonacci(50) >>> letterCounts OverflowError: integer addition A resposta, que voc ver em um minuto, {'M': 1, 's': 4, 'p': 2, 'i': 4} 20.365.011.074. O problema que esse nmero muito Comeamos com um dicionrio vazio. Para cada grande para guardarmos como um inteiro do Python 1. Isso letra da string, achamos o contador (possivelmente zero) e o overflow. Felizmente, esse problema tem uma soluo incrementamos. No final, o dicionrio contem pares de letras e simples. as suas frequncias.

10.6 Inteiros Longos

mais atraente mostrarmos o histograma na ordem alfabtica. Podemos fazer isso com os mtodos items e sort:

Python possui um tipo chamado long int que permite >>> letterItems = letterCounts.items() trabalharmos com qualquer tamanho de inteiros. Existem duas maneiras de criarmos um valor long int. A primeira escrever >>> letterItems.sort() >>> print letterItems um inteiro seguido de um L no final: [('M', 1), ('i', 4), ('p', 2), ('s', 4)] >>> type(1L) Voc ja tinha visto o mtodo items antes, mas <type 'long int'> sort o primeiro mtodo que voc se depara para aplicar em A outra maneira usarmos a funo long que listas. Existem muitos outros mtodos de listas, incluindo converte um valor para um long int. long pode receber append, extend, e reverse. Consulte a documentao do qualquer valor nmerico e at mesmo uma string de digitos: Python para maiores detalhes. >>> long(1) 1L >>> long(3.9) 3L >>> long('57')

10.8 Glossrio
dicionrio Uma coleo de pares de chaves-valores (dictionary) que so mapeados pelas chaves, para se obter os valores. As chaves podem ser qualquer tipo de dados imutavel, e os valores podem ser de qualquer tipo. chave (key) Um valor que usado para buscar uma entrada em um dicionrio.

N.T. A partir do Python 2. XXX este erro no ocorre mais, pois em caso de sobrecarga o valor inteiro automaticamente promovido para o tipo long.

GNU Free Documentation License #60

Como pensar como um cientista da Computao usando Python par chave-valor Um dos itens de um dicionrio. hint O armazenamento temporrio de um valor pr-computado para evitar a computao (key-value pair) redundante. mtodo (method) Um tipo de funo que chamada com uma sintaxe diferente e invocada no overflow Um resultado numrico que muito contexto de um objeto. grande para ser representado no formato numrico. invocar (invoke) Chamar um mtodo.

GNU Free Documentation License #61

Captulo 11: Arquivos e excees

Se tentarmos abrir um arquivo que no existe, temos um erro:

Arquivos e excees
Durante a execuo de um programa, seus dados ficam na memria. Quando o programa termina, ou o computador desligado, os dados na memria desaparecem. Para armazenar os dados permanentemente, voc tem que coloc-los em um arquivo. Arquivos usualmente so guardados em um disco rgido (HD), num disquete ou em um CD-ROM.

>>> f = open("teste.cat", "r") IOError: [Errno 2] No such file or directory: \ 'teste.cat' Sem nenhuma surpresa, o mtodo read l dados do arquivo. Sem argumentos, ele l todo o contedo do arquivo:

>>> texto = f.read() Quando existe um nmero muito grande de arquivos, eles muitas vezes so organizados dentro de >>> print texto diretrios (tambm chamados de ?pastas? ou ainda Agora horade fechar o arquivo ?*folders*?). Cada arquivo identificado por um nome nico, No existe espao entre ?hora? e ?de? porque ou uma combinao de um nome de arquivo com um nome de ns no gravamos um espao entre as strings. diretrio. read tambm pode receber um argumento que Lendo e escrevendo em arquivos, os programas indica quantos caracteres ler: podem trocar informaes uns com os outros e gerar formatos >>> f = open("teste.dat", "r") imprimveis como PDF. >>> print f.read(9) Trabalhar com arquivos muito parecido com trabalhar com livros. Para utilizar um livro, voc tem que abr- Agora h Se no houver caracteres suficientes no arquivo, lo. Quando voc termina, voc tem que fech-lo. Enquanto o livro estiver aberto, voc pode tanto l-lo quanto escrever nele. read retorna os caracteres restantes. Quando chegamos ao final Em qualquer caso, voc sabe onde voc est situado no livro. do arquivo, read retorna a string vazia: Na maioria das vezes, voc l o livro inteiro em sua ordem natural, mas voc tambm pode saltar atravs de alguns >>> print f.read(1000006) orade fechar o arquivo trechos (skip around). Tudo isso se aplica do mesmo modo a arquivos. >>> print f.read() Para abrir um arquivo, voc especifica o nome dele e indica o que voc quer, seja ler ou escrever (gravar). >>> A funo seguinte, copia um arquivo, lendo e Abrir um arquivo cria um objeto arquivo. Neste gravando at cinqenta caracteres de uma vez. O primeiro exemplo, a varivel f se referencia ao novo objeto arquivo. argumento o nome do arquivo original; o segundo o nome do novo arquivo: >>> f = open("teste.dat", "w") >>> print f def copiaArquivo(velhoArquivo, novoArquivo): <open file "teste.dat", mode "w" at fe820> f1 = open(velhoArquivo, "r") A funo open recebe dois argumentos. O f2 = open(novoArquivo, "w") primeiro o nome do arquivo, e o segundo o modo. Modo while 1: ?w? significa que estamos abrindo o arquivo para gravao (?*write*?, escrever). texto = f1.read(50) if texto == "": Se no existir nenhum arquivo de nome teste.dat, ele ser criado. Se j existir um, ele ser substitudo break pelo arquivo que estamos gravando (ou escrevendo). f2.write(texto) f1.close() Quando executamos um comando print sobre o objeto arquivo, visualizamos o nome do arquivo, o modo e a f2.close() localizao do objeto na memria. return Para colocar dados dentro do arquivo, A comando break novo. O que ele faz saltar invocamos o mtodo write do objeto arquivo: a execuo para fora do loop; o fluxo de execuo passa para o primeiro comando depois do loop. >>> f.write("Agora hora") Neste exemplo, o loop while infinito porque o >>> f.write("de fechar o arquivo") valor 1 sempre verdadeiro. O nico modo de sair do loop Fechar o arquivo diz ao sistema que terminamos executando o break, o que ocorre quando texto a string de escrever (gravar) e que o arquivo est livre para ser lido: vazia, o que ocorre quando alcanamos o fim do arquivo. >>> f.close() Agora podemos abrir o arquivo de novo, desta vez para leitura, e ler o seu contedo para uma string. Desta vez, o argumento modo ?r? para leitura (?reading?): >>> f = open("teste.dat", "r")

11.1 Arquivos texto


Um arquivo texto um arquivo que contm caracteres imprimveis e espaos, organizados dentro de linhas separadas

Como pensar como um cientista da Computao usando Python por caracteres de nova linha. J que Pyhton especialmente quisermos colocar outros valores em um arquivo, temos de projetado para processar arquivos texto, ele oferece mtodos convert-los para strings primeiro. A maneira mais fcil de que tornam esta tarefa mais fcil. fazer isso com a funo str: Para demonstrar, vamos criar um arquivo texto >>> x = 52 com trs linhas de texto separadas por caracteres de nova >>> f.write(str(x)) linha: Uma alternativa usar o operador de formatao %. Quando aplicado a inteiros, % o operador >>> f = open("teste.dat", "w") >>> f.write("linha um\nlinha dois\nlinha trs\n") mdulo. Mas quando o primeiro operador uma string, % o operador de formatao. >>> f.close() O primeiro operando a string de formatao, O mtodo readline l todos os caracteres at, e e o segundo operando uma tupla de expresses. O resultado incluindo, o prximo caractere de nova linha: uma string que contm os valores das expresses, formatadas >>> f = open("teste.dat", "r") de acordo com a string de formatao. >>> print f.readline() Num exemplo simples, a seqncia de linha um formatao "??%d??" significa que a primeira expresso na tupla deve ser formatada como um inteiro. Aqui a letra d representa ?decimal?. >>> readlines retorna todas as linhas restantes como >>> carros = 52 uma lista de strings: >>> "%d" % carros '52' >>> print f.readlines() O resultado a string ?52?, que no deve ser ['linha dois\012', 'linha trs\012'] confundida com o valor inteiro 52. Neste caso, a sada est em formado de lista, o que significa que as strings aparecem entre aspas e o caractere Uma seqncia de formatao pode aparecer em de nova linha aparece como a seqncia de escape 012. qualquer lugar na string de formatao, assim, podemos No fim do arquivo, readline retorna a string embutir um valor em uma seqncia: vazia e readlines retorna a lista vazia: >>> carros = 52 >>> "Em julho vendemos %d carros." % carros >>> print f.readline() 'Em julho vendemos 52 carros.' A seqncia de formatao "%f" formata o >>> print f.readlines() prximo item da tupla como um nmero em ponto flutuante, e [] "%s" formata o prximo como uma string: A seguir temos um exemplo de um programa de processamento de linhas. filtraArquivo faz uma cpia de >>> "Em %d dias fizemos %f milhes %s." % \ velhoArquivo, omitindo quaisquer linhas que comecem por #: (34,6.1,'reais') 'Em 34 dias fizemos 6.100000 milhes de reais.' def filtraArquivo(velhoArquivo, novoArquivo): Por padro, o formato de ponto flutuante exibe f1 = open(velhoArquivo, "r") seis casas decimais. f2 = open(novoArquivo, "w") O nmero de expresses na tupla tem que ser while 1: igual ao nmero de seqncias de formatao na string. Alm texto = f1.readline() disso, os tipos das expresses tm que iguais aos da seqncia if texto == "": de formatao: break >>> "%d %d %d" % (1,2) if texto[0] == '#': TypeError: not enough arguments for format string continue >>> "%d" % 'reais' f2.write(texto) TypeError: illegal argument type for built-in \ f1.close() operation f2.close() No primeiro exemplo, no existem expresses return suficientes; no segundo, a expresso do tipo errado. O comando continue termina a iterao corrente Para um controle maior na formatao de do loop, mas continua iterando o loop. O fluxo de execuo passa para o topo do loop, checa a condio e prossegue nmeros, podemos especificar o nmero de dgitos como parte da seqncia de formatao: conforme o caso. >>> "%6d" % 62 ' 62' >>> "%12f" % 6.1 ' 6,100000' O nmero depois do sinal de porcentagem o nmero mnimo de espaos que o valor ocupar. Se o valor fornecido tiver um nmero menor de dgitos, espaos em 11.2 Gravando variveis branco sero adicionados antes para preencher o restante. Se o O argumento de write tem que ser uma string, assim se nmero de espaos for negativo, os espaos sero adicionados depois: Assim, se texto for a string vazia, o loop termina. Se o primeiro caractere de texto for o jogo da velha (? # ?), o fluxo de execuo passa para o topo do loop. Somente se ambas as condies falharem que texto ser copiado para dentro do novo arquivo. GNU Free Documentation License #63

Como pensar como um cientista da Computao usando Python >>> "%-6d" % 62 11.4 Pickling '62 ' Para nmeros em ponto-flutuante, tambm Para colocar valores em um arquivo, voc tem que convertlos para strings. Voc j viu como fazer isto com str: podemos especificar o nmero de dgitos depois da vrgula: >>> "%12.2f" % 6.1 ' 6.10' Neste exemplo, o resultado reserva 12 espaos e inclui dois dgitos depois da vrgula. Esta formatao til para exibir valores monetrios com os centavos alinhados. >>> f.write (str(12.3)) >>> f.write (str([1,2,3])) O problema que quando voc l de volta o valor, voc tem uma string. O Tipo original da informao foi perdido. De fato, voc no pode sequer dizer onde comea um valor e termina outro:

Por exemplo, imagine um dicionrio que contm nomes de estudantes como chaves e salrios-hora como >>> f.readline() valores. Aqui est uma funo que imprime o contedo do ?12.3[1, 2, 3]? dicionrio como um relatrio formatado: A soluo o pickling, assim chamado porque ?preserva? estruturas de dados. O mdulo pickel contm os def relatorio(salarios): comandos necessrios. Para us-lo, importe pickle e ento abra estudantes = salarios.keys() o arquivo da maneira usual: estudantes.sort() >>> import pickle for estudante in estudantes: >>> f = open(?test.pck?, ?w?) print "%-20s %12.02f" % (estudante, \ Para armazenar uma estrutura de dados, use o salarios[estudante]) mtodo dump e ento feche o arquivo do modo usual: Para testar esta funo, criaremos um pequeno dicionrio e imprimiremos o contedo: >>> pickle.dump(12.3, f) >>> pickle.dump([1,2,3], f) >>> salarios = {'maria': 6.23, 'joo': 5.45, \ >>> f.close() 'josu': 4.25} Ento, podemos abrir o arquivo para leitura e >>> relatorio(salarios) carregar as estruturas de dados que foram descarregadas joo 5.45 (dumped): josu 4.25 >>> f = open(?test.pck?, ?r?) maria 6.23 Controlando a largura de cada valor, podemos >>> x = pickle.load(f) garantir que as colunas ficaro alinhadas, desde que os nomes >>> x contenham menos que vinte e um caracteres e os salrios 12,3 sejam menores do que um bilho de reais por hora. >>> type(x) <type ?float?> >>> y = pickle.load(f) 11.3 Diretrios >>> y Quando voc cria um novo arquivo abrindo-o e escrevendo [1, 2, 3] nele, o novo arquivo fica no diretrio corrente (seja l onde for que voc esteja quando rodar o programa). Do mesmo modo, >>> type(y) quando voc abre um arquivo para leitura, Python procura por <type ?list?> Cada vez que invocamos load, obtemos um ele no diretrio corrente. nico valor do arquivo, completo com seu tipo original. Se voc quiser abrir um arquivo que esteja em algum outro lugar, voc tem que especificar o caminho (path) para o arquivo, o qual o nome do diretrio (ou folder) onde o 11.5 Excees arquivo est localizado: >>> f = open("/usr/share/dict/words", "r") >>> print f.readline() Aarhus Este exemplo abre um arquivo chamado words que reside em um diretrio de nome dict, o qual reside em share, o qual reside em usr, o qual reside no diretrio de mais alto nvel do sistema, chamado /.

Whenever que um erro em tempo de execuo acontece, ele gera uma exceo. Usualmente, o programa pra e Python exibe uma mensagem de erro. Por exemplo, dividir por zero gera uma exceo:

>>> print 55/0 ZeroDivisionError: integer division or modulo Do mesmo modo, acessar um item de lista Voc no pode usar / como parte do nome de um inexistente: arquivo; ela um caractere reservado como um delimitador entre nomes de diretrios e nomes de arquivos. >>> a = [] O arquivo /usr/share/dict/words contm uma >>> print a[5] lista de palavras em ordem alfabtica, na qual a primeira IndexError: list index out of range palavra o nome de uma universidade Dinamarquesa. Ou acessar uma chave que no est em um dicionrio: >>> b = {} >>> print b[?what?] GNU Free Documentation License #64

Como pensar como um cientista da Computao usando Python KeyError: what def entraNumero(): Em cada caso, a mensagem de erro tem duas x = input (?Escolha um nmero: ?) partes: o tipo do erro antes dos dois pontos, e especificidades if x == 17: do erro depois dos dois pontos. Normalmente Python tambm raise ?ErroNumeroRuim?, ?17 um nmero ruim? exibe um ?*traceback*? de onde estava a execuo do return x programa, mas ns temos omitido esta parte nos exemplos. O comando raise toma dois argumentos: o tipo s vezes queremos executar uma operao que da exceo e informaes especficas sobre o erro. pode causar uma exceo, mas no queremos que o programa ErroNumeroRuim um novo tipo de exceo que ns pare. Ns podemos tratar a exceo usando as instrues try e inventamos para esta aplicao. except. Se a funo que chamou entraNumero trata o Por exemplo, podemos pedir ao usurio um erro, ento o programa pode continuar; de outro modo, Pyhton nome de arquivo e ento tentar abr-lo. Se o arquivo no exibe uma mensagem de erro e sai: existe, no queremos que o programa trave; queremos tratar a exceo: >>> entraNumero() Escolha um nmero: 17 nomedoarquivo = raw_input(?Entre com o nome do \ ErroNumeroRuim: 17 um nmero ruim arquivo: ?) A mensagem de erro inclui o tipo da exceo e a try: informao adicional que voc forneceu. f = open (nomedoarquivo, ?r?) Como um exerccio, escreva uma funo que except: use entraNumero para pegar um nmero do teclado e que trate print ?No existe arquivo chamado?, a exceo ErroNumeroRuim. nomedoarquivo A instruo try executa os comandos do primeiro bloco. Se no ocorrerem excees, ele ignora a 11.6 Glossrio instruo except. Se qualquer exceo acontece, ele executa os comandos do ramo except e continua. arquivo (file) Uma entidade nomeada, usualmente armazenada em um disco rgido (HD), Podemos encapsular esta habilidade numa disquete ou CD-ROM, que contm uma funo: existe toma um nome de arquivo e retorna verdadeiro seqncia de caracteres. se o arquivo existe e falso se no existe: def existe(nomedoarquivo) try: f = open(nomedoarquivo) f.close() return 1 except: return 0 Voc pode usar mltiplos blocos except para tratar diferentes tipos de excees. O Manual de Referncia de Python (Python Reference Manual) tem os detalhes. Se o seu programa detecta uma condio de erro, voc pode faz-lo lanar uma exceo. Aqui est um exemplo que toma uma entrada do usurio e testa se o valor 17. Supondo que 17 no seja uma entrada vlida por uma razo qualquer, ns lanamos uma exceo. diretrio Uma coleo nomeada de arquivos, (directory) tambm chamado de pasta ou folder. caminho (path) Uma seqncia de nomes de diretrios que especifica a exata localizao de um arquivo. arquivo texto Um arquivo que contm caracteres (text file) organizados em linhas separadas por caracteres de nova linha. comando break Um comando que fora a atual iterao de (break um loop a terminar. O fluxo de execuo statement) vai para o topo do loop, testa a condio e prossegue conforme o caso.

GNU Free Documentation License #65

Captulo 12: Classes e objetos

>>> final.x = 3.0 >>> final.y = 4.0 12.1 Tipos compostos definidos pelo usurio Esta sintaxe similar sintaxe para acessar uma varivel de um mdulo, como math.pi ou string.uppercase. Depois de usarmos alguns tipos nativos do Python, estamos Neste caso, porm, estamos acessando um item de dado de prontos para criar um tipo de dados: o Ponto. uma instncia. Estes itens so chamados atributos. Considere o conceito matemtico de um ponto. O seguinte diagrama de estado mostra o Em duas dimenses, um ponto um par de nmeros resultado destas atribuies: (coordenadas) que so tratadas coletivamente como um objeto simples. Na notao matemtica, pontos so freqentemente escritos entre parnteses com vrgula separando as coordenadas. Por exemplo, (0, 0) representa a origem, e (x, y) representa o ponto x unidades direita, e y unidades acima da origem. Uma maneira natural para representar um ponto em Python, com dois valores numricos em ponto flutuante. A varivel final refere a um objeto Ponto, que A questo, ento, como agrupar estes dois valores em um contm dois atributos. Cada atributo faz referncia a um objeto composto. A maneira rpida e rasteira usar uma lista nmero em ponto flutuante. ou uma tupla, e para algumas aplicaes, esso pode ser a 1 melhor escolha . Podemos ler o valor de um atributo usando a mesma sintaxe: Uma alternativa definir um novo tipo composto, tambm chamado uma classe. Esta abordagem >>> print final.y envolve um pouco mais de esforo, mas ela tem vantagens que 4.0 logo ficaro evidentes. >>> x = final.x Eis a definio de uma classe: >>> print x 3.0 class Ponto: A expresso final.x significa, "V ao objeto final pass Definies de classes podem aparecer em e pegue o valor de x". Neste caso, atribumos este valor a uma qualquer parte de um programa, mas elas costuma ficar varivel cujo nome 'x'. No h conflito entre a varivel x e o prximas do comeo do programa (aps os comandos import). atributo x. O propsito da notao objeto.atributo identificar As regras de sintaxe para a definio de classes so as mesmas a qual varivel voc est fazendo referncia de forma que no ambguo. de outros comandos compostos (veja Seo 4.4). Voc pode usar a notao objeto.atributo como A definio acima cria uma nova classe parte de qualquer expresso; assim os seguintes comandos so chamada Ponto. O comando pass no tem nenhum efeito; aqui ele necessrio porque um comando composto precisa ter vlidos: algo no seu corpo. print '(' + str(final.x) + ', ' + str(final.y) + Quando criamos a classe Ponto, criamos um ')' novo tipo de dado, tambm chamado Ponto. Os membros distAoQuadrado = final.x * final.x + final.y * \ deste novo tipo so chamados instncias deste tipo ou objetos. Criar uma nova instncia instanciar. Para instanciar final.y A primeira linha imprime (3.0, 4.0); a segunda o objeto Ponto, invocamos a funo (adivinhou?) Ponto: linha calcula o valor 25.0. final = Ponto() tentador imprimir o valor do prprio objeto A varivel final agora contm uma referncia a final: um novo objeto da classe Ponto. Uma funo como Ponto, que cria novos objetos, chamada construtor. >>> print final <__main__.Ponto instance at 80f8e70> O resultado indica que final uma instncia da 12.2 Atributos classe Ponto e foi definida no prgrama principal: __main__. 80f8e70 o identificador nico deste objeto, escrito em Podemos adicionar novos dados em uma instncia usando a hexadecimal (base 16). Esta no provavelmente a forma notao de ponto (dot notation): mais informativa para mostrar um objeto Ponto. Logo voc ir ver como mudar isso.
1

N.T.: A linguagem Python tambm incorpora um tipo nativo complex que representa nmeros complexos. Uma instncia de complex, como a=3+5j possui dois valores de ponto flutuante em seus atributos a.real e a.imag, e pode ser utilizada para armazenar pontos em um espao bi-dimensional.

Como exerccio, crie e imprima um objeto Ponto, e ento use id para imprimir o identificador nico do objeto. Traduza a forma hexadecimal para a forma decimal e confirme se so compatveis.

12.3 Instncias como parmetros

Como pensar como um cientista da Computao usando Python do mesmo objeto.

>>> p2 = p1 Voc pode passar uma instncia como um parmetro da forma >>> p1 == p2 usual. Por exemplo: True def mostrarPonto(p): Este tipo de igualdade chamado de igualdade rasa porque ela compara somente as referncias e no o print '(' + str(p.x) + ', ' + str(p.y) + ')' A funo mostrarPonto pega o ponto (p) como contedo dos objetos. um argumento e mostra-o no formato padro. Se voc chamar Para comparar o contedo dos objetos -mostrarPonto(final), a sada ser (3.0, 4.0). igualdade profunda -- podemos escrever uma funo chamada Como um exerccio, re-escreva a funo mesmoPonto: distncia da Seo 5.2 para receber dois pontos como def mesmoPonto(p1, p2) : parmetros, ao invs de quatro nmeros. return (p1.x == p2.x) and (p1.y == p2.y) Agora se criarmos dois diferentes objetos que contm os mesmos dados, podemos usar mesmoPonto para 12.4 O significado de "mesmo" verificar se eles representam o mesmo ponto. O significado da palavra "mesmo" parece perfeitamente claro at que voc pense a respeito, e ento voc percebe que h >>> p1 = Ponto() >>> p1.x = 3 mais nesta palavra do que voc esperava. >>> p1.y = 4 Por exemplo, se voc diz "Cris e eu temos o mesmo carro", voc est dizendo que o carro de Cris e o seu >>> p2 = Ponto() so do mesmo fabricante e modelo, mas so dois carros >>> p2.x = 3 diferentes. Se voc disser "Cris e eu temos a mesma me", >>> p2.y = 4 voc est dizendo que a me de Cris e a sua, so a mesma >>> mesmoPonto(p1, p2) pessoa1. Portanto a idia de 'semelhana' diferente True dependendo do contexto. claro, se as duas variveis referirem ao mesmo Quando falamos de objetos, h uma objeto, elas tm igualdade rasa e igualdade profunda. ambigidade similar. Por exemplo, se dois Pontos forem os mesmos, isto quer dizer que eles contm os mesmos dados (coordenadas) ou que so realmente o "mesmo" objeto? 12.5 Retngulos Para verificar se duas referncias se referem ao Digamos que desejemos uma classe para representar um 'mesmo' objeto, use o operador '==' 2. Por exemplo: retngulo. A questo , qual informao temos de prover para >>> p1 = Ponto() especificar um retngulo? Para manter as coisas simples, assuma que o retngulo orientado verticalmente ou >>> p1.x = 3 horizontalmente, nunca em um ngulo. >>> p1.y = 4 H algumas possibilidades: poderamos >>> p2 = Ponto() especificar o centro do retngulo (duas coordenadas) e seu >>> p2.x = 3 tamanho (largura e altura); ou poderamos especificar um dos >>> p2.y = 4 lados e o tamanho; ou poderamos especificar dois lados >>> p1 == p2 opostos. A escolha convencional especificar o canto superior esquerdo do retngulo e o tamanho. False Mesmo que p1 e p2 contenham as mesmas Novamente, vamos definir uma nova classe: coordenadas, os dois no representam o mesmo objeto. Se atribuirmos p1 a p2, ento as duas variveis so pseudnimos class Rectangle: pass E instanci-la: 1 Nem todos os idiomas tm este problema. Por box = Rectangle() exemplo, em alemo h palavras diferentes para diferentes sentidos de "mesmo". "Mesmo carro" box.width = 100.0 nesse contexto seria "gleiche Auto", e "mesma me" box.height = 200.0 seria "selbe Mutter". Este cdigo cria um novo objeto Retngulo com 2 LR: Eu no diria que devemos usar == para verificar se dois atributos ponto-flutuante. Para especificar o canto superior esquerdo, podemos embutir um objeto dentro de um dois objetos so o mesmo. Isto uma falha do livro que talvez se origine no original que falava de Java. objeto! Em Python o operador is faz o mesmo que o == de box.corner = Ponto() Java: compara referncias, e portanto serve para determinar se duas variveis apontam para o mesmo box.corner.x = 0.0; box.corner.y = 0.0; objeto. No entanto, a o cdigo acima est correto A expresso box.corner.x significa, "v ao porque em Python a implemetao default de == objeto referenciado por 'box' e selecione o atributo 'corner'; (mtodo __eq__) comparar o id das instncias, ento v ao objeto 'corner' e deste, selecione o atributo de porm as classes list e dict, por exemplo, nome 'x'". implementam __eq__ comparando os valores A figura mostra o estado deste objeto: contidos (ex.: isto retorna True: l1 = [1,2,3]; l2 = [1,2,3]; l1 == l2). GNU Free Documentation License #67

Como pensar como um cientista da Computao usando Python

12.8 Copiando
Ao usar 'alias' - como fizemos na seo anterior - podemos tornar o programa um pouco difcil de ler ou entender, pois as mudanas feitas em um local, podem afetar inesperadamente um outro objeto. E pode se tornar difcil de encontrar todas as variveis que podem afetar um dado objeto. Copiar um objeto freqentemente uma alternativa ao 'alias'. O modulo 'copy' contm uma funo chamada 'copy' que duplica um qualquer objeto. Veja:

12.6 Instancias como valores retornados

>>> import copy Funes podem retornar instncias. Por exemplo, findCenter >>> p1 = Ponto() pega um Retngulo como um argumento e retorna um Ponto >>> p1.x = 3 que contem as coordenadas do centro do retngulo: >>> p1.y = 4 def findCenter(box): >>> p2 = copy.copy(p1) p = Ponto() >>> p1 == p2 p.x = box.corner.x + box.width/2.0 0 p.y = box.corner.y + box.height/2.0 >>> mesmoPonto(p1, p2) Para chamar esta funo, passe 'box' como um 1 argumento e coloque o resultado em uma varivel. Uma vez que importamos o modulo 'copy', podemos usar o mtodo 'copy' para criar um outro 'Ponto'. p1 e >>> center = findCenter(box) p2 no representam o mesmo ponto, mas eles contem os >>> print mostrarPonto(center) mesmo dados. (50.0, 100.0) Para copiar um simples objeto como um 'Ponto', que no contem nenhum objeto embutido, 'copy' suficiente. Isto eh chamado 'shallow' copia. 12.7 Objetos so mutveis Podemos mudar o estado de um objeto fazendo uma atribuio a um dos seus atributos. Por exemplo, para mudar o tamanho de um retngulo sem mudar sua posio, podemos modificar os valores de sua largura e altura. Veja: Mas para um objeto como um 'Rectangle', que contem uma referencia para um 'Ponto', o mtodo 'copy' no ir executar corretamente a copia. Ele ir copiar a referencia para o objeto 'Ponto', portanto o que acontece aqui que os dois Rectangle (o novo e o antigo) iro fazer referencia a um simples 'Ponto'.

box.width = box.width + 50 Em outras palavras, se criarmos um 'box', c1, box.height = box.height + 100 utilizando a forma usual, e depois fazer uma copia, c2, usando Poderamos encapsular este cdigo em um o mtodo 'copy', o diagrama de estado resultante ficar assim: mtodo e generaliza-lo para aumentar o tamanho deste retngulo em qualquer medida: def growRect(box, dwidth, dheight) : box.width = box.width + dwidth box.height = box.height + dheight As variveis dwidth e dheight indicam em quanto vamos aumentar o tamanho do retngulo em cada direo. Chamando este mtodo, teramos o mesmo efeito.

o resultado no ser o que esperamos. Neste caso, invocando 'growRect' em um dos retngulos (c1), isto Por exemplo, poderamos criar um novo no ir afetar o outro retngulo (c2, neste exemplo). Mas se Retngulo com o nome de 'bob' e passar este nome para o usarmos o mtodo 'moveRect' em qualquer um deles, isto ir mtodo growRect: inevitavelmente afetar o outro. Este comportamento confuso e propenso a erros! >>> bob = Rectangle() Mas felizmente o modulo 'copy' contem um >>> bob.width = 100.00 mtodo chamado 'deepcopy' que copia no somente o objeto, >>> bob.height = 200.00 mas tambm copia todo e qualquer objeto 'embutido' neste >>> bob.corner.x = 0.0; objeto. Por isto, voc no ficar surpreso porque este mtodo chama-se 'deepcopy' (copia profunda) no ? Veja como >>> bob.corner.y = 0.0; funciona: >>> growRect(bob, 50, 100) Enquanto growRect est sendo executado, o >>> c2 = copy.deepcopy(c1) parmetro 'box' um alias (apelido) para 'bob'. Qualquer Agora, c1 e c2 so objetos completamente mudana feita em 'box', tambm ir afetar 'bob'. separados. Como exerccio, escreva uma function (mtodo) Podemos usar 'deepcopy' para re-escrever com o nome de moveRect que pega um Rectangle e dois 'growRect' sendo que ao invs de modificar um Rectangle parmetros com o nome de 'dx' e 'dy'. Esta funo dever existente, ele cria um novo que tem a mesma localizao do mudar a localizao do retngulo atravs da adio de 'dx' outro, mas com novas dimenses: coordenada 'x' e da adio de 'dy' coordenada 'y'. def growRect(box, dwidth, dheight): GNU Free Documentation License #68

Como pensar como um cientista da Computao usando Python import copy newBox = copy.deepcopy(box) newBox.width = newBox.width + dwidth newBox.height = newBox.height + dheight return newBox Como exerccio, re-escreva o mtodo 'moveRect' para ele criar e retornar um novo Rectangle ao invs de apenas modificar o antigo.

12.9 Glossrio
classe (class) Um tipo composto (XXX compound type) definido pelo usurio. Uma classe tambm pode ser visualizada como um molde que define a forma dos objetos que sero suas instncias. instanciar Criar uma instncia de uma classe. (instantiate) instncia Um objeto que pertence a uma classe. (instance) objeto (object) Um tipo de dado composto comumente utilizado para representar uma coisa ou um conceito do mundo real. construtor Um mtodo utilizado para criar novos (constructor) objetos. atributo Um dos itens de dados nomeados que (attribute) compem uma instncia. igualdade rasa Igualdade de referncias; ocorre quando (shallow duas referncias apontam para o mesmo equality) objeto. igualdade Igualdade de valores; ocorre quando duas profunda (deep referncias apontam para objetos que tm equality) o mesmo valor. cpia rasa Ato de copiar o contedo de um objeto, (shallow copy) incluindo as referncias a objetos embutidos (XXX embedded); implementada pela funo copy do mdulo copy. cpia profunda Ato de copiar o contedo de um objeto, (deep copy) bem como dos objetos embutidos (XXX embedded), e dos objetos embutidos nestes, e assim por diante; implementada pela funo deepcopy do mdulo copy.

GNU Free Documentation License #69

Captulo 13: Classes e funes

quantidade de tempo que a mquina de fazer po gasta para fazer po. Ento vamos usar somaHorario para tentar saber quando o po estar pronto. Se voc no tiver terminado de 13.1 Horario escrever imprimirHorario ainda, de uma olhada na seo 14.2 Como exemplo de outro tipo definido pelo usurio, vamos antes de voc continuar isso: definir uma classe chamada Horario que grava os registros de >>> horarioAtual = Horario() horrio do dia. Eis a definio da classe: >>> horarioAtual.horas = 9 class Horario: >>> horarioAtual.minutos = 14 pass >>> horarioAtual.segundos = 30 Podemos criar uma nova instncia de Horario e determinar atributos para horas, minutos e segundos: >>> horarioDoPao = Horario() horario = Horario() >>> horarioDoPao.horas = 3 horario.horas = 11 >>> horarioDoPao.minutos = 35 horario.minutos = 59 >>> horarioDoPao.segundos = 0 horario.segundos = 30 O diagrama de estado para o objeto Horario >>> horarioTermino = somaHorario(horarioAtual, \ parece com isso: horarioDoPao) >>> imprimirHorario(horarioTermino) A sada deste programa 12:49:30, o que correto. Por outro lado, existem casos onde o resultado no correto. Voc pode pensar em algum ? O problema que esta funo no lida com casos onde o nmero de segundos ou minutos acrescentado em mais de sessenta. Quando isso acontece, temos de "transportar" os segundos extras para a coluna dos minutos ou Como exerccio, escreva uma funo os minutos extras na coluna das horas. 'imprimirHorario' que tenha como argumento um objeto Aqui est a segunda verso corrigida da funo: Horario e imprima-o na forma horas:minutos:segundos. def somaHorario(t1, t2): Como um segundo exerccio, escreva uma soma = Horario() funo booleana que tenha como argumento dois objetos soma.horas = t1.horas + t2.horas Horario, h1 e h2, e retorne verdadeiro (1) se h1 vem depois de h2 cronologicamente, do contrrio, retorne falso (0). soma.minutos = t1.minutos + t2.minutos soma.segundos = t1.segundos + t2.segundos

13.2 Funes Puras


Nas prximas sesses, vamos escrever duas verses de uma funo chamada adicionaHorario, que calcula a soma de dois horrios. Elas vo demonstrar 2 tipos de funes: funes puras e funes modificadoras. Segue uma verso rudimentar de somaHorario: def somaHorario(h1, h2): soma = Horario() soma.horas = h1.horas + h2.horas soma.minutos = h1.minutos + h2.minutos soma.segundos = h1.segundos + h2.segundos return soma A funo cria um novo objeto Horario, inicializa os seus atributos, e retorna uma referncia para o novo objeto. Isso chamado de funo pura pois ela no modifica nenhum dos objetos que so passados como parmetros e no tem nenhum efeito colateral, como imprimir um valor ou pegar entrada do usurio.

if soma.segundos >= 60: soma.segundos = soma.segundos - 60 soma.minutos = soma.minutos + 1 if soma.minutos >= 60: soma.minutos = soma.minutos - 60 soma.horas = soma.horas + 1 return soma Apesar desta funo estar correta, ela est comeando a ficar grande. Depois vamos sugerir uma aproximao alternativa que rende um cdigo menor. Clique aqui para feedback

13.3 Modificadores

Existem momentos quando til para uma funo modificar um ou mais dos objetos que ela recebe como parmetro. Aqui est um exemplo de como usar esta Usualmente, quem est chamando a funo mantm uma funo. Ns vamos criar dois objetos Horario: horarioAtual, referncia para os objetos que ele passa, de forma que que contm o horrio atual; e horarioDoPao, que contm a quaisquer mudanas que a funo faz so visveis para quem

Como pensar como um cientista da Computao usando Python est chamando. Funes que trabalham desta forma so Em geral, recomendamos que voc escreva chamadas modificadores. funes puras sempre que for necessrio e recorrer para modificadores somente se existir uma grande vantagem. Esta incrementar, que adiciona um nmero dado de aproximao poderia ser chamada de um estilo de segundos para um objeto Horario, poderia ser escrito quase programao funcional. Clique aqui para feedback naturalmente como um modificador. Um rascunho rudimentar da funo seria algo parecido com isso: def incrementar(horario, segundos): horario.segundos = \ horario.segundos + segundos if horario.segundos >= 60: horario.segundos = \ horario.segundos - 60 horario.minutos = horario.minutos + 1

13.5 Desenvolvimento Prototipado versus Desenvolvimento Planejado


Neste captulo, demonstramos uma aproximao para o desenvolvimento de programas que chamamos de desenvolvimento prototipado. Em cada caso, escrevemos um rascunho rudimentar (ou prottipo) que executou os clculos bsicos e ento, o testamos em uns poucos casos, corrigindo as falhas que fomos encontrando. Embora esta aproximao possa ser eficaz, ela pode conduzir a cdigo que desnecessariamente complicado pois trata de muitos casos especiais e no confivel, pois difcil saber se voc encontrou todos os erros.

if horario.minutos >= 60: horario.minutos = \ Uma alternativa o desenvolvimento planejado, horario.minutos - 60 onde uma viso de alto nvel do problema pode tornar a horario.horas = horario.horas + 1 codificao muito mais fcil. Nesse caso, a abstrao que um A primeira linha executa a operao bsica; o objeto Horario realmente um nmero de trs digitos na base resto lida com os caso especiais que vimos antes. 60! O componente segundo a "coluna dos uns", o Esta funo est correta ? O que aconteceria se o componente minuto a "coluna do 60", e o componente hora parmetro segundos for muito maior que sessenta ? Nesse a "coluna do 360". caso, no suficiente transportar apenas uma vez; teramos de Quando ns escrevemos somaHorario e continuar fazendo isso at que segundos seja menor que incrementar, ns estvamos efetivamente fazendo adies em sessenta. Uma soluo seria substituir os comando if por base 60, que o motivo pelo qual tinhamos de transportar de comandos while: uma coluna para a prxima. def incrementar(horario, segundos): Essa observao sugere uma outra aproximao horario.segundos = \ para todo o problema - ns podemos converter um objeto Horario em um nmero simples e levar vantagem do fato de horario.segundos + segundos que um computador sabe como fazer aritmtica com nmeros. A seguinte funo converte o objeto Horario em um inteiro: while horario.segundos >= 60: def converterParaSegundos(t): horario.segundos = minutos = t.horas * 60 + t.minutos horario.segundos - 60 segundos = minutos * 60 + t.segundos horario.minutos = horario.minutos return segundos + 1 Agora, tudo que precisamos uma maneira de converter de um inteiro para um objeto Horario: while horario.minutos >= 60: def criarHorario(segundos): horario.minutos = \ horario = Time() horario.minutos - 60 horario.horas = segundos/3600 horario.horas = horario.horas + 1 Esta funo agora esta correta, mas no a segundos = segundos - horario.horas * 3600 soluo mais eficiente. horario.minutos = segundos/60 Como um exerccio, reescreva esta funo de segundos = segundos - horario.minutos * 60 maneira que ela no contenha nenhum loop. Como um horario.segundos = segundos segundo exerccio, reescreva incrementar como uma funo return horario pura, e escreva chamadas de funes para as duas funes. Voc deve ter que pensar um pouco para se Clique aqui para feedback convencer que esta tcnica de converter de uma base para outra correta. Assumindo que voc est convencido, voc pode usar essas funes para reescrever somaHorario: 13.4 O que melhor ? Qualquer coisa que pode ser feita com modificadores tambm podem ser feitas com funes puras. De fato, algumas linguagens de programao permitem apenas funes puras. Existe alguma evidncia que programas que usam funes puras so desenvolvidos mais rapidamente e so menos propensos a erros que programas que usam modificadores. No entanto, modificadores as vezes so convenientes, e em alguns casos, programao funcional menos eficiente. def somaHorario(t1, t2): segundos = \ converterParaSegundos(t1) + converterParaSegundos(t2) return criarHorario(segundos) Esta verso muito mais curta que a original, e muito mais fcil para demonstrar que est correta (assumindo, como sempre, que as funes que so chamadas

GNU Free Documentation License #71

Como pensar como um cientista da Computao usando Python caractersticas dos algoritmos que eles no requerem nenhuma inteligncia para serem executados. Eles so Como um exerccio, reescreva incrementar da processos mecnicos no qual cada passo segue o ltimo de mesma forma. Clique aqui para feedback acordo com um conjunto simples de regras. esto corretas).

13.6 Generalizao

Na nossa opinio, preocupante que humanos gastem tanto tempo na escola aprendendo a executar algoritmos que, literalmente, no requerem inteligncia.

Algumas vezes, converter de base 60 para base 10 e voltar Por outro lado, o processo de projetar algoritmos mais difcil do que simplesmente lidar com horrios. interessante, intelectualmente desafiante, e uma parte central Converso de base mais abstrata; nossa intuio para lidar daquilo que chamamos programao. com horrios melhor. Algumas das coisas que as pessoas fazem Mas se conseguirmos abstrair horrios como naturalmente, sem dificuldade ou conscincia, so as mais nmeros de base 60 e investirmos em criar as funes de difceis de se expressar atravs de algoritmos. Entender a converso (converterParaSeguntos e criarHorario), ns linguagem natural um bom exemplo. Todos ns fazemos conseguimos um programa que menor, fcil de ler e depurar, isso, mas at hoje ningum conseguiu explicar como fazemos e mais confivel. isso, pelo menos no na forma de algoritmo. Clique aqui para tambm fcil para adicionar funcionalidades feedback. depois. Por exemplo, imagine subtrair dois Horarios para encontrar a durao entre eles. Uma aproximao ingnua seria implementar subtrao com emprstimo. Usando as 13.8 Glossrio funes de converso ser mais fcil e provavelmente estar correto. funo pura (pure Uma funo que no modifica function) nenhum dos objetos que ela recebe Ironicamente, algumas vezes fazer um problema como parmetro. A maioria das mais difcil (ou mais genrico) o torna mais simples (porque funes puras frutfera. existem alguns poucos casos especiais e poucas oportunidades para errar). Clique aqui para feedback modificador Uma funo que muda um ou mais (modifier) dos objetos que ela recebe como parmetros. A maioria dos 13.7 Algoritmos modificadores nula. Quando voc escreve uma soluo genrica para uma classe de problemas, ao contrrio de uma soluo especfica para um nico problema, voc escreveu um algoritmo. Ns mencionamos isso antes mas no definimos cuidadosamente. Isso no fcil para definir, ento vamos tentar definir demonstrando algumas situaes. Primeiramente, considere alguma coisa que no seja um algoritmo. Quando voc aprendeu a multiplicar nmeros de um dgito, voc provavelmente memorizou a tabela de multiplicao. Como resultado, voc memorizou 100 solues especficas. Esse tipo de conhecimento no algoritmo. Mas se voc "preguioso", voc provavelmente trapaceou por ter aprendido alguns truques. Por exemplo, para encontrar o produto de n e 9, voc pode escrever n-1 como o primeiro dgito e 10-n como o segundo dgito. Este truque um soluo genrica para multiplicar qualquer nmero de um dgito por 9. Isso um algoritmo! De modo parecido, as tcnicas que voc aprendeu para somar com transporte, subtrao com emprstimo, e diviso longa so todas algoritmos. Uma das estilo de programao Um estilo de programao onde a funcional (functional maioria das funes so puras. programming style) desenvolvimento Uma maneira de desenvolver prototipado (prototype programas comeando com um e gradualmente development) prottipo melhorando-o. desenvolvimento Uma maneira de desenvolver planejado (planned programas que envolvem uma development) percepo de alto nvel do problema e mais planejamento do que desenvolvimento incremental ou desenvolvimento prototipado. algoritmo (algorithm) Um conjunto de instrues para resolver uma classe de problemas usando um processo mecnico, no inteligente.

GNU Free Documentation License #72

Captulo 14: Classes e mtodos

ATENO As referncias cruzadas a nomes em cdigos de outros captulos (especialmente 13) ainda no foram unificadas...

14.2 exibeHora (printTime)


No captulo 13, definimos uma classe chamada Horrio (Time) e voc escreveu uma funo chamada exibeHora (printTime), que deve ter ficado mais ou menos assim:

14.1 Caractersticas da orientao a objetos

Python uma linguagem de programao orientada a class Horario: objetos, o que significa que ela tem caractersticas que pass suportam a programao orientada a objetos. No fcil definir programao orientada a def exibeHora(time) objetos, mas temos visto already algumas de suas print str(time.horas) + ?:? + \ caractersticas: str(time.minutos) + ?:? + \ Programas so construdos sobre definies de str(time.segundos) objetos e definies de funes, e a maioria das Para chamar esta funo, passamos um objeto computaes expressa em termos de operaes Time como um parmetro: sobre objetos. Cada definio de objeto corresponde a algum objeto >>> horaCorrente = Hora() ou conceito do mundo real, e as funes que operam >>> horaCorrente.horas = 9 com aqueles objetos correspondem maneira como >>> horaCorrente.minutos = 14 os objetos do mundo real interagem. >>> horaCorrente.segundos = 30 Por exemplo, a classe Tempo, definida no >>> exibeHora(horaCorrente) captulo 13 corresponde maneira como as pessoas registram Para fazer de exibeHora um mtodo, tudo o que as horas do dia, e as funes que definimos correspondem aos temos a fazer mover a definio da funo para dentro da tipos de coisas que as pessoas fazem com times. Do mesmo definio da classe. Note a mudana na endentao: modo, as classes Ponto e Retngulo correspondem aos conceitos matemticos de um ponto e de um retngulo. class Horario: def exibeHora(time): At aqui, no tiramos vantagem das caractersticas fornecidas por Python que suportam a print str(time.horas) + ?:? + \ programao orientada a objetos. Estritamente falando, estas str(time.minutos) + ?:? + \ caractersticas no so necessrias. Na maior parte das vezes, str(time.segundos) elas fornecem uma sintaxe alternativa para as coisas que j Agora podemos chamar exibeHora usando a fizemos, mas em muitos casos, a alternativa mais concisa e natao de ponto: convm mais acuradamente estrutura do programa.

Por exemplo, no programa Time, no existe uma >>> horaCorrente.exibeHora() conexo bvia entre a definio da classe e a definio da Como usual, o objeto no qual o mtodo funo que segue. Com alguma investigao, fica aparente que invocado aparece antes do ponto e o nome do mtodo aparece toda funo toma pelo menos um objeto Time como um depois do ponto. parmetro. O objeto no qual o mtodo invocado Esta observao a motivao por trs dos atribudo ao primeiro parmetro, ento, neste caso, mtodos. J temos visto alguns mtodos, tais como keys horaCorrente atribudo ao parmetro time. (chaves) e values (valores), os quais foram invocados em Por conveno, o primeiro parmetro de um dicionrios. Cada mtodo associado com uma classe e mtodo chamado self. A razo para isto um pouco intended para ser invocado em instncias daquela classe. convoluted, mas baseada numa metfora til. Mtodos so simplesmente como funes, com A sintaxe para uma chamada de funo, duas diferenas: exibeHora(horaCorrente), sugere que a funo um agente Mtodos so definidos dentro da definio de uma ativo. Diz algo como, ?Ei, exibeHora! Aqui est um objeto classe para tornar explcita a relao entre a classe e o para voc exibir.? mtodo. Na programao orientada a objetos, os objetos A sintaxe para a chamada do mtodo diferente da so agentes ativos. Uma chamado do tipo sintaxe para a chamada de uma funo. horaCorrente.exibeHora() diz ?Ei, horaCorrente! Por favor Nas prximas sees, vamos pegar as funes exiba-se a si mesmo!? dos dois captulos anteriores e transform-las em mtodos. Esta mudana de perspectiva pode ser mais Esta transformao puramente mecnica: voc pode polida, mas no fica bvio que seja til. Nos exemplos que consegu-la simplesmente seguindo uma seqncia de passos. temos visto at aqui, pode ser que no seja. Mas s vezes, Se voc se sentir confortvel convertendo de uma forma para a deslocar a responsabilidade das funes para cima dos objetos outra, voc estar apto para escolher a melhor forma para seja torna possvel escrever funes mais versteis, e torna mais o l o que for que voc estiver fazendo. fcil manter e reutilizar o cdigo.

Como pensar como um cientista da Computao usando Python objetos herana, que facilitam a programao orientada a objetos. Vamos converter incremento (da Seo 13.3) em um mtodo. programao Um estilo de programao na qual os Para poupar espao, deixaremos de fora mtodos definidos orientada a dados e as operaes que os manipulam previamente(anteriormente?), mas voc deve mant-los em objetos esto organizados em classes e mtodos. sua verso: mtodo Uma funo que definida dentro de uma class Time: definio de classe e chamada em instncias desta classe. #previous method definitions here...

14.3 Um outro exemplo

def increment(self, segundos): self.seconds = seconds + self.seconds while self.segundos >= 60: self.seconds = self.segundos - 60 self.minutes = self.minutos + 1 while self.minutes >= 60: self.minutes = self.minutos - 60 self.hours = self.horas + 1 A transformao puramente mecnica ? movemos a definio do mtodo para dentro da definio da classe e mudamos o nome do primeiro parmetro. Agora podemos chamar incremento como um mtodo: horaCorrente.incremento(500) De novo, o objeto no qual o mtodo chamado gets atribui ao primeiro parmetro, self. O segundo parmetro, segundo toma(gets) o valor 500. Como um exerccio, converta ?converteParaSegundos? (da Seo 13.5) para um mtodo na classe ?Time?.

override (sem Substituir uma definio j pronta. incluem substituir um traducao; termo Exemplos consagrado) parmetro padro por um argumento particular e substituir um mtodo padro, fornecendo um novo mtodo com o mesmo nome. mtodo de inicializao (tambem chamado de construtor) Um mtodo especial que invocado automaticamente quando um novo objeto criado e que inicializa os atributos deste objeto.

sobrecarga de Estender a funcionalidade dos operadores operador nativos (+, -, *, >, <, etc.) de forma que eles funcionem tambm com tipos definidos pelo usurio. produto escalar Operao definida na lgebra linear que multiplica dois pontos (com coordenadas (x,y,z)) e retorna um valor numrico. multiplicao Operao definida na lgebra linear que por escalar multiplica cada uma das coordenadas de um ponto por um valor numrico. polimrfica Uma funo que pode operar com mais de um tipo. Se todas as operaes de uma funo pode ser aplicadas a um certo tipo, ento a funo pode ser aplicada a este tipo.

14.10 Glossrio
linguagem Uma linguagem que prov caractersticas orientada a tais como classes definidas pelo usurio e

GNU Free Documentation License #74

Captulo 15: Conjuntos de objetos

Rainha -> 12 Rei -> 13

15.1 Composio
At agora, voc vio diversos exemplos de composio. Um dos primeiros exemplos foi o uso de uma invocao de mtodo como parte de uma expresso. Outro exemplo a estrutura aninhada dos comandos: voc pode pr um comando if dentro de um lao while, dentro de outro comando if, e assim por diante. Tendo visto este padro, e tendo aprendido a respeito de listas e objetos, voc no deveria ficar surpreso em aprender que voc pode criar listas de objetos. Voc tambm pode criar obejtos que contm listas (como atritos); voc pode criar listas que contm listas; voc pode criar objetos que contm objetos; e assim por diante.

O motivo pelo qual ns estamos usando notao matemtica para estes mapeamentos que eles no so parte do programa Python. Eles so parte do projeto do programa, mas eles nunca aparecem explicitamente no cdigo. A definio de classe para o tipo Carta fica parecida com esta: class Carta: def __init__(self, naipe=0, posicao=0): self.naipe = naipe self.posicao = posicao Como sempre, ns fornecemos um mtodo de inicializao que recebe um parmetro opcional para cada atributo.

Neste captulo e no prximo, voc ir ver alguns Para criar um objeto que representa o 3 de Paus, exemplos destas combinaes, usando objetos Carta como usa-se este comando: exemplo. tresDePaus = Carta(0, 3) O primeiro argumento, 0, representa o naipe de Paus. 15.2 Objetos Carta Se voc no estiver familiarizado com jogos de cartas, agora um bom momento para conseguir um baralho, ou ento esse captulo pode no fazer muito sentido. H 52 cartas em um baralho, cada uma das quais pertence a um dos quatro naipes e a uma das treze posies. Os naipes so Espadas, Copas, Ouros e Paus (em ordem descendente no bridge). As posies so s, 2, 3, 4, 5, 6, 7, 8, 9, 10, Valete, Rainha e Rei. Dependendo do jogo, a posio do s pode ser maior do que a do Rei ou menor do que a do 2.

15.3 Atributos de classe e o mtodo __str__


Para imprimir objetos Carta de uma maneira que as pessoas possam facilmente ler, ns gostaramos de mapear os cdigos inteiros para palavras. Uma forma natural de fazer isso usar listas de strings. Ns atribumos estas listas para atributos de classe no topo da definio de classe:

class Carta: Se quisermos definir um novo objeto para listaDeNaipes = ["Paus", "Ouros", "Copas", representar uma carta, bvio que os atributos devem ser "Espadas"] posicao e naipe. No to bvio so os tipos aos quais devem listaDePosicoes = ["narf", "s", "2", "3", "4", pertencer os atributos. Uma possibilidade usar strings contendo palavras como "Espada" para naipes e "Rainha" para "5", "6", "7", posies. Um problema com esta implementao que no "8", "9", "10", "Valete", seria fcil comparar cartas para ver qual possui o maior naipe "Rainha", "Rei"] ou posio. Uma alternativa usar inteiros para codificar as posies e naipes. "Codificar", neste caso, no significa o # mtodo init omitido mesmo que as pessoas normalmente pensam, que criptografar ou traduzir para um cdigo secreto. O que um def __str__(self): cientista da computao quer dizer com "codificar" "definir return (self.listaDePosicoes[self.posicao] + um mapeamento entre uma seqncia de nmeros e os itens " de " + self.ListaDeNaipes[self.naipe]) que eu quero representar". Por exemplo: Um atributo de classe definido fora de Espadas -> 3 qualquer mtodo, e ele pode ser acessado por quaisquer mtodos da classe. Copas -> 2 Dentro de __str__, ns podemos usar Ouros -> 1 listaDeNaipes e listaDePosicoes para mapear os valores Paus -> 0 numricos de naipe e posicao para strings. Por exemplo, a expresso self.listaDeNaipes[self.naipe] significa "use o Uma caracterstica bvia deste mapeamento atributo naipe do objeto self como um ndice para o atributo de que os naipes so mapeados para inteiros na ordem, de modo classe chamado listaDeNaipes, e selecione a string que ns podemos comparar naipes pela comparao de apropriada". inteiros. O mapeamento de posies bastante bvio. Cada uma das posies numricas mapeia para o inteiro O motivo para o "narf" no primeiro elemento em correspondente e, as cartas com figura so mapeadas conforme listaDePosicoes preencher o lugar do 0-simo elemento da abaixo: lista, que nunca ser usado. As nicas posies vlidas so de 1 a 13. Este item desperdiado no inteiramente necessrio. Valete -> 11 Ns poderamos ter iniciado com 0, como normal. Porm,

Como pensar como um cientista da Computao usando Python menos confuso codificar 2 como 2, 3 como 3, e assim por Com essa deciso, ns podemos escrever diante. __cmp__: Com os mtodos que ns temos at agora, ns def __cmp__(self, other): podemos criar e imprimir cartas: # verificar os naipes if self.naipe > other.naipe: return 1 >>> carta1 = Carta(1, 11) if self.naipe < other.naipe: return -1 >>> print carta1 # as cartas tm o mesmo naipe... verificar as Valete de Ouros Atributos de classe como listaDeNaipes so posies compartilhados por todos os objetos Carta. A vantagem disso if self.posicao > other.posicao: return 1 que ns podemos usar qualquer objeto Carta para acessar os if self.posicao < other.posicao> return -1 atributos de classe: # as posies so iguais... um empate >>> carta2 = Carta(1, 3) return 0 >>> print carta2 Nesta ordenao, Ases so menores do que 2. 3 de Ouros Como um exerccio, modifique ``__cmp__``, de >>> print carta2.listaDeNaipes[1] modo que os Ases sejam maiores do que os Reis. Ouros A desvantagem que se ns modificarmos um atributo de classe, isso afetar cada instncia da classe. Por 15.5 Baralhos exemplo, se ns decidirmos que "Valete de Ouros" deveria realmente se chamar "Valete de Baleias Rodopiantes", ns Agora que ns temos objetos para representar Cartas, o poderamos fazer isso: prximo passo lgico definir uma classe para representar um Baralho. claro que um baralho formado por cartas; >>> carta1.listaDeNaipes = "Baleias Rodopiantes" portanto, cada objeto Baralho ir conter uma lista de cartas >>> print carta1 como um atributo. 3 de Baleias Rodopiantes A seguir, damos uma definio para a classe O problema que todos os Ouros se tornam Baralho. O mtodo de inicializao cria o atributo cartas e Baleias Rodopiantes: gera o conjunto padro de 52 cartas: >>> print carta2 classe Baralho 3 de Baleias Rodopiantes def __init__(self): Normalmente, no uma boa idia modificar self.cartas = [] atributos de classe. for naipe in range(4): for posicao in range(1, 14): 15.4 Comparando cartas self.cartas.append(Carta(naipe, posicao)) A maneira mais fcil de popular o baralho com Para tipos primitivos, existem operadores condicionais (<, >, um lao aninhado. O lao externo enumera os naipes de 0 at ==, etc.) que comparam valores e determinam quando um 3. O lao interno enumera as posies de 1 at 13. Como o maior que, menor que ou igual a outro. Para tipos definidos lao externo repete quatro vezes e o lao interno 13 vezes, o pelo usurio, ns podemos sobrescrever o comportamento dos nmero total de vezes que o corpo executado 52 (13 vezes operadores pr-definidos fornecendo um mtodo __cmp__. quatro). Cada iterao cria uma nova instncia de Carta com o Por conveno, __cmp__ recebe dois parmetros, self e other, naipe e posio atuais e a inclui na lista cartas. e retorna 1 se o primeiro objeto for maior, -1 se o segundo O mtodo append trabalha sobre listas mas no, objeto for maior, e 0 se eles forem iguais. obviamente, sobre tuplas. Alguns tipos so totalmente ordenados, o que significa que ns podemos comparar quaisquer dois elementos e dizer qual o maior. Por exemplo, os inteiros e os nmeros 15.6 Imprimindo o baralho de ponto flutuante so totalmente ordenados. Alguns conjuntos so no-ordenados, o que significa que no existe maneira Como sempre, quando ns definimos um novo tipo de objeto, significativa de dizer que um elemento maior que o outro. ns gostaramos de ter um mtodo para imprimir o contedo Por exemplo, as frutas so no-ordenadas, e por isso que no de um objeto. Para imprimir um Baralho, ns percorremos a podemos comparar mas e laranjas. lista e imprimimos cada Carta: O conjunto de cartas de jogo parcialmente class Baralho: ordenado, o que significa que s vezes voc pode comparar ... cartas, e s vezes no. Por exemplo, voc sabe que o 3 de Paus def imprimirBaralho(self): maior do que o 2 de Paus, e que o 3 de Ouros maior do que o 3 de Paus. Mas qual o melhor, o 3 de Paus ou o 2 de for carta in self.cartas: Ouros? Um tem uma posio maior, mas o outro tem um naipe print carta maior. Aqui, e a partir daqui, as reticncias (...) indicam Para tornar as cartas comparveis, voc tem que que ns omitimos os outros mtodos da classe. decidir o que mais importante: posio ou naipe. Para ser Como uma alternativa a imprimirBaralho, ns honesto, a escolha arbitrria. Por questo de escolha, ns iremos dizer que naipe mais importante, porque um baralho poderamos escrever um mtodo __str__ para a classe de cartas novo vem ordenado com todas as cartas de Paus Baralho. A vantagem de __str__ que ela mais flexvel. Em vez de apenas imprimir o contedo de um objeto, ela gera uma juntas, seguidas pelas de Ouros, e assim por diante. representao em string que outras partes do programa podem GNU Free Documentation License #76

Como pensar como um cientista da Computao usando Python manipular antes de imprimir ou armazenar para uso posterior. intervalo a <= x < b. Como o limite superior estritamente menor que b, ns podemos usar o comprimento de uma lista Abaixo, uma verso de __str__ que devolve uma como o segundo parmetro, e ns garantimos que o ndice representao em string de um Baralho. Para adicionar um sempre ser vlido. Por exemplo, esta expresso escolhe o pouco de estilo, ela distribui as cartas em uma cascata, na qual ndice de uma carta aleatria em um baralho: cada carta indentada um espao a mais do que a carta anterior: random.randrange(0, len(self.cartas)) Uma maneira fcil de embaralhar as cartas class Baralho: percorrer a lista e trocar cada carta por outra escolhida ... aleatoriamente. possvel que a carta seja trocada por ela def __str__(self): mesma, mas isso no problema. Na verdade, se ns exclussemos essa possibilidade, a ordem das cartas no seria s = "" totalmente aleatria: for i in range(len(self.cartas)): s = s + " "*i + str(self.cartas[i]) + "\n" class Baralho: return s ... Este exemplo demonstra diversas caractersticas. def embaralhar(self): Primeiro, em vez de percorrer self.cartas e atribuir cada carta a import random uma varivel, ns estamos usando i como uma varivel de lao nCartas = len(self.cartas) e um ndice para a lista de cartas. for i in range(nCartas): Segundo, ns estamos usando o operador de j = random.randrange(i, nCartas) multiplicao de strings para indentar cada carta com um self.cartas[i], self.cartas[j] = espao adicional com relao anterior. A expresso " "*i produz um nmero de espaos igual ao valor atual de i. self.cartas[j], self.cartas[i] Em vez de assumir que existem 52 cartas no Terceiro, em vez de usar o comando print para baralho, ns obtivemos o comprimento real da lista e o imprimir as cartas, ns usamos a funo str. Passar um objeto como um argumento para str equivale a invocar o mtodo guardamos na varivel nCartas. __str__ sobre o objeto. Para cada carta no baralho, ns escolhemos uma Finalmente, ns estamos usando a varivel s carta aleatria dentre as cartas que ainda no foram como um acumulador. Inicialmente, s a string vazia. A cada embaralhadas. Ento, ns trocamos a carta atual (i) pela carta repetio do lao, uma nova string gerada e concatenada selecionada (j). Para trocar as cartas, ns usamos uma com o valor antigo de s para obter um novo valor. Quando o atribuio de tupla, como visto na Seo 9.2: lao termina, s contm a representao em string completa do self.cartas[i], self.cartas[j] = self.cartas[j], Baralho, que se parece com: self.cartas[i] >>> baralho = Baralho() Como exerccio, reescreva esta linha de cdigo sem usar uma atribuio de seqncia. >>> print Baralho s de Paus 2 de Paus 15.8 Removendo e distribuindo cartas 3 de Paus Outro mtodo que pode ser til para a classe Baralho 4 de Paus removerCarta. Ele recebe uma carta como parmetro, remove5 de Paus a do baralho e retorna verdadeiro (1), se a carta estava no 6 de Paus baralho e falso (0), caso contrrio: 7 de Paus class Baralho: 8 de Paus ... 9 de Paus def removerCarta(self, carta): 10 de Paus if carta in self.cartas: Valete de Paus self.cartas.remove(carta) Rainha de Paus return 1 Rei de Paus else s de Ouros return 0 E assim por diante. Mesmo que o resultado O operador in retorna verdadeiro se o primeiro aparea em 52 linhas, uma string longa que contm operando estiver contido no segundo, que deve ser uma lista newlines. ou uma tupla. Se o primeiro operando for um objeto, Python usa o mtodo __cmp__ do objeto para determinar igualdade com os itens da lista. Como o mtodo __cmp__ da classe 15.7 Embaralhando Carta verifica por igualdade profunda, o mtodo removerCarta Se um baralho estiver perfeitamente embaralhado, ento cada tambm testa por igualdade profunda. carta tem a mesma probabilidade de aparecer em qualquer Para distribuir as cartas, ns iremos remover e lugar no baralho, e qualquer localizao no baralho tem a devolver a carta do topo. O mtodo de lista pop fornece uma mesma probabilidade de conter qualquer carta. maneira conveniente de fazer isso: Para embaralhar as cartas, ns usaremos a funo randrange do mdulo random. Com dois argumentos class Baralho: ... inteiros, a e b, randrange escolhe um inteiro aleatrio no GNU Free Documentation License #77

Como pensar como um cientista da Computao usando Python def distribuirCarta(self): return self.cards.pop() Na verdade, pop remove a ltima carta da lista. Portanto, ns estamos realmente distribuindo as cartas do fim para o incio do baralho. Uma ltima operao que ns poderamos querer a funo booleana estahVazio, que retorna verdadeiro se o baralho no contm cartas: class Baralho: ... def estahVazio(self): return (len(self.cartas) == 0)

15.9 Glossrio
codificar Representar um conjunto de valores usando (encode) outro conjunto de valores, construindo um mapeamento entre eles. atributo de Uma varivel que definida dentro de uma classe (class definio de classe, mas fora de qualquer atribute) mtodo. Atributos de classe podem ser acessados a partir de qualquer mtodo da classe e so compartilhados por todas as instncias da classe. acumulador Uma varivel usada em um lao para (accumulator) acumular uma srie de valores, para, por exemplo, concaten-los em uma string ou som-los a uma soma em andamento.

GNU Free Documentation License #78

Capitulo 16: Herana

pass

16.1 Herana

Esse comando indica que a nova classe Mao herda da classe existente Baralho.

O construtor de Mao inicializa os atributos da Uma das caractersticas mais marcantes das linguagens orientadas a objetos a herana. Herana a habilidade de mo, que so nome e cartas. A string nome identifica essa definir uma nova classe que uma verso modificada de uma mo, provavelmente pelo nome do jogador que est segurando as cartas. O nome um parmetro opcional com a string vazia classe existente. como valor default. cartas a lista de cartas da mo, A principal vantagem dessa caracterstica que inicializada com uma lista vazia voc pode adicionar novos mtodos a uma classe sem ter que modificar a classe existente. Chama-se "herana" porque a class Mao(Baralho): nova classe herda todos os mtodos da classe existente. def __init__(self, nome=""): Ampliando a metfora, podemos dizer que a classe existente self.cartas = [] s vezes chamada de classe me (parent). A nova classe pode self.nome = nome ser chamada de classe filha ou, simplesmente, "subclasse". Em praticamente todos os jogos de cartas, A herana uma caracterstica poderosa. Alguns necessario adicionar e remover cartas do baralho. Remover programas que seriam complicados sem herana podem ser cartas j est resolvido, uma vez que Mao herda removerCarta escritos de forma simples e concisa graas a ela. E a herana de Baralho. Mas precisamos escrever adicionarCarta: tambm pode facilitar o reuso do cdigo, uma vez que voc pode adaptar o comportamento de classes existentes sem ter class Mao(Baralho): que modific-las. Em alguns casos, a estrutura da herana #... reflete a natureza real do problema, tornando o programa mais def adicionarCarta(self,carta): fcil de entender. self.cartas.append(carta) Por outro lado, a herana pode tornar um De novo, a elipse indica que omitimos outros programa seja difcil de ler. Quando um mtodo invocado, s mtodos. O mtodo de listas append adiciona a nova carta no vezes no est claro onde procurar sua definio. A parte final da lista de cartas. relevante do cdigo pode ser espalhada em vrios mdulos. E, tambm, muitas das coisas que podem ser feitas utilizando herana tambm podem ser feitas de forma igualmente 16.3 Dando as cartas elegante (ou at mais) sem ela. Se a estrutura natural do problema no se presta a utilizar herana, esse estilo de Agora que temos uma classe Mao, queremos distribuir cartas programao pode trazer mais problemas que vantagens. de Baralho para mos de cartas. No imediatamente bvio se Nesse captulo, vamos demonstrar o uso de esse mtodo deve ir na classe Mao ou na classe Baralho, mas herana como parte de um programa que joga uma variante de como ele opera num nico baralho e (possivelmente) em Mico. Um dos nossos objetivos escrever um cdigo que vrias mos de cartas, mais natural coloc-lo em Baralho. possa ser reutilizado para implementar outros jogos de cartas. O mtodo distribuir deve ser bem geral, j que diferentes jogos tero diferentes requerimentos. Podemos querer distribuir o baralho inteiro de uma vez s ou adicionar 16.2 Uma mo de cartas uma carta a cada mo. Para quase todos os jogos de baralho, preciso representar uma mo de cartas. Uma mo de cartas similar a um mao de baralho. Porque ambos so formados por uma srie de cartas e ambos requerem operaes, como, adicionar e remover cartas. Fora isso, a habilidade de embaralhar a mo e o baralho tambm so teis. Mas, ao mesmo tempo, a mo tambm diferente do baralho. Dependendo do jogo que est sendo jogado, precisamos realizar algumas operaes nas mos de cartas que no fazem sentido para o baralho inteiro. Por exemplo, no pquer, podemos classificar uma mo (trinca, flush, etc.) ou compar-la com outra mo. No jogo de bridge, podemos querer computar a quantidade de pontos que h numa mo, a fim de fazer um lance. Essa situao sugere o uso de herana. Se Mao uma subclasse de Baralho, ter todos os mtodos de Baralho, e novos mtodos podem ser adicionados. Na definio de classe, o nome da classe pai aparece entre parnteses: class Mao(Baralho): distribuir recebe dois argumentos, uma lista (ou tupla) de mos e o numero total de cartas a serem dadas. Se no houver cartas suficientes no baralho, o mtodo d todas as cartas e pra: class Baralho: #... def distribuir(self, maos, nCartas=999): nMaos = len(maos) for i in range(nCartas): if self.estahVazia(): break # interromper se acabaram as cartas carta = self.pegarCarta() # pegar a carta do topo mao = maos[i % nMaos] # quem deve receber agora? mao.adicionarCarta(carta) # adicionar a carta mao O segundo parmetro, nCartas, opcional; o default um nmero grande, o que na prtica significa que

Como pensar como um cientista da Computao usando Python todas as cartas do baralho sero dadas se este parmetro for 16.5 A classe JogoDeCartas omitido. A varivel do lao i vai de 0 a nCartas-1. A cada A classe JogoDeCartas toma conta de algumas tarefas bsicas volta do lao, uma carta removida do baralho, usando o comuns a todos os jogos, como, criar o baralho e embaralhmtodo de lista pop, que remove e retorna o ltimo item na lo: lista. class JogoDeCartas: O operador mdulo (%) permite dar cartas em def __init__(self): ao redor da mesa (uma carta de cada vez para cada mo). self.baralho = Baralho() Quando i igual ao numero de mos na lista, a expresso i % self.baralho.embaralhar() nMaos volta para o comeo da lista (ndice 0). Este o primeiro dos casos que vimos at agora em que o mtodo de inicializao realiza uma computao significativa, para alm de inicializar atributos. 16.4 Exibindo a mao Para implementar jogos especficos, podemos Para exibir o contedo de uma mo, podemos tirar vantagem herdar de JogoDeCartas e adicionar caracteristicas para o novo dos mtodos exibirBaralho e __str__ herdados de Baralho. Por jogo. Como exemplo, vamos escrever uma simulao de Mico. exemplo: O objetivo do jogo livrar-se das cartas que >>> baralho = Baralho() estiverem na mo. Para fazer isso, preciso combinar cartas formando pares ou casais que tenham a mesma cor e o mesmo >>> baralho.embaralhar() nmero ou figura. Por exemplo, o 4 de paus casa com o 4 de >>> mao = Mao("fabio") espadas porque os dois naipes so pretos. O Valete de copas >>> baralho.distribuir([mao], 5) combina com o Valete de ouros porque ambos so vermelhos. >>> print mao Antes de mais nada, a Dama de paus removida Mo fabio contm do baralho, para que a Dama de espadas fique sem par. A 2 de espadas Dama de espadas ento faz o papel do mico. As 51 cartas que sobram so distribuidas aos jogadores em ao redor da mesa 3 de espadas (uma carta de cada vez para cada mo). Depois que as cartas 4 de espadas foram dadas, os jogadores devem fazer todos os casais s de copas possveis que tiverem na mo, e em seguida descart-los na 9 de paus mesa. Nao l uma grande mo, mas tem potencial Quando ningum mais tiver nenhum par para para um straight flush. descartar, o jogo comea. Na sua vez de jogar, o jogador pega Embora seja conveniente herdar os mtodos uma carta (sem olhar) do vizinho mais proximo esquerda, existentes, h outras informacoes num objeto Mao que que ainda tiver cartas. Se a carta escolhida casar com uma podemos querer incluir quando ao exib-lo. Para fazer isso, carta que ele tem na mo, ele descarta esse par. Quando todos podemos fornecer um mtodo __str__ para a classe Mao que os casais possveis tiverem sido feitos, o jogador que tiver sobrescreva o da classe Baralho: sobrado com a Dama de espadas na mo perde o jogo. class Mao(Baralho) #... def __str__(self): s = "Mao " + self.nome if self.estahVazia(): return s + " est vazia\n" else: return s + " contm\n" + Baralho.__str__(self) Inicialmente, s uma string que identifica a mo. Se a mo estiver vazia, o programa acrescenta as palavras est vazia e retorna o resultado. Em nossa simulao computacional do jogo, o computador joga todas as mos. Infelizmente, algumas nuances do jogo presencial se perdem. Num jogo presencial, o jogador que est com o mico na mo pode usar uns truques para induzir o vizinho a pegar a carta, por exemplo, segurando-a mais alto que as outras, ou mais baixo, ou se esforando para que ela no fique em destaque. J o computador simplesmente pega a carta do vizinho aleatoriamente...

16.6 Classe MaoDeMico

Uma mo para jogar Mico requer algumas habilidades para alem das habilidades gerais de uma Mao. Vamos definir uma Se no, o programa acrescenta a palavra contm nova classe, MaoDeMico, que herda de Mao e prov um e a representao de string do Baralho, computada pela mtodo adicional chamado descartarCasais: invocao do mtodo __str__ na classe Baralho em self. Pode parecer estranho enviar self, que se refere class MaoDeMico(Mao): def descartarCasais(self): Mao corrente, para um mtodo Baralho, mas isso s at voce se lembrar que um Mao um tipo de Baralho. Objetos Mao conta = 0 podem fazer tudo que os objetos Baralho fazem, entao, cartasIniciais = self.cartas[:] permitido passar uma instncia de Mao para um mtodo for carta in cartasIniciais: Baralho. casal = Carta(3 - carta.naipe, carta.valor) Em geral, sempre permitido usar uma instncia if casal in self.cartas: de uma subclasse no lugar de uma instncia de uma classe self.cartas.remove(carta) me. self.cartas.remove(casal) print "Mao %s: %s casais %s" % GNU Free Documentation License #80

Como pensar como um cientista da Computao usando Python argumento. (self.nome,carta,casal) conta = conta + 1 J que __init__ herdado de JogoDeCartas, um novo objeto Mico contm um novo baralho embaralhado: return conta Comeamos fazendo uma cpia da lista de cartas, para poder percorrer a cpia enquanto removemos class Mico(JogoDeCartas): def jogar(self, nomes): cartas do original. Uma vez que self.cartas modificada no lao, no queremos us-la para controlar o percurso. Python # remover a Dama de paus pode ficar bem confuso se estiver percorrendo uma lista que self.baralho.removerCarta(Carta(0,12)) est mudando! Para cada carta na mo, verificamos qual a carta que faz par com ela e vamos procur-la. O par da carta tem o mesmo valor (nmero ou figura) e naipe da mesma cor. A expresso 3 - carta.naipe transforma um paus (naipe 0) numa espadas (naipe 3) e um ouros (naipe 1) numa copas (naipe 2). Voc deve analisar a frmula at se convencer de que as operaes opostas tambm funcionam. Se o par da carta tambem estiver na mo, ambas as cartas so removidas. O exemplo a seguir demonstra como usar descartarCasais: >>> jogo = JogoDeCartas() >>> mao = MaoDeMico("fabio") >>> jogo.baralho.distribuir([mao], 13) >>> print mao mo fabio contm s de espadas 2 de ouros 7 de espadas 8 de paus 6 de copas 8 de espadas 7 de paus Rainha de paus 7 de ouros 5 de paus Valete de ouros 10 de ouros 10 de copas >>> mao.descartarCasais() Mo fabio: 7 de espadas faz par com 7 de paus Mo fabio: 8 de espadas faz par com 8 de paus Mo fabio: 10 de ouros faz par com 10 de copas >>> print mao Mo fabio contm s de espadas 2 de ouros 6 de copas Rainha de paus 7 de ouros 5 de paus Valete de ouros Observe que no existe um mtodo __init__ para a classe MaoDeMico. Ele herdado de Mao. # fazer uma mo para cada jogador self.maos = [] for nome in nomes : self.maos.append(MaoDeMico(nome)) # distribuir as cartas self.baralho.distribuir(self.maos) print "---------- As cartas foram dadas" self.exibirMaos() # remover casais iniciais casais = self.removerTodosOsCasais() print "---------- Os pares foram descartados, o jogo comea" self.exibirMaos() # jogar at que 25 casais se formem vez = 0 numMaos = len(self.maos) while casais < 25: casais = casais + self.jogarVez(vez) vez = (vez + 1) % numMaos print "---------- Fim do jogo" self.exibirMaos() Algumas etapas do jogo foram separadas em mtodos. removerTodosOsCasais percorre a lista de mos e invoca descartarCasais em cada uma: class Mico(JogoDeCartas): #... def removerTodosOsCasais(self): conta = 0 for mao in self.maos: conta = conta + mao.descartarCasais() return conta Como exerccio, escreva ``exibirMaos`` que percorre ``self.maos`` e exibe cada mo. conta uma acumulador que soma o nmero de pares em cada mo e retorna o total. Quando o nmero total de pares alcana 25, 50 cartas foram removidas das mos, o que significa que sobrou s uma carta e o jogo chegou ao fim. A varivel vez mantm controle sobre de quem a vez de jogar. Comea em 0 e incrementa de um em um; quando atinge numMaos, o operador mdulo faz ela retornar para 0.

16.7 Classe Mico

O mtodo jogarVez recebe um argumento que Agora podemos focar nossa ateno no jogo em si. Mico uma subclasse de JogoDeCartas com um novo mtodo indica de quem a vez de jogar. O valor de retorno o nmero chamado jogar que recebe uma lista de jogadores como de pares feitos durante essa rodada: GNU Free Documentation License #81

Como pensar como um cientista da Computao usando Python class Mico(JogoDeCartas): Rei de ouros Rainha de ouros #... def jogarVez(self, i): Mo Clara contm if self.maos[i].estahVazia(): Valete of ouros return 0 Rei de paus vizinho = self.buscarVizinho(i) 10 de espadas novaCarta = self.maos[vizinho].pegarCarta() 10 de copas self.maos[i].adicionarCarta(novaCarta) 10 de paus print "Mao", self.maos[i].nome, "pegou", novaCarta Mo Jair: Dama de copas faz par com Dama de ouros conta = self.maos[i].descartarCasais() Mo Clara: 10 de espadas faz par com 10 de paus self.maos[i].embaralhar() ---------- Os pares foram descartados, o jogo return conta Se a mo de um jogador estiver vazia, ele est comea fora do jogo, ento, ele no faz nada e retorna 0. Mo Alice contm Do contrrio, uma jogada consiste em achar o Rei de copas primeiro jogador esquerda que tenha cartas, pegar uma carta Valete de paus dele, e tentar fazer pares. Antes de retornar, as cartas na mo Rainha de espadas so embaralhadas, para que a escolha do prximo jogador seja Rei de espadas aleatria. 10 de ouros O mtodo buscarVizinho comea com o jogador imediatamente esquerda e continua ao redor da mesa at encontrar um jogador que ainda tenha cartas: Mo Jair contm Valete de espadas class Mico(JogoDeCartas): Valete de copas #... Rei de ouros def buscarVizinho(self, i): numMaos = len(self.maos) for next in range(1,numMaos): vizinho = (i + next) % numMaos if not self.maos[vizinho].estahVazia(): return vizinho Se buscarVizinho alguma vez circulasse pela mesa sem encontrar cartas, retornaria None e causaria um erro em outra parte do programa. Felizmente, podemos provar que isso nunca vai acontecer (desde que o fim do jogo seja detectado corretamente). No mencionamos o mtodo exibirBaralhos. Esse voc mesmo pode escrever. A sada a seguir produto de uma forma reduzida do jogo, onde apenas as 15 cartas mais altas do baralho (do 10 para cima) foram dadas, para trs jogadores. Com esse baralho reduzido, a jogada pra depois que 7 combinaes foram feitas, ao invs de 25: >>> import cartas >>> jogo = cartas.Mico() >>> jogo.jogar(["Alice","Jair","Clara"]) ---------- As cartas foram dadas Mo Alice contm Rei de copas Valete de paus Rainha de espadas Rei de espadas 10 de ouros Mo Jair contm Rainha de copas Valete de espadas Valete de copas Mo Clara contm Valete de ouros Rei de paus 10 de copas Mo Alice pegou o Rei de ouros Mo Alice: Rei de copas faz par com Rei de ouros Mo Jair pegou 10 de copas Mo Clara pegou Valete de paus Mo Alice pegou Valete de copas Mo Jair pegou Valete de ouros Mo Clara pegou Dama de espadas Mo Alice pegou Valete de ouros Mo Alice: Valete de copas faz par com Valete de ouros Mo Jair pegou Rei de paus Mo Clara pegou Rei de espadas Mo Alice pegou 10 de copas Mo Alice: 10 de ouros faz par com 10 de copas Mo Jair pegou Dama de espadas Mo Clara pegou Valete de espadas Mo Clara: Valete de paus faz par com Valete de espadas Mo Jair pegou Rei de espadas Mo Jeff: Rei de paus faz par com Rei de espadas ---------- Fim do jogo Mo Alice est vazia Mo Jair contm Rainha de espadas GNU Free Documentation License #82

Como pensar como um cientista da Computao usando Python classe me (parent A classe de quem a classe filha class) herda. Ento, o Jair perdeu. classe filho (child Um nova classe criada herdando de class) uma classe existente; tambm chamada de "subclasse". Mo Clara est vazia

16.8 Glossrio

herana (inheritance) Habilidade de definir uma nova classe que a verso modificada de uma classe definida anteriormente.

GNU Free Documentation License #83

Captulo 17: Listas encadeadas

17.1 Referncias Embutidas


Ns temos visto exemplos de atributos que referenciam outros objetos, que so chamados referncias embutidas (veja a Seo 12.8). Uma estrutura de dados comum, a lista ligada, tira vantagem desta caracterstica.

Para ligar os ns, temos que fazer o primeiro n Listas ligadas so constitudas de ns (nodos), da lista referir ao segundo e o segundo n referir ao terceiro: onde cada n contm uma referncia para o prximo n na lista. Alm disto, cada n contm uma unidade de dados >>> no1.proximo = no2 chamada a carga. >>> no2.proximo = no3 A referncia do terceiro n None, que indica Uma lista ligada considerada uma estrutura de dados recorrente porque ela tem uma definio recorrente. que ele o final da lista. Agora o diagrama de estado se parece com: Uma lista ligada :

Uma lista vazia, representada por None, ou Um n que contm um objeto carga e uma referncia para uma lista ligada. Agora voc sabe como criar ns e lig-los em uma lista. O que pode estar menos claro neste ponto por qu.

Estruturas de dados recorrentes so adequadas para mtodos recorrentes.

17.2 A classe No (Node)


Como usual quando se escreve uma nova classe, ns comearemos com os mtodos de inicializao e __str__ de modo que podemos testar o mecanismo bsico de se criar e Listas so teis porque elas provm um modo de montar mltiplos objetos em uma nica entidade, algumas vezes mostrar o novo tipo: chamada uma coleo. No exemplo, o primeiro n da lista serve como uma referncia para toda a lista. class No: def __init__(self, carga=None, proximo=None): Para passar uma lista como um parmetro, voc apenas tem que passar uma referncia ao primeiro n. Por self.carga = carga exemplo, a funo imprimeLista toma um nico n como um self.proximo = proximo argumento. Iniciando com o cabea da lista, ela imprime cada n at que chegue ao fim: def __str__(self): def imprimeLista(no): return str(self.carga) while no: Como de costume, os parmetros para o mtodo de inicializao so opcionais. Por omisso (default), ambos, a print no, carga e a ligao, proximo, so definidas como None. no = no.proximo print A representao string de um n simplesmente a representao string da carga. Como qualquer valor pode ser Para chamar este mtodo, ns passamos uma passado para a funo str, ns podemos armazenar qualquer referncia ao primeiro no: valor em uma lista. >>> imprimeLista(no1) Para testar a implementao at agora, ns 1 2 3 criamos um No e o imprimimos: Dentro de imprimeLista ns temos uma referncia para o primeiro n da lista, mas no h variveis >>> no = No("teste") que refiram aos outros ns. Ns temos que usar o valor >>> print no proximo de cada n para alcanar o prximo n. teste Para percorrer uma lista ligada, comum usar Para ficar interessante, ns precisamos uma lista uma varivel lao como no para referir a cada um dos ns com mais do que um n: sucessivamente. >>> no1 = No(1) Este diagrama mostra o valor de lista e os >>> no2 = No(2) valores que no assume: >>> no3 = No(3) Este cdigo cria trs ns, mas ns ainda no temos uma lista ainda porque os ns no esto ligados. O diagrama de estado parecido com este:

17.3 Listas como Colees

Como pensar como um cientista da Computao usando Python anterior na lista, incluindo ele mesmo. Por exemplo, esta figura mostra uma lista com dois ns, um dos quais refere-se a si mesmo:

Por conveno, listas so freqentemente impressas em braquetes com vrgulas entre os elementos, como em [1, 2, 3]. Como um exerccio, modifique imprimeLista para que ela gere uma sada neste formato.

17.4 Listas e Recorrncia


Se ns invocarmos imprimeLista nesta lista, ele natural expressar muitas operaes de listas utilizando ficar em lao para sempre. Se ns invocarmos mtodos recorrentes. Por exemplo, o seguinte um algoritmo imprimeDeTrasParaFrente, ele recorrer infinitamente. Este recorrente para imprimir uma lista de trs para frente. tipo de comportamento torna as listas infinitas difceis de se lidar. 1. Separe a lista em dois pedaos: o primeiro n (chamado a cabea); e o resto (chamado o rabo). A despeito disto, elas ocasionalmente so teis. Por exemplo, podemos representar um nmero como uma lista 2. Imprima o rabo de trs para frente. de dgitos e usar uma lista infinita para representar uma frao repetente. 3. Imprima a cabea. Mesmo assim, problemtico que no possamos provar que imprimeLista e imprimeDeTrasParaFrente terminem. O melhor que podemos fazer a afirmao hipottica, "Se a lista no contm laos, ento este mtodo terminar." Este tipo de hiptese chamado uma prcondio. Ele impe uma limitao sobre um dos parmetros Tudo o que precisamos so um caso base e um e descreve o comportamento do mtodo se a limitao modo de provar que para qualquer lista, ns iremos, ao final, satisfeita. Voc ver mais exemplos em breve. chegar no caso base. Dada a definio recorrente de uma lista, um caso base natural a lista vazia, representada por None: Logicamente, o Passo 2, a chamada recorrente, assume que ns temos um modo de imprimir a lista de trs para frente. Mas se ns assumimos que a chamada recorrente funciona -- o passo de f -- ento podemos nos convencer de que o algoritmo funciona. def imprimeDeTrasParaFrente(lista): if lista == None : return cabeca = lista rabo = lista.proximo imprimeDeTrasParaFrente(rabo) print cabeca, A primeira linha trata o caso base fazendo nada. As prximas duas linhas dividem a lista em cabeca e rabo. As duas ltimas linhas imprimem a lista. A vrgula no final da ltima linha impede o Python de imprimir uma nova linha aps cada n.

17.6 O Teorema da Ambigidade Fundamental


Uma parte de imprimeDeTrasParaFrente pode ter gerado surpresa: cabeca = lista rabo = lista.proximo Aps a primeira atribuio, cabeca e lista tm o mesmo tipo e o mesmo valor. Ento por que ns criamos uma nova varivel?

A razo que as duas variveis tm diferentes papis. Quando pensamos em cabeca, pensamos como uma referncia a um nico n, e quando pensamos em lista o Ns invocamos este mtodo como invocamos o fazemos como uma referncia ao primeiro n da lista. Estes imprimeLista: "papis" no so parte do programa; eles esto na mente do programador. >>> imprimeDeTrasParaFrente(no1) 3 2 1 Em geral no podemos dizer olhando para o programa qual o papel que uma varivel tem. Esta O resultado a lista de trs para frente. ambigidade pode ser til, mas tambm pode tornar os Voc pode se perguntar por qu imprimeLista e programas difceis de serem lidos. Usamos freqentemente imprimeDeTrasParaFrente so funes e no mtodos da nomes de variveis como no e lista para documentar como classe No. A razo que ns queremos usar None para pretendemos usar uma varivel e algumas vezes criamos representa a lista vazia e no legal invocar um mtodo sobre variveis adicionais para remover a ambigidade. None. Esta limitao torna complicado escrever cdigo de Poderamos ter escrito manipulao de lista em estilo orientado a objeto limpo. imprimeDeTrasParaFrente sem cabeca e rabo, que a tornaria Podemos provar que imprimeDeTrasParaFrente mais concisa mas possivelmente menos clara: sempre termina? Em outras palavras, ir ela sempre atingir o caso base? De fato, a resposta no. Algumas listas faro este def imprimeDeTrasParaFrente(lista): mtodo falhar. if lista == None : return imprimeDeTrasParaFrente(lista.proximo) print lista, 17.5 Listas Infinitas Olhando para as duas chamadas de funo, No h nada que impea um n de referenciar de volta um n temos que lembrar que imprimeDeTrasParaFrente trata seu argumento como uma coleo e print trata seu argumento GNU Free Documentation License #85

Como pensar como um cientista da Computao usando Python def imprimeDeTrasParaFrenteLegal(lista): print "[", O teorema da ambigidade fundamental descreve a ambigidade que inerente referncia a um n: if lista != None : cabeca = lista Uma varivel que refere a um n pode tratar o n como um objeto nico ou como o primeiro em uma lista de rabo = lista.proximo ns. imprimeDeTrasParaFrente(rabo) print cabeca, print "]", 17.7 Modificando Listas Novamente, uma boa idia verificar mtodos Existem duas maneiras de se modificar uma lista ligada. como este para ver se eles funcionam com casos especiais Obviamente, podemos modificar a carga dos ns, mas as como uma lista vazia ou um singleton. operaes mais interessantes so aquelas que adicionam, Quando usamos este mtodo em algum lugar no removem ou reordenam os ns. programa, invocamos imprimeDeTrasParaFrenteLegal Como um exemplo, vamos escrever um mtodo diretamente, e ele invoca imprimeDeTrasParaFrente por ns. que remove o segundo n na lista e retorna uma referncia ao Neste sentido, imprimeDeTrasParaFrenteLegal atua como um envoltrio, e usa imprimeDeTrasParaFrente como um n removido: ajudador. def removeSegundo(lista): if lista == None : return 17.9 A Classe ListaLigada primeiro = lista segundo = lista.proximo Existem alguns problemas sutis com o modo que # faz o primeiro no referir ao terceiro implementamos listas. Em um inverso de causa e efeito, proporemos uma implementao alternativa primeiro e ento primeiro.proximo = segundo.proximo explicaremos qual problema ela resolve. # separa o segundo no do resto da lista como um objeto nico. segundo.proximo = None Primeiro, criaremos uma nova classe chamada ListaLigada. Seus atributos so um inteiro que contm o return segundo Novamente, estamos usando variveis comprimento da lista e uma referncia para o primeiro n. temporrias para tornar o cdigo mais fcil de ser lido. Aqui Objetos do tipo ListaLigada servem como cabos (handles) para se manipular listas de objetos No: est como usar este mtodo: class ListaLigada: >>> imprimeLista(no1) def __init__(self): 1 2 3 self.comprimento = 0 >>> removido = removeSegundo(no1) self.cabeca = None >>> imprimeLista(removido) Uma coisa legal acerca da classe ListaLigada 2 que ela prov um lugar natural para se colocar funes >>> imprimeLista(no1) envoltrias como imprimeDeTrasParaFrenteLegal, que podemos transformar em um mtodo da classe ListaLigada: 1 3 Este diagrama de estado mostra o efeito da class ListaLigada: operao: ... def imprimeDeTrasParaFrente(self): print "[", if self.cabeca != None : self.cabeca.imprimeDeTrasParaFrente() print "]", O que acontece se voc invocar este mtodo e passar uma lista com somente um elemento (um singleton)? O que acontece se voc passar a lista vazia como um argumento? class No: ... Existe uma pr-condio para este mtodo? Se houver, corrija o mtodo para tratar uma violao da pr-condio de modo def imprimeDeTrasParaFrente(self): razovel. if self.proximo != None: rabo = self.proximo rabo.imprimeDeTrasParaFrente() 17.8 Envoltrios e Ajudadores print self.carga, Freqentemente til dividir uma operao de lista em dois Apenas para tornar as coisas confusas, mudamos mtodos. Por exemplo, para imprimir uma lista de trs para o nome de imprimeDeTrasParaFrenteLegal. Agora existem frente no formato convencional de lista [3, 2, 1], podemos usar dois mtodos chamados imprimeDeTrasParaFrente: um na o mtodo imprimeDeTrasParaFrente para imprimir 3, 2, mas classe No (o ajudador); e um na classe ListaLigada``(o queremos um metodo separado para imprimir os braquetes e o envoltrio). Quano o envoltrio invoca primeiro n. Vamos cham-lo de ``self.cabeca.imprimeDeTrasParaFrente, ele est invocando o imprimeDeTrasParaFrenteLegal: ajudador, porque self.cabeca um objeto No. GNU Free Documentation License #86

Como pensar como um cientista da Computao usando Python Outro benefcio da classe ListaLigada que ela 17.11 Glossrio torna mais fcil adicionar e remover o primeiro elemento de uma lista. Por exemplo, adicionaPrimeiro um mtodo para referncia referncia embutida Uma ListaLigada; ele toma um item de carga como argumento e o (embedded reference) armazenada/associada em/a um coloca no incio da lista: atributo de um objeto. class ListaLigada: lista ligada (linked Uma estrutura de dados que ... list) implementa uma coleo usando def adicionaPrimeiro(self, carga): uma sequncia de ns ligados. no = No(carga) n ou nodo (node) Um elemento de uma lista, no.proximo = self.cabeca usualmente implementado como um objeto que contm uma referncia self.cabeca = no para outro objeto do mesmo tipo. self.comprimento = self.comprimento + 1 Como de costume, voc deve conferir cdigos carga (cargo) Um item de dado contido em um n. como este para ver se eles tratam os casos especiais. Por ligao (link) Uma referncia embutida usada para exemplo, o que acontece se a lista est inicialmente vazia? ligar/conectar um objeto a outro.

17.10 Invariantes
Algumas listas so "bem formadas"; outras no o so. Por exemplo, se uma lista contm um lao, ela far muitos de nossos mtodos falharem, de modo que podemos querer requerer que listas no contenham laos. Outro requerimento que o valor de comprimento no objeto ListaLigada seja igual ao nmero real de ns da lista. Requerimentos como estes so chamados de invariantes porque, idealmente, eles deveriam ser verdade para cada objeto o tempo todo. Especificar invariantes para objetos um prtica de programao til porque torna mais fcil provar a correo do cdigo, verificar a integridade das estruturas de dados e detectar erros. Uma coisa que algumas vezes confusa acerca de invariantes que existem momentos em que eles so violados. Por exemplo, no meio de adicionaPrimeiro, aps termos adicionado o n mas antes de termos incrementado comprimento, o invariante violado. Este tipo de violao aceitvel; de fato, freqentemente impossvel modificar um objeto sem violar um invariante por, no mnimo, um pequeno instante. Normalmente, requeremos que cada mtodo que viola um invariante deve restaurar este invariante. Se h qualquer aumento significativo de cdigo no qual o invariante violado, importante tornar isto claro nos comentrios, de modo que nenhuma operao seja feita que dependa daquele invariante.

pr-condio Uma assero que precisa/deve ser (precondition) verdadeira para que um mtodo trabalhe corretamante. teorema da ambigidade fundamental (fundamental ambiguity theorem) Uma referncia para um n de uma lista pode ser tratada como um objeto nico ou como o primeiro em uma lista de ns.

singleton (singleton) Uma lista ligada com somente um n. envoltrio (wrapper) Um mtodo que atua como um intermedirio (middleman) entre um chamador e um mtodo ajudador (helper), freqentemente tornando a invocao do mtodo mais fcil ou menos propensa a erros. ajudador (helper) Um mtodo que no invocado diretamente pelo chamador (caller) mas usado por outro mtodo para realizar parte de uma operao. invariante (invariant) Uma assero que deveria ser verdadeira sempre para um objeto (exceto talvez enquanto o objeto estiver sendo modificado).

GNU Free Documentation License #87

Captulo 18: Pilhas

18.1 Tipos abstratos de dados


Os tipos de dados que voc viu at agora so todos concretos, no sentido que ns especificamos completamente como eles so implementados. Por exemplo, a classe Card(XXX ver como foi traduzido) representa uma carta utilizando dois inteiros. Como discutimos no momento, esta no a nica maneira de representar uma carta; existem muitas implementaes alternativas. Um tipo abstrato de dado, ou TAD, especifica um conjunto de operaes (ou mtodos) e a semntica das operaes (o que elas fazem), mas no especifica a implementao das operaes. Isto o que o faz abstrato. Por que isto til?

operaes que definem uma pilha. A interface no exatamente o que se supe ser, mas podemos escrever um cdigo para traduzir do TAD Pilha para as operaes nativas. Este cdigo chamado uma implementao do TAD Pilha. Geralmente, uma implementaa um conjunto de mtodos que satisfazem os requisitos sintticos e semnticos de uma interface. Aqui est uma implementao do TAD Pilha que usa uma lista do Python: class Stack : def __init__(self) : self.items = [] def push(self, item) : self.items.apend(item) def pop(self) : return self.items.pop()

Simplifica a tarefa dde especificar um algoritmo se voc pode XXXdenotar(denote) as operaes que voc precisa sem ter que pensar, ao mesmo tempo, como as operaes so executadas. Uma vez que existem geralmente muitas maneiras de implementar um TAD, pode ser til escrever um algritmo que pode ser usado com qualquer das possveis implementaes.

def isEmpty(self) : return (self.items == []) Um objeto Stack contm um atributo chamado TADs bastante conhecidos, como o TAD Pilha deste items que uma lista de tens na pilha. O mtodo de captulo, j esto implementados em bibliotecas inicializao define items como uma lista vazia. padro, ento eles podem ser escritos uma vez e Para adicionar um novo tem na pilha, push o usado por muitos programadores. coloca em items. Para remover um tem da pilha, pop usa o As operaes em TADs provm uma linguagem de mtodo de lista homnimo para remover e retornar um ltimo alto nvel comum para especificar e falar sobre tem da lista. algoritmos. Finalmente, para verificar se a pilha est vazia, Quando falamos sobre TADs, geralmente isEmpty comprara items a uma lista vazia. distinguimos o cdigo que usa o TAD, chamado cliente, do Uma implementao como esta, na qual os cdigo que implementa o TAD, chamado cdigo fornecedor. mtodos consistem de simples invocaes de mtodos existentes, chamado revestimento. Na vida real, revestimento uma fina camada de madeira de boa qualidade 18.2 O TAD Pilha usado em XXX*furniture-making* para esconder madeira de menor qualidade embaixo. Cientistas da Computao usam Neste captulo, iremos olhar um TAD comum, a pilha. Uma esta metfora para descrever um pequeno trecho de cdigo que pilha uma coleo, ou seja, uma estrutura de dados que esconde os detalhes de uma implementao e fornece uma contei mltiplos elementos. Outras colees que vimos interface mais simples, ou mais padronizada. incluem dicionrios e listas. Um TAd definido pelo conjunto de operaes que podem ser executadas nele, que chamado interface. A interface para uma pilha consiste nestas operaes: __init__ : Inicializa uma nova pilha vazia. push : Adiciona um novo item na pilha pop : Remove um tem da pilha e o retorna, O tem que retornadao sempre o ltimo adicionado.

18.4 Empilhando e desempilhando


Uma pilha uma estrutura de dados genrica, o que significa que podemos adicionar qualquer tipo de tem a ela. O exemplo a seguir empilha dois inteiros e uma XXXstring na pilha: >>> >>> >>> >>>

s = Stack() s.push(54) isEmpty : Verifica se a pilha est vazia. s.push(45) Uma s vezes chamada uma estrutura de dados s.push("+") "last in, first out" ou LIFO, porque o ltimo tem adicionad o Podemos usar isEmpty e pop para remover e primeiro a ser removido. imprimir todos os tens da pilha:

18.3 Implementando pilhas com listas de Python


As operaes de lista que Python oferecem so similares s

while not s.isEmpty() : priint s.pop() A sada + 45 54. Em outras palavras, usamos a

Como pensar como um cientista da Computao usando Python pilha para imprimir os tens ao contrrio! Sabidamente, este Uma expresso regular uma maneira de especificar um no o formato padro de imprimir uma lista, mas, usando conjunto de strings. Por exemplo, [A-z] o conjunto de todas uma pilha, foi notavelmente fcil de fazer. as letras e [0-9] o conjunto de todos os dgitos. O operador ^nega um conunto, ento [^0-9] o conjunto de tudo o que Voc deve comparar este trecho de cdigo com a no nmero, que exatamente o que queremos para dividir implementao de printBackward na seo 17.4. Existe um expresses ps-fixas. paralelo natura entre a verso recursiva de printBackward e o algoritmo de pilha aqui. A diferen que printBackward usa a >>> import re pilha de execuo para XXXmanter a trilha(keep track) dos >>> re.split ("[^0-9]", "123+456*/") ns enquanto percorre a lista, e ento imprime-a no retorno da ['123', '+', '456', '*', '', '/', ' '] recurso. o algoritmo de pilha faz a mesma coisa, exceto que Note que a ordem dos argumentos diferente de usa o objeto Stack ao invs da pilha de execuo. string.split, o delimitador vem antes da string.

18.5 Usando uma pilha para avaliar expresses ps- e os operadores * e /. Tambm inclui duas strings vazias que so inseridas depois dos operadores. fixas
Em muitas linguagens de programao, expresses matemticas so executadas com o poerador entre os roid operandos, como em 1 + 2. Este formato chamado notao infixa. Uma alternativa usada por algumas calculadoras chamada notao ps-fixa. Em notao ps-fixa, o operador segue os operandos, como em 1 2 +.

A lista resultante inclui os operandos 123 e 456,

18.7 Avaliando em ps-fixo.


Para avaliar uma expresso ps-fixa, usaremos o parser da seo anterior e o algoritmo da seo anterior a ela. Para manter as coisas simples, comearemos com um avaliador que implementa somente os operadores + e .

A razo pela qual a notao ps-fixa til algumas vezes que existe uma maneira natural de avaliar def evalPostfix (expr) : import re uma expresso ps-fixa usando uma pilha: tokenList = re.split ("([^0-9])", expr) comeando no incio da expresso, peque um termo stack = Stack() (operador ou operando) de cada vez. for token in tokenList Se o termo um operando, empilhe-o if token == '' or token = ' ' : Se o termo um operador, desempilhe dois continue operandos, execute a operao neles, e empilhe o if token == '+' : resultado. sum = stack.pop() + stack.pop() Quando chegar ao fim da expresso, deve existir stack.push(sum) exatamente um operando sobrando na pilha. Este if token == '*' : operando o resultado. product = stack.pop() * stack.pop() Como um exerccio, aplique este algoritmo stack.push(product) expresso 1 2 + 3 * . else: Este exemplo demonstra uma das vantagens da stack.push(int(token)) notao ps-fixa - no necessrio usar parnteses para controlar a ordem das operaes. Para ter o mesmo resultado return stack.pop() em notao infixa, deveramos escrever (1 + 2) * 3. A primeira condio cuida de espaos e strings vazias. As duas prximas condies manipulam os operadores. Como um exerccio, escreva a expresso psNs assumimos, agora que qualquer coisa um operador. fixa que equivalente a 1 + 2 * 3. claro, seria melhor chegar por entrada errnea e enviar uma mensagem de erro, mas faremos isto depois.

18.6 Anlise sinttica


(56 + 47) * 2 Para implementar o algoritmo anterior, necessitamos estar prontos para percorrer uma string e quebr-la em operandos e operadores. Este process um exemplo de parsing, e o resultado - os pedaos da string - so chamados tokens. Voc deve lembrar estas palavras do captulo 1.

Vamos test-lo avaliando a forma ps-fixa de >>> print evalPostfix("56 47 + 2 *") 206

Python fornece um mtodo split nos mdulos 18.8 Clientes de fornecedores. string e re (expresses regulares). A funo string.split separa uma string numa lista usando um nico caracter como Um dos objetivos de um TAD separar os interesses do fornecedor, quem escreve o cdigo que implementa o TAD, e delimitador. Por exemplo: o cliente, que usa o TAD. O fornecedor tem que se preocupar apenas se a implementao est correta - de acordo com a >>> import string especificao do TAD - e no como ele ser usado. >>> string.split ("Now is the time", " ") ['Now', 'is', 'the', 'time'] Inversamente, o cliente assume que a Neste caso, o delimitador o caracter de espao, implementao do TAD est correta e no se preocupa com os detalhes. Quando voc est usando um tipo nativo do Python, ento a string dividida a cada espao. tem o luxo de pensar exclusivamente como um cliente. A funo re.split mais poderosa, permitindo claro, quanto voc implementa um TAD, voc nos fornecer uma expreso regular ao invs de um delimitador. tambm tem que escrever cdigo cliente para test-lo. Neste GNU Free Documentation License #89

Como pensar como um cientista da Computao usando Python caso, voc faz os dois papis, o que pode ser confuso. Voc deve fazer algum esfor para manter a trilha do papel que est fazendo a cada momento.

18.9 Glossrio
tipo abstrato de dados (TAD) (abstract data type(ADT)): Um tipo de dado(geralmente uma coleo de objetos) que definidopor um conjunto de operaes, que podem ser implementadas de vrias maneiras.

interface o conjunto de operaes que definem um (interface): TDA. implementa Cdigo que satisfaz(preenche?) os requisitos o sintticos e semnticos de uma interface. (implementati on): cliente Um programa (ou o programador que o (client): escreveu) que faz utilizao de um TDA. fornecedor Cdigo (ou o programador que o escreveu) (provider): que implementa um TDA. revestimento Definio de classe que implementa um (veneer): TDA com definies de mtodos que so chamadas a outros mtodos, s vezes com pequenas modificaes. A lmina faz um trabalho insignificante, mas melhora ou padroniza a interface dada ao cliente. estrutura de Tipo de estrutura de dados que contem data dados de um tipo qualquer(tipo genrico). genrica (generic data structure): infixa (infix): Notao matemtica em que os operadores se situam entre os operandos. ps-fixa Notao matemtica em que os operadores (postfix): se situam aps os operandos. parse (parse): Ler um conjunto de caracteres(string de caracteres) ou tokens(smbolos atmicos) e analisar sua estrutura gramatical. token (token): Conjunto de caracteres que so tratados como uma unidade atmica para fins de anlise gramatical, como as palavras na linguagem natural. delimitador Um caracter que utilizado para separar os atmicos(tokens), como a (delimiter): smbolos pontuao na linguagem natural.

GNU Free Documentation License #90

Captulo 19: Filas

Este captulo apresenta dois TDAs: Fila e Fila por Prioridade. Na nossa vida diria, fila um alinhamento de consumidores aguardando algum tipo de servio. Na maioria dos casos, o primeiro da fila o primeiro a ser atendido. Mas h excees. No aeroporto, passageiros cujo vo vai decolar logo, s vezes so chamados primeiro ao balco do check-in, mesmo que estejam no meio da fila. No supermercado, comum na fila do caixa algum deixar passar na frente uma pessoa que chega fila s com um ou dois produtos na mo.

A regra que determina quem o prximo da fila chama-se poltica de enfileiramento. A poltica de def remove(self): enfileiramento mais simples chama-se FIFO, sigla de first-infirst-out: primeiro a entrar, primeiro a sair. A poltica de cargo = self.head.cargo enfileiramento mais geral o enfileiramento por prioridade, self.head = self.head.next em que se atribui uma prioridade a cada pessoa da fila e a que self.length = self.length - 1 tiver maior prioridade vai primeiro, independente da sua return cargo ordem de chegada. Dizemos que essa a poltica mais geral de todas, porque a prioridade pode ser baseada em qualquer Os mtodos isEmpty e remove so idnticos aos coisa: hora de partida do vo; quantos produtos a pessoa vai mtodos isEmpty e removeFirst de LinkedList. O mtodo passar pelo caixa; o grau de prestgio da pessoa. claro que insert novo e um pouco mais complicado. nem todas as polticas de enfileiramento so "justas", mas o Queremos inserir novos itens no fim da lista. Se que justo depende do ponto de vista. a fila estiver vazia, basta fazer head apontar ao novo n. Se O TDA Fila e o TDA Fila por Prioridade tm o no, percorremos a lista at o ltimo n e l penduramos o mesmo conjunto de operaes. A diferena est na semntica novo n. possvel identificar o ltimo n porque o seu das operaes: a fila usa a poltica FIFO; e a fila por atributo next None. prioridade (como o prprio nome sugere) usa a poltica de Existem duas invariantes para um objeto Fila enfileiramento por prioridade. bem formado: o atributo length deve ser o nmero de ns na fila, e o ltimo n deve ter seu atributo next igual a None. Estude o mtodo at ficar convencido de que ele preserva 19.1 Um TDA Fila ambas invariantes. O TDA Fila definido pelas seguintes operaes: __init__ Inicializar uma nova fila vazia. insert Adicionar um novo item fila.

self.head = node else: # find the last node in the list last = self.head while last.next: last = last.next # append the new node last.next = node self.length = self.length + 1

19.3 Caractersticas de performance

Quando invocamos um mtodo, normalmente no estamos remove Remover e retornar um item da fila. O item preocupados com os detalhes da sua implementao. Porm, h um certo "detalhe" que pode ser bom conhecer: as retornado o que foi adicionado primeiro. caractersticas de performance do mtodo. Quanto tempo leva, isEmpty Checar se a fila est vazia. e como o tempo de execuo muda medida em que aumenta o nmero de itens da coleo? Primeiro, olhe para remove. No h laos ou chamadas de funo aqui, o que sugere que o tempo de execuo desse mtodo sempre o mesmo, toda vez. Um A primeira implementao que vamos ver de um TDA Fila mtodo assim chamado de operao de tempo constante. Na chama-se fila encadeada porque feita de objetos Ns verdade, o mtodo pode ser ligeiramente mais rpido quando a encadeados. A definio da classe a seguinte: lista est vazia, uma vez que ele pula o corpo da condicional, mas essa diferena no significativa. XXX: o condicional s class Queue: aparece na re-implementao do mtodo na classe def __init__(self): ImprovedQueue, p.200; essa inconsistncia pode ser conferida self.length = 0 tambm nas pginas 198-199 do livro original (PDF e impresso). self.head = None

19.2 Fila encadeada

def isEmpty(self): return (self.length == 0) def insert(self, cargo): node = Node(cargo) node.next = None if self.head == None: # if list is empty the new node goes first

A performance de insert muito diferente. No caso geral, temos de percorrer a lista para achar o ltimo elemento. Este percurso leva um tempo proporcional extenso da lista. Uma vez que o tempo de execuo uma funo linear da extenso, dizemos que este mtodo opera em tempo linear. Isso bem ruim, se comparado com o tempo constante.

19.4 Fila encadeada aprimorada

Como pensar como um cientista da Computao usando Python vantagem que o objetivo foi atingido -- tanto insert quanto remove` so operaes de tempo constante.

Queremos uma implementao do TDA Fila que possa realizar Como exerccio, escreva uma implementao todas as operaes em tempo constante. Uma maneira de fazer do TDA Fila usando uma lista nativa do Python. Compare a isso modificar a classe Fila, de modo que ela mantenha a performance dessa implementao com a de ImprovedQueue, referncia tanto ao primeiro quanto ao ltimo n, como mostra para filas de diversos comprimentos. a figura:

19.5 Fila por prioridade


O TDA Fila por Prioridade tem a mesma interface que o TDA Fila, mas semntica diferente. Mais uma vez, a interface a seguinte: A implementao de ImprovedQueue tem essa cara: class ImprovedQueue: def __init__(self): self.length = 0 self.head = None self.last = None __init__ Inicializar uma nova fila vazia. insert Adicionar um novo item fila. remove Remover e retornar um item da fila. O item retornado aquele que tiver maior prioridade. isEmpty Checar se a fila est vazia. A diferena semntica que o item removido da fila no necessariamente o que foi includo primeiro e, sim, o que tem maior prioridade. Que prioridades so essas e como elas se comparam umas com as outras no especificado pela implementao Fila por Prioridade. Isso depende de quais itens esto na fila.

def isEmpty(self): return (self.length == 0) At agora, a nica mudana o atributo last. Ele Por exemplo, se os itens da fila tiverem nome, usado nos mtodos insert e remove: podemos escolh-los por ordem alfabtica. Se for a pontuao de um jogo de boliche, podemos ir da maior para a menor, mas class ImprovedQueue: se for pontuao de golfe, teramos que ir da menor para a # ... maior. Se possvel comparar os itens da fila, possvel achar e remover o que tem maior prioridade. Essa implementao da def insert(self, cargo): Fila por Prioridade tem como atributo uma lista Python node = Node(cargo) chamada items, que contm os itens da fila. node.next = None class PriorityQueue: if self.length == 0: def __init__(self): #if list is empty, the new node is head & self.items = [] last self.head = self.last = node def isEmpty(self): else: return self.items == [] # find the last node last = self.last def insert(self, item): # append the new node self.items.append(item) last.next = node O mtodo de inicializao, isEmpty, e insert so self.last = node apenas uma fachada para operaes bsicas de lista. O nico self.length = self.length + 1 mtodo interessante remove: Uma vez que last no perde de vista o ultimo n, no necessrio busc-lo. Como resultado, esse mtodo tem class PriorityQueue: tempo constante. # ... def remove(self): Mas essa rapidez tem preo. preciso adicionar um caso especial a remove, para configurar last para None maxi = 0 quando o ultimo n removido: for i in range(1,len(self.items)): if self.items[i] > self.items[maxi]: class ImprovedQueue: maxi = i #... item = self.items[maxi] def remove(self): self.items[maxi:maxi+1] = [] cargo = self.head.cargo return item self.head = self.head.next No incio de cada iterao, maxi armazena o self.length = self.length - 1 ndice do maior item (a prioridade mais alta de todas) que if self.length == 0: vimos at agora. A cada volta do lao, o programa compara o self.last = None i-simo item ao campeo. Se o novo item for maior, maxi return cargo recebe o valor de i. Essa implementao mais complicada que a Quando o comando for se completa, maxi o primeira, e mais difcil de se demonstrar que est correta. A ndice do maior item. Esse item removido da lista e GNU Free Documentation License #92

Como pensar como um cientista da Computao usando Python >>> tiger = Golfer("Tiger Woods", 61) >>> phil = Golfer("Phil Mickelson", 72) Vamos testar a implementao: >>> hal = Golfer("Hal Sutton", 69) >>> q = PriorityQueue() >>> >>> q.insert(11) >>> pq = PriorityQueue() >>> q.insert(12) >>> pq.insert(tiger) >>> q.insert(14) >>> pq.insert(phil) >>> q.insert(13) >>> pq.insert(hal) >>> while not q.isEmpty(): print q.remove() >>> while not pq.isEmpty(): print pq.remove() 14 Tiger Woods : 61 13 Hal Sutton : 69 12 Phil Mickelson : 72 11 Como exerccio, escreva uma implementao do Se a fila contm nmeros ou strings simples, TDA Fila por Prioridade usando uma lista encadeada. eles so removidas em ordem numrica decrescente ou Mantenha a lista em ordem para que a remoo seja uma alfabtica invertida (de Z at A). Pyhton consegue achar o operao de tempo constante. Compare a performance dessa maior inteiro ou string porque consegue compar-los usando implementao com a implementao usando uma lista nativa os operadores de comparao nativos. do Python. Se a fila contm objetos de outro tipo, os objetos tm que prover um mtodo __cmp__. Quando remove usa o operador > para comparar dois itens, o mtodo __cmp__ de 19.7 Glossrio um dos itens invocado, recebendo o segundo item como argumento. Desde que o mtodo __cmp__ funcione de forma fila (queue) Conjunto de objetos ordenados esperando consistente, a Fila por Prioridade vai funcionar. algum tipo de servio. retornado.

19.6 A classe Golfer


Como exemplo de um objeto com uma definio no-usual de prioridade, vamos implementar uma classe chamada Golfer (golfista), que mantm registro dos nomes e da pontuao de golfistas. Como sempre, comeamos definindo __init__ e __str__: class Golfer: def __init__(self, name, score): self.name = name self.score= score def __str__(self): return "%-16s: %d" % (self.name, self.score) O mtodo __str__ usa o operador de formato para colocar nomes e pontuaes em colunas arrumadas. Em seguida, definimos uma verso de __cmp__, ma qual a pontuao mais baixa fica com prioridade mxima. Como sempre, __cmp__ retorna 1 se self "maior que" other, -1 se self "menor que" other, e 0 se eles so iguais. class Golfer: #... def __cmp__(self, other): if self.score < other.score: return 1 # less is more if self.score > other.score: return -1 return 0 Agora estamos prontos para testar a fila por prioridade com a classe Golfer:

Fila (Queue) TAD (Tipo Abstrato de Dado) que realiza operaes comuns de acontecerem em uma fila. poltica de As regras que determinam qual membro enfileiramento de uma fila o prximo a ser removido. (queueing policy) FIFO "First In, First Out," (primeiro a entrar, primeiro a sair) poltica de enfileiramento em que o primeiro membro a chegar o primeiro a ser removido. fila por Poltica de enfileiramento em que cada prioridade membro tem uma prioridade, determinada (priority queue) por fatores externos. O membro com a maior prioridade o primeiro a ser removido. Fila por TAD que define as operaes comuns de Prioridade acontecerem em uma fila por prioridade. (Priority Queue) fila encadeada Implementao de uma fila usando uma (linked queue) lista encadeada. tempo constante Operao cujo tempo de execuo no (constant time) depende do tamanho da estrutura de dados. tempo linear Operao cujo tempo de execuo uma (linear time) funo linear do tamanho da estrutura de dados.

GNU Free Documentation License #93

Captulo 20: rvores

Como listas ligadas, rvores so constitudas de clulas. Uma espcie comum de rvores a rvore binria, em que cada clula contm referncias a duas outras clulas (possivelmente nulas). Tais referncias so chamadas de subrvore esquerda e direita. Como as clulas de listas ligadas, as clulas de rvores tambm contm uma carga. Um diagrama de estados para uma rvore pode aparecer assim:

montar uma lista ligada. cada invocao do construtor cria uma clula. class Tree : def __init__(self, cargo, left=None, right=None) : self.cargo = cargo self.left = left self.right = right def __str__(self) : return str(self.cargo) A carga pode ser de qualquer tipo, mas os parmetros left e right devem ser clulas. left e right so opcionais; o valor default None. Para imprimir uma clula, imprimimos apenas a sua carga. Uma forma de construir uma rvore de baixo para cima. Aloque os filhos primeiro: left = Tree(2) right = Tree(3) Em seguida crie a clula pai e ligue ela a seus filhos:

Para evitar a sobrecarga da figura, ns tree = Tree(1, left, right); frequentemente omitimos os Nones. Podemos escrever este cdigo mais O topo da rvore (a clula qual o apontador concisamente encaixando as invocaes do construtor: tree se refere) chamada de raiz. Seguindo a metfora das rvores, as outras clulas so chamadas de galhos e as clulas >>> tree = Tree(1, Tree(2), Tree(3)) De qualquer forma, o resultado a rvore que nas pontas contendo as referncias vazia so chamadas de folhas. Pode parecer estranho que desenhamos a figura com a apareceu no incio do captulo. raiz em cima e as folhas em baixo, mas isto nem ser a coisa mais estranha. Para piorar as coisas, cientistas da computao misturam outra metfora alm da metfora biolgica - a rvore genealgica. Uma clula superior pode ser chamada de pai e Cada vez que Voc v uma nova estrutura de dados, sua as clulas a que ela se refere so chamadas de seus filhos. primeira pergunta deveria ser "Como eu percorro esta estrutura?" A forma mais natural de percorrer uma rvore Clulas com o mesmo pai so chamadas de irmos. fazer o percurso recursivamente. Por exemplo, se a rvore Finalmente, existe tambm o vocabulrio contm inteiros na carga, a funo abaixo retorna a soma das geomtrico para falar de rvores. J mencionamos esquerda e cargas: direita, mas existem tambm as direes "para cima" (na direo da raiz) e "para baixo" (na direo dos filhos/folhas). def total(tree) : Ainda nesta terminologia, todas as clulas situadas mesma if tree == None : return 0 distncia da raiz constituem um nvel da rvore. return total(tree.left) + total(tree.right) + Provavelmente no precisamos de trs metforas tree.cargo para falar de rvores, mas a elas esto. O caso base a rvore vazia, que no contm nenhuma carga, logo a soma das cargas 0. O passo recursivo Como listas ligadas, rvores so estruturas de faz duas chamadas recursivas para achar a soma das cargas das dados recursivas j que elas so definidas recursivamente: subrvores dos filhos. Ao finalizar a chamada recursiva, adicionamos a carga do pai e devolvemos o valor total. Uma rvore

20.2 Percorrendo rvores

a rvore vazia, representada por None, ou uma clula que contm uma referncia a um objeto (a carga da clula) e duas referncias a rvores.

20.3 rvores de expresses

Uma rvore uma forma natural para representar a estrutura de uma expresso. Ao contrrio de outras notaes, a rvore pode representar a computao de forma no ambgua. Por 20.1 Construindo rvores exemplo, a expresso infixa 1 + 2 * 3 ambgua, a menos que O processo de montar uma rvore similar ao processo de saibamos que a multiplicao feita antes da adio.

Como pensar como um cientista da Computao usando Python A rvore de expresso seguinte representa a rvore numa ordem diferente, Voc produzir expresses numa mesma computao: notao diferente. Por exemplo, se Voc imprime subrvores primeiro e depois a raiz, Voc ter: def printTreePostorder(tree) : if tree == None : return printTreePostorder(tree.left) printTreePostorder(tree.right) print tree.cargo, O resultado, 1 2 3 * +, est na notao psfixa! Esta ordem de percurso chamada de psordem. Finalmente, para percorrer uma rvore em inordem, Voc imprime a subrvore esquerda, depois a raiz e depois a subrvore direita: def printTreeInorder(tree) : if tree == None : return printTreeInorder(tree.left) print tree.cargo, printTreeInorder(tree.right) As clulas de uma rvore de expresso podem ser operandos como 1 e 2 ou operaes como + e *. As clulas O resultado 1 + 2 * 3, que a expresso na contendo operandos so folhas; aquelas contendo operaes notao infixa. devem ter referncias aos seus operandos. (Todos os nossos Para sermos justos, devemos lembrar que operandos so binrios, significando que eles tem exatamente acabamos de omitir uma complicao importante. algumas dois operandos.) vezes quando escrevemos expresses na notao infixa Podemos construir rvores assim: devemos usar parntesis para prescrever a ordem das operaes. Ou seja, um percurso em inordem no suficiente >>> tree = Tree('+', Tree(1), Tree('*', Tree(2), para gerar a expresso infixa. Tree(3))) Ainda assim, com alguns aperfeioamentos, a Examinando a figura, no h dvida quanto rvore de expresso e os trs modos recursivos de percurso ordem das operaes; a multiplicao feita primeiro para resultam em algoritmos para transformar expresses de uma calcular o segundo operando da adio. notao para outra. rvores de expresso tem muitos usos. O Como um exerccio, modifique exemplo neste captulo usa rvores para traduzir expresses `printTreeInorder` de modo que ele coloque parntesis em para as notaes psfixa, prefixa e infixa. rvores similares volta de cada operador e par de operandos. A sada correta e so usadas em compiladores para analisar sintaticamente, no ambgua? Os parntesis so sempre necessrios? otimizar e traduzir programas. Se percorrermos uma rvore em inordem e acompanharmos em qual nvel na rvore estamos, podemos 20.4 Percurso de rvores gerar uma representao grfica da rvore: Podemos percorrer uma rvore de expresso e imprimir o seu def printTreeIndented(tree, level=0) : if tree == None : return contedo como segue: printTreeIndented(tree.right, level+1) def printTree(tree) : print ' '*level + str(tree.cargo) if tree == None : return printTreeIndented(tree.left, level+1) print tree.cargo, O parmetro level registra aonde estamos na printTree(tree.left) rvore. Por 'default', o nvel inicialmente zero. A cada chamada recursiva repassamos level+1 porque o nvel do filho printTree(tree.right) Em outras palavras, para imprimir uma rvore, sempre um a mais do que o nvel do pai. Cada item imprima primeiro o contedo da raiz, em seguida imprima indentado dois espaos por nvel. Para o nosso exemplo toda a subrvore esquerda e finalmente imprima toda a obtemos: subrvore direita. Esta forma de percorrer uma rvore chamada de prordem, porque o contedo da raiz aparece >>> printTreeIndented(tree) 3 antes dos contedos dos filhos. Para o exemplo anterior, a sada : * 2 >>> tree = Tree('+', Tree(1), Tree('*', Tree(2), + Tree(3))) 1 >>> printTree(tree) Se Voc deitar a sada acima Voc enxerga uma + 1 * 2 3 verso simplificada da figura original. Esta notao diferente tanto da notao psfixa quanto da infixa; uma notao chamada de prefixa, em que os operadores aparecem antes dos seus operandos. Voc pode suspeitar que se Voc percorre a GNU Free Documentation License #95

Como pensar como um cientista da Computao usando Python >>> tokenList = [9, 11, 'end'] >>> x = getNumber(tokenList) Nesta seo analisamos expresses infixas e construmos as >>> printTreePostorder(x) rvores de express correspondentes. Por exemplo, para a 9 expresso (3+7)*9 resultar a seguinte rvore: >>> print tokenList [11, 'end'] Em seguida precisaremos da funo getProduct, que constri uma rvore de expresso para produtos. Os dois operandos de um produto simples so nmeros, como em 3 * 7.

20.5 Construindo uma rvore de expresso

Segue uma verso de getProduct que trata de produtos simples. def getProduct(tokenList) : a = getNumber(tokenList) if getToken(tokenList, '*') : b = getNumber(tokenList) return Tree('*', a, b) else : return a Supondo que a chamada de getNumber seja bem sucedida e devolva uma rvore de uma s clula atribumos o primeiro operando a `. Se o prximo caractere for *, vamos buscar o segundo nmero e construir a rvore com a, b e o operador.

Note que simplificamos o diagrama omitindo os nomes dos campos. O analisador que escreveremos aceitar expresses que incluam nmeros, parntesis e as operaes + e *. Vamos supor que a cadeia de entrada j foi tokenizada numa lista do Python. A lista de tokens para a expresso (3+7)*9 :

Se o caractere seguinte for qualquer outra coisa, ['(', 3, '+', 7, ')', '*', 9, 'end'] ento simplesmente devolvemos uma clula folha com a. O token final end prtico para prevenir que o Seguem dois exemplos: analisador tente buscar mais dados aps o trmino da lista. >>> tokenList = [9, '*', 11, 'end'] A ttulo de um exerccio, escreva uma funo >>> tree = getProduct(tokenList) que recebe uma expresso na forma de uma cadeia e devolve a >>> printTreePostorder(tree) lista de tokens. 9 11 * A primeira funo que escreveremos getToken que recebe como parmetros uma lista de tokens e um token esperado. Ela compara o token esperado com o o primeiro token da lista: se eles batem a funo remove o token da lista e >>> tokenList = [9, '+', 11, 'end'] devolve um valor verdadeiro, caso contrrio a funo devolve >>> tree = getProduct(tokenList) um valor falso: >>> printTreePostorder(tree) def getToken(tokenList, expected) : 9 O segundo exemplo sugere que ns if tokenList[0] == expected : consideramos um operando unitrio como uma espcie de tokenList[0:1] = [] # remove the token produto. Esta definio de "produto" talvez no seja intuitiva, return 1 mas ela ser til. else : Agora tratamos produtos compostos, como 3 * 5 return 0 * 13. Encaramos esta expresso como um produto de J que tokenList refere a um objeto mutvel, as produtos, mais precisamente como 3 * (5 * 13). A rvore alteraes feitas aqui so visveis para qualquer outra varivel resultante : que se refira ao mesmo objeto. A prxima funo, getNumber, trata de operandos. Se o primeiro token na tokenList for um nmero ento getNumber o remove da lista e devolve uma clula folha contendo o nmero; caso contrrio ele devolve None. def getNumber(tokenList) : x = tokenList[0] if type(x) != type(0) : return None del tokenList[0] return Tree(x, None, None) Antes de continuar, convm testar getNumber isoladamente. Atribumos uma lista de nmeros a tokenList, extramos o primeiro, imprimimos o resultado e imprimimos o que resta na lista de tokens:

GNU Free Documentation License #96

Como pensar como um cientista da Computao usando Python Com uma pequena alterao em getProduct, return x podemos acomodar produtos arbitrariamente longos: else : def getProduct(tokenList) : a = getNumber(tokenList) if getToken(tokenList, '*') : b = getProduct(tokenList) # this line changed return Tree('*', a, b) else : return a Em outras palavras, um produto pode ser um singleton ou uma rvore com * na raiz, que tem um nmero como filho esquerdo e um produto como filho direito. Este tipo de definio recursiva devia comear a ficar familiar. composto: x = tokenList[0] if type(x) != type(0) : return None tokenList[0:1] = [] # remove the token return Tree(x, None, None) # return a leaf with the number Testemos este cdigo com 9 * (11 + 5) * 7:

>>> tokenList = [9, '*', '(', 11, '+', 5, ')', '*', 7, 'end'] >>> tree = getSum(tokenList) >>> printTreePostorder(tree) 9 11 5 + 7 * * O analisador tratou os parntesis corretamente; a Testemos a nova verso com um produto adio feita antes da multiplicao. Na verso final do programa, seria uma boa idia dar a getNumber um nome mais descritivo do seu novo papel.

>>> tokenList = [2, '*', 3, '*', 5 , '*', 7, 'end'] >>> tree = getProduct(tokenList) >>> printTreePostorder(tree) 2 3 5 7 * * * A seguir adicionamos o tratamento de somas. De novo, usamos uma definio de "soma" que ligeiramente no intuitiva. Para ns, uma soma pode ser uma rvore com + na raiz, que tem um produto como filho esquerdo e uma soma como filho direito. Ou, uma soma pode ser simplesmente um produto. Se Voc est disposto a brincar com esta definio, ela tem uma propriedade interessante: podemos representar qualquer expresso (sem parntesis) como uma soma de produtos. Esta propriedade a base do nosso algoritmo de anlise sinttica.

20.6 Manipulando erros


Ao longo do analisador sinttico tnhamos suposto que as expresses (de entrada) so bem formadas. Por exemplo, quando atingimos o fim de uma subexpresso, supomos que o prximo caractere um facha parntesis. Caso haja um erro e o prximo caractere seja algo diferente, devemos tratar disto.

def getNumber(tokenList) : if getToken(tokenList, '(') : x = getSum(tokenList) if not getToken(tokenList, ')'): raise 'BadExpressionError', getSum tenta construir a rvore com um produto 'missing parenthesis' esquerda e uma soma direita. Mas, se ele no encontra uma return x +, ele simplesmente constri um produto. else : def getSum(tokenList) : # the rest of the function omitted a = getProduct(tokenList) O comando raise cria uma exceo; neste caso criamos um novo tipo de exceo, chamada de if getToken(tokenList, '+') : BadExpressionError. Se a funo que chamou getNumber, ou b = getSum(tokenList) uma das outras funes no traceback, manipular a exceo, return Tree('+', a, b) ento o programa pode continuar. caso contrrio Python vai else : imprimir uma mensagem de erro e terminar o processamento em seguida. return a Vamos testar o algoritmo com 9 * 11 + 5 * 7: A ttulo de exerccio, encontre outros locais nas funes criadas onde erros possam ocorrer e adiciona >>> tokenList = [9, '*', 11, '+', 5, '*', 7, comandos ``raise`` apropriados. Teste seu cdigo com 'end'] expresses mal formadas. >>> tree = getSum(tokenList) >>> printTreePostorder(tree) 20.7 A rvore dos animais 9 11 * 5 7 * + Quase terminamos, mas ainda temos que tratar Nesta seo, desenvolvemos um pequeno programa que usa dos parntesis. Em qualquer lugar numa expresso onde uma rvore para representar uma base de conhecimento. podemos ter um nmero, podemos tambm ter uma soma inteira envolvida entre parntesis. Precisamos, apenas, O programa interage com o usurio para criar modificar getNumber para que ela possa tratar de uma rvore de perguntas e de nomes de animais. Segue uma subexpresses: amostra da funcionalidade: def getNumber(tokenList) : if getToken(tokenList, '(') : x = getSum(tokenList) # get subexpression getToken(tokenList, ')') #eat closing parenthesis Are you thinking of an animal? y Is it a bird? n What is the animals name? dog What question would distinguish a dog from a bird? Can it fly

GNU Free Documentation License #97

Como pensar como um cientista da Computao usando Python If the animal were dog the answer would be? n # make a guess guess = tree.getCargo() prompt = "Is it a " + guess + "? " Are you thinking of an animal? y if yes(prompt) : Can it fly? n print "I rule!" Is it a dog? n continue What is the animals name? cat What question would distinguish a cat from a dog? # get new information Does it bark prompt = "What is the animal\'s name? " If the animal were cat the answer would be? n animal = raw_input(prompt) prompt = "What question would distinguish a Are you thinking of an animal? y %s from a %s? " Can it fly? n question = raw_input(prompt % (animal,guess)) Does it bark? y Is it a dog? y # add new information to the tree I rule! tree.setCargo(question) prompt = "If the animal were %s the answer Are you thinking of an animal? n Aqui est a rvore que este dilogo constri: would be? " if yes(prompt % animal) : tree.setLeft(Tree(guess)) tree.setRight(Tree(animal)) else : tree.setLeft(Tree(animal)) tree.setRight(Tree(guess)) A funo yes um auxiliar; ele imprime um prompt e em seguida solicita do usurio uma entrada. Se a resposta comear com y ou Y, a funo devolve um valor verdadeiro: def yes(ques) : No comeo de cada rodada, o programa parte do from string import lower topo da rvore e faz a primeira pergunta. Dependendo da ans = lower(raw_input(ques)) resposta, ele segue pelo filho esquerdo ou direito e continua return (ans[0:1] == 'y') at chegar numa folha. Neste ponto ele arrisca um palpite. Se A condio do lao externo 1`, que significa o palpite no for correto, ele pergunta ao usurio o nome de um novo animal e uma pergunta que distingue o palpite errado que ele continuar at a execuo de um comando break, caso do novo animal. A seguir, adiciona uma clula rvore o usurio no pense num animal. contendo a nova pergunta e o novo animal. O lao while interno caminha na rvore de cima para baixo, guiado pelas respostas do usurio. Aqui est o cdigo: def animal() : # start with a singleton root = Tree("bird") Quando uma nova clula adicionada rvore, a nova pergunta substitui a carga e os dois filhos so o novo animal e a carga original. Uma falha do programa que ao sair ele esquece tudo que lhe foi cuidadosamente ensinado!

# loop until the user quits A ttulo de exerccio, pense de vrias jeitos para while 1 : salvar a rvore do conhecimento acumulado num arquivo. print Implemente aquele que Voc pensa ser o mais fcil. if not yes("Are you thinking of an animal? ") : break # walk the tree tree = root while tree.getLeft() != None : prompt = tree.getCargo() + "? " if yes(prompt): tree = tree.getRight() else: tree = tree.getLeft()

20.8 Glossrio
rvore binria Uma rvore em que cada clula tem zero, (binary tree) um ou dois descendentes. raiz (root) A clula mais alta de uma rvore, a (nica) clula de uma rvore que no tem pai. folha (leaf) Uma clula mais baixa numa rvore; uma clula que no tem descendentes. pai (parent) A clula que aponta para uma clula dada. filho (child) Uma clula apontada por uma clula dada. irmos Clulas que tem o mesmo pai. GNU Free Documentation License #98

Como pensar como um cientista da Computao usando Python prefixa (prefix matemtica em que cada operador aparece notation) antes dos seus operandos. nvel (level) Um conjunto de clulas equidistantes da raiz. ps-ordem Uma forma de percorrer uma rvore (postorder) visitando os filhos de cada clula antes da operador Um operador sobre dois operandos. prpria clula. binrio (binary operator) in-ordem Uma forma de percorrer uma rvore (inorder) visitando a subrvore esquerda, seguida da subexpresso Uma expresso entre parntesis que se raiz e finalmente da subrvore direita. comporta como um operando simples numa (subexpression ) expresso maior. (siebling) pr-ordem Uma forma de percorrer uma rvore (preorder) visitando cada clula antes dos seus filhos. notao Uma forma de escrever uma expresso

GNU Free Documentation License #99

GNU Free Documentation License

Version 1.2, November 2002 Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 021101301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this The purpose of this License is to make a manual, textbook, or License. A Front-Cover Text may be at most 5 words, and a other functional and useful document "free" in the sense of Back-Cover Text may be at most 25 words. freedom: to assure everyone the effective freedom to copy and A "Transparent" copy of the Document means a redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License machine-readable copy, represented in a format whose preserves for the author and publisher a way to get credit for specification is available to the general public, that is suitable their work, while not being considered responsible for for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint modifications made by others. programs or (for drawings) some widely available drawing This License is a kind of "copyleft", which editor, and that is suitable for input to text formatters or for means that derivative works of the document must themselves automatic translation to a variety of formats suitable for input be free in the same sense. It complements the GNU General to text formatters. A copy made in an otherwise Transparent Public License, which is a copyleft license designed for free file format whose markup, or absence of markup, has been software. arranged to thwart or discourage subsequent modification by We have designed this License in order to use it readers is not Transparent. An image format is not Transparent for manuals for free software, because free software needs free if used for any substantial amount of text. A copy that is not documentation: a free program should come with manuals "Transparent" is called "Opaque". providing the same freedoms that the software does. But this Examples of suitable formats for Transparent License is not limited to software manuals; it can be used for copies include plain ASCII without markup, Texinfo input any textual work, regardless of subject matter or whether it is format, LaTeX input format, SGML or XML using a publicly published as a printed book. We recommend this License available DTD, and standard-conforming simple HTML, principally for works whose purpose is instruction or PostScript or PDF designed for human modification. reference. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, 1. APPLICABILITY AND DEFINITIONS SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, This License applies to any manual or other work, in any PostScript or PDF produced by some word processors for medium, that contains a notice placed by the copyright holder output purposes only. saying it can be distributed under the terms of this License. The "Title Page" means, for a printed book, the Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions title page itself, plus such following pages as are needed to stated herein. The "Document", below, refers to any such hold, legibly, the material this License requires to appear in the manual or work. Any member of the public is a licensee, and title page. For works in formats which do not have any title is addressed as "you". You accept the license if you copy, page as such, "Title Page" means the text near the most modify or distribute the work in a way requiring permission prominent appearance of the work's title, preceding the beginning of the body of the text. under copyright law. A section "Entitled XYZ" means a named A "Modified Version" of the Document means any work containing the Document or a portion of it, either subunit of the Document whose title either is precisely XYZ or copied verbatim, or with modifications and/or translated into contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific another language. section name mentioned below, such as "Acknowledgements", A "Secondary Section" is a named appendix or a "Dedications", "Endorsements", or "History".) To "Preserve front-matter section of the Document that deals exclusively the Title" of such a section when you modify the Document with the relationship of the publishers or authors of the means that it remains a section "Entitled XYZ" according to Document to the Document's overall subject (or to related this definition. matters) and contains nothing that could fall directly within The Document may include Warranty that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not Disclaimers next to the notice which states that this License

0. PREAMBLE

Como pensar como um cientista da Computao usando Python applies to the Document. These Warranty Disclaimers are Document, thus licensing distribution and modification of the considered to be included by reference in this License, but Modified Version to whoever possesses a copy of it. In only as regards disclaiming warranties: any other implication addition, you must do these things in the Modified Version: that these Warranty Disclaimers may have is void and has no A. Use in the Title Page (and on the covers, if any) a effect on the meaning of this License. title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the 2. VERBATIM COPYING Document). You may use the same title as a previous version if the original publisher of that version gives You may copy and distribute the Document in any medium, permission. either commercially or noncommercially, provided that this B. List on the Title Page, as authors, one or more License, the copyright notices, and the license notice saying persons or entities responsible for authorship of the this License applies to the Document are reproduced in all modifications in the Modified Version, together with copies, and that you add no other conditions whatsoever to at least five of the principal authors of the Document those of this License. You may not use technical measures to (all of its principal authors, if it has fewer than five), obstruct or control the reading or further copying of the copies unless they release you from this requirement. you make or distribute. However, you may accept C. State on the Title page the name of the publisher of compensation in exchange for copies. If you distribute a large the Modified Version, as the publisher. enough number of copies you must also follow the conditions D. Preserve all the copyright notices of the in section 3. Document. E. Add an appropriate copyright notice for your You may also lend copies, under the same modifications adjacent to the other copyright notices. conditions stated above, and you may publicly display copies. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in 3. COPYING IN QUANTITY the form shown in the Addendum below. G. Preserve in that license notice the full lists of If you publish printed copies (or copies in media that Invariant Sections and required Cover Texts given in commonly have printed covers) of the Document, numbering the Document's license notice. more than 100, and the Document's license notice requires H. Include an unaltered copy of this License. Cover Texts, you must enclose the copies in covers that carry, I. Preserve the section Entitled "History", Preserve its clearly and legibly, all these Cover Texts: Front-Cover Texts Title, and add to it an item stating at least the title, on the front cover, and Back-Cover Texts on the back cover. year, new authors, and publisher of the Modified Both covers must also clearly and legibly identify you as the Version as given on the Title Page. If there is no publisher of these copies. The front cover must present the full section Entitled "History" in the Document, create title with all words of the title equally prominent and visible. one stating the title, year, authors, and publisher of You may add other material on the covers in addition. Copying the Document as given on its Title Page, then add an with changes limited to the covers, as long as they preserve the item describing the Modified Version as stated in the title of the Document and satisfy these conditions, can be previous sentence. treated as verbatim copying in other respects. J. Preserve the network location, if any, given in the If the required texts for either cover are too Document for public access to a Transparent copy of voluminous to fit legibly, you should put the first ones listed the Document, and likewise the network locations (as many as fit reasonably) on the actual cover, and continue given in the Document for previous versions it was the rest onto adjacent pages. based on. These may be placed in the "History" section. You may omit a network location for a work If you publish or distribute Opaque copies of the that was published at least four years before the Document numbering more than 100, you must either include Document itself, or if the original publisher of the a machine-readable Transparent copy along with each Opaque version it refers to gives permission. copy, or state in or with each Opaque copy a computer K. For any section Entitled "Acknowledgements" or network location from which the general network-using public "Dedications", Preserve the Title of the section, and has access to download using public-standard network preserve in the section all the substance and tone of protocols a complete Transparent copy of the Document, free each of the contributor acknowledgements and/or of added material. If you use the latter option, you must take dedications given therein. reasonably prudent steps, when you begin distribution of L. Preserve all the Invariant Sections of the Opaque copies in quantity, to ensure that this Transparent copy Document, unaltered in their text and in their titles. will remain thus accessible at the stated location until at least Section numbers or the equivalent are not considered one year after the last time you distribute an Opaque copy part of the section titles. (directly or through your agents or retailers) of that edition to M. Delete any section Entitled "Endorsements". Such the public. a section may not be included in the Modified It is requested, but not required, that you contact Version. the authors of the Document well before redistributing any N. Do not retitle any existing section to be Entitled large number of copies, to give them a chance to provide you "Endorsements" or to conflict in title with any with an updated version of the Document. Invariant Section. O. Preserve any Warranty Disclaimers.

4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the

If the Modified Version includes new frontmatter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles

GNU Free Documentation License #101

Como pensar como um cientista da Computao usando Python must be distinct from any other section titles. 7. AGGREGATION WITH INDEPENDENT You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your WORKS Modified Version by various parties--for example, statements of peer review or that the text has been approved by an A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a organization as the authoritative definition of a standard. volume of a storage or distribution medium, is called an You may add a passage of up to five words as a "aggregate" if the copyright resulting from the compilation is Front-Cover Text, and a passage of up to 25 words as a Back- not used to limit the legal rights of the compilation's users Cover Text, to the end of the list of Cover Texts in the beyond what the individual works permit. When the Document Modified Version. Only one passage of Front-Cover Text and is included in an aggregate, this License does not apply to the one of Back-Cover Text may be added by (or through other works in the aggregate which are not themselves arrangements made by) any one entity. If the Document derivative works of the Document. already includes a cover text for the same cover, previously If the Cover Text requirement of section 3 is added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may applicable to these copies of the Document, then if the replace the old one, on explicit permission from the previous Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket publisher that added the old one. the Document within the aggregate, or the electronic The author(s) and publisher(s) of the Document equivalent of covers if the Document is in electronic form. do not by this License give permission to use their names for Otherwise they must appear on printed covers that bracket the publicity for or to assert or imply endorsement of any whole aggregate. Modified Version.

5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of If a section in the Document is Entitled that section if known, or else a unique number. Make the same "Acknowledgements", "Dedications", or "History", the adjustment to the section titles in the list of Invariant Sections requirement (section 4) to Preserve its Title (section 1) will in the license notice of the combined work. typically require changing the actual title. In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any 9. TERMINATION sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. "Endorsements." Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received 6. COLLECTIONS OF DOCUMENTS copies, or rights, from you under this License will not have You may make a collection consisting of the Document and their licenses terminated so long as such parties remain in full other documents released under this License, and replace the compliance. individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying 10. FUTURE REVISIONS OF THIS LICENSE of each of the documents in all other respects. The Free Software Foundation may publish new, revised You may extract a single document from such a versions of the GNU Free Documentation License from time collection, and distribute it individually under this License, to time. Such new versions will be similar in spirit to the provided you insert a copy of this License into the extracted present version, but may differ in detail to address new document, and follow this License in all other respects problems or concerns. See http://www.gnu.org/copyleft/. regarding verbatim copying of that document. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the GNU Free Documentation License #102

Como pensar como um cientista da Computao usando Python Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

How to use this License for your documents


To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the BackCover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

GNU Free Documentation License #103