associacao pyconbrasil django turbogears zope planet Início Logado como (Login)

AprendendoComPygame

Índice

Capítulo 0

Introdução

  • Por quê?
  • O que
  • Ferramentas
  • Lugar

Capítulo 1

Interaja

  • Interpretador
  • Nomes
  • Compare
  • Controle
  • Loops
  • Funções
  • Listas
  • Ajuda
  • Exercícios

Capítulo 2

Módulos

  • Import
  • Random
  • Namespaces
  • Funções
  • Classes
  • Exercícios

Capítulo 3

Demo

  • Bola
  • Demo
  • Exercícios

Capítulo 4

Pong

  • Paddle
  • Ball
  • Game
  • Tweak
  • Exercises

Capítulo 5

Frog

  • Hop Hop
  • Sploosh
  • Vroom
  • Rolling
  • Variation
  • Exercises

Licença

  • GNU Free Documentation License


Prefácio

O objetivo deste livro é introduzir a programação de computadores a qualquer pessoa que esteja realmente iniciando.

Dito isso, faz bastante tempo desde que eu próprio aprendi muitas destas idéias. Se algo não lhe parecer claro, ou se você achar que estou explicando o que é óbvio, por favor deixe-me saber para que eu possa corrigir o problema para os próximos leitores.

Outra coisa, ao ler este livro, tenha isso em mente:

  • Você não pode aprender a programar lendo um livro. Você precisa escrever código, um monte de código.

Então, conforme for lendo, teste os exemplos, mas se o livro lhe inspirar uma idéia, não hesite e pratique-a. Modifique os exemplos e veja no que dá.

Brinque, se divirta, veja o que você pode fazer, então volte e leia um pouco mais. Esta é a melhor maneira de aprender.


Capítulo 0

Introdução

Por quê?

O computador é uma ferramenta muito versátil e poderosa.

A coisa realmente mais interessante sobre computadores é que eles são programáveis. Isso significa que o computador pode fazer muitas coisas diferentes por carregar e seguir diferentes conjuntos de instruções, chamados programas.

  • abiword
  • gimp
  • gnumeric
  • sh
  • bzflag

Existem muitos programas disponíveis prontos para usar, o que não requer nenhuma programação de sua parte para instalá-los no seu computador ou usá-los, mas às vezes os programas disponíveis não são extamente o que você quer.

O ato de criar novos programas ou modificar os que já existem para que atendam melhoras suas necessidades é chamado programação.

O que é?

Instruções

Se um computador fosse um jogo de tabuleiro, um programa seria as instruções para o jogo. O programa diz ao computador como começar, o que fazer e certas situações particulares e quando parar.

Esta não é uma analogia perfeita, é claro, mas vai nos ajudar bem a começar.

Um maneira em que um programa é como um jogo de tabuleiro é que cada jogador precisa esperar a sua vez.

Às vezes, quando um complexo programa de computador está rodando, pode parecer que há todo um mundo ao redor dele, tudo se movendo simultaneamente, mas isso é apenas uma ilusão.

O computador pode processar apenas uma instrução por vez.

No entanto, ele pode processar as instruções tão rapidamente que para nós ele parece simultâneo e quase vivo.

Ferramentas

Antes de poder começar a programar, você precisa instalar certas ferramentas.

Computador

  • O seu computador não precisa ser o último nem o mais rápido, mas eu recomendo que você use um sistema operacional amigável para programar, como linux ou BSD. Todos os exemplos neste livro vão rodar perfeitamente no Windows, MacOS, Linux, ou BSD.

Compilador ou interpretador

  • Existem centenas de diferentes linguagens de programação disponíveis atualmente. Neste livro nós vamos iniciar com python. Esta linguagem é livre (pode ser usada livremente sem custos) e está disponível para uma ampla variedade de sistemas operacionais. (Download).

Editor

  • Um editor de textos é diferente de um processador de textos. Não tente editar os seus programas com o Word. Isso é possível, mas é difícil. O python já vem com um editor chamado IDLE, mas você pode querer testar outros editores também. Em sistemas parecidos com unix, como o Linux, eu recomendo o NEdit ou o Kate. No Windows você querer simplesmente usar o notepad por enquanto, mas você realente quiser programar você pode querer algo bem melhor. Algumas pessoas recomendam o SciTE para windows. No MacOS, o BBEdit serve bem.

As próximas duas coisas não são essenciais para a programação em geral, mas nós vamos usá-las para começar:

