獲取python的源碼 3.x及最新版本的源碼:https://github.com/python/cpython python2.7分支的源碼:https://github.com/python/cpython/tree/v2.7.18 python官網也提供源碼下載:https://www.py ...
# 20212218 2021-2022-2 《Python程式設計》實驗二報告
課程:《Python程式設計》 班級: 2122 姓名: 林思凡 學號:20212218 實驗教師:王志強 實驗日期:2022年4月5日 必修/選修: 公選課
## 1.實驗內容 運用老師上課講的知識,外加上CSDN查找並潛心鑽研的拓展知識,完成一個簡易計算器 計算器功能如下: - 進行單次普通二元運算,運算符包括+、-、*、/、%、//、**等 - 進行單詞普通複數運算,運算符包括+、-、*、/ - 進行一串四則運算的結果輸出(這是在CSDN上學的,絕對不是無條件照抄,每一步都理解了,花了我相當長時間)
- 第二步,完成普通運算框架搭建,這一步王老師在課堂上已有所提及,我在此基礎上進行了完善,提高了此程式的容錯率。
比如,輸入/、%、//運算符時,若除數為0則會報錯。因此加入if條件判斷語句避免除數為0的情況。- 第三步,完成複數運算框架搭建,這一步與普通運算的框架搭建方法大同小異,只不過要記住複數要引用complex()函數,且複數的形式為a+bj,而非a+bi。
- 第四步,開始搭建四則運算框架(結果如圖),這一步花費了整個程式%80的時間,在此展開敘述
- 4-1,首先引入re模塊的findall()函數,將字元串形式的四則運算式子分隔字元,儲存在一個列表中。
- 4-2,將四則運算式子中小括弧內的式子進行運算,然後刪去括弧。
- 4-3,計算四則運算式子中的乘除運算。
- 4-4,計算四則運算式子中的加減運算。
- 4-5,框架搭建完畢,開始進行細化和完善。
- 4-5-1,運用if條件控制語句,避免出現兩個運算符同時出現的情況,如"2+(-3)"去除括弧之後會變成2+-3,這時需要去掉加號。
- 第五步,整體框架搭建完成,開始進行整體細化。比如運用while語句給每一個部分做一個返回鍵和退出鍵。程式到這裡基本完成。
成品 完整程式如下(會托管到碼雲):
import re flag1 = 1 while flag1 == 1: choice = input("請選擇您想要的計算器類型(0為簡單普通計算器、1為複數計算器、2為四則運算計算器、輸入E/e退出): \n") if choice == "E" or choice == "e": break if choice == "0": flag2 = 1 while flag2 == 1: op = input("請輸入需要做的操作(+、-、*、/、%、//、**、輸入e返回上一級、輸入E退出):\n") if op == "e": break if op == "E": flag1 = 0 break a = int(input("請輸入操作數a:")) b = int(input("請輸入操作數b:")) if op == "+": result = a + b elif op == "-": result = a - b elif op == "*": result = a * b elif op == "/": if b == 0: print("除數不能為0!請重新輸入!\n") continue else: result = a / b elif op == "%": if b == 0: print("除數不能為0!請重新輸入!\n") continue else: result = a % b elif op == "//": if b == 0: print("除數不能為0!請重新輸入!\n") continue else: result = a // b elif op == "**": result = a ** b else: print("輸入有誤,請重新輸入!\n") continue print(a, op, b, "=", result) elif choice == "1": flag3 = 1 while flag3 == 1: op = input("請輸入需要做的操作(+、-、*、/、輸入e返回上一級、輸入E退出):\n") if op == "e": break if op == "E": flag1 = 0 break a = complex(input("請輸入第一個複數(形式為a+bj):")) b = complex(input("請輸入第二個複數(形式為a+bj):")) result = 0 if op == "+": result = a + b elif op == "-": result = a - b elif op == "*": result = a * b elif op == "/": result = a / b else: print("輸入有誤,請重新輸入!\n") print(a, op, b, "=", result) if choice == '2': flag4 = 1 while flag4 == 1: a = input("請輸入一個四則運算式,我們將為您一步解出答案輸入(輸入e返回上一級、輸入E退出):\n") if a == "e": break if a == "E": flag1 = 0 break def division(n): list1 = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)', n) return list1 def change(n, m): if n[m] == '-': if n[m - 1] == '+': n[m - 1] = '-' del n[m] elif n[m - 1] == '-': n[m - 1] = '+' del n[m] return n def senior(n): s_count = 0 for i in n: if i == '*': if n[s_count + 1] != '-': n[s_count - 1] = float(n[s_count - 1]) * float(n[s_count + 1]) del n[s_count] del n[s_count] elif n[s_count + 1] == '-': n[s_count] = float(n[s_count - 1]) * float(n[s_count + 2]) n[s_count - 1] = '-' del n[s_count + 1] n = change(n, s_count - 1) return senior(n) elif i == '/': if n[s_count + 1] != '-': # 3*2 n[s_count - 1] = float(n[s_count - 1]) / float(n[s_count + 1]) del n[s_count] del n[s_count] elif n[s_count + 1] == '-': # 3*-2 n[s_count] = float(n[s_count - 1]) / float(n[s_count + 2]) n[s_count - 1] = '-' del n[s_count + 1] n = change(n, s_count - 1) return senior(n) s_count = s_count + 1 return n def junior(n): j_count = 0 if n[0] == '-': sum = 0 else: sum = float(n[0]) for i in n: if i == '-': sum = sum - float(n[j_count + 1]) if i == '+': sum = sum + float(n[j_count + 1]) j_count = j_count + 1 if sum >= 0: n = [str(sum)] else: n = ['-', str(-sum)] return n def calculate(n): if '*' in n or '/' in n: n = senior(n) if '+' in n or '-' in n: n = junior(n) return n def no_bracket(n): left_bracket = 0 count = 0 for i in n: if i == '(': left_bracket = count if i == ')': part = n[left_bracket + 1: count] resule_of_part = calculate(part) n = n[: left_bracket] + resule_of_part + n[count + 1:] n = change(n, left_bracket) return no_bracket(n) count = count + 1 return n def main(n): n_list = division(n) n_list1 = no_bracket(n_list) answer = calculate(n_list1) if len(answer) == 2: answer = -float(answer[1]) else: answer = float(answer[0]) return answer b = main(a) print(f"{a} = {b}")
## 3. 實驗過程中遇到的問題和解決過程 - 問題1:查閱代碼時,不清楚什麼是re模塊 - 問題1解決方案:查閱csdn相關資料,瞭解re模塊是一個字元匹配模塊,依次拿出表達式和文本中的字元比較,如果每一個字元都能匹配,則匹配成功;一旦有匹配不成功的字元則匹配失敗。如果表達式中有量詞或邊界,這個過程會稍微有一些不同。
- 問題2:查閱代碼時,不瞭解re模塊中的findall()函數 - 問題2解決方案:查閱csdn相關資料,瞭解findall()函數時一條用於多次查找匹配字元的函數,與re模塊中的match()和search()不同,後兩者只返回第一個匹配的字元。
- 問題3:初次使用re模塊的findall()函數時,出現報錯TypeError: expected string or bytes-like object - 問題3解決方案:上CSDN查閱相關報錯,發現findall語句參數只能是字元串,然後才返回一個列表;檢查自己的程式時發現在參數中引入了列表,改成字元串之後便正常運行。
- 問題4:查閱代碼時,不瞭解遞歸函數 - 問題4解決方案:查閱csdn相關資料,瞭解到,遞歸就是在運行的過程中調用自己。 構成遞歸需具備的條件: 1、子問題須與原始問題為同樣的事,且更為簡單; 2、不能無限制地調用本身,須有個出口,化簡為非遞歸狀況處理。
- 問題5:測試四則運算時,發現負數會自動轉成正數造成計算錯誤 - 問題5解決方案:多次調試,發現兩出問題,第一處是"或"條件判斷書寫存在錯誤;第二處是在一處計算當中忘記添加負號,改正之後解決,程式運行正常。
1. 調試真的非常非常好用!此次程式編寫行數為188行。當你面對一大堆代碼找不出問題所在時,不要猶豫,進行調試!通過調試,你能洞悉代碼每一步的運行情況,運籌帷幄,掌握全局,揪出漏洞,及時填補!
2. 網路是非常好非常好的學習平臺,在這裡你能夠獲得程式員大佬們悉心傳授的知識,並且受益無窮!本次計算器設計的四則運算部分,就是在我深入剖析大佬的代碼之後,恍然大悟才寫出來的。
## 參考資料
- [什麼是遞歸,通過這篇文章,讓你徹底搞懂遞歸](https://blog.csdn.net/abcdef314159/article/details/107906395?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164912286116780269818899%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164912286116780269818899&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-107906395.142^v5^pc_search_result_control_group,157^v4^control&utm_term=%E9%80%92%E5%BD%92&spm=1018.2226.3001.4187)
- [python——正則表達式(re模塊)詳解](https://blog.csdn.net/guo_qingxia/article/details/113979135?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164912120316780274154982%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164912120316780274154982&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-113979135.142^v5^pc_search_result_control_group,157^v4^control&utm_term=re%E6%A8%A1%E5%9D%97&spm=1018.2226.3001.4187) - [如何簡單地理解Python中的if __name__ == '__main__'](https://blog.csdn.net/yjk13703623757/article/details/77918633?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164913249116780271929101%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164913249116780271929101&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-77918633.142^v5^pc_search_result_control_group,157^v4^control&utm_term=+if+__name__+%3D%3D+__main__%3A&spm=1018.2226.3001.4187) - [項目3:python實現一個簡易計算器](https://blog.csdn.net/a971956955/article/details/81489914?ops_request_misc=&request_id=&biz_id=102&utm_term=python%E8%AE%A1%E7%AE%97%E5%99%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-81489914.nonecase&spm=1018.2226.3001.4187)