day_2:面向?qū)ο?,異常處理,單元測試

題目什么的感覺為了保密就不寫出來了,我自己知道就好了。

二分法

這道題本身難度不大,我也不知道什么非常優(yōu)雅的辦法,不過從回答者的角度來說,使用什么樣的策略才能最快得到正確答案?由這一問題可以延伸出一個基本算法——二分法。

有一個數(shù)字,已知其介于0~1000000,那么我們該如何最快猜出這個數(shù)字的準(zhǔn)確大小,這就是二分法的問題描述了。

最樸素的方法,從0開始遍歷逐個比對,似乎也只要常數(shù)級別的時間復(fù)雜度,但還是不夠優(yōu)秀。

那么就每次將范圍減半,判斷是否在范圍內(nèi),這樣的話我們的時間復(fù)雜度就會變成對數(shù)級別,面對大規(guī)模問題用時少了。

具體的實現(xiàn)需要結(jié)合遞歸的編程思想,因為問題已經(jīng)被我們簡化為判斷數(shù)是否在一個范圍內(nèi),是的話就將范圍減半并繼續(xù)判斷,不是的話則從另一部分繼續(xù)判斷。有興趣的朋友可以自行了解一下。

import sys
from random import randrange


def f(r, a, b):
    if r == a:
        return a
    elif r == b:
        return b
    elif r <= int((a + b) / 2):
        return f(r, int((a + b) / 2), b)
    else:
        return f(r, a, int((a + b) / 2))


sys.setrecursionlimit(1000000000)  # 改變python默認(rèn)的遞歸深度
n = 10 ** 10
r = randrange(n)
if r == f(r, n, 0):
    print(f(r, n, 0))

面向?qū)ο缶幊?/h3>

一切皆對象。

將想要解決的問題看作對象,抽象出其屬性,通過定義方法來解決問題。

好處在于只要待解決問題的屬性不變,直接的添加新的方法就能解決問題。(還是要重寫代碼會不會太麻煩了?以后繼續(xù)領(lǐng)悟)

在python中的實現(xiàn)就是類的定義、繼承與多態(tài),在解決大型問題時候很方便。


異常處理

try:

    執(zhí)行語句

except A:

    出現(xiàn)A錯誤則執(zhí)行該處

except B:

    出現(xiàn)B錯誤則執(zhí)行該處

else:

    try語句部分正常執(zhí)行后則執(zhí)行該處

finally:

    無論以上是否執(zhí)行,最后一定執(zhí)行finally部分
  1. except中拋出的錯誤利用as被命名為e,因此在except中還可以利用該對象來進行一些操作,比如打印錯誤的返回值之類的。
    關(guān)于錯誤的類型可以參看python官方文檔
  1. 值得注意的一點是,當(dāng)存在1調(diào)用2,2調(diào)用3,3調(diào)用4時,在2、3、4出現(xiàn)的錯誤都會被拋到1進行處理,因此只需要在1處進行異常處理便可捕獲可能的錯誤。

用assert代替print進行調(diào)試

n = 2
assert n != 0, print(n等于0)

單元測試

可以參看廖雪峰老師的教程
這個則是python官方的uniittest文檔

常用的幾個test方法

常用的test方法.png
字符串、列表等的test方法.png
數(shù)值大小的test方法.png

待測試的代碼

from random import randrange


class GuessGame(object):
    def __init__(self, min_int, max_int, times):
        self.truth = randrange(min_int, max_int)
        self.min_int = min_int
        self.max_int = max_int
        self.times = times

    def guessing(self):
        times = self.times
        truth = self.truth
        while times:
            try:
                guess = int(input('剩余游戲次數(shù):%s\n請輸入您的答案:' % times))
            except ValueError as e:
                print('輸入的不是數(shù)字,請重新輸入')
                continue
            if guess == truth:
                print('回答正確,游戲結(jié)束')
                break
            else:
                if guess > truth:
                    print('您的結(jié)果偏大')
                else:
                    print('您的結(jié)果偏小')
            times -= 1
        else:
            print('游戲結(jié)束,失敗\n答案為%s' % truth)


if __name__ == '__main__':
    game = GuessGame(1, 100, 5)
    game.guessing()

測試用代碼,主要檢查了在定義類實例時候輸入的范圍和次數(shù)是否是int類型,用了assertIsInstance

import unittest
from day_2 import GuessGame


class TestGuessGame(unittest.TestCase):  # 繼承TestCase,其中有常用的測試方法

    def test_is_range_and_times_int(self):
        game = GuessGame(1, 100, 5)
        self.assertIsInstance(game.min_int, int)
        self.assertIsInstance(game.max_int, int)
        self.assertIsInstance(game.times, int)


if __name__ == '__main__':
    unittest.main()

這個單元測試只測試了類實例的屬性,這次的方法并沒有輸出一個結(jié)果,所以沒有對方法的輸出結(jié)果進行測試。

官方文檔的介紹相當(dāng)詳細了,不過很多東西我暫時都很難有實踐的機會,因此整理的并不多。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容