引言

马上就要举行年会抽奖了,我们都不知道是否有人能够中奖。我觉得无聊的时候可以尝试自己写一个抽奖系统,主要是为了娱乐。现在人工智能这么方便,写一个简单的代码不是一件困难的事情。今天我想和大家一起构建一个简易的抽奖系统,这样也能够巩固一下我自己对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. PC首页资源加载速度由8s降到2s的优化实践

    随着需求的不断开发,前端项目不断膨胀,业务提出:你们的首页加载也太慢啦,我都需要7.8秒才能看到内容,于是乎主管就让我联合后端开启优化专项,目标是3s内展示完全首页的内容. 性能指标 开启优化时,我们 ...

  2. 使用 PDF一机一码加密大师,加密打包PDF文件(一机一码,绑定机器,无需额外安装阅读器)

    PDF一机一码加密大师, 可以加密任意PDF文档,添加一机一码授权, 静态密码等, 可以禁止用户复制,打印PDF文档中的内容,并且加密生成的PDF在其他用户电脑上无需安装第三方阅读器即可直接阅读. 下 ...

  3. HTML一键打包IPA(苹果IOS应用)工具 网站打包 APP

    工具简介 HTML一键打包IPA(苹果应用)工具可以把本地HTML项目或者网站打包为一个苹果应用IPA文件,无需编写任何代码,支持在苹果设备上安装运行. 该软件已经被GDB苹果网页一键打包工具取代,详 ...

  4. Spring Boot虚拟线程与Webflux在JWT验证和MySQL查询上的性能比较

    早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错.内容较长,我就不翻译了,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读. 测试场景 作者采用了一个尽 ...

  5. Ubuntu22.04 编译安装nginx

    1.下载nginx软件包 https://nginx.org/en/download.html 2.压缩包上传服务器并解压缩 tar xf nginx-1.22.1.tar.gz 3.进入解压目录,编 ...

  6. tensorboard可视化点云

    tensorboard可视化点云 用 tensorboard 自带的 add_mesh 方法:支持可视化点云和网格,参考链接: tensorflow 网站的tensorboard pytorch 网站 ...

  7. Android历史版本

    目录 [隐藏]  1 测试版 2 版本列表 2.1 Android 1.0 2.2 Android 1.1 2.3 Android 1.5 Cupcake 2.4 Android 1.6 Donut ...

  8. 基于SpringBoot+Netty实现即时通讯(IM)功能

    简单记录一下实现的整体框架,具体细节在实际生产中再细化就可以了. 第一步 引入netty依赖 SpringBoot的其他必要的依赖像Mybatis.Lombok这些都是老生常谈了 就不在这里放了 &l ...

  9. Swagger系列:SpringBoot3.x中使用Knife4j

    目录 一.简介 二.版本说明 三.使用 四.效果图 一.简介 官网:https://doc.xiaominfo.com/ Knife4j是一个集Swagger2 和 OpenAPI3 为一体的增强解决 ...

  10. 一个Unity富文本插件的实现思路

    项目中原来的富文本组件不太好用,做了一些修改,记述主要思路.缺陷很多. 仅适用于没用TextMeshPro,且不打算用的项目,否则请直接用TextMeshPro 原组件特点: 使用占位符模式,创建新的 ...