<imgsrc="img/pestle.png"width="75"align="right">Years ago I learned to make Thai red curry paste from scratch, including roasting then grinding seeds and pounding stuff in a giant mortar and pestle. It takes forever and so I generally buy curry paste ready-made from the store.
<imgsrc="img/pestle.png"width="75"align="right">
<imgsrc="img/redcurry.jpeg"width="70"align="right">Similarly, most cookbooks provide a number of fundamental recipes, such as making sauces, that are used by other recipes. A cookbook is organized into a series of executable recipes, some of which "invoke" other recipes. To make dinner, I open a cookbook, acquire some raw ingredients, then execute one or more recipes, usually in a specific sequence.
Writing a program proceeds in the same way. Opening a cookbook is the same as importing libraries. Acquiring raw ingredients could mean loading data into the memory. The main program invokes functions (recipes) to accomplish a particular task. As part of writing a program, we will typically break out logical sections of code into functions specific to our problem, whereas the functions in libraries tend to be broadly-applicable.
The way we organize our code is important. Programs quickly become an incomprehensible rats nest if we are not strict about style and organization. Here is the general structure of the Python programs we will write:
A sequence of operations grouped into a single, named entity is called a **function**. Functions are like mini programs or subprograms that we can plan out just like full programs.
Python **programs** consist of zero or more functions and the so-called "main" program, consisting of a sequence of operations that gets the ball rolling.
+ 导入任何库
+ 定义任何常量,简单的数据值
+ 定义任何函数
+ 主程序体
Instead of loading data from the disk, functions operate on data given to them from the invoking program. This incoming data is analogous to a recipe's list of ingredients and is specified in the form of one or more named *parameters* (also called *arguments*). Instead of printing a result or displaying a graph, as a program would, functions *return* values. Functions are meant as helper routines that are generically useful.
2. the kind of value(s) it operates on (parameter types)
3. the kind of value it returns (return type)
4. what the function does and the value it returns
If we can't specifying exactly what goes in and out of the function, there's no hope of determining the processing steps, let alone Python code, to implement that function.
Once we fully understand our goal, we plan out the sequence of operations needed by the function to compute the desired result. As when designing a whole program, we start with the return value and work our way backwards, identifying operations in reverse order. Note: The operations should be purely a function of the data passed to them as parameters---functions should be completely ignorant of any other data. (More on this when we actually translate function pseudocode to Python.)
Python functions are like black boxes that, in general, accept input data and yield (return) values. Each invocation of a function triggers the execution of the code associated with that function and returns a result value or values. For example, here is a function called `pi` that takes no parameters but returns value 3.14159 each time it is called:
The code template for a function with no arguments is:
没有参数的函数的代码模板是:
```py
```py
deffuncname():
deffuncname():
...
@@ -55,10 +59,11 @@ def funcname():
...
@@ -55,10 +59,11 @@ def funcname():
returnexpression
returnexpression
```
```
with holes for the function name, statements associated with a function, and an expression describing the return value. Functions that have no return value skip the `return` statement.
<imgsrc="img/redbang.png"width="30"align="left"> The way that we associate statements with a function in Python is by indentation. So `return 3.14159` is part of the function because it is indented after the function header. The first statement that begins in the same column as the `def` is first statement outside of the function.
@@ -69,10 +74,11 @@ print("this is not part of function")
...
@@ -69,10 +74,11 @@ print("this is not part of function")
```
```
<imgsrc="img/redbang.png"width="30"align="left">*The Python interpreter does not execute the code inside the function unless we directly invoke that function.* Python sees the function definition as just that: a "recipe" definition that we can call if we want.
<imgsrc="img/redbang.png"width="30"align="left">
The *definition* of a function is different than invoking or *calling* a function. Calling a function requires the function name and any argument values. In this case, we don't have any arguments so we call the function as just `pi()`:
We don't need a print statement because we are executing inside a notebook, not a Python program. If this were in a regular Python program, we would need a print statement: `print(pi())`, but of course that also works here.
Every invocation of that function evaluates to the value 3.14159. The function `return`s a value but `print`s nothing. For example, Jupyter notebooks or the Python interactive shell does not print anything if we assign the result to variable:
```python
```python
x=pi()
x=pi()
```
```
We distinguish between functions and variables syntactically by always putting the parentheses next to the function name. I.e., `pi` is a variable reference but `pi()` is a function call.
Some functions don't have return values, such as a function that displays an image in a window. It has a *side effect* of altering the display but does not really have a return value. The `return` statement is omitted if the function does not return a value. Here's a contrived side-effecting example that does not need to return a value:
Naturally, we can also return strings, not just numbers. For example here's a function called `hello` that does nothing but return string `'hello'`:
```python
```python
defhello():
defhello():
...
@@ -157,26 +145,29 @@ print(id, phone)
...
@@ -157,26 +145,29 @@ print(id, phone)
# parrt 5707
# parrt 5707
```
```
现在转到更有趣的案例,这里是带有一个参数的函数的模板:
Turning to the more interesting cases now, here is the template for a function with one argument:
```py
deffuncname(argname):
`def`*funcname*`(`*argname*`)`:<br>
statement1
*statement 1*<br>
statement2
*statement 2*<br>
...
*...*<br>
returnexpression
`return`*expression*<br>
```
If there are two arguments, the function header looks like:
如果有两个参数,则函数头如下所示:
`def`*funcname*`(`*argname1*, *argname2*`)`:<br>
```py
deffuncname(argname1,argname2):
```
Our job as programmers is to pick a descriptive function name, argument name(s), and statements within the function as per our function workplan.
我们作为程序员的工作是,根据我们的函数工作计划,选择函数中的描述性函数名称,参数名称和语句。
**Invoking a function** with arguments looks like *funcname*`(`*expression*`)` or *funcname*`(`*expression1*`,`*expression2*`)` etc... The order of the arguments matters. Python matches the first expression with the first argument name given in the function definition.
Let's take a look at some of the code snippets from [Programming Patterns in Python](python-patterns.ipynb) and see if we can abstract some useful functions.
In [Model of Computation](computation.ipynb), we saw code to translate mathematical Sigma notation to python and so this code to sum the values in a list should be pretty familiar to you:
In [Model of Computation](computation.ipynb), we saw code to translate mathematical Sigma notation to python and so this code to sum the values in a list should be pretty familiar to you: