版本1和10间的区别 (跳过第9版)
于2006-09-01 12:09:11修订的的版本1
大小: 3820
编辑: czk
备注:
于2008-02-23 15:34:13修订的的版本10
大小: 5778
编辑: localhost
备注: converted to 1.6 markup
删除的内容标记成这样。 加入的内容标记成这样。
行号 1: 行号 1:
## page was renamed from Python游戏设计基础/实验3
行号 7: 行号 8:
 * 编写一个循环结构,对输入的一组数排序算法。
 * 编写一组函数,实现。。。

 * At the Python interactive prompt, write a function that prints its single argument to the screen and call it interactively, passing a variety of object types: string, integer, list, dictionary. Then try calling it without passing any argument. What happens? What happens when you pass two arguments?
 * Write a function called adder in a Python module file. The function adder should accept two arguments and return the sum (or concatenation) of its two arguments. Then add code at the bottom of the file to call the function with a variety of object types (two strings, two lists, two floating points), and run this file as a script from the system command line. Do you have to print the call statement results to see results on your screen?
 * Generalize the adder function you wrote in the last exercise to compute the sum of an arbitrary number of arguments, and change the calls to pass more or less than two. What type is the return value sum? (Hints: a slice such as S[:0] returns an empty sequence of the same type as S, and the type built-in function can test types.) What happens if you pass in arguments of different types? What about passing in dictionaries?
 * Change the adder function from previous exercise to accept and add three arguments:def adder(good, bad, ugly). Now,
provide default values for each argument and experiment with calling the function interactively. Try passing one, two, three, and four arguments. Then, try passing keyword arguments. Does the call adder(ugly=1, good=2) work? Why? Finally, generalize the new adder to accept and add an arbitrary number of keyword arguments, much like Exercise 3, but you'll need to iterate over a dictionary, not a tuple. (Hint: the dict.keys( ) method returns a list you can step through with afor or while.)


= 思考题 =

Consider the following code, which uses a while loop and found flag to search a list of powers of 2,
for the value of 2 raised to the 5th power (32). It's stored in a module file called power.py.
{{{#!python
 * 编写一个循环结构,对输入的一组整数进行排序。
 * 在Python的交互方式下,写一个只有一个参数的函数,函数的功能只是简单的输出它的参数。然后调用这个函数,给它传各种不同类型的对象:字符串、整数、列表、字典等。然后再试试不给任何参数去调用它会发生什么。如果是给了两个参数去调用,那又会怎样呢?
 * 在Python文件中写一个adder函数,这个函数接受两个参数,并返回这两个参数的和。在文件的末尾用各种不同的参数(两个字符串、两个列表、两个浮点数等)调用这个函数,然后运行这个Python程序。在你要查看函数调用的结果时,你是否必须在每个函数调用前加上print?
 * 让这个adder函数更加通用,使它可以计算任意个参数的和,并在调用时试着给不同个数的参数去调用它。这个函数的返回类型是什么?如果在调用时传进去的多个参数不是同一种类型的,那会发生什么?如果传进去的是一个字典,那又会怎样?
 * 修改adder函数,使它可以接受三个参数def adder(good, bad, ugly)。为每个参数提供一个缺省值,然后试着以一个、两个、三个、四个参数去调用它,看会发生什么情况。然后试着使用关键字参数去掉用。adder(ugly=1, good=2)这样的调用可不可以用?为什么?最后,让这个adder函数可以接受任意个关键字参数。
 * 定义如下的六个函数:
{{{
def f1(a, b): print a, b # Normal args
def f2(a, *b): print a, b # Positional varargs
def f3(a, **b): print a, b # Keyword varargs
def f4(a, *b, **c): print a, b, c # Mixed modes
def f5(a, b=2, c=3): print a, b, c # Defaults
def f6(a, b=2, *c): print a, b, c # Defaults and positional varargs
}}}
现在测试如下的调用,会产生什么结果?为什么?你认为把不同的匹配方式混合在一起使用是一个好主意吗?你能想到这样的写法在哪里会有用吗?
{{{
>>> f1(1, 2)
>>> f1(b=2, a=1)
>>> f2(1, 2, 3)
>>> f3(1, x=2, y=3)
>>> f4(1, 2, 3, x=2, y=3)
>>> f5(1)
>>> f5(1, 4)
>>> f6(1)
>>> f6(1, 3, 4)
}}}
 * 编写一组函数:一个square(x)函数计算并返回x的平方;一个average(x,y)函数,计算并返回x和y的平均值;一个close_enough(x,y)函数,如果x和y很接近(它们之差的绝对值小于0.00...01)返回True否则返回False;一个fix_point(f,guess)函数,让next=f(guess),如果close_enough(next, guess)返回真,那么函数返回next,否则函数返回fix_point(f,next);一个sqrt(x)函数,sqrt(x)=fix_point(lambda y:average(y,x/y),1.0)。试解释sqrt的功能和原理。
 * 求这个列表[2, 4, 9, 16, 25]里每个数的平方根,并把它们保存在一个新的列表里面。尝试用三种方法来实现:1.用for循环来实现;2.用map函数来实现;3.用列表产生式来实现。使用math模块的sqrt函数来计算平方根(首先import math,然后math.sqrt(x)计算x的平方根)。在这三种方法中,你最喜欢哪一种方法?
 * 下面的代码用了一个while循环和一个found标记,来在一个2的幂构成的列表中查找2的5次幂。{{{#!python
行号 23: 行号 38:
X=5 X = 5
行号 27: 行号 42:
        found = 1         found = True
行号 34: 行号 49:
}}}
{{{
}}}输出{{{
行号 37: 行号 51:
}}} }}}这个例子没有使用好的的Python编程技术。我们用如下的步骤来改进它:
   a. 首先,用带else的while循环来消除found标记和最后的if语句。
   a. 然后,用带else的for循环来消除列表下标的使用。
   a. 然后,使用in运算符来完全消除循环的使用。
   a. 最后,使用for循环来生成2的幂构成的列表,而不是把数字以字面常量的形式直接写在代码中。
   a. 更多思考:(1) 你觉得把2**X表达式放在循环的外面能不能改善程序的速度?你怎么实现?(2)Python有一个map(function, list)函数,试着用它来产生2的幂构成的列表。
