【教学类-06-03】20220327 X以内数字分合题(分)及生成word 打印docx纸(方法一)(Python VS )

21 篇文章 0 订阅

本代码价值:

终端生成的列表 通过TXT文本转换成docx文件

征文需求:

3月上海疫情隔离开启居家办公生涯。月底区教育局有一个“工具运用”的征文比赛,阿夏以《设计Python学具,开展大班幼儿学习活动的案例研究》为题,将已有的五个教学案例进行汇总。

第五项“数字加减法.py”的学具并不能立刻通过代码生成,需要借助“运行——保存为TXT——打开TXT——复制TXT内容——新建docx——黏贴TXT内容——分栏——放大字体、加粗——加框——添加页眉信息(X以内加减题,姓名、班级、学号、分数)”的方式。

1、不足之处:需手动制作word模板:

曾经阿夏觉得Python实现了题目批量,已节约了大量时间,因此愿意通过手动黏贴制作word模板。但是经过了5以内、10以内、20以内的模板制作,感觉也是比较费时间,人力操作依旧繁琐。

2、阶段体验:论文过程冗长无价值:

而在撰写文本经验的时候,阿夏也发自内心地认为“如果把这么多的制作过程写出来,图文占空间,根本无法体现编程的价值(高效)评审员估计要看晕了。”

因此,阿夏用了两天的时间,从网上搜索各种解题思路和实现代码,拼拼贴贴,反复测试。终于用繁琐的代码实现了“列示题TXT转docx”的初步结果。

3.宏观把控:“减负”背景下少触红线:

随后,阿夏把马先生设计的“加减法不重复题数代码“加上了”列示题TXT转docx”的程序,顺利获得了“X以内列示题(加法题、减法题、加减混合题)”的代码。

但是考虑到“减负”政策,如果直接演示“一年级的数学列示题”的设计和教学运用过程,也是有一定的降分风险(虽然班级里100%的孩子都在家练习过)”因此阿夏决定用大班主题教材上的《数字分合题》(相对安全)为教学目标,改良代码,制作“X以内数字分合题(分题)的不重复题数的代码”

代码演示:

0. 效果展示:生成一份带名称的docx文件(所有X以内不重复的减法题都在其中)(这里是分题,所以是减法)

1、拷贝代码,“X以内数字分合题-最大不重复数量.py”,py可以在盘的任意位置。生成的文件统一在VS打开的默认文件夹下,作者这里是D\test 下:


# -*- coding: utf-8 -*-  
 
 
# 第1部分:题目库
print('----------------第一步开始:生成数学题----------------')
 
# -*- coding: utf-8 -*-  
""" 
@author: 马清新
@file: 阿夏修改(20以内加法题、20以内减法题、20以内加减法混合题(最大不重复算式值).py
@time: 2022/2/4 17.18
# 特别说明
1、选择“1.纯加法题。2.纯减法题。3.加减法混合题(请输入序号)”
2、分开计算,纯加法题数量+纯减法题数量=加减法混合题数量。
3、结果分别保存在相应的TXT内
4、可通过注释,选择题目是否有答案。
5、本题所有答案都是打乱模式 random.shuffle.如果是10以内加法、减法、加减法可以排序 sort 
"""
 
import random
from re import X
import time
from async_generator import yield_
 
 
    
   
# 数字分合 总分结构,求分1 分2的数字 
 
