引言

马上就要举行年会抽奖了,我们都不知道是否有人能够中奖。我觉得无聊的时候可以尝试自己写一个抽奖系统,主要是为了娱乐。现在人工智能这么方便,写一个简单的代码不是一件困难的事情。今天我想和大家一起构建一个简易的抽奖系统,这样也能够巩固一下我自己对Python语法和框架的理解。

今天我们将继续使用Python语言进行开发,并且使用最简单的HTML、JS、CSS来配置样式和界面。在Python中,我们将使用一个名为fastapi的第三方框架,虽然这是我第一次接触它,但我发现它真的非常方便使用,简直就像是把飞机开在马路上一样。与使用Spring框架相比,fastapi让搭建过程变得轻松愉快。

这个抽奖系统的业务逻辑其实非常简单。首先,我们需要一个9宫格的页面,用户可以在页面上添加参与人员。虽然我们可以使用数据库来存储参与人员的信息,但为了方便演示,我选择了简单地使用内存存储。

在这个系统中,除了保证每个人只有一个参与机会外,其他的校验要求都很少。然后,用户可以通过点击开始按钮,页面会随机停下来,然后将停下来的奖项传给后台并保存,最后在前端页面上显示。

虽然逻辑简单,但是通过这个抽奖系统的开发,我们可以巩固自己对Python语法和框架的理解,同时也能够体验到人工智能带来的便利。让我们一起动手搭建这个简易版的抽奖系统吧!

前端界面

尽管前端界面写得不够出色,但这并非我今天的重点。实际上,我想回顾一下Python的编写方式和框架的理解。我创建了一个简单的九宫格,每个格子都设有不同的奖项,而且用户还可以手动进行设置和修改,从而保证了灵活性。

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>抽奖系统</title>
<link rel="stylesheet" href="/static/css/styles.css">
<script src="/static/js/main.js"></script>
</head>
<body>
<h1>欢迎来到小雨抽奖系统</h1>
<form id="participant-form">
<label for="participant-name">参与者姓名:</label>
<input type="text" id="participant-name" name="participant-name" required>
<button type="submit">添加参与者</button>
</form>
<div id="grid">
<div class="grid-item" data-prize="奖项1">奖项1</div>
<div class="grid-item" data-prize="奖项2">奖项2</div>
<div class="grid-item" data-prize="奖项3">奖项3</div>
<div class="grid-item" data-prize="奖项4">奖项4</div>
<div class="grid-item" data-prize="奖项5">奖项5</div>
<div class="grid-item" data-prize="奖项6">奖项6</div>
<div class="grid-item" data-prize="奖项7">奖项7</div>
<div class="grid-item" data-prize="奖项8">奖项8</div>
<div class="grid-item" data-prize="奖项9">奖项9</div>
</div>
<button id="draw-button">抽奖</button>
<h2>获奖名单</h2>
<ul id="prize-list"></ul>
<script>
document.getElementById('participant-form').addEventListener('submit', function(event) {
event.preventDefault();
var participantName = document.getElementById('participant-name').value;
fetch('/participant', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({name: participantName}),
})
.then(response => response.json())
.then(data => {
console.log(data);
document.getElementById('participant-name').value = '';
})
.catch((error) => {
console.error('Error:', error);
});
}); document.getElementById('draw-button').addEventListener('click', function() {
var items = document.getElementsByClassName('grid-item');
var index = 0;
var interval = setInterval(function() {
items[index].classList.remove('active');
index = (index + 1) % items.length;
items[index].classList.add('active');
}, 100);
setTimeout(function() {
clearInterval(interval);
var prize = items[index].getAttribute('data-prize');
fetch('/draw', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({prize: prize}),
})
.then(response => response.json())
.then(data => {
console.log(data);
if (data.code !== 1) {
alert(data.message);
} else {
var li = document.createElement("li");
li.appendChild(document.createTextNode(data.message));
document.getElementById('prize-list').appendChild(li);
}
})
.catch((error) => {
console.error('Error:', error);
});
}, Math.floor(Math.random() * (10000 - 3000 + 1)) + 3000);
});
</script>
</body>
</html>
</h2></button></title>

CSS样式主要用于配置9个宫格的显示位置和实现动态动画高亮效果。除此之外,并没有对其他效果进行配置。如果你有兴趣,可以在抽奖后自行添加一些炫彩烟花等效果,完全取决于你的发挥。

代码如下:

