|
| 1 | +>信心软弱的,你们要接纳,但不要辩论所疑惑的事。有人信百物都可吃,但那软弱的,只吃蔬菜。吃的人不可轻看不吃的人,不吃的人不可论断吃的人;因为神已经收纳他了。(ROMANS 14:1-3) |
| 2 | +
|
| 3 | +#函数练习 |
| 4 | + |
| 5 | +已经学习了函数的基本知识,现在练习练习。完成下面练习的原则: |
| 6 | + |
| 7 | +1. 请读者先根据自己的设想写下代码,然后运行调试,检查得到的结果是否正确 |
| 8 | +2. 我也给出参考代码,但是,参考代码并不是最终结果 |
| 9 | +3. 读者可以在上述基础上对代码进行完善 |
| 10 | +4. 如果读者愿意,可以将代码提交到github上,或者到我的QQ群(群号:26913719)中跟大家分享讨论 |
| 11 | + |
| 12 | +##解一元二次方程 |
| 13 | + |
| 14 | +解一元二次方程,是初中数学中的基本知识,一般来讲解法有:公式法、因式分解法等。读者可以根据自己的理解,写一段求解一元二次方程的程序。 |
| 15 | + |
| 16 | +最简单的思路就是用公式法求解,这是普适法则(普世法则?普适是否等同于普世?)。 |
| 17 | + |
| 18 | +>古巴比伦留下的陶片显示,在大约公元前2000年(2000 BC)古巴比伦的数学家就能解一元二次方程了。在大約公元前480年,中國人已经使用配方法求得了二次方程的正根,但是并没有提出通用的求解方法。公元前300年左右,欧几里得提出了一种更抽象的几何方法求解二次方程。 |
| 19 | +
|
| 20 | +>7世紀印度的婆羅摩笈多(Brahmagupta)是第一位懂得用使用代數方程,它同時容許有正負數的根。 |
| 21 | +
|
| 22 | +>11世紀阿拉伯的花拉子密 独立地发展了一套公式以求方程的正数解。亚伯拉罕·巴希亚(亦以拉丁文名字萨瓦索达著称)在他的著作Liber embadorum中,首次将完整的一元二次方程解法传入欧洲。(源自《维基百科》) |
| 23 | +
|
| 24 | +参考代码: |
| 25 | + |
| 26 | + #!/usr/bin/env python |
| 27 | + # coding=utf-8 |
| 28 | + |
| 29 | + """ |
| 30 | + solving a quadratic equation |
| 31 | + """ |
| 32 | + |
| 33 | + from __future__ import division |
| 34 | + import math |
| 35 | + |
| 36 | + def quadratic_equation(a,b,c): |
| 37 | + delta = b*b - 4*a*c |
| 38 | + if delta<0: |
| 39 | + return False |
| 40 | + elif delta==0: |
| 41 | + return -(b/(2*a)) |
| 42 | + else: |
| 43 | + sqrt_delta = math.sqrt(delta) |
| 44 | + x1 = (-b + sqrt_delta)/(2*a) |
| 45 | + x2 = (-b - sqrt_delta)/(2*a) |
| 46 | + return x1, x2 |
| 47 | + |
| 48 | + if __name__ == "__main__": |
| 49 | + print "a quadratic equation: x^2 + 2x + 1 = 0" |
| 50 | + coefficients = (1, 2, 1) |
| 51 | + roots = quadratic_equation(*coefficients) |
| 52 | + if roots: |
| 53 | + print "the result is:",roots |
| 54 | + else: |
| 55 | + print "this equation has no solution." |
| 56 | + |
| 57 | +保存为20501.py,并运行之: |
| 58 | + |
| 59 | + $ python 20501.py |
| 60 | + a quadratic equation: x^2 + 2x + 1 = 0 |
| 61 | + the result is: -1.0 |
| 62 | + |
| 63 | +能够正常运行,求解方程。 |
| 64 | + |
| 65 | +但是,如果再认真思考,发现上述代码是有很大改进空间的。至少我发现: |
| 66 | + |
| 67 | +- 如果不小心将第一个系数(a)的值输入了0,程序肯定会报错。如何避免之?要记住,任何人的输入都是不可靠的。 |
| 68 | +- 结果貌似只能是小数,这在某些情况下是近似值,能不能得到以分数形式表示的精确结果呢? |
| 69 | +- 复数,python是可以表示复数的,如果delta<0,是不是写成复数更好,毕竟我是学过高中数学的。 |
| 70 | + |
| 71 | +读者是否还有其它改进呢?你能不能进行改进,然后跟我和其他朋友一起来分享你的成就呢? |
| 72 | + |
| 73 | +至少要完成上述改进,可能需要其它的有关python知识,甚至于前面没有介绍。这都不要紧,掌握了基本知识之后,在编程的过程中,就要不断发挥google的优势,让她帮助你找寻完成任务的工具。 |
| 74 | + |
| 75 | +>python是一个开发的语言,很多大牛人都写了一些工具,让别人使用,减轻了后人的劳动负担。这就是所谓的第三方模块。虽然python中已经有一些“自带电池”,即默认安装的,比如上面程序中用到的math,但是我们还嫌不够。于是又很多第三方的模块来专门解决某个问题。比如这个解方程问题,就可以使用SymPy(www.sympy.org)来解决,当然NumPy也是非常强悍的工具。 |
| 76 | +
|
| 77 | +##统计考试成绩 |
| 78 | + |
| 79 | +每次考试之后,教师都要统计考试成绩,一般包括:平均分,对所有人按成绩从高到低排队,谁成绩最好,谁成绩最差。还有其它的统计项,暂且不做了。只统计这几项吧。下面的任务就是读者转动脑筋,思考如何用程序实现上面的统计。为了简化,以字典形式表示考试成绩记录,例如:`{"zhangsan":90, "lisi":78, "wangermazi":39}`,当然,也许不止这三项,可能还有,每个老师所处理的内容稍有不同,因此字典里的键值对也不一样。 |
| 80 | + |
| 81 | +怎么做? |
| 82 | + |
| 83 | +有几种可能要考虑到: |
| 84 | + |
| 85 | +- 最高分或者最低分,可能有人并列。 |
| 86 | +- 要实现不同长度的字典作为输入值。 |
| 87 | +- 输出结果中,除了平均分,其它的都要有姓名和分数两项,否则都匿名了,怎么刺激学渣,表扬学霸呢? |
| 88 | + |
| 89 | +不管你是学渣还是学霸,都能学好python。请思考后敲代码调试你的程序,调试之后再阅读下文。 |
| 90 | + |
| 91 | +参考代码: |
| 92 | + |
| 93 | + #!/usr/bin/env python |
| 94 | + # coding=utf-8 |
| 95 | + """ |
| 96 | + 统计考试成绩 |
| 97 | + """ |
| 98 | + from __future__ import division |
| 99 | + |
| 100 | + def average_score(scores): |
| 101 | + """ |
| 102 | + 统计平均分. |
| 103 | + """ |
| 104 | + score_values = scores.values() |
| 105 | + sum_scores = sum(score_values) |
| 106 | + average = sum_scores/len(score_values) |
| 107 | + return average |
| 108 | + |
| 109 | + def sorted_score(scores): |
| 110 | + """ |
| 111 | + 对成绩从高到低排队. |
| 112 | + """ |
| 113 | + score_lst = [(scores[k],k) for k in scores] |
| 114 | + sort_lst = sorted(score_lst, reverse=True) |
| 115 | + return [(i[1], i[0]) for i in sort_lst] |
| 116 | + |
| 117 | + def max_score(scores): |
| 118 | + """ |
| 119 | + 成绩最高的姓名和分数. |
| 120 | + """ |
| 121 | + lst = sorted_score(scores) #引用分数排序的函数sorted_score |
| 122 | + max_score = lst[0][1] |
| 123 | + return [(i[0],i[1]) for i in lst if i[1]==max_score] |
| 124 | + |
| 125 | + def min_score(scores): |
| 126 | + """ |
| 127 | + 成绩最低的姓名和分数. |
| 128 | + """ |
| 129 | + lst = sorted_score(scores) |
| 130 | + min_score = lst[len(lst)-1][1] |
| 131 | + return [(i[0],i[1]) for i in lst if i[1]==min_score] |
| 132 | + |
| 133 | + if __name__ == "__main__": |
| 134 | + examine_scores = {"google":98, "facebook":99, "baidu":52, "alibaba":80, "yahoo":49, "IBM":70, "android":76, "apple":99, "amazon":99} |
| 135 | + |
| 136 | + ave = average_score(examine_scores) |
| 137 | + print "the average score is: ",ave #平均分 |
| 138 | + |
| 139 | + sor = sorted_score(examine_scores) |
| 140 | + print "list of the scores: ",sor #成绩表 |
| 141 | + |
| 142 | + xueba = max_score(examine_scores) |
| 143 | + print "Xueba is: ",xueba #学霸们 |
| 144 | + |
| 145 | + xuezha = min_score(examine_scores) |
| 146 | + print "Xuzha is: ",xuezha #学渣们 |
| 147 | + |
| 148 | +保存为20502.py,然后运行: |
| 149 | + |
| 150 | + $ python 20502.py |
| 151 | + the average score is: 80.2222222222 |
| 152 | + list of the scores: [('facebook', 99), ('apple', 99), ('amazon', 99), ('google', 98), ('alibaba', 80), ('android', 76), ('IBM', 70), ('baidu', 52), ('yahoo', 49)] |
| 153 | + Xueba is: [('facebook', 99), ('apple', 99), ('amazon', 99)] |
| 154 | + Xuzha is: [('yahoo', 49)] |
| 155 | + |
| 156 | +貌似结果还不错。不过,还有改进余地,看看现实,就感觉不怎么友好了。看官能不能优化一下?当然,里面的函数也不一定是最好的方法,你也可以修改优化。期盼能够在我上面公布的途径中交流一二。 |
| 157 | + |
| 158 | +##找素数 |
| 159 | + |
| 160 | +这是一个比较常见的题目。我们姑且将范围缩小一下,找出100以内的素数吧。 |
| 161 | + |
| 162 | +还是按照前面的管理,读者先做,然后我提供参考代码,然后自行优化。 |
| 163 | + |
| 164 | +>質數(Prime number),又称素数,指在大於1的自然数中,除了1和此整数自身外,無法被其他自然数整除的数(也可定義為只有1和本身两个因数的数)。 |
| 165 | +
|
| 166 | +>哥德巴赫猜想是數論中存在最久的未解問題之一。这个猜想最早出现在1742年普鲁士人克里斯蒂安·哥德巴赫与瑞士数学家莱昂哈德·欧拉的通信中。用现代的数学语言,哥德巴赫猜想可以陳述為:“任一大於2的偶數,都可表示成兩個質數之和。”。哥德巴赫猜想在提出后的很长一段时间内毫无进展,直到二十世纪二十年代,数学家从组合数学与解析数论两方面分别提出了解决的思路,并在其后的半个世纪里取得了一系列突破。目前最好的结果是陈景润在1973年发表的陈氏定理(也被称为“1+2”)。(源自《维基百科》) |
| 167 | +
|
| 168 | +对这个练习,我的思路是先做一个函数,用它来判断某个整数是否是素数。然后循环即可。参考代码: |
| 169 | + |
| 170 | + #!/usr/bin/env python |
| 171 | + # coding=utf-8 |
| 172 | + |
| 173 | + """ |
| 174 | + 寻找素数 |
| 175 | + """ |
| 176 | + |
| 177 | + import math |
| 178 | + |
| 179 | + def is_prime(n): |
| 180 | + """ |
| 181 | + 判断一个数是否是素数 |
| 182 | + """ |
| 183 | + if n <= 1: |
| 184 | + return False |
| 185 | + for i in range(2, int(math.sqrt(n) + 1)): |
| 186 | + if n % i == 0: |
| 187 | + return False |
| 188 | + return True |
| 189 | + |
| 190 | + if __name__ == "__main__": |
| 191 | + primes = [i for i in range(2,100) if is_prime(i)] #从2开始,因为1显然不是质数 |
| 192 | + print primes |
| 193 | + |
| 194 | +代码保存后运行: |
| 195 | + |
| 196 | + $ python 20503.py |
| 197 | + [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] |
| 198 | + |
| 199 | +打印出了100以内的质数。 |
| 200 | + |
| 201 | +还是前面的观点,这个程序你或许也发现了需要进一步优化的地方,那就太好了。另外,关于判断质数的方法,还有好多种,读者可以自己创造或者网上搜索一些,拓展思路。 |
| 202 | + |
| 203 | +------ |
| 204 | + |
| 205 | +[总目录](./index.md) | [上节:函数(4)](./204.md) | [下节:类(1)](./206.md) |
| 206 | + |
| 207 | +如果你认为有必要打赏我,请通过支付宝:**qiwsir@126.com**,不胜感激。 |
0 commit comments