Python怎么实现一个随机抽奖小工具

发布时间:2022-03-29 16:12:36 作者:iii
来源:亿速云 阅读:259

这篇文章主要介绍“Python怎么实现一个随机抽奖小工具”,在日常操作中,相信很多人在Python怎么实现一个随机抽奖小工具问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么实现一个随机抽奖小工具”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

先看效果:

Python怎么实现一个随机抽奖小工具

1. 核心功能设计

针对随机抽奖的小工具,需要可以导入参与抽奖的人员名单,然后选择不同的奖励类型进行随机抽取获奖名单并导出。

那么,简单进行需求拆解,大致梳理出以下核心功能:

名单导入

为了避免出现重名情况,这里我们约定以下几点:

①导入参与抽奖的人员名单文件(xlsx类型文件)

②数据第一列为ID,第二列为name

参考格式案例

Python怎么实现一个随机抽奖小工具

奖项类型选择

奖项类型是指一等奖、二等奖这类标识语,这里我们内置了特等奖-六等奖共7个选项供选取

本轮人数

本轮人数是指每次抽奖时一次性抽取的获奖人数,默认值为5

①当填入的数字超过剩余未获奖人数时,会进行提示并显示未获奖人数

②当填入的数字为0表示轮空,也需要手动结束

③当填入的数字为负数时,点击抽奖无响应

④当填入的非数字时,会进行提示需要输入正确数字

抽奖时轮播区域

用于显示抽奖中随机滚动参与本轮抽奖的人员名单

人员名单

当选择正确的人员名单文件后,这里会自动显示人员信息列表

中奖记录

记录每次抽取的奖项类型及获奖名单

开始抽奖

①开始抽奖时,会先判断抽奖设置是否满足条件,否则会有相关提示

②抽奖中点击开始抽奖会提示正在抽奖中

结束

①非抽奖状态下点击结束无响应

②抽奖中点击结束将显示本次抽奖结果

重置

①重置会清掉历史抽奖记录(含本地文件,如有必要建议对中奖名单留档)

②抽奖中点击重置会提示正在抽奖中

③非抽奖状态点击重置会提示该操作会删除历史记录,是否确认

基本功能点确认后,我们就开始进行GUI设计。

2. GUI设计与实现

基于功能点,我们用axure简单进行UI布局设计,然后再通过GUI开发库进行设计,这里依旧采用的是pysimplegui,主要是简单方便。

Python怎么实现一个随机抽奖小工具

基于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=(("Text Files", "*.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))

其包含的控件如下:

需要注意的是这里有个Frame组件,用于layout嵌套,可以很好地模块化UI布局。

3. 功能实现

在本案例中,需要实现三个功能,分别是:读取人员名单、随机抽奖以及保存中奖名单。

3.1 读取人员名单

这里采用的是openpyxl读取表格数据并获得某几列的值,由于存在表头,所以最后不需要表头

def nameList(window):
    fileName = values["_file"]
    try:
        wb = openpyxl.load_workbook(fileName)
        active_sheet = wb.active
        names = [cell_object.value for cell_object in list(active_sheet.columns)[1]][1:]
        ids = [cell_object.value for cell_object in list(active_sheet.columns)[0]][1:]
        names = [name+"_"+str(id_) for name, id_ in zip(names, ids)]
        window["nameList"].update(names)
        return names
    except:
        sg.popup("请选择正确格式的的人员名单文件", title="提示",)

3.2. 随机抽奖

由于我们需要一次随机抽取的人数存在多个,所以这里用的是random.sample(),需要注意的是传入的参数中names是需要去掉已中奖名单

def Result(window, names):
    global is_run, luckyNames
    _type = values["_type"]                # 本轮奖项类型
    _num = int(values["_num"])             # 本轮人数

    while True:
        randomName = random.sample(names, k=_num)
        luckyName = "   ".join(randomName)
        window["luckyName"].update(luckyName)

        if not is_run:
            headers = ["奖项", "名单"]
            toCsv(headers, [_type]*len(randomName), randomName, lucky)
            luckyNames = luckyNames + _type+" : "+luckyName+"

"
            window["result"].update(luckyNames)
            return
        time.sleep(0.088)

3.3. 保存中奖名单

这里我们用的是csv库的方法,追加存储

def toCsv(headers, col1, col2, file):
    # 存在则追加,不存在则新建
    if os.path.exists(lucky):
        with open(lucky, "a", encoding="utf_8_sig", newline="") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows(zip(col1, col2))
    else:
        with open(lucky, "w", encoding="utf_8_sig", newline="") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(headers)
            writer.writerows(zip(col1, col2))

完成核心功能函数后,我们再进行GUI交互逻辑的实现。

3.4. GUI交互逻辑

这里有两个全局变量,其中一个用于记录当前抽奖状态,另外一个用于存储当前已经获奖的人员信息。关于交互逻辑的详情,大家可以结合核心功能需求及以下代码了解。

# 初始状态
is_run = False
luckyNames = ""

# 事件循环
while True:
    event, values = window.read()
    if event in (None, "关闭程序"):
        break
    if event == "_file":
        nameList(window)

    if event == "开始抽奖":
        if is_run:
            sg.popup("抽奖进行中,无需重复操作......", title="提示")
            continue
        try:
            names = nameList(window)               # 人员名单
            _num = int(values["_num"])             # 本轮人数
            lucky = "中奖名单.csv"                 # 中奖名单
            if os.path.exists(lucky):
                with open("中奖名单.csv", "r", encoding="utf_8_sig") as f:
                    reader = csv.reader(f)
                    selectedNames = set([i[1] for i in reader][1:])
                names_set = set(names)-selectedNames
            else:
                names_set = set(names)
            if len(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="提示")
    elif event == "结束":
        is_run = False
    elif event == "重置":
        if is_run:
            sg.popup("抽奖进行中,请等待抽奖结束后重置...", title="提示")
            continue
        yes_no = sg.popup_yes_no(
            "重置会清楚历史数据,是否执行此操作??", text_color="red", title="提示")
        if yes_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怎么实现一个随机抽奖小工具”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. 安卓用线程实现随机抽奖
  2. js怎么实现随机抽奖

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:Python容错的前缀树怎么实现中文纠错

下一篇:python面向对象之类的继承怎么实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》