此做業要求參見:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2148python
此做業代碼地址:https://git.coding.net/tianl364/Arithmetic_Demo.gitgit
結對同窗:田良express
支持出題4個數的四則運算題目,全部題目要求做者有能力正確回答 (提示:1/3 != 0.33333333333333333333333333333333,而是無限長)。編程
爲了快出成果,你快速造個控制檯的版本,包括之後改版成更優秀界面的核心功能,並考慮到擴展。數據結構
表達式生成,主要代碼以下:app
# 操做數4,運算符3 for j in range(4 + 3): if j % 2 == 0: # 隨機生成操做數 exp.append(self.generate_operand()) else: # 隨機生成運算符 exp.append(self.generate_operation())
操做數和運算符的隨機生成,主要代碼以下:dom
# 生成操做數 def generate_operand(self): return str(random.randint(1, 9)) # 生成運算符 def generate_operation(self): operators = ['+', '-', '*', '/'] return operators[random.randint(0, len(operators) - 1)]
中綴表達式轉後綴表達式,主要代碼以下:函數
# 將中綴表達式轉換爲後綴表達式 def middle_to_after(s): expression = [] ops = [] # ss = s.split(' ') # s = s.replace('=', '') for item in s: if item in ['+', '-', '*', '/']: while len(ops) >= 0: if len(ops) == 0: ops.append(item) break op = ops.pop() if op == '(' or ops_rule[item] > ops_rule[op]: ops.append(op) ops.append(item) break else: expression.append(op) elif item == '(': ops.append(item) elif item == ')': while len(ops) > 0: op = ops.pop() if op == '(': break else: expression.append(op) else: expression.append(item) while len(ops) > 0: expression.append(ops.pop()) return expression
後綴表達式的計算,主要代碼以下:學習
# 計算後綴表達式 def expression_to_value(expression): stack_value = [] for item in expression: if item in ['+', '-', '*', '/']: n2 = stack_value.pop() n1 = stack_value.pop() result = cal(n1, n2, item) stack_value.append(result) else: stack_value.append(int(item)) return stack_value[0] # 四則運算規則 def cal(n1, n2, op): if op == '+': return n1 + n2 if op == '-': return n1 - n2 if op == '*': return n1 * n2 if op == '/': return n1 / n2
在實現功能一的過程當中,對以前數據結構裏「棧」的使用較多,也花了許多時間複習這個概念以及中綴表達式與後綴表達式之間的轉變,雖然以前使用過屢次c語言版本的中綴轉後綴,但此次經過python實現仍是以爲很是便利。而在制定操做符優先級和四則運算規則時,經過不斷封裝函數來下降程序的耦合也使得程序更加易讀。spa
老師看了你的表演,大大讚揚了你。而後她說,"你的題庫裏怎麼都是沒有括號的題呢,我記得你當初括號就掌握得很差啊。"你的臉紅了,對老師說,"給我2個小時時間,我給你一個新版本,有括號的。"
括號的生成方式,主要代碼以下:
if exp: i = 0 for j in self.position_matrix[position]: # 0表示添加操做數和運算符 if j == 0: expression.append(exp[i]) if i < len(exp): i += 1 # -1表示添加左括號 elif j == -1: expression.append('(') # 1表示添加右括號 elif j == 1: expression.append(')')
括號的成對生成,主要代碼以下:
# 4個數的式子括號最多兩對,隨機生成一對括號或兩對括號 position_matrix = [[-1, 0, 0, 0, 1, 0, 0, 0, 0, 2, 2], [-1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2], [0, 0, -1, 0, 0, 0, 1, 0, 0, 2, 2], [0, 0, -1, 0, 0, 0, 0, 0, 1, 2, 2], [0, 0, 0, 0, -1, 0, 0, 0, 1, 2, 2], [-1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1], [-1, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0], [-1, 0, 0, -1, 0, 0, 0, 1, 1, 0, 0], [0, 0, -1, -1, 0, 0, 0, 1, 0, 0, 1], [0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 1] ] # 生成括號表達式 def generate_parentheses(self, exp): expression = [] # 從10種狀況中選取一種 position = random.randint(0, 9)
括號的隨機生成問題,單個括號經過位置也好實現,可是題目要求括號出現了嵌套的狀況,這須要在每次添加操做數前都要隨機插入括號,有時還須要插入2個左括號,而在插入左括號後還要隨機插入右括號與之匹配,這些判斷一一添加進去會十分冗餘,通過咱們的分析,先發現最多隻能出現兩對括號的狀況,而後將全部括號一一列舉,就發現這個數量並不龐大,經過枚舉一個矩陣即可以輕鬆表示,隨後咱們又制定了矩陣的表示規則,較爲簡練的實現了功能二。
對輸入指令的判斷,主要代碼以下:
# 這是主方法 def main(argv): if '-c' in sys.argv: input_text = str(sys.argv[2]) if input_text.isdigit() and int(input_text) > 0: normalize_exp(int(input_text)) else: print('題目數量必須是 正整數。') else: circular_problem() if __name__ == '__main__': main(sys.argv[1:])
按指定格式輸出,主要代碼以下:
# 規範輸出 def normalize_exp(num): i = 0 while i < num: generate = Exp_Generating.Generator() inputText = generate.generate() expression = middle_to_after(inputText) value = expression_to_value(expression) inputText += '=' print('%-15s %-15s' % (inputText, value)) i += 1
輸入題目個數的校驗,主要代碼以下:
input_text = str(sys.argv[2]) if input_text.isdigit() and int(input_text) > 0: normalize_exp(int(input_text)) else: print('題目數量必須是 正整數。')
這個查重的邏輯表面上看起來較爲複雜,可是咱們能夠經過利用數據結構中二叉樹的原理進行實現,先將表達式轉化爲二叉樹,再將二叉樹進行後序遍歷,若是兩個式子經過交換律能變成同樣的式子,那麼他們所生產的二叉樹後序遍歷的結果也同樣。
因爲自身基礎和編程能力較差,對於我來講結對編程是一個向我結對夥伴田良學習的過程。能夠看到別人的思路和技能,獲得實時的講解,受到激勵,從而努力提升本身的水平,提出更多創意。在結對編程中,由於可以隨時的交流,我在程序中的錯誤也減小了許多,也學會了從對方的角度看待問題,去更好的解決程序開發過程當中遇到的各類問題。
1 中綴表達式如何轉成後綴表達式
2 類名,函數名,變量名如何命名規範
3 對於添加括號問題時是選用枚舉仍是隨機
4 是否在一個文件中完成全部功能
5 因爲本身編程能力較差,致使本身的任務未能及時完成形成總體工程拖延
工做地點:信息科學與技術學院 數據可視化與可視分析實驗室,使用田良的電腦進行編程