首页 > 其他 > 详细

中小学数学卷子自动生成程序——与Creddit同学的结对编程项目分析

时间:2019-09-19 19:16:35      阅读:89      评论:0      收藏:0      [点我收藏+]

1.简单介绍


项目名称:中小学数学卷子自动生成程序

主要功能:a.登陆

                     通过命令行输入账号和密码进行登陆,成功后出现提示

                     否则需要重新输入

                  b.切换难度

                     可以输入“切换为XX”,修改生成题目的类型,如小学,初中,高中,不符合要求时提示重新输入

                  c.随机生成试卷

                     根据提示,输入数字,可以随机生成需要的数量的题目,题目难度默认为账户类型,亦可输入切换;

                     生成的试卷以txt格式和固定格式的文件名保存在特定的目录下;

                     新生成的题目不能与同文件夹下的题目重复。

                 D.附录

                     小学、初中、高中题目难度要求

 

小学

初中

高中

 

难度要求

+,-,*./

平方,开根号

sin,cos,tan

 

备注

只能有+,-,*./和()

题目中至少有一个平方或开根号的运算符

题目中至少有一个sin,cos或tan的运算符

 

 

2.开发环境

                  Windows10 python3.7

 

3.思路结构

                 由于老师提供的说明文档中已经对项目的要求介绍的非常详细。正常的一个思路就是将程序分为几个模块,包括:登陆,切换,生成等。

                 我的队友也不例外,他的python源代码中,除了主函数外,分为了Validlogin(), response_login(), paper_generating() 三个部分,从函数名就可以知道,我的队友想法相同。

                  那么我们就接下来就从这三个部分入手。

 

4.关键部分介绍

A.Validlogin() (登陆部分)

 

 1 def Validlogin():
 2     global user_id,level
 3     print(输入用户名和密码,两者之间用空格隔开)
 4     try:
 5         f=open("USER_IDlist.txt","r",encoding="utf-8")
 6         userlist=f.read().split(\n)
 7         login_flag=False
 8         while True:
 9             user_login=input().split( )
10             while len(user_login)!=2:
11                 user_login=input("请输入正确的用户名、密码:").split( )
12             id=user_login[0]
13             psd=user_login[1]
14             for i in range(len(userlist)):
15                 str=userlist[i].split()
16                 if str[0].lstrip("username:")==id and str[1].lstrip("password:")== psd:
17                     level=str[2].lstrip("level:")
18                     user_id=id
19                     login_flag=True
20             if login_flag:
21                 print("登陆成功!\n当前选择为{}出题".format(level))
22                 break
23             else: print("请输入正确的用户名、密码! ")
24     except Exception as error:
25         print(error)

 

            全局变量 user_id, level 分别代表登陆的账户的用户名和生成试卷难度

            由于读取文件可能会产生异常,用try/except控制。

            队友将文档提供的账户和密码保存为 文件USER_IDlist.txt中,每次登陆前先进行读取。

 

            接下里是一个while循环配合flag标志判断输入的账号名和密码是否正确。

            这一部分的逻辑比较简单,直接遍历预设的账户,判断是否符合。

 

B.reponse_login()

def response_login():
    try:
        while True:
            global level,num
            str=input(准备生成{}数学题目,请输入生成题目数量,大小范围在(含)10-30以内:.format(level))
            result = re.match(r切换为(.+), str)
            if  str.isdigit() :
                if int(str)<10 or int(str)>30:
                    print("输入范围不符合要求!")
                    continue
                else:
                    num=int(str)
                    break
            elif result:
                if(result.group(1)==小学 or result.group(1)==初中 or result.group(1)==高中):
                    level=result.group(1)
                    print("切换成功!")
                    continue
                else:
                    print("请输入小学,初中,高中三个选项中的一个!")
                    continue
            elif not result:
                try:
                    if int(str)==-1:
                        print("即将重新登陆!")
                        Validlogin()
                    else:print("请输入正确的命令!")
                except:
                    print("请输入正确的命令!")

    except Exception as error:
        print(error)

 

           第二部分是选择部分 。这部分有两个功能:切换难度和输入题号,因此需要判断输入的字符串是题数或是切换难度的关键词。

           输入后,使用match()判断是否匹配关键字,使用isdigit()判断是否是数字。

           当输入为切换难度时,判断难度类型是否符合,若符合,用全局变量level提取。

           当不是输入数字时,可以一直切换难度,所以整体是在while循环中。

           使用全局变量num,将输入的题号提取。

 

