惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
T
The Exploit Database - CXSecurity.com
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
T
Tailwind CSS Blog
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
PCI Perspectives
PCI Perspectives
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
Recent Commits to openclaw:main
Recent Commits to openclaw:main
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
N
News and Events Feed by Topic
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
雷峰网
雷峰网
有赞技术团队
有赞技术团队
Last Week in AI
Last Week in AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
GbyAI
GbyAI
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
S
Security Affairs
F
Fortinet All Blogs
L
LINUX DO - 最新话题
博客园 - 【当耐特】
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
W
WeLiveSecurity
Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tenable Blog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
CERT Recently Published Vulnerability Notes
Engineering at Meta
Engineering at Meta
P
Palo Alto Networks Blog
博客园 - 叶小钗
T
Threatpost
H
Heimdal Security Blog
Microsoft Security Blog
Microsoft Security Blog

皓子的小站

网站字体应用之坑——font-family 篇 糟糕的 meta name="theme-color" How to Automatically Track Newly Supported ESLint Rules in Oxlint How to Gradually Migrate from ESLint to Oxlint (Without Breaking Everything) 静态资源预压缩:零运行时开销,极致节省带宽 CVE-2025-70886 Proof of Concept (PoC) | A Script to Crash Halo CMS Comment Backend 自定义网页鼠标指针——一段曲折的旅程 CVE-2025-70886 漏洞复现/PoC | 一个脚本让 Halo CMS 评论后台瘫痪 2025 年终总结 & 博客两周年 老用户专享!已有 Halo 专业版授权可免费升级商业版 自动追踪 Oxlint 对 ESLint 规则的新增支持 Halo 贡献者证书与实体周边盲盒开箱 博客评论系统指南 CDN 回源跟随配置导致登录异常问题排查 SCDN 免费赞助计划:助力高质量博客&博客圈 锐捷校园网:网络共享与带宽叠加方案(哈理工案例) ESLint 到 Oxlint 渐进式迁移快速上手指南 Fixing Vite Breaking Inline JS & CSS in Thymeleaf Templates 解决 Vite 破坏 Thymeleaf 模板内联 JS & CSS 的方法 我的博客,为什么是月更? 博客俱乐部一周年纪念品开箱 网站字体加载之坑——format 篇 经历 1000000000 次 DDoS 请求攻击后,我总结了三条经验 题解分享:[AtCoder Beginner Contest 414 E] Count A%B=C 题解分享:[蓝桥杯 2025 国 Python A] 杨辉三角 P12876 FiF口语训练破解刷分教程(适用于 Windows) 不要与蠢人辩论 小心网络地雷·续篇 当心网络组织“开往”·续篇 当心网络组织“开往” 小心网络地雷 在 Halo CMS 中通过模板实现随机推荐多篇文章 回应某博客上有关“开往”组织在内部会议上对我的污蔑(上) 再遭 DDoS 攻击:CDN 流量限额拦不住请求计费飙升 2025年团体程序设计天梯赛 - Python 个人赛时暴力题解 网站流量分析工具 Umami 中国大陆合规版发布 把握当下,享受生活 Folo 认证功能反成漏洞?警惕 RSS 订阅源所有权被恶意盗取风险 在 Halo CMS 中通过模板实现随机文章跳转功能 从沉默展柜到时代回响:731部队罪证陈列馆参访手记 脚本分享:CDN 流量触顶后自动切换至 Cloudflare 官方 BUG 快薅!Halo 永久/买断用户可额外获得一份买断许可 老用户专享!已有 1Panel 永久授权/买断许可用户可再领免费买断许可证! 限时特惠!1¥ 立即解锁 1Panel 专业版全功能 61 天 混合云架构下的动态 IPv6 智能加速实践:从家庭网络到全球分发的低成本部署指南 如何用 AI 全方面辅助博客创作 - 从博文之内到博文之外 Random Number Generation and Formatting in Thymeleaf Thymeleaf 随机数生成与格式化详解 列举我维护的项目和发布的软件包 快速部署教程 - 通过 Webhook 触发邮件通知的开源自托管服务 Going Against the Grain - Four Websites That Make Your URL Longer 反其道而行 - 四个让你网址变得更长的网站 2024 年终总结 & 博客一周年 基于 OneBot API 的简易异步 QQ 群批量发消息脚本 如何快速完成中文排版优化 如何给文章分类和打标签 群规之敏感违禁词对抗 一图展示​ ​RSS3 世界 - The Open(RSS3) Universe 开源项目发到 bilibili 后可能获得的 PR C/C++:为什么 a[i][j] 等价于 *(*(a+i)+j) Fast Methods to Convert Uppercase Letters to Lowercase in C++ C++ 中快速将字符串大写字母转为小写的方法 Fixing GitHub Actions push to ghcr '403 Forbidden' error Fixing docker pull image "ghcr.io..." Unauthorized error 本站“算法题练习/题解分享”相关文章汇总 不怕流氓多,就怕流氓有文化——站长应该防范的几个问题及对应解决方法分享 题解分享:HRBUST 1132 水数 新手程序员必备的三项技能 如何快速排查插件(模组)的兼容性问题(基于二分法和分治思想) 通过 Umami 最新功能观察定时发布文章的最佳时段 踩坑分享:如何一个人搬运 126.7 斤的书坐动车 两篇文章分享:别像弱智一样提问 & 提问的智慧 论下落式音游/定轨音游中的优质粪铺(文末附铺面推荐) 为什么选择无纸化阅读?为什么买墨水屏电子书?为什么 Kindle“失败”了? 我维护的 Halo 主题,现已发布到 Halo 应用商店! 我常用的 OSU!Mania 皮肤分享 电荷守恒辨析:为什么一个离子带多个电荷要乘上所带电荷数而不是除以所带电荷数 注意!align-items: flex-start 会导致 overflow-wrap: break-word 失效 惊人 98 元限定T恤!1Panel, Halo 开发商开启推广积分奖励活动 Minecraft Spigot Bukkit 服务器插件开发 教程收集 中文博客倡议 Windows 10 遇到“只能重装系统”但不想重装的解决方案 Windows 10 文件系统错误 -2144926975 -2147219196 修复 Windows 10 升级 Windows 11 简明教程 CSS 预处理器如何正确的复用样式(stylus 中使用 @extend 继承的坑) 请一定要回复博客下的匿名评论!对于博主和评论者有关匿名评论的倡议 一图解释单一质点运动波动图像和振动图像的关系 解决 Docker pull image "ghcr.io..." Unauthorized error 解决 GitHub Actions push to ghcr '403 Forbidden' error 解决 Umami API 更新延迟问题(如何修改开源项目代码并构建 Docker 镜像-以 Umami 为例) 在国家公祭日自动将网站变灰 中文博客圈列表 解决 Halo CMS 的 Umami Plugin CORS&CSP 跨域报错问题 Windows 创建存储池报错 无法创建池 不支持该请求 (0x00000032) Windows 显示器突然黑白 桌面突然黑白 鼠标和截图还是彩色的 通过指令过滤出正确的公网 IPv6 地址(记一次折腾 IPv6 DDNS) 我的世界免费科技地址 1.7-1.21 网站 Favicon 下载工具发布 键盘 Bios 内可用 系统内无法输入 设备管理器无黄色感叹号 设备管理器 网卡一堆黄色感叹号 例如 WAN, Miniport
OSU!Standard(osu!std)/OSU!Taiko 转 OSU!Mania 铺面转换器发布
HowieHz · 2024-06-16 · via 皓子的小站

