函數(shù)練習(xí)

2018-02-24 15:48 更新

已經(jīng)學(xué)習(xí)了函數(shù)的基本知識,現(xiàn)在練習(xí)練習(xí)。完成下面練習(xí)的原則:

  1. 請讀者先根據(jù)自己的設(shè)想寫下代碼,然后運(yùn)行調(diào)試,檢查得到的結(jié)果是否正確
  2. 我也給出參考代碼,但是,參考代碼并不是最終結(jié)果
  3. 讀者可以在上述基礎(chǔ)上對代碼進(jìn)行完善
  4. 如果讀者愿意,可以將代碼提交到github上,或者到我的QQ群(群號:26913719)中跟大家分享討論

解一元二次方程

解一元二次方程,是初中數(shù)學(xué)中的基本知識,一般來講解法有:公式法、因式分解法等。讀者可以根據(jù)自己的理解,寫一段求解一元二次方程的程序。

最簡單的思路就是用公式法求解,這是普適法則(普世法則?普適是否等同于普世?)。

古巴比倫留下的陶片顯示,在大約公元前2000年(2000 BC)古巴比倫的數(shù)學(xué)家就能解一元二次方程了。在大約公元前480年,中國人已經(jīng)使用配方法求得了二次方程的正根,但是并沒有提出通用的求解方法。公元前300年左右,歐幾里得提出了一種更抽象的幾何方法求解二次方程。

7世紀(jì)印度的婆羅摩笈多(Brahmagupta)是第一位懂得用使用代數(shù)方程,它同時容許有正負(fù)數(shù)的根。

11世紀(jì)阿拉伯的花拉子密 獨立地發(fā)展了一套公式以求方程的正數(shù)解。亞伯拉罕·巴希亞(亦以拉丁文名字薩瓦索達(dá)著稱)在他的著作Liber embadorum中,首次將完整的一元二次方程解法傳入歐洲。(源自《維基百科》)

參考代碼:

#!/usr/bin/env python
# coding=utf-8

"""
solving a quadratic equation
"""

from __future__ import division
import math

def quadratic_equation(a,b,c):
    delta = b*b - 4*a*c
    if delta<0:
        return False
    elif delta==0:
        return -(b/(2*a))
    else:
        sqrt_delta = math.sqrt(delta)
        x1 = (-b + sqrt_delta)/(2*a)
        x2 = (-b - sqrt_delta)/(2*a)
        return x1, x2

if __name__ == "__main__":
    print "a quadratic equation: x^2 + 2x + 1 = 0"
    coefficients = (1, 2, 1)
    roots = quadratic_equation(*coefficients)
    if roots:
        print "the result is:",roots
    else:
        print "this equation has no solution."

保存為20501.py,并運(yùn)行之:

$ python 20501.py 
a quadratic equation: x^2 + 2x + 1 = 0
the result is: -1.0

能夠正常運(yùn)行,求解方程。

但是,如果再認(rèn)真思考,發(fā)現(xiàn)上述代碼是有很大改進(jìn)空間的。至少我發(fā)現(xiàn):

  • 如果不小心將第一個系數(shù)(a)的值輸入了0,程序肯定會報錯。如何避免之?要記住,任何人的輸入都是不可靠的。
  • 結(jié)果貌似只能是小數(shù),這在某些情況下是近似值,能不能得到以分?jǐn)?shù)形式表示的精確結(jié)果呢?
  • 復(fù)數(shù),python是可以表示復(fù)數(shù)的,如果delta<0,是不是寫成復(fù)數(shù)更好,畢竟我是學(xué)過高中數(shù)學(xué)的。

讀者是否還有其它改進(jìn)呢?你能不能進(jìn)行改進(jìn),然后跟我和其他朋友一起來分享你的成就呢?

