Python怎么实现一个随机抽奖小工具
Python怎么实现一个随机抽奖小工具
这篇文章主要介绍“Python怎么实现一个随机抽奖小工具”,在日常操作中,相信很多人在Python怎么实现一个随机抽奖小工具问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么实现一个随机抽奖小工具”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
先看效果:
1. 核心功能设计
针对随机抽奖的小工具,需要可以导入参与抽奖的人员名单,然后选择不同的奖励类型进行随机抽取获奖名单并导出。
那么,简单进行需求拆解,大致梳理出以下核心功能:
名单导入
为了避免出现重名情况,这里我们约定以下几点:
①导入参与抽奖的人员名单文件(xlsx
类型文件)
②数据第一列为ID,第二列为name
参考格式案例
奖项类型选择
奖项类型是指一等奖、二等奖这类标识语,这里我们内置了特等奖-六等奖共7个选项供选取
本轮人数
本轮人数是指每次抽奖时一次性抽取的获奖人数,默认值为5
①当填入的数字超过剩余未获奖人数时,会进行提示并显示未获奖人数
②当填入的数字为0表示轮空,也需要手动结束
③当填入的数字为负数时,点击抽奖无响应
④当填入的非数字时,会进行提示需要输入正确数字
抽奖时轮播区域
用于显示抽奖中随机滚动参与本轮抽奖的人员名单
人员名单
当选择正确的人员名单文件后,这里会自动显示人员信息列表
中奖记录
记录每次抽取的奖项类型及获奖名单
开始抽奖
①开始抽奖时,会先判断抽奖设置是否满足条件,否则会有相关提示
②抽奖中点击开始抽奖会提示正在抽奖中
结束
①非抽奖状态下点击结束无响应
②抽奖中点击结束将显示本次抽奖结果
重置
①重置会清掉历史抽奖记录(含本地文件,如有必要建议对中奖名单留档)
②抽奖中点击重置会提示正在抽奖中
③非抽奖状态点击重置会提示该操作会删除历史记录,是否确认
基本功能点确认后,我们就开始进行GUI设计。
2. GUI设计与实现
基于功能点,我们用axure
简单进行UI布局设计
,然后再通过GUI
开发库进行设计,这里依旧采用的是pysimplegui
,主要是简单方便。
基于GUI设计,我们编码如下:
nameList_column=[[sg.Text("人员名单:")],[sg.Listbox(values=[],size=(20,10),key="nameList")],]result_column=[[sg.Text("中奖记录:")],[sg.Multiline("",size=(48,10),key="result",text_color="DeepPink")],]#主题设置sg.theme("SystemDefaultForReal")#布局设置layout=[[sg.Text("选择参与抽奖人员名单文件:",font=("微软雅黑",12)),sg.InputText("",key="_file",size=(50,1),font=("微软雅黑",10),enable_events=True),sg.FileBrowse("打开",file_types=(("TextFiles","*.xlsx"),),size=(10,1),font=("微软雅黑",11))],[sg.Frame(layout=[[sg.Text("本轮奖项:",font=("微软雅黑",12)),sg.Combo(["特等奖","一等奖","二等奖","三等奖","四等奖","五等奖","六等奖"],font=("微软雅黑",10),default_value="特等奖",size=(15,5),key="_type"),sg.Text("本轮人数:",font=("微软雅黑",12)),sg.InputText("5",key="_num",size=(38,1),font=("微软雅黑",10))],],title="抽奖设置",title_color="red",relief=sg.RELIEF_SUNKEN,tooltip="请进行抽奖设置后再开始抽奖")],[sg.Multiline(size=(48,5),font=("微软雅黑",18),text_color="Blue",key="luckyName",justification="center")],[sg.Column(nameList_column),sg.Column(result_column)],[sg.Text("操作说明:",font=("微软雅黑",12))],[sg.Text("①先选择参与抽奖的人员名单xlsx文件,人员名单文件包含ID和name两个字段②获奖名单将存在小工具所在文件夹,重置会删除历史记录文件",font=("微软雅黑",10)),sg.Text("",font=("微软雅黑",12),size=(5,1)),sg.Button("开始抽奖",font=("微软雅黑",12),button_color="Orange"),sg.Button("结束",font=("微软雅黑",12),button_color="red"),sg.Button("重置",font=("微软雅黑",12),button_color="red"),],]#创建窗口window=sg.Window("抽奖小工具,作者@微信公众号:可以叫我才哥",layout,font=("微软雅黑",12),default_element_size=(50,1))
其包含的控件如下:
Text 文本
InputText 输入文本框
FileBrowse 文件浏览
Multiline 多行文本框
Combo 下拉框
Listbox 列表
Button 按钮
需要注意的是这里有个Frame组件,用于layout嵌套,可以很好地模块化UI布局。
3. 功能实现
在本案例中,需要实现三个功能,分别是:读取人员名单、随机抽奖以及保存中奖名单。
3.1 读取人员名单
这里采用的是openpyxl
读取表格数据并获得某几列的值,由于存在表头,所以最后不需要表头
defnameList(window):fileName=values["_file"]try:wb=openpyxl.load_workbook(fileName)active_sheet=wb.activenames=[cell_object.valueforcell_objectinlist(active_sheet.columns)[1]][1:]ids=[cell_object.valueforcell_objectinlist(active_sheet.columns)[0]][1:]names=[name+"_"+str(id_)forname,id_inzip(names,ids)]window["nameList"].update(names)returnnamesexcept:sg.popup("请选择正确格式的的人员名单文件",title="提示",)
3.2. 随机抽奖
由于我们需要一次随机抽取的人数存在多个,所以这里用的是random.sample()
,需要注意的是传入的参数中names是需要去掉已中奖名单
defResult(window,names):globalis_run,luckyNames_type=values["_type"]#本轮奖项类型_num=int(values["_num"])#本轮人数whileTrue:randomName=random.sample(names,k=_num)luckyName="".join(randomName)window["luckyName"].update(luckyName)ifnotis_run:headers=["奖项","名单"]toCsv(headers,[_type]*len(randomName),randomName,lucky)luckyNames=luckyNames+_type+":"+luckyName+""window["result"].update(luckyNames)returntime.sleep(0.088)
3.3. 保存中奖名单
这里我们用的是csv
库的方法,追加存储
deftoCsv(headers,col1,col2,file):#存在则追加,不存在则新建ifos.path.exists(lucky):withopen(lucky,"a",encoding="utf_8_sig",newline="")ascsvfile:writer=csv.writer(csvfile)writer.writerows(zip(col1,col2))else:withopen(lucky,"w",encoding="utf_8_sig",newline="")ascsvfile:writer=csv.writer(csvfile)writer.writerow(headers)writer.writerows(zip(col1,col2))
完成核心功能函数后,我们再进行GUI交互逻辑的实现。
3.4. GUI交互逻辑
这里有两个全局变量,其中一个用于记录当前抽奖状态,另外一个用于存储当前已经获奖的人员信息。关于交互逻辑的详情,大家可以结合核心功能需求及以下代码了解。
#初始状态is_run=FalseluckyNames=""#事件循环whileTrue:event,values=window.read()ifeventin(None,"关闭程序"):breakifevent=="_file":nameList(window)ifevent=="开始抽奖":ifis_run:sg.popup("抽奖进行中,无需重复操作......",title="提示")continuetry:names=nameList(window)#人员名单_num=int(values["_num"])#本轮人数lucky="中奖名单.csv"#中奖名单ifos.path.exists(lucky):withopen("中奖名单.csv","r",encoding="utf_8_sig")asf:reader=csv.reader(f)selectedNames=set([i[1]foriinreader][1:])names_set=set(names)-selectedNameselse:names_set=set(names)iflen(names_set)>=_num:is_run=True_thread.start_new_thread(Result,(window,names_set))else:sg.popup(f"请选择正确本轮抽奖人数(当前{len(names_set)}个未中奖人数)",title="提示")except:sg.popup("请选择正确本轮抽奖人数(别超过总人数哦)",title="提示")elifevent=="结束":is_run=Falseelifevent=="重置":ifis_run:sg.popup("抽奖进行中,请等待抽奖结束后重置...",title="提示")continueyes_no=sg.popup_yes_no("重置会清楚历史数据,是否执行此操作??",text_color="red",title="提示")ifyes_no=="Yes":try:os.remove(lucky)luckyNames=""window["result"].update(luckyNames)window["luckyName"].update(luckyNames)sg.popup("抽奖历史记录已被重置......",title="提示")except:sg.popup("无抽奖历史记录......",title="提示")window.close()
基于此,我们就完成了随机抽奖小工具的制作。
启动页如下:
到此,关于“Python怎么实现一个随机抽奖小工具”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!
推荐阅读
-
python(中无效的十进制怎么解决 python怎么转换进制)
python怎么转换进制?Python执行二进制转换:1.十进制到二进制(bin)首先,让让我们看看如何将十进制转换成二进制。我...
-
python怎么清除完全相同的行(python splte如何分隔有多个相同符号的str)
pythonsplte如何分隔有多个相同符号的str?str你的string内容str_(相同的符号)执行完了以后再在相同符号的...
-
python(编程控制电脑关机 如何控制电脑关机)
如何控制电脑关机?可以在电脑的运行窗口中输入输入公式,给电脑可以设置自动关机。1.按开快捷键winr然后打开运行窗口。2.在运行窗...
-
python中的特殊标识符(python 中 标识符中可以有逗号吗)
python中标识符中可以有逗号吗?在python语言中合法的标识符是字母、数字以及_,所以我合法的标识符中肯定不能有逗号if...
-
python(excel 提取数据写入新表 python导入excel数据找不到工作簿)
python导入excel数据找不到工作簿?我可以导入数据后找不到工作,不是因为他的工作没有被转移。什么软件可提取并合并Exce...
-
python中字典定义的四种方法(python global关键字的用法详解)
pythonglobal关键字的用法详解?global标志实际上是目的是提示python讲解器,说被其修饰的变量是全局变量。这样...
-
python(array用法 python如何对两个数组做差处理)
python如何对两个数组做差处理?Python中的列表中的元素肯定不能真接相加,减。t最佳的位置的是将列表装换成Python中的...
-
python多行注释符号怎么表示
python多行注释符号怎么表示这篇文章主要介绍“python多行...
-
python支持的操作系统是什么
python支持的操作系统是什么这篇文章主要介绍“python支持...
-
python如何判断列表为空
python如何判断列表为空这篇文章主要介绍“python如何判断...