项目原地址(github):HowieHz/osu-beatmap-to-mania-converter: Convert osu!standard(osu!std) to osu!mania (github.com)
本页面是为了访问 GitHub 不畅的小伙伴制作的镜像,内容更新可能会有延迟,请以上面链接的原址为准。

为了加载速度,本镜像去除了外部图片链接。

v0.3.1 演示视频:
osu!std 转 osu!mania 铺面转换器 震撼发布!_哔哩哔哩bilibili_演示

Convert OSU!Standard(osu!std)/OSU!Taiko to OSU!Mania

主要功能

  • 将 OSU!Standard 铺面转换为 OSU!Mania 铺面。
  • (!制作中)将 OSU!Taiko 铺面转换为 OSU!Mania 铺面。

如果想支持本项目就点个 star 吧,你的支持将指引我砥砺前行。

如在使用中遇到 Bug,想提出新功能,对现有功能不满,想提出建议,想问问题,想进行讨论。欢迎前来提出新的 Issue

在我的博客上阅读:点我跳转

为何创建此项目

For fun.

这个软件的用途

对于 OSU!Standard 转 OSU!Mania

  1. 帮助萌新分配左手的两个键,而不是一直单戳
  2. OSU!Mania 铺师直接从 OSU!Standard 铺面采音用
  3. 手法分析/铺面解析
  4. 在主模式开 Autopilot mod 享受游戏(广义上,此软件生成的铺面相较于原铺,就相当于 NO SV 铺面相较于 SV 铺面)

