# -- coding: utf-8 -- """ 三人行技能 - 核心生成器 SanRenXing Generator — 三人脱口秀课程 docx 批量生成工具
支持任意主题,每课生成约 2400 字的三人对话课程文档。
用法示例:
from sanrenxing import SanRenXingGenerator gen = SanRenXingGenerator( course_name="Python从小白到大牛", output_dir=r"D:\Python课程", ) gen.add_lessons({ 1: ("什么是Python", "基础概念"), 2: ("变量与数据类型", "基础语法"), }) gen.run()
"""
import os import re import sys import json import argparse
sys.stdout.reconfigure(encoding="utf-8") if hasattr(sys.stdout, "reconfigure") else None
─────────────────────────────────────────────
默认颜色
─────────────────────────────────────────────
COLOR_ZHANG = (0, 100, 200) # 深蓝:张教授 COLOR_XIAOMEI = (180, 50, 0) # 深红:小美 COLOR_LIN = (0, 130, 60) # 深绿:林老师 COLOR_TECH = (100, 50, 150) # 深紫:技术要点
─────────────────────────────────────────────
默认三位主播
─────────────────────────────────────────────
DEFAULT_SPEAKERS = [
{ "name": "张教授", "desc": "技术专家,男,落地开发经验丰富,风趣幽默,善用接地气比喻解释技术。", "color": COLOR_ZHANG, "role": "expert", # expert / novice / educator }, { "name": "小美", "desc": "行业小白,女,从普通人视角发问,语言诙谐毒辣,一针见血不留情面。", "color": COLOR_XIAOMEI, "role": "novice", }, { "name": "林老师", "desc": "教育行业专家,女,从教育普及角度分析问题,语言成熟严谨,善于类比总结。", "color": COLOR_LIN, "role": "educator", },
]
─────────────────────────────────────────────
工具函数
─────────────────────────────────────────────
def count_chars(text: str):
"""返回 (中文字符数, 英文单词数, 总计)""" cn = len(re.findall(r"[一-鿿]", text)) en = len(re.findall(r"[a-zA-Z]+", text)) return cn, en, cn + en
def safe_filename(title: str) -> str:
"""将标题转换为安全的文件名""" for ch in '::/"\|?*<>': title = title.replace(ch, "_") return title.strip()
─────────────────────────────────────────────
内容生成引擎
─────────────────────────────────────────────
def build_content(n: int, title: str, category: str, course_name: str, speakers: list) -> str:
""" 根据课程编号、标题、类别,生成完整的脱口秀对话文本。 返回带有【主播名】标签的纯文本字符串。 """ expert = next(s for s in speakers if s["role"] == "expert") novice = next(s for s in speakers if s["role"] == "novice") educator = next(s for s in speakers if s["role"] == "educator") en = expert["name"] nv = novice["name"] ed = educator["name"] # 提取短标题(去掉前缀编号等) topic = re.split(r"[::—-–]", title)[-1].strip() if re.search(r"[::—-–]", title) else title # ── 开场白(~250 字)────────────────────────────────────────────────── opening = f"""【{en}】 各位观众好,欢迎收看《{course_name}》!我是{en}。今天是第{n}课,主题是:{title}。这是整个课程体系里相当关键的一环,掌握好了你会有一种"原来如此"的豁然开朗感。废话不多说,先介绍两位搭档。
【{nv}】 大家好,我是{nv}!说实话,每次听{en}说"关键"我都有点慌,因为上次他说关键的那课,我搞了两个晚上才弄明白。不过还是很期待啦,我代表所有小白坐在这里,专门负责提傻问题。
【{ed}】 (微笑)小白提的问题往往才是最真实的问题。我是{ed},今天会从认知框架和教育实践的角度,帮大家把零散的知识点串联成一个完整的体系。好,{en},请开始吧。
【{en}】 好,进入正题——{topic},开讲!"""
# ── 第一段:核心概念(~700 字)────────────────────────────────────── sec1 = f"""【{en}】 首先我们来回答一个根本性的问题:{topic}到底是什么?它存在的价值是什么?别小看这个问题,很多学了好几年的人依然说不清楚。我见过太多开发者把{topic}当成一个"黑盒子"在用——能跑就行,跑不通再说——这样迟早会在项目里吃大亏。
【{nv}】 呃……我确实就是这么用的。
【{en}】 (笑)那今天你收获最大。我们来做个比喻:如果一个系统是一栋大楼,那{topic}就相当于这栋楼的地基。地基不牢,楼越高越危险。在{course_name}的整体框架里,{topic}处于这样的位置——它不是锦上添花的功能,而是所有上层逻辑的前提。
【{nv}】 那万一我以前搭的"楼"地基不牢,是不是要推倒重来?
【{en}】 不一定推倒重来,但需要"补桩"。好消息是,{topic}的核心逻辑其实是可以后期加固的,只要你理解了它的本质。它的核心可以用一句话概括:{topic}的本质是"状态 + 转换 + 目标"三件套——在什么状态下,通过什么转换,达到什么目标。所有复杂的理论,最终都可以归结到这个三角模型。
【{ed}】 从教育学角度,这种"三角模型"的教学方法被称为"概念图谱"。它的好处是,每次遇到新的知识点,你不是从零开始,而是在已有的图谱上增加节点。{topic}作为{category}这个大类里的重要节点,和你之前学过的内容有直接的关联,理解它会让你的整个知识网络更加完整。
【{nv}】 {ed}老师,能举个具体例子吗?比如说,{topic}在实际场景里是怎么"用上"的?
【{ed}】 好,比如在处理一个复杂业务流程时,你需要判断当前状态、选择操作路径、追踪执行结果——这整个过程就是{topic}的典型应用场景。只要你能识别出这个模式,你就知道什么时候该用{topic}、怎么用最合适。
【{en}】 对,实战中{topic}最常见的使用场景,就是当系统逻辑变得复杂到用 if-else 堆不下去的时候。这是一个很明显的信号,告诉你该引入{topic}了。记住这个判断标准,以后你写代码时会感激今天的这节课。"""
# ── 第二段:原理剖析(~700 字)────────────────────────────────────── sec2 = f"""【{en}】 好,基本概念清楚了。现在我们来挖深一层,聊聊{topic}的工作原理。我知道"原理"两个字让很多人头疼,但这次我保证用最直观的方式讲——讲完你就算解释给你家人听,也能让他们大概明白。
【{nv}】 这个我最感兴趣了,因为我之前每次跳过"原理"
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/257924.html