作者:小小明
前言
每次年會都與大獎擦肩而過,自認為自己是個絕緣體質,這不是又到了年底了嗎,一個朋友想要做一個“年會抽獎”小工具,這下找到了我,讓給幫忙做一個抽獎程式,于是,有了這篇文章…

效果演示
俗話說:百聞不如一見,說得再好聽,也不如一睹真容,在講述這個小程式之前,我直接上效果圖吧!如果覺得好,記得給本文評論、點贊、轉發,三連擊哦,

這個抽獎程式,第一版我大概倒騰了1小時左右,就弄出來了,一共修改了三版,
- ① 第一版:這里讀取的是一個txt檔案,即所有的姓名都放在一個txt檔案中,抽獎程式是讀取該檔案中的姓名資料,來完成該程序的;
- ② 第二版:增加重置功能;
- ③ 第三版:這是final版本,鑒于大家都把資料存放在Excel中,我這里直接從csv格式的Excel檔案中讀取姓名資料,來完成抽獎這個程序;
功能邏輯敘述
程式已經被打包,不管你電腦有沒有Python環境,拿去就可以用,為了讓大家更明白的使用該程式,我這里還是為大家介紹一些它的使用原理,
當你打開該程式時,會出現如下提示:

提示中提到了一個names.csv檔案 ,這就是你公司員工的姓名資訊資料,你需要將這個程式和這個names.csv檔案,放在同一個作業部錄下,那么之后,整個程式就是基于該檔案中的資料,完成抽獎這個程序的,
如果說你只是想 拿來玩玩兒,你沒有這個names.csv檔案 ,此時,請點擊上圖中的Yes按鈕,那么系統會給出一個提示(如圖所示),自動為你生成若干姓名,用于抽獎,

最終你就可以簡單試玩兒了,

這是我為大家繪制的前置檢查的邏輯流程圖:

使用注意事項
為了讓大家用起來更貼心,我給大家寫出了3條使用建議,如下:
- ① 員工姓名資訊必須保存為CSV格式檔案,并且檔案名必須是names.csv;
- ② 你可以使用WPS或者Office編輯names.csv檔案,檔案表頭會自動跳過,該檔案會自動從第二行讀取第一列的姓名資訊,其他列資料不用洗掉會自動被忽略;
- ③ 針對姓名中出現同名同姓的情況,程式會給出提示并直接退出,建議是個每個同名同姓的值加上編號或部門等額外的區分資訊;
程式生成的names.csv資料檔案結構如下:

自己用辦公軟體WPS或者Office來編輯names.csv檔案時參考下面示例,只需將姓名列放在第一列即可:

其他列的資料都會自動被忽略,
對于出現同名同姓的情況,我們可以這樣命名:

如果同一部門也存在同名同姓,則可以加入其他可以區分的欄位加以區分,
開發流程
我覺得這個開發流程是有必要給你講述一下的,后面如果你有自己獨有的需求,可以繼續在此基礎上,完善這個程式,
1)姓名隨機生成
首先我們開發一些基本的函式,用于隨機姓名的生成,姓名檔案的加載等,創建本地檔案lottery_draw_func.py,完整代碼如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 創建時間:2021/1/16 21:10
__author__ = 'xiaoxiaoming'
import random
def load_name_list(file='names.csv'):
with open(file, encoding="gbk") as f:
next(f) # 跳過標題行
lines = [line.strip().split(",")[0] for line in f]
return lines
def random_name():
xing = '趙錢孫李周吳鄭王馮陳褚衛蔣沈韓楊朱秦尤許何呂施張孔曹嚴華金魏陶姜戚謝鄒喻柏水竇章云蘇潘葛' \
'奚范彭郎魯韋昌馬苗鳳花方俞任袁柳酆鮑史唐費廉岑薛雷賀倪湯滕殷羅畢郝鄔安常樂于時傅皮卞齊康' \
'伍余元卜顧孟平黃和穆蕭尹姚邵湛汪祁毛禹狄米貝明臧計伏成戴談宋茅龐熊紀舒屈項祝董梁杜阮藍閔' \
'席季麻強賈路婁危江童顏郭梅盛林刁鐘徐邱駱高夏蔡田樊胡凌霍虞萬支柯昝管盧莫經房裘繆干解應宗' \
'丁宣賁鄧郁單杭洪包諸左石崔吉鈕龔程嵇邢滑裴陸榮翁荀羊於惠甄曲家封芮羿儲靳汲邴糜松井段富巫' \
'烏焦巴弓牧隗山谷車侯宓蓬全郗班仰秋仲伊宮寧仇欒暴甘鈄厲戎祖武符劉景詹束龍葉幸司韶郜黎薊薄' \
'印宿白懷蒲邰從鄂索咸籍賴卓藺屠蒙池喬陰鬱胥能蒼雙聞莘黨翟譚貢勞逄姬申扶堵冉宰酈雍卻璩桑桂' \
'濮牛壽通邊扈燕冀郟浦尚農溫別莊晏柴瞿閻充慕連茹習宦艾魚容向古易慎戈廖庾終暨居衡步都耿滿弘' \
'匡國文寇廣祿闕東歐殳沃利蔚越夔隆師鞏厙聶晁勾敖融冷訾辛闞那簡饒空曾毋沙乜養鞠須豐巢關蒯相' \
'查后荊紅游竺權逯蓋益桓公萬俟司馬上官歐陽夏侯諸葛聞人東方赫連皇甫尉遲公羊澹臺公冶宗政濮陽' \
'淳于單于太叔申屠公孫仲孫軒轅令狐鐘離宇文長孫慕容鮮于閭丘司徒司空丌官司寇仉督子車顓孫端木' \
'巫馬公西漆雕樂正壤駟公良拓跋夾谷宰父谷梁晉楚閆法汝鄢涂欽段干百里東郭南門呼延歸海羊舌微生' \
'岳帥緱亢況郈有琴梁丘左丘東門西門商牟佘佴伯賞南宮墨哈譙笪年愛陽佟第五言福'
ming = '偉剛勇毅俊峰強軍平保東文輝力明永健世廣志義興良海山仁波寧貴福生龍元全國勝學祥才發武新利清' \
'飛彬富順信子杰濤昌成康星光天達安巖中茂進林有堅和彪博誠先敬震振壯會思群豪心邦承樂紹功松善' \
'厚慶磊民友裕河哲江超浩亮政謙亨奇固之輪翰朗伯宏言若鳴朋斌梁棟維啟克倫翔旭鵬澤晨辰士以建家' \
'致樹炎德行時泰盛秀娟英華慧巧美娜靜淑惠珠翠雅芝玉萍紅娥玲芬芳燕彩春菊蘭鳳潔梅琳素云蓮真環' \
'雪榮愛妹霞香月鶯媛艷瑞凡佳嘉瓊勤珍貞莉桂娣葉璧璐婭琦晶妍茜秋珊莎錦黛青倩婷姣婉嫻瑾穎露瑤' \
'怡嬋雁蓓紈儀荷丹蓉眉君琴蕊薇菁夢嵐苑筠柔竹靄凝曉歡霄楓蕓菲寒欣瀅伊亞宜可姬舒影荔枝思麗秀' \
'飄育馥琦晶妍茜秋珊莎錦黛青倩婷寧蓓紈苑婕馨瑗琰韻融園藝詠卿聰瀾純毓悅昭冰爽琬茗羽希'
result = []
result.append(random.choice(xing))
for i in range(random.randint(1, 2)):
result.append(random.choice(ming))
if random.randint(1, 30) == 1:
result.append(random.choice(ming))
return "".join(result)
def create_random_name(num=10):
result = set()
while len(result) != num:
result.add(random_name())
return list(result)
def write_random_name(num=10, file='names.csv'):
names = create_random_name(num)
with open(file, "w", encoding="gbk") as f:
f.write("name\n")
for name in names:
f.write(f"{name}\n")
if __name__ == '__main__':
write_random_name(40)
lines = load_name_list()
print(lines)
效果圖如下:

2)GUI程式界面開發
然后開發一個gui主程式,用于展示界面,檔案名為lottery_draw.py,部分代碼如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 創建時間:2021/1/16 21:14
__author__ = 'xiaoxiaoming'
import _thread
import os
import random
import sys
import time
from collections import Counter
import PySimpleGUI as sg
from lottery_draw_func import load_name_list, write_random_name
if not os.path.exists("names.csv"):
yes_no = sg.popup_yes_no(
"待抽獎人員姓名名單檔案names.csv沒有找到!!!\n"
"請將所有的待抽獎人員姓名名單保存在names.csv檔案中,\n"
"確認后重啟程式!!!\n"
"或者你是否要讓程式自動幫你生成隨機姓名串列用于測驗?",
title="提示")
if yes_no == "Yes":
num = None
while num is None:
text = sg.popup_get_text("請輸入要生成的姓名個數:", default_text="50")
try:
num = int(text)
except:
sg.popup("您輸入的文本非數字或者點擊了取消,請輸入數字并點擊確認", title="提示")
write_random_name(num)
else:
sys.exit(0)
sg.change_look_and_feel("LightBlue")
file_list_column = [
[sg.Text("待抽獎名單: ", key="in"), ],
[sg.Listbox(values=[], size=(20, 10), key="list1")],
]
image_viewer_column = [
[sg.Text("已中獎名單: ", key="out"), ],
[sg.Listbox(values=[], size=(20, 10), key="list2")],
]
layout = [
[sg.Text('誰是幸運兒?', justification='center', font=('楷體', 30), size=(18, 1))],
[
sg.Column(file_list_column),
sg.VSeperator(),
sg.Column(image_viewer_column),
],
[sg.Text('《《 ', justification='center', size=(16, 1), background_color='skyblue', font=('楷體', 32), key="name")],
[
sg.Button('開始', enable_events=True, key="開始", font=('楷體', 20)),
sg.Button('結束', enable_events=True, key="結束", pad=(60, 0), font=('楷體', 20)),
sg.Button('重置', enable_events=True, key="重置", font=('楷體', 20)),
]
]
names = load_name_list()
counter = Counter(names)
name_count = counter.most_common(1)[0]
if name_count[1] != 1:
sg.popup(f"本地檔案 names.csv 存在同名同姓{name_count[0]},\n請手動改同名同姓加其他的值區分后,再重啟程式繼續", title="提示")
sys.exit(0)
window = sg.Window('年會抽獎程式', layout, finalize=True)
window["in"].update(f"待抽獎名單({len(names)}人):")
winners = []
random.shuffle(names)
if len(names) > 100:
window["list1"].update(names[:100] + ["....", "只展示前100人"])
else:
window["list1"].update(names)
is_run = False
def ring_roll(window):
global is_run
while True:
for name in names:
window['name'].Update(name)
if not is_run:
names.remove(name)
if len(names) > 100:
window["list1"].update(names[:100] + ["....", "只展示前100人"])
else:
window["list1"].update(names)
window["in"].update(f"待抽獎名單({len(names)}人):")
winners.append(name)
window["list2"].update(winners)
window["out"].update(f"已中獎名單({len(winners)}人):")
return
time.sleep(0.05)
while True:
event, values = window.read()
# print(event, values)
if event in (None,):
break # 相當于關閉界面
roll = None
if event == "開始":
if is_run:
sg.popup("抽獎已經在進行中了,請不要重復點擊開始...", title="提示")
continue
is_run = True
_thread.start_new_thread(ring_roll, (window,))
elif event == "結束":
is_run = False
elif event == "重置":
if is_run:
sg.popup("抽獎已經在進行中了,請結束后再進行重置操作...", title="提示")
continue
yes_no = sg.popup_yes_no('該操作會清空所有已中獎名單,并隨機排序待抽獎名單,\n是否繼續?', title="提示")
if yes_no == "Yes":
names.extend(winners)
winners.clear()
random.shuffle(names)
if len(names) > 100:
window["list1"].update(names[:100] + ["....", "只展示前100人"])
else:
window["list1"].update(names)
window["list2"].update(winners)
window["in"].update(f"待抽獎名單({len(names)}人):")
window["out"].update(f"已中獎名單:")
window.close()
經過簡單測驗,沒有問題后,我們開始打包程式,以便于任何人拿著程式就可以用,
程式打包exe
首先我們準備好一個圖示檔案,這個既可以通過一些網站下載,或者可以通過一些在線網站將普通圖示轉成圖示,
這里呢,我將使用我10年前上初中時開發的一個小工具:

直接將圖片往自動轉換區一拖動,然后桌面上就生成了相應的圖示,
接下來,將該圖示重命名為a.ico后,移動到和程式在相同的檔案夾下,就可以進行打包操作了,
命令列輸入:
pyinstaller -wF lottery_draw.py -i a.ico
點擊回車后,便順利的完成打包操作,部分截圖如下:

檔案大小也只有9MB:

后面我就把程式發給朋友了,朋友使用之后覺得挺滿意的,還給我發了個紅包:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250292.html
標籤:python
上一篇:逆向win.pyc