对于 OSU!Taiko 转 OSU!Mania

  1. OSU!Mania 铺师直接从 OSU!Taiko 铺面采音用
  2. 手法分析/铺面解析
  3. ...

我有不同的见解/我想补充

这个软件可以生成怎样的铺面

对于 OSU!Standard 转 OSU!Mania

  1. 符合一般玩家双指分配的铺面(低密度单戳,高密度两指交替击打)
  2. 单戳练习铺生成器 (参数例:最大叠键数 1000000,最小叠键时间间距设置为 0)
  3. 强双练习铺生成器 (参数例:最大叠键数 1,最小叠键时间间隔 1000000)

对于 OSU!Taiko 转 OSU!Mania

  1. 符合一般玩家手指分配音符的铺面
  2. 小红圈和小蓝圈单戳的铺面(参数例:红圈列/蓝圈列最大叠键数 1000000,红圈列/蓝圈列最小叠键时间间距设置为 0)
  3. 小红圈和小蓝圈强制两指交换击打的铺面(参数例:红圈列/蓝圈列最大叠键数 1,红圈列/蓝圈列最小叠键时间间距设置为 1000000)

  • OSU!Standard(osu!std)/OSU!Taiko 转 OSU!Mania 铺面转换器发布
    • 主要功能
    • 为何创建此项目
    • 这个软件的用途
      • 对于 OSU!Standard 转 OSU!Mania
      • 对于 OSU!Taiko 转 OSU!Mania
    • 这个软件可以生成怎样的铺面
      • 对于 OSU!Standard 转 OSU!Mania
      • 对于 OSU!Taiko 转 OSU!Mania
    • 物件转换规则,可生成的铺面类型
      • OSU!Standard 转 OSU!Mania
        • 物件转换规则
        • 可生成铺面
      • OSU!Taiko 转 OSU!Mania
        • 物件转换规则
        • 可生成铺面
    • 软件可配置项说明
      • OSU!Standard 转 OSU!Mania
        • 基础设置
        • 输出目标 OSU!Mania 2k/4k 为才有的配置项
    • 如何下载使用
      • 通过二进制文件运行图形用户界面
        • 在 Windows 平台
        • 在 MacOS & Linux 平台
      • 通过源码运行图形用户界面
      • 通过二进制文件运行命令行程序
        • Windows 平台
        • MacOS & Linux 平台
      • 通过源码运行命令行程序
      • 通过二进制文件运行交互式命令行程序
        • Windows
        • MacOS & Linux
      • 通过源码运行交互式命令行程序
    • 开发中遇到的雷
      • 读取主模式铺面
      • 输出 Mania 模式铺面
    • 软件原理解释
      • 程序结构
      • 软件如何根据 .osu 文件生成 Mania 铺面
        • osu!std to osu!mania
          • to mania!mania 1k
          • to osu!mania 2k
          • to osu!mania 4k
        • osu!taiko to osu!mania 4k
    • TODO
      • 优先且易实现
      • 优先
        • 其他的 mania 2k 输出选项
      • 滞后
        • i18n
        • 项目环境配置/文档
      • 后备
    • 更新日志

物件转换规则,可生成的铺面类型

OSU!Standard 转 OSU!Mania