行号 39: 行号 58:
As is, the example doesn't follow normal Python coding techniques. Follow the steps below to improve it. For all the
transformations, you may type your code interactively or store it in a script file run from the system command line (using a file makes this exercise much easier).
           a. First, rewrite this code with a while loop else, to eliminate the found flag and final if statement.
           a. Next, rewrite the example to use a for loop with an else, to eliminate the explicit list indexing logic. Hint: to get the index of an item, use the list index method (L.index(X) returns the offset of the first X in list L).
           a. Next, remove the loop completely by rewriting the examples with a simple in operator membership expression.
           a. Finally, use a for loop and the list append method to generate the powers-of-2 list (L) instead of hard-coding a list literal.
           a. Deeper thoughts: (1) Do you think it would improve performance to move the 2**X expression outside the loops? How would you code that? (2) Python also includes a map(function, list) tool that can generate the powers-of-2 list too: map(lambda x: 2**x, range(7)). Try typing this code interactively.
= 思考题 =
 * 在Python中定义两个名字相同的函数,会怎么样?
 * 函数中的参数的默认值如果是变量,那么这个参数的默认值会随着那个变量的变化而变化吗?试着写一个程序去验证
 * 在Python中缺少像C语言中的a?b:c这样的条件运算符,不过可以用a and b or c来模仿。但这个Python中的这个写法和?:并不完全相同,请想想有什么区别?并试着去验证它。(正是因为有这个重要的区别,Python2.5中增加了b if a else c的语法来完全模拟a?b:c条件运算符。)
 * 在程序设计语言中,有些语法元素可以用变量命名,可以作为参数传给函数,可以作为函数的返回值,可以存储在数据结构中。拥有这些特点的语法元素称为第一类(first-class)元素。在C语言中,数据变量是第一类元素,但是函数并不是第一类元素。而像Python这样的语言中,函数也是第一类元素。函数可以作为第一类元素的语言,支持一种完全不同的程序设计风格:函数式程序设计。试着在网上搜索更多关于函数式程序设计语言和函数式程序设计的资料,试着解释这种风格和传统的程序设计风格有什么根本的区别。

实验目的

  • 分支、循环结构的实现
  • 函数的用法

实验内容

  • 编写一个分支结构,输入一个百分制分数,输出分数的等级(优、良、中、及格、不及格)
  • 编写一个循环结构,对输入的一组整数进行排序。
  • 在Python的交互方式下,写一个只有一个参数的函数,函数的功能只是简单的输出它的参数。然后调用这个函数,给它传各种不同类型的对象:字符串、整数、列表、字典等。然后再试试不给任何参数去调用它会发生什么。如果是给了两个参数去调用,那又会怎样呢?
  • 在Python文件中写一个adder函数,这个函数接受两个参数,并返回这两个参数的和。在文件的末尾用各种不同的参数(两个字符串、两个列表、两个浮点数等)调用这个函数,然后运行这个Python程序。在你要查看函数调用的结果时,你是否必须在每个函数调用前加上print?
  • 让这个adder函数更加通用,使它可以计算任意个参数的和,并在调用时试着给不同个数的参数去调用它。这个函数的返回类型是什么?如果在调用时传进去的多个参数不是同一种类型的,那会发生什么?如果传进去的是一个字典,那又会怎样?
  • 修改adder函数,使它可以接受三个参数def adder(good, bad, ugly)。为每个参数提供一个缺省值,然后试着以一个、两个、三个、四个参数去调用它,看会发生什么情况。然后试着使用关键字参数去掉用。adder(ugly=1, good=2)这样的调用可不可以用?为什么?最后,让这个adder函数可以接受任意个关键字参数。
  • 定义如下的六个函数:

def f1(a, b): print a, b          # Normal args
def f2(a, *b): print a, b         # Positional varargs
def f3(a, **b): print a, b        # Keyword varargs
def f4(a, *b, **c): print a, b, c   # Mixed modes
def f5(a, b=2, c=3): print a, b, c # Defaults
def f6(a, b=2, *c): print a, b, c    # Defaults and positional varargs

现在测试如下的调用,会产生什么结果?为什么?你认为把不同的匹配方式混合在一起使用是一个好主意吗?你能想到这样的写法在哪里会有用吗?

>>> f1(1, 2)
>>> f1(b=2, a=1)
>>> f2(1, 2, 3)
>>> f3(1, x=2, y=3)
>>> f4(1, 2, 3, x=2, y=3)
>>> f5(1)
>>> f5(1, 4)
>>> f6(1)
>>> f6(1, 3, 4)
  • 编写一组函数:一个square(x)函数计算并返回x的平方;一个average(x,y)函数,计算并返回x和y的平均值;一个close_enough(x,y)函数,如果x和y很接近(它们之差的绝对值小于0.00...01)返回True否则返回False;一个fix_point(f,guess)函数,让next=f(guess),如果close_enough(next, guess)返回真,那么函数返回next,否则函数返回fix_point(f,next);一个sqrt(x)函数,sqrt(x)=fix_point(lambda y:average(y,x/y),1.0)。试解释sqrt的功能和原理。
  • 求这个列表[2, 4, 9, 16, 25]里每个数的平方根,并把它们保存在一个新的列表里面。尝试用三种方法来实现:1.用for循环来实现;2.用map函数来实现;3.用列表产生式来实现。使用math模块的sqrt函数来计算平方根(首先import math,然后math.sqrt(x)计算x的平方根)。在这三种方法中,你最喜欢哪一种方法?
  • 下面的代码用了一个while循环和一个found标记,来在一个2的幂构成的列表中查找2的5次幂。

       1 L = [1, 2, 4, 8, 16, 32, 64]
       2 X = 5
       3 found = i = 0
       4 while not found and i < len(L):
       5     if 2 ** X == L[i]:
       6         found = True
       7     else:
       8         i = i+1
       9 if found:
      10     print 'at index', i
      11 else:
      12     print X, 'not found'
    

    输出

    at index 5
    这个例子没有使用好的的Python编程技术。我们用如下的步骤来改进它:
    1. 首先,用带else的while循环来消除found标记和最后的if语句。
    2. 然后,用带else的for循环来消除列表下标的使用。
    3. 然后,使用in运算符来完全消除循环的使用。
    4. 最后,使用for循环来生成2的幂构成的列表,而不是把数字以字面常量的形式直接写在代码中。
    5. 更多思考:(1) 你觉得把2**X表达式放在循环的外面能不能改善程序的速度?你怎么实现?(2)Python有一个map(function, list)函数,试着用它来产生2的幂构成的列表。

思考题

  • 在Python中定义两个名字相同的函数,会怎么样?
  • 函数中的参数的默认值如果是变量,那么这个参数的默认值会随着那个变量的变化而变化吗?试着写一个程序去验证
  • 在Python中缺少像C语言中的a?b:c这样的条件运算符,不过可以用a and b or c来模仿。但这个Python中的这个写法和?:并不完全相同,请想想有什么区别?并试着去验证它。(正是因为有这个重要的区别,Python2.5中增加了b if a else c的语法来完全模拟a?b:c条件运算符。)
  • 在程序设计语言中,有些语法元素可以用变量命名,可以作为参数传给函数,可以作为函数的返回值,可以存储在数据结构中。拥有这些特点的语法元素称为第一类(first-class)元素。在C语言中,数据变量是第一类元素,但是函数并不是第一类元素。而像Python这样的语言中,函数也是第一类元素。函数可以作为第一类元素的语言,支持一种完全不同的程序设计风格:函数式程序设计。试着在网上搜索更多关于函数式程序设计语言和函数式程序设计的资料,试着解释这种风格和传统的程序设计风格有什么根本的区别。

Python游戏开发基础/实验3 (2008-02-23 15:34:13由localhost编辑)

ch3n2k.com | Copyright (c) 2004-2020 czk.