个人作业1——四则运算题目生成程序(基于控制台)

一、题目描述:
1. 使用 -n 参数控制生成题目的个数,例如
       Myapp.exe -n 10 -o Exercise.txt
       将生成10个题目。
2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如 
       Myapp.exe -r 10
       将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
3. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数
4. 每道题目中出现的运算符个数不超过3个。
5. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。
生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:
     1. 四则运算题目1
     2. 四则运算题目2
          ……
 
     其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。
6. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:
       1. 答案1
       2. 答案2
 
特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。
7. 程序应能支持一万道题目的生成。
8. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,并会输出所有题目中重复的题目,输入参数如下:
     Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt -o Grade.txt
 
        统计结果输出到文件Grade.txt,格式如下:
 
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
Repeat:2
RepeatDetail:
(1)   2,45+32  Repeat 3,32+45                    
(2)   5,3+(2+1)  Repeat 7,1+2+3
 
解释:
Correct: 5 ----5道题目正确,正确的题号 1,3,5,7,9
Wrong:5 -----5道题目错误,错误的题号 2,4,6,8,10
Repeat:2   2---组题目重复
(1) 第一组 题号2,题目 45+32  与题号3的题目重复,题号3为 32+45
(2)第二组  题号5,题目 3+(2+1) 与题号7的题目重复,题号7为 1+2+3
 
其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。
 
二、功能设计
主要实现以下几个功能:
1.随机生成整数或者分数,随机生成符号,括号,进行拼接,形成等式
2.对所形成的等式进行转换,从中缀表达式转换为后缀表达式
3.对后缀表达式进行计算
4.对等式进行查重
5.对提供的答案文件进行判断,找出错误和正确的题号和数量
6.对上面功能所产生的题目和答案进行写入文件
 
三、设计实现
有以下类
getneed: 获取随机数、随机符号
create: 生成等式
change : 中缀表达式转后缀表达式
compute : 对后缀表达式进行计算
contrast : 对给定的答案文件进行对照
_int_ : 主界面,并对各个类进行整合,实现功能
 
四、代码说明
主要代码有以下:
1.生成等式
 1 def getExample(l):  # 获取表达式
 2     a = getNeed.getNum(l)
 3     for i in range(getNeed.getChNum()):  # 不包括上限
 4         # print(i)
 5         c = getNeed.getSignal()
 6         gl = random.randint(0, 1)
 7         if (gl == 1):
 8             b = getNeed.getNum(l)
 9         else:
10             b = random.randint(1, l)
11             b = "|%d|" % (b)
12         if (gl == 0):
13             a = "%s%s%s" % (b, c, a)
14         else:
15             a = "%s%s%s" % (a, c, b)
16         r = random.randint(0, 3)
17         if (r == 2):
18             a = '(' + a + ')'
19         view = ''.join(re.split('\|', a))
20 
21     return a, view

2.中缀表达式转后缀表达式

 1 def mid_after(equation):  # 中缀转后缀
 2     expression = []
 3     ops = []
 4     i = 0
 5     while (i < len(equation)):
 6         # print(i)
 7         if (equation[i] == '|'):  # 是数字进表达式expression栈
 8             index = equation.find('|', i + 1)  # 在i+1后寻找|
 9             num = equation[i + 1:index]
10             # print(num)
11             expression.append(num)
12             i = index + 1
13         elif (isCh(equation[i])):  # 是运算符进行判断优先级
14             if (ops == []):
15                 ops.append(equation[i])
16                 i += 1
17             else:
18                 if (equation[i] == ')'):  # 遇到右括号,栈内左括号以后的符号出栈
19                     while (equation[i] == ')' and ops[len(ops) - 1] is not '('):
20                         expression.append(ops[len(ops) - 1])
21                         ops.pop()
22                     ops.pop()
23                     i += 1
24                 elif (GetPriority(equation[i], 0) > GetPriority(ops[len(ops) - 1], 1)):  # 优先级大于栈顶符号加入栈
25                     ops.append(equation[i])
26                     i += 1
27                 else:
28                     while (not ops == [] and GetPriority(equation[i], 0) <= GetPriority(ops[len(ops) - 1],
29                                                                                         1)):  # 优先级小于等于 出栈
30                         expression.append(ops[len(ops) - 1])
31                         ops.pop()
32                     ops.append(equation[i])
33                     i += 1
34 
35     while (not ops == []):
36         expression.append(ops[len(ops) - 1])
37         ops.pop()
38     # print(expression)
39     return expression

3. 后缀表达式进行计算

 1 def fourComputer(expression):
 2     st = []  # 数字进栈
 3     i = 0
 4     while (i < len(expression)):
 5         ch = expression[i]
 6         if (not change.isCh(ch)):
 7             st.append(ch)
 8         else:
 9             a = st.pop()  # 栈顶元素弹出
10             b = st.pop()  # 继续弹出
11             if (ch == '+'):
12                 answer = str(Fraction(a) + Fraction(b))
13                 st.append(answer)
14             elif (ch == "-"):
15                 answer = str(Fraction(b) + Fraction(a))
16                 st.append(answer)
17             elif (ch == '*'):
18                 answer = str(Fraction(a) * Fraction(b))
19                 st.append(answer)
20             elif (ch == "÷"):
21                 answer = str(Fraction(b) / Fraction(a))
22                 st.append(answer)
23         i += 1
24     answer = false_true(st.pop())
25     return answer

4.对给定答案文件进行对照

def contrast(path):
    answer = []
    answer1 = []
    with open('answer.txt') as file:
        for line in file:
            answer.append(line)

    with open(path) as file1:
        for line1 in file1:
            answer1.append(line1)
    l = len(answer)  # 正确答案
    l1 = len(answer1)  # 对照答案
    rnum = 0  # 正确数量
    wnum = 0  # 错误数量
    right = []  # 正确题号
    wrong = []  # 错误题号

    if (l > l1):
        for i in range(l1):
            if (answer[i] == answer1[i]):
                rnum += 1
                right.append(i + 1)
            else:
                wnum += 1
                wrong.append(i + 1)
        for j in range(l1, l):
            wnum += 1
            wrong.append(j + 1)
    else:
        for i in range(l):
            if (answer[i] == answer1[i]):
                rnum += 1
                right.append(i + 1)
            else:
                wnum += 1
                wrong.append(i + 1)

    return rnum, wnum, right, wrong

 

五、测试运行

 六、PSD统计:

 

 

 

PSP2.1

Personal Software Process Stages

Time Senior Student

Time

 

Planning

计划

30

20

 

· Estimate

估计这个任务需要多少时间

800

700

 

Development

开发

600

500

 

· Analysis

需求分析 (包括学习新技术)

10

5

 

· Design Spec

生成设计文档

30

40

 

· Design Review

设计复审

10

10

 

· Coding Standard

代码规范

10

10

 

· Design

具体设计

20

15

 

· Coding

具体编码

600

500

 

· Code Review

代码复审

10

10

 

· Test

测试(自我测试,修改代码,提交修改)

20

30

 

Reporting

报告

30

60

 

·

测试报告

10

10

 

·

计算工作量

10

10

 

·

并提出过程改进计划

5

5

 

 

 

 

 

 

 

七、代码地址

https://gitee.com/Zdigi/four_operations/tree/master/calculate

posted on 2018-03-30 19:37  Zdigi  阅读(153)  评论(0编辑  收藏  举报