物件转换规则

  1. 主模式音符 -> mania 音符
  2. 主模式长条 -> mania 长条
  3. 主模式转盘 -> mania 长条

可生成铺面

  • OSU!Mania 1k
  • OSU!Mania 2k
  • OSU!Mania 4k(将 4k 左边两轨当 2k 使用,无需玩家制作 2k 界面皮肤)

OSU!Taiko 转 OSU!Mania

物件转换规则

红色在内侧,蓝色在外侧。

  1. 小红圈(别名 d(咚)) -> mania 音符
  2. 小蓝圈(别名 k(咔)) -> mania 音符
  3. 大红圈(别名 D/O) -> mania 音符
  4. 大蓝圈(别名 K/X) -> mania 音符
  5. 长黄条(滚动条) -> mania 长条
  6. 大的长黄条 -> mania 长条
  7. 拨浪鼓(转盘) -> mania 长条

注:

  1. 长黄条/大的长黄条的转换是不完美的。因为实际上你游玩 taiko 铺面的时候,不论是大黄条还是小黄条,应按照黄条上面的白点的节奏击打任意一个键,而不是作为一个长条来按。
  2. 拨浪鼓(转盘)的转换是不完美的。因为实际上你游玩 taiko 铺面的时候,你应该交替击打红蓝键来完成转盘。

可生成铺面

  • OSU!Mania 4k
    • 按照手法设置对应从左到右 1 到 4 轨。手法设置用字母 d 和 k 来表示如何分配四个键的位置,如:kddk(直观手法), ddkk/kkdd(硬抗手法), dkdk/kdkd/dkkd(少见的手法)。
    • 小红圈就在其中一个 d 轨生成一个音符
    • 大红圈就在两个 d 轨都生成音符,形成双押(可配置将大红圈视为小红圈)
    • 小蓝圈就在其中一个 k 轨生成一个音符
    • 大蓝圈就在两个 k 轨都生成音符,形成双押(可配置将大蓝圈视为小蓝圈)
    • 大/小黄条和拨浪鼓转换后的长音符在某个轨道上生成
    • (具体有关“其中一个 x 轨”,“某个轨道” 具体是其中的哪个轨道,则由具体生成时的软件设置来决定)
  • OSU!Mania 5k
    • 从左到右依次是 1-5 轨道
    • 1 轨道放小红圈转换后的音符
    • 2 轨道放大红圈转换后的音符
    • 3 轨道放大/小黄条和拨浪鼓转换后的长音符
    • 4 轨道放小蓝圈转换后的音符
    • 5 轨道放大蓝圈转换后的音符

软件可配置项说明

OSU!Standard 转 OSU!Mania

基础设置

  1. 设置惯用单戳指所在轨道:物件会优先生成在这个轨道上(main key)
  2. 设置铺面从哪一轨开始生成(start key)
  3. 是否移除铺面变速(可选项:全移除,不移除,仅移除继承时间点(绿线))(Remove SV)

输出目标 OSU!Mania 2k/4k 为才有的配置项

  1. 交互起手设置:最开始的交互哪个轨道起手(Trill start key)
  2. 纵连两键间距小于多少毫秒开始转交互(Minimum Jack Time Interval)
  3. 几个纵开始转交互(Maximum number of jack notes)

如何下载使用

通过二进制文件运行图形用户界面

在 Windows 平台

Releases 下载最新版本二进制文件。
运行 obmc-latest-noconsole.exe 为后缀的程序,即可开始运行图形用户界面,随后根据引导完成操作即可。

在 MacOS & Linux 平台

请看通过源码运行图形用户界面

通过源码运行图形用户界面

下载项目源码,然后进入到项目根目录。
在本地部署 Python3.12 环境后,运行以下指令。
即可从源码运行此项目。

python ./src/main.py

通过二进制文件运行命令行程序

Windows 平台

Releases 下载最新版本二进制文件 obmc-latest.exe
在下载文件所在目录的资源管理器的地址栏,输入 cmd 之后回车,在随后弹出的命令行窗口中输入以下指令

obmc-latest.exe -h

即可看到相关帮助

MacOS & Linux 平台

请看通过源码运行命令行程序

通过源码运行命令行程序

