20190919-6 四则运算试题生成,结对

此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/7631

结对贺敬文同学:https://www.cnblogs.com/hejw031/

一、题目要求

功能1. 四则运算

   支持出题4个数的四则运算题目,所有题目要求作者有能力正确回答 (提示:1/3 != 0.33333333333333333333333333333333,而是无限长)。

功能2. 在功能1的基础上增加括号运算

功能3. 限定题目数量,"精美"打印输出,避免重复

功能4. 支持分数出题和运算

二、运行效果

功能1与功能2一起编码实现

 截图如下:

 

 功能3截图如下:

三、代码分析

编码语言使用python语言,为方便计算题目,随机生成的100以内的算式。

 1.随机生成题目的相关问题

功能一通过用函数random随机生成数字的范围0-100和运算符的数量,随机生成三个及以内的四则运算符。

功能二在给四则运算添加括号的过程中,列举出了括号添加的位置,然后根据函数random随机添加某一种带括号的情况。

添加括号对我们来说是有困难的,在此体会到了编程思想的灵活性,这一条路走不通的情况下,不妨换换思考问题的角度。

相关代码如下:

def create_equation():      # 随机生成算式
    eq = []
    for i in range(3):
        eq.append(random.randint(0, 10))
        eq.append(operator[random.randint(0, 3)])
    eq.append(random.randint(0, 100))
    p = random.randint(1, 5)
    if p is 1:
        eq.insert(0, "(")
        eq.insert(4, ")")
    elif p is 2:
        eq.insert(0, "(")
        eq.insert(6, ")")
    elif p is 3:
        eq.insert(2, "(")
        eq.insert(6, ")")
    elif p is 4:
        eq.insert(2, "(")
        eq.append(")")
    elif p is 5:
        eq.insert(4, "(")
        eq.append(")")
    return eq

2.逆波兰表达式的相关问题

  听到逆波兰表达式有些陌生,在网上查阅后知道逆波兰表达式就是后缀表达式。程序首先随机生成四则运算题目,之后再将题目转成后缀表达式,题目转化为计算表达式的值,需要用到数据结构中的中缀表达式与后缀表达式的转换,其转换过程用到运算符优先级大小的比较。在这里又复习了表达式转换和栈的相关知识。

def reverse_polish(equation):       # 将算式转换为逆波兰表达式
    result = []
    c = []
    slist = [i for i in equation]

    for item in slist:
        if item in range(0, 100):
            result.append(item)
        elif not c and item in cal.keys():
            c.append(item)
            continue
        elif c and item in cal.keys():
            for x in range(c.__len__()):
                z = c[-1]
                temp = cal[z] if z in cal else cal1[z]
                if temp >= cal[item]:
                    result.append(c.pop())
                else:
                    c.append(item)
                    break
            if not c:
                c.append(item)
        elif item is ")":
            for x in range(c.__len__()):
                if c[-1] == "(":
                    c.pop()
                    break
                else:
                    result.append(c.pop())
        elif item is "(":
            c.append(item)
        # print(result,c)
    for x in range(c.__len__()):
        result.append(c.pop())
    return result

3.栈的相关问题

在定义栈的时候出现问题,在网上查阅相关资料后,理解不是很透,因此使用了栈的模板进行改写

class PyStack(object):      #自定义栈

    def __init__(self, initSize = 20, incSize = 10):
        self.initSize = incSize
        self.incSize = incSize
        self.stackList = []
        self.top = self.bottom = 0

    def push(self, ele):
        if self.top-self.bottom >= self.initSize:
            self.incSize += self.initSize
        self.stackList.append(ele)
        self.top += 1

    def pop(self):
        if self.top-self.bottom > 0:
            self.top -= 1
            ret = self.stackList.pop()
            return ret
        else:
            return None

    def len(self):
        return self.top-self.bottom

四、功能四支持分数出题和运算

  在做完以上三项功能后又尝试了功能四的计算。

  通过random.randint(a, b)函数,随机生成四个数字,数字随机生成之后,就需要生成运算符,通过调用random.choice()函数,random.choice从序列中获取一个随机字符。其函数原型为:random.choice(sequence),参数sequence表示一个有序类型。通过random.choice()函数,随机生成运算符,并将运算符赋值到变量a中,接下来需要生成运算式,并将计算结果暂时赋值在变量faker中:然后手动输入计算的结果,此时已经接收到计算结果,最后一步就是进行判断对错。如果正确则将正确的个数存在变量temp中,进行自增,无论结果对错,变量i作为存储题目总数的变量都进行自增运算。最后输出对的个数和总题数。

部分代码如下:

while i < n:

    first_num=random.randint(1,10)
    second_num=random.randint(1,100)
    third_num=random.randint(1,100)
    fourth_num=random.randint(1,100)
    a = random.choice("+-*/")
    if second_num==1:
        x=first_num
    else:
        x=fractions.Fraction(first_num,second_num)  #第一个数是分子、第二个是分母
    if fourth_num==1:
        y=second_num
    else:
        assert isinstance(fourth_num, object)
        y=fractions.Fraction(second_num,fourth_num)

运行效果截图:

 

四、结对编程体会

  这次结对编程对我的体会很深。首先两个人在一起发挥出双剑合璧的威力,俗话说”三个臭皮匠,胜过一个诸葛亮”,大家在做同一件事时,集思广义发挥各自优点,可以使我分析更能切中要害。其次相互监督,不间断的代码复查可以提高代码质量,相互督促可以使我们都能集中精力,更加认真的工作,我们对题目的理解深度相差无几,设计在我们共同讨论中产生,这样我们在进行代码复查的时候比起传统的方式就会更有效。任何一段代码都至少被两双眼睛看过,两个脑袋思考过,代码的质量会得到有效提高。同时,我们也能相互学习对方的技能,提高自己的知识水平。当然,结对编程也有缺点,两个人在一起也需要磨合时间,沟通个自己意见也需要时间。

五、编码、争论、复审等活动中花费时间较长,较大收获的事件

1.开始我们对于用哪种语言也产生了分歧,讨论过后选择C语言,然后感觉C语言代码太复杂,最后放弃C语言选择了python。

2.讨论如何添加括号及随机函数的使用方法。

3.对于栈和后缀表达式的问题有了进一步的了解。

4.如何把题目打印出来,讨论实现功能三批量生成试题写入文件的方法。

5.两个人的编程代码风格有所不同,在变量命名、代码缩进时沟通不够,因此花了许多时间去适应对方。

六、给出照片1张,包括结对的2位同学、工作地点、计算机,可选项包括其他能表达结对编程工作经历的物品或场景

地点:冬华公寓B-608

计算机:贺敬文同学计算机

七、使用coding.net做版本控制

 git地址:https://e.coding.net/wangzw877/sizeyunsuan.git

原文地址:https://www.cnblogs.com/wangzw822/p/11572252.html