（首页）开始编程之旅 翻译自Lee Harr的Start Programming

# 1. StartProgramming-1-6 函数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.

attachfile:many_squares.png

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. square 是一个函数对象。

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.

## 1.1. 参数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?

square() 表现得很好。它按照你的要求在屏幕上画正方形，但是怎样才能让你的正方形边长不相等呢？

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

generalSquare 有一个参数 -- 是 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)

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

StartProgramming-1-6 (last edited 2009-12-25 07:13:54 by localhost)