用 Python 构建「原创力约束器」:用数据倒逼独立思考
一、实际应用场景描述
在《心理健康与创新能力》课程中,"社会认同偏差"(Social Proof Bias)与"从众效应"(Bandwagon Effect)被视为抑制独立思考的两大隐形杀手。我们天生倾向于模仿他人的解决方案——因为这最安全、最省力。
典型场景:
- 开发场景:接到新需求,第一反应是去 GitHub 搜现成方案,Ctrl+C / Ctrl+V 后改改参数,从不思考"有没有更好的写法"。
- 设计场景:PM 画原型,下意识参照竞品截图,"抄"成了最快的交付方式,原创性在 deadline 压力下被彻底牺牲。
- 决策场景:开会讨论技术方案,第一个发言的人定调子,后面的人纷纷附和,没人愿意做"唱反调的人"。
课程中有一个残酷的洞察:模仿的次数越多,大脑用于原创的"肌肉"就越萎缩。 我们建立了庞大的"模仿库",却没有一套系统来约束它、对抗它。
本程序旨在建立一个原创力约束系统:追踪每周模仿 vs 原创的方案数量,设定原创最低阈值,当原创不足时触发"强制独立思考"模式。
二、引入痛点
传统方案管理的盲区
问题 表现 后果
无意识模仿 照搬方案时毫不自知 原创能力持续退化
缺少量化 "我这周挺有想法的吧?"全凭感觉 无法客观评估独立思考的占比
无底线约束 一周下来可能 0 原创 在"借鉴"的幌子下彻底躺平
模仿无溯源 抄了就忘,无法复盘 错过从模仿到创新的跃迁机会
核心痛点总结
我们缺少一个"原创力底线"的守护者。 就像代码覆盖率工具倒逼测试一样,我们需要一个工具来倒逼独立思考。
三、核心逻辑讲解
程序围绕 "记录 → 统计 → 约束 → 倒逼" 四步循环:
1. 双轨记录(Dual-Track Logging)
每次提出或采纳一个方案时,必须标记为:
-
"imitation"(模仿):基于他人方案的修改、套用、参考
-
"original"(原创):从第一性原理出发、独立推导的方案
关键:不是禁止模仿,而是让它可见。
2. 周度统计(Weekly Analytics)
每周自动计算:
- 原创率 = 原创方案数 / 总方案数
- 连续原创天数:激励持续独立思维
- 模仿溯源:记录"模仿了谁",后续可分析"哪些来源最容易让你停止思考"
3. 约束机制(Constraint Engine)
设定两条硬规则:
- 原创最低线:每周至少 N 个原创方案(默认 3)
- 模仿上限:每天最多 M 个模仿方案(默认 2)
当触发阈值时:
- 原创不足 → 程序进入"强制原创模式",生成一道"从零设计"的练习题
- 模仿超标 → 弹出警告:"今天已经够多了,自己想一个"
4. 模仿跃迁(Imitation → Innovation)
最高级的功能:当一条模仿记录被标记为"已深度理解"后,程序会提示你:
"你已经理解了这个方案,现在试着改一个核心参数,让它的适用场景发生根本性变化。"
这是从"照搬"到"创新"的关键一跃。
四、代码模块化实现
项目结构
originality_enforcer/
│
├── README.md
├── main.py # CLI 交互入口
├── models.py # 数据模型
├── storage.py # 持久化层
├── logger.py # 方案记录模块
├── analyzer.py # 原创力统计分析
├── constraint.py # 约束引擎(核心)
└── challenger.py # 强制原创练习生成器
1️⃣ 数据模型(models.py)
# models.py
# 方案记录的数据模型
# 核心设计:区分"模仿"与"原创",让隐性思维习惯显性化
from dataclasses import dataclass, field
from datetime import datetime, date
from typing import Optional, List
from enum import Enum
class SolutionType(Enum):
"""方案类型 —— 这是整个程序的灵魂字段"""
IMITATION = "imitation" # 模仿:基于他人方案的修改/套用
ORIGINAL = "original" # 原创:独立推导、第一性原理出发
class DepthLevel(Enum):
"""对模仿方案的理解深度"""
SHALLOW = "shallow" # 照搬,不理解原理
UNDERSTOOD = "understood" # 理解原理,能解释清楚
TRANSCENDED = "transcended" # 已超越,能提出改进
@dataclass
class SolutionRecord:
"""
一条方案记录
每次提出或采纳一个方案时,创建一条记录
"""
id: int
title: str # 方案简述
solution_type: SolutionType # 模仿 or 原创
context: str # 场景:在什么问题中提出的
source: Optional[str] = None # 模仿来源(如:GitHub某项目/同事方案/StackOverflow)
depth: DepthLevel = DepthLevel.SHALLOW # 对模仿方案的理解深度
date: date = field(default_factory=date.today)
timestamp: datetime = field(default_factory=datetime.now)
notes: Optional[str] = None # 思考笔记
def to_dict(self):
return {
"id": self.id,
"title": self.title,
"solution_type": self.solution_type.value,
"context": self.context,
"source": self.source,
"depth": self.depth.value,
"date": self.date.isoformat(),
"notes": self.notes
}
@classmethod
def from_dict(cls, data: dict):
return cls(
id=data["id"],
title=data["title"],
solution_type=SolutionType(data["solution_type"]),
context=data["context"],
source=data.get("source"),
depth=DepthLevel(data.get("depth", "shallow")),
date=date.fromisoformat(data["date"]),
notes=data.get("notes")
)
@dataclass
class WeeklyChallenge:
"""一条强制原创练习"""
id: int
prompt: str # 练习题面
date_assigned: date
completed: bool = False
def to_dict(self):
return {
"id": self.id,
"prompt": self.prompt,
"date_assigned": self.date_assigned.isoformat(),
"completed": self.completed
}
@classmethod
def from_dict(cls, data: dict):
return cls(
id=data["id"],
prompt=data["prompt"],
date_assigned=date.fromisoformat(data["date_assigned"]),
completed=data.get("completed", False)
)
设计要点:
-
"solution_type" 是灵魂字段,将"模仿"和"原创"从模糊感知变成精确数据
-
"depth" 追踪对模仿方案的理解程度,为"从模仿到创新"的跃迁提供路径
-
"source" 字段让你可以事后分析"哪些信息源最容易让你停止独立思考"
2️⃣ 持久化层(storage.py)
# storage.py
# 数据持久化模块
import json
import os
from typing import List, Optional
from models import SolutionRecord, WeeklyChallenge
from datetime import date
DATA_DIR = "data"
RECORDS_FILE = os.path.join(DATA_DIR, "solutions.json")
CHALLENGE_FILE = os.path.join(DATA_DIR, "challenges.json")
SETTINGS_FILE = os.path.join(DATA_DIR, "settings.json")
def _ensure_dir():
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR)
# ---------- SolutionRecord 操作 ----------
def load_records() -> List[SolutionRecord]:
if not os.path.exists(RECORDS_FILE):
return []
with open(RECORDS_FILE, "r", encoding="utf-8") as f:
return [SolutionRecord.from_dict(item) for item in json.load(f)]
def save_records(records: List[SolutionRecord]):
_ensure_dir()
with open(RECORDS_FILE, "w", encoding="utf-8") as f:
json.dump([r.to_dict() for r in records], f, ensure_ascii=False, indent=2)
def get_next_record_id() -> int:
records = load_records()
return max((r.id for r in records), default=0) + 1
# ---------- WeeklyChallenge 操作 ----------
def load_challenges() -> List[WeeklyChallenge]:
if not os.path.exists(CHALLENGE_FILE):
return []
with open(CHALLENGE_FILE, "r", encoding="utf-8") as f:
return [WeeklyChallenge.from_dict(item) for item in json.load(f)]
def save_challenges(challenges: List[WeeklyChallenge]):
_ensure_dir()
with open(CHALLENGE_FILE, "w", encoding="utf-8") as f:
json.dump([c.to_dict() for c in challenges], f, ensure_ascii=False, indent=2)
def get_next_challenge_id() -> int:
challenges = load_challenges()
return max((c.id for c in challenges), default=0) + 1
# ---------- Settings 操作 ----------
def load_settings() -> dict:
"""加载用户设置"""
if not os.path.exists(SETTINGS_FILE):
return {"min_original_per_week": 3, "max_imitation_per_day": 2}
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_settings(settings: dict):
_ensure_dir()
with open(SETTINGS_FILE, "w", encoding="utf-8") as f:
json.dump(settings, f, ensure_ascii=False, indent=2)
3️⃣ 方案记录模块(logger.py)
# logger.py
# 方案记录模块:区分模仿与原创
from storage import load_records, save_records, get_next_record_id
from models import SolutionRecord, SolutionType, DepthLevel
def log_solution(
title: str,
solution_type: SolutionType,
context: str,
source: str = None,
depth: DepthLevel = DepthLevel.SHALLOW,
notes: str = None
) -> SolutionRecord:
"""记录一条方案"""
record = SolutionRecord(
id=get_next_record_id(),
title=title,
solution_type=solution_type,
context=context,
source=source,
depth=depth,
notes=notes
)
records = load_records()
records.append(record)
save_records(records)
return record
def update_depth(record_id: int, new_depth: DepthLevel, notes: str = None):
"""更新对某条模仿方案的理解深度"""
records = load_records()
for r in records:
if r.id == record_id:
r.depth = new_depth
if notes:
r.notes = (r.notes or "") + f"\n[{new_depth.value}] {notes}"
break
save_records(records)
def get_today_records() -> list:
"""获取今天的记录"""
from datetime import date
today = date.today()
records = load_records()
return [r for r in records if r.date == today]
4️⃣ 原创力统计分析(analyzer.py)
# analyzer.py
# 原创力统计分析引擎
from storage import load_records, load_settings
from datetime import date, timedelta
from collections import Counter, defaultdict
def get_week_range(ref_date: date = None):
"""获取本周一~周日的日期范围"""
ref = ref_date or date.today()
monday = ref - timedelta(days=ref.weekday())
sunday = monday + timedelta(days=6)
return monday, sunday
def weekly_stats(ref_date: date = None) -> dict:
"""计算本周核心指标"""
monday, sunday = get_week_range(ref_date)
records = load_records()
week_records = [r for r in records if monday <= r.date <= sunday]
total = len(week_records)
original = sum(1 for r in week_records if r.solution_type == SolutionType.ORIGINAL)
imitation = sum(1 for r in week_records if r.solution_type == SolutionType.IMITATION)
settings = load_settings()
min_original = settings["min_original_per_week"]
return {
"total": total,
"original": original,
"imitation": imitation,
"original_rate": original / total * 100 if total > 0 else 0,
"min_original": min_original,
"status": "✅ 达标" if original >= min_original else "⚠️ 未达标",
"gap": max(0, min_original - original),
"week_start": monday.isoformat(),
"week_end": sunday.isoformat()
}
def daily_imitation_count(check_date: date = None) -> int:
"""获取某天的模仿方案数量"""
d = check_date or date.today()
records = load_records()
return sum(
1 for r in records
if r.date == d and r.solution_type == SolutionType.IMITATION
)
def original_streak() -> int:
"""计算连续有原创方案的天数"""
records = load_records()
if not records:
return 0
dates_with_original = set(
r.date for r in records if r.solution_type == SolutionType.ORIGINAL
)
d = date.today()
streak = 0
while d in dates_with_original:
streak += 1
d -= timedelta(days=1)
return streak
def source_analysis() -> dict:
"""分析模仿来源分布"""
records = load_records()
imitation_records = [
r for r in records if r.solution_type == SolutionType.IMITATION and r.source
]
return dict(Counter(r.source for r in imitation_records).most_common())
def print_weekly_report(ref_date: date = None):
"""打印周度报告"""
stats = weekly_stats(ref_date)
streak = original_streak()
print("\n" + "=" * 60)
print(f" 原创力周报 ({stats['week_start']} ~ {stats['week_end']})")
print("=" * 60)
print(f"\n 总方案数:{stats['total']}")
print(f" 原创方案:{stats['original']} | 模仿方案:{stats['imitation']}")
print(f" 原创率:{stats['original_rate']:.1f}%")
print(f" 连续原创天数:{streak} 天 🔥" if streak > 0 else " 连续原创天数:0 天")
# 原创率可视化
bar_len = int(stats['original_rate'] / 5)
bar = "█" * bar_len + "░" * (20 - bar_len)
print(f" [{bar}] {stats['original_rate']:.1f}%")
print(f"\n 原创最低线:{stats['min_original']} 个/周")
print(f" 状态:{stats['status']}")
if stats['gap'] > 0:
print(f" ⚠️ 还差 {stats['gap']} 个原创方案,加油!")
# 来源分析
sources = source_analysis()
if sources:
print(f"\n 模仿来源 TOP 3:")
for src, cnt in list(sources.items())[:3]:
print(f" · {src}: {cnt} 次")
# 评估与建议
print(f"\n --- 评估 ---")
if stats['original_rate'] >= 50:
print(f" ✅ 原创率健康,继续保持独立思维。")
elif stats['original_rate'] >= 25:
print(f" 💡 原创率中等,有意识地减少"直接照搬",多问"为什么"。")
else:
print(f" ⚠️ 原创率偏低,本周大多数方案为模仿。")
print(f" 💡 建议:每次想照搬前,先给自己 2 分钟独立思考时间。")
5️⃣ 约束引擎(constraint.py)
# constraint.py
# 约束引擎:原创力底线守护者
from storage import load_records, load_settings
from models import SolutionType
from datetime import date
from analyzer import daily_imitation_count, weekly_stats
def check_daily_imitation_limit() -> tuple[bool, str]:
"""
检查今日模仿次数是否超标
返回:(是否允许继续模仿, 提示信息)
"""
settings = load_settings()
max_per_day = settings["max_imitation_per_day"]
today_count = daily_imitation_count()
if today_count >= max_per_day:
return False, (
f"⚠️ 今日模仿方案已达上限({max_per_day} 个)。"
f" 试着自己想一个原创方案吧。"
)
else:
remaining = max_per_day - today_count
return True, f"今日还可记录 {remaining} 个模仿方案。"
def check_weekly_original_minimum(ref_date: date = None) -> tuple[bool, str]:
"""
检查本周原创是否达标
返回:(是否达标, 提示信息)
"""
stats = weekly_stats(ref_date)
if stats['gap'] > 0:
return False, (
f"⚠️ 本周原创方案还差 {stats['gap']} 个。"
f" 原创率仅 {stats['original_rate']:.1f}%。"
)
else:
return True, f"✅ 本周原创达标({stats['original']}/{stats['min_original']})。"
def enforce_before_log(solution_type: SolutionType) -> tuple[bool, str]:
"""
在记录方案前的拦截检查
返回:(是否允许记录, 提示信息)
"""
if solution_type == SolutionType.IMITATION:
allowed, msg = check_daily_imitation_limit()
return allowed, msg
else:
return True, ""
6️⃣ 强制原创练习生成器(challenger.py)
# challenger.py
# 当原创不足时,生成"从零设计"练习题,强制独立思考
from storage import load_challenges, save_challenges, get_next_challenge_id
from datetime import date
import random
# 原创练习题库:覆盖不同场景,强制从第一性原理出发
CHALLENGE_POOL = [
"不用任何框架,只用原生 API,设计一个用户认证流程。",
"不参考任何现有 UI,从零画一个文件上传组件的草图。",
"抛开你熟悉的所有排序算法,设计一个"只适用于你当前数据特征"的排序方法。",
"不看任何文档,凭记忆写一个 HTTP 客户端的完整请求流程。",
"假设世界上没有 Redis,你会用什么方式实现"热点数据缓存"?",
"不使用任何 ORM,手写出当前项目中一个复杂的 SQL 查询。",
"从零设计一个"消息通知"系统,不参考任何现有方案。",
"如果禁止使用 for 循环,你会如何遍历和处理一个数据集?",
"不借助任何第三方库,实现一个简单的模板引擎。",
"假设你是第一个解决这类问题的人,写下你的思考过程。",
"不用任何设计模式,写出一段"最朴素"但能跑通的代码,然后逐步重构它。",
"抛开 REST 规范,设计一个你认为"最合理"的 API 风格。",
]
def generate_weekly_challenge() -> str:
"""生成本周的强制原创练习"""
# 先检查本周是否已有未完成的挑战
challenges = load_challenges()
today = date.today()
monday = today - __import__('datetime').timedelta(days=today.weekday())
existing = [c for c in challenges if c.date_assigned >= monday and not c.completed]
if existing:
return existing[0].prompt # 返回本周已有的
# 生成新的
prompt = random.choice(CHALLENGE_POOL)
challenge = WeeklyChallenge(
id=get_next_challenge_id(),
prompt=prompt,
date_assigned=monday
)
challenges.append(challenge)
save_challenges(challenges)
return prompt
def mark_challenge_completed(challenge_id: int):
"""标记挑战已完成"""
challenges = load_challenges()
for c in challenges:
if c.id == challenge_id:
c.completed = True
break
save_challenges(challenges)
def get_pending_challenge() -> Optional[dict]:
"""获取当前待完成的挑战"""
from datetime import timedelta
challenges = load_challenges()
today = date.today()
monday = today - timedelta(days=today.weekday())
for c in challenges:
if c.date_assigned >= monday and not c.completed:
return {"id": c.id, "prompt": c.prompt}
return None
7️⃣ 主程序入口(main.py)
# main.py
# CLI 主入口
from storage import load_records
from logger import log_solution, update_depth, get_today_records
from analyzer import print_weekly_report, original_streak
from constraint import enforce_before_log, check_weekly_original_minimum
from challenger import generate_weekly_challenge, get_pending_challenge, mark_challenge_completed
from models import SolutionType, DepthLevel
from datetime import date
def select_type() -> SolutionType:
print("\n 方案类型:")
print(" 1. 模仿(基于他人方案的修改/套用)")
print(" 2. 原创(独立推导/第一性原理出发)")
while True:
choice = input(" 选择 > ").strip()
if choice == "1":
return SolutionType.IMITATION
elif choice == "2":
return SolutionType.ORIGINAL
print(" 无效输入。")
def select_depth() -> DepthLevel:
print("\n 理解深度:")
print(" 1. 照搬(不理解原理)")
print(" 2. 已理解(能解释清楚)")
print(" 3. 已超越(能提出改进)")
while True:
choice = input(" 选择 > ").strip()
if choice == "1":
return DepthLevel.SHALLOW
elif choice == "2":
return DepthLevel.UNDERSTOOD
elif choice == "3":
return DepthLevel.TRANSCENDED
print(" 无效输入。")
def cmd_log_solution():
"""记录方案"""
print("\n--- 记录方案 ---")
# 先选择类型
sol_type = select_type()
# 约束检查
allowed, msg = enforce_before_log(sol_type)
print(f" {msg}")
if not allowed:
print(" ❌ 已拦截。请尝试记录一个原创方案。")
return
title = input(" 方案简述:").strip()
context = input(" 场景(什么问题):").strip()
source = None
if sol_type == SolutionType.IMITATION:
source = input(" 模仿来源(GitHub/同事/文档...):").strip()
depth = DepthLevel.SHALLOW
if sol_type == SolutionType.IMITATION:
depth = select_depth()
notes = input(" 笔记/反思(回车跳过):").strip()
log_solution(title, sol_type, context, source or None, depth, notes or None)
print(" ✅ 方案已记录!")
def cmd_check_status():
"""查看今日 + 本周状态"""
print("\n--- 今日快照 ---")
today_records = get_today_records()
if not today_records:
print(" 今天还没有记录。")
else:
for r in today_records:
tag = "📋 模仿" if r.solution_type == SolutionType.IMITATION else "💡 原创"
print(f" {tag} {r.title}")
# 本周状态
ok, msg = check_weekly_original_minimum()
print(f"\n--- 本周原创检查 ---")
print(f" {msg}")
def cmd_weekly_report():
"""查看周报"""
print_weekly_report()
def cmd_challenge():
"""查看/生成本周原创挑战"""
pending = get_pending_challenge()
if pending:
print(f"\n 本周挑战(未完成):")
print(f" 🏋 {pending['prompt']}")
done = input("\n 完成了吗?(y/n) > ").strip().lower()
if done == "y":
mark_challenge_completed(pending["id"])
print(" ✅ 挑战已完成!你突破了舒适区。")
else:
print(" 继续加油,完成后记得标记!")
return
# 生成新挑战
prompt = generate_weekly_challenge()
print(f"\n 本周原创挑战:")
print(f" 🏋 {prompt}")
def cmd_settings():
"""修改设置"""
from storage import load_settings, save_settings
settings = load_settings()
print(f"\n 当前设置:")
print(f" 每周最低原创数:{settings['min_original_per_week']}")
print(f" 每天最多模仿数:{settings['max_imitation_per_day']}")
new_min = input(" 修改最低原创数(回车不变):").strip()
new_max = input(" 修改每日模仿上限(回车不变):").strip()
if new_min.isdigit():
settings['min_original_per_week'] = int(new_min)
if new_max.isdigit():
settings['max_imitation_per_day'] = int(new_max)
save_settings(settings)
print(" ✅ 设置已保存。")
def main():
print(" 🧩 原创力约束器 v1.0")
print(" 用数据守护你的独立思考")
while True:
print("\n" + "-" * 40)
print(" 1. 记录方案(模仿/原创)")
print(" 2. 查看今日状态")
print(" 3. 查看周度报告")
print(" 4. 本周原创挑战")
print(" 5. 修改设置")
print(" 6. 退出")
print("-" * 40)
choice = input(" 请选择 > ").strip()
if choice == "1":
cmd_log_solution()
elif choice == "2":
cmd_check_status()
elif choice == "3":
cmd_weekly_report()
elif choice == "4":
cmd_challenge()
elif choice == "5":
cmd_settings()
elif choice == "6":
streak = original_streak()
if streak > 0:
print(f"\n 连续原创 {streak} 天。保持独立思考,世界需要你的想法。再见!")
else:
print("\n 再见!记得常回来记录。")
break
else:
print(" 无效选项。")
if __name__ == "__main__":
main()
五、README 文件
# 原创力约束器 (Originality Enforcer)
## 项目简介
基于《心理健康与创新能力》课程中"独立思考"与"从众效应"
理论开发的个人认知训练工具。追踪每周模仿 vs 原创方案数量,
设定原创最低阈值,倒逼独立思考能力。
核心理念:模仿是学习的起点,但不应是终点。
原创力需要被量化、被守护、被锻炼。
## 功能特性
| 功能 | 说明 |
|------|------|
| 双轨记录 | 每次方案标记为"模仿"或"原创" |
| 每日限额 | 限制模仿方案数量,防止无意识照搬 |
| 周度底线 | 设定每周最低原创数(默认3个) |
| 强制练习 | 原创不足时生成"从零设计"挑战题 |
| 深度追踪 | 记录对模仿方案的理解程度(照搬→理解→超越) |
| 周报分析 | 原创率、连续天数、来源分布 |
## 环境要求
- Python 3.8+
- 无需第三方依赖
## 快速开始
### 1. 运行程序
python main.py
### 2. 记录方案(选项1)
方案类型:2(原创)
方案简述:用位运算优化权限判断逻辑
场景:用户权限模块重构
### 3. 查看周报(选项3)
原创率:42.9%
[█████████░░░░░░░░] 42.9%
状态:⚠️ 未达标(还差 1 个原创方案)
### 4. 原创挑战(选项4)
🏋 不用任何框架,只用原生 API,设计一个用户认证流程。
## 数据文件
- data/solutions.json:方案记录
- data/challenges.json:原创挑战
- data/settings.json:用户设置
## 适用人群
- 担心"模仿依赖症"的开发者
- 希望量化独立思考能力的创作者
- 对个人认知习惯进行工程化管理的学习者
## 核心理念引用
> "从众效应让我们在安全感中丧失创造力。
> 真正的创新,始于敢于自己想答案的那一刻。"
六、使用说明
推荐工作流
每次提出或采纳方案时:
🧩 原创力约束器 v1.0
用数据守护你的独
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!