错题集自动生成程序 python

暑期在某教育机构兼职助教,由于要为每位学生整理每节课出门测的错题,工作量巨大,因此编写了该程序,能偷懒一点是一点。mmd,以前哪有那么多事情,jhpy。

效果:在为试卷手动打标后,运行程序,生成每位学生每课的错题集,错题都会被加在同一个word,结构如下

 

 

 

班级的excel格式如下: 

 务必把chumence.exe和设置路径.xlsx放在同一个文件夹下:

 使用:

0.分割试卷,单个题用###

 不需要的内容用!!!

小猫钓鱼等1+n的题目用@@@与@@@@@ 

1.点击chumence.exe

2.选择成绩excel

3.选择出门测试卷word

4.检查、修改、关闭分割完的题目格式是否有问题,直接修改保存

5.等待程序运行完

可能遇到的问题的解决办法(测试下来一共就这几种):

1.必须有微软office,否则无法使用程序

2.word中,安全,宏设置,启用所有宏;信任对VBA工程对象……,否则会跳出安全警告

3.文件名中带有特殊字符,如?,无法生成文件夹

4.忘了,再补充

代码如下,可打包成exe方便使用:

# -*- coding: utf-8 -*-
from openpyxl import load_workbook
from docx import Document
import docx
import tkinter as tk
from tkinter import filedialog
import numpy as np
import os
import docx
from docx.text.paragraph import Paragraph
from docx.image.image import Image
from docx.parts.image import ImagePart
from docx.oxml.shape import CT_Picture
import win32com.client as win32
from win32com.client import constants
import  win32com
import signal
import wmi
import datetime
import time


c = wmi.WMI()
for process in c.Win32_Process(name="WINWORD.EXE"):
    process.Terminate()

def mkdir(path):
    folder = os.path.exists(path)
    if not folder:  # 判断是否存在文件夹如果不存在则创建为文件夹
        os.makedirs(path)  # makedirs 创建文件时如果路径不存在会创建这个路径

def sp(shuzu,cn,c,sn,s,date):
    sent = ""
    for temp in shuzu:
        if temp == "cn":
            sent = sent + str(cn)
        elif temp == "c":
            sent = sent + str(c)
        elif temp == "sn":
            sent = sent + str(sn)
        elif temp == "s":
            sent = sent + str(s)
        elif temp == "date":
            sent = sent + str(date)
        elif temp == "/":
            sent = sent + "/"
        else:
            print("请输入规范的缩写!")
    return sent




# 实例化
root = tk.Tk()
root.withdraw()

# 获取文件夹路径
print("————————————————请选择出门测成绩excel——————————————")
print("   ")
print("   ")
print("   ")
#score_path = "C:/Users/y3420/Desktop/出门测错题集自动生成程序/江浦路23年07月03日地理张靖成绩明细.xlsx"
score_path = filedialog.askopenfilename()
print(score_path)
#score_path = 'C:/Users/y3420/Desktop/出门测/出门测成绩汇总.xlsx'
print("————————————————请选择出门测试卷word——————————————")
print("   ")
print("   ")
print("   ")
#doc_path = "C:/Users/y3420/Desktop/出门测错题集自动生成程序/高一暑出门测01英语.docx"
doc_path = filedialog.askopenfilename()
print(doc_path)
#doc_path = 'C:/Users/y3420/Desktop/出门测/地理第一次.docx'
print("————————————————请选择学员上级总文件夹——————————————")
print("   ")
print("   ")
print("   ")
top_path = filedialog.askdirectory()
#top_path = "C:/Users/y3420/Desktop/出门测错题集自动生成程序/日月光test"
print(top_path)
#top_path = 'C:/Users/y3420/Desktop/日月光test/'
print("————————————————正在自动生成错题集——————————————")
print("   ")
print("   ")
print("   ")
set_path = '设置路径.xlsx'

#读取设置的路径
set = load_workbook(set_path)
sheets = set.worksheets
sheet1 = sheets[0]
i = 2
set_ctj_path = []
set_title = []
print(sheet1[11][1].value)
while sheet1[i][1].value is not None:
    set_ctj_path.append(sheet1[i][1].value)
    print(sheet1[i][1].value)
    i = i + 1
i = 2
while sheet1[i][2].value is not None:
    set_title.append(sheet1[i][2].value)
    print(sheet1[i][2].value)
    i = i + 1
i = 0
print("out1")