body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
} h1, h2 {
color: #333;
} form {
margin-bottom: 20px;
} #participant-form {
display: flex;
justify-content: center;
margin-top: 20px;
} #participant-form label {
margin-right: 10px;
} #participant-form input {
margin-right: 10px;
} #participant-form button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
} #draw-button {
display: block;
width: 200px;
height: 50px;
margin: 20px auto;
background-color: #f44336;
color: white;
border: none;
text-align: center;
line-height: 50px;
font-size: 20px;
cursor: pointer;
} #grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px;
width: 300px;
height: 300px;
margin: 0 auto; /* This will center the grid horizontally */
} .grid-item {
width: 100%;
height: 100%;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
} .grid-item.active {
background-color: yellow;
} #prize-list {
list-style-type: none;
padding: 0;
width: 80%;
margin: 20px auto;
} #prize-list li {
padding: 10px;
border-bottom: 1px solid #ccc;
}

Python后台

在我们的Python后端中,我们选择使用了fastapi作为框架来接收请求。这个框架有很多优点,其中最重要的是它的速度快、简单易懂。但唯一需要注意的是,在前端向后端传递请求参数时,请求头必须包含一个json的标识。如果没有这个标识,后端将无法正确接收参数,并可能报错。

为了更好地优化我们的后端,如果你有足够的时间,可以考虑集成数据库等一些重量级的操作。这样可以更好地处理数据,并提供更多功能。

主要的Python代码如下:

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
# from models import Participant, Prize
# from database import SessionLocal, engine
from pydantic import BaseModel
from random import choice app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates")
prizes = []
participants = [] class Participant(BaseModel):
name: str class Prize(BaseModel):
winner: str
prize: str class DatePrize(BaseModel):
prize: str @app.get("/")
async def root(request: Request):
return templates.TemplateResponse("index.html", {"request": request}) @app.post("/participant")
async def add_participant(participant: Participant):
participants.append(participant)
return {"message": "Participant added successfully"} @app.post("/draw")
async def draw_prize(date_prize: DatePrize):
if not participants:
return {"message": "No participants available","code":0}
winner = choice(participants)
prize = Prize(winner=winner.name,prize=date_prize.prize)
prizes.append(prize)
participants.remove(winner)
return {"message": f"Congratulations {winner.name}, you have won a prize : {date_prize.prize}!","code":1} @app.get("/prizes")
async def get_prizes():
return {"prizes": [prize.winner for prize in prizes]} @app.get("/participants")
async def get_participants():
return {"participants": [participant.name for participant in participants]}

由于我使用的是poetry作为项目的运行工具,因此在使用之前,你需要进行一些配置工作。