c.paper_generating()

def paper_generating():
    global level,num
    content = ‘‘
    pre_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
    pre_path = os.getcwd()
    targetpath = pre_path + / + user_id+/+level
    ques_set = set()
    if not os.path.exists(targetpath):
        os.makedirs(targetpath)
    files = os.listdir(targetpath)
    for file in files:
        text_path = targetpath + / + file
        text = open(text_path, r,encoding=utf-8)
        content += text.read()
    for j in range(num):
        question=[]
        operater_num = random.randint(1, 5)
        k = operater_num - 2
        if operater_num < 2:
            k = 0
        bracket_num = random.randint(0, k)
        for i in range(operater_num+1):
            question.append(str(random.randint(MIN_N,MAX_N)))
            question.append(Arithmetic_operator[random.randint(0,3)])
        question.append(str(random.randint(MIN_N,MAX_N)))
        ins=[2*i for i in range(operater_num+1)]
        if level==初中:
            add_num=random.randint(1,2)
            for i in range(add_num):
                if(random.randint(0,1)==1):
                    question[ins[random.randint(0,operater_num)]] = ps_operator[0] + question[ins[i]]
                else:
                    question[ins[random.randint(0,operater_num)]] =question[ins[i]]+ps_operator[1]
        if level==高中:
            add_num_1 = random.randint(0, 1)
            add_num_2=random.randint(1,2)
            for i in range(add_num_1):
                if(random.randint(0,1)==1):
                    question[ins[random.randint(0,operater_num)]] = ps_operator[0] + question[ins[i]]
                else:
                    question[ins[random.randint(0,operater_num)]] =question[ins[i]]+ps_operator[1]
            for i in range(add_num_2):
                k=random.randint(0,2)
                question[ins[random.randint(0,operater_num)]] =Trigonometric_operator[k] +"("+ question[ins[i]]+")"
        for i in range(bracket_num):
            question[ins[i]]=(+question[ins[i]]
            t=random.randint(1,2)
            question[ins[i+t]] = question[ins[i+t]]+)
        for i in range(len(question)):
            if re.match(r\([0-9]+\), question[i]):
                if not (re.match(rsin\([0-9]+\), question[i]) or re.match(rcos\([0-9]+\), question[i]) or re.match(
                        rtan\([0-9]+\), question[i])):
                    question[i] = str(random.randint(1, 100))
        ques = ‘‘.join(question)
        ques_set.add(ques)
        if ques in content or len(ques_set) == j:
            j -= 1
            continue
        f = open(targetpath + / + pre_time + .txt, a,encoding=utf-8)
        f.write(( + str(j + 1) + )  + ques + " = ?" + \n+\n)
    print("出题成功!",end=‘‘)

 

          第三部分是生成题目保存到文件。

          生成文件部分比较常规,利用time的函数,直接生成以时间命名的文件,并根据当前路径进行存放。

          读取旧文件,先将所有字符保存到一个字符串content中。

          然后根据难度随机生成题目。

          生成题目分为三步基本以random为核心。

          先随机生成不定数量不定值的操作数;然后根据不同难度会用到不同的符号,采用全局变量的数组控制;在随机生成一些括号加入到式子中。

          生成后的式子到content中进行比较,如果能在content找到则说明重复,则重新生成。

 

 5.结果展示

技术分享图片

 

 

总结:

         队友采用python进行开发,而我采用了Java语音。两份项目很大的差异也是由开发环境不同导致的。自己完成工程后,再学习别人的代码,体验非常新鲜有趣。

         

优点:

         与Java相比,python更加简单简洁,虽然Java也有很多好用的包、工具,但是使用起来也不方便,无论是配置环境的导入或是在代码上的实现,比起python还是麻烦太多。
         并且Java类似c、c++的语法,加上面向对象的代码风格,在编写这种简单的项目代码量会增加很多。

缺点:

        虽然队友的逻辑和实现都没有什么问题,但是由于空行分段比较少,看起来比较密集,寻找代码中的细节没有那么容易。

中小学数学卷子自动生成程序——与Creddit同学的结对编程项目分析

原文:https://www.cnblogs.com/One-Random/p/11551526.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!