軟工第二次作業
| 這個作業屬于哪個課程 | 22計科12班 |
|---|---|
| 這個作業要求在哪里 | 結對項目 |
| 這個作業的目標 | 結對項目實現一個自動生成小學四則運算題目的命令行程序 |
GitHub地址:https://github.com/xian226/-four_operation
成員信息
| 姓名 | 學號 |
|---|---|
| 張顥嚴 | 3222004426 |
| 王睿嫻 | 3222003968 |
PSP表格
| PSP2.1 | Personal Software Process Stages | 預估耗時 (分鐘) | 實際耗時 (分鐘) |
|---|---|---|---|
| Planning | 計劃 | 60 | 60 |
| ·Estimate | ·估計這個任務需要多少時間 | 30 | 30 |
| Development | 開發 | 480 | 600 |
| ·Analysis | ·需求分析(包括學習新技術) | 300 | 300 |
| · Design Spec | ·生成設計文檔 | 60 | 60 |
| ·Design Review | .設計復審 | 20 | 10 |
| · Coding Standard | ·代碼規范(為目前的開發制定合適的規范) | 10 | 10 |
| ·Design | .具體設計 | 15 | 15 |
| ·Coding | .具體編碼 | 180 | 300 |
| · Code Review | ·代碼復審 | 20 | 10 |
| ·Test | ·測試(自我測試,修改代碼,提交修改) | 60 | 60 |
| Reporting | 報告 | 60 | 60 |
| ·Test Report | ·測試報告 | 30 | 40 |
| ·Size Measurement | ·計算工作量 | 15 | 10 |
| ·Postmortem & Process Improvement Plan | ·事后總結,并提出過程改進計劃 | 5 | 5 |
| ·合計 | 1345 | 1570 |
效能分析

