引言
馬上就要舉行年會抽獎了,我們都不知道是否有人能夠中獎。我覺得無聊的時候可以嘗試自己寫一個抽獎系統,主要是為了娛樂。現在人工智慧這麼方便,寫一個簡單的程式碼不是一件困難的事情。今天我想和大家一起構建一個簡易的抽獎系統,這樣也能夠鞏固一下我自己對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框架接收前端的請求,並處理抽獎邏輯。
說實話,雖然我們有能力開發一個簡易的抽獎系統,但既然我們都是程式設計師,為何要費力去搞一個抽獎系統呢?我們可以採用更簡單的方式,將每個人的序號寫在紙條上,放進一個紙箱子裡,然後讓領導親自用手抓取。這樣做不僅更可靠,還能增加年會的活躍氛圍。