软件工程(2019)第五次作业

四则运算生成器


ProjectAddress(含有可执行文件)

 
小学四则运算自动生成程序,要求:

  • 能够自动生成四则运算练习题
  • 可以定制题目数量
  • 用户可以选择运算符
  • 用户设置最大数(如十以内、百以内等)
  • 用户选择是否有括号、是否有小数
  • 用户选择输出方式(如输出到文件、打印机等)
  • 最好能提供图形用户界面(根据自己能力选做,以完成上述功能为主)

任务分工

 

  • 驾驶员:张家铭(负责代码的编写)
  • 领航员:张天翊(负责调试以及测试)

项目结果

 这里率先给出成品结果图。
 如下图所示,展示了界面的功能分布。



 如下图所示,这里运行了一个样例。

  1. 数值范围 :0~100
  2. 需要生成所有算符,包括小数
  3. 产生10道题
  4. 需要生成题目和答案文件
  5. 每个算式数字个数为2



     如下图所示,表示了习题样例。



     如下图所示,表示了答案样例。

算法细节

0.项目结构

  1. 如何计算表达式

 使用Python内置的eval(),其用来执行一个字符串表达式,并返回表达式的值。

2.算法流程图

 绘制的算法流程图如下:

3.函数模块

  • Moulde List
    • returnDotNumber()
    • check()
    • generateEquationDueToBracket()
    • generateEquation()
    • draw()
  • returnDotNumber()
     该函数完成的功能是生成整数或者按照一定概率生成小数。

    def returnDotNumber():
       global percentOfDot
       percentOfDot = round(random.uniform(0, 1), 2)
       # percentOfDot = 1
       if typeString[-1] == '1':
           n = int(percentOfDot * 100)
           l = n * "0"
           l += (100 - n) * '1'
           s = list(l)
           random.shuffle(s)
           s = ''.join(s)
           if s[random.randint(0, 99)] == '1':
               return 1
           else:
               return 0
       else:
           return 1
  • checkI()
     该函数完成的功能是判断值是否小于零以及是否有除以零的错误。
   def check(string, KEY):
       """
       :param string:
       :return:
       """
       global answerOfquestion, indexOfQuestion
       try:
           answerOfEval = eval(string)
           if answerOfEval < 0:
               return False
           if KEY == 1:
               answerOfquestion += "{0:>5s}{1:<.2f}\n".format(str(
                   indexOfQuestion) + '. ', round(eval(string), 2))
               indexOfQuestion += 1
               # print('answerOfquestion:',answerOfquestion)
               return True
           if KEY == 2:
               return True
       except ZeroDivisionError:
           return False
  • generateEquation()
     该函数是按照要求生成表达式。
    def generateEquation():
       """
       :return:
       """
       global questionString, theNumberOfquestion, rawEquation
   
       specialFunctionList = []
       if typeString[0] == '1':
           specialFunctionList.append('+')
       if typeString[1] == '1':
           specialFunctionList.append('-')
       if typeString[2] == '1':
           specialFunctionList.append('*')
       if typeString[3] == '1':
           specialFunctionList.append('/')
       if typeString[4] == '1':
           specialFunctionList.append('()')
       if typeString[5] == '1':
           specialFunctionList.append('.')
       # print('specialFunctionList:', specialFunctionList)
       i = 0
       key = 0
       while i < theNumberOfquestion + key:
           equationStirng = ''
           if returnDotNumber() == 1:
               equationStirng += str(random.randint(MINMUM, MAXMUM))
           else:
               dotNum = random.uniform(MINMUM, MAXMUM)
               dotNum = round(dotNum, 2)
               equationStirng += str(dotNum)
           j = 0
           tempKey = 0
           while j < numberOfTerms - 1 + tempKey:
               tempString = random.choice(['+', '-', '*', '/', '.', '()'])
               if tempString in specialFunctionList:
                   if tempString == "()":
                       specialList_copy = copy.deepcopy(specialFunctionList)
                       if '()' in specialFunctionList:
                           specialList_copy.remove('()')
                       if '.' in specialFunctionList:
                           specialList_copy.remove('.')
                       equationStirng_temp = random.choice(
                           specialList_copy)
                       equationStirng += equationStirng_temp
                       equationStirng += '('
                       equationStirng += generateEquationDueToBracket(
                           specialFunctionList,random.randint(2,numberOfTerms))
                       equationStirng += ')'
                   elif tempString == '+':
                       equationStirng += '+'
                       equationStirng += str(random.randint(MINMUM, MAXMUM))
                   elif tempString == '-':
                       equationStirng += '-'
                       equationStirng += str(random.randint(MINMUM, MAXMUM))
                   elif tempString == '*':
                       equationStirng += '*'
                       equationStirng += str(random.randint(MINMUM, MAXMUM))
                   elif tempString == '/':
                       equationStirng += '/'
                       equationStirng_temp = str(random.randint(MINMUM, MAXMUM))
                       if equationStirng_temp == '0':
                           tempList = [i for i in range(MINMUM, MAXMUM)]
                           tempList.remove(0)
                           equationStirng += str(random.choice(tempList))
                       else:
                           equationStirng += equationStirng_temp
                   elif tempString == '.':
                       if returnDotNumber() == 1:
                           specialFunctionList_copy = copy.deepcopy(
                               specialFunctionList)
                           if '()' in specialFunctionList_copy:
                               specialFunctionList_copy.remove('()')
                           if '.' in specialFunctionList_copy:
                               specialFunctionList_copy.remove('.')
                           equationStirng_temp = random.choice(
                               specialFunctionList_copy)
                           if equationStirng_temp == '/':
                               equationStirng += '/'
                               equationStirng_temp = str(
                                   random.randint(MINMUM, MAXMUM))
                               if equationStirng_temp == '0':
                                   tempList = [i for i in range(MINMUM, MAXMUM)]
                                   tempList.remove(0)
                                   equationStirng += str(random.choice(tempList))
                               else:
                                   equationStirng += equationStirng_temp
                           else:
                               equationStirng += equationStirng_temp
                               equationStirng += str(
                                   round(random.randint(MINMUM, MAXMUM)))
   
                       else:
                           specialFunctionList_copy = copy.deepcopy(
                               specialFunctionList)
                           if '()' in specialFunctionList_copy:
                               specialFunctionList_copy.remove('()')
                           if '.' in specialFunctionList_copy:
                               specialFunctionList_copy.remove('.')
                           equationStirng_temp = random.choice(
                               specialFunctionList_copy)
                           if equationStirng_temp == '/':
                               equationStirng += '/'
                               equationNum_temp = round(random.uniform(
                                   MINMUM, MAXMUM), 2)
                               if equationNum_temp == 0:
                                   tempList = [i for i in range(MINMUM, MAXMUM)]
                                   tempList.remove(0)
                                   equationStirng += str(random.choice(tempList))
                               else:
                                   equationStirng += str(equationNum_temp)
                           else:
                               equationStirng += equationStirng_temp
                               equationStirng += str(
                                   round(random.uniform(MINMUM, MAXMUM), 2))
               else:
                   tempKey += 1
               j += 1
           if check(equationStirng, 1) == False:
               key += 1
           else:
               rawEquation += "#" + str(indexOfQuestion - 1) + '. '
               equationStirng += '=\n'
               rawEquation += equationStirng
           i += 1
       questionString = rawEquation
       # print(questionString)

