问题描述
作为一个学委,通常的任务就是收取班级作业,然后向老师报告当前未交人员的名单
JS版本:实现以一个表格数据查询另一个表格【JS】
之前我已经尝试通过用JS实现了,本质上差别其实也不是很大,只是对于JS来说,文件处理
是它的硬伤之一,因为他设计之初就不是为了文本处理,而且你要想,如果js能随意获取你计算机上的文件,那会不会有些惊悚了(当然可以通过node中的fs模块实现,但终究有点小问题)
因此,为针对文件处理这一类的问题,我就尝试使用python去解决了
需求描述
- 获取当前已提交文件的所有人
- 获取班级名单Excel
- 查询未提交的人数
实现代码
import os
import xlrd
import re
turnInPath = input('已上交的文件目录:')
classListPath = "D://Leo//Document//Class//xxxxxx.xlsx"
# os.listdir:参数为文件夹路径,可以返回文件夹下的所有子文件夹、文件名称
# 不能返回子文件夹下的文件
fileArr = os.listdir(turnInPath)
fileStr = "|".join(fileArr)
worksheet = xlrd.open_workbook(classListPath)
sheet_names= worksheet.sheet_names()
for sheet_name in sheet_names:
sheet = worksheet.sheet_by_name(sheet_name)
cols = sheet.col_values(1) # 获取第二列内容, 数据格式为此数据的原有格式(原:字符串,读取:字符串; 原:浮点数, 读取:浮点数)
del cols[0] # 删除第一位的列名
classList = cols
isChinese = re.compile(u'[\u4e00-\u9fa5]') #中文的范围为\u4e00-\u9fa5
turnInList = []
for fileName in fileArr:
arr = isChinese.findall(fileName)
turnInList.append(''.join(arr))
# 在提交列表 & 在班级列表 (为了处理非本班的提交)
# 若能完全确定一定是本班的,则为了效率可注释
# 该段代码通常适用于 两个班混交 or 统一分组(不过这个需要读取Excel了)
# diff = [ ]
# for item in turnInList:
# if(item in classList):
# diff.append(item)
# 在班级列表 && 不在(真实上交列表)
for item in classList:
if(item not in "".join(turnInList)):
print(item)
代码解释
获取已提交人员信息
输入路径
为方便多次复用,这里特地将文件目录进行输入,并进行适当提示
turnInPath = input('已上交的文件目录:')
读取文件夹
通过使用python内置模块
os
,获取所有文件名称
# os.listdir:参数为文件夹路径,可以返回文件夹下的所有子文件夹、文件名称
# 不能返回子文件夹下的文件
fileArr = os.listdir(turnInPath)
读取中文
从所有提交名单中获取中文(中文名称大概率就是姓名了,当然可能存在
作业
等冗余后缀,这些后面会处理)
- 设置正则
- 循环处理
isChinese = re.compile(u'[\u4e00-\u9fa5]') #中文的范围为\u4e00-\u9fa5
turnInList = []
for fileName in fileArr:
arr = isChinese.findall(fileName)
turnInList.append(''.join(arr))
首先对os.listdir
进行循环,获取所有文件名中为中文的,放入turnInlist
数组中
获取班级名单
设置班级名单路径
因为这里班级名单基本不变,因此就直接定为常量了
classListPath = "D://Leo//Document//Class//xxxxx.xlsx"
打开花名册
worksheet = xlrd.open_workbook(classListPath)
获取列
sheet_names= worksheet.sheet_names()
for sheet_name in sheet_names:
sheet = worksheet.sheet_by_name(sheet_name)
获取列
sheet = worksheet.sheet_by_name(sheet_name)
cols = sheet.col_values(1) # 获取第二列内容, 数据格式为此数据的原有格式(原:字符串,读取:字符串; 原:浮点数, 读取:浮点数)
del cols[0] # 删除第一位的列名
classList = cols
这里解释一下为什么要杀出数组的第一个
因为通常情况下,我们的班级名单中的列通常会是这样的
这样就会多余出一行来
输出未提交名单
# 在班级列表 && 不在(真实上交列表)
for item in classList:
if(item not in "".join(turnInList)):
print(item)
这里只需要注意一点的就是"".join(turnInList)
,为什么这里需要转为字符串?
因为这里我们需要做到的是最大匹配
也就是说,如果有一个提交的命名为张三的作业.xxx
的话,通过判断是否是classList中的元素是否是turnInList
的子串即可实现对张三的判断