hao='数字分合(分)'
sumMax = int(input('请输入最大数字((≥0)):\n'))# 输入最大值
regNum = int(input('请输入需要的数量:\n'))# 输入需要的数量
# 生成1个列表,列表从0开始,到算术最大和结束,因为range函数包左不包右,因此如果要包括算式最大和,必须+1
# range函数从0开始,这样列表元素和列表索引一致,减轻算法的难度
numList = [x for x in range(0,sumMax+1)]# 建立整数列表,假设SUMMAX=20 sumMax+1等于21 但实际范围就是1-20,确保列表索引和列表元素一致
# resultList列表用于保存最后需求数量的合规算术式
resultList = []# 储存结果的列表
# 从列表第2个元素开始到列表最后一个元素进行循环遍历
for x in numList[0:]:# 0等于数字1
    # 从列表第x个元素开始到列表最后一个元素进行循环遍历
    for y in numList[x:]:
        #  加法
        if (x == y) and (x + y <= sumMax)and (y != 0): # X或Y两者一个或者两个都不能0。没有0+0,0-0
            tempStr = '  '+str(x+y)+'\n' + ' /  ' +  '  \ '+'\n'+' __    ' + str(y)+'\n'
            resultList.append((tempStr, (x+y))) 
            tempStr = '  '+str(x+y)+'\n' + ' /   ' +  '  \ '+'\n'+str(x)+'    __' +'\n'
            resultList.append((tempStr, (x+y)))  
        elif x + y <= sumMax and (y != 0):# 第一位或者第二位都不为0,也就是没有
            tempStr = '  '+str(x+y)+'\n' + ' /   ' +  '  \ '+'\n'+'__   '+ str(y)+'\n'
            resultList.append((tempStr, (x+y)))
            tempStr = '  '+str(x+y)+'\n' + ' /   ' +  '  \ '+'\n'+str(x)+'    __'+'\n'
            resultList.append((tempStr, (x+y)))               
        elif y - x == 0 and(y == 0):#此段只有一个答案0+0=0,不需要的话,此段注释掉
            tempStr = '  '+str(x+y)+'\n' + ' /   ' +  '  \ '+'\n'+str(x)+'   __' +'\n' 
            resultList.append((tempStr, (y+x)))# 带答案的题目,如0+0=0,
    
    selectList = []# 选择列表
    
    if regNum > len(resultList):#如果(输入算式的数量)大于(结果列表的数量)#输入题数大于实际需求,就用shuffle洗牌,
        print(f'您的需求大于最大算式生成数量!最大生成算式数量为{len(resultList)}') # 加了最大不重复算式统计值,如果输入的题数大于储存结果的列表的数量,列表加LEN
        i = len(resultList)# i的数量等于储存结果的列表的数量
        for _ in resultList:# 值在循环储存结果的列表内
            selectList.append(_) #选择列表 需要添加循环储存结果列表的内容
        random.shuffle(selectList) #shuffle 洗牌算法,把列表所有元素打乱,随机排列
        # selectList.sort()#sort 正序排列,只有10以内的能排序,超过10就乱序
        # selectList.sort(reverse=True) #从大到小 倒叙排列 5 + 0 = 5   4 + 1 = 5 ……
        # selectList.shuffle()
 
        for _ in selectList:   
            # 可选打印带答案的和不带答案啊8
            # print(_[0])# 不带答案
            print(f'{_[0]}{_[1]}')# 终端带答案,
        
    else:#输入题数小于实际需求,代码自动随机抽取,不会排序,
        i = regNum
        selectList = random.sample(resultList,i)
        for _ in selectList:
            # 可选打印带答案的和不带答案啊
            # print(_[0])# 不带答案
           print(f'{_[0]}{_[1]}')# 终端带答案,
       
    # 验证生成算式数量70
    print(f'共生成不重复的纯加法算式的题目数量{len(selectList)}')# 选择列表的数量
    print(f'纯加法最大不重复的算式的限制数量{len(resultList)}')#  结果列表的数量
 
    str_title = '过渡.txt'  # 保存带数字提示的题目
    with open(str_title,'w',encoding='utf-8') as f:#  打开TXT文件
        for a in selectList:#  #循环查找答案的内容
            f.write(str(a[0])+'\n')# 不带答案
            # f.write(str(a[1])+'\n')#只有答案
            # f.write(str(a[0])+str(a[1])+'\n')#有题目有答案  TXT里面是题目+答案,终端显示题目 无答案,因为上面选了(0)
    f.close()# #关闭TXT      
        # elif sumMax<x + y <= sumMax+5:
        #     tempStr = '  '+str(x+y)+'\n' + ' /   ' +  '  \ '+'\n'+'__  '+'   __' +'\n'+'\n' 
        #     resultList.append((tempStr, (y+x)))# 带答案的题目,如0+0=0,
            
        
        #     tempStr = '  '+str(c)+'\n' + ' / ' +  ' \ '+'\n'+'(  )  ' + str(a)+'\n'+'\n'
 
 
 
# else:
#     print('输入错误,请重新输入.')
 
print('----------------------第一步完成--------------------')
time.sleep(0.5) 
print('----------------第二步开始:txt转换docx-------------')
 
# 第二部分:  TXT转docx
from docx import Document
import os
#  作者:we1can https://www.bilibili.com/read/cv13745103 出处:bilibili
# 创建word并设置字体
document = Document()
paragraph = document.add_paragraph()
run = paragraph.add_run()
run.font.name = 'Times New Roman'
 
