• 20200924-5 四则运算试题生成,结对


    此作业的要求参见:https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11245

    结对伙伴:宫立秋

    github中代码地址:https://github.com/amancer34/calculate.git

    一、功能1 四则运算

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

    重点:要随机生成一个四则运算表达式,由作者从控制台输入答案,并判断答案是否与系统给出答案一致。

    难点:判断作者输入的答案与系统给出的答案是否相等时,还要考虑结果是负数的情况,我们一开始没有考虑到,导致输入的负号程序接收不到,程序运行结果不对。

    编程收获:

    1、random.randint(a,b)函数中随机数是可以取到b的。

    2、eval()函数可以用来执行一个字符串表达式,并返回表达式的值。

    运行截图:

     补充截图:

    主要代码:

    #产生四则运算表达式
    def ques():
        operators = ['+','-','*','/']
        #随机产生运算符
        i1 = random.randint(0,3)
        i2 = random.randint(0,3)
        i3 = random.randint(0,3)
        #随机产生四个数
        number1 = random.randint(1,10)
        number2 = random.randint(1,10)
        number3 = random.randint(1,10)
        number4 = random.randint(1,10)
        ques = str(number1) + operators[i1] + str(number2) + operators[i2] + str(number3) + operators[i3] + str(number4)
        print(ques)
        return ques
        
    #判断输入的数据是否正确
    def result():
        total = 0
        for i in range(20):
            question = ques()
            res = eval(question)
            ans = input("? ")
            if str(res) == str(ans):
                print("答对啦,你真是个天才!")
                total += 1
            else:
                print("再想想吧,答案似乎是%f" %res)
        print("一共答对" + str(total) + "道题," + "共20道题!")
                
    if __name__ == "__main__":
        #创建对象
        parser = argparse.ArgumentParser()
        #添加参数-c
        parser.add_argument("-c","--cin")
        #解析添加的参数
        args = parser.parse_args()
    if args.cin == None: result()

    功能2 支持括号

    重点: 随机生成括号,并添加在功能1中生成的四则运算表达式的所有可能位置。

    难点:考虑到括号可能在表达式中出现的所有位置,以及左括号出现后与之所匹配的右括号可能出现的位置。

    编程收获:

    随机生成括号时也要加if判断确保左括号与右括号是相匹配的,如果只靠random函数随机生成,可能导致左右括号不匹配,使得运算结果不正确。

    运行截图:

    补充截图:

    主要代码: 

    #产生四则运算表达式
    def ques():
        brackets = ['(','',')']
        operators = ['+','-','*','/']
        #随机产生运算符
        i1 = random.randint(0,2)
        i2 = random.randint(0,3)
        i3 = random.randint(0,3)
        #随机产生四个数
        number1 = random.uniform(0,1)
        number1 = Fraction(number1).limit_denominator(10)
        number2 = random.uniform(0,1)
        number2 = Fraction(number2).limit_denominator(10)
        number3 = random.randint(1,10)
        number4 = random.randint(1,10)
        #随机产生左括号
        left1 = random.randint(0,1)
        left2 = random.randint(0,1)
        left3 = random.randint(0,1)
        #随机产生右括号
        right1 = random.randint(1,2)
        right2 = random.randint(1,2)
        right3 = random.randint(1,2)
        #括号匹配
        if left1 == 0:
            left2 = 1
            left3 = 1
            if right1 == 2:
                right2 = 1
                right3 = 1
            else:
                right2 = 2
                right3 = 1
        else:
            if left2 == 0:
                left3 = 1
                right1 = 1
                if right2 == 2:
                    right3 = 1
                else:
                    right3 = 2
            else:
                left3 = 0
                right1 = 1
                right2 = 1
                right3 = 2
        ques = brackets[left1] + str(number1) + operators[i1] + brackets[left2] + str(number2)
        ques += brackets[right1] + operators[i2] + brackets[left3] + str(number3) + brackets[right2]
        ques += operators[i3] + str(number4) + brackets[right3]
        ques = str(ques)
        return ques

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

    重点:由作者输入题目数量,程序生成相应数量的四则运算表达式,并将运算结果与题目对齐输出在屏幕及文件右边。

    难点:在控制台输入题目数量时要用到argparse模块,通过其中的add_argument()函数将“-c”这个参数添加到命令行,否则会报错。

    编程收获:

    1、将表达式加等号后要将其赋给一个新的变量,加上等号后的字符串用eval()函数不能返回正确结果。

    2、可以用isdigit()函数判断输入的是否为整数

    3、用format()函数可以格式化输出,将运算结果输出在右端。

    运行截图:

    主要代码:

    #命令行输入题目数目
    def command_input(num):
        data = open('data.txt','w+')
        if num.isdigit():
            for i in range(int(num)):
                question = ques()
                question1 = question + '='
                res = Fraction(eval(question)).limit_denominator(100000)
                print('{:<50}{:<25}'.format(question1,str(res)))
                print('{:<50}{:<25}'.format(question1,str(res)),file = data)
        else:
            print("题目数量必须是正整数。")

    if __name__ == "__main__": #创建对象 parser = argparse.ArgumentParser() #添加参数-c parser.add_argument("-c","--cin") #解析添加的参数 args = parser.parse_args() if args.cin == None: result() else: command_input(args.cin)

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

    重点:将运算结果表示为一个分数,并约分。

    难点:在得到运算结果后要分成分子、分母两个部分进行保存,同时对其进行输出时,要转换成十进制形式输出,如果直接输出会得到错误的结果。

    编程收获:

    1、将一个假分数转化为一个带分数的形式时使用“//”可以直接得到整数部分。

    2、random.uniform(a,b)随机生成的实数范围是[a,b],random.random()函数的下限才无法取到。

    3、Fraction()函数可以将随机生成的小数转化为分数,并对其进行自动约分。

    4、limit_denominator(max_denominator)用于返回一个分母不大于max_denominator且最接近原值的分数,避免浮点数和有理数转化失真。

    运行截图:

    补充截图:

    主要代码:

    #将分子分母转换为十进制数
    def take_decimalism(dicts = {}):
        j= len(dicts)-1
        sum1 = 0
        for i in range(0,len(dicts)):
            if j < 0:
                break
            sum1 = int(dicts[j]) * int(math.pow(10,i)) + sum1
            j = j-1
        return sum1        
        
    #遍历结果,将分子、分母存储到两个字典中并约分
    def traversal_dist(res):
        d1={}
        d2={}
        count1=0
        count2=0
        flag=0
        sign=0
        for i in res:
            if i=='-':
                sign=i
                continue
            if i=='/':
                flag=1
                continue
            if flag==0:
                d1[count1]=i
                count1=count1+1
            else:
                d2[count2]=i
                count2=count2+1
        #分子
        numerator = take_decimalism(d1)
        #分母
        denominator = take_decimalism(d2)
        if denominator == 0:
            return numerator
        else:
            w1=numerator // denominator
            w2=numerator % denominator
            answer=0
            if sign=='-':
                if w1==0:
                    answer=sign+str(w2)+"/"+str(denominator)
                else:
                    answer=sign+str(w1)+" " +str(numerator)+"/"+str(denominator)
            else:
                if w1==0:
                    answer=str(w2)+"/"+str(denominator)
                else:
                    answer=str(w1)+" " +str(numerator)+"/"+str(denominator)
            return answer

    二、结对编程体会:

    1、能更快的解决问题。一个人编程时,如果遇到某些问题,需要反复琢磨,但是结对编程可以互相交流对问题的想法,能更快找到一个解决办法。

    2、能更快的通过测试。测试时可能会有一些错误,自己挑错可能会有些费力,让对方给自己挑错,能更快找到出错的地方并修改,从而更快的通过测试。

    3、有时编程会感到枯燥,但结对编程会相对减少枯燥感。

    当然在编程时有时会因想法不同而产生一些争议,但我认为能更好的提高效率,优点是大于缺点的。

    三、至少5项在编码、争论、复审等活动中花费时间较长,收获较大的事件:

    1、在功能1中我们因为将用eval()函数返回的结果转化为了int及float导致对于负数的负号接收不到,运行结果不对。

    2、在功能2中只随机生成了括号没用if判断做括号的匹配,导致括号不对,生成的表达式也不对,一直出错。

    3、在功能3中因在生成的表达式中又添加了“=”,用eval()函数无法得到结果,需要将新的字符串重新赋给一个变量,再将原有的式子用eval()函数得到结果。

    4、在功能4中需要将运算结果中的分子、分母分别遍历存储最后再转化为十进制输出。

    5、在功能4中分子、分母转化为十进制时从列表或字典中取得第一个数是个位的数,也是最小的数,转化为十进制要乘10的0次方,我们在做的时候将顺序弄反,导致结果不对;输出时还要考虑到有负号和没负号两种情况。

    四、结对编程截图:

  • 相关阅读:
    glog下载、安装、使用
    VS所需插件
    Qt 实现动态调整流程指令顺序(通过鼠标事件实现)
    QComboBox实现复选框功能
    QString string char* int互相转化
    Qt 滚动区域显示下拉框
    模式对话框,非模式对话框,reject和accept()槽函数确定对话框的返回值
    QT递归搜索文件(entryList)
    QT中foreach的使用
    Qstring格式化字符串
  • 原文地址:https://www.cnblogs.com/amancer1151/p/13733863.html
Copyright © 2020-2023  润新知