aprenda a programar-luciano ramalho

Upload: rodrigo-scimini-gibba

Post on 10-Oct-2015

61 views

Category:

Documents


0 download

TRANSCRIPT

  • Aprenda a programarpor Luciano Ramalho

    Porque aprender a programar?

    A razo fundamental, que nos motivou a produzir este tutorial, uma s: programar divertido. claro que nem todo mundo vai concordar com isso, assim como muita gente no acha graa nenhumaem jogar xadrez ou explorar cavernas. Ao contrrio do xadrez e da espeleologia, a programaotambm uma habilidade que tem forte demanda no mercado de trabalho.Mas a dura realidade que somente com centenas ou milhares de horas de experincia programando que voc estar apto a incluir essa disciplina em seu currculo e se dar bem em uma entrevista deemprego. Portanto nosso objetivo aqui bem mais modesto do que transformar voc em umprogramador profissional. O que estamos te oferecendo uma introduo suave a esse tpicofascinante. Ao final, esperamos que voc descubra se tem a vocao e a motivao necessrias paracriar softwares, como hobby ou profisso.Antes de comear, apenas um aviso: o prazer de construir um programa pode causar dependnciapsicolgica. No apenas por dinheiro que programadores do mundo inteiro varam noites escrevendocdigo.

    Captulo 0 Porque aprender a programar? Material necessrio

    Captulo 1 Captulo 2 Captulo 3 Captulo 4 Captulo 5 Captulo 6 Exemplos Diagrama lunar

    Material necessrio

    Para acompanhar esse tutorial voc precisar de um computador qualquer onde tenha instalado uminterpretador da linguagem Python. Na pgina http://www.python.org/download/ voc encontra linkspara baixar o interpretador adequado para o seu computador. No caso do Windows, o download daverso atual tem cerca de 5MB, pois inclui tambm a linguagem Tcl e o pacote de programaogrfica Tk. Se voc usa Linux, existe uma alta probabilidade de j ter o interpretador instalado.Experimente digitar "python" no seu shell.

    Porqu Python

    Nossa meta no mostrar como se programa em uma linguagem especfica, mas sim como seprograma de uma forma geral. Ou seja, a linguagem para ns ser um veculo, e no o destino.Mesmo assim, pensamos bastante antes de escolher a linguagem Python para os exemplos dessetutorial. Centenas de linguagens j foram criadas desde que o computador eletrnico foi inventado nos anos40. Algumas j so lnguas mortas. Outras, como C++ e Java, so peas fundamentais nodesenvolvimento da economia digital. No entanto, a complexidade dessas duas linguagens nos

  • motivou a descart-las, e focalizar o universo das chamadas linguagens de "scripting", que so maissimples e se prestam a um estilo de programao informal, mais sintonizado com um tutorial comoesse.As trs linguagens de scripting mais populares atualmente so JavaScript, VBScript e Perl. Todas soutilizadas na construo de web-sites dinmicos. As duas primeiras praticamente no tm aplicaofora desse domnio, e por isso foram descartadas. que, embora seja nosso objetivo abordar tambmesse tpico, achamos que complexo demais para comear, especialmente devido dificuldade de sediagnosticar erros de programao em pginas dinmicas. E Perl uma linguagem esquisita demais,criada para agradar programadores tarimbados e hackers, segundo seu prprio criador.Felizmente, bem perto de Perl no mapa das linguagens modernas existe uma outra, no to conhecida,mas igualmente poderosa. Seu nome uma homenagem ao grupo humorstico ingls Monty Python,adorado por geeks de todo o mundo. Apesar da associao cmica, Python vem sendo usada emprojetos srios por entidades como Yahoo, NASA, InfoSeek, MCI Worldcom, IBM e Hiway, a maiorempresa de hospedagem de web-sites do mundo. tambem a base do Zope, a mais sofisticadaplataforma para construo de web-applications disponvel hoje como open-source. Apesar de sua sintaxe simples e clara, Python oferece os seguintes recursos disponveis tambm emlinguagens mais complicadas como Java e C++:

    programao orientada a objetos (incluindo herana mltipla, conceito apenas parcialmentepresente em Java)

    excees, um moderno mecanismo para o tratamento de erros mdulos, uma forma inteligente de acessar e organizar cdigo a ser reutilizado coleta de lixo automtica, sistema que elimina os erros causados pelo acmulo de dados

    inteis na memria do computador (caracterstica presente tambm em Java, mas no em C++) recursos avanados de manipulao de textos, listas e outras estruturas de dados possibilidade de executar o mesmo programa sem modificaes em vrias plataformas de

    hardware e sistemas operacionais (uma virtude de Java, mas difcil de se conseguir em C++) Em resumo, Python nos oferece uma sintaxe simples mas ao mesmo tempo suporta a maior parte dascaractersticas importantes de linguagens modernas e amplamente utilizadas como Java, C++, Perl eVBScript. Por esse motivos acreditamos que seja a melhor escolha para quem quer comear aprogramar hoje.

    Abrindo e fechando o interpretador

    A melhor forma de aprender e a programar usando um interpretador em modo interativo. Dessaforma voc pode digitar comandos linha por linha, e observar a cada passo o como o computadorinterpreta e executa esses comandos. Para fazer isso em Python, h duas maneiras: voc pode executar o interpretador em modo texto(chamado "Pyhton (command line)" no Windows), ou usar o IDLE, que um interpretador baseadoem janelas. Se voc usa Windows, escolha o IDLE para acompanhar esse tutorial.Seja qual for o interpretador que voc escolheu, ao execut-lo voc ver uma mensagem cominformaes de copyright mais ou menos como essa:Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam>>>O smbolo ">>>" exibido pelo interpretador o que os americanos chamam de "prompt", que algunstraduzem equivocadamente por "aviso", mas ns vamos chamar de "deixa" (em teatro, o termo"prompt" a deixa que indica ao ator a hora de dizer ou fazer algo; em computao, o prompt informao usurio que o sistema est pronto para receber um novo comando).Para sair do interpretador voc pode fechar a janela do IDLE, ou teclar [CTRL]+[D] (no IDLE ou nointerpretador em UNIX) ou [CTRL]+[Z] (no interpretador DOS).

  • Uma calculadora melhor

    Vamos ento aproveitar a deixa e escrever algo. Experimente escrever uma expresso aritmtica bemsimples, como 2+2:

    >>> 2+24>>>

    A resposta reconfortante: para Python, 2+2 igual a 4. Voc pode experimentar outras expressesmais complexas, mas bom saber que os quatro operadores bsicos em Python (e em quase todas aslinguagens modernas) so esses:+ adio- subtrao* multiplicao/ divisoSe voc quiser operar com nmeros decimais, deve usar o ponto e no a vrgula como separadordecimal:

    >>> 1.23 * 0.450.5535>>>

    Em muitas linguagens de programao, assim como em Python, os nmeros inteiros tm umtratamento especial. Isso fica evidente quando fazemos uma diviso:

    >>> 7/23>>>

    Em vez de 3,5, o resultado foi 3. Isso acontece sempre que todos os nmeros de uma expresso sointeiros. Neste caso, Python imagina que se deseja um resultado inteiro tambm (esse comportamentoestranho na realidade muito conveniente em programao). Para indicar que voc deseja resultadosno-inteiros, use um ponto decimal em algum dos operandos:

    >>> 7.0/23.5>>> 7/2.03.5>>> 7/2.3.5>>>

    Note que basta digitar um ponto aps o nmero. Voc pode digitar espaos entre os nmeros e operadores para fazer uma expresso longa ficar maislegvel. Veja esse exemplo:

  • >>> 1 + 2 * 37>>>

    Note que o interpretador Python mais esperto que uma calculadora comum. Ele sabe que amultiplicao deve ser efetuada antes da adio. Se voc teclar a mesma expresso em umacalculadora qualquer obter o resultado 9, que incorreto. Em Python, se voc realmente desejaefetuar a soma antes da multiplicao, precisa usar parnteses:

    >>> (1 + 2) * 39>>>

    Ao contrrio do que voc aprendeu na escola, aqui os smbolos [] e {} no servem para agruparexpresses dentro de outras expresses. Apenas parnteses so usados:

    >>> ( 9 - ( 1 + 2 ) ) / 3.02.0>>> ( 9 - 1 + 2 ) / 3.03.33333333333>>>

    DICA: Se voc escrever algo que o interpretador no reconhece, ver na tela uma mensagem de erro.No crie o mau hbito de ignorar essas mensagens, mesmo que elas paream difceis de entender numprimeiro momento. A nica vantagem de cometer erros aprender com eles, e se a preguia o impedirde ler as mensagens, seu aprendizado ser bem mais lento.Veja aqui como decifrar as mensagens de erro do Python.

  • Como ler uma mensagem de erro

    A dura realidade que um programador profissional passa boa parte de sua vida caando erros, e porisso fundamental saber extrair o mximo de informaes das mensagens resultantes. A essa altura voc talvez j tenha provocado um erro para ver o que acontece. Vamos fazer issoagora, e aprender a ler as mensagens resultantes. Pode parecer perda de tempo, mas importantssimo saber interpretar as mensagens de erro porque a melhor forma de aprender aprogramar experimentando, e ao experimentar voc certamente vai provocar muitos erros.Como exemplo, vamos digitar uma expresso aritmtica sem sentido:

    No interpretador IDLE voc ver apenas o sinal de diviso assinalado em vermelho e a mensagemSyntaxError: invalid syntax, erro de sintaxe invlida.No interpretador de linha de comando voc ver uma mensagem mais longa:>>> 7 + / 2 File "", line 1 7 + / 2 ^SyntaxError: invalid syntax>>>

    A primeira linha da mensagem de erro informa o arquivo onde ocorreu o erro: File"Quando voc est usando o interpretador em modo interativo essa informao intil, mas ao trabalhar com programas extensos ela se torna indispensvel. Asprximas duas linhas indicam onde ocorreu o erro: 7 + / 2 ^

    Note que o smbolo ^ est apontando exatamente a posio do sinal /. Foi apartir desse ponto que a expresso deixou de fazer sentido para o interpretador.Agora vamos provocar um outro tipo de erro:>>> 7/0Traceback (innermost last): File "", line 1, in ? 7/0ZeroDivisionError: integer division or modulo>>>

    S mais tarde poderemos explicar completamente a primeira linha de uma mensagemcomo essa, mas a parte mais importante a ltima linha, que nesse caso bemfcil de entender: ZeroDivisionError: integer division or moduloDo lado esquerdo aparece o nome do erro:ZeroDivisionError, ou erro de divisopor zero. Aps o sinal : vem informaes adicionais sobre o contexto ondeocorreu o erro: em uma diviso inteira ou modulo (em ingls, modulo o nome dooperador %, que apresentamos acima). O / e o % so os dois operadores que podemcausar um ZeroDivisionError.

    Conversor de dlares

    Digamos que voc tem uma loja de discos importados, e precisa constantemente converter dlares em

  • reais. O valor do dlar para venda em 20/05/1999 de 1.686. Para converter US$9,95 e US$11,95 emreais voc pode digitar:

    >>> 9.95 * 1.68616.7757>>> 11.95 * 1.68620.1477>>>

    Mas h uma forma melhor: em vez de digitar o valor 1.686 o tempo todo, voc pode armazenar essevalor na memria do computador, assim:

    >>> d = 1.686>>>

    Note que o interpretador no respondeu nada (a menos que voc tenha cometido um erro), mas eleguardou o nmero em uma posio de sua memria, e associou o smbolo "d" a essa posio. Agora,fica mais confortvel converter dlares em reais:

    >>> 9.95 * d16.7757>>> 11.95 * d20.1477>>> 5 * d, 7 * d, 9 * d(8.43, 11.802, 15.174)>>>

    No ltimo caso, convertemos de uma vez s os valores 5, 7 e 9 em dlares. E se a cotao do dlarmudou para 1.61? Basta armazenar o novo nmero e refazer os clculos:

    >>> d = 1.61>>> 5 * d, 7 * d, 9 * d(8.05, 11.27, 14.49)>>>

    Se estiver usando o IDLE, voc no precisa digitar a segunda linha novamente. Clique sobre a linhaque digitamos no exemplo anterior e tecle [ENTER]. A linha ser reproduzida na ltima deixa, ebastar um novo [ENTER] para process-la.

    Tabela de preos em dlares e reais

    Agora vamos mostrar como o interpretador Python muito mais poderoso que uma calculadora.Imagine que em sua loja de discos importados voc tem um balco de ofertas com discos de $4 at $9.Se quisesse fazer uma tabela de preos em reais voc poderia digitar:

    >>> 4*d, 5*d, 6*d, 7*d, 9*d(6.44, 8.05, 9.66, 11.27, 14.49)>>>

  • Mas isso um tanto chato e repetitivo, alm do que o resultado no muito apresentvel. Emprogramao, sempre que voc fizer algo repetitivo porque no encontrou ainda a melhor soluo.Lidar com sries de nmeros uma atividade comum, e Python pode ajudar muito nesses casos.Digite o seguinte:

    >>> lista = [5,6,7,8,9]>>>

    Aqui ns criamos uma lista de preos na memria do computador e associamos o nome "lista" a essesdados. Em seguida, digite o seguinte (voc ter que teclar [ENTER] duas vezes ao final dessa linha;depois saber porque).

    >>> for p in lista: p * d

    8.059.6611.2712.8814.49>>>

    Aqui ns instrumos o interpretador a fazer os seguintes passos: - para cada item sucessivo da lista: -associe o nome p ao item em questo - calcule p * dAgora digamos que voc tem discos com valores de 4 a 15 dlares. Voc poderia digitar a lista denovo, mas a coisa comea a ficar repetitiva novamente. H uma forma melhor. A linguagem Pythonpossui uma palavra chamada "range" que serve para gerar faixas de nmeros. Vamos usar essapalavra. Digite:

    >>> range

    >>>

    Quando voc digita o nome de uma funo sem fornecer dados, Python limita-se a dizer a que serefere o nome. Nesse caso: "built-in function range", ou funo embutida range. Isso quer dizer que apalavra range o nome de uma funo, um tipo de comando que produz resultados a partir de dadosfornecidos. E trata-se ainda de uma funo embutida, ou seja, includa no prprio interpretador (amaioria das funes da linguagem Python no so embutidas, mas fazem parte de mdulos que oprogramador precisa chamar explicitamente; isso ser explicado depois {*REF}).Acabamos de dizer que uma funo "produz resultados a partir de dados fornecidos", ento vamosfornecer algum dado para ver que resultados a funo range produz. Digite "range(5)" e veja o queacontece:

    >>> range(5)[0, 1, 2, 3, 4]>>>

    Quando apenas um dado fornecido, range gera uma lista de nmeros de zero at o nmero anteriorao valor fornecido. um comportamento um pouco estranho, mas til em programao (o primeiro

  • item de uma srie, na maioria das linguagens, o item nmero zero; isso ser discutido maisprofundamente quando aprendermos mais sobre listas {*REF}). Agora digamos que eu queira uma sequncia a partir de 2, e no zero. Digite:

    >>> range(2,5)[2, 3, 4]>>>

    Agora para obter a lista de valores de discos podemos digitar:

    >>> range(4,16)[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]>>>

    E usando o comando for, calcular de uma s vez todos os valores convertidos:

    >>> for p in range(4,16): p * d

    6.448.059.6611.2712.8814.4916.117.7119.3220.9322.5424.15>>>

    Mas o ideal mesmo era ter os valores em dlares e reais lado a lado. Isso fcil:

    >>> for p in range(4,16): p, p * d

    (4, 6.44)(5, 8.05)(6, 9.66)(7, 11.27)(8, 12.88)(9, 14.49)(10, 16.1)(11, 17.71)(12, 19.32)(13, 20.93)(14, 22.54)(15, 24.15)>>>

    Resumindo o que foi feito at aqui, com apenas duas linhas de cdigo em Python, voc pode gerartabelas de converso de qualquer tamanho. Experimente:

  • >>> d = 1.686>>> for p in range(50,150): p, p * d

    Parabns, voc acaba de construir seu primeiro programa!

    Aprenda a programar Captulo 2

    por Luciano Ramalho No final do primeiro captulo desse curso digitamos o seguinte programa diretamente no interpretadorPython:

    >>> d = 1.686>>> for p in range(50,150): print p, p * d

    O resultado desta seqncia de comandos uma longa lista de nmeros em duas colunas. Sabemosque a primeira coluna da esquerda contm preos em dlar e a outra, em reais. Mas nada na listagemindica isto. Observe esse trecho:

    95 160.1796 161.85697 163.54298 165.22899 166.914100 168.6101 170.286102 171.972103 173.658104 175.344105 177.03

    Aqui podemos observar outras deficincias: as colunas no esto corretamente alinhadas, e os valoresem reais aparecem com uma, duas ou trs casas decimais. Como se trata de uma tabela de preos, osvalores em ambas colunas deveriam ter sempre duas casas decimais. Vamos fazer algumas melhoriasem nosso programa gerador de tabelas de preos.

    Quatro tipos de dados

    Para evitar aquele degrau na segunda coluna entre o 99 e o 100, precisamos fazer um pequeno desviopara comear a aprender a lidar com textos, alm de nmeros. Digite eu = seguido do seu nome entreaspas:

    >>> eu = 'Fulano'

    Voc tem que digitar as aspas para evitar um erro. As aspas podem ser 'simples' ou "duplas". Pythonguardar uma cpia do seu nome na memria do computador, e associar o identificador eu a esse

  • dado. Agora basta digitar eu para ver o seu nome.

    >>> eu'Fulano'>>>

    Antes havamos criado a varivel d referindo-se cotao do dlar, e no captulo anterior tambmcriamos uma varivel chamada lista, contendo uma lista de valores. Agora criamos a varivel eu parase referir ao seu nome. Estes so exemplos de trs tipos de dados que Python capaz de processar.Voc pode saber o tipo de uma varivel ou estrutura de dados usando a funo type. Veja estesexemplos:

    >>> eu = 'Luciano'>>> d = 1.902>>> type(eu)

    >>> type(d)

    >>>

    Python acaba de nos dizer que a varivel eu do tipo 'string' (uma cadeia de caracteres) e d do tipo'float', palavra que se pronuncia como "flut" e que uma abreviao do termo tcnico "floating pointnumber" ou nmero de ponto flutuante. Este nome estranho tem origem no fato de que em certaslinguagens, como Cobol ou Clipper, os nmeros tem pontos decimais em uma posio fixa. No casode Python, C++, Java e outras linguagens modernas, o ponto normalmente no fixo, mas sim"flutuante".Vejamos mais alguns tipos de dados:

    >>> type(1)

    >>> type(1.)

    >>> type([1,2,3])

    >>>

    Observe que o nmero 1 no 'float', mas 'int'. J o nmero 1. seguido de um ponto decimal considerado um 'float'. Como j dissemos no primeiro captulo, inteiros e floats tm tratamentodiferente em Python e na maioria das linguagens modernas. Uma diviso de inteiros (como 7/2),sempre fornece um resultado inteiro (3, nesse exemplo). O prximo dado testado uma lista, [1,2,3],que Python chama de 'list'.Agora, experimente fazer esses dois testes:

    >>> type(range)

    >>> type(range(4,7))

    >>>

  • Ao perguntarmos qual o tipo associado ao nome range, Python responde:'builtin_function_or_method'. Tambm j vimos isso no captulo anterior: o nome range refere-se auma funo embutida no prprio interpretador. No teste seguinte, fornecemos argumentos para afuno range, e assim produzimos um resultado (neste caso, a lista [4,5,6], que foi criada na memriado seu computador, mas no foi exibida). sobre este resultado que a funo type foi aplicada,retornando a informao de que se trata de um dado do tipo 'list'. Ou seja, range uma expresso dotipo builtin_function_or_method, mas range(4,7) uma expresso do tipo 'list'. Faz sentido? Se nofaz, escreva reclamando!Cada tipo de dados suporta operaes diferentes. Faa algumas experincias e analise os resultados:

    >>> n1 = 10>>> n2 = 20>>> n1 + n230>>> n1 = 'abacate'>>> n2 = 'banana'>>> n1 + n2'abacatebanana'>>> n2 + n1'bananaabacate'>>>

    Por exemplo, o operador + realiza uma soma quando aplicado a dados numricos, mas quandoaplicado a dados do tipo string, o sinal + faz uma operao de concatenao (juno de duasseqncias de caracteres). Agora experimente isto:

    >>> x = 3.>>> x * 515.0>>> 'x' * 5'xxxxx'>>>

    Note que x e 'x' so coisas totalmente diferentes. x o nome de uma varivel que neste momento serefere ao valor 3. (um float). O resultado de x * 5 15.0 (outro float, como era de se esperar). J 'x' uma string com um caractere. Quando o sinal * aplicado entre uma string e um nmero inteiro,Python realiza uma operao de repetio. Como voc pode notar, os operadores + e * fazem coisasdiferentes dependendo dos tipos de dados fornecidos na expresso. um prazer trabalhar com Python porque se trata de uma linguagem muito coerente. Observe:

    >>> [1,2] + [3,4][1, 2, 3, 4]>>> '12' * 3'121212'>>> [1,2] * 3[1, 2, 1, 2, 1, 2]>>>

    No primeiro exemplo, vemos o operador + concatenando duas listas. Os outros dois exemplosmostram a operao de repetio. Note que '12' no um nmero, mas uma string composta pelos

  • caracteres '1' e '2'. Para Python, strings e listas tm muito em comum: ambas so seqncias de itens.Enquanto strings so seqncias de caracteres, listas so seqncias de itens quaisquer. Nos doiscasos, concatenao e repetio funcionam de forma logicamente idntica.

    Enfeitando a tabela

    Agora que sabemos sobre alguns tipos de dados, e que os operadores funcionam de forma diferenteconforme os dados da expresso, estamos prontos para aperfeioar nosso gerador de tabelas usando opoderoso operador '%', que em Python no tem nada a ver com porcentagens. Para ver como elefunciona, vamos criar uma string como esta:

    >>> msg = 'um dlar vale %f real.'>>>

    Agora vamos ver o que acontece quando chamamos a varivel msg:

    >>> msg'um d\363lar vale %f real.'>>>

    Python representa varaveis string dessa forma: entre aspas simples, e trocando os acentos por cdigosespeciais (estamos falando do cdigo ASCII em notao octal, algo que explicaremos depois). Se vocquiser exibir o contedo de msg de forma mais apresentvel, use o comando print:

    >>> print msgum dlar vale %f real.>>>

    OK, hora de explicar porque colocamos esse estranho %f dentro da mensagem. Trata-se de ummarcador de posio para sinalizar onde Python dever inserir um nmero quando quisermos imprimira mensagem com o valor da cotao. Experimente digitar o seguinte:

    >>> d = 1.902>>> print msg % dum dlar vale 1.902000 real.>>>

    Veja o que aconteceu: Python substituiu a marca %f pelo valor da varivel d. assim que funciona: apartir de uma string com marcas de posio e um ou mais valores, o operador % produz uma novastring com os valores inseridos nas respectivas posies. Veja agora um exemplo com dois valores:

    >>> msg2 = 'Um dlar vale %f real e um real vale %f dlar.'>>> print msg2 % (d, 1/d)Um dlar vale 1.902000 real e um real vale 0.525762 dlar.>>>

  • Note que os valores d e 1/d esto entre parnteses. Isso obrigatrio quando queremos passar mais deum valor para o operador % (uma sequncia de valores entre parnteses um "tuplo", um tipoespecial de lista que explicaremos em um outro captulo).O smbolo %f serve para informar a Python que o valor a ser inserido naquela posio um float. Sevoc quiser limitar o nmero de casas aps o ponto decimal, basta usar um formato como esse:

    >>> d = 1.685>>> '%.2f' % d'1.69'>>>

    Aps o marcador %, a indicao .2 determina que devem aparecer duas casas decimais aps o ponto.Note que o resultado arredondado: 1.685 virou 1.69. Vamos usar esse recurso na nossa tabela:

    >>> for p in range(4,16): print 'US$ %.2f = R$ %.2f' % (p,p*d) US$ 4.00 = R$ 6.74US$ 5.00 = R$ 8.43US$ 6.00 = R$ 10.12US$ 7.00 = R$ 11.80US$ 8.00 = R$ 13.49US$ 9.00 = R$ 15.17US$ 10.00 = R$ 16.86US$ 11.00 = R$ 18.55US$ 12.00 = R$ 20.23US$ 13.00 = R$ 21.92US$ 14.00 = R$ 23.60US$ 15.00 = R$ 25.29>>>

    Est quase linda. Falta s consertar o degrau que acontece entre a linha do 9 e do 10. No marcador deposio voc tambm pode colocar um nmero esquerda do ponto para definir a largura total doespao que ser reservado. Na faixa de preos de 4 a 15, os maiores valores tem cinco caracteres decomprimento (incluindo o ponto decimal), por isso vamos usar '%6.2f'. Agora podemos fazer umaverso bem melhor da tabela:

    >>> for p in range(4,16): print 'US$ %5.2f = R$ %5.2f' % (p,p*d) US$ 4.00 = R$ 6.74US$ 5.00 = R$ 8.43US$ 6.00 = R$ 10.12US$ 7.00 = R$ 11.80US$ 8.00 = R$ 13.49US$ 9.00 = R$ 15.17US$ 10.00 = R$ 16.86US$ 11.00 = R$ 18.55US$ 12.00 = R$ 20.23US$ 13.00 = R$ 21.92US$ 14.00 = R$ 23.60US$ 15.00 = R$ 25.29>>>

  • Entendendo melhor o for

    Como voc percebeu, no comando for tudo aquilo que aparece aps os sinal ":" repetido vriasvezes, uma vez para cada item da lista de valores indicada aps a palavra in. Mas os comandos aserem repetidos podem ser vrios, e na maioria das vezes no so escritos na mesma linha que o for,como temos feito, mas sim em linhas subseqentes. O comando for algo que chamamos de "estrutura de controle", que serve para determinar a forma deexecuo de um comando ou de uma seqncia de comandos, s vezes chamada de um "bloco". Emoutras linguagens, os blocos so delimitados por marcadores especiais. Java, Perl e C++ usam ossinais { e } para este fim. Pascal e Delphi usam as palavras BEGIN e END. Alm desses marcadoresexigidos pelas linguagens, os programadores usam tambm o recurso da recurso da endentao, ouseja, o recuo em relao margem esquerda, para tornar mais fcil a visualizao da estrutura doprograma. Veja este exemplo em Perl:

    for ($i = 0; $i < 5; $i++) { $v = $i * 3; print "$v\n";}

    Ateno: isto Perl, e no Python.

    Aqui, os comandos $v = $i * 3; e print "$v\n"; formam o bloco que est sobre o controle do comandofor, ou seja, os dois comandos sero executados repetidamente. O programa equivalente em Python escrito assim:

    >>> for i in range(5): v = i * 3 print v

    Em nossa opinio, o cdigo em Python bem mais legvel. Para sinalizar quais comandos fazem partedo bloco que est sob o controle do for, apenas a endentao utilizada. Se voc est usando o IDLE,esse recuo acontece automaticamente quando uma linha de comando termina com o sinal ':', que emPython sempre indica o incio de um bloco. No interpretador Python invocado a partir da linha decomando no DOS ou em UNIX, a indentao no automtica. Voc precisa digitar ao menos umespao em branco ou, melhor ainda, um [TAB], para evitar uma mensagem de erro como essa:

    >>> for i in range(5):... print i File "", line 2 print i ^SyntaxError: invalid syntax

    Note que o interpretador est reclamando de sintaxe invlida, e apontando (^) para a primeira palavrado bloco que deveria estar recuado. Veja a mesma coisa, com a segunda linha recuada com a tecla[TAB]:

  • >>> for i in range(5):... print i...01234>>>

    J deve ter ficado claro porque era preciso digitar dois [ENTER] depois do for nos exemplosanteriores: que, no modo interativo, o interpretador Python espera uma linha em branco parasinalizar o final de uma srie de comandos que formam um bloco dentro de uma estrutura de controle.Agora que entendemos o conceito de bloco, podemos enfeitar ainda mais a nossa tabela colocando umsegundo comando print dentro do nosso for:Veja este exemplo:

    >>> for p in range(9,13): print 'US$ %5.2f = R$ %5.2f' % (p, p * d) print '-' * 20 US$ 9.00 = R$ 15.17--------------------US$ 10.00 = R$ 16.85--------------------US$ 11.00 = R$ 18.54--------------------US$ 12.00 = R$ 20.22-------------------->>>

    A outra face do %

    Antes de encerrar este captulo, vale a pena contar que, assim como o + e o *, o operador '%' tambmtem dupla personalidade. Quando aplicado sobre dois nmeros, que podem ser inteiros ou floats, o '%'retorna o resto da diviso inteira do primeiro pelo segundo. Veja s:

    >>> 6 % 30>>> 7 % 31>>> 8 % 32>>> 9 % 30>>>

    Explicando: 6 / 3 d 2, e o resto 0; a diviso inteira de 7 / 3 tambm d 2, mas o resto 1. Estaoperao chamada de "modulo" em ingls. Sua principal utilidade determinar se um nmero mltiplo de outro. Nos exemplos acima, o resultado de 6 % 3 e 9 % 3 zero, porque 6 e 9 somltiplos de 3.

  • No prximo captulo vamos comear a elaborar programas mais extensos. O modo interativo, quetemos usado at agora, vai continuar sendo til para testarmos novas idias e observar ocomportamento de funes e mdulos do Python rapidamente. Mas, a partir da prxima sesso, vamoscomear a gravar nossos programas para uso posterior, em vez de digit-los diretamente nointerpretador. E vamos tambm descobrir como solicitar informaes do usurio, de forma que osprogramas possam ser utilizados por pessoas que no sabem programar e preferem ficar longe de uminterpretador interativo.

    Aprenda a programarCaptulo 3

    por Luciano Ramalho Depois de dois captulos bem bsicos, hora de engatar uma segunda e comear a criar programasmais dignos desse nome. No vamos desprezar o que fizemos at aqui, digitando diretamente na deixado interpretador Python. Ao contrrio: tenha sempre em mente que voc pode us-lo para esclareceraquela dvida rpida ou mesmo localizar um bug escondido em um sistema complexo. A maioria dasoutras linguagens no oferece um ambiente para execuo imediata de comandos como o Python.Uma exceo famosa a linguagem Logo, onde o interpretador interativo serve justamente parafacilitar a aprendizagem da programao por tentativa e erro.Mas a partir de agora vamos atacar programas mais extensos, e no vamos querer digit-los linha porlinha no modo interativo. Em vez disso, vamos escrever os comandos em um editor de textos, salvar oarquivo, e mandar o interpretador Python ler o programa salvo.

    Rodando programas no IDLE

    A verso Windows do Python 1.5.2 traz o IDLE, um interpretador interativo em modo grfico que japresentamos no primeiro captulo. Se voc no usa essa verso do Python, v direto para a prximaseo: Testando no sistema. O IDLE inclui um editor de programas simplrio, mas til para quem estaprendendo a linguagem. O editor do IDLE exibe com cores diferentes as palavras da linguagem, deacordo com sua funo sinttica (lembra da aula de portugus onde o verbo era verde, o sujeitovermelho etc?). Para abrir o editor, rode o IDLE e acione o comando File > New window. A janelaque se abrir, com o ttulo "untitled", um editor. Experimente digitar um programinha como esse:

    for i in range(100): print 'Luciano 'print 'e seus Camargos'

    Note que o editor pinta algumas palavras de laranja. So as chamadas palavras-chave, peas toimportantes em Python como os verbos em portugus. A funo range e a varivel i, aparecem empreto. Assim so exibidos os identificadores que o prprio programador pode definir ou redefinir. E ostextos entre aspas aparecem em verde: dessa forma, fica difcil esquecer de fechar aspas. Outra coisaque acontece magicamente a endentao. O editor "sabe" que aps os ":" do comando for, deve virum bloco endentado. Para encerrar o bloco endentado, voc pode teclar [ENTER] duas vezes parapular uma linha, como ocorre tambm na deixa do interpretador, ou ento teclar [BackSpace] paraapagar de uma vez s os quatro espaos esquerda da linha.Uma vez digitado esse programinha voc pode execut-lo de duas maneiras: diretamente de dentro doIDLE ou na deixa do sistema operacional. O primeiro mtodo o mais fcil, mas o segundo omelhor por vrios motivos. Para usar o modo fcil, s teclar [F5]. Se voc ainda no salvou o texto

  • do seu programa, o IDLE vai exibir uma mensagem pedindo para que voc o faa. Basta usar ocomando File > Save, ou melhor ainda, [CTRL]+[S]. Se voc no sabe onde salvar, sugiro que crieuma pasta chamada Curso dentro da pasta onde est o seu interpretador Python e salve ali(provavelmente a pasta ficar sendo C:\Arquivos de Programas\Python\Curso). Assim fica fcilencontr-lo depois. Use o nome egotrip.py.A execuo do programinha egotrip causa a exibio repetida do nome do autor, seguinda do nome desua banda. No tempo do Apple II e do TK-85, programinhas como esse eram invariavelmente osprimeiros exerccios de qualquer estudante de programao. No IDLE, a "sada" ou "output" doprograma (aquilo que ele produz), exibida dentro de uma janela intitulada "*Output*". Voc podefechar essa janela quando o programa parar. bom mesmo que voc feche, porque ao rodar oprograma de novo, outra janela de output ser criada, e elas se multiplicam rapidamente quando agente est concentrado programando...Voc talvez tenha notado que o Python bastante lento. Em meu notebook Pentium 133 o programaleva 10 segundos para escrever as 101 linhas. muito. Mas a culpa no do Python, e sim do IDLE,como veremos a seguir.

    Navegando pela linha de comando

    No Linux a linha de comando est em toda parte, mas no Windows fica um pouco escondida. Paraencontr-la, clique na barra de tarefas do Windows em Iniciar > Programas > Prompt do MS-DOS.Para quem nunca navegou pelo sistema via prompt, eis aqui o mnimo que voc precisa saber. Veja oque aparece na janela do Prompt: esquerda do cursor, voc tem a informao mais importante para se orientar: a letra do drive e onome da pasta onde voc se encontra. Se o seu Windows est com a configurao de fbrica, vocestar em C:\Windows. O sinal > apenas a deixa do sistema, equivalente ao >>> usado peloPython para indicar que est pronto para receber um comando. Antes de mais nada, vamos acionar umprograminha muito que nos poupar muita digitao posteriormente. Digite "doskey" ao lado doprompt e tecle [ENTER].C:\Windows>doskey [ENTER]

    Voc ver a mensagem DOSKey instalado. A partir de agora, tudo o que voc digitar na linha decomando ser salvo pelo DOSKey, e poder ser recuperado para repetio posterior. Logo veremoscomo.Agora, vamos ver o que existe na pasta onde estamos (a pasta Windows). Digite:C:\Windows>dir [ENTER]

    Voc ver uma longa listagem de arquivos, com seus nomes abreviados, extenses, tamanhos, datas enomes longos. Em meu notebook aparecem 236 arquivos na pasta Windows. No estamosinteressados neles agora, o objetivo era apenas mostrar que o comando dir produz uma listagem dosarquivos da pasta, ou diretrio, atual. Para ver o doskey em ao, tecle a [^] (seta para cima). O ltimocomando digitado aparece de novo, pronto para ser executado ao toque de um [ENTER].Agora vamos navegar at o diretrio onde foi gravado o programa egotrip.py. Digite:C:\Windows>cd \ [ENTER]

    Agora voc est no chamado diretrio raiz do seu disco. Digite dir e veja como a maioria dos itensdentro dessa pasta so outras pastas, como a prpria pasta Windows e a pasta Arquivos de Programas.Vamos "entrar" nessa ltima pasta. Para isso, vamos usar seu nome abreviado pelo DOS, arquiv~1:C:\>cd arquiv~1 [ENTER]

  • Agora vamos entrar na pasta do Python:C:\Arquivos de programas>cd python [ENTER]

    E, em seguida, na pasta Curso, que voc deve ter criado quando salvou o arquivo egotrip.py.C:\Arquivos de programas\Python>cd cursoC:\Arquivos de programas\Python\Curso>dir

    Voc dever ver uma listagem como essa:O volume da unidade C KAYAK_DOSO nmero de srie do volume 3A64-0AE9Pasta de C:\Arquivos de programas\Python\Curso

    . 25/10/99 20:57 .

    .. 25/10/99 20:57 ..

    EGOTRIP PY 89 25/10/99 20:32 egotrip.py 1 arquivo(s) 89 bytes 2 pasta(s) 21.331.968 bytes disponveis

    C:\Arquivos de programas\Python\Curso>

    Agora voc est no ponto certo para digitar o comando que causar a execuo do seu programaegotrip.py.

    Testando no sistema

    Meu ambiente favorito para rodar programas em Python a prpria linha de comando do sistemaoperacional. No costumo usar o editor do IDLE, mas sim o TextPad, um excelente editor de textossobre o qual voc pode ler mais no site da MAGNET. Seja qual for o editor que voc usa, oimportante salvar o arquivo como texto ASCII puro. O Notepad do Windows pode melhor queWord para esse fim. No Linux, vi, joe, pico e emacs so alguns editores ASCII bastante comuns.Entre esses, prefiro o emacs. Uma vez digitado e salvo o arquivo, voc precisa execut-lo a partir dalinha de comando do seu sistema.Quem usa Linux ou j est habituado ao DOS, pode seguir at a prxima seo, ASCII art.

    ASCII art

    No Windows, para executar o programa, digite esse encantamento (supondo que voc fez tudoconforme descrito na seo acima, ou fez tudo diferente mas sabia o que estava fazendo):C:\Arquivos de programas\Python\Curso>..\python egotrip.py

    Os sinais ..\ na frente do comando python servem para dizer ao DOS para executar um programa queest no diretrio anterior no caminho atual. Assim, acionamos o programa python.exe que est napasta C:\Arquivos de programas\Python.No Linux, voc precisar chegar at o diretrio que contm o exemplo, e digitar:>python egotrip.py

    Ou, se isso no funcionar, tente algo como segue (o comando exato vai depender da sua instalao):>/usr/local/bin/python egotrip.py

    Bom, deu trabalho mas chegamos. E como voc deve ter notado, a execuo do programinha foi bem

  • mais veloz que no IDLE (em meu computador, menos de 1 segundo, em vez de 10).Agora vamos fazer uma pequena mudana no programa egotrip que ter um grande efeito. Para fazeressa alterao, no Windows o modo mais rpido segurar a tecla [ALT] e pressionar [TAB] at que ocone do editor do IDLE identificado pelo nome do arquivo egotrip.py esteja selecionado. Ento soltea tecla [ALT], que o editor aparecer sobrepondo-se s demais janelas. Agora vamos modificar oprograma egotrip. Ao final da segunda linha, digite uma vrgula. O seu programa dever ficar assim:--for i in range(100): print 'Luciano ',print 'e seus Camargos'--

    Salve com [CTRL]+[S] e rode o programa novamente. Tecle [F5] para rodar no IDLE, ou siga essespassos para testar no DOS:[ALT][TAB] at voltar ao prompt do DOS[^] (seta para cima) para fazer o doskey repetir o comando ..\python egotrip.py[ENTER] para executar o comando acima.10 entre 10 programadores que usam a plataforma Windows tm muita prtica com a sequncia[ALT]+[TAB], [^], [ENTER]. Logo, logo, em sua primeira sesso de caa a um bug, voc teroportunidade de praticar bastante.Nesse caso, interessante testar o programa tanto no IDLE quanto na linha de comando. Voc verque os resultados so bem diferentes. Experimente e tente explicar porqu.Como exerccio final, subsitua o argumento 100 da funo range pelo nmero 1000, e rode oprograma novamente (no recomendo usar o [F5] do IDLE dessa vez; ser bem demorado). Tenteacrescentar ou retirar letras do seu nome. O efeito ser diferente. Bem vindo ao mundo da expressoartstica com caracteres de computador.

    Seu primeiro programa interativo

    At agora, todos os programas que mostramos no so interativos, ou seja, uma vez rodando eles noaceitam a entrada de dados de um usurio ou do sistema. Programas no interativos so usados emmuitas situaes comuns. O programa que emite os cheques da folha de pagamentos de uma grandeempresa provavelmente no interativo, mas recebe todos os dados necessrios em um nico lote,antes de sua execuo. Mas os programas mais interessantes, como um processador de textos, umgame ou o piloto automtico de um avio so todos interativos. Esse o tipo de programa quepassaremos a desenvolver agora.Nosso passeio pela ASCII art no teve apenas objetivos estticos. Quizemos mostrar como rodar umprograma em Python a partir da linha de comando porque, a partir de agora, vamos usar um comandoda linguagem Python que no funciona na atual verso do IDLE. O comando chama-se "raw_input", esua funo receber uma entrada de dados do usurio (input quer dizer entrada de dados; cuidadoporque voc deve ter sido condicionado a acreditar que "antes de P e B sempre vem a letra M", masinput ingls, e se escreve com N mesmo; eu perdi uma hora com isso quando aprendia BASIC).Vejamos um primeiro exemplo. Observe que no estamos acentuando o texto no programa porque oDOS no reproduz corretamente os acentos do Windows, e precisamos do DOS para testar esseprograma. Deve haver uma forma de convencer o DOS a exibir os acentos corretos do Windows, masainda no descobrimos como.De qualquer forma, isso no quer dizer que no d para fazer programas com acentuao correta emPython; quando aprendermos a criar softwares grficos esse problema desaparecer.

  • Digite o programinha abaixo, salve como despdom1.py e execute na linha de comando.

    # despdom1.py - Calculadora de despesas domesticas

    print 'Balanco de despesas domesticas'ana = raw_input('Quanto gastou Ana? ')bia = raw_input('Quanto gastou Bia? ')total = float(ana) + float(bia)print 'Total de gastos = R$ %s.' % totalmedia = total/2print 'Gastos por pessoa = R$ %s.' % media

    Os nmeros que aparecem esquerda na listagem acima no fazem parte do programa e no devemser digitados. Eles esto a para facilitar a explicao que vem logo a seguir.Antes de esmiuar o programa, vale a pena execut-lo para ver o que acontece. Voc ser solicitado adigitar um valor para Ana e outro para Bia. Note que os valores devero ser apenas nmeros. Sequiser usar centavos, use o ponto decimal em vez de vrgula, como j vnhamos fazendo antes. E nadade $ ou R$. Vejamos um exemplo de execuo:

    C:\Arquivos de programas\Python\Curso>..\python despdom1.py

    Balanco de despesas domesticas

    Quanto gastou Ana? 10Quanto gastou Bia? 20Total de gastos = 30.0Gastos por pessoa = 15.0

    C:\Arquivos de programas\Python\Curso>

    Dissecando o cdigo

    Agora vamos acompanhar, linha por linha, como o interpretador executou o programa. Essa aatividade mais importante para desenvolver voc como programador ou programadora. Voc precisaaprender a ler um programa e simular mentalmente que acontece dentro do computador. "Quandovoc aprender a se colocar no lugar do computador ao ler um programa, estar pronto, Gafanhoto".Linha 1: O sinal # indica comentrio. Tudo o que aparece em uma linha a partir desse sinal ignoradopelo interpretador Python. Neste caso, o comentrio explica para ns, humanos, o propsito doprograma. Note que o comentrio no aparece para o usurio final quando o programa executado.Comentrios servem apenas para ser lidos por outros programadores.Linha 3: O velho comando print usado para escrever o ttulo "Balanco de despesas domesticas" natela do usurio.Linha 4: O comando raw_input exibe a pergunta "Quanto gastou Ana?", aguarda uma resposta earmazena na varavel ana.Linha 5: O mesmo comando usado para guardar os gastos de Bia na varivel bia.Linha 6: Aqui calculado o total. Note o uso da funo float. Acontece que a funo raw_input noretorna nmeros, e sim strings. Como vimos no captulo anterior, o operador "+" tem efeitos diferentesquando aplicado a strings; em vez de somar, ele concatena ou junta os textos. Nesse caso, se ana 10 e bia 20, ana + bia seria 1020. Para realizar a soma, precisamos antes transformar as strings

  • em nmeros, o que feito pela funes float ou int. Nesse caso, usamos float porque no vamos noslimitar a aceitar nmeros inteiros.Linha 7: O total exibido, com o auxlio do operador % que insere o valor na posio assinalada peloscaracteres %s dentro da mensagem. O cdigo %s faz com que Python transforme o nmero em string.Linha 8: Clculo da mdia. Como ambos os valores so float, o resultado ser preciso (se fosseminteiros, o resultado tambm seria forado a ser inteiro, o que nesse caso levaria a erros do tipo).Linha 9: Mostramos a mdia, usando a mesma tcnica da linha 7.Experimente rodar o programa algumas vezes. Note que no um programa muito robusto: se vocno digitar coisa alguma e teclar [ENTER] aps uma das perguntas, ou responder com letras em vezde nmeros, o programa "quebra". No prximo captulo aprenderemos a lidar entradas inesperadas.

    Um programa mais esperto

    O programa acima quase til. Ele calcula a despesa total e a mdia, mas no responde perguntafundamental: quanto Ana tem que pagar a Bia, ou vice-versa? A aritmtica envolvida simples: seAna gastou menos, ela precisa pagar a Bia um valor igual diferena entre o que gastou e a mdia.Gostaramos que nosso programa funcionasse assim:

    Balanco de despesas domesticas

    Quanto gastou Ana? 10Quanto gastou Bia? 20Total de gastos: R$ 30.0Gastos por pessoa: R$ 15.0Ana deve pagar: R$ 5.0

    Utilize o comando File > Save As... para salvar o programa despdom1.py como despdom2.py. Agoravamos modific-lo para fazer o que queremos. Abaixo, o programa final, e a seguir, a explicao decada mudana que foi feita.

    # despdom2.py - Calculadora de despesas domesticas - versao 2

    print 'Balanco de despesas domesticas'ana = float(raw_input('Quanto gastou Ana? '))bia = float(raw_input('Quanto gastou Bia? '))printtotal = ana + biaprint 'Total de gastos: R$ %s' % totalmedia = total/2print 'Gastos por pessoa: R$ %s' % mediaif ana < media: diferenca = media - ana print 'Ana deve pagar: R$ %s' % diferencaelse: diferenca = media - bia print 'Bia deve pagar: R$ %s' % diferenca

    Linha 1: Acrescentamos "versao 2" ao comentrioLinhas 4 e 5: Aqui fazemos a converso dos resultados de raw_input para float imediatamente, demodo que os valores armazenados na variveis ana e bia so nmeros, e no strings como antes.

  • Linha 6: Uma mudana cosmtica apenas: acrescentamos uma linha com apenas um print, para deixarna tela uma linha em branco entre as perguntas e os resultados.Linhas 7: Agora podemos simplesmente somar os valores de ana e bia, que j foram convertidos parafloat nas linhas 4 e 5.Linhas 8 a 10: Exibimos o total e processamos a mdia, como antes.Linha 11: Apresentamos um novo comando de bloco, o comando if, que pode ser traduzidoexatamente como "se". Essa linha diz, literalmente: "se ana < media:". Ou seja, se o valor de Ana formenor que o valor da mdia, execute o bloco endentado a seguir (linhas 12 e 13). Caso contrrio, noexecute essas linhas, e passe direto para a linha 14.Linhas 12 e 13: Calculamos e exibimos quanto Ana deve pagar.Linha 14: Aqui vemos outro comando de bloco, o else, que pode ser traduzido como "seno". O elses pode existir aps um bloco iniciado por if. O bloco que segue o else s executado quando acondio prevista no if no ocorre. Isso significa que, quando temos um bloco if e um bloco else, garantido que apenas um dos dois ser executado. Nesse caso, as linhas 15 e 16 s sero executadasse o valor de Ana no for menor que a mdia.Linhas 15 e 16: Calculamos e exibimos quanto Bia deve pagar.Experimente um pouco com o programa despdom2.py. O que acontece quando os gastos de Ana e Biaso iguais? Tente responder essa pergunta sem rodar o programa. A chave est na linha 11. Qual amdia quando os gastos so iguais? Tente simular mentalmente o comportamento do computador naexecuo passo a passo do programa. Dedique alguns minutos a esse desafio, e s ento rode oprograma com valores iguais para ver se acontece o que voc imaginou.

    Tudo sobre o if

    O comando if, que acabamos de conhecer atravs de um exemplo, uma pea fundamental dalinguagem Python, e de quase todas as linguagens de programao existente. Sua funo descritacomo "comando de execuo condicional de bloco", ou seja, um comando que determina a execuoou no de um bloco de comandos, de acordo com uma condio lgica. No exemplo, a condiolgica "ana < media". O operador < serve para comparar dois nmeros e determinar se o primeiro menor que o segundo (ele tambm funciona com strings, mas a a comparao segue uma regraparecida com a ordem usada dos dicionrios). Os operadores de comparao de Python so os mesmosusados em Java e C++:

    Operador descrio exemplo== igual a == b!= diferente a != b< menor que a < b> maior que a > b>= maior ou igual a a >= b

  • >>> a = 1>>> b = 2>>> a == 1>>> a == 2>>> a == b>>> 2 == b>>> a != b>>> a != 1>>> a < b>>> a >= b

    As linhas 1 e 2 no produzem nenhum resultado, como j vimos antes. Elas apenas atribuem valor svariveis a e b. A linha 3 parece um pouco com a linha 1, mas significa algo completamente diferente.Aqui no acontece nenhuma atribuio, apenas uma comparao, que vai gerar um resultado. Um errobastante comum cometido por quem est aprendendo Python, C ou Java usar = no lugar de == aofazer uma comparao (em Basic, por exemplo, o = usado nos dois casos). Aps cada as linhas apartir da linha 3, o interpretador mostrar um nmero 1 ou 0, para indicar que a comparao verdadeira (1) ou falsa (0).Voltando ao comando if, no existe nenhuma lei que force a presena de um operador de comparaona condio do if. A nica coisa que interessa que a expresso que estiver no lugar da condio serconsiderada falsa se for igual a 0 (zero), uma string vazia, uma lista vazia ou o valor especial None,sobre o qual voltaremos a falar depois. Qualquer valor que no seja um desses ser considerado"verdadeiro", e provocar a execuo do bloco subordinado ao if. por isso que os operadores decomparao retornam 0 ou 1 para representar falso ou verdadeiro.No obrigatria a presena de um bloco else aps um if. Mas um else s pode existir aps um if. Eum if pode conter, no mximo, um else. Existe um terceiro comando de bloco relacionado a esses,chamado elif. Ele corresponde combinao else-if existente em outras linguagens. Assim como o if,cada elif deve ser acompanhado de uma condio que determinar a execuo do bloco subordinado.Como todo comando de bloco, a primeira linha do elif deve ser terminada por um sinal de :.Um if pode ser seguido de qualquer quantidade de blocos elif, e se houver um bloco else ele devervir depois de todos os elif. Veja esse fragmento de cdigo, parte de um jogo simples que criaremos noprximo captulo:

    if vf == 0: print 'Alunissagem perfeita!'elif vf

  • Aprenda a programarCaptulo 4

    oramentos, pousos lunares e tratamento de erros

    por Luciano Ramalho O captulo anterior terminou com uma questo no ar. Aps estudarmos todas as formas de se usar ocomando if, restou o desafio de usar um bloco elif para consertar um pequeno defeito no programadespdom2.py. O bug se manifesta quando os gastos de Ana e Bia so iguais. Nesse caso, o programaescreve na tela:

    Bia deve pagar: R$ 0.0

    Em vez de fazer a Bia escrever um cheque de zero reais, o melhor seria tratar esse caso especial. Vejacomo faz-lo, usando uma construo if/elif/else (listagem 1). Se voc guardou o arquivodespdom2.py da lio anterior, ter muito pouco o que digitar. Abra-o e salve com o nome dedespdom3.py. O cdigo idntico verso anterior at a linha 14. Ali, voc faz a primeira alterao:o else substitudo por um elif que verifica se Bia gastou menos que a mdia. As linhas 15 e 16continuam como antes, mas agora elas s sero executadas se bia < media for verdadeiro. As linhas 17e 18 so novas, e servem para tratar o caso em que nem ana < media nem bia < media, ou seja,quando no h diferena a ser paga. Agora voc pode testar o programa digitando valores diferentes edepois valores iguais para as despesas de Ana e Bia.Listagem 1

    1 # despdom3.py - Calculadora de despesas domesticas - versao 3 2 3 print 'Balanco de despesas domesticas' 4 ana = float(raw_input('Quanto gastou Ana? ')) 5 bia = float(raw_input('Quanto gastou Bia? ')) 6 print 7 total = ana + bia 8 print 'Total de gastos: R$ %s' % total 9 media = total/2 10 print 'Gastos por pessoa: R$ %s' % media 11 if ana < media: 12 diferenca = media ana 13 print 'Ana deve pagar: R$ %s' % diferenca 14 elif bia < media: 15 diferenca = media bia 16 print 'Bia deve pagar: R$ %s' % diferenca 17 else: 18 print 'Ana e Bia gastaram a mesma Quantia.'

    Somadora infinita

    Logo adiante iremos reescrever o programinha acima para torn-lo mais flexvel, permitindo digitar osnomes e os gastos de qualquer nmero de pessoas. Assim ele ser til para repartir as contas de umaviagem de frias ou daquela festa entre amigos. Para comear, vamos construir um programa umpouco mais simples, capaz de somar uma srie de nmeros (listagem 2).

  • Listagem 2

    1 # somadora1.py - somadora infinita - versao 1 2 3 print 'Digite os valores a somar Seguidos de .' 4 print 'Para encerrar digite zero: 0' 5 n = float(raw_input(':')) 6 total = n 7 while n != 0: 8 n = float(raw_input(':')) 9 total = total + n 10 print 'TOTAL: %s' % total

    Vamos ver o que faz esse programa, linha por linha.Linhas 3 e 4: Exibimos as instrues de uso.Linha 5: Usamos o comando raw_input() para exibir o sinal ":" e ler o primeiro valor digitado pelousurio, e a funo float para transformar a string resultante em um nmero de ponto flutuante. Oresultado armazenado na varivel n.Linha 6: A varivel total servir para guardar a soma acumulada. Para comear, colocamos nela oprimeiro valor digitado.Linha 7: Aqui usamos um novo comando de bloco, o while. Essa linha pode ser traduzida assim:"enquanto n diferente de zero...". Assim como o comando for, o while causa a execuo repetida dobloco subordinado (linhas 8 e 9). Em um comando while, a repetio condicionada a uma expressolgica do mesmo tipo que usamos com o comando if. Nesse exemplo, a condio n != 0 causar arepetio do bloco enquanto for verdadeiro que n diferente de 0. No momento que n contiver o valor0, a condio ser falsa e a repetio deixar de ocorrer. O programa ento seguir para a linha 10.Linha 10: Mostramos o total acumulado. Fim do programa.

    Mais sobre o while

    Os comandos while e for so semelhantes por causarem a repetio de um bloco. Ambos sochamados, pelos computlogos, de comandos de iterao (iterao sinnimo de repetio; noconfunda com "interao", que uma ao recproca entre dois ou mais agentes).A diferena que no comando for a iterao serve para percorrer uma lista de itens, como fizemosanteriormente quando trabalhamos com tabelas de converso. No caso do for, o nmero de repeties sempre conhecido de antemo: o bloco ser executado uma vez para cada item da lista. O comandowhile serve para todos os outros casos de iterao, quando o nmero de repeties indefinido. Nossasomadora infinita um exemplo tpico: a iterao que solicita valores e os totaliza poder ser repetidaqualquer nmero de vezes, dependendo apenas da sua vontade.Agora vamos analisar de perto duas circunstncias especiais. Rode o programa e digite 0 (zero) comoprimeiro valor. Nas linhas 5 e 6 o programa armazenar o zero nas variveis n e total. A seguir, nalinha 7, o comando while verificar a condio n != 0. Nesse caso, a condio ser falsa. Ento obloco subordinado ao while no ser executado nenhuma vez, e o programa passar direto para a linha10, mostrando o total.Outro momento interessante ocorre quando o primeiro valor digitado no zero, e a iterao executada. Digamos que o usurio digitou [1][Enter], [2][Enter] e [0][Enter]. O zero digitado pelousurio ser lido e armazenado em n na linha 8, como j vimos. Na linha 9 o valor de n somado aototal. Nessa iterao o valor de n zero, portanto estamos somando zero ao total, uma operao

  • inofensiva. S aps efetuar essa soma intil, o programa retornar ao incio do bloco e verificar que acondio do while no mais verdadeira, pois agora nosso n igual a zero. importante perceberque, apesar de o valor de n passar a ser zero na linha 8, a execuo continua at o fim do bloco,passando pela linha 9, para s ento ocorrer o retorno ao incio do bloco e a verificao da condio decontinuidade da repetio.Quando estudamos as condies lgicas no final do captulo anterior, aprendemos que Pythonconsidera o valor 0 (zero) como sinnimo de "falso", e valores no-zero como "verdadeiros".Programadores experientes em Python costumam tirar proveito desse fato para abreviar as condiesque colocam em seus ifs e whiles. Em nosso programa somadora1.py, a linha 7:

    while n != 0:

    Pode ser escrita de forma mais abreviada assim:

    while n:

    Faa essa alterao no programa e experimente. Voc ver que nada mudou no seu funcionamento.Isso porque, quando n diferente de zero, a condio "n" expressa em while n: consideradaverdadeira, e a iterao executada. Quando n passa a ser zero, a condio falsa, encerrando aiterao.

    Loops (quase) infinitos

    Outra forma de escrever a somadora, mais elegante em minha opinio, a mostrada na listagem 3.Listagem 3

    1 # somadora2.py - somadora infinita - versao 2 2 3 print 'Digite os valores a somar seguidos de .' 4 print 'Para encerrar digite zero: 0' 5 total = 0 6 while 1: 7 n = float(raw_input(':')) 8 if n == 0: break 9 total = total + n 10 print 'TOTAL: %s' % total

    Aqui a lgica um pouco diferente: na linha 6 o loop while tem como condio o nmero 1. Como onmero 1 constante, e considerado "verdadeiro" pelo interpretador Python, o loop das linhas 6 a 9seria repetido infinitas vezes, em tese. Na prtica, a linha 8 verifica se o valor de n zero. Em casoafirmativo, o comando "break" acionado. Isso faz com que o loop while seja interrompidoimediatamente, e a execuo do programa passa diretamente para a prxima linha aps o bloco (linha10 em nosso exemplo).Essa forma de codificar, usando loops infinitos com breaks, no est de acordo com a ProgramaoEstruturada, a filosofia dominante entre os programadores nos anos 70. O problema que no ficaimediatamente aparente qual a condio de terminao do loop e alguns professores de computaopodem descontar pontos por isso. Mas em se tratando de um bloco de apenas trs linhas, no acho queisso seja um grande problema. A vantagem que agora a funo de leitura de dados ocorre em apenas

  • um lugar no programa (na linha 7) e no em dois, como na verso anterior (linhas 5 e 8 desomadora1.py). Isso simplificar nossa prxima alterao. Alm disso, no acontece mais a totalizaointil da linha 9, somando zero ao total na sada, porque o comando break da linha 8 faz o programapassar direto para a linha 10.Uma forma mais natural de codificar esse loop seria usar comandos com o do/while ou repeat/untilexistentes em linguagens como C/C++/Java e Pascal/Delphi; nessas estruturas de controle, o teste feito no fim do loop, garantindo a execuo do bloco ao menos uma vez. o que precisamos fazeraqui, mas Python no possui um comando de loop especial para essa situao. Vejamos outroexemplo.Suponha que voc queira, por algum motivo estranho, somar os nmeros naturais (1, 2, 3 etc.) atobter um total maior ou igual a 100. Observe na listagem 4 como ficaria o loop central para fazer issoem Pascal, Java e Python.Listagem 4

    DelphiREPEAT n := n + 1; total := total + n;UNTIL (total >= 100);Javado { n = n + 1; total = total + n;} while (total < 100);Pythonwhile 1: n = n + 1 total = total + n if total >= 100: break

    Note que os trs programas acima esto incompletos; reproduzimos apenas o loop principal.Generalizando, qualquer loop com teste no final pode ser codificado em Python usando-se umacombinao de while 1 e if/break, assim:

    while 1: comando1 comando2 # etc. if condicao_final: break

    Um programa mais tolerante

    Um defeito das nossas somadoras, e de todos os programas que fizemos at agora, que eles notoleram falhas na digitao. Se voc rodar o programa somadora2.py e digitar apenas [Enter] paraencerrar, ver a seguinte mensagem na tela:

  • Traceback (innermost last): File 'somadora1.py', line 7, in ? n = float(raw_input()) ValueError: empty string for float()

    A segunda linha dessa mensagem identifica o local do erro: linha 7 do arquivo (file) somadora1.py.Na terceira linha est reproduzida a linha do programa onde ocorreu o problema, e a mensagem finalinforma qual foi o erro. Podemos traduz-la assim: "Erro de valor: string vazia para a funo float()".O problema que, ao digitarmos [Enter] sem fornecer um nmero, a funo raw_input() retorna umastring vazia (nada mais justo, pois nada foi digitado). Em seguinda, a funo float() tenta transformar astring vazia em um ponto flutuante, mas no sabe como. ela que dispara a mensagem de erro,fazendo com que o programa seja interrompido antes de mostrar o valor total da soma.Efeito semelhante pode ser obtido se voc digitar um texto qualquer em vez de um nmero.Experimente.Nesse caso, a mensagem de erro final : "ValueError: invalid literal for float(): blah". Nesse caso, areclamao de "invalid literal", significando que o texto fornecido para a funo float() no se parececom um nmero.A melhor maneira de resolver esse problema envolve o uso de mais uma comando de bloco dePython: o conjunto try/except (tentar/exceto). Esse par de palavras-chave formam o mecanismo de"tratamento de excees" de Python, algo que s se encontra em linguagens bastante modernas comoJava e as verses mais recentes de C++. A idia bsica simples: no caso da nossa somadora, vamostentar (try) converter a string digitada em float; se isso no der certo, temos uma exceo, que deve tertratamento especial. No nosso caso, vamos simplesmente acionar o comando break para interromper oloop e exibir a totalizao.Veja na listagem 5 como fica a somadora3.py, agora com tratamento de excees.Listagem 5

    1 # somadora3.py - somadora infinita - versao 3 2 3 print 'Digite os valores a somar seguidos de .' 4 print 'Para encerrar apenas .' 5 total = 0 6 while 1: 7 try: 8 n = float(raw_input(':')) 9 total = total + n 10 except: 11 break 12 print 'TOTAL: %s' % total

    Vamos comentar apenas as diferenas em relao verso anterior:Linha 4: mudamos a mensagem para o usurio, j que agora basta um [Enter] para encerrar.Linha 7: incio do bloco try: tentaremos executar as linhas 8 e 9. Qualquer erro que ocorrer aqui sertratado no bloco except.Linha 8: aqui o local mais provvel do erro, quando float() tenta converter o resultado de raw_input().Linha 9: se ocorrer um erro na linha 8, a linha 9 no ser executada porque, dentro do bloco tryqualquer erro causa a transferncia imediata da execuo para o bloco except correspondente.

  • Linha 10: incio do bloco except associado ao bloco try da linha 7Linha 11: tratamento do erro: em caso de exceo, vamos simplesmente interromper o loop com umcomando break.Linha 12: como esta linha vem logo aps um loop infinito (while 1), a nica forma de chegarmos aqui atravs de um break. Ou seja, nesse caso o loop s termina em conseqncia de uma exceo.Experimente o programa agora: ele ficou muito mais conveniente de usar. Para interromper a soma eobter o total, basta teclar [Enter] em uma linha em branco. Uma boa melhoria na "usabilidade" dasomadora!

    Como tratar um erro de verdade

    A terceira verso da nossa somadora ainda no chegou l: tratamos da mesma forma a situao emque usurio no digitou nada e aquela onde ele digitou algo que no um nmero vlido em Python.Pode ser que o usurio seja um datilgrafo moda antiga, que digita L minsculo no lugar do dgito1. Ou ainda algum que quer usar, com toda razo, a "," como separador decimal (Python s aceitanmeros com ponto decimal). Para diferenciar um tipo de erro do outro, e saber quando o usurioapenas quer encerrar o programa, precisamos guardar a linha que ele digitou antes de tentartransform-la em um nmero. Veja como na listagem 6.Listagem 6

    1 # somadora4.py - somadora infinita - versao 4 2 3 print 'Digite os valores a somar seguidos de .' 4 print 'Para encerrar apenas .' 5 total = 0 6 while 1: 7 try: 8 linha = raw_input(':') 9 n = float(linha) 10 total = total + n 11 except: 12 if len(linha) == 0: 13 break 14 elif ',' in linha: 15 print 'Use o . (ponto) como separador decimal.' 16 else: 17 print 'Isso nao parece um numero valido.' 18 print 'TOTAL: %s' % total

    Vamos analisar as novidades dessa verso:Linha 8: a nova variavel linha armazena a linha digitada pelo usurio, para verificao posterior.Linha 9: a linha convertida em nmero.Linha 11: incio do bloco que tratar os erros, provavelmente ocorridos na linha 9.Linha 12: a funo len() retorna o nmero de itens de uma seqncia; nesse caso, o nmero decaracteres da string linha. Se o nmero igual a zero, ento a string est vazia.Linha 13: no caso da string vazia, executamos um break porque o usurio no quer mais digitar.Linha 14: o operador in (em) retorna verdadeiro se o item esquerda for encontrado na seqncia direita; nesse caso verificamos se existe uma vrgula dentro da string linha.Linha 15: como encontramos uma vrgula, vamos supor que o usurio tentou digitar um nmero

  • fracionrio. Ento vamos sugerir que ele use o ponto decimal. Nesse caso, no executamos o break.Nenhum outro comando no bloco if/elif/else ser executado, e o loop recomear de novo a partir dalinha 6.Linhas 16 e 17: aqui vamos tratar todos os demais casos, dizendo que o que foi digitado no se parececom um nmero. Novamente, sem o break, o loop reiniciar, e logo o sinal ':' aparecer na telaaguardando nova digitao.

    Associao de nomes a valores

    Voltemos ao problema do clculo de despesas. Nossa meta fazer um programa que seja capaz decalcular a partilha de gastos de qualquer grupo de pessoas, e no apenas de Ana e Bia. Para isso,vamos precisar associar o nome das pessoas aos seus respectivos gastos. A linguagem Python possuiuma estrutura de dados ideal para essa aplicao. o dicionrio, conhecido pelos programadores Perlcomo hash ou associao. Como ocorre em Perl, em Python o dicionrio serve para associar chaves avalores. O mais comum que as chaves sejam strings, como no nosso caso, onde as chaves seronomes de pessoas. Mas as chaves podem ser qualquer tipo de objeto.Em Python o dicionrio bem mais poderoso que em Perl, pois seus valores podem conter qualquertipo de objeto como listas e at mesmo outros dicionrios. Para entender rapidamente o funcionamentode um dicionrio, nada melhor que experimentar com o interpretador interativo IDLE. Faa osseguintes testes, que explicaremos a seguir, com a listagem 7.Listagem 7

    1 Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32 2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam 3 dic = {} 4 >>> dic['ze'] = 300 5 >>> dic['mauricio'] = 100 6 >>> dic['heloisa'] = 150 7 >>> dic['ze'] 8 300 9 >>> dic 10 {'mauricio': 100, 'ze': 300, 'heloisa': 150} 11 >>> dic['ze'] = 200 12 >>> dic 13 {'mauricio': 100, 'ze': 200, 'heloisa': 150} 14 >>> dic.keys() 15 ['mauricio', 'ze', 'heloisa'] 16 >>> dic['paulo'] 17 Traceback (innermost last): 18 File '', line 1, in ? 19 dic['paulo'] 20 KeyError: paulo 21 >>> dic.has_key('heloisa') 22 1 23 >>> dic.has_key('paulo') 24 0 25 >>>

    Linha 3: antes de usar um dicionrio, preciso cri-lo. Nesse caso, criamos um dicionrio vazio. Aschaves {} so usadas para representar dicionrios, como veremos novamente nas linhas 10 e 13.Linhas 4, 5 e 6: criamos trs itens no dicionrio, usando as chaves 'ze', 'mauricio' e 'heloisa' e osvalores 300, 100 e 150, respectivamente.Linhas 7 e 8: aqui acessamos o valor associado chave 'ze' e obtemos o nmero 300.

  • Linhas 9 e 10: agora acessamos o dicionrio como um todo, e obtemos uma listagem entre chaves,com os itens separados por vrgula. Cada par de chave e valor aparece separado pelo sinal ':'. Note quea ordem dos itens no tem lgica aparente. Python no garante a ordem dos itens de um dicionrio.Linha 11: associamos um novo valor a uma chave existente. Num dicionrio, todas as chaves sonicas. No pode haver dois itens com a mesma chave 'ze'. Assim, essa operao muda o valorassociado esta chave.Linhas 12 e 13: exibimos de novo o dicionrio inteiro. Note que o valor associado chave 'ze' mudou.Linha 14: o mtodo keys() retorna a lista de chaves do dicionrio. Um mtodo nada mais que umafuno associada a um objeto, que deve ser invocada usando a sintaxe objeto.metodo(). Em nossoexemplo temos dic.keys().Linha 15: aqui aparece a lista de chaves. Note que a lista, como sempre, vem delimitada porcolchetes. O resultado do mtodo keys() uma lista de chaves, e no um dicionrio.Linhas 16 a 20: tentamos acessar o valor de uma chave inexistente. Python reclama com a mensagem'KeyError: paulo', indicando que o dicionrio no possui uma chave igual a 'paulo'.Linhas 21 a 24: para verificar se uma determinada chave existe, usamos o mtodo has_key()(tem_chave). Os exemplos mostram que has_key() retorna 1 quando a chave existe, e zero quando elano existe.

    Resolvendo o Oramento da Repblica

    Agora que conhecemos o funcionamento bsico dos dicionrios, podemos implementar o nossoaplicativo de acerto de contas, que pode ser muito til por exemplo na administrao de uma repblicade universitrios. Antes de mais nada, vejamos como vai funcionar o programa (listagem 8):Listagem 8

    1 D:\magnet\aprendaprog\cap04>python desprep1.py 2 Balanco de despesas da Republica Recanto Suico 3 4 (deixe um nome em branco para encerrar) 5 6 Digite o nome da pessoa: Marcos 7 Quanto gastou Marcos? 10 8 Digite o nome da pessoa: Alexandre 9 Quanto gastou Alexandre? 500 10 Digite o nome da pessoa: Tyrone 11 Quanto gastou Tyrone? 250 12 Digite o nome da pessoa: Harley 13 Quanto gastou Harley? 124,67 14 Numero invalido. 15 Quanto gastou Harley? 124.67 16 Digite o nome da pessoa: 17 18 Numero de pessoas: 4 19 Total de gastos: R$ 884.67 20 Gastos por pessoa: R$ 221.17 21 22 Saldo de Marcos: -211.17 23 Saldo de Alexandre: 278.83 24 Saldo de Tyrone: 28.83 25 Saldo de Harley: -96.50 26 27 D:\magnet\aprendaprog\cap04>

  • Linha 1: invocao do programa a partir da linha de comando.Linhas 2 e 4: apresentao e instrues de uso.Linha 6: o programa pergunta o nome de uma pessoa.Linha 7: a seguir, solicita o valor dos gastos daquela pessoa.Linhas 8 a 12: o processo repetido quantas vezes for necessrio.Linha 13: o usurio digita um nmero com vrgula no lugar do ponto decimal.Linha 14: o programa informa que o numero "invlido".Linha 15: novamente o programa pede o valor gasto por Harley.Linha 16: o usurio no fornece outro nome, encerrando a digitao.Linhas 18 a 20: o nmero de pessoas, o total gasto e o gasto mdio por pessoa so calculados.Linhas 22 a 25: para cada pessoa, o programa exibe seu saldo. Aqueles que tm saldo negativo tmvalores a pagar; os que de saldo positivo tm valores a receber.Agora, vamos listagem do programa desprep1.py (listagem 9):Listagem 9

    1 #desprep1.py - calculo de despesas da republica 2 3 print 'Balanco de despesas da Republica Recanto Suico' 4 print 5 print '(deixe um nome em branco para encerrar)' 6 print 7 total = 0 8 contas = {} 9 while 1: 10 pessoa = raw_input('Digite o nome da pessoa: ') 11 if not pessoa: break 12 while 1: 13 resp = raw_input('Quanto gastou %s? ' % pessoa) 14 try: 15 gasto = float(resp) 16 break 17 except: 18 print 'Numero invalido.' 19 contas[pessoa] = gasto 20 total = total + gasto 21 22 num_pessoas = len(contas) 23 print 24 print 'Numero de pessoas: %d' % num_pessoas 25 print 'Total de gastos: R$ %.2f' % total 26 media = total/num_pessoas 27 print 'Gastos por pessoa: R$ %.2f' % media 28 print 29 for nome in contas.keys(): 30 saldo = contas[nome] - media 31 print 'Saldo de %s: %.2f' % (nome, saldo)

    Linhas 3 a 5: exibir identificao e instrues.Linha 7: a varivel total inicializada com o valor zero. Isso necessrio em funo da linha 21.Linha 8: o dicionrio de contas criado, sem contedo. Ele armazenar as contas de cada pessoa.

  • Linha 9: incio do loop principal.Linha 10: solicitamos um nome e armazenamos na varivel pessoa.Linha 11: se a varivel pessoa estiver vazia, nenhum nome foi digitado. Ento executamos um breakpara deixar o loop principal, j que o usurio no quer mais fornecer nomes.Linha 12: incio do loop secundrio, para digitao do valor numrico.Linha 13: solicitamos o valor gasto pela pessoa em questo.Linha 14: incio do bloco try, onde tentaremos converter a string digitada em nmero.Linha 15: a converso fatdica. Em caso de erro aqui, o programa saltar para o bloco except, na linha17.Linha 16: esse break s ser executado se no ocorrer erro na linha 15. Sua funo interromper oloop secundrio quando obtivermos um valor numrico.Linhas 17 e 18: o bloco except simplesmente exibe na tela a mensagem "Numero invalido". Aqui seencerra o loop secundrio, que repetir novamente a partir da linha 12, solicitando outro valor.Linha 19: o gasto obtido armazenado no dicionrio, usando o nome da pessoa como chave.Linha 20: o total de gastos atualizado. Aqui o final do loop principal. Daqui o programa voltarpara a linha 9, e pedir os dados da prxima pessoa.Linha 22: a funo len() usada para contar o nmero de itens no dicionrio.Linhas 23 a 25: so exibidos o nmero de pessoas e total gasto. A notao %.2f faz com que os gastosapaream com duas casas decimais, pois trata-se de um valor em dinheiro.Linhas 26 a 27: o gasto por cabea calculado e mostrado, tambm com duas casas decimais.Linha 29: aqui comeamos um loop for que ser repetido para cada nome que constar na lista dechaves do dicionrio. A lista de chaves obtida atravs do mtodo keys(). A varivel nome apontar,sucessivamente, para cada nome encontrado nesta lista.Linha 30: os valor gasto por uma pessoa obtido acessando o dicionrio com a expresso contas[nome]. Subtramos o gasto mdio para obter o saldo daquela pessoa.Linha 31: exibimos o nome e o saldo da pessoa. Esta a ltima linha do loop for, que percorrer todasas chaves do dicionrio.

    Nossa primeira simulao

    Agora j sabemos tudo o que precisvamos para implementar um jogo simples, como havamosprometido no captulo anterior. Trata-se de uma simulao de pouso lunar, em modo texto. Esseprograminha baseado em um jogo clssico escrito para calculadoras HP-25. Nossa verso bemmais fcil de entender que o original para calculadora (cuja listagem apareceu na seo A Web comoEla da Magnet nmero 3). Em vez de explicar linha por linha o funcionamento do programa,colocamos comentrios abundantes na prpria listagem, delimitados pelo sinal #. Lembre-se de queno preciso digitar os comentrios (e o programa inteiro pode ser simplesmente copiado do site daMagnet). Esse simulador de alunissagem um game de recursos mnimos, mas ainda assim deve valeralguns minutos de diverso, especialmente se voc curte a fsica newtoniana ensinada no colegial.

  • O jogo da alunissagem

    O jogo da alunissagem # lunar.py # importar funcao sqrt do modulo math from math import sqrt

    x = 500. # altitude em pes v = -50. # velocidade em pes/s g = -5. # aceleracao gravitacional lunar em pes/s/s t = 1. # tempo entre jogadas em segundos comb = 120. # quantidade de combustvel

    print 'Simulacao de alunissagem' print print '(digite a quantidade de combustivel a queimar)'

    fmt = 'Alt: %6.2f Vel: %6.2f Comb: %3d' while x > 0: # enquanto nao tocamos o solo msg = fmt % (x, v, comb) # montar mensagem if comb > 0: # ainda temos combustivel? # obter quantidade de combustivel a queimar resp = raw_input(msg + ' Queima = ') try: # converter resposta em numero queima = float(resp) except: # a resposta nao era um numero queima = 0 if queima > comb: # queimou mais do que tinha? queima = comb # entao queima o que tem comb = comb - queima # subtrai queimado a = g + queima # acel = grav + queima else: # sem combustivel print msg # mensagem sem perguntar a = g # aceleracao = gravidade x0 = x # armazenar posicao inicial v0 = v # armazenar velocidade inicial x = x0 + v0*t + a*t*t/2 # calc. nova posicao v = v0 + a*t # calc. nova vel. # se o loop acabou, tocamos no solo (x

  • como o mostrado abaixo (colocamos em nosso site um desses em branco, para voc imprimir e usar).As unidades esto no sistema ingls, como no original. O mais importante voc saber que cada 5unidades de combustvel queimadas anulam a acelerao da gravidade. Se queimar mais do que 5unidades, voc desacelera; menos do que 5, voc ganha velocidade. Primeiro, pratique seus pousospreocupando-se apenas com a velocidade final. Depois voc pode aumentar a dificuldade,estabelecendo um limite de tempo: por exemplo, o pouso tem que ocorrer em exatos 13 segundos.Uma ltima dica: cuidado para no queimar combustvel cedo demais. Se voc subir, vai acabarcaindo de uma altura ainda maior! Boas alunissagens!

    Aprenda a programarCaptulo 5

    O segredo dos objetos-funo: saiba como criar seus prprios comandos

    por Luciano Ramalho O simulador de alunissagem lunar.py, apresentado no ltimo captulo, tem 50 linhas de cdigo. umjogo bem simples, mas foi nosso exemplo mais extenso at o momento. Em termos de programaoprofissional, trata-se de um programa bem pequeno. No mundo real, softwares modestos tm milharesde linhas de cdigo, e essa contagem chega aos milhes quando se fala de grandes alicativos como oMicrosoft Word ou o sistema operacional Linux. Ao se trabalhar com programas maiores, fundamental poder dividir o trabalho em mdulos, em vez de criar uma soluo "monoltica" com a donosso lunar.py, onde o programa inteiro est expresso em uma nica sequncia de comandos. A partirde agora, vamos ver porque e como modularizar nossos programas, utilizando os conceitos de funo,objeto, classe, mdulo e pacote.

    Dividir para conquistar

    Um programa modularizado facilita o planejamento, a distribuio de tarefas entre vriosprogramadores, o controle de qualidade e a reutilizao de solues. Por exemplo, no captulo anteriorutilizamos vrias vezes sequncias de comandos para ler dados do usurio, parecidas com o fragmentodo programa desprep1.py (mostrado na listagem 1).O ideal seria reunir sequncias como esta em um mdulo que ns pudssemos reutilizar facilmenteem qualquer um de nossos programas, em vez de redigitar ou cortar e colar esse cdigo sempre queprecisarmos reutiliz-lo. Ao evitar a redigitao, no s economizamos tempo, mas ainda limitamos apropagao de "bugs", ou falhas de programao. Imagine se, aps meses de programao, usandocentenas de vezes o fragmento, descobrimos que ele contm um erro em sua lgica. Se o cdigo foicopiado manualmente para cada programa onde foi utilizado, seremos obrigados a localiz-lo ecorrigi-lo em centenas de arquivos diferentes. Por outro lado, se o fragmento foi devidamenteempacotado em um mdulo, a correo somente precisa ser feita em um arquivo.Listagem 1

    while 1: resp = raw_input('Quanto gastou %s? ' % pessoa) try: gasto = float(resp) break except: print 'Numero invalido.'

  • Programao estruturada

    A primeira grande onda a favor da modularizao no desenvolvimento de software foi a chamada"programao estruturada". No incio dos anos 70, essa expresso estava to na moda quanto a"programao orientada a objetos" de hoje. Na realidade, a programao orientada a objetos, ou OOP,pode ser entendida como uma radicalizao da programao estruturada. A pea-chave daprogramao estruturada o conceito de subprograma, um fragmento com comeo, meio e fim, quedesempenha um papel bem definido dentro de um programa maior. Na linguagem Python, umsubprograma definido atravs do comando de bloco def. Existem dois tipos de subprogramas:procedimentos e funes. Em Python, a nica diferena entre eles que as funes produzem valores,e os procedimentos no. Seguindo a tradio da linguagem C, os criadores do Python preferem falarapenas de funes, considerando os procedimentos apenas um tipo especial de funo.Vamos usar o IDLE para ver como se define uma funo. Digite as duas linhas abaixo e tecle [Enter]duas vezes para concluir:

    >>> def dobro(x):... return x * 2

    Aparentemente, nada acontece. Mas voc acabou de definir uma funo, chamada dobro, que estarmazenada na memria do interpretador Python. Para ver sua funo funcionar, basta invoc-laassim:

    >>> dobro(3)6

    Agora vamos aos detalhes da nossa definio de funo. A primeira linha, def dobro(x):, traz duasinformaes importantes: o nome da funo, dobro, e a presena de um argumento, x. O argumento uma varivel especial que associada ao valor fornecido pelo usurio na invocao da funo. Aoreceber a instruo dobro(3), Python associa x ao valor 3. A segunda linha da funo, return x * 2pode ser lida da direita para a esquerda. Primeiro Python calcula a expresso x * 2. Em nossoexemplo, o x est associado ao valor 3, portanto o resultado 6. O comando return sinaliza o fim dafuno, e faz com que o resultado seja passado para quem a invocou. No exemplo abaixo, a funo invocada no meio de uma expresso aritmtica:

    >>> y = dobro(7) + 1>>> y15>>>

    hora de quebrar algumas regras para ver o que acontece. Primeiro, experimente digitar isso:

    >>> dobro()

  • O resultado ser um "traceback" com a mensagem de erro "not enough arguments; expected 1, got 0",ou "argumentos insuficientes; 1 esperado, 0 recebido". Isso aconteceu porque nossa definio, defdobro(x), obriga o usurio da funo a fornecer um argumento. possvel criar uma funo que nopede argumentos, como veremos depois. Outro experimento interessante digitar apenas o nome da funo:

    >>> dobro

    Vale a pena parar e pensar no que acabou de acontecer. Se voc digita o nome da funo sem parnteses, o interpretador no a executa, mas apenas informa aque se refere aquele nome. O que ocorre quando usamos o comando def a criao, na memria, deum objeto do tipo "function", ou funo. O nome fornecido aps o comando def associado ao objeto-funo. Mas o objeto funo existe independente do nome.

    Funes como objetos

    Acabamos de fazer uma afirmao importante, que vale a pena repetir: Python permite criar funesque so tratadas da mesma forma que outros objetos da linguagem, como nmeros e listas. Paraentender as implicaes disso, bom reforar o nosso entendimento de como Python lida com osobjetos que criamos. Para tanto, vamos deixar as funes um pouco de lado e voltar a brincar comlistas:

    >>> l = [10,20,30,40]

    Acabamos de criar uma lista "l" com quatro elementos. Essa a forma sucinta de dizer o que ocorreu.Uma descrio bem melhor a seguinte: criamos uma lista com quatro elementos e associamos avarivel "l" a esta lista. A letra "l" apenas uma etiqueta que identifica a lista; importante notar quea lista existe mesmo antes de receber uma etiqueta.Comprove:

    >>> m = l>>> m[10, 20, 30, 40]>>>

    Agora associamos m a l, ou melhor, lista associada a l. Nosso objeto-lista agora tem duas etiquetas.Podemos usar qualquer uma delas para se referir a ele, tanto que, ao digitarmos m, o interpretadormostra a mesma lista. Podemos tambm acessar e modificar um item especfico da lista:

  • >>> m[2]30>>> m[2] = 55>>> m[10, 20, 55, 40]>>>

    Agora digite l e veja o resultado:

    >>> l[10, 20, 55, 40]>>>

    O que aconteceu com o l? Absolutamente nada! Ele continua sendo uma mera etiqueta colada emnosso objeto-lista. Mudamos a lista atravs da etiqueta m, mas tanto m quanto l referem-se mesmalista, como voc acabou de comprovar.O mesmo ocorre com funes. Ao interpretar o cdigo def dobro(x): return x * 2, Python cria umobjeto-funo e o associa etiqueta dobro. Nada impede que voc associe outras etiquetas ao mesmoobjeto, assim:

    >>> f = dobro>>> f

    Note que o nome f agora est associado ao mesmo objeto-funo que antes chamamos de dobro. O novo nome tambm pode ser usado para invocar a funo:

    >>> f(19)38>>> y = f(17) + 2>>> y36>>>

    Ao tratar funes como objetos, Python deixa para trs linguagens mais tradicionais como C++ e Java,e se junta a uma classe de linguagens utilizadas em trabalhos avanados de Cincia da Computao:linguagens de programao funcional. A mais famosa delas, Lisp, tem sido ferramenta fundamental napesquisa de Inteligncia Artificial h vrias dcadas. Um dialeto simplificado de Lisp, chamadoScheme, usado nos cursos introdutrios de computao do MIT (Massachussetts Institute ofTechnology), um dos mais importantes centros de pesquisa em informtica do planeta. Como voc v,estudando Python estamos em tima companhia.Vejamos na prtica uma vantagem de tratarmos funes como objetos. Python possui uma funopoderosa chamada map. Vamos us-la agora:

    >>> map(dobro, m)[20, 40, 110, 80]>>>

  • Invocamos a funo map com dois argumentos. O primeiro a nossa funo dobro, e o segundo alista m, [10, 20, 55, 40]. A funo map aplica o objeto-funo a cada item do segundo argumento. Oresultado a criao de um novo objeto-lista, sem modificar o original.Veja este outro exemplo:

    >>> map(str, m)['10', '20', '55', '40']>>>

    Neste caso, usamos a funo embutida (ou pr-definida) str para converter cada um dos itensnumricos em uma string.

    Argumentos default

    Como j dissemos, uma funo no precisa retornar um valor. Veja este exemplo:

    >>> def bom_dia():... print 'Bom dia, humanide!'

    Isso o que chamamos de procedimento: uma funo que faz alguma coisa (neste caso, imprime umamensagem), mas no retorna um valor. Voc pode invoc-lo assim:

    >>> bom_dia()Bom dia, humanide!>>>

    intil usar esse procedimento em uma expresso:

    >>> x = bom_dia()Bom dia, humanide!>>> x>>> x == None1>>>

    Nossa funo bom_dia dispensa argumentos, j que em sua definio no colocamos nada entre osparnteses. Para sermos mais simpticos com nossos usurios, poderamos modific-la para aceitar umnome, desta maneira:

    >>> def bom_dia(nome = 'humanide'):... print 'Bom dia, %s!' % nome

    Note que, neste caso, associamos um valor ao argumento nome. o chamado valor "default", que serusado caso o argumento no seja fornecido. Veja como:

  • >>> bom_dia('Martinha')Bom dia, Martinha!>>> bom_dia()Bom dia, humanide!>>>

    A idia de argumento default outro ponto forte da linguagem Python, oferecendo grandeflexibilidade na definio de funes.

    Usando mdulos

    Uma vez entendido o bsico de funes, podemos passar para os mdulos, que so colees defunes. Antes de criarmos nossos prprios mdulos, bom aprender a usar mdulos prontos, parano ficarmos "reinventado a roda". Assim como qualquer boa linguagem moderna, Python possui umacoleo de mdulos com milhares de funes testadas e prontas para uso em diferentes tipos deaplicaes. A verso 1.5.2 do Python inclui mais de 140 mdulos, sem contar com a extenso grficaTk. E muitos outros podem ser encontrados a partir do site Python.org, quase todos livres e gratuitos. Que tipo de coisa pode ser encontrada nessa vasta biblioteca? Eis alguns exemplos de mdulos,apenas para dar uma idia:cgi: programao de pginas dinmicas para a Webftplib: montagem de scripts para interao com servidores FTPgzip: leitura e escrita de arquivos comprimidosmath: funes matemticas (trigonometria, logaritmos etc.)re: buscas de texto avanadas com expresses regulares (como na linguagem Perl)string: operaes com strings, incluindo converses de listastime: hora atual e converso de formatos de dataxmllib: interpretao de arquivos em formato XMLComo primeiro exemplo de como se usa um mdulo, vamos recorrer ao mdulo calendar, umconjunto de funes de alto nvel (ou seja, fceis de usar) para gerar calendrios. Voltando ao seuinterpretador Python, digite o seguinte:

    >>> import calendar

    O comando import geralmente no produz um resultado visvel. Ele localiza o mdulo mencionado,carrega para a memria suas funes e executa os comandos de inicializao do mdulo, se existirem.Em nosso caso, as funes do arquivo calendar.py acabaram de ser lidas para a memria. Para us-las,voc digita o nome do mdulo e o nome da funo separados por um ".":

  • >>> calendar.prmonth(2000,3) March 2000Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30 31>>>

    Fornecendo o ano e o ms, voc recebe o calendrio do ms prontinho. Existe tambm uma funopara gerar um calendrio anual. Experimente:

    >>> calendar.prcal(2000)

    Devido a limitaes das bibliotecas-padro da linguagem C que so a base do Python, o mdulocalendar no chega a ser um "calendrio perptuo". Ele s trabalha com datas de janeiro de 1970 ajaneiro de 2038. Para os curiosos, a explicao que, internamente, as funes de C armazenam datascontando o nmero de segundos transcorridos desde 1/1/1970. Exatamente sete segundos aps 1:14 damadrugada do dia 19/01/2038, esse nmero exceder o limite de um nmero inteiro de 32 bits. maisum bug do novo milnio...Agora, vamos supor que voc deseja exibir o calendrio mensal de uma outra maneira, por exemplo,separando os dias por tabs, para facilitar a exportao para um programa de editorao eletrnica. Ouainda, podemos querer gerar um calendrio em HTML. Nesses dois casos, o resultado da funoprmonth() no muito til. A funo monthcalendar() nos d mais liberdade. Veja como ela funciona:

    >>> calendar.monthcalendar(2000,3)[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9,10, 11, 12], [13, 14, 15, 16, 17, 18,19], [20, 21, 22, 23, 24, 25, 26], [27,28, 29, 30, 31, 0, 0]]>>>

    O resultado uma lista de listas. Cada uma das cinco listas de den