# 打开txt文件,并写入document中
f = open("过渡.txt","r",encoding='utf-8')   # 注意编码类型
document._body.clear_content()# 删除docx里面的第一行 ,这是个空行,用strip无法删除
line = f.readline()
# line=line.strip('\n')# 删除一个数字题下面空行 也就是第三行
while line:       
    line=line.strip('\n') 
    document.add_paragraph(line)  
    line = f.readline()
    # document.add_paragraph(line)  
    # line=line.strip('\n')  
    
    
    
# line = f.readline()
# line=line.strip('\n')# 删除一个数字题下面空行 也就是第三行 
 
f.close()
document.save(u'过渡.docx') # 保存文档
print('----------------------第二步完成--------------------')
time.sleep(0.5) 
print('----------------第三步开始:docx格式调试------------')
 
'''https://www.cnblogs.com/wenshi-jj/p/15388808.html'''
 
# import docx# 导入docx模块
from docx import Document
from docx.shared import Pt 
from docx.shared import RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
 
# 新建节 1页
# doc = docx.Document()# 新建一个空白文档,那么默认是只有一个节
# len(doc.sections)# 长度为1 默认是只有一个节
doc=Document('过渡.docx')
 
for paragraph in doc.paragraphs:
    for run in paragraph.runs:             
        run.font.size = Pt(20)                # 数字题目字体大小
        run.font.bold = True                    #数字题目字体是否加粗
        run.font.name = 'Arial'           # 数字题英文时的字体
        run.element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')  # 数字题中文时的字体
        paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 设置数字题居中对齐
        # paragraph.paragraph_format.line_spacing=0.8  #数字题的段行距
        paragraph.paragraph_format.line_spacing = Pt(26) #数字题段间距
 
 
# 设置主要页边距 
from docx.shared import Cm # 导入cm模块
doc.sections[0].top_margin = Cm(2.54)# sections[1]是第二节=第二页 上边距
doc.sections[0].bottom_margin = Cm(1)# sections[1]是第二节=第二页 下边距
doc.sections[0].left_margin = Cm(1) # sections[1]是第二节=第二页 左边距
doc.sections[0].right_margin = Cm(1)# sections[1]是第二节=第二页 右边距
# 设置其他页边距内容
doc.sections[0].gutter=Cm(0)# sections[1]是第二节=第二页 装订线 默认为0 左
doc.sections[0].header_distance=Cm(2)# sections[1]是第二节=第二页 页眉边距
doc.sections[0].footer_distance=Cm(1)# sections[1]是第二节=第二页 页脚边距
# 装订线还有一个位置属性,暂时未发现如何设置,默认为左,如果需求设置成右,可以建个模板docx文档导入。
 
# 设置纸张方向和大小  LANDSCAPE=横  PORTRAIT纵  默认信纸 纵
from docx.shared import Cm # 导入CM # 
from docx.enum.section import WD_ORIENTATION  # 导入纸张方向
 
doc.sections[0].page_height = Cm(21)  # 设置A4纸的高度
doc.sections[0].page_width = Cm(29.7)  # 设置A4纸的宽
doc.sections[0].orientation = WD_ORIENTATION.LANDSCAPE # 设置纸张方向为横向 L 
 
# 设置分栏
from docx.oxml.ns import qn
 
doc.sections[0]._sectPr.xpath('./w:cols')[0].set(qn('w:num'), '6') #把第二节页设置为2栏
# doc.sections[0]._sectPr.xpath('./w:cols')[0].set(qn('w:distance'), '12')
# doc.sections[0]._sectPr.xpath_distance = Cm(21) 调证分栏间距?
 
 
# 设置页眉和页脚
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT# 导入文本居中 居左、居右
from docx.shared import Pt 
 
header = doc.sections[0].header  # 获取第一个节的页眉
# print('页眉中默认段落数:', len(header.paragraphs))
paragraph = header.paragraphs[0]  # 获取页眉的第一个段落
# {}以内加法题'.format()
text=paragraph.add_run('{}以内{}-不重复题数-共{}题\n'
                   '姓名:______________学号:_______________班级:___________分数________ '.format(sumMax,hao,len(resultList))) # 添加页面内容
text.font.size = Pt(20)                # 页眉字体大小
text.bold = True                    # 页眉字体是否加粗
text.font.name = 'Arial'           # 控制是英文时的字体
text.element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')  # 控制是中文时的字体
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 设置页眉居中对齐
paragraph.paragraph_format.line_spacing=1.5  #页眉中文字的段间距
 