下载项目源码,然后进入到项目根目录。
在本地部署 Python3.12 环境后,运行以下指令。
即可从源码运行此项目。

python ./src/main.py -h

通过二进制文件运行交互式命令行程序

Windows

Releases 下载最新版本二进制文件 obmc-latest.exe
在下载文件所在目录的资源管理器的地址栏,输入 cmd 之后回车,在随后弹出的命令行窗口中输入以下指令

obmc-latest.exe -cui

即可进入交互式命令行程序

MacOS & Linux

请看通过源码运行交互式命令行程序

通过源码运行交互式命令行程序

下载项目源码,然后进入到项目根目录。
在本地部署 Python3.12 环境后,运行以下指令。
即可从源码运行此项目。

python ./src/main.py -cui

开发中遇到的雷

读取主模式铺面

  1. 下面这两段都是 ranked 主模式图取的滑条的数据,可以看到滑条后半部分数据是可以省略的。所以取长度数据要用正数索引值去取。
    • 24,164,11997,6,0,L|32:244,1,57.5,6|0,0:0|0:0,0:0:0:0:
    • 308,340,12297,2,0,L|300:260,1,57.5

输出 Mania 模式铺面

  1. 官方 wiki 是 长键语法:x,y,开始时间,物件类型,长键音效,结束时间,长键音效组
    • 错了,实际上长键语法是 x,y,开始时间,物件类型,长键音效,结束时间:长键音效组
    • 结束时间和长键音效组分隔符是冒号不是逗号!

软件原理解释

点我展开查看

程序结构

读取器(包括预处理) -> 处理器(数据转换) -> 生成器(生成可以直接写入文件的文本)

软件如何根据 .osu 文件生成 Mania 铺面

.osu 文件解析:官方 wiki:.osu 文件解释文档

如依然有不理解的,欢迎致邮 howie_hzgo@outlook.com。如果你正在开发相关读取铺面文件/生成铺面的工具我会在力所能及的层面提供帮助。

osu!std to osu!mania

共同的步骤

  1. 读取除 [HitObjects] 以外的信息,命名为 osu_file_metadata
  2. 读取 [HitObjects] 信息,根据 osu_file_metadata 使用 std_hit_objects_parser 函数进行预处理,命名为 parsed_hit_objects_list
  3. 使用 std_object_type_to_mania_1k 函数将 parsed_hit_objects_list 中类型为主模式滑条和主模式转盘的转换为 Mania 长音符,并且放到 1 轨,处理后的命名为 parsed_mania_1k_hit_objects_list
  4. 根据配置项去除铺面 sv 信息(处理 osu_file_metadata)
to mania!mania 1k
  1. 将元数据处理为 mania 1k 的元数据(处理 osu_file_metadata)
    • 设置 Mode 为 3 (设置铺面模式为 Mania)
    • 设置 CircleSize 为 1 (设置信息为 1k)
    • 设置 BeatmapSetID 为 -1
  2. 根据 osu_file_metadata 和 parsed_mania_1k_hit_objects_list 生成铺面
to osu!mania 2k
  1. 根据配置项处理 parsed_mania_1k_hit_objects_list,处理后的命名为 parsed_mania_2k_hit_objects_list
  2. 将元数据处理为 mania 2k 的元数据(处理 osu_file_metadata)
    • 设置 Mode 为 3 (设置铺面模式为 Mania)
    • 设置 CircleSize 为 2 (设置信息为 2k)
    • 设置 BeatmapSetID 为 -1
  3. 根据 osu_file_metadata 和 parsed_mania_2k_hit_objects_list 生成铺面
to osu!mania 4k
  1. 根据配置项处理 parsed_mania_1k_hit_objects_list,处理后的命名为 parsed_mania_2k_hit_objects_list
  2. 将元数据处理为 mania 4k 的元数据(处理 osu_file_metadata)
    • 设置 Mode 为 3 (设置铺面模式为 Mania)
    • 设置 CircleSize 为 4 (设置信息为 4k)
    • 设置 BeatmapSetID 为 -1
  3. 根据 osu_file_metadata 和 parsed_mania_2k_hit_objects_list 生成铺面