# 读取出门测成绩表
score = load_workbook(score_path)
doc = Document(doc_path)
sheets = score.worksheets
sheet1 = sheets[0]

#print(sheet1[6][2].value) #sheet1 [1][0]开始的


# 获取总行数
max_row_num = sheet1.max_row
max_column_num = sheet1.max_column

# 获取班级编号
row_list1 =  []
for i in range(1,max_row_num):
    for j in range(0,max_column_num):
        if sheet1[i][j].value == "班级编号":
            class_num = sheet1[i + 1][j].value
        if sheet1[i][j].value == "班级名称":
            class_name = sheet1[i + 1][j].value
        if sheet1[i][j].value == "考试日期":
            date = sheet1[i + 1][j].value
        if sheet1[i][j].value == "错误率":
            first_i = i + 1
            first_j = j - 1

with open("日志.txt","a+") as f: #追加写入日志
    d = datetime.datetime.now()
    d.year
    d.month
    d.day
    d.hour
    d.minute
    f.write(str(d.year) + " " + str(d.month) + " " + str(d.day) + " " + str(d.hour) + " " + str(d.minute) + "\n")
    f.write(class_num + class_name + "\n")
    f.write(score_path + "\n")
    f.write(doc_path + "\n")
    f.write(top_path + "\n")

with open("录入.txt","a+") as f: #追加写入日志
    d = datetime.datetime.now()
    d.year
    d.month
    d.day
    d.hour
    d.minute
    f.write(str(d.year) + " " + str(d.month) + " " + str(d.day) + " " + str(d.hour) + " " + str(d.minute) + "\n")
    f.write(class_num + class_name + "\n")
    f.write(score_path + "\n")
    f.write(doc_path + "\n")
    f.write(top_path + "\n")

# 获取正确答案
row_list2 =  []
for row in sheet1[6]:
    row_list2.append(row.value) # 从下标3开始为正确答案

#出门测分run
num = 3
tnum = -1
flag = 0
index = np.zeros((100,4),dtype=int)
#[头部序号,第一题序号,最后一题序号,是否加了头部]
pin = 0
docum = Document()
indoc = Document()

#打标记
line = 3
line0 = 0
line2 = []# !!!,@@@
line22 = []#0,3,4
for i in doc.paragraphs:
    if i.text == "###" or i.text == "@@@" or i.text == "@@@@@":
        line2.append(i.text)
        i.text = i.text + str(line)
        line22.append(line)
        line = line + 1
    if i.text == "!!!" or i.text == "!!!":
        line2.append(i.text)
        i.text = i.text + str(line0)
        line22.append(line0)
        line0 = line0 - 1

temp_path = top_path + "/" + "temp.docx"
doc.save(top_path + "/" + "temp.docx")

runs_path = top_path + "/"

# 打开word应用程序
word = win32com.client.DispatchEx('Word.Application')
# 是否可视化
word.Visible = 1
# 打开
print(temp_path)
doc = word.Documents.Open(temp_path)
# 光标start的查找
# 赋值对象
search_range = doc.Content
# 查找内容
st = 0
ed = 0
start = 0
now = 3


"""
    
start = 0

# 光标end的查找  同上
search_range = doc.Content
search_range.Find.Execute(FindText="!@#")
search_range.Select()
word.Selection.MoveLeft()
end = word.Selection.Start.numerator
print(end)

# 选取光标start到光标end的内容
doc.Range(start, end).Select()
# 复制
word.Selection.Copy()
# 粘贴的目标文件
doc_new = word.Documents.Open(runs_path + str(now) + '.docx')
# 粘贴
doc_new.Application.ActiveDocument.Range().Paste()
# 关闭两个文件
doc_new.Close()
doc.Close()

"""
#chace = []#复制内容
#chace2 = []#对应的下标

p = 0
runs_path = top_path + "/"
doc = word.Documents.Open(temp_path)
for g in range(0,len(line2)):
    i = line2[g]#i 是后一个
    if p == 0:
        start = 0
        # 光标end的查找  同上
        doc = word.Documents.Open(temp_path)
        search_range = doc.Content
        search_range.Find.Execute(FindText=(str(line2[g])+str(line22[g])))
        search_range.Select()
        word.Selection.MoveLeft()
        end = word.Selection.Start.numerator
        # 选取光标start到光标end的内容
        doc.Range(start, end).Select()
        # 复制
        word.Selection.Copy()
        #chace.append(word.Selection.Copy())#