# 设置页脚文字
footer = document.sections[0].footer # 获取第一个节的页脚
paragraph = footer.paragraphs[0] # 获取页脚的第一个段落
paragraph.add_run('')#添加内容
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER#居中
 
# # 文字上下左右加边框 对导入的数学题加边框,控制答案的位置
# from docx.oxml import OxmlElement
# from docx.oxml.ns import qn
 
# #table = document.add_table(rows=1, cols=3)
# hdr_cells = table.rows[0].cells
# hdr_cells[0].text = 'Qty'
 
# set_cell_border(
#         hdr_cells[0],
#         top={"sz": 12, "val": "single", "color": "#000000", "space": "0"},
#         bottom={"sz": 12, "val": "single", "color": "#000000", "space": "0"},
#         left={"sz": 12, "val": "single", "color": "#000000", "space": "0"},
#         right={"sz": 12, "val": "single", "color": "#000000", "space": "0"},
 
doc.save('%d以内%s-不重复题数-共%d题.docx' % (sumMax,str(hao),len(resultList)))  # 保存文档
 
print('----------------------第三步完成--------------------')
time.sleep(0.5) 
print('----------------第四步开始:删除过渡文件------------')
 
# 删除过渡文件
import os
path = '过渡.txt'  # 文件路径
if os.path.exists(path):  # 如果文件存在
    # 删除文件,可使用以下两种方法。
    os.remove(path)  
    #os.unlink(path)
path = '过渡.docx'  # 文件路径
if os.path.exists(path):  # 如果文件存在
    # 删除文件,可使用以下两种方法。
    os.remove(path)  
    #os.unlink(path)
 
print('----------------------第四步完成--------------------')
time.sleep(0.5) 
print('---------------请到D盘test下查找生成word------------')
time.sleep(0.5) 
'''
————————————————
版权声明:本文为CSDN博主「reasonsummer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/reasonsummer/article/details/123781844
'''

基本参数都是调整过的,适合阿夏的电脑及生成的版本。其他电脑 不保证。

运行步骤:

1、VS 运行

 

 

 

 每张A4上 3*6=18题

 

 用同样的方法可以批量5以内、10以内分合题

 

3*6+5=23题

生成docx文件名也不同,便于区分,放在同一个文档里,打印方便。

也可以再增加代码,批量生成“5以内”“10以内”的28份,每份出现的题目顺序不一样的X以内分合题。(个别幼儿用20,50)

 

小结:

有了这个固定的TXT转docx模板,制作各类“数字题型”学具会变得更方便快捷。编程太有用了,值得花时间去写、去优化、去调整一个又一个受益终身的教学代码、办公代码!

后续:

目前没有破解的内容有“段落框架、页码、题目第一位数的排序、def函数体及EXE打包”

等下一次的比赛时估计才会逼着自己去研究吧。

鸣谢:

找了两天的代码,深刻感受到上个月马先生制作本案例中核心代码“不重复列示题.py”时的辛劳,再次表示万分感谢!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Django是一个用于快速开发Web应用程序的Python Web框架。而python-docx-template是一个Python库,它可以使用Word文档作为模板,然后根据传入的数据批量生成Word文档。在Django中,我们可以利用python-docx-template库来实现批量生成Word文档的功能。 首先,我们需要在Django项目中安装python-docx-template库。可以使用pip命令来安装该库: ```bash pip install python-docx-template ``` 接下来,我们可以在Django项目中创建一个视图函数,用于接收数据并根据模板生成Word文档。在视图函数中,我们可以使用python-docx-template库提供的方法将数据填充到Word模板中,生成最终的Word文档。 例如,假设我们有一个Word文档模板`template.docx`,里面包含了一些需要填充数据的位置,我们可以在Django中这样写视图函数: ```python from docxtpl import DocxTemplate from django.http import HttpResponse def generate_word_document(request): # 从请求中获取数据 data = request.GET.get('data', '') # 读取Word模板 doc = DocxTemplate("template.docx") # 根据数据填充模板 context = {'data': data} doc.render(context) # 写入生成Word文档 doc.save("generated_document.docx") # 返回生成Word文档给用户 with open("generated_document.docx", 'rb') as f: response = HttpResponse(f.read(), content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document') response['Content-Disposition'] = 'attachment; filename=generated_document.docx' return response ``` 通过上述视图函数,我们可以在Django项目中实现批量生成Word文档的功能,用户可以通过传入数据来生成他们所需的Word文档。这样我们就可以方便地利用Python和Django来批量生成Word文档,提高生产效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿夏reasonsummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值