Python:中小学数学卷子自动生成程序

时间:2024-01-21 18:41:24

项目需要简单总结有以下几点:

  1. 用户登录操作,命令行输入用户名和密码,判断是否有该账户;

  2. 登录状态下,可选择生成题目的数量或者切换年级;

  3. 根据用户对应的小学、初中、高中三个年级生成不同难度的算术题;

  4. 文件输出打印

根据以上四点需求,我的程序设计也对应分为四个模块对应。

  • log_in()  用户登录
  • number_chose() 选择数量\切换年级
  • arithmetic_production() 题目生成
  • file_output() 打印

在登录模块中,把用户数据按照如下格式保存在UserInfomation.txt文件中,并用open以只读的方式打开。

f = open("UserInformation.txt", "r",encoding="utf-8")    

这里注意文件中包含有中文,需要用utf8的编码打开。

username:张三1
password:123
grade:小学

username:张三2
password:123
grade:小学

username:张三3
password:123
grade:小学

username:李四1
password:123
grade:初中

username:李四2
password:123
grade:初中

username:李四3
password:123
grade:初中

username:王五1
password:123
grade:高中

username:王五2
password:123
grade:高中

username:王五3
password:123
grade:高中
UserInformation

 

在等待用户输入打印题目数量或者切换学历时,需要通过正则表达式进行匹配

import re

in_str = input('准备生成{}数学题目,请输入生成题目数量(10-30):'.format(GRADED))

matchNub = re.match(r'\d+',in_str)             #判读输入为纯数字
matchObj = re.match(r'切换为(.*)',in_str)     #判断输入为切换命令

 

在插入括号时,通过取随机数确定要插入括号的个数,括号所以的组合情况与操作数个数有关,满足组合关系,关系如下

brackt_Nub = C(2,operator_Nub)-1

减去一种情况是左右两端数字组合的情况。

PS:这里没有考虑乘除法运算有时候加括号与不加括号运算顺序一样的问题

定义以下列表保存操作数为3-5时括号所有的位置组合情况

BRACKET_SIT = [[0,2],[2,4]  ,[4,6],[0,4],[2,6]  ,[0,6],[2,8],[4,8],[6,8]]      
    bracket_chose = []                                                      #选择加入括号的位置
    for i in range(bracket_nub):
        temp_sit = BRACKET_SIT[random.randint(0,int(termNub*float((termNub-1)/2))-2)]   #根据括号与操作数的组合关系确定选择括号位置的区间
        bracket_flag = 1                                                    #标记括号是否交叉
        for j in bracket_chose:                                             #交叉判定,括号交叉时重新随机
            if j[1]>=temp_sit[0] and j[0]<temp_sit[0] and j[1]<temp_sit[1] or \
                    j[0]<=temp_sit[1] and j[1]>temp_sit[1] and j[0]>temp_sit[0] or\
                    j[0] == temp_sit[0] and j[1] ==temp_sit[1]:
                bracket_flag = 0
        if bracket_flag:
            bracket_chose.append(temp_sit)
        else:
            i -= 1

为了不改变原来列表中操作数与操作符的位置,插入括号时只改变操作数字符串

    for i in bracket_chose:
        outputDate[i[0]] = '(' + outputDate[i[0]]
        outputDate[i[1]] += ')'

 

按照用户名建立文件夹,按照当前时间新建txt文件,追加写入。

def file_output(Equation,tName):                                            #文件输出
    curPath = os.getcwd()                                                   #获得当前文件目录
    targetPath = curPath+os.path.sep+USER                                   #构建绝对地址
    if not os.path.exists(targetPath):                                      #如果不存在,则新建文件夹
        os.makedirs(targetPath)
    f = open(targetPath + '/' + tName +'.txt','a')                          #如果不存在,新建txt问题,且追加写入
    f.write(Equation+'\n\n')

不会百度,反正我是记不住,每次都要问度娘QAQ

 

最后还有一个去重问题,其实按照程序的算法,随机产生的题目相同的概率不到万分之一 ,相当于我抽到SSR的概率,不过,万一哪天我就抽到了不是嘛?

  • 不能生成与用户文件下所有txt文件重复相同的题目
  • 不能生成本次产生题目中重复的题目(用集合)
    q_set = set()                                                           #集合保存生成的问题,用于去重
    history_data = ''                                                       #历史题目
    curPath = os.getcwd()                                                   #获得当前文件目录
    targetPath = curPath+os.path.sep+USER                                   #构建绝对地址
    files = os.listdir(targetPath)                                          #该文件夹下所有文件名
    for f in files:
        txt_path = targetPath + '/' + f
        contents = open(txt_path,'r')
        history_data +=contents.read()
    for i in range(QUESTION_NUB):
        q_Temp = ''.join(arithmetic_production())                           #将列表转换为字符串
        q_set.add(q_Temp)                                                   #加入集合
        if len(q_set) == i or (q_Temp in history_data):                     #判定是否重复,重复则重新生成
            i -= 1
            continue
        file_output('[' + str(i+1)+'] ' + q_Temp , time_name)               #写入文件

 

总结:度过了一个愉快的中秋假期:),今天最后一天爬下床来把作业写了,一共130余行代码(python真香,可惜还是超了100行……)。过了一个暑假后很多东西都忘记了,比如正则、文件流等等,还有加括号的算法也是想了好久(都是泪啊),就当做是复习了。当然,程序本身还存在很多不足,比如没有判定括号加在乘除法上是无意义的问题。也没有判定做除法和开根号和三角运算时是否能正确运算。继续改进的话还可以每次打印题目后给出答案或者支持用户自己输入答案,答完题目后给出得分。最后欢迎评论给出优化意见或者有更简短的代码分享