[tool.poetry]
name = "python-lottery"
version = "0.1.0"
description = "python 抽奖"
authors = ["努力的小雨"] [tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.105.0"
jinja2 = "^3.1.2" [[tool.poetry.source]]
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple/"
default = true
secondary = false

启动项目命令:poetry run uvicorn main:app --reload --port 8081

效果图

总结

在本文中,我们使用Python语言和fastapi框架构建了一个简易的抽奖系统。系统的前端界面使用了HTML、JS和CSS来配置样式和实现交互效果。后端使用了fastapi框架接收前端的请求,并处理抽奖逻辑。

说实话,虽然我们有能力开发一个简易的抽奖系统,但既然我们都是程序员,为何要费力去搞一个抽奖系统呢?我们可以采用更简单的方式,将每个人的序号写在纸条上,放进一个纸箱子里,然后让领导亲自用手抓取。这样做不仅更可靠,还能增加年会的活跃氛围。

手把手教你用python做一个年会抽奖系统的更多相关文章

  1. 【震惊】手把手教你用python做绘图工具(一)

    在这篇博客里将为你介绍如何通过numpy和cv2进行结和去创建画布,包括空白画布.白色画布和彩色画布.创建画布是制作绘图工具的前提,有了画布我们就可以在画布上尽情的挥洒自己的艺术细胞. 还在为如何去绘 ...

  2. 用 python 写一个年会抽奖小程序

    使用 pyinstaller 打包工具常用参数指南 pyinstaller -F demo.py 参数 含义 -F 指定打包后只生成一个exe格式的文件 -D –onedir 创建一个目录,包含exe ...

  3. 动手实践丨手把手教你用STM32做一个智能鱼缸

    摘要:本文基于STM32单片机设计了一款基于物联网的智能鱼缸. 本文分享自华为云社区<基于STM32+华为云IOT设计的物联网鱼缸[玩转华为云]>,作者: DS小龙哥 . 1. 前言 为了 ...

  4. 手把手教你吧Python应用到实际开发 不再空谈悟法☝☝☝

    手把手教你吧Python应用到实际开发 不再空谈悟法☝☝☝ 想用python做机器学习吗,是不是在为从哪开始挠头?这里我假定你是新手,这篇文章里咱们一起用Python完成第一个机器学习项目.我会手把手 ...

  5. 手把手教你吧Python应用到实际开发 不再空谈悟法✍✍✍

    手把手教你吧Python应用到实际开发 不再空谈悟法 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问 ...

  6. 手把手教你把Python应用到实际开发 不再空谈语法

    手把手教你把Python应用到实际开发 不再空谈语法 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问 ...

  7. 手把手教你使用Python爬取西刺代理数据(下篇)

    /1 前言/ 前几天小编发布了手把手教你使用Python爬取西次代理数据(上篇),木有赶上车的小伙伴,可以戳进去看看.今天小编带大家进行网页结构的分析以及网页数据的提取,具体步骤如下. /2 首页分析 ...

  8. 12岁的少年教你用Python做小游戏

    首页 资讯 文章 频道 资源 小组 相亲 登录 注册       首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...

  9. 手把手教你使用FineUI开发一个b/s结构的取送货管理信息系统系列博文索引

    近阶段接到一些b/s类型的软件项目,但是团队成员之前大部分没有这方面的开发经验,于是自己选择了一套目前网上比较容易上手的开发框架(FineUI),计划录制一套视频讲座,来讲解如何利用FineUI快速开 ...

  10. 手把手教你用vue-cli构建一个简单的路由应用

    上一章说道:十分钟上手-搭建vue开发环境(新手教程)https://www.jianshu.com/p/0c6678671635 开发环境搭建好之后,那么开始新添加一些页面,构建最基本的vue项目, ...

随机推荐

  1. ELK环境部署-Filebeat数据收集(三)

    一.安装JAVA环境 1.解压jdk压缩包 abc@elk:~$ sudo tar -zxvf jdk-11.0.18_linux-x64_bin.tar.gz -c jdk11 2.添加环境变量 a ...

  2. 一个.NET 7 + DDD + CQRS +React+Vite的实战项目

    项目简介 基于SignalR实现聊天通信,支持横向扩展,可支撑上万用户同时在线聊天 后端架构 后端技术栈采用 .NET 7 PostgreSQL (业务数据库) Redis(用于存放热点数据,和支持S ...

  3. redhat7查找已接网线但是还未配置IP的网卡接口

    方法一:nmcli 输出中参数WIRED-PROPERTIES.CARRIER为on即为接网线网卡 #nmcli device show |grep -i -E "device|carrie ...

  4. js详细讲解放大镜的实现

    实现放大镜的整体思路 1.当鼠标放在图片上的时候,出现蒙层. 2.出现蒙层,让鼠标在蒙层中心 3.限制蒙层移动的范围 4.放大镜移动 最终实现的效果 鼠标放上去的时候,出现一个蒙层. 蒙层的移动范围只 ...

  5. WPF中的DesignerProperties

    在WPF开发过程中,最容易遇到的一个问题:就是在自定义控件的过程中写好业务逻辑后,在调用的地方,打开.xmal文件设计器时出现异常,经过排查发现是由于自定义控件初始化过程中需要进行赋值操作.为了能够让 ...

  6. Linux挂载新磁盘

    Linux挂载新磁盘 1. 查看磁盘 # df -lh # 查看磁盘占用情况,同时可以查看已挂载的磁盘及其挂载位置 # fdisk -l # 查看所有的磁盘分区 图中 /dev/sdb 下无分区信息, ...

  7. 【c#版本Openfeign】Net8 自带OpenFeign实现远程接口调用

    引言 相信巨硬,我们便一直硬.Net版本到现在已经出了7了,8也已经在预览版了,相信在一个半月就会正式发布,其中也有很多拭目以待的新功能了,不仅仅有Apm和Tap的结合,TaskToAscynResu ...

  8. 素数是个什么东西 prime number

    /**  * *********************************************************************  * 只有1和它本身两个正因数的自然数,叫质数 ...

  9. ChatGPT API Transition Guide

    ChatGPT API Transition Guide How to get started Written by Joshua J.. Updated over a week ago Prompt ...

  10. 报Bug的礼仪

    不要对1个程序员说:你的代码有Bug.他的第1反应是:1.你的环境有问题吧:2.傻逼你会用吗? 如果你委婉的说:你这个程序和预期的有点不1致,你看看是不是我的打开姿势有问题?他本能的会想:擦,是不是出 ...