利用python——从题库得到得到随机试卷

代码思路:

1、读取 txt 文档,文件基本操作

2、遇到了 编码问题

这里用到了Unidode强制编码函数,将其转化为‘utf_8_sig’格式,经过实践证明可以。

这里说一下编码问题,Python2默认编码方式是ANSII码,遇到中文编码问题,网上解决方法如下:

(1) sys 设置 defaultencode,经过测试 python2.7版本不能用,python3.5可用
(2) 即下面代码的方法,强制编码,txt文件可在sublim/notebook转化为utf8编码的方式。

lis = unicode(lis, encoding='utf_8_sig' )
         lis.encode('utf-8') 

3.接下来,查找题目。

为了出题随机,我们随机提取的行数如下,其中line_start[i]为该部分最开始的行数

 p=random.randint(1,50)+line_start[i]

我们暂定为 往下 15行为文本提取的内容。(为什么是15行呢, 因为最长的题目不超过15行)

这里用到了正则表达式,题目的起始符号为 “ 数字+、”。

正则表达式,这里又遇到一个坑,这个坑是什么呢?大家可以试一试,中文的标点符号正则表达匹配不出来

原因是先要把待匹配的转化为utf8字符,再进行匹配,这里"、"这个符号的UTF8编码是u3001,具体代码如下:

这里 ww.S 即 re.S , 因为 我 import re as ww, 至于为什么这样,因为遇到了我也不知道的bug,说 re 不行,那就as W喽。

    lis = unicode(lis, encoding='utf_8_sig' )
      lis.encode('utf-8')
      lis=ww.findall(u"(\d+[\u3001].*?)\d+[\u3001]",lis,ww.S)

这样我们就得到了提取到的题目

4、题目分配算法

接下来,题目有很多部分,那么怎么划分呢?
按照权重来喽,为了确保

5、出题随机算法

为了确保题目覆盖范围,足够随机,可调整。
line_end是 该部分结束的行数,p是当前行数,counts 是总题目数,time_i是当前的题目数
这里的算法思路是,整体均衡,动态调整 。
p为行数,是决定当前题目的。为了随机,我们让p+随机数。

  imp=get_imp(line_end[i],p,counts[i],time_i)
            p=p+imp