程序中消耗時間最多的函數是
改進思路:由于文件I/O操作消耗了程序的大部分時間,84.4%的總時間都用于此。可以嘗試減少I/O操作或合并I/O操作。
設計實現過程
(1)代碼組織結構:
Product: 負責生成數學表達式,包括操作數和運算符。還負責去重和規范化輸出表達式。
SuffixExpression: 將中綴表達式轉換為后綴表達式,并計算后綴表達式的值。
BinaryTree: 用于生成和比較二叉樹,幫助判斷表達式的重復性。
Answer: 計算表達式的結果并與給定答案進行比對。
(2)類之間的關系
Product 類創建數學表達式,并通過 SuffixExpression 類進行計算。它還使用 BinaryTree 類來判斷表達式的唯一性。
Answer 類使用 SuffixExpression 類來計算表達式結果,并驗證這些結果。
(3)關鍵函數:
Product.creQuestion(): 生成表達式的主函數。
SuffixExpression.toSuffix(): 將中綴表達式轉換為后綴表達式。
Answer.expression_result(): 計算一組表達式的值并寫入答案文件。
Answer.check_answer(): 校對生成的答案與提供的答案。
(4)流程:
Product.creQuestion()
初始化表達式列表。
循環生成表達式。
隨機生成操作數和運算符。
檢查是否需要括號。
檢查表達式是否重復。
計算表達式的值。
返回表達式列表。
SuffixExpression.toSuffix()
初始化操作符棧和后綴表達式棧。
遍歷中綴表達式:
若是操作數,直接入棧。
若是操作符,按照優先級入棧并生成后綴表達式。
處理括號。
將棧中剩余操作符添加到后綴表達式。
返回后綴表達式。
Answer.expression_result()
讀取表達式列表。
初始化答案文件。
遍歷表達式,計算結果。
寫入答案文件。
Answer.check_answer()
讀取題目文件和答案文件。
對每個題目計算其結果。
比對答案,記錄正確和錯誤的題號。
輸出結果到評分文件。
代碼說明
Product類
點擊展開代碼
class Product:
def __init__(self, operRange, expressionNum):
self.operRange = operRange
self.operCount = 3
self.expressionNum = expressionNum
self.problemArray = self.creQuestion()
self.normalizeExpression(self.problemArray)
生成表達式
點擊展開代碼
def creQuestion(self):
expressionList = []
i = 0
while i < self.expressionNum:
random_num_operation = random.randint(1, self.operCount)
exp = []
for j in range(random_num_operation + 1):
exp.append(self.getOperNum() if j % 2 == 0 else self.generateOperation())
expression = " ".join(exp)
if not self.isRepeat(expressionList, expression):
expressionList.append(expression)
i += 1
return expressionList
轉換為后綴表達式
點擊展開代碼
```python class SuffixExpression: def toSuffix(self): suffix_stack = [] ops_stack = [] infix = self.exp.split(' ') for item in infix: if item in ['+', '-', '×', '÷']: while ops_stack and ops_rule[item] <= ops_rule[ops_stack[-1]]: suffix_stack.append(ops_stack.pop()) ops_stack.append(item) elif item == '(': ops_stack.append(item) elif item == ')': while ops_stack and ops_stack[-1] != '(': suffix_stack.append(ops_stack.pop()) ops_stack.pop() # 彈出 '(' else: suffix_stack.append(item) while ops_stack: suffix_stack.append(ops_stack.pop()) return suffix_stack ```計算后綴表達式的值
點擊展開代碼
```python def suffixToValue(self): stack_value = [] for item in self.re: if item in ['+', '-', '×', '÷']: n2 = stack_value.pop() n1 = stack_value.pop() result = self.cal(n1, n2, item) if result is False: return False stack_value.append(result) else: stack_value.append(Fraction(item)) # 處理數值 return stack_value[0] ```計算表達式結果并寫入文件
點擊展開代碼
```python def expression_result(self, exp_list): if os.path.exists('Answer.txt'): with open('Answer.txt', 'r+') as file: file.truncate(0) for i, exp in enumerate(exp_list): suffixExpression = SuffixExpression(exp) exp_value = str(suffixExpression.suffixToValue()) + '\n' result = "Answer" + str(i + 1) + ': ' + exp_value with open('Answer.txt', 'a+', encoding='utf-8') as f: f.write(result) ```運行結果
在終端輸入:python main.py -n 10 -r 10
在Exercise.txt中生成隨機的十道題目

在Answer.txt中生成題目對應的標準答案

將Exercise.txt中的題目復制到exercisefile.txt文件中,將做題答案寫入answerfile.txt中

(此處故意將第2, 7, 9題寫錯)
之后再在終端中輸入:python main.py -n 10 -r 10 -e exercisefile.txt -a answerfile.txt
在生成10道隨機的題目,并且核對剛才十道題目的答案
結果如下:
項目小結
本次結對編程項目的目標是設計并實現一個小學四則運算題目自動生成器,包含生成題目、計算答案以及核對答案等功能。我們通過 Python 語言開發,并分工合作,共同推進項目的完成。整體項目涉及表達式生成、重復性檢查、后綴表達式計算等多個模塊的開發與集成。
我們在項目初期對模塊進行了合理的分工,每人負責特定模塊,并在關鍵點進行溝通。這樣既提高了效率,也確保了每個模塊的獨立性和完整性。
代碼規范與測試:在編寫代碼時,我們遵循了良好的代碼規范,每個模塊在編寫完成后都進行了單獨的測試,確保其功能的正確性和穩定性。這使得項目的集成過程相對順利。
在項目開發中遇到的復雜問題,如重復表達式的檢測、分數運算的處理等,我們通過頻繁的討論和及時的反饋解決了多個難題。
經驗與教訓
在項目進行過程中,我們發現一些初期未考慮到的需求(如分數的帶括號計算等),導致我們需要臨時調整部分模塊的實現。在這方面,我們學到了在項目初期詳細梳理需求的重要性。

浙公網安備 33010602011771號