osu!taiko to osu!mania 4k

  1. 读取除 [HitObjects] 以外的信息,命名为 osu_file_metadata
  2. 读取 [HitObjects] 信息,根据 osu_file_metadata 使用 taiko_hit_objects_parser 函数进行预处理,命名为 parsed_hit_objects_list
    • 预处理分类了大黄条,小黄条,大红圈,小红圈,大蓝圈,小蓝圈,拨浪鼓(转盘)
    • 按照英文官网 wiki 起的类型名:large slider, slider, large red notes, red notes, large blue note, blue note, spinner
  3. 用 taiko_object_type_to_mania_5k 函数将 parsed_hit_objects_list 中类型为大小黄条和拨浪鼓(转盘)的转换为 Mania 长音符,处理后的命名为 parsed_mania_5k_hit_objects_list
    • 从左到右依次是 1-5 轨道
    • 1 轨道放小红圈转换后的音符
    • 2 轨道放大红圈转换后的音符
    • 3 轨道放小蓝圈转换后的音符
    • 4 轨道放大蓝圈转换后的音符
    • 5 轨道放大/小黄条和拨浪鼓转换后的长音符
  4. 根据配置项去除铺面 sv 信息(处理 osu_file_metadata)
  5. 根据配置项处理 parsed_mania_5k_hit_objects_list,处理后的命名为 parsed_mania_4k_hit_objects_list
  6. 将元数据处理为 mania 4k 的元数据(处理 osu_file_metadata)
    • 设置 Mode 为 3 (设置铺面模式为 Mania)
    • 设置 CircleSize 为 4 (设置信息为 4k)
    • 设置 BeatmapSetID 为 -1
  7. 根据 osu_file_metadata 和 parsed_mania_4k_hit_objects_list 生成铺面

TODO

点我展开查看

优先且易实现

...

优先

  1. 完成其他的 mania 2k 输出选项
    1. 生成后提供直接修改游戏内铺面标题的设置
  2. webui 夜间模式支持
  3. dotenv 来读取 env 而不用手动设置 debug flag

其他的 mania 2k 输出选项

  1. 长纵转交互:生成成 1k 的时候会出现大量的纵连,此时根据这个规则开始转换
    • (TODO)两音符击打时间间距小于一个值(Anti long jack)
      • mode1: 不管这个间隔时间是否恒定(variable time interval)
      • mode2: 要求这个间隔时间必须恒定(constant time interval)
    • (TODO)从哪个开始转换为交互(Conversion starts position)
      • mode1: 满足要求便从计算的第一个开始转换(Conversion starts with the first)
      • mode2: 满足要求从满足要求的那个开始转换(比如是大于 3 个连续音符开始转换,那就把第四个音符放在另一个轨道,前三个音符保持为一个三连段纵)(Conversion starts from a position of attainment)
    • (TODO)转换模式(trill or jack)
      • mode1: 满足要求便全部转换成交互(All to trill)
      • mode2: 满足要求便全部转换为短纵(All to jack)
      • mode3: 多少连续音符转换为分组短纵,超过多少音符转换为交互(Long jack converted to trill, keep short jack)
  2. (TODO)防止交互头尾连起来短纵选项:前一个交互的最后一个音符和下一个交互开头的音符要是间隔小于一个值,下一个交互就从另一个轨道开始(Anti minijack between trill)
  3. (TODO)检测 ln 尾部和下一个 note 的间距,小于一个值就把这个 note 放到另一列上
  4. (TODO)允许用户调整 2k -> 4k 对应轨道映射

滞后

i18n

  1. 编写英文文档
  2. 软件支持英文

项目环境配置/文档

  1. 创建 github-action 以便于在每次提交自动构建多平台二进制文件
  2. 配置自动类型检查工具,在每次提交前检查
  3. 贡献文档要求强制进行类型检查
  4. 写项目单元测试
  5. 配置线上单元测试检查的软件

后备

  1. 创建 GUI 程序(肯定是基于 cli,做个 cli 的调用。用简单的 python web 框架调用 cli 是上策,用其他语言写 gui 算中策,用 pyside/pyqt 是下策)

更新日志

Releases