我们要开始学习如何做等级划分啦。要实现这一功能,还得学习 5 个新的知识点,分别是os.path.exists()
、os.mkdir()
、算术运算符 //
、%
和cn2an.an2cn()
在这一个功能中,我们需要将【销售总表.xlsx】按照销售排名拆分成【等级x销售表.xlsx】,并放置在【等级销售表】文件夹中,其中以120人为一个等级。
根据项目概述中对等级划分
功能的描述,可以总结成以下 3 个小步骤,他们分别是:
1)新建一个【等级销售表】文件夹,用于存放生成的【等级x销售表.xlsx】;
2)将【销售总表.xlsx】按照“销售排名”列进行拆分,每 120 人为一个等级,确定等级数量;
3)根据等级数量新建相应数量的工作簿,从等级一开始往后排,写入各个等级的人员销售与排名数据,并保存为【等级x销售表.xlsx】,x 为对应的等级。
等级划分
新建等级销售表文件夹
划分等级之后,不可避免地会出现多个新的工作簿,如果仍和【销售总表.xlsx】以及【销售数据】文件夹存放在同一目录下,会导致查找文件不便。
为了更好地归纳文件,在拆分之前可以先建立一个文件夹用于存放新的工作簿,这里就需要用到os.path.exists()
和os.mkdir()
这两个新知识点。
exists 是“存在”的意思,os.path.exists() 顾名思义是用于判断路径是否存在,括号内写的是文件/文件夹的路径,若路径存在,返回 True,若不存在,则返回 False。
import os # 当前目录下存在test文件夹 print(os.path.exists('./test/')) # 当前目录下不存在test_new文件夹 print(os.path.exists('./test_new/'))
因为【test】文件夹存在,所以会打印 True,而【test_new】文件夹不存在,会打印False。
这个时候如果想要新建一个文件夹,就得用到os.mkdir()
。
dir 是“目录/路径”的意思,故 os.mkdir() 是用于创建目录/路径,os.path.exists()
和os.mkdir()
这两个知识点经常结合着使用。
仍然以上面的情景为例,如果【test_new】文件夹不存在,则新建【test_new】文件夹,代码可以这么写:
import os # 判断是否存在文件夹 path = './test_new/' if not os.path.exists(path): # 新建文件夹 os.mkdir(path)
我们可以看到【static3】文件夹中多了一个【test_new】文件夹。
回到项目本身,如果我们要创建“等级销售表”文件夹,代码应该怎么写呢?
import os path = './等级销售表/' # 判断是否存在文件夹'./等级销售表/',若不存在,则新建'./等级销售表/' if not os.path.exists(path): os.mkdir(path)
确定等级数量
根据康明的需求,每 120 人会划分为一个等级。所以第一步我们要先确定总人数有多少,换个角度思考,其实就是要知道我们前面一直在用的列表 total_rows 有多长。
关于列表的长度,我们可以用len(list)
求得。
确定了总人数,接下来还需要结合运算的结果确定具体需要拆分成几个等级,因此在运算的时候需要用到算术运算符 //
和 %
。
//
用于返回除除法式子的商,可以理解为取整除。
%
则用于返回除法式子的余数,即取模
来串代码看看
print('商:', 10 // 3) print('余数:', 10 % 3)
10 除以 3,得到的商是 3,余数是 1,刚好与代码结果相符。
下面我们取 total_rows 中的前 10 项数据为例进行拆分,每 4 项分为一个等级,
cut = 4 # 取出在汇总排序功能中最后得到的total_rows的一小部分数据 total_rows = [['陈洁', '销售七组', 10393, 815, 2993, 971, 1833, 889, 1128, 8629, 1], ['刘波', '销售七组', 10133, 1496, 2667, 774, 1924, 315, 1142, 8318, 2], ['陈涛', '销售六组', 10140, 1481, 2267, 568, 1989, 1236, 741, 8282, 3], ['张华', '销售二组', 10212, 1395, 2908, 490, 1485, 1149, 837, 8264, 4], ['陈伟', '销售八组', 10427, 1289, 2828, 502, 1279, 1354, 972, 8224, 5], ['李冬梅', '销售六组', 10195, 326, 2946, 886, 1963, 1309, 657, 8087, 6], ['杨秀兰', '销售五组', 10371, 509, 2715, 992, 1394, 1301, 1174, 8085, 7], ['杨林', '销售四组', 10063, 862, 2766, 799, 1611, 964, 1077, 8079, 8], ['李波', '销售一组', 10044, 1380, 2995, 886, 946, 1468, 327, 8002, 9], ['李雪梅', '销售二组', 10078, 1099, 2448, 760, 1574, 1215, 889, 7985, 10]] # 计算等级数量,先整除,得到至少需要拆分的等级数量nums nums = len(total_rows) // cut # 如果余数不为0,则等级数量nums+1,得到最终需要的等级数量 if len(total_rows) % cut != 0: nums += 1 print(nums)
在上面的代码中,第 8 行是先整除计算出等级数量,第 11 到13 行,则是用于判断计算数量等级的时候是否能整除,即余数是否为 0 。如果余数不为 0 ,则等级数量加 1 ,即可得到最终需要的数量等级。
拆分数据并保存工作簿
明确了等级数量,下面开始新建工作簿,写入表头信息,遍历 total_rows 列表,但有一个新的问题,如何实现每 120 人就拆分成一个等级呢?
其实不难,就是做切片,
# 拆分为3个等级 nums = 3 # 每4项为一个等级 cut = 4 # 定义列表 list_info = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 通过遍历拆分成了3个列表 for i in range(nums): # 限定了每个列表最多有cut项 print(list_info[i*cut:(i+1)*cut])
这里第 10 行之所以乘以 cut,是因为我们想以每 4 项切分为一个等级,保证了每一次切片得到的列表最多是 4 项,list_info[i * cut: (i + 1) * cut]
分别取到了list_info[0:4]
,list_info[4:8]
,list_info[8:12]
,因为 list_info 只有 10 项,最多到list_info[9]
,因此list_info[8:12]
实际上就只是取到 list_info 列表的最后两项,得到最后一个等级列表。
回到项目中,我们做一个练习,依旧取前面用的 total_rows 列表的前 10 项,每 4 项拆分为一个等级并写进新工作表,
from openpyxl import Workbook # 每4项拆分为一个等级 cut = 4 # 总共拆成3个等级 nums = 3 # 取出在汇总排序功能中最后得到的total_rows的一小部分数据 total_rows = [['陈洁', '销售七组', 10393, 815, 2993, 971, 1833, 889, 1128, 8629, 1], ['刘波', '销售七组', 10133, 1496, 2667, 774, 1924, 315, 1142, 8318, 2], ['陈涛', '销售六组', 10140, 1481, 2267, 568, 1989, 1236, 741, 8282, 3], ['张华', '销售二组', 10212, 1395, 2908, 490, 1485, 1149, 837, 8264, 4], ['陈伟', '销售八组', 10427, 1289, 2828, 502, 1279, 1354, 972, 8224, 5], ['李冬梅', '销售六组', 10195, 326, 2946, 886, 1963, 1309, 657, 8087, 6], ['杨秀兰', '销售五组', 10371, 509, 2715, 992, 1394, 1301, 1174, 8085, 7], ['杨林', '销售四组', 10063, 862, 2766, 799, 1611, 964, 1077, 8079, 8], ['李波', '销售一组', 10044, 1380, 2995, 886, 946, 1468, 327, 8002, 9], ['李雪梅', '销售二组', 10078, 1099, 2448, 760, 1574, 1215, 889, 7985, 10]] # 按等级数量,拆分等级表 for num in range(nums): # 新建工作表 new_wb = Workbook() new_sheet = new_wb.active # 写入表头 new_sheet.append(['姓名', '销售小组', '工号', '牛奶/瓶', '矿泉水/瓶', '果蔬汁/瓶', '汽水/瓶', '茶饮料/瓶', '咖啡/瓶', '总计/瓶', '销售排名']) # 写入数据 for row in total_rows[num*cut:(num+1)*cut]: new_sheet.append(row) # 保存等级表 new_wb.save('等级{}销售表.xlsx'.format(num + 1))
因为我们每次都提取出来 4 个人的销售数据,每个人的销售数据是一个单独的列表,所以按上面示例第 21 行代码切片得到的实际结果如下所示:
[['陈洁', '销售七组', 10393, 815, 2993, 971, 1833, 889, 1128, 8629, 1], ['刘波', '销售七组', 10133, 1496, 2667, 774, 1924, 315, 1142, 8318, 2], ['陈涛', '销售六组', 10140, 1481, 2267, 568, 1989, 1236, 741, 8282, 3], ['张华', '销售二组', 10212, 1395, 2908, 490, 1485, 1149, 837, 8264, 4]]
[['陈伟', '销售八组', 10427, 1289, 2828, 502, 1279, 1354, 972, 8224, 5], ['李冬梅', '销售六组', 10195, 326, 2946, 886, 1963, 1309, 657, 8087, 6], ['杨秀兰', '销售五组', 10371, 509, 2715, 992, 1394, 1301, 1174, 8085, 7], ['杨林', '销售四组', 10063, 862, 2766, 799, 1611, 964, 1077, 8079, 8]]
[['李波', '销售一组', 10044, 1380, 2995, 886, 946, 1468, 327, 8002, 9], ['李雪梅', '销售二组', 10078, 1099, 2448, 760, 1574, 1215, 889, 7985, 10]]
嵌套的列表并不适合写进新工作表,第 20-22 行增加遍历是为了获取到每个人单独的销售数据也就是单独的小列表,然后再写进新工作表。
最后用 num+1 是因为我们要从等级1开始往后排,而不是从等级 0 开始。
重新看一下,康明在保存为【等级x销售表.xlsx】的时候,x 用的是中文数字,而不是我们项目中的阿拉伯数字。因此引出我们要学习的一个最后一个新知识点——cn2an.an2cn()
,这个用法是很容易的。
在电脑本地运行的时候需要提前安装 cn2an 模块。我们使用pip在cmd/终端中进行安装。
# Windows系统: pip install cn2an # Mac系统: pip3 install cn2an
import cn2an num1 = 101 num2 = '三百六十九' # 将num1转成中文数字 num1_new = cn2an.an2cn(num1) # 讲num2转成阿拉伯数字 num2_new = cn2an.cn2an(num2) print(num1_new) print(num2_new)
可以看到 101 转换成了“一百零一”,”三百六十九”转换成了 369。因此在项目中要想把【等级x销售表.xlsx】中的x换成中文数字,其实就是把保存文件夹代码中的 num+1 先用 cn2an.an2cn() 做转换。
总结
以上,就是功能二的相关知识点,让我们来用思维导图来总结一下吧。
到此这篇关于用Python实现等级划分的文章就介绍到这了,更多相关Python等级划分内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!