至少要完成上述改進(jìn),可能需要其它的有關(guān)python知識,甚至于前面沒有介紹。這都不要緊,掌握了基本知識之后,在編程的過程中,就要不斷發(fā)揮google的優(yōu)勢,讓她幫助你找尋完成任務(wù)的工具。

python是一個開發(fā)的語言,很多大牛人都寫了一些工具,讓別人使用,減輕了后人的勞動負(fù)擔(dān)。這就是所謂的第三方模塊。雖然python中已經(jīng)有一些“自帶電池”,即默認(rèn)安裝的,比如上面程序中用到的math,但是我們還嫌不夠。于是又很多第三方的模塊來專門解決某個問題。比如這個解方程問題,就可以使用SymPy(www.sympy.org)來解決,當(dāng)然NumPy也是非常強(qiáng)悍的工具。

統(tǒng)計考試成績

每次考試之后,教師都要統(tǒng)計考試成績,一般包括:平均分,對所有人按成績從高到低排隊,誰成績最好,誰成績最差。還有其它的統(tǒng)計項,暫且不做了。只統(tǒng)計這幾項吧。下面的任務(wù)就是讀者轉(zhuǎn)動腦筋,思考如何用程序?qū)崿F(xiàn)上面的統(tǒng)計。為了簡化,以字典形式表示考試成績記錄,例如:{"zhangsan":90, "lisi":78, "wangermazi":39},當(dāng)然,也許不止這三項,可能還有,每個老師所處理的內(nèi)容稍有不同,因此字典里的鍵值對也不一樣。

怎么做?

有幾種可能要考慮到:

  • 最高分或者最低分,可能有人并列。
  • 要實現(xiàn)不同長度的字典作為輸入值。
  • 輸出結(jié)果中,除了平均分,其它的都要有姓名和分?jǐn)?shù)兩項,否則都匿名了,怎么刺激學(xué)渣,表揚(yáng)學(xué)霸呢?

不管你是學(xué)渣還是學(xué)霸,都能學(xué)好python。請思考后敲代碼調(diào)試你的程序,調(diào)試之后再閱讀下文。

參考代碼:

#!/usr/bin/env python
# coding=utf-8
"""
統(tǒng)計考試成績
"""
from __future__ import division

def average_score(scores):
    """
    統(tǒng)計平均分.
    """
    score_values = scores.values()
    sum_scores = sum(score_values)
    average = sum_scores/len(score_values)
    return average

def sorted_score(scores):
    """
    對成績從高到低排隊.
    """
    score_lst = [(scores[k],k) for k in scores]
    sort_lst = sorted(score_lst, reverse=True)
    return [(i[1], i[0]) for i in sort_lst]

def max_score(scores):
    """
    成績最高的姓名和分?jǐn)?shù).
    """
    lst = sorted_score(scores)    #引用分?jǐn)?shù)排序的函數(shù)sorted_score
    max_score = lst[0][1]
    return [(i[0],i[1]) for i in lst if i[1]==max_score]

def min_score(scores):
    """
    成績最低的姓名和分?jǐn)?shù).
    """
    lst = sorted_score(scores)
    min_score = lst[len(lst)-1][1]
    return [(i[0],i[1]) for i in lst if i[1]==min_score]

if __name__ == "__main__":
    examine_scores = {"google":98, "facebook":99, "baidu":52, "alibaba":80, "yahoo":49, "IBM":70, "android":76, "apple":99, "amazon":99}

    ave = average_score(examine_scores)
    print "the average score is: ",ave    #平均分

    sor = sorted_score(examine_scores)
    print "list of the scores: ",sor      #成績表

    xueba = max_score(examine_scores)
    print "Xueba is: ",xueba              #學(xué)霸們

    xuezha = min_score(examine_scores)
    print "Xuzha is: ",xuezha             #學(xué)渣們

保存為20502.py,然后運(yùn)行:

$ python 20502.py
the average score is:  80.2222222222
list of the scores:  [('facebook', 99), ('apple', 99), ('amazon', 99), ('google', 98), ('alibaba', 80), ('android', 76), ('IBM', 70), ('baidu', 52), ('yahoo', 49)]
Xueba is:  [('facebook', 99), ('apple', 99), ('amazon', 99)]
Xuzha is:  [('yahoo', 49)]

貌似結(jié)果還不錯。不過,還有改進(jìn)余地,看看現(xiàn)實,就感覺不怎么友好了??垂倌懿荒軆?yōu)化一下?當(dāng)然,里面的函數(shù)也不一定是最好的方法,你也可以修改優(yōu)化。期盼能夠在我上面公布的途徑中交流一二。

找素數(shù)

這是一個比較常見的題目。我們姑且將范圍縮小一下,找出100以內(nèi)的素數(shù)吧。

還是按照前面的管理,讀者先做,然后我提供參考代碼,然后自行優(yōu)化。

質(zhì)數(shù)(Prime number),又稱素數(shù),指在大於1的自然數(shù)中,除了1和此整數(shù)自身外,無法被其他自然數(shù)整除的數(shù)(也可定義為只有1和本身兩個因數(shù)的數(shù))。

哥德巴赫猜想是數(shù)論中存在最久的未解問題之一。這個猜想最早出現(xiàn)在1742年普魯士人克里斯蒂安·哥德巴赫與瑞士數(shù)學(xué)家萊昂哈德·歐拉的通信中。用現(xiàn)代的數(shù)學(xué)語言,哥德巴赫猜想可以陳述為:“任一大於2的偶數(shù),都可表示成兩個質(zhì)數(shù)之和。”。哥德巴赫猜想在提出后的很長一段時間內(nèi)毫無進(jìn)展,直到二十世紀(jì)二十年代,數(shù)學(xué)家從組合數(shù)學(xué)與解析數(shù)論兩方面分別提出了解決的思路,并在其后的半個世紀(jì)里取得了一系列突破。目前最好的結(jié)果是陳景潤在1973年發(fā)表的陳氏定理(也被稱為“1+2”)。(源自《維基百科》)

對這個練習(xí),我的思路是先做一個函數(shù),用它來判斷某個整數(shù)是否是素數(shù)。然后循環(huán)即可。參考代碼:

#!/usr/bin/env python
# coding=utf-8

"""
尋找素數(shù)
"""

import math

def is_prime(n):
    """
    判斷一個數(shù)是否是素數(shù)
    """
    if n <= 1:
        return False
    for i in range(2, int(math.sqrt(n) + 1)):
        if n % i == 0:
            return False
    return True

if __name__ == "__main__":
    primes = [i for i in range(2,100) if is_prime(i)]    #從2開始,因為1顯然不是質(zhì)數(shù)
    print primes

代碼保存后運(yùn)行:

$ python 20503.py 
[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]

打印出了100以內(nèi)的質(zhì)數(shù)。

還是前面的觀點,這個程序你或許也發(fā)現(xiàn)了需要進(jìn)一步優(yōu)化的地方,那就太好了。另外,關(guān)于判斷質(zhì)數(shù)的方法,還有好多種,讀者可以自己創(chuàng)造或者網(wǎng)上搜索一些,拓展思路。

編寫函數(shù)的注意事項

編寫函數(shù),在開發(fā)實踐中是非常必要和常見的,一般情況,你寫的函數(shù)應(yīng)該是:

  1. 盡量不要使用全局變量。
  2. 如果參數(shù)是可變類型數(shù)據(jù),在函數(shù)內(nèi),不要修改它。
  3. 每個函數(shù)的功能和目標(biāo)要單純,不要試圖一個函數(shù)做很多事情。
  4. 函數(shù)的代碼行數(shù)盡量少。
  5. 函數(shù)的獨立性越強(qiáng)越好,不要跟其它的外部東西產(chǎn)生關(guān)聯(lián)。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號