为了均衡, imp 数学期望确保 = 总行数/题目数
那么如何动态调整呢,这里用到了梯度下降算法(这就有点装了,其实不过是一阶龙哥库塔,或者泰勒一阶展开,其实就是 y(t+Δt)=y+y(t)’*Δt,很简单。

ans=int((line_end-p)/counts

为了照顾大题少,小题多,大题靠后,这里稍微倾斜了一下。

def get_imp(line_end,p,counts,time_i):
    ans=int((line_end-p)/counts)
    if ans<3:
        ans=2
    if 1.0*time_i/counts<0.75:
        imp=random.randint(1,5*ans-1)
    else:
        imp=random.randint(1,ans-1)
    return imp

6、保存文件

这里使用时间名字进行保存,为了避免重复。

全部代码如下:


#coding=utf8
import random
import re as ww
import sys
import time
def re(lis):
    try:
       # type(lis)
        lis = unicode(lis, encoding='utf_8_sig' )
        lis.encode('utf-8')
        lis=ww.findall(u"(\d+[\u3001].*?)\d+[\u3001]",lis,ww.S)
        if len(lis)==0:
            for y in range(1,85):
                lis=lis+s[p+y]
            lis = unicode(lis, encoding='utf_8_sig' )
            lis.encode('utf-8')
            lis=ww.findall(u"(\d+[\u3001].*?)\d+[\u3001]",lis,ww.S)
            lis = unicode(lis, encoding='utf_8_sig')
        return lis[0]
    except:
        return "You are so fine that I cannot help missing u" 



def search(p):
    m=""
    if 33<p<1271:
        m="第一章 会计管理及反洗钱类 单选题"
    elif 1270<p<2147:
        m="第一章 会计管理及反洗钱类 多选题"
    elif 2146<p<2595:
        m="第一章 会计管理及反洗钱类 判断题"
    elif 2594<p<3086:
        m="第一章 会计管理及反洗钱类 简答题"
    elif 3085<p<3508:
        m="第二章 个人金融类 单选题"
    elif 3507<p<3772:
        m="第二章 个人金融类 多选题"
    elif 3774<p<3881:
        m="第二章 个人金融类 判断题"
    elif 3880<p<3953:
        m="第二章 个人金融类 简答题"
    return m
def get_lines():
    line_num=[3053,872,310,440,635]
    line_start=[0,3085,3952,4262,4701]
    line_end=[3086,3953,4263,4702,5333]
    return line_num,line_start,line_end
def get_count(n1,n2,n3,n4,n5,count):
    counts=[]
    sum_n=n1+n2+n3+n4+n5
    sum_n=sum_n*1.0
    counts.append(count-int(count*n2/sum_n)-int(count*n3/sum_n)-int(count*n4/sum_n)-int(count*n5/sum_n))
    counts.append(int(count*n2/sum_n))
    counts.append(int(count*n3/sum_n))
    counts.append(int(count*n4/sum_n))
    counts.append(int(count*n5/sum_n))
    return counts
def xiaohua():
    lisxiaohua=["Wanna to see U","You Guess~How much I miss U","aasas","I miss U ,like the sea","Sincerely,yours "]
    xhNum=random.randint(0,len(lisxiaohua)-1)
    xiaohua=lisxiaohua[xhNum]+"\n"
    return xiaohua
def get_imp(line_end,p,counts,time_i):
    ans=int((line_end-p)/counts)
    if ans<3:
        ans=2
    if 1.0*time_i/counts<0.75:
        imp=random.randint(1,5*ans-1)
    else:
        imp=random.randint(1,ans-1)
    return imp
def ma(n1,n2,n3,n4,n5,count,part):
    str1=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    str2=str1.replace(':','_')
    str1="测试时间".decode('utf8')+str2+".txt"
    ff = open(str1,'w')
    ff.close()
    ff = open(str1,'w')
    counts=get_count(n1,n2,n3,n4,n5,count)
    unicode_str = unicode('中文', encoding='utf_8_sig' )
    print unicode_str.encode('utf-8')
    default_encoding = 'utf8'
    if sys.getdefaultencoding() != default_encoding:
        print sys.getdefaultencoding() 
    f=open('TIKU.txt','r')
    s=f.readlines()
    print len(s)
    l=1
    line_num,line_start,line_end=get_lines() 
    for i in range(0,part):
        time_i=0
 #       print "银行考试\n"
       # print "************************SECRET*************************\n"
        #print "第"+str(i+1)+"部分"+" 题目数量"+str(counts[i])+"\n"
        #print "************************SECRET*************************\n"
        ff.writelines("************************SECRET*************************\n")
        ff.writelines("第"+str(i+1)+"部分"+" 题目数量"+str(counts[i])+"\n")
        ff.writelines("************************SECRET*************************\n") 
        if i == 0 :
            p=random.randint(28,88)
        else :
            p=random.randint(1,50)+line_start[i]
        lenth=line_end[i]  
        while(p<lenth and time_i<counts[i]):
            lis=""
            q=s[p]
            try:
                for y in range(1,20):
                    if p+y>len(s):
                        lis = "天荒地老"
                    else :
                        lis=lis+s[p+y]
            except:
                lis=q
            m=search(p)
            number="\n"+"第"+str(l)+"题"+" "+m+"\n"
            lis=re(lis)
            a=''
            for tt in range(len(lis)):
                a+=str(lis[tt].encode('utf8'))
           # print number
            #print lis
            ff.writelines(number)
            ff.writelines("\n"+a+"\n")
            if l%3==0:
                if random.randint(0,10)>6:     
                    xh=xiaohua()
                   # print xh
                    ff.writelines(xh+"\n")
                if l%30==0:
                    ff.writelines("休息一下啦\n")
            l=l+1  
            #imp=importance(n1,n2,n3,n4,count)
            imp=get_imp(line_end[i],p,counts[i],time_i)
            p=p+imp
            time_i=time_i+1
    ff.close()
def mam(p): 
    for i in range(0,p):
        ma(80,40,30,15,15,100,5)
        time.sleep(1)
        print i
mam(10)

PS.过两天我会上传另外一个版本,是简单的数学问题。希望实现百词斩的算法。如果时间充足,搞一个基于机器学习的简单的分类器。目前计划:

0、提取题目,将题目分类。小包括数字个数,类划分使用特征词汇的方法。

1、将题目存入数据库或者列表。由于比较小,存成csv格式应该差不多足够了。

2、设置一个记录做对/错的记录列表。暂时用列表。

3、针对性对错题 在生成试卷的过程中再出现。

预期目标:输入txt文本文件,能够实现出题/界面程序/猿题库或者百词斩形式,假期用两三天完成吧。有愿意开发的一起哦~

邮箱:sx1995@buaa.edu.cn

  • 11
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!为了用Python读取Excel题库随机组成Word版本试卷,您可以按照以下步骤进行操作: 1. 首先,将Excel题库转换为CSV格式的文件。可以使用Excel软件将题库另存为CSV格式,或者使用Python的pandas库将Excel读取为DataFrame对象,然后将其保存为CSV格式,例如: ```python import pandas as pd # 读取Excel题库 df = pd.read_excel('questions.xlsx') # 将DataFrame保存为CSV格式 df.to_csv('questions.csv', index=False) ``` 2. 创建一个Python脚本,用于读取CSV格式的题库随机抽取试题。例如: ```python import csv import random # 读取CSV题库 with open('questions.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) questions = list(reader) # 随机抽取试题 random.shuffle(questions) selected_questions = questions[:10] # 输出试题 for i, question in enumerate(selected_questions): print(f'第{i+1}题:{question[0]}') print(f'答案:{question[1]}\n') ``` 其中,上述代码中的`questions.csv`为CSV格式的题库文件名,`10`为需要随机抽取的试题数量。您可以根据实际情况修改这些参数。 3. 安装Python-docx库,用于生成Word版本试卷。可以使用pip命令进行安装: ``` pip install python-docx ``` 4. 使用Python-docx库生成Word版本试卷。例如: ```python import csv import random from docx import Document from docx.shared import Inches # 读取CSV题库 with open('questions.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) questions = list(reader) # 随机抽取试题 random.shuffle(questions) selected_questions = questions[:10] # 生成Word版本试卷 document = Document() # 添加试题 for i, question in enumerate(selected_questions): # 添加题目 document.add_heading(f'第{i+1}题:{question[0]}', level=1) # 添加答案 document.add_paragraph(f'答案:{question[1]}') # 添加分隔线 document.add_page_break() # 保存Word版本试卷 document.save('exam.docx') ``` 其中,上述代码中的`questions.csv`为CSV格式的题库文件名,`10`为需要随机抽取的试题数量,`exam.docx`为生成的Word版本试卷文件名。您可以根据实际情况修改这些参数。 希望这些步骤可以帮助您用Python读取Excel题库随机组成Word版本试卷。如有任何问题,欢迎随时联系我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值