4.总结

 整个项目下来,用了三个晚上就把基本功能都实现了出来,这首先要依靠自己对于工具的熟悉程度,其次还要感谢软件工程带给自己的编辑软件的思想,诸如驼峰式变量名称,基于测试的开发方法等等,也是由于软件工程课程的学习,让我渐渐明白了了测试框架的重要性。总之,在做自己喜欢的事情的时候,真的是可以干得又快又满足
 先来说说自己对于这次项目的感悟以及收获。1.Python很强大。这门语言可以快速地实现你想要的功能,让你能够全身心地投入到结构与逻辑设计中,就比如这次需要使用到字符串表达式,使用Python提供的内置函数eval()可以很方便地计算,这使得工作负担一下子就减轻了。2.界面的设计。这次使用tkinter设计界面,用到了复合选项,带有滚动条的文本框和按钮不可见等以前没有用到的新功能,之所以有了以前的基础,这次才能够很快速的开发出demo。3.关于括号的处理。关于括号,这是一个当时没有一个很好解决办法的需求,足足在第二个版本中才添加上,但是目前觉得自己的解决办法也不是很完美,自己单独列写了一个几乎和gengerate()一样的函数,当需要在括号中生成算式时,就调用新写的函数即可,这未尝不是一种处理办法,但是不够优雅!
 再来说所自己的领航员。作为领航员这个角色,他的目的是为了辅助驾驶员完成编码工作,并且进行代码测试以及样例覆盖。由于天翊才学Python编程不久,所以,在一起合作时并没有充分感觉到结对编程的快乐,通常需要一边编写代码,一边给他讲述我在干什么,导致效率发生了下降。但是,他还是很耐心地在一步步跟着我做,最后也能出色地完成代码的测试工作,做好领航员的角色。

5.彩蛋

 就在我把软件打包完毕后,发送给家里当老师的小舅妈看的时候,运行时报了错误,说是操作系统位数出了问题,我才发现,原来电脑本身是32位的WIN7系统,而我的打包文件是64位的,32位机不支持64位应用,结果,我又在同学的电脑上配置好了32位python环境,然后再次打包,最终才好使。
 下面这个是我的设计草稿:

6.合作过程

参考资料##

posted @ 2019-04-28 21:10  张家铭  阅读(479)  评论(0编辑  收藏  举报