## page was renamed from Python游戏设计基础/实验3 = 实验目的 = * 分支、循环结构的实现 * 函数的用法 = 实验内容 = * 编写一个分支结构,输入一个百分制分数,输出分数的等级(优、良、中、及格、不及格) * 编写一个循环结构,对输入的一组整数进行排序。 * 在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 L = [1, 2, 4, 8, 16, 32, 64] X = 5 found = i = 0 while not found and i < len(L): if 2 ** X == L[i]: found = True else: i = i+1 if found: print 'at index', i else: print X, 'not found' }}}输出{{{ at index 5 }}}这个例子没有使用好的的Python编程技术。我们用如下的步骤来改进它: a. 首先,用带else的while循环来消除found标记和最后的if语句。 a. 然后,用带else的for循环来消除列表下标的使用。 a. 然后,使用in运算符来完全消除循环的使用。 a. 最后,使用for循环来生成2的幂构成的列表,而不是把数字以字面常量的形式直接写在代码中。 a. 更多思考:(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这样的语言中,函数也是第一类元素。函数可以作为第一类元素的语言,支持一种完全不同的程序设计风格:函数式程序设计。试着在网上搜索更多关于函数式程序设计语言和函数式程序设计的资料,试着解释这种风格和传统的程序设计风格有什么根本的区别。