題目什么的感覺為了保密就不寫出來(lái)了,我自己知道就好了。
二分法
這道題本身難度不大,我也不知道什么非常優(yōu)雅的辦法,不過(guò)從回答者的角度來(lái)說(shuō),使用什么樣的策略才能最快得到正確答案?由這一問(wèn)題可以延伸出一個(gè)基本算法——二分法。
有一個(gè)數(shù)字,已知其介于0~1000000,那么我們?cè)撊绾巫羁觳鲁鲞@個(gè)數(shù)字的準(zhǔn)確大小,這就是二分法的問(wèn)題描述了。
最樸素的方法,從0開始遍歷逐個(gè)比對(duì),似乎也只要常數(shù)級(jí)別的時(shí)間復(fù)雜度,但還是不夠優(yōu)秀。
那么就每次將范圍減半,判斷是否在范圍內(nèi),這樣的話我們的時(shí)間復(fù)雜度就會(huì)變成對(duì)數(shù)級(jí)別,面對(duì)大規(guī)模問(wèn)題用時(shí)少了。
具體的實(shí)現(xiàn)需要結(jié)合遞歸的編程思想,因?yàn)閱?wèn)題已經(jīng)被我們簡(jiǎn)化為判斷數(shù)是否在一個(gè)范圍內(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>
一切皆對(duì)象。
將想要解決的問(wèn)題看作對(duì)象,抽象出其屬性,通過(guò)定義方法來(lái)解決問(wèn)題。
好處在于只要待解決問(wèn)題的屬性不變,直接的添加新的方法就能解決問(wèn)題。(還是要重寫代碼會(huì)不會(huì)太麻煩了?以后繼續(xù)領(lǐng)悟)
在python中的實(shí)現(xiàn)就是類的定義、繼承與多態(tài),在解決大型問(wèn)題時(shí)候很方便。
異常處理
try:
執(zhí)行語(yǔ)句
except A:
出現(xiàn)A錯(cuò)誤則執(zhí)行該處
except B:
出現(xiàn)B錯(cuò)誤則執(zhí)行該處
else:
try語(yǔ)句部分正常執(zhí)行后則執(zhí)行該處
finally:
無(wú)論以上是否執(zhí)行,最后一定執(zhí)行finally部分
- except中拋出的錯(cuò)誤利用as被命名為e,因此在except中還可以利用該對(duì)象來(lái)進(jìn)行一些操作,比如打印錯(cuò)誤的返回值之類的。
關(guān)于錯(cuò)誤的類型可以參看python官方文檔
- 值得注意的一點(diǎn)是,當(dāng)存在1調(diào)用2,2調(diào)用3,3調(diào)用4時(shí),在2、3、4出現(xiàn)的錯(cuò)誤都會(huì)被拋到1進(jìn)行處理,因此只需要在1處進(jìn)行異常處理便可捕獲可能的錯(cuò)誤。
用assert代替print進(jìn)行調(diào)試
n = 2
assert n != 0, print(n等于0)
單元測(cè)試
可以參看廖雪峰老師的教程
這個(gè)則是python官方的uniittest文檔
常用的幾個(gè)test方法
待測(cè)試的代碼
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請(qǐng)輸入您的答案:' % times))
except ValueError as e:
print('輸入的不是數(shù)字,請(qǐng)重新輸入')
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()
測(cè)試用代碼,主要檢查了在定義類實(shí)例時(shí)候輸入的范圍和次數(shù)是否是int類型,用了assertIsInstance
import unittest
from day_2 import GuessGame
class TestGuessGame(unittest.TestCase): # 繼承TestCase,其中有常用的測(cè)試方法
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()
這個(gè)單元測(cè)試只測(cè)試了類實(shí)例的屬性,這次的方法并沒(méi)有輸出一個(gè)結(jié)果,所以沒(méi)有對(duì)方法的輸出結(jié)果進(jìn)行測(cè)試。
官方文檔的介紹相當(dāng)詳細(xì)了,不過(guò)很多東西我暫時(shí)都很難有實(shí)踐的機(jī)會(huì),因此整理的并不多。