##
        if i == "###":
            way = runs_path + str(num) + '.docx'
            num = num + 1
            #chace2.append(num)#
        elif i == "!!!" or i == "!!!":
            way = runs_path + 'nouse.docx'
        elif i == "@@@" and flag == 0:  # 头部
            way = runs_path + str(tnum) + '.docx'
            #chace2.append(tnum)#
            index[pin, 0] = tnum
            tnum = tnum - 1
            flag = flag + 1
        elif i == "@@@" and flag != 0:  # 第一题——
            if flag == 1:
                index[pin, 1] = num
            way = runs_path + str(num) + '.docx'
            #chace2.append(num)#
            num = num + 1
            flag = flag + 1
##
        # 粘贴的目标文件
        print(way)
        print("0:"+str(line2[g])+str(line22[g]))
        docxx = Document()
        docxx.add_paragraph()
        docxx.save(way)
        doc_new = word.Documents.Open(way)
        # 粘贴
        doc_new.Application.ActiveDocument.Range().Paste()
        # 关闭两个文件
        #doc_new.Close()#不关闭文档
        doc.Close()
        p = 1
    else:
        doc = word.Documents.Open(temp_path)
        search_range = doc.Content
        j = line2[g-1]#j 是前一个
        search_range.Find.Execute(FindText=(j+str(line22[g-1])))
        # 选中查找到的内容
        search_range.Select()
        # 光标左移
        word.Selection.MoveRight()
        # 将光标位置赋予start
        start = word.Selection.Start.numerator
        # 光标end的查找  同上
        search_range = doc.Content
        search_range.Find.Execute(FindText=(i+str(line22[g])))
        search_range.Select()
        word.Selection.MoveLeft()
        end = word.Selection.Start.numerator
        # 选取光标start到光标end的内容
        doc.Range(start, end).Select()
        word.Selection.Copy()
        #chace.append(word.Selection.Copy())
        if i == "###":
            way = runs_path + str(num) + '.docx'
            #chace2.append(num)
            num = num + 1
        elif i == "!!!" or i == "!!!":
            way = runs_path + 'nouse.docx'
        elif i == "@@@" and flag == 0:  # 头部
            way = runs_path + str(tnum) + '.docx'
            #chace2.append(tnum)
            index[pin, 0] = tnum
            tnum = tnum - 1
            flag = flag + 1
        elif i == "@@@" and flag != 0:  # 第一题——
            if flag == 1:
                index[pin, 1] = num
            way = runs_path + str(num) + '.docx'
            #chace2.append(num)
            num = num + 1
            flag = flag + 1
        elif i == "@@@@@":#最后一题
            if index[pin,1] == 0:
                index[pin,1] = num
            index[pin,2] = num
            if pin <=99:
                pin = pin + 1
            else:
                print("超出最大限度")
            flag = 0
            way = runs_path + str(num) + '.docx'
            #chace2.append(num)
            #indoc.save(runs_path + str(num) + '.docx')
            indoc = Document()
            num = num + 1
        # 粘贴的目标文件
        print(way)
        print(j+str(line22[g-1])+" : "+i+str(line22[g]))
        docxx = Document()
        docxx.add_paragraph()
        docxx.save(way)
        doc_new = word.Documents.Open(way)
        # 粘贴
        doc_new.Application.ActiveDocument.Range().Paste()
        # 关闭两个文件
        #doc_new.Close()#不关闭文档
        doc.Close()
print(line2)
print(line22)
print("请检查分割出的word格式是否正确,调正完成后请随便输入点东西,回车")
input()

app =win32com.client.Dispatch('Word.Application')
# 挨个创建错题word
top_path= top_path + "/"

if not os.path.exists(top_path + "tttttt.docx"):
    indoc = docx.Document()
    indoc.save(top_path + "tttttt.docx")
else:
    docxxx = Document()
    docxxx.add_paragraph()
    docxxx.save(top_path + "tttttt.docx")

