[Python] 借助 Turtle 逐字展示《醉翁亭记》

背景

turtle --- Turtle graphics 中提供了关于 turtle\text{turtle} turtle 模块的介绍。我想到可以用 turtle\text{turtle} turtle 来展示经典的古文,比如《醉翁亭记》,于是用 trae 完成了代码(我做了少量调整)。

正文

整体思路

我想借助 turtle --- Turtle graphics 来逐字展示《醉翁亭记》,示例效果如下图所示 ⬇️

有几个核心的问题

  • 界面的长和宽需要根据字数动态计算,而不是 hard-code
  • 每过一个固定的时间,就多展示一个字,我们可以在 main 方法里实现这个主循环

借助 trae,我们就不必自己处理这些细节了。在它生成的代码的基础上,再让它进行调整(或者自己亲自调整)即可。这次的代码,主要是 trae 完成的,我只做了些微小的调整,就不赘述写代码的过程了(我在它提供的代码的基础上,反复运行并让它继续调整)。

完整的代码

python 复制代码
import math
import time
from turtle import Screen, Turtle

ARTICLE = (
    "環滁皆山也。 其西南諸峰,林壑尤美。望之蔚然而深秀者,琅琊也。"
    "山行六七里,漸聞水聲潺潺,而瀉出於兩峰之間者,讓泉也。"
    "峰回路轉,有亭翼然臨於泉上者,醉翁亭也。作亭者誰?山之僧曰智僊也。"
    "名之者誰?太守自謂也。太守與客來飲於此,飲少輒醉,而年又最高,"
    "故自號曰醉翁也。醉翁之意不在酒,在乎山水之間也。"
    "山水之樂,得之心而寓之酒也。"
    "\n\n"
    "若夫日出而林霏開,雲歸而巖穴暝,晦明變化者,山間之朝暮也。"
    "野芳發而幽香,佳木秀而繁陰,風霜高潔,水落而石出者,山間之四時也。"
    "朝而往,暮而歸,四時之景不同,而樂亦無窮也。"
    "\n\n"
    "至於負者歌於途,行者休於樹,前者呼,後者應,傴僂提攜,"
    "往來而不絕者,滁人遊也。臨谿而漁,谿深而魚肥;釀泉為酒,泉香而酒洌;"
    "山肴野蔌,雜然而前陳者,太守宴也。宴酣之樂,非絲非竹,射者中,"
    "弈者勝,觥籌交錯,起坐而諠譁者,眾賓懽也;蒼顏白髮,"
    "頹然乎其間者,太守醉也。"
    "\n\n"
    "已而夕陽在山,人影散亂,太守歸而賓客從也。樹林陰翳,鳴聲上下,"
    "遊人去而禽鳥樂也。然而禽鳥知山林之樂,而不知人之樂;"
    "人知從太守遊而樂,而不知太守之樂其樂也。醉能同其樂,"
    "醒能述以文者,太守也。太守謂誰?廬陵歐陽脩也。"
)

CHAR_SIZE = 20
CHAR_WIDTH = 36
CHARS_PER_COLUMN = 20
COLUMN_SPACING = 40
MARGIN = 80

CHAR_DELAY_MS = 150

FONT_PATH = "/System/Library/Fonts/PingFang.ttc"

PUNCTUATION = set(",。、;:?!「」『』()【】《》""''......---·〈〉﹝﹞〔〕")


def load_article():
    return "".join(
        ch for ch in ARTICLE if ch not in PUNCTUATION and not ch.isspace()
    )


def draw_char(x, y, ch, pen):
    pen.penup()
    pen.goto(x, y)
    pen.pendown()
    font = (FONT_PATH, CHAR_SIZE, "normal")
    pen.write(ch, align="center", font=font)


def setup_screen(width, height):
    screen = Screen()
    screen.setup(width, height)
    screen.title("醉翁亭記")
    screen.tracer(0)
    return screen


def setup_pen():
    pen = Turtle()
    pen.hideturtle()
    pen.color("black")
    return pen


def draw_next_char(position, characters, screen, pen, start_x, start_y):
    col = position // CHARS_PER_COLUMN
    row = position % CHARS_PER_COLUMN

    x = start_x - col * COLUMN_SPACING
    y = start_y - row * CHAR_WIDTH

    ch = characters[position]
    draw_char(x, y, ch, pen)
    screen.update()


def main():
    characters = list(load_article())

    total = len(characters)
    column_count = math.ceil(total / CHARS_PER_COLUMN)
    content_width = (column_count - 1) * COLUMN_SPACING
    content_height = (CHARS_PER_COLUMN - 1) * CHAR_WIDTH + CHAR_SIZE

    screen_width = content_width + 2 * MARGIN
    screen_height = content_height + 2 * MARGIN

    start_x = screen_width // 2 - MARGIN
    start_y = screen_height // 2 - MARGIN - CHAR_SIZE

    screen = setup_screen(screen_width, screen_height)
    pen = setup_pen()

    for position in range(total):
        draw_next_char(position, characters, screen, pen, start_x, start_y)
        time.sleep(CHAR_DELAY_MS / 1000)

    screen.mainloop()


if __name__ == "__main__":
    main()

运行效果

请将以上代码保存为 main.py。使用如下命令可以运行 main.py

bash 复制代码
python3 main.py

运行中的效果如下图所示 ⬇️

全文都展示好之后,效果如下图所示 ⬇️

说明

字体

我是在 Mac 电脑上进行操作的,代码里有一个地方用到了系统相关的路径(具体位置如下图所示),如果您用的是其他系统,请将其替换为合适的值

《醉翁亭记》

为了便于读者使用,我把《醉翁亭记》全文嵌在代码里了,这并不是好的编程风格。

《醉翁亭记》的内容,我是从 这个链接 复制过来(为了方便展示,我删掉了其中的两个注释符号)的。《醉翁亭记》是北宋欧阳修的作品,所以没有版权问题。

参考资料

相关推荐
XZ-0700011 小时前
week2-1-可视化
开发语言·python
Java后端的Ai之路1 小时前
14、Python - 责任链模式
服务器·开发语言·人工智能·python·责任链模式
张人玉1 小时前
基于 Python 机器学习 与 PyQt5 桌面框架开发的可视化分析系统——基于大数据的网上购物消费行为分析可视化大屏
python·qt·机器学习·echarts·three.js
一位正在转型AI全栈的前端工程师1 小时前
AI 全栈学习之旅 -Week 5:RAG 知识库问答系统:从零到生产级部署的全栈实践总结
前端·python
2601_962381861 小时前
Python办公联动:Excel数据一键自动生成PPT图表
python·数据分析·自动化·excel·ppt
东莞市永盛电气1 小时前
三相208V变380V变压器,出海工业设备供电适配方案
python·单片机·嵌入式硬件
未若君雅裁2 小时前
上下文压缩双刃剑-Summarization与ContextEditing中间件实战
python·中间件·langchain
IT毕设实战小研2 小时前
电影数据可视化推荐系统
大数据·后端·爬虫·python·算法·信息可视化·课程设计
前端 贾公子3 小时前
第09章:上下文与记忆 (3)
python·langchain
缘友一世3 小时前
GLM-5.3-NVFP4 部署实战系列[二]Docker 镜像选择与补丁镜像构建:纯 Python overlay,不重编一行 CUDA
python·docker·容器·vllm