Pygame

  • Para fazer o aprendizado de programação mais divertido, nós vamos usar gráficos. Programas gráficos geralmente são considerados um tópico mais avançado, mas com as ferramentas apropriadas isso não é muito difícil, e vai nos ajudar a fazer as coisas ficarem mais claras. Pygame (http://pygame.org) é um conjunto de bibliotecas python que precisa ser instalado em seu sistema para ajudar com a parte gráfica.

pygsear

  • Como um suplemento para o Pygame, pegue os arquivos que eu fiz para ajudar as pessoas a começar a programar. Eu os chamo pygsear (http://www.nongnu.org/pygsear/). Pegue o arquivo com o maior número de versão da página, seja em .zip ou em .tar.gz, o que for mais fácil para você descompactar. O arquivo que você precisa é algo como pygsear-0.52.tar.gz ou pygsear-0.52.zip.

Lugar

  • Isso pode significar um abiente de trabalho quieto, onde ninguém vá interrompê-lo constantemente enquanto você está tentando pensar. Isso é importante, visto que programar requer pensar um tanto. No entanto, mais importante ainda é um lugar de trabalho no computador -- algum lugar seguro para colocar seus arquivos onde ninguém vá acidentalmente apagá-los -- algum lugar onde você possa organizar as coisas de uma forma que faça sentido para você. Crie uma pasta para trabalhar nela. dentro desta pasta, descompacte a biblioteca pygsear que você baixou. Isso deve criar uma nova pasta chamada como pygsear-0.47.

Teste o ambiente:

  • Para ver se tudo está funcionando bem, tente rodar o programa de teste. Isso deve ser fácil como clicar no arquivo test.py dentro da pasta pygsear. Se isso não funcionar, você deve abrir um console (janela de terminal modo texto), mudar para o diretório onde foi descompactado o pygsear e digitar:

 python test.py 

  • Próximo passo, tenha certeza de que você possa usar seu editor com os arquivos neste diretório, e também salvá-los ali. Se tudo está funcionando, nós estamos prontos para começar a programar!

Não está funcionando!

  • Se algo não está funcionando corretamente -- seja o programa de teste que não está iniciando, ou você não consegue entender como usar o editor de textos -- você pode precisar pedir a ajuda de alguém para deixar tudo funcionando nesta primeira vez. Quando você pedir ajuda à alguém, veja o que ele faz e pergunte se você não entender!


Capítulo 1

Interaja

Interpretador

  • Eventualmente, seu program vai parecer como outros programas. Ele vai ter um ícone onde as pessoas cliquem, o que fará rodar. Mas por enquanto, nós vamos trabalhar na linha de comando -- o modo interativo.

Nota: Se você está trabalhando em um sistema com um terminal de texto decente (BSD, Linux, etc) você pode querer usá-lo em vez do arquivo interact.py para estas sessões interativas. Simplesmente abra um terminal no diretório de exemplo, digite python e então digite from penguin import *. Depois disso, o efeito deve ser o mesmo de usar o arquivo interact.py, com a diferença de que você vai ter mais recursos de edição de texto. O interpretador interativo é uma maneira para digitar programas em python e obter os resultados imediatamente. Olhe no diretório de exemplos do pygsear e rode o programa chamado interact.py. Você deve ver uma nova janela com um pequeno pinguim no meio da tela. O >>> no canto inferior esquerdo é chamado de prompt. Ele é o interpretador Python esperando que você o diga o que fazer.

Vamos começar com algo chamado 'gráficos tartaruga'. Estranhamente, nossa tartaruga vai se parecer com um pinguim. O pingüim é chamado pete. Vamos fazer com que pete desenhe uma linha. Digite isso e pressione [ENTER]:

pete.forward(100)

Este comando é uma chamada de função ou de método. Ele diz para o pete andar 100 pixels para a frente. Você pode colocar qualquer número dentro dos parentêses (mesmo números negativos), mas tenha em mente que a tela onde pete está andando tem provavelmente apenas 600 pixels de largura e 500 pixels de altura.

Nós podemos também fazer pete se virar:

pete.right(30)

pete entende como se virar em graus, então quando nós dizemos para pete right(30), ele vira 30 graus para sua direita. Note que a quantidade é relativa à onde pete está olhando quando você o diz para se virar. Isso significa que se você dizer pete.right(30) de novo, pete vai se virar um pouco mais para a direita, e se você faz pete.right(30) mais uma vez ele vai ter virado um total de 90 graus e vai estar olhando para o lado direito da tela.

Agora zere o gráfico por digitar: reset()

Veja se vcê consegue fazer pete andar em volta de um quadrado. Como você pode fazer isso?

Algo como isso:

Primeiro, vá para a frente novamente. Note que usando as setas do teclado para cima e para baixo você pode recuperar as linhas que você digitou anteriormente e poupar um pouco de digitação. Então aperte a seta para cima até que a linha seja novamente pete.forward(100) e aperte [ENTER].

É claro que um quadrado são justamente quatro lados iguais, então faça com que pete se vire 90 graus para a direita: pete.right(90)

Agora a maneira mais simples de continuar é simplesmente continuar a seta para cima duas vezes e apertar [ENTER] até que pete esteja onde ele começou. Lembre-se, se você fizer uma besteira, ou as coisa ficarem confusas, não se preocupe. Apenas digite: reset() pete vai voltar para onde ele iniciou e limpar a tela no processo. Você também pode usar home() para levar pete de volta para onde ele começou sem mudar nada na tela, ou cls() para apagar tudo sem fazer com pete se mova.

Nomes

Enquanto programa você vai precisar achar nomes para muitas coisas diferentes que você criar. Esses nomes são às vezes chamados variáveis ou identificadores. Por exemplo, você pode dar um nome para o número 50:

comprimento = 50 A caixa acima representa um objeto do tipo inteiro ao qual foi dado o nome 'comprimento'. Essa idéia pode parecer ridícula, mas imagine um número que é usado várias vezes no seu código, e subitamente você percebe que precisa mudar o 50 por 75. Você pode fazer isso:

   1 forward(50)
   2 right(90)
   3 forward(50)
   4 right(90)
   5 forward(50)
   6 right(90)
   7 forward(50)
   8 right(90)

Você pode então usar a função de procurar/substituir no seu editor para mudar todos os 50s para 75s, mas existe uma grande chance de você deixar passar algum. Ainda pior, se o código for parte de uma seção maior, você pode acidentalmente mudar um 50 que não tem nada a ver com essa mudança.

This is much better:

   1 length = 50
   2 
   3 forward(length)
   4 right(90)
   5 forward(length)
   6 right(90)
   7 forward(length)
   8 right(90)
   9 forward(length)
  10 right(90)

So, if you needed to change the size of your squares from 50 to 75, instead of having to go through and change all of the 50s to 75s, you can just change length = 50 to length = 75 and instantly make all of the needed changes.

  • This picture shows the name length being taken from the 50 object and placed on the 75 object.

What Was That Again?

Once you have created variables, you will want to be able to see and to use the values they are holding on to. In the interactive session, you can just mention the name again, and the interpreter will tell you what it is.

Like this: >>> car = 'Ford Fairlane' >>> weight = 1700 >>> length = 23.4 >>> has_trunk = True >>> car 'Ford Fairlane' >>> weight 1700 >>> length 23.399999999999999 >>> has_trunk True

Notice here that there are a few different types of values that your variable names can be attached to.

'Ford Fairlane' is a string -- a series of characters enclosed in quotes. 1700 is an integer with nothing after the decimal point. 23.4 is called a floating point number -- it can have a fractional value, and notice that the value stored may not be exactly what you specified. True and False are available as boolean values.

Nicknames

When we used the calls pete.forward() and pete.right() to make a square, the words forward and right are names for different methods that pete the Penguin object understands.

Sometimes it is helpful to have more than one name for things. For instance, if you get tired of typing out pete.forward all the time, you could do:

forward = pete.forward

and then even:

fd = forward

(Note that there are no parenthesis at the end of any of the names.)

Now, instead of using pete.forward(20), you could just say fd(20)

Of course, forward(20) and pete.forward(20) still work too. An object can have as many names or aliases as you would like to give it.

  • Here the method object pete.forward has been given many different names: forward, fd and foo.

Good Names

Making short names -- like using fd for pete.forward -- can save you a lot of time and typing when working in the interactive interpreter.

However, when you start creating longer programs, you need to balance two things: You do not want to not type too much, but also you need to be able to remember what a particular name refers to.

Generally, unless a name will only be mentioned in one small area, you should not use names like:

a i q

since it is just too difficult to understand what they mean.

Instead, think about what the names refer to, and use names like:

number_of_apples appleindex quitAppleGame

Notice that there are a few different styles used to name things.

You should read through some other people's code and choose a style that you like, then try to use the same style consistently in all of your code.

A Little Math

Sometimes you do not know exactly what you want to store in a variable, but you could calculate it from other values that you do know. Just use mathematical symbols, and Python will do the calculations for you.

Like this: >>> price = 125 >>> tax_rate = 0.08 >>> tax = price * tax_rate >>> total = price + tax >>> total 135.0 >>> shares = 4 >>> total_per_share = total / shares >>> total_per_share 33.75

So, to multiply two numbers, use the *

Division uses the /

Compare

You know how to give objects names, but you will also need to know how to tell if one thing is the same as another, or if it is equal, greater or less than another.

To do this, we use comparison operators.

The most common comparison is equality:

this == 5

Note the difference between these two lines:

this = 4 this == 5

The first line is an assignment. It uses 1 equals sign (=) and it says "Set the variable this equal to 4." This is naming, like we talked about on the last page.

The second line is a comparison. It uses 2 equals signs (==) and it asks a question: "Is the variable this equal to 5?"

Try these lines in the Python interpreter:

this = 5 assignment that = 10 assignment this == that True or False? this = that assignment this == that True or False?

If this is equal to that then Python will return True (1) and if not, then Python returns False (0).

Some other common comparisons:

3 < 5 is less than True 9 > 8 is greater than True 1 != 0 is not equal to True 5 is not None is not True

The last example introduces two new ideas:

First, None is a special object you can use to mean "no value" or "unknown" or "not set" or "null". It took me a long time to really understand when to use None and the best way is just to read other people's code and see how they use it.

Second, the comparison is a bit different, as it does not compare the values of the two objects, but their actual identities.

In Python, every object has a unique id number which you can get by using the builtin id() function.

So, what the last line actually means is:

   1 id(5) != id(None)

We use is or is not because it is quicker and easier to read.

This comparison of identity also implies that two objects can be equal even if they are not identical.

For instance:

x1 = 3.2 3.2 is not an integer, it is a floating point number. x2 = 1.8 1.8 is also a float. x_total = x1 + x2 Adding floats always returns a float. x_total == 5 equals True x_total is 5 is False

Control

Now that you can make comparisons, you can control the flow of your programs.

Start up the interact.py program again, and try this:

   1 choice = 'blast'
   2 if choice == 'blast':
   3     pete.blast()

The drawing on the right is a flow chart and it represents the code on the left. You can follow the flow by starting at the top, following the lines, and acting on the instructions in the boxes.

In the code, notice how the line after the if statement is indented.

Indentation is how Python knows those statements are all run only if the condition is True. Like this:

   1 if choice == 'blast':
   2     pete.blast()
   3     pete.blast()
   4     pete.blast()
   5 
   6 pete.write(choice)

So the three blast()s will only happen if the choice is 'blast', but the write will happen no matter what.

Sometimes, you will want to make a choice between two things:

It can help to make this more clear by reading the word else as "otherwise".

   1 choice = 'blast'
   2 if choice == 'blast':
   3     pete.blast()
   4 else:
   5     pete.reset()

There are only two possibilities here, and your program can only flow down one of these two branches.

Other times, you will want to have multiple branches in your flow.

Here, the word elif can be read as "else if" or "otherwise if"

   1 choice = 'tree'
   2 if choice == 'blast':
   3     pete.blast()
   4 elif choice == 'tree':
   5     pete.tree()
   6 else:
   7     pete.reset()

You can have as many elif sections as you need. Once any one of the if or elif conditions is True, that section will run and all other elif or else sections will be skipped.

else is not required, and will only run if none of the preceeding if or elif conditions were True.

Loops

We made a square by performing the same two steps repeatedly -- once for each side of the square:

   1 forward(100)
   2 right(90)

It made it a bit easier that we could use the up-arrow to get back things we typed previously and so save ourselves some typing, but it was still easy to make a mistake and turn our square in to something not exactly what we planned.

There must be a simpler way, and there is.

Computers are great at repeating things over and over again without ever making any mistakes. We just need to know how to tell the computer what to do.

for

One way to tell a computer to repeat a set of steps is called a loop.

Here is how we tell pete to make a square using a loop:

   1 for side in 1, 2, 3, 4:
   2     forward(100)
   3     right(90)

Go ahead and type in the first line for side in 1, 2, 3, 4: and hit [ENTER]

Notice that the interpreter does not come back with the >>> prompt this time. Instead it shows ...

This means it is waiting for more input before it can get started. You are saying "I want you to do something 4 times", and the computer comes back with "Ok. What should I do 4 times?"

In Python, the way we tell the computer which steps are part of the loop is by indenting.

It is sort of like an outline.

Use 4 spaces for each level of indentation. Go ahead now and hit 4 spaces, then type in the second line of the loop forward(100) and hit [ENTER]

The computer comes back with ... again.

It does not know if you are finished telling it what to do 4 times, or if there are more steps inside of the loop.

Turns out there is another step in the loop. Hit 4 more spaces, then type in the last line right(90) and hit [ENTER]

Again, the computer comes back with ... but this time we are finished with the steps in the loop.

To finish the loop, hit [ENTER] again.

pete should, very quickly, draw a square for you.

This loop is so simple that we can "unroll" the loop and take a look at exactly what is happening...

   1 for side in 1, 2, 3, 4:
   2     forward(100)
   3     right(90)
   4         side = 1
   5 forward(100)
   6 right(90)
   7 
   8 side = 2
   9 forward(100)
  10 right(90)
  11 
  12 side = 3
  13 forward(100)
  14 right(90)
  15 
  16 side = 4
  17 forward(100)
  18 right(90)

These two pieces of code are equivalent. The result will be exactly the same.

Two things to notice here.

First, the variable side is never used inside of the loop. You might have named it differently, and it would not make much difference. Other reasonable names might have been count or even i or x. You do have to be a bit careful though, as naming the variable forward would cause problems.

Second, although horizontal space is used to indicate which statements are part of the loop, vertical space is not meaningful. Use blank lines in your code to make it easier to read.

while

The for loop is best when you have a list of objects and you want to do something with each one of them.

Other times, you will want to continue looping until a particular condition is met. Like this:

   1 angle = 0
   2 per = 6
   3 
   4 while angle < 360:
   5     forward(10)
   6     right(per)
   7     angle += per

Functions

Loops are useful for performing a set of steps repeatedly, but what if you want to repeat the entire loop over and over again -- maybe with different parameters.

For instance, maybe you want to draw a lot of squares all on different parts of the screen.

Many randomly placed squares

Using functions we can save a piece of code so that we can use it again later.

A function is sort of like a mini program inside of your program.

When we use the function, we say that we call it, almost like you might call the time service on your phone.

Functions can either return some value or object to your main program (like the current time), or they can perform some action (like setting the time) without returning a value. A function which does not return a value is sometimes called a procedure.

Let's make a function which, when called, will draw a square, starting wherever pete happens to be at the time:

   1 def square():
   2     for side in 1, 2, 3, 4:
   3         forward(100)
   4         right(90)

  • square is a function object.

Notice that the body of the function, just like the body of the loop before, is indented, and since there is a loop inside of our function, the body of the loop is indented again. The first indent should be 4 spaces, the second indent is 4 more for a total of 8 spaces.

To call our new function, use this:

square()

To see why we might want to make functions, try a combination of a loop which calls our function:

   1 for side in 1, 2, 3, 4:
   2     forward(125)
   3     square()
   4     left(90)

Loop in progress...

If you had done that by hand, or tried to figure out how to put all those loops together, it would have taken a long time, and it would have been very easy to make a mistake. With functions, you can think in terms of larger pieces. This loop says: "Set side equal to 1, go forward, make a square, turn left, set side equal to 2, go forward, etc..."

Remember that "Set side equal to 1" has nothing to do with the length of the side. It is just counting.

Parameters

square() is fine as it is. It makes a square on the screen just as you asked it to, but what if all your squares are not the same size?

Let's make a function which is a bit more general purpose:

   1 def generalSquare(length):
   2     for side in 1, 2, 3, 4:
   3         forward(length)
   4         right(90)

  • generalSquare takes one parameter -- the length

This time, our function takes a parameter (also called an argument) the length of a side of the square, and when moving forward, instead of using the value 100, it uses the value of the length.

Now, to make a square with a side of length 20, we will call:

generalSquare(20)

When this function gets called, the variable length is given the value we put in the parentheses. Then any time python sees length in the body of the function, it substitutes that value.

This generalized square method is so useful, that it is built-in to all Penguin objects. In interact.py you can use it like this:

pete.square(20)

In fact, there is also another type of square built-in which is centered on the penguin's present location:

pete.cSquare(50)

will draw a 50-pixel square with pete right in the middle.

How might we use the squares? Let's try this:

   1 width = 5
   2 
   3 while width < 200:
   4     set_color('random')
   5     pete.square(width)
   6     width += 2
   7     left(65)

That's pretty neat. Let's make that in to a function too...

   1 def flow(angle, grow=2):
   2     width = 5
   3 
   4     while width < 200:
   5         set_color('random')
   6         pete.square(width)
   7         width += grow
   8         left(angle)
  • square, turn, square, turn, square, etc...

As you can see, functions can also take more than one parameter. flow takes two parameters: the angle to turn between squares, and the amount to grow between squares. Also, grow uses a default value of 2.

So, we can call flow with 2 parameters:

flow(4, 1)

or, if the default value is ok, then we can call it with just the one parameter:

flow(14)

and it will be the same as if we had called flow(14, 2)

More General

All of these squares might make you wonder if you can draw some other shape. Maybe you want to make an even more general function. Try this:

   1 def lineTurn(length, angle):
   2     for side in 1, 2, 3, 4:
   3         forward(length)
   4         right(angle)
  • Two parameters, no default values.

and call it like this:

   1 lineTurn(150, 90)
   2 lineTurn(200, 120)
   3 lineTurn(50, 72)

Notice that I did not give it a name that mentions square at all, since what lineTurn() makes will not always be a square.

Give those three function calls a try and see what you get.

The first call is fine. It is just as if we called generalSquare(150). The second call succeeds in making a triangle, but it is a bit wasteful as it draws over one of the sides twice.

What happens on the last call though? It gets most of the way through a pentagon and stops.

It is close to being a complete pentagon... You could finish it up by just typing forward(50) but it would be nice if the function could do that on its own.

In the next section, we will do just that.

Lists

In the loops in previous examples, we used code like this:

   1 for x in 1, 2, 3, 4:

The series of numbers 1, 2, 3, 4 is a called a sequence, and loops can iterate over the members of any sequence.

What this code means is: "set x = 1 and do the following things, then set x = 2, and do these things again", etc, until the end of the sequence.

A sequence like this will often be written either in square brackets [1, 2, 3, 4] (called a list) or in parentheses (1, 2, 3, 4) (a tuple).

The difference between these is a bit subtle.

A list can be changed after it is constructed (we say that it is mutable), whereas a tuple cannot be changed (immutable).

The differences will become more clear later, but I will use the word "list" for now to keep things simpler.

Create

It is very common to give the list a name instead of typing the list itself in to a loop statement. When creating a list like this, brackets are required.

You can make an empty list:

empty_list = []

or if you know exactly what needs to be in the list, just go ahead and fill it up:

   1 sides = ['side one', 'side two', 'side three', 'side four']

Sometimes, especially if the elements in the list are long, it looks better to break it up in to multiple lines. As long as you are inside the brackets, that is fine:

   1 verbose_sides = [
   2   'The side known as "side one"',
   3   'This one is side two',
   4   'Another side, called "side three"',
   5   'The final side, or side four'
   6 ]

Mutate

Lists are mutable, but what exactly does that mean?

Lists are objects with special methods built in to make it easy to add, remove, sort, and find things that are in the list.

For instance, if you did not know beforehand what words you wanted to print around the square, you could add them to the list as you found out:

   1 from pygsear.Widget import Dialog_LineInput
   2 sides = []
   3 for side in 'first', 'second', 'third', 'fourth':
   4     message = 'Enter the name of the %s side' % side
   5     namegetter = Dialog_LineInput(message=message)
   6     name = namegetter.modal()
   7     sides.append(name)

Iterate

In this case, the members in the list sides are not numbers, but text (called strings), so we could not use them in math formulas, but we could use them like this:

   1 for word in sides:
   2     write(word)
   3     forward(180)
   4     right(90)

Or, more generally:

   1 def messageSquare(messages=['one', 'two', 'three', 'four']):
   2     for word in messages:
   3         write(word)
   4         forward(180)
   5         right(90)

The function messageSquare() takes one parameter, and if called without a value it will use the default argument ['one', 'two', 'three', 'four'].

In other words, a call to:

messageSquare()

is the same as if you called it:

messageSquare(['one', 'two', 'three', 'four'])

You can also call it with a totally different list:

messageSquare(['penguins', 'like', 'to eat', 'herring'])

or with a list created before:

messageSquare(sides)

Range

The function messageSquare() has a problem similar to the problem with the function at the end of the last page. If you pass in a sequence which is longer or shorter than 4 elements, it is probably not going to do what you want.

Try it now. If the sequence is less than 4 elements, it will not make a complete square. If the sequence is more than 4 elements, it will write over the words on previous sides.

   1 reset()
   2 messageSquare(['one', 'side', 'short'])
   3 reset()
   4 messageSquare(['one', 'side', 'too', 'many', 'here'])

To get around this problem, we need to figure out what angle to turn from the number of sides we want the shape to have.

Using the built-in function range() we can make a very general function to draw polygons:

   1 def poly(sides, length):
   2     angle = 360.0 / sides
   3     for side in range(sides):
   4         forward(length)
   5         right(angle)

The function range() takes a number, and returns a list with that many elements.

That means: if sides=5 then range(sides) is the same as range(5) and it returns [0, 1, 2, 3, 4]

So the function call poly(5, 10) will draw a five-sided figure with sides of length 10.

Now we can make almost any sort of regular polygon by giving poly() the number of sides and the length of each side:

   1 poly(5, 20)
   2 poly(6, 30)
   3 poly(100, 3)

The last one will probably be indistinguishable from a circle. In fact, if pete did not have a built in circle() method, that would be a good way to simulate a circle.

Help

We will come back to functions and sequences in the next chapter, but first I want to bring up one more thing about the interactive interpreter:

Notice that by typing:

help

python will tell you how to get help.

Basically, it tells you to type help() with which you can enter the python help browser and get a lot of generally helpful information. Alternatively, you can put something inside the parentheses which you want to get help on. Try this: >>> help(range) Help on built-in function range:

range(...) range([start,] stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements.

You type in the first line, after the >>>

help(range)

and Python will tell you about the range function.

That is interesting. Let's try out the example they give:

range(4) returns: [0, 1, 2, 3]

Just like they said it would be. How about if we give range 2 numbers:

range(4, 10) returns: [4, 5, 6, 7, 8, 9]

Notice how the list returned does include the first number you give, but it does not include the last number you give.

Now try range with 3 arguments:

range(0, 100, 10) returns: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

Very nice. I wonder if we can use this to make pete perform some even more amazing tricks?

Also notice that you can get help on pete himself!

Unfortunately, help(pete) only tells us that pete is an instance of the Penguin class. We can get help on pete and all of his kind with:

help(Penguin)

Exercises:

1. Play the practice.py game to get used to moving the penguin around. Read the comments at the start of the file to see how to play. (Hint)

2. You made pete move in a square. Now make him go in a rectangle that is twice as wide as it is high. (Hint)

3. Now see if you can make pete go in a triangle. (Hint)

4. Use a variable distance to make pete walk in a square or triangular spiral. (Hint)

5. Make two different loops -- one to draw a pentagon and one to draw a five-pointed star. (Hint)

6. Turn exercise 4 in to both a for loop and a while loop. (Hint)

7. Create functions for triangle and pentagon like we made for square. Make the functions take a parameter for the length of a side. (Hint)

8. Create a function which takes a sequence of strings and writes them around the edges of a polygon with one side for each string. (Hint)

9. Create a function which takes a sequence of strings and writes each one on a separate line, one above the next. (Hint)

Chapter 2 Modules

Import

At the top of most Python programs, you will see import statements like this:

   1 import random
   2 import os.path
   3 from math import sqrt
   4 from penguin import *

The import statement lets you quickly and easily load in python modules.

Modules are useful code that is already written -- either code which someone else wrote or your own code. Before starting any programming project, it is a good idea to look around and see if there is already a module which will do what you need.

Why would you want to import a module?

If you need to make your game behave randomly, you might want to choose from different attack strategies:

   1 import random
   2 strategies = ['aggressive', 'cautious', 'defensive']
   3 strategy = random.choice(strategies)

Or, if your game needs to know the size of a file:

   1 import os.path
   2 os.path.getsize('.')

Or, if you need to know the distance between two objects:

   1 from math import sqrt
   2 x0, y0 = (150, 75)
   3 x1, y1 = (275, 300)
   4 distance = sqrt((x0 - x1)**2 + (y0 - y1)**2)

This distance formula (the Pythagorean Theorem) is so useful that it is included in the math module:

   1 import math
   2