Python投票小程序案例?

wen python案例 4

从零搭建你的Python投票小程序:完整案例与实战解析

目录导读

  1. 为什么选择Python开发投票小程序?
  2. 系统功能设计与准备
  3. 核心代码逐段解析
  4. 完整运行与测试指南
  5. 常见问题与优化方向
  6. 问答环节:你关心的投票痛点

为什么选择Python开发投票小程序?

在团队决策、课堂互动或小型活动中,一个轻量级的投票小程序能极大提升效率,Python凭借其简洁的语法、丰富的标准库(如tkinterFlask)以及快速开发特性,成为构建此类工具的首选语言,本文将以命令行版+简易图形界面版两个案例,手把手教你实现一个完整的投票系统,涵盖选题、代码实现、防刷票策略等真实业务逻辑。


系统功能设计与准备

1 功能需求

  • 用户输入候选人名单(支持动态添加)
  • 每个用户限投1次(基于IP或Session限制)
  • 实时显示投票结果(饼图或列表)
  • 支持导出结果到CSV

2 环境准备

pip install flask matplotlib pandas   # 如果用Web版或图表
# 纯命令行版仅需Python 3.6+

核心代码逐段解析

1 命令行版投票(最简实现)

# voting_cli.py
import json
class VoteSystem:
    def __init__(self):
        self.candidates = []
        self.votes = {}
        self.voted_ips = set()  # 简单防刷:模拟IP记录
    def add_candidate(self, name):
        self.candidates.append(name)
        self.votes[name] = 0
    def vote(self, candidate, ip="local"):
        if ip in self.voted_ips:
            return "您已投过票"
        if candidate not in self.candidates:
            return "候选人不存在"
        self.votes[candidate] += 1
        self.voted_ips.add(ip)
        return f"投票成功!{candidate}当前票数:{self.votes[candidate]}"
    def show_result(self):
        for c in self.candidates:
            print(f"{c}: {self.votes[c]}票")

关键逻辑:通过voted_ips集合限制重复投票,实际生产需用数据库+Token。

2 Flask Web版投票(带界面)

# app.py
from flask import Flask, request, render_template, session
import matplotlib.pyplot as plt
import io
import base64
app = Flask(__name__)
app.secret_key = 'your-secret-key'  # 用于session防刷
# 初始化数据
candidates = ['方案A', '方案B', '方案C']
votes = {c: 0 for c in candidates}
voted_sessions = set()
@app.route('/')
def index():
    return render_template('vote.html', candidates=candidates)
@app.route('/vote', methods=['POST'])
def do_vote():
    candidate = request.form.get('candidate')
    session_id = request.cookies.get('session')  # 实际用session对象
    if session_id in voted_sessions:
        return "您已经投过票", 403
    if candidate not in candidates:
        return "无效候选人", 400
    votes[candidate] += 1
    voted_sessions.add(session_id)
    return "投票成功!<a href='/result'>查看结果</a>"

说明:使用session(基于Cookie)实现单用户限制,比IP更准确。

3 生成可视化结果(饼图)

def gen_pie_chart():
    plt.figure(figsize=(6, 4))
    plt.pie(votes.values(), labels=votes.keys(), autopct='%1.1f%%')
    plt.title('投票结果分布')
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    buf.seek(0)
    img_base64 = base64.b64encode(buf.read()).decode()
    return f'<img src="data:image/png;base64,{img_base64}"/>'

完整运行与测试指南

1 命令行版测试

python voting_cli.py
# 输入候选人:张三、李四
# 输入投票:1 代表张三,2 代表李四
# 输入show查看结果

2 Web版启动

python app.py
# 访问 http://127.0.0.1:5000

测试要点

  • 同一浏览器多次投票是否能被拦截?
  • 切换浏览器(不同session)是否能再次投票?
  • 候选人列表为空时如何处理?

常见问题与优化方向

1 安全性提升

  • 改用数据库(SQLite)持久化数据,防止重启丢失
  • 添加验证码防止机器人刷票
  • 使用JWT Token进行用户身份校验

2 功能扩展

  • 支持多选投票(如选3个喜欢的方案)
  • 实时图表更新(WebSocket)
  • 管理员后台管理候选人

3 代码质量优化

# 使用用户对象代替IP/Session
class User:
    def __init__(self, user_id):
        self.id = user_id
        self.has_voted = False
# 在路由中检查 user.has_voted

问答环节:你关心的投票痛点

Q1:如何真正做到一人一票?

纯前端/单机版无法绝对防刷,生产环境需结合邮箱验证、手机号验证微信登录,本示例的session/IP限制只能抵御普通用户。

Q2:投票数据如何保持持久?

使用sqlite3JSON文件存储,Flask版可修改为:

import json
with open('votes.json','w') as f:
    json.dump(votes, f)

Q3:如果候选人有100个,界面怎么展示?

推荐分页搜索或按类别分组,后台使用Flask-Admin快速构建管理后台。

Q4:能否直接部署到服务器?

可以,使用gunicorn部署Flask应用,前端用Nginx反向代理:

gunicorn -w 4 -b 0.0.0.0:8000 app:app

Q5:支持匿名投票吗?

本案例即为匿名投票(仅限制重复),如需实名,可在User表中增加real_name字段。


通过本文,你不仅获得了两个可直接运行的Python投票小程序(命令行版与Web版),还理解了如何设计投票逻辑、防刷机制以及数据可视化,作为一个经典的编程案例,它非常适合入门者练习用户输入处理、状态管理、Web框架基础,如果你需要源码包或完整项目结构,欢迎在评论区留言,动手改造它,让它适配你的下一个活动吧!

标签: 投票案例

抱歉,评论功能暂时关闭!