for i in range(first_i, max_row_num+1):#读取同学的答案
    c = wmi.WMI()
    for process in c.Win32_Process(name="WINWORD.EXE"):
        process.Terminate()
    app = win32com.client.Dispatch('Word.Application')
    glag = 0
    flag = 0
    fish = 0
    index[:,3] = 0
    row_list3 = []
    for row in sheet1[i]:
        row_list3.append(row.value)
    sn = row_list3[first_j]
    s = row_list3[first_j + 1]
    cn = class_num
    c = class_name
    if s != "NoneNone":
        ctj_path = top_path + sp(set_ctj_path,cn,c,sn,s,date) #错题集路径
        title = sp(set_title,cn,c,sn,s,date)  # word名字  班级号+班级名称+考试日期
        #ctj_path = top_path + str(sn) + str(s) + '/' + str(c) + '/' + str(title) + '.docx' #如果文件夹里没有班级编号,只能依据班级名称查找
        for j in range(3, len(row_list2)):#检查每一题的对错
            #a = time.time()##############
            if row_list2[j] != row_list3[j]:#错题
                mkdir(ctj_path)  # 如果路径不存在,则生成
                if not os.path.exists(ctj_path + "/" + title + ".docx"):
                    indoc = docx.Document()
                    indoc.save(ctj_path + "/" + title + ".docx")
                if pin >= 1:#如果有小猫钓鱼
                    for k in range(0,pin):
                        if j >= index[k,1] and j <= index[k,2]:#查询是否为小猫钓鱼
                            fish = 1
                            break
                        else:
                            fish = 0
                    if fish == 1:
                        if index[k,3] == 0:#如果为第一次出现,则同时选项与题目  win32com.client.Dispatch('Word.Application').Documents.Open
                            app = win32com.client.Dispatch('Word.Application')
                            file_mode = runs_path + str(index[k,0]) + '.docx'
                            doc = app.Documents.Open(file_mode)
                            doc.Content.Copy()
                            doc.Close()
                            word = win32com.client.DispatchEx('Word.Application')
                            doc1 = word.Documents.Open(top_path + "tttttt.docx")
                            s = word.Selection
                            s.MoveRight(1,doc1.Content.End)
                            s.Paste()
                            doc1.Close()
                            index[k,3] = 1
                            file_mode = runs_path + str(j) + '.docx'
                            doc = app.Documents.Open(file_mode)
                            doc.Content.Copy()
                            doc.Close()
                            word = win32com.client.DispatchEx('Word.Application')
                            doc1 = word.Documents.Open(top_path + "tttttt.docx")
                            s = word.Selection
                            s.MoveRight(1, doc1.Content.End)
                            s.Paste()
                            doc1.Close()
                            glag = 0
                        else:
                            glag = 1
                    else:
                        glag = 1
                else:
                    glag = 1
                if glag == 1:
                    glag = 0
                    file_mode = runs_path + str(j) + '.docx'
                    doc = app.Documents.Open(file_mode)
                    doc.Content.Copy()
                    doc.Close()
                    word = win32com.client.DispatchEx('Word.Application')
                    doc1 = word.Documents.Open(top_path + "tttttt.docx")
                    s = word.Selection
                    s.MoveRight(1, doc1.Content.End)
                    s.Paste()
                    doc1.Close()
            #b = time.time()##############
            #print(b - a)
        #a = time.time()
        if j == len(row_list2)-1:
            file_mode = top_path + "tttttt.docx"
            if not os.path.exists(file_mode):
                indoc = docx.Document()
                indoc.save(file_mode)
            doc = app.Documents.Open(file_mode)
            doc.Content.Copy()
            doc.Close()
            word = win32com.client.DispatchEx('Word.Application')
            mkdir(ctj_path)  # 如果路径不存在,则生成
            if not os.path.exists(ctj_path + "/" + title + ".docx"):
                indoc = docx.Document()
                indoc.save(ctj_path + "/" + title + ".docx")
            doc1 = word.Documents.Open(ctj_path + "/" + title + ".docx")
            s = word.Selection
            s.MoveRight(1, doc1.Content.End)
            s.Paste()
            doc1.Close()
            print(ctj_path + "/" + title + ".docx")
            with open("录入.txt", "a+") as f:  # 追加写入日志
                f.write(ctj_path + "/" + title + ".docx\n")
        docxxx = Document()
        docxxx.add_paragraph()
        docxxx.save(top_path + "tttttt.docx")
        #b = time.time()
        #print(b - a)
        glag = 0
with open("录入.txt","a+") as f: #追加写入日志
    f.write("正常完成\n")
with open("日志.txt","a+") as f: #追加写入日志
    f.write("正常完成\n")
c = wmi.WMI()
for process in c.Win32_Process(name="WINWORD.EXE"):
    process.Terminate()
print("错题集正常生成完成,请关闭。")
input()

#print(index) WINWORD.EXE
#st.write()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值