2026-10-07 · 喵窝资源铺
场景:部门团餐接龙「A套餐/B套餐/C套餐」,收了三轮——张三先选A第二天改成B、孙七第三轮反悔选C,最后还要回答「A套餐到底几个人订」。人工翻聊天记录数票,改一次票数错一次。这篇给一个脚本(jielong_vote.py):多轮接龙文本 + 选项列表喂进去,关键词归票 + 改票留最新,每个选项票数、人选、改票记录、认不出的行全部列清楚。代码实跑验证,真实输出见下。
先 pip install pandas openpyxl,每轮接龙各自存成 txt,运行 python jielong_vote.py round1.txt round2.txt "A套餐" "B套餐" "C套餐" 票数表.xlsx(选项按顺序排在 txt 后面):
# -*- coding: utf-8 -*-
"""接龙按选项分组统计票数:改票留最新,未识别行标出来不瞎猜。
用法 python jielong_vote.py r1.txt r2.txt [...] "选项1" "选项2" ... out.xlsx"""
import re, sys, difflib
import pandas as pd
def parse(fp):
rows = []
for line in open(fp, encoding="utf-8"):
line = line.strip()
if not line:
continue
line = re.sub(r'^[\d0-9]+\s*[\.,、\)).]\s*', '', line) # 剥行首编号(含全角)
line = line.replace(':', ':')
m = re.match(r'([一-龥A-Za-z·]{2,8})\s*[::,,]?\s*(.*)', line) # 冒号可选
if not m:
continue
name, rest = m.group(1), m.group(2).strip()
if not rest:
continue
rows.append({'姓名': name, '选择': rest})
return rows
files = [a for a in sys.argv[1:] if a.endswith('.txt')]
out = sys.argv[-1]
options = [a for a in sys.argv[1:-1] if not a.endswith('.txt')]
votes, changes = {}, [] # votes: 姓名 -> (选择, 轮次)
for rnd, fp in enumerate(files, 1):
for r in parse(fp):
prev = votes.get(r['姓名'])
if prev is not None and prev[0] != r['选择']:
if prev[1] != rnd: # 同轮内重复出现=确认,不算改票
changes.append((r['姓名'], prev[0], r['选择'], rnd))
votes[r['姓名']] = (r['选择'], rnd)
def classify(text):
hits = [o for o in options if o in text]
if len(hits) == 1:
return hits[0]
if not hits:
best = difflib.get_close_matches(text, options, cutoff=0.4)
if len(best) == 1:
return best[0]
return f'??未识别({text})'
return f'??多选({text})' # 同时提到两个选项,交人工
tally = {o: [] for o in options}
for name, (sel, _) in votes.items():
tally.setdefault(classify(sel), []).append(name)
rows = [{'选项': o, '票数': len(p), '人选': '、'.join(p)}
for o, p in tally.items()]
df = pd.DataFrame(rows).sort_values('票数', ascending=False)
df.to_excel(out, index=False)
print(f'共 {len(files)} 轮,有效投票 {len(votes)} 人 -> {out}')
print(df.to_string(index=False))
for name, old, new, rnd in changes:
print(f'--- 改票(留最新) ---\n {name}: 第{rnd}轮「{old}」改为「{new}」')
for name, (sel, _) in votes.items():
c = classify(sel)
if c.startswith('??'):
print(f'--- 未识别需人工 ---\n {name}: 「{sel}」 {c}')
造了 4 轮接龙共 14 行,故意埋了:跨轮改票、改票说明里带理由、行首全角编号、无冒号行、混进一条管理员通知、以及一条「不要A套餐了,换B套餐」的改票(一句话提到两个选项)。跑一遍的输出:
共 4 轮,有效投票 12 人 -> doc_out2.xlsx
选项 票数 人选
A套餐 4 王五、周八、郑十、陈二
B套餐 3 张三、李四、钱二
C套餐 3 赵六、孙七、吴九
??未识别(管理员发的通知) 1 这不是接龙
??多选(不要A套餐了,换B套餐) 1 刘一
--- 改票(留最新) ---
张三: 第2轮「A套餐」改为「改成B套餐(A太贵了)」
--- 改票(留最新) ---
孙七: 第3轮「B套餐」改为「改C套餐」
--- 未识别需人工 ---
这不是接龙: 「管理员发的通知」 ??未识别(管理员发的通知)
--- 未识别需人工 ---
刘一: 「不要A套餐了,换B套餐」 ??多选(不要A套餐了,换B套餐)
12 人各归各档,A/B/C 票数一目了然;张三改票「A太贵了」这种带理由的照样识别成 B;管理员通知和「一句话提到两个选项」的刘一都标成未识别交人工,绝不硬塞进某个选项。幂等验证:同样输入重跑一遍,读回来的表格逐格一致(比数据不比 xlsx 字节)。
如果接龙的选项不是固定几档(比如自由填数量、带规格),或者要把票数表再跟签到/付款记录对一遍,逻辑要再包一层,可以直接找我们代写(见下)。
懒得自己跑?找我们代写
喵窝资源铺提供 Python 脚本代写服务:你说清楚接龙格式、选项和要什么表,我们写好、用你的真实聊天记录测试通过再交付,24 小时内出活。AI 服务,明码标价,先看效果再付款(虚拟物品不退款,不满意免费重做)。
👉 了解代写服务 | 联系我们
📖 相邻文章:多轮接龙合并去重 · 单轮接龙统计成Excel · 报名名单×签到表核对 · AA收款记录对账 · 聊天记录批量提取待办 · 博客目录
票数表仅供参考,最终以群内原始接龙消息为准;??未识别行务必人工确认后再定档。