一,增量式开发
写一些复杂函数的时候,你会发现要花很多时间调试。
要应对越来越复杂的程序,你不妨来试试增量式开发的办法。增量式开发的目的是避免长时间的调试过程,一点点对已有的小规模代码进行增补和测试。
看个例子:写一个计算两点距离的函数,输入的参数是什么,输出的返回值是什么?
这个案例里面,输入的应该是两个点的坐标,平面上就是四个数字了。返回的值是两点间的距离,就是一个浮点数了。
$ cat a.py
#!/bin/python
def distance(x1, y1, x2, y2):
return 0.0
上面的这些代码肯定算不出距离了,不管输入什么都会返回0了。但这个函数语法上是正确的,而且可以运行,这样在程序过于复杂的情况之前就能及时测试了。
要测试一下这个新函数,就用简单的参数来调用一下:
$ cat a.py
#!/bin/python
def distance(x1, y1, x2, y2):
return 0.0
print distance(1, 2, 4, 6)
$ python a.py
0.0
返回值为0.0,与函数定义的return返回值一样。
选择这些参数,水平的距离就是3,竖直距离就是4,这样的话,平面距离就应该是5了,是一个3-4-5三角形的斜边长了。看图:
如此我们已经知道正确结果应该是什么了,这样对测试来说很有帮助。
现在我们已经确认过了,这个函数在语法上是正确的,接下来我们就可以在函数体内添加代码了。下一步先添加一下求x2-x1和y2-y1的值的内容。接下来的版本里面,就把它们存在一些临时变量里面,然后输出:
$ cat a.py
#!/bin/python
def distance(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
print('dx is', dx)
print('dy is', dy)
return 0.0
print distance(1, 2, 4, 6)
$ python a.py
('dx is', 3)
('dy is', 4)
0.0
成功显示了,现在我们就知道函数已经得到了正确的实际参数,并且正确进行了初步的运算。如果没有显示,只要检查一下这么几行代码就可以了。接下来,就要计算dx和dy的平方和了。
$ cat a.py
#!/bin/python
def distance(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
dsquared = dx**2 + dy**2
print('dsquared is', dsquared)
return 0.0
print distance(1, 2, 4, 6)
$ python a.py
('dsquared is', 25)
0.0
在这一步,咱们依然会运行一下程序,来检查输出,结果为25。输出正确了,最后一步就是用math.sqrt这个函数来计算并返回结果:
注意,要导入math模块,才能使用math.sqrt函数。
$ cat a.py
#!/bin/python
import math
def distance(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
dsquared = dx**2 + dy**2
result = math.sqrt(dsquared)
return result
print distance(1, 2, 4, 6)
$ python a.py
5.0
返回值为5.0,跟预期的结果一样。
总结:
函数的最终版本在运行的时候是不需要显示任何内容的,这个函数只需要返回一个值。我们写的这些print打印语句都是用来调试的,但一旦程序能正常工作了,就应该把print语句去掉。这些print代码也叫【脚手架代码】因为是用来构建程序的,但不会被存放在最终版本的程序中。调试的过程中,我们可以用一些变量来存储中间值,这样你可以显示一下这些值,来检查正确性。
当我们动手的时候,每次建议只添加一两行代码。等经验更多了,你发现自己很顺畅地驾驭大块代码了。不论如何,增量式开发总还是能帮我们节省很多调试消耗的时间。
二,组合
看个例子:在一个函数里面调用另外一个函数。
写一个函数,这个函数需要两个点,一个是圆心,一个是圆周上面的点,函数要用来计算这个圆的面积。
假设圆心的坐标存成一对变量:xc和yc,圆周上一点存成一对变量:xp和yp。
第一步就是算出来这个圆的半径,也就是这两个点之间的距离。我们就用之前写过的那个distance的函数来完成这件事:
raduis = distance(xc, yc, xp, yp)
下一步就是根据计算出来的半径来算圆的面积,使用area()
result = area(radius)
把上述的步骤组合在一个函数里面:
def circle_area(xc, yc, xp, yp):
radius = distance(xc, yc, xp, yp)
result = area(radius)
return result
临时变量radius和result是用于开发和调试用的,只要程序能正常工作了,就可以把它们都去掉,精简为:
def circle_area(xc, yc, xp, yp):
return area(distance(xc, yc, xp, yp))
结束。