手把手教你用python做一个年会抽奖系统
引言
馬上就要舉行年會(huì)抽獎(jiǎng)了,我們都不知道是否有人能夠中獎(jiǎng)。我覺得無聊的時(shí)候可以嘗試自己寫一個(gè)抽獎(jiǎng)系統(tǒng),主要是為了娛樂。現(xiàn)在人工智能這么方便,寫一個(gè)簡(jiǎn)單的代碼不是一件困難的事情。今天我想和大家一起構(gòu)建一個(gè)簡(jiǎn)易的抽獎(jiǎng)系統(tǒng),這樣也能夠鞏固一下我自己對(duì)Python語法和框架的理解。
今天我們將繼續(xù)使用Python語言進(jìn)行開發(fā),并且使用最簡(jiǎn)單的HTML、JS、CSS來配置樣式和界面。在Python中,我們將使用一個(gè)名為fastapi的第三方框架,雖然這是我第一次接觸它,但我發(fā)現(xiàn)它真的非常方便使用,簡(jiǎn)直就像是把飛機(jī)開在馬路上一樣。與使用Spring框架相比,fastapi讓搭建過程變得輕松愉快。
這個(gè)抽獎(jiǎng)系統(tǒng)的業(yè)務(wù)邏輯其實(shí)非常簡(jiǎn)單。首先,我們需要一個(gè)9宮格的頁(yè)面,用戶可以在頁(yè)面上添加參與人員。雖然我們可以使用數(shù)據(jù)庫(kù)來存儲(chǔ)參與人員的信息,但為了方便演示,我選擇了簡(jiǎn)單地使用內(nèi)存存儲(chǔ)。
在這個(gè)系統(tǒng)中,除了保證每個(gè)人只有一個(gè)參與機(jī)會(huì)外,其他的校驗(yàn)要求都很少。然后,用戶可以通過點(diǎn)擊開始按鈕,頁(yè)面會(huì)隨機(jī)停下來,然后將停下來的獎(jiǎng)項(xiàng)傳給后臺(tái)并保存,最后在前端頁(yè)面上顯示。
雖然邏輯簡(jiǎn)單,但是通過這個(gè)抽獎(jiǎng)系統(tǒng)的開發(fā),我們可以鞏固自己對(duì)Python語法和框架的理解,同時(shí)也能夠體驗(yàn)到人工智能帶來的便利。讓我們一起動(dòng)手搭建這個(gè)簡(jiǎn)易版的抽獎(jiǎng)系統(tǒng)吧!
前端界面
盡管前端界面寫得不夠出色,但這并非我今天的重點(diǎn)。實(shí)際上,我想回顧一下Python的編寫方式和框架的理解。我創(chuàng)建了一個(gè)簡(jiǎn)單的九宮格,每個(gè)格子都設(shè)有不同的獎(jiǎng)項(xiàng),而且用戶還可以手動(dòng)進(jìn)行設(shè)置和修改,從而保證了靈活性。
前端代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>抽獎(jiǎng)系統(tǒng)</title>
<link rel="stylesheet" href="/static/css/styles.css">
<script src="/static/js/main.js"></script>
</head>
<body>
<h1>歡迎來到小雨抽獎(jiǎng)系統(tǒng)</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="獎(jiǎng)項(xiàng)1">獎(jiǎng)項(xiàng)1</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)2">獎(jiǎng)項(xiàng)2</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)3">獎(jiǎng)項(xiàng)3</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)4">獎(jiǎng)項(xiàng)4</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)5">獎(jiǎng)項(xiàng)5</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)6">獎(jiǎng)項(xiàng)6</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)7">獎(jiǎng)項(xiàng)7</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)8">獎(jiǎng)項(xiàng)8</div>
<div class="grid-item" data-prize="獎(jiǎng)項(xiàng)9">獎(jiǎng)項(xiàng)9</div>
</div>
<button id="draw-button">抽獎(jiǎng)</button>
<h2>獲獎(jiǎng)名單</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個(gè)宮格的顯示位置和實(shí)現(xiàn)動(dòng)態(tài)動(dòng)畫高亮效果。除此之外,并沒有對(duì)其他效果進(jìn)行配置。如果你有興趣,可以在抽獎(jiǎng)后自行添加一些炫彩煙花等效果,完全取決于你的發(fā)揮。
代碼如下:
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后臺(tái)
在我們的Python后端中,我們選擇使用了fastapi作為框架來接收請(qǐng)求。這個(gè)框架有很多優(yōu)點(diǎn),其中最重要的是它的速度快、簡(jiǎn)單易懂。但唯一需要注意的是,在前端向后端傳遞請(qǐng)求參數(shù)時(shí),請(qǐng)求頭必須包含一個(gè)json的標(biāo)識(shí)。如果沒有這個(gè)標(biāo)識(shí),后端將無法正確接收參數(shù),并可能報(bào)錯(cuò)。
為了更好地優(yōu)化我們的后端,如果你有足夠的時(shí)間,可以考慮集成數(shù)據(jù)庫(kù)等一些重量級(jí)的操作。這樣可以更好地處理數(shù)據(jù),并提供更多功能。
主要的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作為項(xiàng)目的運(yùn)行工具,因此在使用之前,你需要進(jìn)行一些配置工作。
[tool.poetry]
name = "python-lottery"
version = "0.1.0"
description = "python 抽獎(jiǎng)"
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
啟動(dòng)項(xiàng)目命令:poetry run uvicorn main:app --reload --port 8081
效果圖
總結(jié)
在本文中,我們使用Python語言和fastapi框架構(gòu)建了一個(gè)簡(jiǎn)易的抽獎(jiǎng)系統(tǒng)。系統(tǒng)的前端界面使用了HTML、JS和CSS來配置樣式和實(shí)現(xiàn)交互效果。后端使用了fastapi框架接收前端的請(qǐng)求,并處理抽獎(jiǎng)邏輯。
說實(shí)話,雖然我們有能力開發(fā)一個(gè)簡(jiǎn)易的抽獎(jiǎng)系統(tǒng),但既然我們都是程序員,為何要費(fèi)力去搞一個(gè)抽獎(jiǎng)系統(tǒng)呢?我們可以采用更簡(jiǎn)單的方式,將每個(gè)人的序號(hào)寫在紙條上,放進(jìn)一個(gè)紙箱子里,然后讓領(lǐng)導(dǎo)親自用手抓取。這樣做不僅更可靠,還能增加年會(huì)的活躍氛圍。
總結(jié)
以上是生活随笔為你收集整理的手把手教你用python做一个年会抽奖系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信文件为什么会过期
- 下一篇: ElasticSearch Groovy