Escolar Documentos
Profissional Documentos
Cultura Documentos
Pythontut PDF
Pythontut PDF
Allen Downey
Jerey Elkner
Chris Meyers
Copyright (c) 2002 Allen Downey, Jerey 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.
#2
Como pensar como um cientista da Computao usando Python
ndice
#3
Como pensar como um cientista da Computao usando Python
#4
Como pensar como um cientista da Computao usando Python
Foreword
Foreword #5
Como pensar como um cientista da Computao usando Python
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 que ele oferece um equilbrio realmente bom entre o lado
ver completo este trabalho. Python uma linguagem de prtico e o lado conceitual. Sendo Python interpretado, os
programao divertida e extremamente fcil de usar que tem iniciantes podem pegar a linguagem e comear a fazer coisas
ganho forte popularidade nestes ltimos poucos anos. legais quase imediatamente sem se perderem em problemas de
Desenvolvida dez anos atrs por Guido van Rossun, a sintaxe compilao e ligao. Alm disso, Python vem com uma
simples do Python e seu sentido geral so grandemente grande biblioteca de mdulos que podem ser utilizados para
derivados do ABC, uma linguagem didtica que foi fazer todo tipo de tarefa, desde a programao para a web at
desenvolvida nos anos 80. Entretanto, Python tambm foi grficos. Com tal enfoque prtico temos uma bela maneira de
criado para solucionar problemas reais e tomou emprestado alcanar o engajamento dos alunos e permitir que eles
uma grande quantidade de caractersticas de linguagens de finalizem projetos significativos. Entretanto, Python tambm
programao como C++, Java, Modula-3 e Scheme. Por causa pode servir de excelente embasamento para a introduo de
disso, uma das mais notveis caractersticas do Python o conceitos importantes em cincia da computao. J que
grande apelo que tem junto a desenvolvedores profissionais de Python suporta plenamente procedimentos (procedures) e
software, cientistas, pesquisadores, artistas e educadores. classes, os alunos podem ser gradualmente introduzidos a
tpicos como abstrao procedural, estruturas de dados, e
A Despeito deste apelo do Python junto s mais programao orientada a objetos ? todos aplicveis em cursos
variadas comunidades, voc pode ainda estar pensando ?por posteriores de Java ou C++. Python ainda toma emprestado
que Python?? ou ?por que ensinar programao com certas caractersticas de linguagens de programao funcionais
Python??. Responder estas perguntas no uma tarefa fcil ? e pode ser usado para introduzir conceitos cujos detalhes
especialmente se a opinio pblica est do lado de alternativas poderiam ser aprofundados em cursos de Scheme e Lisp.
mais masoquistas como C++ e Java. Entretanto, eu acho que a
resposta mais direta que programar com Python um Lendo o prefcio de Jeffrey, fiquei
bocado 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. classe.
Em vez disso, preferiria muito mais v-los tentando solucionar
problemas interessantes explorando idias diferentes, Embora Python seja ainda uma linguagem
trilhando caminhos no convencionais, quebrando regras, e jovem e em evoluo, acredito que tem um futuro brilhante
aprendendo a partir de seus erros. Fazendo assim, no em educao. Este livro um passo importante nessa direo.
pretendo desperdiar metade de um semestre tentando explicar
problemas obscuros de sintaxe, mensagens ininteligveis de David Beazley
compiladores ou as vrias centenas de maneiras pelas quais Universidade de Chicago
um programa pode gerar uma falha geral de proteo.
Uma das razes pelas quais eu gosto de Python Autor de Python Essencial Reference
Apresentao #6
Como pensar como um cientista da Computao usando Python
Preface
By Je Elkner computer science classes the following year, the most pressing
problem was the lack of an available textbook.
This book owes its existence to the
collaboration made possible by the Internet and the free Free content came to the rescue. Earlier in the
software movement. Its three authorsa college professor, a year, Richard Stallman had introduced me to Allen Downey.
high school teacher, and a professional programmerhave yet Both of us had written to Richard expressing an interest in
to meet face to face, but we have been able to work closely developing free educational content. Allen had already written
together and have been aided by many wonderful folks who a rst-year computer science textbook, How to Think Like a
have donated their time and energy to helping make this book Computer Scientist. When I read this book, I knew
better. immediately that I wanted to use it in my class. It was the
clearest and most helpful computer science text I had seen. It
We think this book is a testament to the benets emphasized the processes of thought involved in
and future possibilities of this kind of collaboration, the programming rather than the features of a particular language.
framework for which has been put in place by Richard Reading it immediately made me a better teacher.
Stallman and the Free Software Foundation.
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
How and why I came to use Python modied to meet the needs of its user. Once I decided to use
Python, it occurred to me that I could translate Allens original
In 1999, the College Boards Advanced Placement (AP) Java version of the book into the new language. While I would
Computer Science exam was given in C++ for the rst time. not have been able to write a textbook on my own, having
As in many high schools throughout the country, the decision Allens book to work from made it possible for me to do so, at
to change languages had a direct impact on the computer the same time demonstrating that the cooperative development
science curriculum at Yorktown High School in Arlington, model used so well in software could also work for
Virginia, where I teach. Up to this point, Pascal was the educational content.
language of instruction in both our rst-year and AP courses.
In keeping with past practice of giving students two years of Working on this book for the last two years has
exposure to the same language, we made the decision to been rewarding for both my students and me, and my students
switch to C++ in the rst-year course for the 1997-98 school played a big part in the process. Since I could make instant
year so that we would be in step with the College Boards changes whenever someone found a spelling error or dicult
change for the AP course the following year. passage, I encouraged them to look for mistakes in the book
by giving them a bonus point each time they made a
Two years later, I was convinced that C++ was suggestion that resulted in a change in the text. This had the
a poor choice to use for introducing students to computer double benet of encouraging them to read the text more
science. While it is certainly a very powerful programming carefully and of getting the text thoroughly reviewed by its
language, it is also an extremely dicult language to learn and most important critics, students using it to learn computer
teach. I found myself constantly ghting with C++s dicult science.
syntax and multiple ways of doing things, and I was losing
many students unnecessarily as a result. Convinced there had For the second half of the book on ob ject-
to be a better language choice for our rst-year class, I went oriented programming, I knew that someone with more real
looking for an alternative to C++. programming experience than I had would be needed to do it
right. The book sat in an unnished state for the better part of
I needed a language that would run on the a year until the free software community once again provided
machines in our Linux lab as well as on the Windows and the needed means for its completion.
Macintosh platforms most students have at home. I wanted it
to be free and available electronically, so that students could I received an email from Chris Meyers
use it at home regardless of their income. I wanted a language expressing interest in the book. Chris is a professional
that was used by professional programmers, and one that had programmer who started teaching a programming course last
an active developer community around it. It had to support year using Python at Lane Community College in Eugene,
both procedural and ob ject-oriented programming. And most Oregon. The prospect of teaching the course had led Chris to
importantly, it had to be easy to learn and teach. When I the book, and he started helping out with it immediately. By
investigated the choices with these goals in mind, Python the end of the school year he had created a companion project
stood out as the best candidate for the job. on our Website at http://www.ibiblio.org/obp called Python
for Fun and was working with some of my most advanced
I asked one of Yorktowns talented students, students as a master teacher, guiding them beyond where I
Matt Ahrens, to give Python a try. In two months he not only could take them.
learned the language but wrote an application called pyTicket
that enabled our sta to report technology problems via the
Web. I knew that Matt could not have nished an application
of that scale in so short a time in C++, and this Intro ducing programming with Python
accomplishment, combined with Matts positive assessment of
Python, suggested that Python was the solution I was looking The process of translating and using How to Think Like a
for. Computer Scientist for the past two years has conrmed
Pythons suitability for teaching beginning students. Python
greatly simplies programming examples and makes
important programming ideas easier to teach.
Finding a textb o ok
The rst example from the text illustrates this
Having decided to use Python in both of my introductory point. It is the traditional hello, world program, which in the
Preface #7
Como pensar como um cientista da Computao usando Python
C++ version of the book looks like this: they learned in their math courses. I had much less diculty
teaching variables this year than I did in the past, and I spent
#include <iostream.h> less time helping students with problems using them.
void main()
{
Another example of how Python aids in the
teaching and learning of programming is in its syntax for
cout << "Hello, world." << endl; 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 dierence between a function denition and a
function call, and the related distinction between a parameter
print "Hello, World!" and an argument. Python comes to the rescue with syntax that
Even though this is a trivial example, the is nothing short of beautiful. Function denitions begin with
advantages of Python stand out. Yorktowns Computer the keyword def, so I simply tell my students, When you
Science I course has no prerequisites, so many of the students dene a function, begin with def, followed by the name of the
seeing this example are looking at their rst program. Some of function that you are dening; when you call a function,
them are undoubtedly a little nervous, having heard that simply call (type) out its name. Parameters go with
computer programming is dicult to learn. The C++ version denitions; arguments go with calls. There are no return types,
has always forced me to choose between two unsatisfying parameter types, or reference and value parameters to get in
options: either to explain the #include, void main(), {, and } the way, so I am now able to teach functions in less than half
statements and risk confusing or intimidating some of the the time that it previously took me, with better
students right at the start, or to tell them, Just dont worry comprehension.
about all of that stu now; we will talk about it later, and risk Using Python has improved the eectiveness of
the same thing. The educational ob jectives at this point in theour computer science program for all students. I see a higher
course are to introduce students to the idea of a programming general level of success and a lower level of frustration than I
statement and to get them to write their rst program, thereby experienced during the two years I taught C++. I move faster
introducing them to the programming environment. The with better results. More students leave the course with the
Python program has exactly what is needed to do these things, ability to create meaningful programs and with the positive
and nothing 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
computer programming but with the minutia of C++ syntax. I I have received email from all over the globe from people
found this same thing happening throughout the book. Whole using this book to learn or to teach programming. A user
paragraphs simply disappear from the Python version of the community has begun to emerge, and many people have been
text because Pythons much clearer syntax renders them contributing to the pro ject by sending in materials for the
unnecessary. companion Website at http://www.thinkpython.com.
Using a very high-level language like Python With the publication of the book in print form, I
allows a teacher to postpone talking about low-level details of expect the growth in the user community to continue and
the machine until students have the background that they need accelerate. The emergence of this user community and the
to better make sense of the details. It thus creates the ability to possibility it suggests for similar collaboration among
put rst things rst pedagogically. One of the best examples educators have been the most exciting parts of working on this
of this is the way in which Python handles variables. In C++ a pro ject for me. By working together, we can increase the
variable is a name for a place that holds a thing. Variables quality of materials available for our use and save valuable
have to be declared with types at least in part because the size time. I invite you to join our community and look forward to
of the place to which they refer needs to be predetermined. hearing from you. Please write to the authors at
Thus, the idea of a variable is bound up with the hardware of feedback@thinkpython.com.
the machine. The powerful and fundamental concept of a
variable is already dicult enough for beginning students (in Jerey Elkner
both computer science and algebra). Bytes and addresses do Yorktown High School
not help the matter. In Python a variable is a name that refers
to a thing. This is a far more intuitive concept for beginning Arlington, Virginia
students and is much closer to the meaning of variable that
Preface #8
Como pensar como um cientista da Computao usando Python
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 Encontrando um livro texto
autores ? um professor universitrio, um secundrio e um
programador profissional ? ainda no se encontraram Tendo decidido usar Python em ambas as minhas classes
pessoalmente, mas temos podido trabalhar bem de perto e introdutrias de cincia da computao do ano seguinte, o
temos sido ajudados por muitos colegas maravilhosos que tm problema mais urgente era a falta de um livro texto disponvel.
dedicado seu tempo e energia a ajudar a fazer deste um livro
cada vez melhor. O contedo livre veio em socorro.
Anteriormente naquele ano, Richard Stallman tinha me
Achamos que este livro um testemunho dos apresentado a Allen Downey. Ambos havamos escrito a
benefcios e possibilidades futuras deste tipo de colaborao, Richard expressando interesse em desenvolver contedo
cujo modelo tem sido colocado por Richard Stallman e pela educacional livre. Allen j tinha escrito um livro texto para o
Free Software Foundation. primeiro ano de cincia da computao, How to Think Like a
Computer Scientist. Quando li este livro, soube imediatamente
que queria utiliz-lo nas minhas aulas. Era o texto mais claro e
proveitoso em cincia da computao que eu tinha visto. Ele
Como e porque eu vim a usar Python enfatizava o processo de reflexo envolvido em programao
em vez de caractersticas de uma linguagem em particular. L-
Em 1999, o Exame de Colocao Avanada em Cincia da lo fez de mim imediatamente um melhor professor.
Computao da Comisso de Faculdades (College Board?s
Advanced Placement (AP) Computer Science) foi aplicado em O How to Think Like a Computer Scientist era
C++ pela primeira vez. Como em muitas escolas secundrias no s um excelente livro, como tambm fora lanado sob
atravs do pas, a deciso de mudar linguagens teve um uma licena pblica GNU, o que significava que ele poderia
impacto direto no currculo de cincia da computao na ser usado livremente e modificado para atender as
Yorktown High School em Arlington, Virginia, onde leciono. necessidades de seu usurio. Uma vez que eu havia decidido
At ento, Pascal era a linguagem didtica para nossos cursos usar Python, me ocorreu que eu poderia traduzir a verso
de primeiro ano e avanado. Mantendo a prtica corrente de original do livro de Allen do Java para a nova linguagem.
dar aos estudantes dois anos de exposio mesma Apesar de no estar capacitado para escrever eu mesmo um
linguagem, tomamos a deciso de mudar para C++ no curso livro texto, tendo o livro de Allen a partir do qual trabalhar
de primeiro ano para o ano letivo de 1997-98 de modo que tornou possvel para mim faz-lo, ao mesmo tempo
estaramos em sincronismo com a mudana da Comisso de demonstrando que o modelo de desenvolvimento cooperativo
Faculdades (College Board?s) em relao ao curso avanado to bem utilizado em software poderia tambm funcionar para
para o ano seguinte. contedo educacional.
Dois anos depois, eu estava convencido que Trabalhar neste livro pelos ltimos dois anos
C++ foi uma escolha infeliz para introduzir os alunos em tem sido recompensador para mim e meus alunos, e eles
cincia da computao. Ao mesmo tempo em que tiveram um grande papel neste processo. A partir do momento
certamente uma linguagem de programao muito poderosa, em que eu podia fazer mudanas instantneas assim que
tambm uma linguagem extremamente difcil de aprender e algum encontrasse um erro ortogrfico ou um trecho difcil,
de ensinar. Eu me encontrava constantemente lutando com a eu os encorajei a procurar por erros no livro, dando a eles
sintaxe difcil do C++ e as mltiplas maneiras de fazer a pontos de bonificao cada vez que eles fizessem uma
mesma coisa, e estava, como resultado, perdendo muitos sugesto que resultasse em uma mudana no texto. Isto teve o
alunos desnecessariamente. Convencido de que deveria existir duplo benefcio de encoraj-los a ler o texto mais
uma linguagem melhor para a nossa classe de primeiro ano, cuidadosamente e de ter o texto totalmente revisado por seus
fui procurar por uma alternativa ao C++. crticos mais importantes: alunos utilizando-o para aprender
cincia da computao.
Eu precisava de uma linguagem que pudesse
rodar nas mquinas em nosso laboratrio Linux bem como nas Para a segunda metade do livro, sobre
plataformas Windows e Macintosh que a maioria dos alunos programao orientada a objetos, eu sabia que seria preciso
tinha em casa. Eu precisava que ela fosse gratuita e disponvel algum com uma maior experincia do que a minha em
eletronicamente, assim os alunos poderiam utiliz-la em casa programao real para faz-lo corretamente. O livro esteve em
independentemente de suas rendas. Eu queria uma linguagem estado inacabado por quase um ano at que a comunidade de
que fosse utilizada por programadores profissionais, e que software livre providenciasse mais uma vez os meios
tivesse uma comunidade de desenvolvimento ativa em torno necessrios para sua concluso.
dela. Ela teria que suportar ambas, programao procedural e Eu recebi um e-mail de Chris Meyers mostrando
orientada a objetos. E, mais importante, deveria ser fcil de interesse no livro.
aprender e de ensinar. Quando considerei as alternativas tendo comeou a dar umChris um programador profissional que
curso de programao no ano anterior
em mente aquelas metas, Python sobressaiu-se como a melhor usando Python no Lane Community College em Eugene,
candidata para a tarefa. Oregon. A perspectiva de dar aquele curso ligou Chris ao
Pedi para um dos talentosos estudantes de livro, e ele comeou a ajudar o trabalho imediatamente. Pelo
Yorktown, Matt Ahrens, que experimentasse Python. Em dois final do ano letivo ele tinha criado um projeto colaborativo em
meses ele no s aprendeu a linguagem como tambm nosso Website em http://www.ibiblio.org/obp chamado
escreveu uma aplicao chamada pyTicket que possibilitou Python for Fun e estava trabalhando com alguns dos meus
nossa equipe reportar problemas de tecnologia pela Web. Eu alunos mais avanados como um guru, guiando-os alm de
sabia que Matt no poderia ter finalizado uma aplicao onde eu poderia lev-los.
daquele porte em perodo to curto em C++, esta realizao,
combinada com a avaliao positiva do Python dada por Matt,
sugeriam que Python era a soluo que eu estava procurando.
Prefcio #9
Como pensar como um cientista da Computao usando Python
Prefcio #10
Como pensar como um cientista da Computao usando Python
Contributor List
To paraphrase the philosophy of the Free Software unconsciously in Chapter 1 needed to be changed
Foundation, this book is free like free speech, but not to subconsciously.
necessarily free like free pizza. It came about because of a
collaboration that would not have been possible without the Chris McAloon sent in several corrections to
GNU Free Documentation License. So we thank the Free Sections 3.9 and 3.10.
Software Foundation for developing this license and, of Matthew J. Moelter has been a long-time contributor
course, making it available to us. who sent in numerous corrections and suggestions to
We also thank the more than 100 sharp-eyed the book.
and thoughtful readers who have sent us suggestions and Simon Dicon Montford reported a missing function
corrections over the past few years. In the spirit of free denition and several typos in Chapter 3. He also
software, we decided to express our gratitude in the form of a found errors in the increment function in Chapter 13.
contributor list. Unfortunately, this list is not complete, but we
are doing our best to keep it up to date. John Ouzts corrected the denition of return value
If you have a chance to look through the list, in Chapter 3.
you should realize that each person here has spared you and Kevin Parks sent in valuable comments and
all subsequent readers from the confusion of a technical error suggestions as to how to improve the distribution of
or a less-than-transparent explanation, just by sending us a the book.
note.
David Pool sent in a typo in the glossary of Chapter
Impossible as it may seem after so many 1, as well as kind words of encouragement.
corrections, there may still be errors in this book. If you
should stumble across one, please check the online version of Michael Schmitt sent in a correction to the chapter on
the book at http://thinkpython.com, which is the most up-to- les and exceptions.
date version. If the error has not been corrected, please take a
minute to send us email at feedback@thinkpython.com. If we Robin Shaw pointed out an error in Section 13.1,
make a change due to your suggestion, you will appear in the where the printTime function was used in an example
next version of the contributor list (unless you ask to be without being dened.
omitted). Thank you! Paul Sleigh found an error in Chapter 7 and a bug in
Lloyd Hugh Allen sent in a correction to Section 8.4. Jonah Cohens Perlscript that generates HTML from
LaTeX.
Yvon Boulianne sent in a correction of a semantic
error in Chapter 5. Craig T. Snydal is testing the text in a course at Drew
University. He has contributed several valuable
Fred Bremmer submitted a correction in Section 2.1. suggestions and corrections.
Jonah Cohen wrote the Perl scripts to convert the Ian Thomas and his students are using the text in a
LaTeX source for this book into beautiful HTML. programming course. They are the rst ones to test
the chapters in the latter half of the book, and they
Michael Conlon sent in a grammar correction in have made numerous corrections and suggestions.
Chapter 2 and an improvement in style in Chapter 1,
and he initiated discussion on the technical aspects of Keith Verheyden sent in a correction in Chapter 3.
interpreters.
Peter Winstanley let us know about a longstanding
Benoit Girard sent in a correction to a humorous error in our Latin in Chapter 3.
mistake in Section 5.6.
Chris Wrobel made corrections to the code in the
Courtney Gleason and Katherine Smith wrote chapter on le I/O and exceptions.
horsebet.py, which was used as a case study in an
earlier version of the book. Their program can now Moshe Zadka has made invaluable contributions to
be found on the website. this pro ject. In addition to writing the rst draft of
the chapter on Dictionaries, he provided continual
Lee Harr submitted more corrections than we have guidance in the early stages of the book.
room to list here, and indeed he should be listed as
one of the principal editors of the text. Christoph Zwerschke sent several corrections and
pedagogic suggestions, and explained the dierence
James Kaylin is a student using the text. He has between gleich and selbe.
submitted numerous corrections.
James Mayer sent us a whole slew of spelling and
David Kershaw xed the broken catTwice function in typographical errors, including two in the contributor
Section 3.10. list.
Eddie Lam has sent in numerous corrections to Hayden McAfee caught a potentially confusing
Chapters 1, 2, and 3. He also xed the Makele so inconsistency between two examples.
that it creates an index the rst time it is run and
helped us set up a versioning scheme. Angel Arnal is part of an international team of
translators working on the Spanish version of the
Man-Yong Lee sent in a correction to the example text. He has also found several errors in the English
code in Section 2.4. version.
David Mayo pointed out that the word Tauhidul Hoque and Lex Berezhny created the
illustrations in Chapter 1 and improved many of the Ben Logan sent in a number of typos and problems
other illustrations. with translating the book into HTML.
Dr. Michele Alzetta caught an error in Chapter 8 and Jason Armstrong saw the missing word in Chapter 2.
sent some interesting pedagogic comments and
suggestions about Fibonacci and Old Maid. Louis Cordier noticed a spot in Chapter 16 where the
code didnt match the text.
Andy Mitchell caught a typo in Chapter 1 and a
broken example in Chapter 2. Brian Cain suggested several clarications in
Chapters 2 and 3.
Kalin Harvey suggested a clarication in Chapter 7
and caught some typos. Rob Black sent in a passel of corrections, including
some changes for Python 2.2.
Christopher P. Smith caught several typos and is
helping us prepare to update the book for Python 2.2. Jean-Philippe Rey at Ecole Centrale Paris sent a
number of patches, including some updates for
David Hutchins caught a typo in the Foreword. Python 2.2 and other thoughtful improvements.
Gregor Lingl is teaching Python at a high school in Jason Mader at George Washington University made
Vienna, Austria. He is working on a German a number of useful suggestions and corrections.
translation of the book, and he caught a couple of bad
errors in Chapter 5. Jan Gundtofte-Bruun reminded us that a error is an
error.
Julie Peters caught a typo in the Preface.
Abel David and Alexis Dinno reminded us that the
Florin Oprina sent in an improvement in makeTime, plural of matrix is matrices, not matrixes. This
a correction in printTime, and a nice typo. error was in the book for years, but two readers with
the same initials reported it on the same day. Weird.
D. J. Webre suggested a clarication in Chapter 3.
Charles Thayer encouraged us to get rid of the semi-
Ken found a stful of errors in Chapters 8, 9 and 11. colons we had put at the ends of some statements and
Ivo Wever caught a typo in Chapter 5 and suggested to clean up our use of argument and parameter.
a clarication in Chapter 3. Roger Sperberg pointed out a twisted piece of logic
Curtis Yanko suggested a clarication in Chapter 2. in Chapter 3.
Verso Brasileira
tem um programa que funciona, deve guard-lo em um script, lugar, o interpretador Python vai exibir uma mensagem de
de forma a poder execut-lo ou modific-lo no futuro. erro e vai terminar - e o programa no vai rodar. Durante as
primeiras semanas da sua carreira como programador, voc
provavelmente perder um bocado de tempo procurando erros
de sintaxe. Conforme for ganhando experincia, entretanto,
1.2 O que um programa? cometer menos erros e os localizar mais rpido.
Um programa uma seqncia de instrues que 1.3.2 Erros em tempo de execuo (runtime errors)
especificam como executar uma computao. A computao
pode ser algo matemtico, como solucionar um sistema de O segundo tipo de erro o erro de runtime, ou erro em tempo
equaes ou encontrar as razes de um polinmio, mas de execuo, assim chamado porque s aparece quando voc
tambm pode ser uma computao simblica, como buscar e roda o programa. Esses erros so tambm conhecidos como
substituir uma palavra em um documento ou (estranhamente) excees, porque normalmente indicam que alguma coisa
compilar um programa. excepcional (e ruim) aconteceu.
Os detalhes so diferentes em diferentes Erros de runtime so raros nos programas
linguagens, mas algumas instrues bsicas aparecem em simples que voc vai ver nos primeiros captulos - ento, vai
praticamente todas as linguagens: demorar um pouco at voc se deparar com um erro desse
tipo.
entrar Pegar dados do teclado, de um arquivo
ou de algum outro dispositivo.
1.3.3 Erros de semntica
sair Mostrar dados na tela ou enviar dados
para um arquivo ou outro dispositivo. O terceiro tipo de erro o erro de semntica (mais
comumente chamado erro de lgica). Mesmo que o seu
calcular Executar operaes matemticas programa tenha um erro de semntica, ele vai rodar com
bsicas, como adio e multiplicao. sucesso, no sentido de que o computador no vai gerar
nenhuma mensagem de erro. S que o programa no vai fazer
executar Checar certas condies e executar a a coisa certa, vai fazer alguma outra coisa. Especificamente,
condicionalmente seqncia apropriada de instrues. aquilo que voc tiver dito para ele fazer.
repetir Executar alguma ao repetidamente, O problema que o programa que voc
normalmente com alguma variao. escreveu no aquele que voc queria escrever. O significado
Acredite se quiser: isso praticamente tudo. do programa (sua semntica ou lgica) est errado. Identificar
Todos os programas que voc j usou, no importa quo erros semnticos pode ser complicado, porque requer que
complicados, so feitos de instrues mais ou menos voc trabalhe de trs para frente, olhando a sada do programa
parecidas com essas. Assim, poderamos definir programao e tentando imaginar o que ele est fazendo.
como o processo de dividir uma tarefa grande e complexa em
sub-tarefas cada vez menores, at que as sub-tarefas sejam 1.3.4 Depurao experimental (Debugging)
simples o suficiente para serem executadas com uma dessas
instrues bsicas. Uma das habilidades mais importantes que voc vai adquirir
Isso pode parecer um pouco vago, mas vamos a de depurar. Embora possa ser frustrante, depurar uma das
voltar a esse tpico mais adiante, quando falarmos sobre partes intelectualmente mais ricas, desafiadoras e
algoritmos. interessantes da programao.
De certa maneira, a depurao como um
trabalho de detetive. Voc se depara com pistas, e tem que
1.3 O que depurao (debugging)? deduzir os processos e eventos que levaram aos resultados
que aparecem.
Programar um processo complicado e, como feito por Depurar tambm como uma cincia
seres humanos, freqentemente conduz a erros. Por mero experimental. Uma vez que voc tem uma idia do que est
capricho, erros em programas so chamados de bugs e o errado, voc modifica o seu programa e tenta de novo. Se a
processo de encontr-los e corrigi-los chamado de sua hiptese estava correta, ento voc consegue prever o
depurao (debugging). resultado da modificao e fica um passo mais perto de um
programa que funciona. Se a sua hiptese estava errada, voc
Trs tipos de erro podem acontecer em um tem que tentar uma nova. Como Sherlock Holmes mostrou,
programa: erros de sintaxe, erros em tempo de execuo "Quando voc tiver eliminado o impossvel, aquilo que
(runtime errors) e erros de semntica. Distinguir os trs tipos restou, ainda que improvvel, deve ser a verdade." (Arthur
ajuda a localiz-los mais rpido: Conan Doyle, O signo dos quatro).
sobre 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.
literalidade As linguagens naturais esto cheias de
Linguagens naturais so as linguagens que as pessoas falam, expresses idiomticas e metforas. Se eu
como o portugus, o ingls e o espanhol. Elas no foram digo "Caiu a ficha", possvel que no exista
projetadas pelas pessoas (muito embora as pessoas tentem ficha nenhuma, nem nada que tenha cado.
colocar alguma ordem nelas); elas evoluram naturalmente. Nas linguagens formais, no h sentido
ambguo.
Linguagens formais so linguagens que foram Pessoas que crescem falando uma linguagem
projetadas por pessoas, para aplicaes especficas. Por natural -- ou seja, todo mundo - muitas vezes tm dificuldade
exemplo, a notao que os matemticos usam uma de se acostumar com uma linguagem formal. De certa
linguagem formal, que particularmente boa em denotar maneira, a diferena entre linguagens formais e naturais
relaes entre nmeros e smbolos. Os qumicos usam uma como a diferena entre poesia e prosa, porm mais acentuada:
linguagem formal para representar a estrutura qumica das
molculas. E, mais importante:
poesia As palavras so usadas pela sua sonoridade,
Linguagens de programao so linguagens alm de seus sentidos, e o poema como um
formais que foram desenvolvidas para expressar todo cria um efeito ou uma reao emocional.
computaes. A ambigidade no apenas freqente, mas na
maioria das vezes, proposital.
As linguagens formais tendem a ter regras
estritas quanto sintaxe. Por exemplo, 3 + 3 = 6 uma prosa O sentido literal das palavras mais
expresso matemtica sintaticamente correta, mas 3=+6$ no importante, e a estrutura contribui mais para o
. H2O um nome qumico sintaticamente correto, mas 2Zz significado. A prosa mais fcil de analisar do
no . que a poesia, mas ainda muitas vezes
ambgua.
As regras de sintaxe so de dois tipos, um
relacionado aos tokens, outro estrutura. "Tokens" so os programas O significado de um programa de computador
elementos bsicos da linguagem, como as palavras, nmeros, exato e literal, e pode ser inteiramente
e elementos qumicos. Um dos problemas com 3=+6$ que $ entendido pela anlise de seus tokens e de sua
no um token vlido em linguagem matemtica (pelo menos estrutura.
at onde sabemos). Do mesmo modo, 2Zz invlida porque Aqui vo algumas sugestes para a leitura de
no existe nenhum elemento cuja abreviatura seja Zz. programas (e de outras linguagens formais). Primeiro, lembre-
O segundo tipo de erro de sintaxe est se de que linguagens formais so muito mais densas do que
relacionado estrutura de uma expresso -- quer dizer, ao linguagens naturais, por isso, mais demorado l-las. A
modo como os tokens esto arrumados. A expresso 3=+6$ estrutura, tambm, muito importante, logo, geralmente no
estruturalmente invlida, porque voc no pode colocar um uma boa idia ler de cima para baixo, da esquerda para a
sinal de "mais" imediatamente aps um sinal de "igual". Do direita. Em vez disso, aprenda a analisar o programa na sua
mesmo modo, frmulas moleculares devem ter ndices cabea, identificando os tokens e interpretando a estrutura.
subscritos colocados depois do nome do elemento, no antes. Finalmente, os detalhes so importantes. Pequenas coisas,
como, erros ortogrficos e m pontuao, com as quais voc
Faa este exerccio: crie o que parea ser uma pode se safar nas linguagens naturais, podem fazer uma
frase bem estruturada em portugus com "tokens" grande diferena em uma linguagem formal.
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 1.5 O primeiro programa
uma expresso em uma linguagem formal, voc tem de
imaginar como a estrutura da frase (embora, em uma Tradicionalmente, o primeiro programa escrito
linguagem natural, voc faa isso inconscientemente). Este em uma nova linguagem de programao chamado de "Al,
processo chamado parsing (anlise sinttica). Mundo!" porque tudo que ele faz apresentar as palavras
Por exemplo, quando voc ouve a frase, "Caiu a "Al, Mundo!". Em Python, ele assim:
ficha", entende que "a ficha" o sujeito e "caiu" o verbo. print "Al, Mundo!"
Uma vez que voc analisou a frase, consegue entender o seu
significado, ou a semntica da frase. Assumindo que voc Isso um exemplo de um comando print, que,
saiba o que uma ficha e o que significa cair, voc entender na realidade, no "imprime" nada em papel. Ele apresenta o
o sentido geral dessa frase. valor na tela. Neste caso, o resultado so as palavras:
Muito embora as linguagens formais e as Al, Mundo!
naturais tenham muitas caractersticas em comum -- tokens, As aspas no programa marcam o comeo e o
estrutura, sintaxe e semntica -- existem muitas diferenas: fim do valor; elas no aparecem no resultado final.
ambigidade As linguagens naturais esto cheias de Algumas pessoas julgam a qualidade de uma
ambigidades, que as pessoas contornam linguagem de programao pela simplicidade do programa
usando pistas contextuais e outras "Al, Mundo!". Por esse padro, Python se sai to bem
informaes. J as linguagens formais so quanto possvel.
desenvolvidas para serem quase ou
totalmente desprovidas de ambigidade, o
que significa que qualquer expresso tem 1.6 Glossrio
precisamente s um sentido,
independentemente do contexto.
soluo de O processo de formular um problema,
redundncia Para compensar a ambigidade e reduzir problemas encontrar uma soluo e expressar esta
mal-entendidos, emprega-se muita
tm de comear com uma letra. Embora seja vlida a comando, o interpretador avalia e exibe o resultado:
utilizao de letras maisculas, por conveno, no usamos.
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 variveis e operadores, nem toda expresso contm todos estes
palavras, tal como em meu_nome ou preco_do_cha_na_china. elementos. Um valor por si s considerado uma expresso,
do mesmo modo que uma varivel:
Se voc der a uma varivel um nome invlido,
causar um erro de sintaxe: >>> 17
17
>>> 76trombones = "grande parada" >>> x
SyntaxError: invalid syntax 2
>>> muito$ = 1000000 Avaliar uma expresso no exatamente a
SyntaxError: invalid syntax mesma coisa que imprimir um valor:
>>> class = "Ciencias da Computacao 101"
>>> mensagem = "E a, Doutor?"
SyntaxError: invalid syntax
>>> mensagem
76trombones invlida porque no comea com
uma letra. muito$ invlida porque contm um caractere 'E a, Doutor?'
ilegal, o cifro. Mas o que est errado com class? >>> print mensagem
E a, Doutor?
Ocorre que class uma das palavras Quando Python exibe o valor de uma expresso,
reservadas em Python. Palavras reservadas definem as regras usa o mesmo formato que voc usaria para entrar com o valor.
e a estrutura da linguagem e no podem ser usadas como No caso de strings, isso significa que as aspas so includas
nomes de variveis. [#]_. Mas o comando print imprime o valor da expresso, que,
Python tem 29 palavras reservadas: 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 17
class else from is print yield 3.2
continue except global lambda raise "Al, Mundo!"
Pode ser til ter essa lista mo. Se o 1 + 1
interpretador acusar erro sobre um de seus nomes de varivel no produz qualquer sada. Como voc mudaria
e voc no souber porqu, veja se o nome est na lista. o "script" para exibir os valores destas quatro expresses?
como este, em que o inteiro seguinte est muito prximo: como 4*3 equivale a 4+4+4, no de estranhar que "Legal"*3
seja o mesmo que "Legal"+"Legal"+"Legal". Por outro lado,
>>> minuto*100/60 uma diferena significativa separa concatenao e repetio de
98 adio e multiplicao. Voc saberia mencionar uma
De novo, o resultado arredondado para baixo, propriedade da adio e da multiplicao que no ocorre na
mas agora pelo menos a resposta aproximadamente correta. concatenao e na repetio?
A alternativa usar a diviso em ponto flutuante, o que
veremos no captulo 3.
2.9 Composio
2.7 Ordem dos operadores At agora, vimos os elementos de um programa -- variveis,
expresses, e instrues ou comandos -- isoladamente, sem
Quando mais de um operador aparece em uma expresso, a mencionar como combin-los.
ordem de avaliao depende das regras de precedncia.
Python segue as mesmas regras de precedncia para seus linguagens deUma das caractersticas mais prticas das
operadores matemticos que a matemtica. O acrnimo pequenos blocosprogramao a possibilidade de pegar
e combin-los numa composio. Por
PEMDAS uma maneira prtica de lembrar a ordem das exemplo, ns sabemos como somar nmeros e sabemos como
operaes: exibi-los; acontece que podemos fazer as duas coisas ao
Parnteses tm a mais alta precedncia e podem ser mesmo tempo:
usados para forar uma expresso a ser avaliada na >>> print 17 + 3
ordem que voc quiser. J que expresses entre
parnteses so avaliadas primeiro, 2 * (3-1) 4, e 20
(1+1)**(5-2) 8. Voc tambm pode usar parnteses Na realidade, a soma tem que acontecer antes da
para tornar uma expresso mais fcil de ler, como em impresso, assim, as aes no esto na realidade acontecendo
(minuto * 100) / 60, ainda que isso no altere o ao mesmo tempo. O ponto que qualquer expresso
resultado. envolvendo nmeros, strings, e variveis pode ser usada
dentro de um comando print. Voc j tinha visto um exemplo
Exponenciao ou potenciao tem a prxima disto:
precedncia mais alta, assim 2**1+1 3 e no 4, e
3*1**3 3 e no 27. print "Nmero de minutos desde a meia-noite: ", \
Multiplicao e Diviso tm a mesma precedncia, hora*60+minuto
que mais alta do que a da Adio e da Subtrao, Esta possibilidade pode no parecer muito
que tambm tm a mesma precedncia. Assim 2*3-1 impressionante agora, mas voc ver outros exemplos em que
d 5 em vez de 4, e 2/3-1 -1, no 1 (lembre-se de a composio torna possvel expressar computaes
que na diviso inteira, 2/3=0). complexas de modo limpo e conciso.
Operadores com a mesma precedncia so avaliados Ateno: Existem limites quanto ao lugar onde
da esquerda para a direita. Assim, na expresso voc pode usar certos tipos de expresso. Por exemplo, o lado
minuto*100/60, a multiplicao acontece primeiro, esquerdo de um comando de atribuio tem que ser um nome
resultando em 5900/60, o que se transforma de varivel, e no uma expresso. Assim, o seguinte no
produzindo 98. Se as operaes tivessem sido vlido: minuto+1 = hora.
avaliadas da direita para a esquerda, o resultado
poderia ter sido 59*1, que 59, que est errado.
2.11 Glossrio
2.8 Operaes com strings valor (value) Um nmero ou string (ou outra coisa que
ainda vamos conhecer) que pode ser
De maneira geral, voc no pode executar operaes atribuda a uma varivel ou computada em
matemticas em strings, ainda que as strings se paream com uma expresso.
nmeros. O que segue invlido (assumindo que mensagem
do tipo string): tipo (type) Um conjunto de valores. O tipo de um
valor determina como ele pode ser usado
mensagem-1 "Al"/123 mensagem*"Al" "15"+2 em expresses. At agora, os tipos vistos
Interessante o operador +, que funciona com so: inteiros (tipo int), nmeros em ponto-
strings, embora ele no faa exatamente o que voc poderia flutuante (tipo float) e strings (tipo string).
esperar. Para strings, o operador + representa concatenao, ponto- Formato para representar nmeros que
que significa juntar os dois operandos ligando-os pelos flutuante possuem partes fracionrias.
extremos. Por exemplo: (floating-point)
fruta = "banana" varivel Nome que se refere a um valor.
assada = " com canela" (variable)
print fruta + assada
A sada deste programa banana com canela. O comando Trecho de cdigo que representa uma
espao antes da palavra com parte da string e necessrio (statement) instruo ou ao. At agora, os comandos
para produzir o espao entre as strings concatenadas. vistos foram de atribuio e exibio.
O operador * tambm funciona com strings; ele atribuio Comando que atribui um valor a uma
realiza repetio. Por exemplo, "Legal"*3 (assignment) varivel.
"LegalLegaLegal". Um dos operadores tem que ser uma diagrama de Representao grfica de um conjunto de
string; o outro tem que ser um inteiro. estado (state variveis e os valores aos quais elas se
diagram) referem.
Por um lado, esta interpretao de + e * faz
sentido pela analogia entre adio e multiplicao. Assim
Captulo 3: Funes
'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
<type 'str'>
podem representar o mesmo nmero, mas pertencem a tipos
diferentes. A razo que eles so representados de modo
O nome da funo type e ela exibe o tipo de diferente dentro do computador.
um valor ou varivel. O valor ou varivel, que chamado de
argumento da funo, tem que vir entre parnteses. comum
se dizer que uma funo 'recebe' um valor e 'retorna' um
resultado. O resultado chamado de valor de retorno. 3.3 Coero entre tipos
Em vez de imprimir um valor de retorno,
podemos atribui-lo a uma varivel: Agora que podemos converter entre tipos, temos outra
maneira de lidar com a diviso inteira. Voltando ao exemplo
>>> bia = type('32') do captulo anterior, suponha que queiramos calcular a frao
>>> print bia de hora que j passou. A expresso mais bvia, minuto / 60,
<type 'str'>
faz aritmtica inteira, assim, o resultado sempre 0, mesmo
aos 59 minutos passados da hora.
Como outro exemplo, a funo id recebe um
valor ou uma varivel e retorna um inteiro, que atua como um Uma soluo converter minuto para ponto
identificador nico para aquele valor: flutuante e fazer a diviso em ponto flutuante:
>>> id(3) >>> minuto = 59
134882108 >>> float(minuto) / 60
>>> bia = 3 0.983333333333
>>> bia(beth) Opcionalmente, podemos tirar vantagem das
134882108 regras de converso automtica entre tipos, chamada de
Todo valor tem um id, que um nmero nico coero de tipos. Para os operadores matemticos, se
relacionado ao local onde ele est guardado na memria do qualquer operando for um float, o outro automaticamente
computador. O id de uma varivel o id do valor a qual ela se convertido para float:
refere. >>> minuto = 59
>>> 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 Em matemtica, voc provavelmente j viu funes como
>>> int('Al') seno (sin) e log, e aprendeu a resolver expresses como
ValueError: invalid literal for int() : Al sin(pi/2) e log(1/x). Primeiro voc resolve e expresso entre
parnteses (o argumento). Por exemplo, pi/2
int tambm pode converter valores em ponto aproximadamente 1,571, e 1/x 0.1 (se x for 10,0).
flutuante para inteiro, mas lembre que isso trunca a parte
fracionria: A voc avalia a funo propriamente dita, seja
procurando numa tabela ou realizando vrios clculos. O sin
>>> int(3.99999) de 1,571 1 e o log de 0,1 -1 (assumindo que log indica o
3 logaritmo na base 10).
>>> int(-2.3)
-2
Este processo pode ser aplicado repetidamente
para avaliar expresses mais complicadas, como
A funo float converte inteiros e strings em log(1/sin(pi/2)). Primeiro voc avalia o argumento na funo
nmeros em ponto flutuante: mais interna, depois avalia a funo e assim por diante.
>>> float(32) Python tem um mdulo matemtico que prov a
32.0 maioria das funes matemticas mais familiares. Um mdulo
>>> float('3.14159') um arquivo que contm uma coleo de funes
3.14159 relacionadas agrupadas juntas.
Finalmente, a funo str converte para o tipo Antes de podermos usar as funes contidas em
string: um mdulo, temos de import-lo:
>>> str(32) >>> import math
Para chamar uma das funes, temos que lista de parmetros especifica que informao, se houver
especificar o nome do mdulo e o nome da funo, separados alguma, voc tem que fornecer para poder usar a nova funo.
por um ponto. Esse formato chamado de notao de ponto:
Uma funo pode ter quantos comandos forem
>>> decibel = math.log10(17.0) necessrios, mas eles precisam ser endentados a partir da
>>> angulo = 1.5 margem esquerda. Nos exemplos deste livro, usaremos uma
>>> altura = math.sin(angulo)
endentao de dois espaos.
A primeira instruo atribui a decibel o As primeiras funes que vamos mostrar no
logaritmo de 17 na base 10. Existe tambm uma funo tero parmetros, ento, a sintaxe ter esta aparncia:
chamada log, que pega o logaritmo na base e.
def novaLinha():
A terceira instruo encontra o seno do valor da print
varivel angulo. sin e as outras funes trigonomtricas (cs,
tan, etc.) recebem argumentos em radianos. Para converter de Esta funo chamada de novaLinha. Os
graus em radianos, divida por 360 e multiplique por 2*pi. Por parnteses vazios indicam que ela no tem parmetros.
exemplo, para encontrar o seno de 45 graus, primeiro calcule Contm apenas um nico comando, que gera como sada um
o ngulo em radianos e depois ache o seno: caractere de nova linha (isso o que acontece quando voc
usa um comando print sem qualquer argumento).
>>> graus = 45
A sintaxe para a chamada desta nova funo a
>>> angulo = graus * 2 * math.pi / 360.0 mesma sintaxe para as funes nativas:
>>> math.sin(angulo)
0.707106781187 print 'Primeira Linha.'
A constante pi tambm parte do mdulo math. novaLinha()
Se voc sabe geometria, pode checar o resultado anterior print 'Segunda Linha.'
comparando-o com a raiz quadrada de dois dividido por dois: A sada deste programa :
>>> math.sqrt(2) / 2.0 Primeira Linha.
0.707106781187
Segunda Linha.
Observe o espao extra entre as duas linhas. E
3.5 Composio se quisssemos mais espao entre as linhas? Poderamos
chamar a mesma funo repetidamente:
Do mesmo modo como nas funes matemticas, as funes print 'Primeira Linha.'
do Python podem ser compostas, o que significa que voc novaLinha()
pode usar uma expresso como parte de outra. Por exemplo, novaLinha()
voc pode usar qualquer expresso como um argumento para
uma funo: novaLinha()
print 'Segunda Linha.'
>>> x = math.cos(angulo + pi/2) Ou poderamos escrever uma nova funo
Esta instruo toma o valor de pi, divide-o por chamada tresLinhas, que produzisse trs novas linhas:
2, e soma o resultado ao valor de angulo. A soma ento
passada como um argumento para a funo cos. def tresLinhas() :
novaLinha()
Voc tambm pode pegar o resultado de uma novaLinha()
funo e pass-lo como um argumento para outra:
novaLinha()
>>> x = math.exp(math.log(10.0))
Esta instruo encontra o logaritmo base e de 10 print 'Primeira Linha.'
e ento eleva e quela potncia. O resultado atribudo a x. tresLinhas()
print 'Segunda Linha.'
Esta funo contm trs comandos, todos com
3.6 Adicionando novas funes 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.
At aqui, temos utilizado somente as funes que vm com
Python, mas tambm possvel adicionar novas funes. Criar Algumas coisas que devem ser observadas sobre
novas funes para resolver seus prprios problemas uma este programa:
das coisas mais teis de uma linguagem de programao de
propsito geral. 1. Voc pode chamar o mesmo procedimento
repetidamente. Isso muito comum, alm de til.
No contexto de programao, funo uma
seqncia nomeada de instrues ou comandos, que realizam 2. Voc pode ter uma funo chamando outra funo;
uma operao desejada. Esta operao especificada numa neste caso tresLinhas chama novaLinha.
definio de funo. At agora, as funes que usamos neste
livro so pr-definidas e suas definies no foram Pode no estar claro, at agora, de que vale o
apresentadas. Isso demonstra que podemos usar funes sem esforo de criar novas funes - existem vrias razes, mas
ter que nos preocupar com os detalhes de suas definies. este exemplo demonstra duas delas:
A sintaxe para uma definio de funo : Criar uma nova funo permite que voc coloque
nome em um grupo de comandos. As funes podem
def NOME( LISTA DE PARAMETROS ) : simplificar um programa ao ocultar uma computao
COMANDOS complexa por trs de um simples comando cujo
nome pode ser uma palavra em portugus, em vez de
Voc pode usar o nome que quiser para as algum cdigo misterioso.
funes que criar, exceto as palavras reservadas do Python. A
Criar uma nova funo pode tornar o programa lembra que uma funo pode chamar outra. Enquanto estiver
menor, por eliminar cdigo repetido. Por exemplo, no meio de uma funo, o programa poderia ter de executar os
um atalho para 'imprimir' nove novas linhas comandos em uma outra funo. Mas enquanto estivesse
consecutivas chamar tresLinhas trs vezes. executando esta nova funo, o programa poderia ter de
executar ainda outra funo!
Como exerccio, escreva uma funo chamada
noveLinhas que use tresLinhas para imprimir nove linhas Felizmente, Python adepto de monitorar a
em branco. Como voc poderia imprimir vinte e sete novas posio onde est, assim, cada vez que uma funo se
linhas? 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
voc ler um programa, no o leia de cima para baixo. Em vez
Reunindo os fragmentos de cdigo da Seo 3.6, o programa disso, siga o fluxo de execuo.
completo fica assim:
def novaLinha() :
3.9 Parmetros e argumentos
print
Algumas das funes nativas que voc j usou requerem
def tresLinhas() : argumentos, aqueles valores que controlam como a funo faz
novaLinha() seu trabalho. Por exemplo, se voc quer achar o seno de um
novaLinha() nmero, voc tem que indicar qual nmero . Deste modo, sin
novaLinha() recebe um valor numrico como um argumento.
Algumas funes recebem mais de um
print 'Primeira Linha.' argumento. Por exemplo, pow recebe dois argumentos, a base
tresLinhas() e o expoente. Dentro da funo, os valores que lhe so
print 'Segunda Linha.' passados so atribudos a variveis chamadas parmetros.
Esse programa contm duas definies de Veja um exemplo de uma funo definida pelo
funes: novaLinha e tresLinhas. Definies de funes so usurio, que recebe um parmetro:
executadas como quaisquer outros comandos, mas o efeito
criar a nova funo. Os comandos dentro da definio da def imprimeDobrado(bruno):
funo no so executados at que a funo seja chamada, print bruno, bruno
logo, a definio da funo no gera nenhuma sada. Esta funo recebe um nico argumento e o
Como voc j deve ter imaginado, preciso atribui a um parmetro chamado bruno. O valor do parmetro
criar uma funo antes de poder execut-la. Em outras (a essa altura, no sabemos qual ser) impresso duas vezes,
palavras, a definio da funo tem que ser executada antes seguido de uma nova linha. Estamos usando bruno para
que ela seja chamada pela primeira vez. mostrar que o nome do parmetro deciso sua, mas claro que
melhor escolher um nome que seja mais ilustrativo.
Como exerccio, mova as ltimas trs linhas
deste programa para o topo, de modo que a chamada da A funo imprimeDobrado funciona para
funo aparea antes das definies. Rode o programa e veja qualquer tipo que possa ser impresso:
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
expresso como um argumento para imprimeDobrado:
A execuo sempre comea com o primeiro
comando do programa. Os comandos so executados um de >>> imprimeDobrado('Spam'*4)
cada vez, pela ordem, de cima para baixo. SpamSpamSpamSpam SpamSpamSpamSpam
>>> imprimeDobrado(math.cos(math.pi))
As definies de funo no alteram o fluxo de
execuo do programa, mas lembre-se que comandos dentro -1.0 -1.0
da funo no so executados at a funo ser chamada. Como acontece normalmente, a expresso
Embora no seja comum, voc pode definir uma funo avaliada antes da execuo da funo, assim imprimeDobrado
dentro de outra. Neste caso, a definio mais interna no imprime SpamSpamSpamSpam SpamSpamSpamSpam em
executada at que a funo mais externa seja chamada. vez de 'Spam'*4 'Spam'*4.
Chamadas de funo so como um desvio no Como exerccio, escreva um chamada a
fluxo de execuo. Em vez de ir para o prximo comando, o imprimeDobrado que imprima 'Spam'*4 'Spam'*4. Dica:
fluxo salta para a primeira linha da funo chamada, executa strings podem ser colocadas tanto entre aspas simples
todos os comandos l e ento volta atrs para retomar de onde quanto duplas e o tipo de aspas que no for usado para
havia deixado. envolver a string pode ser usado dentro da string, como
parte dela.
Parece muito simples, at a hora em que voc
3.13 Glossrio
corpo sem nenhuma instruo (usualmente, como um uma delas verdadeira, o ramo correspondente executado, e
delimitador de espao para cdigo que voc ainda no a instruo termina. Mesmo que mais de uma condio seja
escreveu). Nesse caso, voc pode usar o comando pass, que verdadeira, apenas o primeiro ramo verdadeiro executa.
no faz nada.
Como exerccio, coloque os exemplos acima em
funes chamadas comparar(x, y) e executar(escolha).
4.5 Execuo alternativa
4.7 Condicionais aninhados
Um segundo formato da instruo if a execuo alternativa,
na qual existem duas possibilidades e a condio determina
qual delas ser executada. A sintaxe se parece com: Um condicional tambm pode ser aninhado dentro de outra.
Poderamos ter escrito o exemplo tricotmico (dividido em
if x % 2 == 0: trs) como segue:
print x, " par"
if x == y:
else:
print x, "e", y, "so iguais"
print x, " impar"
else:
Se o resto da diviso de x por 2 for 0, ento if x < y:
sabemos que x par, e o programa exibe a mensagem para
esta condio. Se a condio falsa, o segundo grupo de print x, " menor que", y
instrues executado. Desde que a condio deva ser else:
verdadeira (true) ou falsa (false), precisamente uma das print x, " maior que", y
alternativas vai ser executada. As alternativas so chamadas O condicional mais externo tem dois ramos. O
ramos (branches), porque existem ramificaes no fluxo de primeiro ramo contm uma nica instruo de sada. O
execuo. segundo ramo contm outra instruo if, que por sua vez tem
Por sinal, se voc precisa checar a paridade de dois ramos. Os dois ramos so ambos instrues de sada,
nmeros com freqncia, pode colocar este cdigo dentro de embora pudessem conter instrues condicionais tambm.
uma funo: Embora a endentao das instrues torne a
def imprimeParidade(x):
estrutura aparente, condicionais aninhados tornam-se difceis
de ler rapidamente. Em geral, uma boa idia evitar o
if x % 2 == 0: aninhamento quando for possvel.
print x, " par"
else: Operadores lgicos freqentemente fornecem
print x, " impar"
uma maneira de simplificar instrues condicionais aninhadas.
Por exemplo, podemos reescrever o cdigo a seguir usando
Para qualquer valor de x, imprimeParidade uma nica condicional:
exibe uma mensagem apropriada. Quando voc a chama, pode
fornecer uma expresso de resultado inteiro como um if 0 < x:
argumento: if x < 10:
>>> imprimeParidade(17) print "x um nmero positivo de um s
algarismo."
>>> imprimeParidade(y+1)
A instruo print executada somente se a
fizermos passar por ambos os condicionais, ento, podemos
usar um operador and:
4.6 Condicionais encadeados if 0 < x and x < 10:
print "x um nmero positivo de um s algarismo."
s vezes existem mais de duas possibilidades e precisamos de
mais que dois ramos. Uma condicional encadeada uma Esses tipos de condio so comuns, assim,
maneira de expressar uma computao dessas: Phython prov uma sintaxe alternativa que similar notao
matemtica:
if x < y:
if 0 < x < 10:
print x, " menor que", y
print "x um nmero positivo de um s algarismo."
elif x > y:
print x, " maior que", y
else:
print x, "e", y, "so iguais" 4.8 A instruo return
elif uma abreviao de "else if" ("ento se").
De novo, precisamente um ramo ser executado. No existe O comando return permite terminar a execuo de uma funo
limite para o nmero de instrues elif, mas se existir uma antes que ela alcance seu fim. Uma razo para us-lo se voc
instruo else ela tem que vir por ltimo: detectar uma condio de erro:
if escolha == 'A': import math
funcaoA()
elif escolha == 'B': def imprimeLogaritmo(x):
funcaoB() if x <= 0:
elif escolha == 'C': print "Somente nmeros positivos, por favor."
funcaoC() return
else:
print "Escolha invlida." resultado = math.log(x)
Cada condio checada na ordem. Se a print "O log de x ", resultado
primeira falsa, a prxima checada, e assim por diante. Se A funo imprimeLogaritmo recebe um
def tresLinhas():
novaLinha()
novaLinha()
Um primeiro passo lgico nesta computao parmetros. Registre cada estgio do desenvolvimento
encontrar as diferenas x2 - x1 e y2 - y1. Ns iremos guardar incremental conforme voc avance.
estes valores em variveis temporrias chamadas dx e dy e
imprimi-las:
def distancia(x1, y1, x2, y2): 5.3 Composio
dx = x2 - x1
dy = y2 - y1 Conforme voc poderia esperar agora, voc pode chamar uma
print "dx vale", dx funo de dentro de outra. Esta habilidade chamada de
print "dy vale", dy composio.
return 0.0 Como um exemplo, vamos escrever uma funo
Se a funo estiver funcionando, as sadas que recebe dois pontos, o centro de um crculo e um ponto em
devero ser 3 e 4. Se assim, sabemos que a funo est seu permetro, e calcula a rea do crculo.
recebendo os parmetros corretos e realizando a primeira
computao corretamente. Se no, existem poucas linhas para Assuma que o ponto do centro est guardado
checar. nas variveis xc e yc, e que o ponto do permetro est nas
variveis xp e yp. O primeiro passo encontrar o raio do
Em seguida, computaremos a soma dos crculo, o qual a distncia entre os dois pontos. Felizmente,
quadrados de dx e dy: temos uma funo, distancia, que faz isto:
def distancia(x1, y1, x2, y2): Raio = distancia(xc, yc, xp, yp)
dx = x2 - x1 O segundo passo encontrar a rea de um
dy = y2 - y1 crculo com o raio dado e retorn-la:
dquadrado = dx**2 + dy**2 resultado = area(raio)
print "dquadrado vale: ", dquadrado return resultado
return 0.0
Juntando tudo numa funo, temos:
Note que removemos os comandos print que
havamos escrito no passo anterior. Cdigo como este def area2(xc, yc, xp, yp):
chamado de andaime porque ajuda a escrever o programa, raio = distancia(xc, yc, xp, yp)
mas no parte do produto final. resultado = area(raio)
De novo, ns vamos rodar o programa neste return resultado
estgio e checar a sada (que deveria ser 25). Chamamos esta funo de area2 para
distinguir da funo area, definida anteriormente. S pode
Finalmente, se ns tnhamos importado o existir uma nica funo com um determinado nome em um
mdulo matemtico math, podemos usar a funo sqrt para determinado mdulo.
computar e retornar o resultado:
As variveis temporrias raio e resultado so
def distancia(x1, x2, y1, y2): teis para o desenvolvimento e para depurao (debugging),
dx = x2 - x1 mas uma vez que o programa esteja funcionando, podemos
dy = y2 - y1 torn-lo mais conciso atravs da composio das chamadas de
dquadrado = dx**2 + dy**2 funo:
resultado = math.sqrt(dquadrado) def area2(xc, yc, xp, yp):
return resultado return area(distancia(xc, yc, xp, yp))
Se isto funcionar corretamente, voc conseguiu. Como exerccio, escreva uma funo
Caso contrrio, talvez fosse preciso imprimir (exibir) o valor inclinacao(x1, y1, x2, y2) que retorne a inclinao (ou
de resultado antes da instruo return. coeficienteAngular?) de uma linha dados os pontos (x1, y1) e
Enquanto for iniciante, voc deve acrescentar (x2, y2). Depois use esta funo em uma funo chamada
apenas uma ou duas linhas de cdigo de cada vez. Conforme cortaY(x1, y1, x2, y2) que retorne a interseo da linha com o
ganhar mais experincia, voc se ver escrevendo e depurando eixo y, dados os pontos (x1, y1) e (x2, y2).
pedaos maiores. De qualquer modo, o processo de
desenvolvimento incremental pode poupar um bocado de
tempo de depurao. 5.4 Funes booleanas
Os aspectos chave do processo so:
Funes podem retornar valores booleanos, o que muitas
1. Comece com um programa que funciona e faa vezes conveniente por ocultar testes complicados dentro de
pequenas mudanas incrementais. Em qualquer ponto funes. Por exemplo:
do processo, se houver um erro, voc saber
exatamente onde ele est. def ehDivisivel(x, y):
2. Use variveis temporrias para manter valores If x % y == 0:
intermedirios de modo que voc possa exibi-los e return True # verdadeiro (true), divisvel
chec-los. else:
return False # falso (false), no divisvel
3. Uma vez que o programa funcione, voc pode querer
remover algum cdigo muleta, ou andaime O nome desta funo ehDivisivel ("
(scaffolding) ou consolidar mltiplos comandos divisvel"). comum dar a uma funo booleana nomes que
dentro de expresses compostas, mas somente se isto soem como perguntas sim/no. ehDivisivel retorna ou True ou
no tornar o programa difcil de ler. False para indicar se x ou no divisvel por y.
Como um exerccio, use o desenvolvimento Podemos tornar a funo mais concisa se
incremental para escrever uma funo chamada hipotenusa tirarmos vantagem do fato de a condio da instruo if ser ela
que retorna a medida da hipotenusa de um tringulo mesma uma expresso booleana. Podemos retorn-la
retngulo dadas as medidas dos dois catetos como diretamente, evitando totalmente o if:
De fato, voc est agora mesmo praticando este RuntimeError: Maximum recursion depth exceeded
voto de confiana ao usar as funes nativas. Quando voc Parece um caso de recursividade infinita. Mas o
chama math.cos ou math.exp, voc no examina a que ser que de fato? Existe um caso base -- quando n == 0.
implementao destas funes. Voc apenas assume que elas O problema que o valor de n nunca encontra o caso base.
funcionam porque as pessoas que escreveram as bibliotecas
nativas eram bons programadores. Na primeira chamada recursiva, o valor de n
0.5. Na prxima, ele igual a -0.5. Da em diante, ele se torna
O mesmo tambm verdade quando voc cada vez menor, mas jamais ser 0.
chama uma de suas prprias funes. Por exemplo, na Seo
5.4, escrevemos a funo chamada ehDivisivel que determina Temos ento duas alternativas. Podemos tentar
se um nmero divisvel por outro. Uma vez que nos generalizar a funo fatorial para que funcione com nmeros
convencemos que esta funo est correta -- ao testar e em ponto flutuante, ou fazemos fatorial realizar a checagem
examinar o cdigo -- podemos usar a funo sem examinar o de tipo de seus parmetros. A primeira chamada funo
cdigo novamente. gamma e est um pouco alm do escopo deste livro. Sendo
assim, ficaremos com a segunda.
O mesmo tambm verdadeiro para programas
recursivos. Quando voc tem uma chamada recursiva, em vez Podemos usar type para comparar o tipo do
de seguir o fluxo de execuo, voc poderia assumir que a parmetro com o tipo de um valor inteiro conhecido (como 1).
chamada recursiva funciona (produz o resultado correto) e Ao mesmo tempo em que fazemos isto, podemos nos
ento perguntar-se, "Assumindo que eu possa encontrar o certificar tambm de que o parmetro seja positivo:
fatorial de n-1, posso calcular o fatorial de n?" Neste caso,
claro que voc pode, multiplicando por n. def fatorial (n):
if type(n) != type(1):
Naturalmente, um pouco estranho que uma print "Fatorial somente definido para
funo funcione corretamente se voc ainda nem terminou de
escrev-la, mas por isso que se chama voto de confiana! inteiros."
return -1
elif n < 0:
print "Fatorial somente definido para inteiros\
5.7 Mais um exemplo positivos."
return -1
No exemplo anterior, usamos variveis temporrias para elif n ==0:
explicitar (spell out XXX) os passos e tornar o cdigo mais
fcil de depurar, mas poderamos ter economizado algumas return 1
linhas: else:
return n * fatorial(n-1)
def fatorial(n):
Agora temos trs casos base. O primeiro pega os
if n == 0: no-inteiros. O segundo pega os inteiros negativos. Em ambos
return 1 os casos, o programa exibe uma mensagem de erro e retorna
else: um valor especial, -1, para indicar que alguma coisa saiu
return n * fatorial(n-1) errada:
De agora em diante, tenderemos a utilizar um >>> fatorial ("Fred")
formato mais conciso, mas recomendamos que voc use a Fatorial somente definido para inteiros.
verso mais explcita enquanto estiver desenvolvendo cdigo.
Quando ele estiver funcionando, voc pode enxug-lo se -1
estiver se sentindo inspirado. >>> fatorial (-2)
Fatorial somente definido para inteiros positivos.
Depois de fatorial, o exemplo mais comum de
uma funo matemtica definida recursivamente fibonacci, a -1
qual tem a seguinte definio: Se passarmos pelas duas checagens, ento
saberemos que n um inteiro positivo, e poderemos provar
fibonacci(0) = 1 que a recursividade encontra seu trmino.
fibonacci(1) = 1
Este programa demonstra um padro (pattern)
fibonacci(n) = fibonacci(n-1) + fibonacci(n-2); chamado s vezes de guardio. As duas primeiras
Traduzido em Python, parecer assim: condicionais atuam como guardis, protegendo o cdigo que
vem em seguida de valores que poderiam causar um erro. Os
def fibonacci(n): guardies tornam possvel garantir a correo do cdigo.
if n == 0 or n == 1:
return 1
else:
5.9 Glossrio
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. funo frutfera Uma funo que produz um valor de
Mas, de acordo com o voto de confiana, se voc assume que (fruitful function) retorno.
as duas chamadas recursivas funcionam corretamente, ento valor de retorno O valor entregue como resultado de uma
claro que voc ter o resultado correto ao junt-las. (return value) chamada de funo.
varivel Uma varivel usada para guardar um
temporria valor intermedirio em um clculo
5.8 Checagem de tipos (temporary complexo.
variable)
O que acontece se chamamos fatorial e damos a ela 1.5 como
argumento?: cdigo morto Parte de um programa que nunca pode
(dead code) ser executada, muitas vezes por que ela
>>> fatorial (1.5) aparece depois de uma instruo return.
Captulo 6: Iterao
Uma seqncia de escape pode aparecer em Se chamarmos esta funo com o argumento 2,
qualquer lugar em uma string; no exemplo, a seqncia de teremos a mesma sada que antes. Com o argumento 3, a sada
escape de tabulao a nica coisa dentro da string. :
Como voc acha que se representa uma barra 3 6 9 12 15 18
invertida em uma string? Com o argumento 4, a sada :
Como um exerccio, escreva um nica string 4 8 12 16 20 24
que
Agora voc provavelmente pode adivinhar
produza como imprimir uma tabela de multiplicao - chamando
esta imprimeMultiplos repetidamente com argumentos diferentes.
sada.
De fato, podemos usar um outro loop:
i = 1
while i <= 6:
6.4 Tabelas de duas dimenses (ou bi-dimensionais) imprimeMultiplos(i)
i = i + 1
Uma tabela de duas dimenses uma tabela em que voc l o Note o quanto este loop parecido com aquele
valor na interseo entre uma linha e uma coluna. Uma tabela dentro de imprimeMultiplos. Tudo o que fiz foi substituir o
de multiplicao um bom exemplo. Digamos que voc comando print pela chamada funo.
queira imprimir uma tabela de multiplicao de 1 a 6.
A sada deste programa uma tabela de
Uma boa maneira de comear escrever um multiplicao:
loop que imprima os mltiplos de 2, todos em uma linha:
1 2 3 4 5 6
i = 1 2 4 6 8 10 12
while i <= 6: 3 6 9 12 15 18
print 2*i, ' ', 4 8 12 16 20 24
i = i + 1 5 10 15 20 25 30
print 6 12 18 24 30 36
A primeira linha inicializa a varivel chamada i,
a qual age como um contador ou varivel de controle do
loop. Conforme o loop executado, o valor de i
incrementado de 1 a 6. Quando i for 7, o loop termina. A cada 6.6 Mais encapsulamento
repetio (iterao) do loop, mostrado o valor de 2*i,
seguido de trs espaos. Para demonstrar de novo o encapsulamento, vamos pegar o
cdigo do final da seo 6.5 e acondicion-lo, envolv-lo em
De novo, a vrgula no comando print suprime a uma funo:
nova linha. Depois que o loop se completa, o segundo
comando print inicia uma nova linha. def imprimeTabMult():
A sada do programa : i = 1
while i <= 6:
2 4 6 8 10 12 imprimeMultiplos(i)
At aqui, tudo bem. O prximo passo i = i + 1
encapsular e generalizar. Este processo um plano de desenvolvimento
comum. Ns desenvolvemos cdigo escrevendo linhas de
cdigo fora de qualquer funo, ou digitando-as no
6.5 Encapsulamento e generalizao interpretador. Quando temos o cdigo funcionando, extramos
ele e o embalamos em uma funo.
Encapsulamento o processo de wrapping um pedao de Este plano de desenvolvimento
cdigo em uma funo, permitindo que voc tire vantagem de particularmente til se voc no sabe, quando voc comea a
todas as coisas para as quais as funes so boas. Voc j viu escrever, como dividir o programa em funes. Esta tcnica
dois exemplos de encapsulamento: imprimeParidade na seo permite a voc projetar enquanto desenvolve.
4.5; e eDivisivel na seo 5.4
Generalizao significa tomar algo que
especfico, tal como imprimir os mltiplos de 2, e torn-lo 6.7 Variveis locais
mais geral, tal como imprimir os mltiplos de qualquer inteiro.
Esta funo encapsula o loop anterior e Voc pode estar pensando como podemos utilizar a mesma
generaliza-o para imprimir mltiplos de n: varivel, i, em ambos, imprimeMultiplos e imprimeTabMult.
Isto no causaria problemas quando uma das funes mudasse
def imprimeMultiplos(n): o valor da varivel?
i = 1 A resposta no, porque o i em
while i <= 6: imprimeMultiplos e o i em imprimeTabMult no so a mesma
print n*i, '\t ', varivel.
i = i + 1
Variveis criadas dentro de uma definio de
print funo so locais; voc no pode acessar uma varivel local
Para encapsular, tudo o que tivemos que fazer de fora da funo em que ela "mora". Isto significa que voc
foi adicionar a primeira linha, que declara o nome de uma livre para ter mltiplas variveis com o mesmo nome, desde
funo e sua lista de parmetros. Para generalizar, tudo o que que elas no estejam dentro da mesma funo.
tivemos que fazer foi substituir o valor 2 pelo parmetro n.
O diagrama de pilha para este programa mostra
que duas variveis chamadas i no so a mesma varivel. Elas def imprimeMultiplos(n, altura):
podem se referir a valores diferentes e alterar o valor de uma i = 1
no afeta outra. 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
de onde a funo chamada em imprimeTabMult.
Como esperado, este programa gera uma tabela
quadrada de sete por sete:
O valor de i em imprimeTabMult vai de 1 a 6. 1 2 3 4 5 6 7
No diagrama, i agora 3. Na prxima iterao do loop i ser 2 4 6 8 10 12 14
4. A cada iterao do loop, imprimeTabMult chama 3 6 9 12 15 18 21
imprimeMultiplos com o valor corrente de i como argumento.
O valor atribudo ao parmetro n. 4 8 12 16 20 24 28
5 10 15 20 25 30 35
Dentro de imprimeMultiplos, o valor de i vai de 6 12 18 24 30 36 42
1 a 6. No diagrama, i agora 2. Mudar esta varivel no tem 7 14 21 28 35 42 49
efeito sobre o valor de i em imprimeTabMult.
Quando voc generaliza uma funo
comum e perfeitamente legal ter variveis apropriadamente, voc muitas vezes tem um programa com
locais diferentes com o mesmo nome. Em particular, nomes capacidades que voc no planejou. Por exemplo, voc pode
como i e j so muito usados para variveis de controle de ter notado que, porque ab = ba, todas as entradas na tabela
loop. Se voc evitar utiliz-los em uma funo s porque voc aparecem duas vezes. Voc poderia economizar tinta
j os usou em outro lugar, voc provavelmente tornar seu imprimindo somente a metade da tabela. Para fazer isso, voc
programa mais difcil de ler. tem que mudar apenas uma linha em imprimeTabMult. Mude:
imprimeTabMult(i, altura)
para:
6.8 Mais generalizao
imprimeTabMult(i, i)
Como um outro exemplo de generalizao, imagine que voc e voc ter:
precise de um programa que possa imprimir uma tabela de
multiplicao de qualquer tamanho, no apenas uma tabela de 1
seis por seis. Voc poderia adicionar um parmetro a 2 4
imprimeTabMult: 3 6 9
def imprimeTabMult(altura): 4 8 12 16
i = 1 5 10 15 20 25
while i <= altura: 6 12 18 24 30 36
imprimeMultiplos(i) 7 14 21 28 35 42 49
i = i + 1 Como um exerccio, trace a execuo desta
Ns substitumos o valor 6 pelo parmetro verso de imprimeTabMult e explique como ela funciona.
altura. Se chamarmos imprimeTabMult com o argumento 7,
ela mostra:
1 2 3 4 5 6
6.9 Funes
2 4 6 8 10 12
H pouco tempo mencionamos "todas as coisas para
3 6 9 12 15 18 as quais as funes so boas." Agora, voc pode estar
4 8 12 16 20 24 pensando que coisas exatamente so estas. Aqui esto
5 10 15 20 25 30 algumas delas:
6 12 18 24 30 36
Dar um nome para uma seqncia de comandos torna
7 14 21 28 35 42 seu programa mais fcil de ler e de depurar.
Isto bom, exceto que ns provavelmente
quereramos que a tabela fosse quadrada - com o mesmo Dividir um programa longo em funes permite que
nmero de linhas e colunas. Para fazer isso, adicionamos voc separe partes do programa, depure-as
outro parmetro a imprimeMultiplos para especificar quantas isoladamente, e ento as componha em um todo.
colunas a tabela deveria ter.
Funes facilitam tanto recurso quanto iterao.
S para confundir, chamamos este novo
parmetro de altura, demonstrando que diferentes funes Funes bem projetadas so freqentemente teis
podem ter parmetros com o mesmo nome (como acontece para muitos programas. Uma vez que voc escreva e
com as variveis locais). Aqui est o programa completo: depure uma, voc pode reutiliz-la.
6.10 Glossrio
Captulo 7: Strings
de comprimento:
7.1 Um tipo de dado composto
comprimento = len(fruta)
At aqui, vimos trs diferentes tipos de dado: int, float e ultima = fruta[comprimento-1]
string. Strings so qualitativamente diferentes dos outros dois Como alternativa, podemos usar ndices
tipos porque so feitas de pedaos menores - caracteres. negativos, os quais contam de trs pra frente os elementos da
string. A expresso fruta[-1] resulta a ltima letra, fruta[-2]
Tipos que consistem de pedaos menores so resulta a penltima (a segunda de trs para frente), e assim por
chamados tipos de dados compostos. Dependendo do que diante.
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.
O operador colchete seleciona um nico
7.3 Travessia e o loop for
caractere de uma string.:
Vrias computaes envolvem o processamento de uma string
>>> fruta = "banana" um caractere de cada vez. Muitas vezes elas comeam com o
>>> letra = fruta[1] primeiro, selecionam um de cada vez, fazem alguma coisa
>>> print letra com ele, e continuam at o fim. Este padro de processamento
chamado uma travessia (traversal, com a idia de
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
surpresa: indice = 0
while indice < len(fruta):
a
letra = fruta[indice]
A primeira letra de "banana" no a. A menos
que voc seja um cientista da computao. Neste caso, voc print letra
deve entender a expresso dentro dos colchetes como um indice = indice + 1
deslocamento (offset,) a partir do comeo da string, e o Este loop percorre a string e exibe cada letra em
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
0, dentro dos colchetes: Como um exerccio, escreva uma funo que
tome uma string como argumento e devolva suas letras de
>>> letra = fruta[0] trs para frente, uma por linha.
>>> print letra
b Usar um ndice para percorrer um conjunto de
valores to comum que Python oferece uma sintaxe
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:
ndice indica aquele membro que voc quer, da seu nome. Ele print char
pode ser qualquer expresso inteira.
A cada vez atravs do loop, o prximo caractere
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 Jack
de 0 a 5. Para pegar o ltimo caractere, temos que subtrair 1 Kack
Lack else:
Mack print "Sim, ns no temos bananas!"
Nack Entretanto, voc deve atentar para o fato de que
Oack Pyhton no manipula letras maisculas e minsculas da
Pack mesma maneira que as pessoas o fazem. Todas as letras
Qack
maisculas vm antes das minsculas. Como resultado:
Naturalmente, esta sada no est cem por cento Sua palavra, Zebra, vem antes de banana.
certa porque "Ouack" e "Quack" esto escritos de maneira Uma maneira comum de resolver este problema
errada. converter as strings para um formato padro, seja todas
Como um exerccio, modifique o programa para minsculas, ou todas maisculas, antes de realizar a
corrigir este erro. comparao. Um problema mais difcil fazer o programa
perceber que zebras no so frutas.
Se voc omitir o primeiro ndice (antes dos dois 7.7 Uma funo find (encontrar)
pontos ":"), a fatia comea do incio da string. Se voc omitir
o segundo ndice, a fatia vai at o final da string. Assim: O que faz a seguinte funo?:
>>> fruta = "banana" def find(str, ch):
>>> fruta[:3] indice = 0
'ban' while indice < len(str):
>>> fruta[3:] if str[indice] == ch:
'ana' return indice
O que voc acha de s[:] significa? indice = indice + 1
return -1
Num certo sentido, find (encontrar) o oposto
7.5 Comparao de strings do operador []. Em vez de pegar um ndice e extrair o
caractere correspondente, ela pega um caractere e encontra
(finds) em qual ndice aquele caractere aparece. Se o caractere
O operador de comparao funciona com strings. Para ver se no encontrado, a funo retorna -1.
duas strings so iguais:
Este o primeiro exemplo que vemos de uma
if palavra == "banana": instruo return dentro de um loop. Se str[indice] == ch, a
print "Sim, ns no temos bananas!" funo retorna imediatamente, abandonando o loop
Outras operaes de comparao so teis para prematuramente.
colocar palavras em ordem alfabtica:
Se o caractere no aparece na string, ento o
if palavra < "banana": programa sai do loop normalmente e retorna -1.
print "Sua palavra," + palavra + ", vem antes de\ Este padro de computao s vezes chamado
banana." de travessia "eureka", porque to logo ele encontra (find) o
elif palavra > "banana": que est procurando, ele pode gritar "Eureka!" e parar de
print "Sua palavra," + palavra + ", vem depois \ procurar.
de banana." Como um exerccio, modifique a funo find
(encontrar) de modo que ela receba um terceiro parmetro, o Neste exemplo, a busca falha porque a letra b
ndice da string por onde ela deve comear sua procura. no aparece no intervalo entre 1 e 2 (no incluindo o 2) do
ndice.
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
Captulo 8: Listas
mudar, voc no precisar ir atravs de todo o programa Quase se l como Portugus: "For (para cada)
modificando todos os laos; eles funcionaro corretamente cavaleiro in (na lista de) cavaleiros, print (imprima o nome do)
para qualquer tamanho de lista: cavaleiro."
>>> cavaleiros = ['guerra', 'fome', 'peste', 'morte'] Qualquer expresso de lista pode ser utilizada
i = 0 num lao for:
while i < len(cavaleiros): >>> for numero in range(20):
print cavaleiros[i] if numero % 2 == 0:
i = i + 1 print numero
A ltima vez que o corpo do lao executado, i
len(cavaleiros) - 1, que o ndice do ltimo elemento. >>> for fruta in ["banana", "abacaxi", "laranja"]:
Quando i igual a len(cavaleiros), a condio falha e o corpo
no executado, o que uma boa coisa, porque print "Eu gosto de comer " + fruta + "s!"
len(cavaleiros) no um ndice legal. O primeiro exemplo exibe todos os nmeros
pares entre zero e dezenove. O segundo exemplo expressa o
Embora uma lista possa conter uma outra lista, a entusiasmo por vrias frutas.
lista aninhada ainda conta como um elemento simples. O
comprimento desta lista quatro:
>>> [`spam!', 1, ['Brie', 'Roquefort', \ 8.6 Operaes em listas
'Pol l Veq'], [1, 2 3]]
Como um exerccio, escreva um lao que O operador + concatena listas:
percorra a lista anterior e exiba o comprimento de cada
elemento. O que acontece se voc manda um inteiro para >>> a = [1, 2, 3]
len? >>> b = [4, 5, 6]
>>> c = a + b
>>> print c
8.4 Membros de uma lista [1, 2, 3, 4, 5, 6]
Similarmente, o operador * repete uma lista um
in um operador lgico que testa se um elemento membro nmero dado de vezes:
de uma seqncia. Ns o utilizamos na Seo 7.10 com
strings, mas ele tambm funciona com listas e outras >>> [0] * 4
seqncias: [0, 0, 0, 0]
>>> [1, 2, 3] * 3
>>> cavaleiros = ['guerra', 'fome', 'peste', 'morte'] [1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 'peste' in cavaleiros O primeiro exemplo repete [0] quatro vezes. O
True segundo exemplo repete a lista [1, 2, 3] trs vezes.
>>> 'depravao' in cavaleiros
False
Uma vez que 'peste' um membro da lista 8.7 Fatiamento de listas
cavaleiros, o operador in devolve verdadeiro. Uma vez que
depravao no est na lista, in devolve falso.
A operao de fatiamento que vimos na Seo 7.4 tambm
Podemos utilizar tambm o not em combinao funciona sobre listas:
com o in para testar se um elemento no um membro de uma
lista: >>> lista = ['a', 'b', 'c', 'd', 'e', 'f']
>>> lista[1:3]
>>> ``depravao`` not in cavaleiros ['b', 'c']
True >>> lista[:4]
['a', 'b', 'c', 'd']
>>> lista[3:]
8.5 Listas e laos for ['d', 'e', 'f']
>>> lista[:]
O lao for que vimos na Seo 7.3 tambm funciona com ['a', 'b', 'c', 'd', 'e', 'f']
listas. A sintaxe generalizada de um lao for :
for VARIVEL in LISTA:
CORPO 8.8 Listas so mutveis
Esta declarao equivalente a:
Diferente das strings, as listas so mutveis, o que significa
>>> i = 0 que podemos modificar seus elementos. Utilizando o operador
while i < len(LIST): colchete no lado esquerdo de uma atribuio, podemos
VARIABLE = LIST[i] atualizar um de seus elementos:
XXX BODY
>>> fruta = ["banana", "abacaxi", "laranja"]
i = i + 1
>>> fruta[0] = "abacate"
O lao for mais conciso porque podemos >>> fruta[-1] = "tangerina"
eliminar a varivel do lao, i. Aqui est o lao anterior escrito
com um`lao for: >>> print fruta
['abacate', 'abacaxi', 'tangerina']
>>> for cavaleiro in cavaleiros: Com o operador de fatiamento podemos
print cavaleiro atualizar vrios elementos de uma vez:
>>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] se referem mesma coisa. Estas "coisas" possume nomes -
>>> lista[1:3] = ['x', 'y'] elas so chamadas objetos. Um objeto algo ao qual uma
>>> print lista
varivel pode se referenciar.
['a', 'x', 'y', 'd', 'e', 'f'] Todo objeto possui um identificador nico, que
Tambm podemos remover elementos de uma podemos obter com a funo id. Exibindo o identificador de a
lista atribuindo a lista vazia a eles: e b, podemos dizer se elas se referem ao mesmo objeto.
>>> lista = ['a', 'b', 'c', 'd', 'e', 'f'] >>> id(a)
>>> lista[1:3] = [] 135044008
>>> print lista >>> id(b)
['a', 'd', 'e', 'f'] 135044008
E podemos adicionar elementos a uma lista De fato, obtivemos o mesmo identificador duas
enfiando-os numa fatia vazia na posio desejada: vezes, o que significa que Python criou apenas uma string, e
tanto a quanto b se referem a ela.
>>> lista = ['a', 'd', 'f']
>>> lista[1:1] = ['b', 'c']
Interessantemente, listas se comportam de forma
diferente. Quando criamos duas listas, obtemos dois objetos:
>>> print lista
['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)
135041704
8.9 Remoo em lista Ento o diagrama de estado fica assim:
Mais adiante veremos uma alternativa mais mesmo para qualquer string? Quando eles seriam diferentes?
radical utilizando um dicionrio.
8.17 Glossrio
8.16 Strings e listas
lista (list) Uma coleo denominada de objetos, onde
Duas das mais teis funes no mdulo string envolvem listas cada objeto identificado por um ndice.
de strings. A funo split (separar) quebra uma string em uma
lista de palavras. Por padro, qualquer nmero de caracteres ndice (index) Uma varivel inteira ou valor que indica um
espao em branco considerado um limite de uma palavra: elemento de uma lista.
>>> import string elemento Um dos valores em uma lista(ou outra
>>> poesia = "O orvalho no carvalho..." (element) seqncia). O operador colchete seleciona
>>> string.split(poesia) elementos de uma lista.
['O', 'orvalho', 'no', 'carvalho...'] seqncia Qualquer um dos tipos de dados que
Um argumento opcional chamado um (sequence) consiste de um conjunto ordenado de
delimitador pode ser utilizado para especificar qual caracter elementos, com cada elemento identificado
utilizar como limites da palavra. O exemplo a seguir utiliza a por um ndice.
string va:
lista aninhada Uma lista que um elemento de uma outra
>>> string.split(poesia, 'va') (nested list) lista.
['O or', 'lho no car', 'lho...'] percurso na O acesso seqencial de cada elemento em
Perceba que o delimitador no aparece na lista. lista (list uma lista.
traversal)
A funo join (juntar) o inverso de split. Ela
pega uma lista de strings e concatena os elementos com um objeto Um coisa a qual uma varivel pode se
espao entre cada par: (object) referir.
>>> lista = ['O', 'orvalho', 'no', 'carvalho...'] apelidos Mltiplas variveis que contm referncias
>>> string.join(lista) (aliases) ao mesmo objeto.
'O orvalho no carvalho...' clonar (clone) Criar um novo objeto que possui o mesmo
Como split, join recebe um delimitador que valor de um objeto existente. Copiar a
inserido entre os elementos: referncia a um objeto cria um apelido
(alias) mas no clona o objeto.
>>> string.join(lista, '_')
'O_orvalho_no_carvalho...' delimitador Um caracter uma string utilizados para
(delimiter) indicar onde uma string deveria ser
Como um execcio, descreva o relacionamento dividida(split).
entre string.join(string.split(poesia)) e poesia. Eles so o
Captulo 9: Tuplas
>>> temp = a
9.1 Mutabilidade e tuplas >>> a = b
>>> b = temp
At agora, voc tem visto dois tipos compostos: strings, que
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 atribuio de tupla que resolve esse problema
os caracteres em uma string no. Em outras palavras, strings elegantemente:
so imutveis e listas so mutveis. >>> a, b = b, a
H um outro tipo em Python chamado tupla O lado esquedo uma tupla de variveis; o lado
(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
vrgulas: avaliadas antes de qualquer das atribuies. Esta caracterstica
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
colocar tuplas entre parnteses: de valores na direita deve ser igual:
ns esperamos que um clculo d sempre o mesmo resultado. programa que divida a faixa de valores em intervalos e conte o
Entretanto, para algumas aplicaes queremos que o nmero de valores de cada intervalo.
computador se torne imprevisvel. Jogos so um exemplo
bvio, mas existem outros.
Fazer um programa realmente no- 9.6 Contando
determinstico se mostra no ser to fcil, mas existem
maneiras de faz-lo ao menos parecer no-determinstico. Uma boa maneira de abordar problemas como esse dividir o
Uma dessas maneiras gerar nmeros aleatrios e us-los problema em subproblemas, e encontrar um subproblema que
para determinar o resultado de um programa. Python tem uma se enquadre em um padro de soluo computacional que
funo nativa que gera nmeros pseudo aleatrios, os quais voc j tenha visto antes.
no so verdadeiramente aleatrios no sentido matemtico,
mas para os nossos propsitos eles so. Neste caso, queremos percorrer uma lista de
nmeros e contar o nmero de vezes que valor se encaixa em
O mdulo random contm uma funo chamada um determinado intervalo. Isso soa familiar. Na Seo 7.8,
random que retorna um nmero em ponto flutuante (floating- ns escrevemos um programa que percorria uma string e
point number) entre 0.0 e 1.0. Cada vez que voc chama contava o nmero de vezes que uma determinada letra
random, voc recebe o prximo nmero de uma longa srie. aparecia.
Para ver uma amostra, execute este loop:
Assim, podemos prosseguir copiando o
import random programa original e adaptando-o para o problema atual. O
programa original era:
for i in range(10):
x = random.random() contador = 0
print x for letra in fruta:
if letra == 'a':
Para gerar um nmero aleatrio ente 0.0 e um
limite superior, digamos superior, multiplique x por superior. contador = contador + 1
print contador
Como exerccio, gere um nmero aleatrio entre O primeiro passo substituir fruta por lista e
'inferior' e 'superior'. letra por numero. Isso no muda o programa, apenas o ajusta
Como exerccio adicional, gere um nmero para que ele se torne mais fcil de ler e entender.
inteiro aleatrio entre 'inferior' e 'superior', inclusive os dois O segundo passo mudar o teste. Ns no
extremos. estamos interessados em procurar letras. Ns queremos ver se
numero est entre inferior e superior.:
contador = 0
9.5 Lista de nmeros aleatrios
for numero in lista
if inferior < numero < superior:
O primeiro passo gerar uma lista aleatria de valores.
listaAleatoria pega um parmetro inteiro e retorna uma lista de contador = contador + 1
nmeros aleatrios com o comprimento dado. Inicia-se com print contador
uma lista de n zeros. A cada iterao do loop, ele substitui um O ltimo passo encapsular este cdigo em
dos elementos por um nmero aleatrio. O valor retornado uma funo chamada noIntervalo. Os parmetros so a lista e
uma referncia para a lista completa: os valores inferior e superior:
def listaAleatoria(n): def noIntervalo(lista, inferior, superior):
s = [0] * n contador = 0
for i in range(n): for numero in lista:
s[i] = random.random() if inferior < numero < superior:
return s contador = contador + 1
Vamos realizar um teste desta funo com uma return contador
lista de oito elementos. Para efeitos de depurao, uma boa Atravs da cpia e da modificao de um
idia comear com uma lista pequena. programa existente, estamos aptos a escrever esta funo
>>> listaAleatoria(8)
rapidamente e economizar um bocado de tempo de depurao.
Este plano de desenvolvimento chamado de casamento de
0.15156642489 padres. Se voc se encontrar trabalhando em um problema
0.498048560109 que voc j solucionou antes, reuse a soluo.
0.810894847068
0.360371157682
0.275119183077 9.7 Vrios intervalos
0.328578797631
0.759199803101 Conforme o nmero de intervalos aumenta, noIntervalo torna-
0.800367163582 se intragvel. Com dois intervalos, no to ruim:
Os nmeros gerados por random so
supostamente uniformemente distribudos, o que significa que inferior = noIntervalo(a, 0.0, 0.5)
cada valor tem uma probabilidade igual de acontecer. superior = noIntervalo(a, 0.5, 1)
Mas com quatro intervalos, comea a ficar
Se ns dividirmos a faixa de valores possveis desconfortvel.:
em intervalos do mesmo tamanho, e contarmos o nmero de
vezes que um determinado valor aleatrio caiu em seu intervalo1 = noIntervalo(a, 0.0, 0.25)
respectivo intervalo, ns devemos obter o mesmo nmero intervalo2 = noIntervalo(a, 0.25, 0.5)
aproximado de valores em cada um dos intervalos.
intervalo3 = noIntervalo(a, 0.5, 0.75)
Ns podemos testar esta teoria escrevendo um
Os tipos compostos que voce aprendeu - strings, listas e tuplas >>> del inventario['peras']
- utilizam inteiros como indices. Se voce tentar utilizar >>> print inventario
qualquer outro tipo como indice, voce receber um erro. {'laranjas': 525, 'abacaxis': 430, 'bananas': 312}
Dicionrios sao similiares a outros tipos Ou se ns esperamos por mais peras em breve,
compostos exceto por eles poderem user qualquer tipo nos podemos simplesmente trocar o valor associoado as peras:
imutavel de dados como indice. Como exemplo, nos
criaremos um dicionrio para traduzir palavras em Ingls para >>> inventario['peras'] = 0
Espanhol. Para esse dicionrio, os indices sero strings. >>> print inventario
{'laranjas': 525, 'abacaxis': 430, 'peras': 0, \
Uma maneira de criar um dicionario
comecando com um dicionrio vazio e depois adiconando 'bananas': 312}
elementos. Um dicionrio vazio denotado assim {}: A funo len tambm funciona com dicionrios;
retornando o nmero de pares chave-valor:
>>> ing2esp = {}
>>> ing2esp['one'] = 'uno' >>> len(inventario)
>>> ing2esp['two'] = 'dos' 4
A primeira atribuio cria um dicionario
chamado ing2esp; as outras atribuies adicionam novos
elementos para o dicionrio. Nos podemos imprimir o valor 10.2 Mtodos dos Dicionrios
corrente de um dicionario da maneira usual:
>>> print ing2esp Um mtodo parecido com uma funo - possui parametros e
{'one': 'uno', 'two': 'dos'} retorna valores - mas a sintaxe diferente. Por exemplo, o
Os elementos de um dicionrio aparecem em metodo keys recebe um dicionrio e retorna uma lista com as
uma lista separada por vrgulas. Cada entrada contm um chaves, mas em vez de usarmos a sintaxe de funo
indice e um valor separado por dois-pontos. Em um keys(ing2esp), nos usamos a sintaxe de mtodo
dicionrio, os ndices sao chamados de chaves, entao os ing2esp.keys():
elementos so chamados de pares chave-valor. >>> ing2esp.keys()
Outra maneira de criar dicionrios fornecendo ['one', 'three', 'two']
uma lista de pares chaves-valor utilizando a mesma sintaxe da Dessa forma o ponto especifica o nome da
ltima sada. funo, keys, e o nome do objeto em que deve ser aplicada a
funo, ing2esp. Os parenteses indicam que esse mtodo no
>>> ing2esp = {'one': 'uno', 'two': 'dos', \ possui parameteros.
'three': 'tres'}
Ao invs de chamarmos um mtodo, dizemos
Se nos imprimirmos o valor de ing2esp que ele invocado,
novamente, nos teremos uma surpresa: nesse caso, ns podemos dizer que ns
estamos invocando keys do objeto ing2esp.
>>> print ing2esp O mtodo values parecido; retorna a lista de
{'one': 'uno', 'three': 'tres', 'two': 'dos'} valores de um dicionrio:
Os pares chave-valor no esto em ordem!
Felizmente, no a motivos para se preocupar com a ordem, >>> ing2esp.values()
desde que os elementos do dicionrio nunca sejam indexados ['uno', 'tres', 'dos']
com indices inteiros. Podemos usar as chaves para buscar os O mtodo items retorna os dois, na forma de
valores correspondentes: uma lista de tuplas - cada tupla com um par chave-valor:
>>> print ing2esp['two'] >>> ing2esp.items()
'dos' [('one','uno'), ('three','tres'), ('two','dos')]
A chave 'two' retornou o valor 'dos' mesmo A sintaxe fornece uma informao util. Os
pensando que retornaria o terceiro par chave-valor. colchetes indicam que isso uma lista. Os parentses indicam
que os elementos da lista so tuplas.
Se o mtodo recebe de algum parmetro, se
10.1 Operaes dos Dicionrios utiliza a mesma sintaxe das funes. Por exemplo, o mtodo
has_key recebe uma chave e retorna verdadeiro (1) se a chave
O comando del remove um par chave-valor de um dicionrio. existe no dicionrio:
Por exemplo, o dicionrio abaixo contem os nomes de varias
frutas e o numero de cada fruta em no estoque: >>> ing2esp.has_key('one')
True
>>> inventario = {'abacaxis': 430, 'bananas': 312, \ >>> ing2esp.has_key('deux')
'laranjas': 525, 'peras': 217} False
>>> print inventario Se voce tentar chamar um mtodo sem
{'laranjas': 525, 'abacaxis': 430, 'peras': 217, \ especificar em qual objeto, voce obter um erro. Nesse caso, a
'bananas': 312} mensagem de erro no muito til:
Se alguem comprar todas as peras, podemos >>> has_key('one')
remover a entrada do dicionrio:
Uma boa soluo guardar os valores que j Os dois primeiros numeros da sequncia so long ints, ento
foram calculados armazenando-os em um dicionrio. Um todos os nmeros subsequentes da sequncia tambm sero.
valor previamente calculado que guardado para ser utilizado
mais tarde chamado de hint. Abaixo uma implementao de Como exerccio, converta fatorial para produzir
fibonacci usando hints: um inteiro longo como resultado.
>>> previous = {0:1, 1:1}
>>> def fibonacci(n):
10.7 Contando Letras
if previous.has_key(n):
return previous[n]
No captulo 7, escrevemos uma funo que contava o nmero
else: de ocorrncias de uma letra em uma string. A verso mais
newValue = fibonacci(n-1) + \ comum desse problema fazer um histograma das letras da
fibonacci(n-2) string, ou seja, quantas vezes cada letra aparece na string.
previous[n] = newValue
Um histograma pode ser util para comprimir um
return newValue arquivo de texto. Pois diferentes letras aparecem com
O dicionrio chamado previous guarda os diferentes frequncias, podemos comprimir um arquivo
nmeros de Fibonacci que ns ja conhecemos. Ele comea usando pequenos cdigos para letras comuns e longos cdigos
com apenas dois pares: 0 possui 1; e 1 possui 1. para letras que aparecem em menor frequncia.
Sempre que fibonacci chamada, ela verifica o Dicionrios fornecem uma maneira elegante de
dicionrio para determinar se ele j possui o resultado. Se o gerar um histograma:
resultado estiver ali, a funo pode retornar imediatamente
sempre precisar fazer mais chamadas recursivas. Se o >>> letterCounts = {}
resultado no estiver ali, ele calculado no newValue. O >>> for letter in "Mississippi":
valor de newValue adicionado no dicionrio antes da funo ... letterCounts[letter] =
retornar. letterCounts.get(letter,0) + 1
Usando essa verso de fibonacci, nossa ...
mquina consegue calcular fibonacci(40) em um piscar de >>> letterCounts
olhos. Mas quando tentamos calcular fibonacci(50), ns {'M': 1, 's': 4, 'p': 2, 'i': 4}
veremos um problema diferente: Comeamos com um dicionrio vazio. Para
>>> fibonacci(50)
cada letra da string, achamos o contador (possivelmente zero)
e o incrementamos. No final, o dicionrio contem pares de
OverflowError: integer addition letras e as suas frequncias.
A resposta, que voc ver em um minuto,
20.365.011.074. O problema que esse nmero muito mais atraente mostrarmos o histograma na
grande para guardarmos como um inteiro do Python 1. Isso ordem alfabtica. Podemos fazer isso com os mtodos items e
overflow. Felizmente, esse problema tem uma soluo sort:
simples.
>>> letterItems = letterCounts.items()
>>> letterItems.sort()
>>> print letterItems
10.6 Inteiros Longos [('M', 1), ('i', 4), ('p', 2), ('s', 4)]
Voc ja tinha visto o mtodo items antes, mas
Python possui um tipo chamado long int que permite sort o primeiro mtodo que voc se depara para aplicar em
trabalharmos com qualquer tamanho de inteiros. Existem duas listas. Existem muitos outros mtodos de listas, incluindo
maneiras de criarmos um valor long int. A primeira escrever append, extend, e reverse. Consulte a documentao do
um inteiro seguido de um L no final: Python para maiores detalhes.
>>> type(1L)
<type 'long int'>
A outra maneira usarmos a funo long que 10.8 Glossrio
converte um valor para um long int. long pode receber
qualquer valor nmerico e at mesmo uma string de digitos: dicionrio Uma coleo de pares de chaves-valores
>>> long(1) (dictionary) que so mapeados pelas chaves, para se
1L
obter os valores. As chaves podem ser
qualquer tipo de dados imutavel, e os
>>> long(3.9) valores podem ser de qualquer tipo.
3L
>>> long('57') chave (key) Um valor que usado para buscar uma
57L
entrada em um dicionrio.
Todas as operaes matemticas funcionam par chave-valor Um dos itens de um dicionrio.
com long int s, ento no precisamos modificar muito para (key-value pair)
adaptar fibonacci:
mtodo Um tipo de funo que chamada com
>>> previous = {0: 1L, 1:1L} (method) uma sintaxe diferente e invocada no
>>> fibonacci(50) contexto de um objeto.
20365011074L invocar (invoke) Chamar um mtodo.
Somente trocando os valores iniciais de
previous, conseguimos mudar o comportamento da fibonacci. hint O armazenamento temporrio de um valor
pr-computado para evitar a computao
1 N.T. A partir do Python 2. XXX este erro no ocorre mais, redundante.
pois em caso de sobrecarga o valor inteiro
automaticamente promovido para o tipo long. overflow Um resultado numrico que muito
temos um erro:
Arquivos e excees
>>> f = open("teste.cat", "r")
Durante a execuo de um programa, seus dados ficam na IOError: [Errno 2] No such file or directory: \
memria. Quando o programa termina, ou o computador 'teste.cat'
desligado, os dados na memria desaparecem. Para armazenar Sem nenhuma surpresa, o mtodo read l dados
os dados permanentemente, voc tem que coloc-los em um do arquivo. Sem argumentos, ele l todo o contedo do
arquivo. Arquivos usualmente so guardados em um disco arquivo:
rgido (HD), num disquete ou em um CD-ROM.
>>> 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
imprimveis como PDF. >>> f = open("teste.dat", "r")
>>> print f.read(9)
Trabalhar com arquivos muito parecido com
trabalhar com livros. Para utilizar um livro, voc tem que abr- Agora h
lo. Quando voc termina, voc tem que fech-lo. Enquanto o Se no houver caracteres suficientes no arquivo,
livro estiver aberto, voc pode tanto l-lo quanto escrever read retorna os caracteres restantes. Quando chegamos ao final
nele. Em qualquer caso, voc sabe onde voc est situado no do arquivo, read retorna a string vazia:
livro. 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)
trechos (skip around). orade fechar o arquivo
>>> print f.read()
Tudo isso se aplica do mesmo modo a arquivos.
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 texto = f1.read(50)
(?*write*?, escrever). if texto == "":
Se no existir nenhum arquivo de nome break
teste.dat, ele ser criado. Se j existir um, ele ser substitudo f2.write(texto)
pelo arquivo que estamos gravando (ou escrevendo). f1.close()
Quando executamos um comando print sobre o f2.close()
objeto arquivo, visualizamos o nome do arquivo, o modo e a return
localizao do objeto na memria. A comando break novo. O que ele faz saltar
a execuo para fora do loop; o fluxo de execuo passa para
Para colocar dados dentro do arquivo, o primeiro comando depois do loop.
invocamos o mtodo write do objeto arquivo:
Neste exemplo, o loop while infinito porque o
>>> f.write("Agora hora") valor 1 sempre verdadeiro. O nico modo de sair do loop
>>> f.write("de fechar o arquivo") executando o break, o que ocorre quando texto a string
Fechar o arquivo diz ao sistema que terminamos vazia, o que ocorre quando alcanamos o fim do arquivo.
de escrever (gravar) e que o arquivo est livre para ser lido:
>>> f.close()
Agora podemos abrir o arquivo de novo, desta 11.1 Arquivos texto
vez para leitura, e ler o seu contedo para uma string. Desta
vez, o argumento modo ?r? para leitura (?reading?): Um arquivo texto um arquivo que contm caracteres
imprimveis e espaos, organizados dentro de linhas separadas
>>> f = open("teste.dat", "r") por caracteres de nova linha. J que Pyhton especialmente
Se tentarmos abrir um arquivo que no existe, projetado para processar arquivos texto, ele oferece mtodos
que tornam esta tarefa mais fcil.
Para demonstrar, vamos criar um arquivo texto mdulo. Mas quando o primeiro operador uma string, % o
com trs linhas de texto separadas por caracteres de nova operador de formatao.
linha:
O primeiro operando a string de formatao,
>>> f = open("teste.dat", "w") e o segundo operando uma tupla de expresses. O resultado
>>> f.write("linha um\nlinha dois\nlinha trs\n") uma string que contm os valores das expresses,
>>> f.close()
formatadas de acordo com a string de formatao.
O mtodo readline l todos os caracteres at, e Num exemplo simples, a seqncia de
incluindo, o prximo caractere de nova linha: formatao "??%d??" significa que a primeira expresso na
tupla deve ser formatada como um inteiro. Aqui a letra d
>>> f = open("teste.dat", "r") representa ?decimal?.
>>> print f.readline()
linha um >>> carros = 52
>>> "%d" % carros
>>> '52'
readlines retorna todas as linhas restantes como O resultado a string ?52?, que no deve ser
uma lista de strings: confundida com o valor inteiro 52.
>>> print f.readlines()
Uma seqncia de formatao pode aparecer em
qualquer lugar na string de formatao, assim, podemos
['linha dois\012', 'linha trs\012'] embutir um valor em uma seqncia:
Neste caso, a sada est em formado de lista, o
que significa que as strings aparecem entre aspas e o caractere >>> carros = 52
de nova linha aparece como a seqncia de escape 012. >>> "Em julho vendemos %d carros." % carros
'Em julho vendemos 52 carros.'
No fim do arquivo, readline retorna a string
vazia e readlines retorna a lista vazia: A seqncia de formatao "%f" formata o
prximo item da tupla como um nmero em ponto flutuante, e
>>> print f.readline() "%s" formata o prximo como uma string:
>>> "Em %d dias fizemos %f milhes %s." % \
>>> print f.readlines()
(34,6.1,'reais')
[]
'Em 34 dias fizemos 6.100000 milhes de reais.'
A seguir temos um exemplo de um programa de
processamento de linhas. filtraArquivo faz uma cpia de Por padro, o formato de ponto flutuante exibe
velhoArquivo, omitindo quaisquer linhas que comecem por #: seis casas decimais.
def filtraArquivo(velhoArquivo, novoArquivo):
O nmero de expresses na tupla tem que ser
igual ao nmero de seqncias de formatao na string. Alm
f1 = open(velhoArquivo, "r") disso, os tipos das expresses tm que iguais aos da seqncia
f2 = open(novoArquivo, "w") de formatao:
while 1:
texto = f1.readline() >>> "%d %d %d" % (1,2)
if texto == "": TypeError: not enough arguments for format string
break >>> "%d" % 'reais'
if texto[0] == '#': TypeError: illegal argument type for built-in \
continue operation
f2.write(texto) No primeiro exemplo, no existem expresses
f1.close()
suficientes; no segundo, a expresso do tipo errado.
f2.close() Para um controle maior na formatao de
return nmeros, podemos especificar o nmero de dgitos como parte
O comando continue termina a iterao corrente da seqncia de formatao:
do loop, mas continua iterando o loop. O fluxo de execuo >>> "%6d" % 62
passa para o topo do loop, checa a condio e prossegue
conforme o caso. ' 62'
>>> "%12f" % 6.1
Assim, se texto for a string vazia, o loop ' 6,100000'
termina. Se o primeiro caractere de texto for o jogo da velha (? O nmero depois do sinal de porcentagem o
# ?), o fluxo de execuo passa para o topo do loop. Somente nmero mnimo de espaos que o valor ocupar. Se o valor
se ambas as condies falharem que texto ser copiado para fornecido tiver um nmero menor de dgitos, espaos em
dentro do novo arquivo. branco sero adicionados antes para preencher o restante. Se o
nmero de espaos for negativo, os espaos sero adicionados
depois:
11.2 Gravando variveis >>> "%-6d" % 62
'62 '
O argumento de write tem que ser uma string, assim se
quisermos colocar outros valores em um arquivo, temos de Para nmeros em ponto-flutuante, tambm
convert-los para strings primeiro. A maneira mais fcil de podemos especificar o nmero de dgitos depois da vrgula:
fazer isso com a funo str: >>> "%12.2f" % 6.1
>>> x = 52 ' 6.10'
>>> f.write(str(x)) Neste exemplo, o resultado reserva 12 espaos e
Uma alternativa usar o operador de inclui dois dgitos depois da vrgula. Esta formatao til
formatao %. Quando aplicado a inteiros, % o operador para exibir valores monetrios com os centavos alinhados.
Por exemplo, imagine um dicionrio que comandos necessrios. Para us-lo, importe pickle e ento
contm nomes de estudantes como chaves e salrios-hora abra o arquivo da maneira usual:
como valores. Aqui est uma funo que imprime o contedo
do dicionrio como um relatrio formatado: >>> import pickle
>>> f = open(?test.pck?, ?w?)
def relatorio(salarios): Para armazenar uma estrutura de dados, use o
estudantes = salarios.keys() mtodo dump e ento feche o arquivo do modo usual:
estudantes.sort()
for estudante in estudantes: >>> pickle.dump(12.3, f)
print "%-20s %12.02f" % (estudante, \ >>> pickle.dump([1,2,3], f)
salarios[estudante]) >>> f.close()
Para testar esta funo, criaremos um pequeno Ento, podemos abrir o arquivo para leitura e
dicionrio e imprimiremos o contedo: carregar as estruturas de dados que foram descarregadas
(dumped):
>>> salarios = {'maria': 6.23, 'joo': 5.45, \
>>> f = open(?test.pck?, ?r?)
'josu': 4.25}
>>> x = pickle.load(f)
>>> relatorio(salarios)
>>> x
joo 5.45
12,3
josu 4.25
>>> type(x)
maria 6.23
<type ?float?>
Controlando a largura de cada valor, podemos
garantir que as colunas ficaro alinhadas, desde que os nomes >>> y = pickle.load(f)
contenham menos que vinte e um caracteres e os salrios >>> y
sejam menores do que um bilho de reais por hora. [1, 2, 3]
>>> type(y)
<type ?list?>
11.3 Diretrios Cada vez que invocamos load, obtemos um
nico valor do arquivo, completo com seu tipo original.
Quando voc cria um novo arquivo abrindo-o e escrevendo
nele, o novo arquivo fica no diretrio corrente (seja l onde
for que voc esteja quando rodar o programa). Do mesmo 11.5 Excees
modo, quando voc abre um arquivo para leitura, Python
procura por ele no diretrio corrente.
Whenever que um erro em tempo de execuo acontece, ele
Se voc quiser abrir um arquivo que esteja em gera uma exceo. Usualmente, o programa pra e Python
algum outro lugar, voc tem que especificar o caminho (path) exibe uma mensagem de erro.
para o arquivo, o qual o nome do diretrio (ou folder) onde
o arquivo est localizado: Por exemplo, dividir por zero gera uma
exceo:
>>> f = open("/usr/share/dict/words", "r")
>>> print 55/0
>>> print f.readline()
ZeroDivisionError: integer division or modulo
Aarhus
Este exemplo abre um arquivo chamado words Do mesmo modo, acessar um item de lista
que reside em um diretrio de nome dict, o qual reside em inexistente:
share, o qual reside em usr, o qual reside no diretrio de mais >>> a = []
alto nvel do sistema, chamado /. >>> print a[5]
Voc no pode usar / como parte do nome de IndexError: list index out of range
um arquivo; ela um caractere reservado como um Ou acessar uma chave que no est em um
delimitador entre nomes de diretrios e nomes de arquivos. dicionrio:
O arquivo /usr/share/dict/words contm uma >>> b = {}
lista de palavras em ordem alfabtica, na qual a primeira >>> print b[?what?]
palavra o nome de uma universidade Dinamarquesa.
KeyError: what
Em cada caso, a mensagem de erro tem duas
partes: o tipo do erro antes dos dois pontos, e especificidades
11.4 Pickling do erro depois dos dois pontos. Normalmente Python tambm
exibe um ?*traceback*? de onde estava a execuo do
Para colocar valores em um arquivo, voc tem que convert- programa, mas ns temos omitido esta parte nos exemplos.
los para strings. Voc j viu como fazer isto com str: s vezes queremos executar uma operao que
>>> f.write (str(12.3)) pode causar uma exceo, mas no queremos que o programa
>>> f.write (str([1,2,3]))
pare. Ns podemos tratar a exceo usando as instrues try e
except.
O problema que quando voc l de volta o
valor, voc tem uma string. O Tipo original da informao foi Por exemplo, podemos pedir ao usurio um
perdido. De fato, voc no pode sequer dizer onde comea um nome de arquivo e ento tentar abr-lo. Se o arquivo no
valor e termina outro: existe, no queremos que o programa trave; queremos tratar a
exceo:
>>> f.readline()
?12.3[1, 2, 3]? nomedoarquivo = raw_input(?Entre com o nome do \
A soluo o pickling, assim chamado porque ? arquivo: ?)
preserva? estruturas de dados. O mdulo pickel contm os try:
12.9 Glossrio
Converso de base mais abstrata; nossa intuio para lidar Na nossa opinio, preocupante que humanos
com horrios melhor. gastem tanto tempo na escola aprendendo a executar
algoritmos que, literalmente, no requerem inteligncia.
Mas se conseguirmos abstrair horrios como
nmeros de base 60 e investirmos em criar as funes de Por outro lado, o processo de projetar
converso (converterParaSeguntos e criarHorario), ns algoritmos interessante, intelectualmente desafiante, e uma
conseguimos um programa que menor, fcil de ler e depurar, parte central daquilo que chamamos programao.
e mais confivel.
Algumas das coisas que as pessoas fazem
tambm fcil para adicionar funcionalidades naturalmente, sem dificuldade ou conscincia, so as mais
depois. Por exemplo, imagine subtrair dois Horarios para difceis de se expressar atravs de algoritmos. Entender a
encontrar a durao entre eles. Uma aproximao ingnua linguagem natural um bom exemplo. Todos ns fazemos
seria implementar subtrao com emprstimo. Usando as isso, mas at hoje ningum conseguiu explicar como fazemos
funes de converso ser mais fcil e provavelmente estar isso, pelo menos no na forma de algoritmo. Clique aqui para
correto. feedback.
Ironicamente, algumas vezes fazer um problema
mais difcil (ou mais genrico) o torna mais simples (porque
existem alguns poucos casos especiais e poucas oportunidades 13.8 Glossrio
para errar). Clique aqui para feedback
funo pura (pure Uma funo que no modifica
function) nenhum dos objetos que ela recebe
13.7 Algoritmos como parmetro. A maioria das
funes puras frutfera.
Quando voc escreve uma soluo genrica para uma classe modificador Uma funo que muda um ou mais
de problemas, ao contrrio de uma soluo especfica para um (modifier) dos objetos que ela recebe como
nico problema, voc escreveu um algoritmo. Ns parmetros. A maioria dos
mencionamos isso antes mas no definimos cuidadosamente. modificadores nula.
Isso no fcil para definir, ento vamos tentar definir
demonstrando algumas situaes. estilo de Um estilo de programao onde a
programao maioria das funes so puras.
Primeiramente, considere alguma coisa que no funcional (functional
seja um algoritmo. Quando voc aprendeu a multiplicar programming style)
nmeros de um dgito, voc provavelmente memorizou a
tabela de multiplicao. Como resultado, voc memorizou 100 desenvolvimento Uma maneira de desenvolver
solues especficas. Esse tipo de conhecimento no prototipado programas comeando com um
algoritmo. (prototype prottipo e gradualmente
development) melhorando-o.
Mas se voc "preguioso", voc
provavelmente trapaceou por ter aprendido alguns truques. desenvolvimento Uma maneira de desenvolver
Por exemplo, para encontrar o produto de n e 9, voc pode planejado (planned programas que envolvem uma
escrever n-1 como o primeiro dgito e 10-n como o segundo development) percepo de alto nvel do problema
dgito. Este truque um soluo genrica para multiplicar e mais planejamento do que
qualquer nmero de um dgito por 9. Isso um algoritmo! desenvolvimento incremental ou
desenvolvimento prototipado.
De modo parecido, as tcnicas que voc
aprendeu para somar com transporte, subtrao com algoritmo (algorithm) Um conjunto de instrues para
emprstimo, e diviso longa so todas algoritmos. Uma das resolver uma classe de problemas
caractersticas dos algoritmos que eles no requerem usando um processo mecnico, no
nenhuma inteligncia para serem executados. Eles so inteligente.
processos mecnicos no qual cada passo segue o ltimo de
acordo com um conjunto simples de regras.
14.3 Um outro exemplo orientada a tais como classes definidas pelo usurio e
objetos herana, que facilitam a programao
orientada a objetos.
Vamos converter incremento (da Seo 13.3) em um mtodo.
Para poupar espao, deixaremos de fora mtodos definidos programao Um estilo de programao na qual os
previamente(anteriormente?), mas voc deve mant-los em orientada a dados e as operaes que os manipulam
sua verso: objetos esto organizados em classes e mtodos.
class Time: mtodo Uma funo que definida dentro de uma
#previous method definitions here... definio de classe e chamada em
instncias desta classe.
def increment(self, segundos): override (sem Substituir uma definio j pronta.
self.seconds = seconds + self.seconds traducao; Exemplos incluem substituir um
termo parmetro padro por um argumento
consagrado) particular e substituir um mtodo padro,
while self.segundos >= 60: fornecendo um novo mtodo com o
self.seconds = self.segundos - 60 mesmo nome.
self.minutes = self.minutos + 1
mtodo de Um mtodo especial que invocado
inicializao automaticamente quando um novo objeto
while self.minutes >= 60: (tambem criado e que inicializa os atributos deste
self.minutes = self.minutos - 60 chamado de objeto.
self.hours = self.horas + 1 construtor)
A transformao puramente mecnica ? sobrecarga de Estender a funcionalidade dos operadores
movemos a definio do mtodo para dentro da definio da operador nativos (+, -, *, >, <, etc.) de forma que
classe e mudamos o nome do primeiro parmetro. eles funcionem tambm com tipos
Agora podemos chamar incremento como um definidos pelo usurio.
mtodo: produto escalar Operao definida na lgebra linear que
horaCorrente.incremento(500) multiplica dois pontos (com coordenadas
(x,y,z)) e retorna um valor numrico.
De novo, o objeto no qual o mtodo chamado
gets atribui ao primeiro parmetro, self. O segundo parmetro, multiplicao Operao definida na lgebra linear que
segundo toma(gets) o valor 500. por escalar multiplica cada uma das coordenadas de
um ponto por um valor numrico.
Como um exerccio, converta ?
converteParaSegundos? (da Seo 13.5) para um mtodo na polimrfica Uma funo que pode operar com mais de
classe ?Time?. 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
Rainha -> 12
15.1 Composio
Rei -> 13
At agora, voc vio diversos exemplos de composio. Um O motivo pelo qual ns estamos usando notao
dos primeiros exemplos foi o uso de uma invocao de matemtica para estes mapeamentos que eles no so parte
mtodo como parte de uma expresso. Outro exemplo a do programa Python. Eles so parte do projeto do programa,
estrutura aninhada dos comandos: voc pode pr um comando mas eles nunca aparecem explicitamente no cdigo. A
if dentro de um lao while, dentro de outro comando if, e definio de classe para o tipo Carta fica parecida com esta:
assim por diante.
class Carta:
Tendo visto este padro, e tendo aprendido a
respeito de listas e objetos, voc no deveria ficar surpreso em def __init__(self, naipe=0, posicao=0):
aprender que voc pode criar listas de objetos. Voc tambm self.naipe = naipe
pode criar obejtos que contm listas (como atritos); voc pode self.posicao = posicao
criar listas que contm listas; voc pode criar objetos que Como sempre, ns fornecemos um mtodo de
contm objetos; e assim por diante. inicializao que recebe um parmetro opcional para cada
Neste captulo e no prximo, voc ir ver alguns atributo.
exemplos destas combinaes, usando objetos Carta como Para criar um objeto que representa o 3 de Paus,
exemplo. usa-se este comando:
tresDePaus = Carta(0, 3)
15.2 Objetos Carta O primeiro argumento, 0, representa o naipe de
Paus.
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 15.3 Atributos de classe e o mtodo __str__
baralho, cada uma das quais pertence a um dos quatro naipes e
a uma das treze posies. Os naipes so Espadas, Copas, Para imprimir objetos Carta de uma maneira que as pessoas
Ouros e Paus (em ordem descendente no bridge). As posies possam facilmente ler, ns gostaramos de mapear os cdigos
so s, 2, 3, 4, 5, 6, 7, 8, 9, 10, Valete, Rainha e Rei. inteiros para palavras. Uma forma natural de fazer isso usar
Dependendo do jogo, a posio do s pode ser maior do que a listas de strings. Ns atribumos estas listas para atributos de
do Rei ou menor do que a do 2. classe no topo da definio de classe:
Se quisermos definir um novo objeto para class Carta:
representar uma carta, bvio que os atributos devem ser
posicao e naipe. No to bvio so os tipos aos quais devem listaDeNaipes = ["Paus", "Ouros", "Copas",
pertencer os atributos. Uma possibilidade usar strings "Espadas"]
contendo palavras como "Espada" para naipes e "Rainha" para listaDePosicoes = ["narf", "s", "2", "3", "4",
posies. Um problema com esta implementao que no "5", "6", "7",
seria fcil comparar cartas para ver qual possui o maior naipe "8", "9", "10", "Valete",
ou posio. "Rainha", "Rei"]
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
que os naipes so mapeados para inteiros na ordem, de modo de classe chamado listaDeNaipes, e selecione a string
que ns podemos comparar naipes pela comparao de apropriada".
inteiros. O mapeamento de posies bastante bvio. Cada O motivo para o "narf" no primeiro elemento
uma das posies numricas mapeia para o inteiro em listaDePosicoes preencher o lugar do 0-simo elemento
correspondente e, as cartas com figura so mapeadas da lista, que nunca ser usado. As nicas posies vlidas so
conforme abaixo: de 1 a 13. Este item desperdiado no inteiramente
Valete -> 11 necessrio. Ns poderamos ter iniciado com 0, como
normal. Porm, menos confuso codificar 2 como 2, 3 como
15.9 Glossrio
figura mostra uma lista com dois ns, um dos quais refere-se a
si mesmo:
class No:
...
O que acontece se voc invocar este mtodo e def imprimeDeTrasParaFrente(self):
passar uma lista com somente um elemento (um singleton)? O if self.proximo != None:
que acontece se voc passar a lista vazia como um argumento? rabo = self.proximo
Existe uma pr-condio para este mtodo? Se houver, corrija
o mtodo para tratar uma violao da pr-condio de modo rabo.imprimeDeTrasParaFrente()
razovel. print self.carga,
Apenas para tornar as coisas confusas,
mudamos o nome de imprimeDeTrasParaFrenteLegal. Agora
existem dois mtodos chamados imprimeDeTrasParaFrente:
17.8 Envoltrios e Ajudadores um na classe No (o ajudador); e um na classe ListaLigada``(o
envoltrio). Quano o envoltrio invoca
Freqentemente til dividir uma operao de lista em dois ``self.cabeca.imprimeDeTrasParaFrente, ele est invocando o
mtodos. Por exemplo, para imprimir uma lista de trs para ajudador, porque self.cabeca um objeto No.
frente no formato convencional de lista [3, 2, 1], podemos
usar o mtodo imprimeDeTrasParaFrente para imprimir 3, 2, Outro benefcio da classe ListaLigada que ela
mas queremos um metodo separado para imprimir os torna mais fcil adicionar e remover o primeiro elemento de
braquetes e o primeiro n. Vamos cham-lo de uma lista. Por exemplo, adicionaPrimeiro um mtodo para
imprimeDeTrasParaFrenteLegal: ListaLigada; ele toma um item de carga como argumento e o
coloca no incio da lista:
def imprimeDeTrasParaFrenteLegal(lista):
class ListaLigada:
print "[",
...
if lista != None :
18.1 Tipos abstratos de dados 18.3 Implementando pilhas com listas de Python
Os tipos de dados que voc viu at agora so todos concretos, As operaes de lista que Python oferecem so similares s
no sentido que ns especificamos completamente como eles operaes que definem uma pilha. A interface no
so implementados. Por exemplo, a classe Card(XXX ver exatamente o que se supe ser, mas podemos escrever um
como foi traduzido) representa uma carta utilizando dois cdigo para traduzir do TAD Pilha para as operaes nativas.
inteiros. Como discutimos no momento, esta no a nica
maneira de representar uma carta; existem muitas Este cdigo chamado uma implementao do
implementaes alternativas. TAD Pilha. Geralmente, uma implementaa um conjunto
de mtodos que satisfazem os requisitos sintticos e
Um tipo abstrato de dado, ou TAD, especifica semnticos de uma interface.
um conjunto de operaes (ou mtodos) e a semntica das
operaes (o que elas fazem), mas no especifica a Aqui est uma implementao do TAD Pilha
implementao das operaes. Isto o que o faz abstrato. que usa uma lista do Python:
Por que isto til? class Stack :
def __init__(self) :
Simplifica a tarefa dde especificar um algoritmo se self.items = []
voc pode XXXdenotar(denote) as operaes que
voc precisa sem ter que pensar, ao mesmo tempo,
como as operaes so executadas. def push(self, item) :
self.items.apend(item)
Uma vez que existem geralmente muitas maneiras de
implementar um TAD, pode ser til escrever um
algritmo que pode ser usado com qualquer das def pop(self) :
possveis implementaes. return self.items.pop()
18.9 Glossrio
Este captulo apresenta dois TDAs: Fila e Fila por Prioridade. else:
Na nossa vida diria, fila um alinhamento de consumidores # find the last node in the list
aguardando algum tipo de servio. Na maioria dos casos, o last = self.head
primeiro da fila o primeiro a ser atendido. Mas h excees.
No aeroporto, passageiros cujo vo vai decolar logo, s vezes while last.next: last = last.next
so chamados primeiro ao balco do check-in, mesmo que # append the new node
estejam no meio da fila. No supermercado, comum na fila do last.next = node
caixa algum deixar passar na frente uma pessoa que chega self.length = self.length + 1
fila s com um ou dois produtos na mo.
A regra que determina quem o prximo da fila def remove(self):
chama-se poltica de enfileiramento. A poltica de cargo = self.head.cargo
enfileiramento mais simples chama-se FIFO, sigla de first-in- self.head = self.head.next
first-out: primeiro a entrar, primeiro a sair. A poltica de self.length = self.length - 1
enfileiramento mais geral o enfileiramento por prioridade,
em que se atribui uma prioridade a cada pessoa da fila e a que return cargo
tiver maior prioridade vai primeiro, independente da sua Os mtodos isEmpty e remove so idnticos aos
ordem de chegada. Dizemos que essa a poltica mais geral mtodos isEmpty e removeFirst de LinkedList. O mtodo
de todas, porque a prioridade pode ser baseada em qualquer insert novo e um pouco mais complicado.
coisa: hora de partida do vo; quantos produtos a pessoa vai
passar pelo caixa; o grau de prestgio da pessoa. claro que Queremos inserir novos itens no fim da lista. Se
a fila estiver vazia, basta fazer head apontar ao novo n. Se
nem todas as polticas de enfileiramento so "justas", mas o
que justo depende do ponto de vista. no, percorremos a lista at o ltimo n e l penduramos o
novo n. possvel identificar o ltimo n porque o seu
O TDA Fila e o TDA Fila por Prioridade tm o atributo next None.
mesmo conjunto de operaes. A diferena est na semntica
das operaes: a fila usa a poltica FIFO; e a fila por Existem duas invariantes para um objeto Fila
prioridade (como o prprio nome sugere) usa a poltica de bem formado: o atributo length deve ser o nmero de ns na
enfileiramento por prioridade. fila, e o ltimo n deve ter seu atributo next igual a None.
Estude o mtodo at ficar convencido de que ele preserva
ambas invariantes.
19.1 Um TDA Fila
19.3 Caractersticas de performance
O TDA Fila definido pelas seguintes operaes:
__init__ Inicializar uma nova fila vazia. Quando invocamos um mtodo, normalmente no estamos
preocupados com os detalhes da sua implementao. Porm,
insert Adicionar um novo item fila. h um certo "detalhe" que pode ser bom conhecer: as
caractersticas de performance do mtodo. Quanto tempo leva,
remove Remover e retornar um item da fila. O item e como o tempo de execuo muda medida em que aumenta
retornado o que foi adicionado primeiro. o nmero de itens da coleo?
isEmpty Checar se a fila est vazia. 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
mtodo assim chamado de operao de tempo constante.
19.2 Fila encadeada Na verdade, o mtodo pode ser ligeiramente mais rpido
quando a lista est vazia, uma vez que ele pula o corpo da
A primeira implementao que vamos ver de um TDA Fila condicional, mas essa diferena no significativa. XXX: o
chama-se fila encadeada porque feita de objetos Ns condicional s aparece na re-implementao do mtodo na
encadeados. A definio da classe a seguinte: classe ImprovedQueue, p.200; essa inconsistncia pode ser
conferida tambm nas pginas 198-199 do livro original (PDF
class Queue: e impresso).
def __init__(self): A performance de insert muito diferente. No
self.length = 0 caso geral, temos de percorrer a lista para achar o ltimo
self.head = None elemento.
Este percurso leva um tempo proporcional
def isEmpty(self): extenso da lista. Uma vez que o tempo de execuo uma
return (self.length == 0) funo linear da extenso, dizemos que este mtodo opera em
tempo linear. Isso bem ruim, se comparado com o tempo
def insert(self, cargo): constante.
node = Node(cargo)
node.next = None
if self.head == None: 19.4 Fila encadeada aprimorada
# if list is empty the new node goes first
self.head = node Queremos uma implementao do TDA Fila que possa
13 >>> pq = PriorityQueue()
12 >>> pq.insert(tiger)
11 >>> pq.insert(phil)
Se a fila contm nmeros ou strings simples, >>> pq.insert(hal)
eles so removidas em ordem numrica decrescente ou >>> while not pq.isEmpty(): print pq.remove()
alfabtica invertida (de Z at A). Pyhton consegue achar o Tiger Woods : 61
maior inteiro ou string porque consegue compar-los usando Hal Sutton : 69
os operadores de comparao nativos.
Phil Mickelson : 72
Se a fila contm objetos de outro tipo, os Como exerccio, escreva uma implementao do
objetos tm que prover um mtodo __cmp__. Quando remove TDA Fila por Prioridade usando uma lista encadeada.
usa o operador > para comparar dois itens, o mtodo __cmp__ Mantenha a lista em ordem para que a remoo seja uma
de um dos itens invocado, recebendo o segundo item como operao de tempo constante. Compare a performance dessa
argumento. Desde que o mtodo __cmp__ funcione de forma implementao com a implementao usando uma lista
consistente, a Fila por Prioridade vai funcionar. nativa do Python.
Em seguida, definimos uma verso de __cmp__, fila por Poltica de enfileiramento em que cada
ma qual a pontuao mais baixa fica com prioridade mxima. prioridade membro tem uma prioridade, determinada
Como sempre, __cmp__ retorna 1 se self "maior que" other, (priority queue) por fatores externos. O membro com a
-1 se self "menor que" other, e 0 se eles so iguais. maior prioridade o primeiro a ser
removido.
class Golfer: Fila por TAD que define as operaes comuns de
#... Prioridade acontecerem em uma fila por prioridade.
def __cmp__(self, other): (Priority
if self.score < other.score: return 1 # less Queue)
is more
fila encadeada Implementao de uma fila usando uma
if self.score > other.score: return -1 (linked queue) lista encadeada.
return 0
Agora estamos prontos para testar a fila por tempo constante Operao cujo tempo de execuo no
prioridade com a classe Golfer: (constant time) depende do tamanho da estrutura de
dados.
>>> tiger = Golfer("Tiger Woods", 61)
tempo linear Operao cujo tempo de execuo uma
>>> phil = Golfer("Phil Mickelson", 72) (linear time) funo linear do tamanho da estrutura de
>>> hal = Golfer("Hal Sutton", 69) dados.
>>>
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
frequentemente omitimos os Nones. tree = Tree(1, left, right);
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))
nas pontas contendo as referncias vazia so chamadas de De qualquer forma, o resultado a rvore que
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 20.2 Percorrendo rvores
misturam outra metfora alm da metfora biolgica - a rvore
genealgica. Uma clula superior pode ser chamada de pai e
as clulas a que ela se refere so chamadas de seus filhos. Cada vez que Voc v uma nova estrutura de dados, sua
Clulas com o mesmo pai so chamadas de irmos. primeira pergunta deveria ser "Como eu percorro esta
estrutura?" A forma mais natural de percorrer uma rvore
Finalmente, existe tambm o vocabulrio fazer o percurso recursivamente. Por exemplo, se a rvore
geomtrico para falar de rvores. J mencionamos esquerda e contm inteiros na carga, a funo abaixo retorna a soma das
direita, mas existem tambm as direes "para cima" (na cargas:
direo da raiz) e "para baixo" (na direo dos filhos/folhas).
Ainda nesta terminologia, todas as clulas situadas mesma def total(tree) :
distncia da raiz constituem um nvel da rvore. if tree == None : return 0
return total(tree.left) + total(tree.right) +
Provavelmente no precisamos de trs
metforas para falar de rvores, mas a elas esto. tree.cargo
O caso base a rvore vazia, que no contm
Como listas ligadas, rvores so estruturas de nenhuma carga, logo a soma das cargas 0. O passo recursivo
dados recursivas j que elas so definidas recursivamente: faz duas chamadas recursivas para achar a soma das cargas
das subrvores dos filhos. Ao finalizar a chamada recursiva,
Uma rvore adicionamos a carga do pai e devolvemos o valor total.
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
exemplo, a expresso infixa 1 + 2 * 3 ambgua, a menos que
saibamos que a multiplicao feita antes da adio. rvore numa ordem diferente, Voc produzir expresses
numa notao diferente. Por exemplo, se Voc imprime
A rvore de expresso seguinte representa a subrvores primeiro e depois a raiz, Voc ter:
mesma computao:
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)
O resultado 1 + 2 * 3, que a expresso na
notao infixa.
Para sermos justos, devemos lembrar que
As clulas de uma rvore de expresso podem acabamos de omitir uma complicao importante. algumas
ser operandos como 1 e 2 ou operaes como + e *. As clulas vezes quando escrevemos expresses na notao infixa
contendo operandos so folhas; aquelas contendo operaes devemos usar parntesis para prescrever a ordem das
devem ter referncias aos seus operandos. (Todos os nossos operaes. Ou seja, um percurso em inordem no suficiente
operandos so binrios, significando que eles tem exatamente para gerar a expresso infixa.
dois operandos.)
Ainda assim, com alguns aperfeioamentos, a
Podemos construir rvores assim: rvore de expresso e os trs modos recursivos de percurso
resultam em algoritmos para transformar expresses de uma
>>> tree = Tree('+', Tree(1), Tree('*', Tree(2), notao para outra.
Tree(3)))
Examinando a figura, no h dvida quanto Como um exerccio, modifique
ordem das operaes; a multiplicao feita primeiro para `printTreeInorder` de modo que ele coloque parntesis em
calcular o segundo operando da adio. volta de cada operador e par de operandos. A sada correta
e no ambgua? Os parntesis so sempre necessrios?
rvores de expresso tem muitos usos. O
exemplo neste captulo usa rvores para traduzir expresses Se percorrermos uma rvore em inordem e
para as notaes psfixa, prefixa e infixa. rvores similares acompanharmos em qual nvel na rvore estamos, podemos
so usadas em compiladores para analisar sintaticamente, gerar uma representao grfica da rvore:
otimizar e traduzir programas.
def printTreeIndented(tree, level=0) :
if tree == None : return
printTreeIndented(tree.right, level+1)
20.4 Percurso de rvores print ' '*level + str(tree.cargo)
printTreeIndented(tree.left, level+1)
Podemos percorrer uma rvore de expresso e imprimir o seu O parmetro level registra aonde estamos na
contedo como segue: rvore. Por 'default', o nvel inicialmente zero. A cada
def printTree(tree) : chamada recursiva repassamos level+1 porque o nvel do filho
if tree == None : return
sempre um a mais do que o nvel do pai. Cada item
indentado dois espaos por nvel. Para o nosso exemplo
print tree.cargo, obtemos:
printTree(tree.left)
printTree(tree.right) >>> printTreeIndented(tree)
Em outras palavras, para imprimir uma rvore, 3
imprima primeiro o contedo da raiz, em seguida imprima *
toda a subrvore esquerda e finalmente imprima toda a 2
subrvore direita. Esta forma de percorrer uma rvore +
chamada de prordem, porque o contedo da raiz aparece 1
antes dos contedos dos filhos. Para o exemplo anterior, a
sada : Se Voc deitar a sada acima Voc enxerga uma
verso simplificada da figura original.
>>> tree = Tree('+', Tree(1), Tree('*', Tree(2),
Tree(3)))
>>> printTree(tree) 20.5 Construindo uma rvore de expresso
+ 1 * 2 3
Esta notao diferente tanto da notao Nesta seo analisamos expresses infixas e construmos as
psfixa quanto da infixa; uma notao chamada de prefixa, rvores de express correspondentes. Por exemplo, para a
em que os operadores aparecem antes dos seus operandos. expresso (3+7)*9 resultar a seguinte rvore:
Voc pode suspeitar que se Voc percorre a
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) :
from string import lower
ans = lower(raw_input(ques))
return (ans[0:1] == 'y')
A condio do lao externo 1`, que significa
que ele continuar at a execuo de um comando break, caso
o usurio no pense num animal.
No comeo de cada rodada, o programa parte do
topo da rvore e faz a primeira pergunta. Dependendo da O lao while interno caminha na rvore de cima
resposta, ele segue pelo filho esquerdo ou direito e continua para baixo, guiado pelas respostas do usurio.
at chegar numa folha. Neste ponto ele arrisca um palpite. Se
o palpite no for correto, ele pergunta ao usurio o nome de Quando uma nova clula adicionada rvore,
um novo animal e uma pergunta que distingue o palpite errado a nova pergunta substitui a carga e os dois filhos so o novo
do novo animal. A seguir, adiciona uma clula rvore animal e a carga original.
contendo a nova pergunta e o novo animal. Uma falha do programa que ao sair ele
Aqui est o cdigo: esquece tudo que lhe foi cuidadosamente ensinado!
def animal() : A ttulo de exerccio, pense de vrias jeitos para
salvar a rvore do conhecimento acumulado num arquivo.
# start with a singleton Implemente aquele que Voc pensa ser o mais fcil.
root = Tree("bird")
6. COLLECTIONS OF DOCUMENTS
9. TERMINATION
You may make a collection consisting of the Document and
other documents released under this License, and replace the You may not copy, modify, sublicense, or distribute the
individual copies of this License in the various documents Document except as expressly provided for under this
with a single copy that is included in the collection, providedLicense. Any other attempt to copy, modify, sublicense or
that you follow the rules of this License for verbatim copying distribute the Document is void, and will automatically
of each of the documents in all other respects. terminate your rights under this License. However, parties
You may extract a single document from such a who have received copies, or rights, from you under this
collection, and distribute it individually under this License, License will not have their licenses terminated so long as such
provided you insert a copy of this License into the extracted parties remain in full compliance.
document, and follow this License in all other respects
regarding verbatim copying of that document.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised
versions of the GNU Free Documentation License from time
to time. Such new versions will be similar in spirit to the
present version, but may differ in detail to address new
problems or concerns. See http://www.gnu.org/copyleft/.
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
Free Software Foundation. If the Document does not specify a