工具v2中增加 学生讲义制作 功能
This commit is contained in:
parent
97f8152ea3
commit
bf502507eb
|
|
@ -7,7 +7,7 @@ import os,re,time,json,sys
|
||||||
"""---设置题目列表---"""
|
"""---设置题目列表---"""
|
||||||
#留空为编译全题库, a为读取文本文件中的题号筛选.txt文件生成题库
|
#留空为编译全题库, a为读取文本文件中的题号筛选.txt文件生成题库
|
||||||
problems = r"""
|
problems = r"""
|
||||||
|
10000
|
||||||
"""
|
"""
|
||||||
"""---设置题目列表结束---"""
|
"""---设置题目列表结束---"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import json,re,os,Levenshtein,fitz,time
|
import json,re,os,Levenshtein,fitz,time,sys
|
||||||
|
|
||||||
def GetDate(): #获得当前日期
|
def GetDate(): #获得当前日期
|
||||||
currentdate = str(time.localtime().tm_year)+str(time.localtime().tm_mon).zfill(2)+str(time.localtime().tm_mday).zfill(2)
|
currentdate = str(time.localtime().tm_year)+str(time.localtime().tm_mon).zfill(2)+str(time.localtime().tm_mday).zfill(2)
|
||||||
|
|
@ -513,7 +513,7 @@ def GenerateTexDataforEditing(id_string,prodict,templatefilepath,editor): # 根
|
||||||
output += "\\item (%s) "%str(id).zfill(6) + content + "\n\n" + "答案: " + answer + "\n\n" + "解答与提示: " + solution + "\n\n" + "备注: " + remark + "\n\n"
|
output += "\\item (%s) "%str(id).zfill(6) + content + "\n\n" + "答案: " + answer + "\n\n" + "解答与提示: " + solution + "\n\n" + "备注: " + remark + "\n\n"
|
||||||
output += "\\end{enumerate}"
|
output += "\\end{enumerate}"
|
||||||
template = ReadTextFile(templatefilepath)
|
template = ReadTextFile(templatefilepath)
|
||||||
texdata = StringSubstitute(r"<<[\s\S]*?>>",template,[output])
|
texdata = StringSubstitute(r"<<[\s\S]*?待替换[\s\S]*?>>",template,[output])
|
||||||
return texdata # 返回Tex文件的字符串, 待保存至tex文件
|
return texdata # 返回Tex文件的字符串, 待保存至tex文件
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -618,7 +618,7 @@ def ShareSameUsages(prodict,same_group): #对same_group中的所有题号共享
|
||||||
prodict[id]["usages"] = current_usages.copy()
|
prodict[id]["usages"] = current_usages.copy()
|
||||||
return((same_group,current_usages)) #返回same_group中的题号列表 及 所有题号记录 组成的二元组
|
return((same_group,current_usages)) #返回same_group中的题号列表 及 所有题号记录 组成的二元组
|
||||||
|
|
||||||
def SortUsages(prodict):
|
def SortUsages(prodict): #对使用记录按字符串进行排序
|
||||||
for id in prodict:
|
for id in prodict:
|
||||||
usages = prodict[id]["usages"].copy()
|
usages = prodict[id]["usages"].copy()
|
||||||
usages.sort()
|
usages.sort()
|
||||||
|
|
@ -674,5 +674,60 @@ def MatchCondition(problem,condition_dict): #判断problem这一字典是否符
|
||||||
match = False
|
match = False
|
||||||
return match #返回是否符合条件
|
return match #返回是否符合条件
|
||||||
|
|
||||||
|
|
||||||
|
def get_color(value): # 根据得分率获得rgb颜色代码
|
||||||
|
value = float(value)
|
||||||
|
if value>=0.5:
|
||||||
|
(r,g)=(1,2-2*value)
|
||||||
|
else:
|
||||||
|
(r,g)=(2*value,1)
|
||||||
|
return "{%.3f,%3f,0}"%(r,g) #返回用大括号包围的rgb数值
|
||||||
|
|
||||||
|
def GenerateValueColorCode(matchobj): # 生成三位小数代表的颜色方框(黑色边框, 难度对应的底色)的LaTeX代码
|
||||||
|
value = matchobj.group(1)
|
||||||
|
return "\t\\fcolorbox[rgb]{0,0,0}%s{%s}"%(get_color(value),value) #返回代码
|
||||||
|
|
||||||
|
def StudentsGetAfterContent(id,prodict,answered,spaceflag): #生成学生版讲义后的答案及空格, answered表示有无答案, spaceflag表示有无空格
|
||||||
|
string = ""
|
||||||
|
if answered:
|
||||||
|
string += "答案: \\textcolor{red}{%s}\n\n"%(prodict[id]["ans"] if prodict[id]["ans"] != "" else "暂无答案")
|
||||||
|
if spaceflag:
|
||||||
|
if prodict[id]["space"] != "":
|
||||||
|
string += "\\vspace*{%s}\n\n"%prodict[id]["space"]
|
||||||
|
return string #生成学生讲义后的答案及空格
|
||||||
|
|
||||||
|
def XeLaTeXCompile(filedir,filename): #在filedir目录中用XeLaTeX编译filename文件两次(能编译出正确的引用和页码)
|
||||||
|
flagsuc = True
|
||||||
|
for i in range(2):
|
||||||
|
if os.system("xelatex -interaction=batchmode -output-directory=%s %s"%(filedir,filename)) == 0:
|
||||||
|
print("第%d次编译成功."%(i+1))
|
||||||
|
else:
|
||||||
|
flagsuc = False
|
||||||
|
return flagsuc # 若第二次编译成功则返回True, 否则返回False
|
||||||
|
|
||||||
|
def GenerateStudentsBodyString(problems,sectiontitles,pro_dict,consecutivenumbering,answered,spaceflag): #生成学生版的.tex文件的主体内容
|
||||||
|
bodystring = ""
|
||||||
|
if len(problems) == len(sectiontitles):
|
||||||
|
count = 0
|
||||||
|
for i in range(len(problems)):
|
||||||
|
idlist = generate_number_set(problems[i],pro_dict)
|
||||||
|
sectionstring = "\\section{%s}\n\\begin{enumerate}\n\\setcounter{enumi}{%d}\n\n"%(sectiontitles[i],count if consecutivenumbering else 0)
|
||||||
|
for id in idlist:
|
||||||
|
count += 1
|
||||||
|
aftercontent = StudentsGetAfterContent(id,pro_dict,answered,spaceflag)
|
||||||
|
sectionstring += "\\item {\\tiny(%s)} %s\n\n%s"%(id,pro_dict[id]["content"],aftercontent)
|
||||||
|
sectionstring += "\\end{enumerate}"
|
||||||
|
bodystring += sectionstring
|
||||||
|
else:
|
||||||
|
idstring = ",".join(problems)
|
||||||
|
idlist = generate_number_set(idstring,pro_dict)
|
||||||
|
sectionstring = "\\begin{enumerate}\n\n"
|
||||||
|
for id in idlist:
|
||||||
|
aftercontent = StudentsGetAfterContent(id,pro_dict,answered,spaceflag)
|
||||||
|
sectionstring += "\\item {\\tiny(%s)} %s\n\n%s"%(id,pro_dict[id]["content"],aftercontent)
|
||||||
|
sectionstring += "\\end{enumerate}"
|
||||||
|
bodystring += sectionstring
|
||||||
|
return bodystring #返回主题内容字符串
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("数据库工具, import用.")
|
print("数据库工具, import用.")
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
problems = ["1:5","6:10","10000:10004"] #题号列表, 每个字符串表示一个分块的题目
|
||||||
|
notetitle = "测试讲义" #讲义标题, 也是文件标题
|
||||||
|
sectiontitles = ["课前","课后","附加"] #小节标题列表, 如果与题号列表长度不符则作为不设小节处理
|
||||||
|
consecutivenumbering = False #不同小节是否连续编号, True表示连续编号, False表示每小节从1开始编号
|
||||||
|
answered = True #是否展示答案, True表示展示答案, False表示不展示答案
|
||||||
|
spaceflag = True #是否留空格, True表示留空格, False表示不留空格
|
||||||
|
|
||||||
|
from database_tools import *
|
||||||
|
|
||||||
|
prodictpath = "../题库0.3/problems.json"
|
||||||
|
pro_dict = load_dict(prodictpath)
|
||||||
|
|
||||||
|
outputdir = "临时文件" #输出文件的目录
|
||||||
|
outputfilepath = os.path.join(outputdir,notetitle+".tex")
|
||||||
|
print("输出文件目录: %s\n输出文件名: %s"%(os.path.join(os.getcwd(),outputdir),notetitle+".tex"))
|
||||||
|
|
||||||
|
latex_raw = ReadTextFile("模板文件/讲义模板.txt")
|
||||||
|
|
||||||
|
if sys.platform != "win32": #非win系统用默认字体
|
||||||
|
latex_raw = re.sub(r"fontset[\s]*=[\s]*none","fontset = fandol",latex_raw)
|
||||||
|
latex_raw = re.sub(r"\\setCJKmainfont",r"% \\setCJKmainfont",latex_raw)
|
||||||
|
|
||||||
|
|
||||||
|
bodystring = GenerateStudentsBodyString(problems,sectiontitles,pro_dict,consecutivenumbering,answered,spaceflag) #生成.tex中的内容主体字符串, 用于替换模板中的相应部分
|
||||||
|
|
||||||
|
latex_data = StringSubstitute(r"<<[\s\S]*?待替换[\s\S]*?>>",latex_raw,(notetitle,bodystring)) #替换标题和bodystring
|
||||||
|
SaveTextFile(latex_data,outputfilepath) #保存.tex文件
|
||||||
|
|
||||||
|
succeeded = XeLaTeXCompile(outputdir,notetitle+".tex")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
\documentclass[10pt,a4paper,twoside]{article}
|
||||||
|
\usepackage[UTF8, fontset = none, heading = true]{ctex}
|
||||||
|
\setCJKmainfont[BoldFont=黑体,ItalicFont=楷体]{华文中宋}
|
||||||
|
\usepackage{amssymb,amsmath,amsfonts,amsthm,mathrsfs,dsfont,graphicx}
|
||||||
|
\usepackage{ifthen,indentfirst,enumerate,color,lastpage}
|
||||||
|
\usepackage{tikz}
|
||||||
|
\usepackage{multicol}
|
||||||
|
\usepackage{multirow}
|
||||||
|
\usepackage{makecell}
|
||||||
|
\usepackage{longtable}
|
||||||
|
\usepackage{diagbox}
|
||||||
|
\usepackage[top=1in, bottom=1in,left=0.8in,right=0.8in]{geometry}
|
||||||
|
\usepackage{fancyhdr}
|
||||||
|
\fancyhf{}
|
||||||
|
\fancyhead[LO]{学号\blank{50} \ 姓名\blank{80}}
|
||||||
|
\chead{\papername}
|
||||||
|
\rhead{--\ \thepage\ of \pageref{LastPage} \ --}
|
||||||
|
\pagestyle{fancy}
|
||||||
|
\ctexset{section={
|
||||||
|
name={},
|
||||||
|
number=\chinese{section},
|
||||||
|
}}
|
||||||
|
\CTEXsetup[format={\bfseries\raggedright}]{section}
|
||||||
|
\usetikzlibrary{arrows,calc,intersections,patterns,decorations.pathreplacing,3d,angles,quotes,positioning,shapes.geometric}
|
||||||
|
|
||||||
|
\renewcommand{\baselinestretch}{1.5}
|
||||||
|
\newtheorem{defi}{定义~}
|
||||||
|
\newtheorem{eg}{例~}
|
||||||
|
\newtheorem{ex}{~}
|
||||||
|
\newtheorem{rem}{注~}
|
||||||
|
\newtheorem{thm}{定理~}
|
||||||
|
\newtheorem{coro}{推论~}
|
||||||
|
\newtheorem{axiom}{公理~}
|
||||||
|
\newtheorem{prop}{性质~}
|
||||||
|
\newcommand{\blank}[1]{\underline{\hbox to #1pt{}}}
|
||||||
|
\newcommand{\bracket}[1]{(\hbox to #1pt{})}
|
||||||
|
\newcommand{\onech}[4]{\par\begin{tabular}{p{.9\linewidth}}
|
||||||
|
A.~#1\\
|
||||||
|
B.~#2\\
|
||||||
|
C.~#3\\
|
||||||
|
D.~#4
|
||||||
|
\end{tabular}}
|
||||||
|
\newcommand{\twoch}[4]{\par\begin{tabular}{p{.46\linewidth}p{.46\linewidth}}
|
||||||
|
A.~#1& B.~#2\\
|
||||||
|
C.~#3& D.~#4
|
||||||
|
\end{tabular}}
|
||||||
|
\newcommand{\vartwoch}[4]{\par\begin{tabular}{p{.46\linewidth}p{.46\linewidth}}
|
||||||
|
(1)~#1& (2)~#2\\
|
||||||
|
(3)~#3& (4)~#4
|
||||||
|
\end{tabular}}
|
||||||
|
\newcommand{\fourch}[4]{\par\begin{tabular}{p{.23\linewidth}p{.23\linewidth}p{.23\linewidth}p{.23\linewidth}}
|
||||||
|
A.~#1 &B.~#2& C.~#3& D.~#4
|
||||||
|
\end{tabular}}
|
||||||
|
\newcommand{\varfourch}[4]{\par\begin{tabular}{p{.23\linewidth}p{.23\linewidth}p{.23\linewidth}p{.23\linewidth}}
|
||||||
|
(1)~#1 &(2)~#2& (3)~#3& (4)~#4
|
||||||
|
\end{tabular}}
|
||||||
|
|
||||||
|
|
||||||
|
\newcommand{\papername}{<<待替换1>>}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\begin{center}
|
||||||
|
{\bf\large \papername}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
<<待替换2>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
Reference in New Issue