- 文档
- 教程
【免费下载链接】app-ideas
A Collection of application ideas which can be used to improve your coding skills.
本篇技术指南基于开源仓库 app-ideas 中 Tier-2 中级项目 Calculator-CLI 编写,讲解如何从零设计并实现一个命令行计算器:支持多参数连续相加、-f浮点输出、even/odd子命令筛选,以及全局与子命令两级--help。读完本文,你将掌握 CLI 参数解析的通用设计方法,并获得一份可运行、可扩展的 Python 参考实现及 Go / Node.js 落地方案要点。
项目定位与验收标准
Calculator CLI 位于 Projects/2-Intermediate,难度分级为2-Intermediate,适用于已经熟悉基础语法、希望系统练习命令行参数解析与子命令结构的开发者。它区别于仓库中 Tier-1 的图形界面版 Calculator-App:后者侧重 UI 与事件处理,而本项目的核心是命令行交互设计。
原文档以 User Stories 形式给出验收标准,共 4 条必选与 3 条可选需求:
核心 User Stories
- 用户可以通过
add命令一次性相加多个数字 - 用户可以通过
-f标志保留浮点结果 - 用户可以通过
even/odd子命令只对偶数或奇数求和 - 用户可以通过
--help或-h查看所有可用命令与标志
Bonus Features
- 支持全部基础算术运算:加(addition)、减(subtraction)、乘(multiplication)、除(division)
- 通过
--help或-h查看每个子命令自己的参数说明 - 支持Power of(幂运算)与Square Root of(平方根)
文档还特别注明了一条关键约束:
故事 1 和故事 2 主要针对静态类型语言,要求传入参数必须保持相同类型。也就是说,
add 1 2 3与add 1.5 2.5内部应分别作为整型数组与浮点数组处理,而不是混用。
命令行界面(CLI)设计
实现前先确定命令语法。本项目的交互模式可抽象为:calc <command> [options] <numbers...>。建议的完整命令表如下:
| 命令 | 作用 | 示例 |
|---|---|---|
add | 多参数相加 | calc add 1 2 3→6 |
sub | 从第一个数依次减去其余数 | calc sub 10 3 2→5 |
mul | 多参数相乘 | calc mul 2 3 4→24 |
div | 从第一个数依次除以其余数 | calc div 10 2→5 |
pow | 幂运算(支持链式) | calc pow 2 3→8 |
sqrt | 平方根(一般取单参数) | calc sqrt 9→3 |
全局-h/--help | 列出全部命令 | calc --help |
子命令-h/--help | 列出某命令的参数 | calc add --help |
add 专属标志
| 标志 | 含义 |
|---|---|
-f/--float | 保留浮点结果(默认整数输出) |
--even | 仅对偶整数求和 |
--odd | 仅对奇整数求和 |
--even与--odd语义互斥,应设计为互斥组(mutually exclusive group),同时传入时由解析器直接报错。
Python 参考实现:从 argparse 到完整命令集
Python 标准库的argparse天生支持子命令(add_subparsers)与互斥参数组,是实现本项目的最小依赖方案。下面给出经过本地运行验证的完整实现骨架:
import argparse, math, sys def compute(args): # 统一转 float,保证 add -f 1.5 2.5 场景下同类型运算 try: values = [float(v) for v in args.numbers] except ValueError: sys.exit("Error: all arguments must be numeric, got " + ", ".join(args.numbers)) # even / odd 筛选:仅保留整数值并按奇偶过滤 if getattr(args, 'even', False): values = [v for v in values if v.is_integer() and int(v) % 2 == 0] if getattr(args, 'odd', False): values = [v for v in values if v.is_integer() and int(v) % 2 == 1] op = args.command if op == 'add': total = sum(values) elif op == 'sub': total = values[0] - sum(values[1:]) elif op == 'mul': total = 1 for v in values: total *= v elif op == 'div': total = values[0] for v in values[1:]: if v == 0: sys.exit("Error: division by zero") total /= v elif op == 'pow': total = values[0] for v in values[1:]: total = total ** v elif op == 'sqrt': total = math.sqrt(values[0]) # 默认输出整数;-f 时保留浮点 if not args.float_out: total = int(total) return total def main(): parser = argparse.ArgumentParser(prog="calc", description="A basic calculator CLI.") subparsers = parser.add_subparsers(dest="command") add_parser = subparsers.add_parser("add", help="add multiple numbers") add_parser.add_argument("numbers", nargs="+", type=str, help="numbers to add") add_parser.add_argument("-f", "--float", dest="float_out", action="store_true", help="keep floating point result") group = add_parser.add_mutually_exclusive_group() group.add_argument("--even", action="store_true", help="only add even numbers") group.add_argument("--odd", action="store_true", help="only add odd numbers") for op, op_help in (("sub", "subtract numbers"), ("mul", "multiply numbers"), ("div", "divide numbers"), ("pow", "power of"), ("sqrt", "square root of")): p = subparsers.add_parser(op, help=op_help) p.add_argument("numbers", nargs="+", type=str, help="numbers for %s" % op) p.add_argument("-f", "--float", dest="float_out", action="store_true", help="keep floating point result") args = parser.parse_args() if args.command is None: parser.print_help() # 无参数时默认展示用法 return try: print(compute(args)) except ValueError as e: sys.exit(str(e)) if __name__ == "__main__": main()实现要点拆解:
nargs="+"允许一次传入任意多个数字,直接满足"多参数相加"需求;- 参数统一转
float:这是对文档中"静态类型语言要求参数同类型"注释的 Python 侧响应——add 1 2 3结果为整型 6,add -f 1.5 2.5结果为浮点 4.0,输出精度由-f显式控制; add_mutually_exclusive_group()保证--even与--odd不能共存;add_subparsers+dest="command"让每个子命令拥有独立解析器,从而自然获得"子命令级--help"能力。
运行验证:全部 User Stories 实测输出
以下输出均在 Python 3.12 环境实测得到,可直接作为验收脚本:
# 故事 1:add 多参数相加 $ python calc.py add 1 2 3 4 5 15 # 故事 2:-f 浮点结果(默认整数、-f 保留小数) $ python calc.py add -f 1.5 2.5 4.0 # 故事 3:even / odd 子命令筛选 $ python calc.py add --even 1 2 3 4 6 $ python calc.py add --odd 1 2 3 4 4 # 故事 4:全局 --help 列出全部命令 $ python calc.py --help usage: calc [-h] {add,sub,mul,div,pow,sqrt} ... options: -h, --help show this help message and exit # Bonus 1:完整算术运算 $ python calc.py sub 10 3 2 5 $ python calc.py mul 2 3 4 24 $ python calc.py div -f 10 4 2.5 # Bonus 2:子命令级 --help $ python calc.py add --help usage: calc add [-h] [-f] [--even | --odd] numbers [numbers ...] options: -f, --float keep floating point result --even only add even numbers --odd only add odd numbers # Bonus 3:幂与平方根 $ python calc.py pow 2 3 8 $ python calc.py sqrt -f 2 1.4142135623730951值得注意的边界行为:
div遇到除数为 0 时应给出明确错误并退出(如Error: division by zero),不要静默崩溃;sqrt对非整数结果默认取整、加-f保留精度;--even/--odd只过滤"整数且奇偶匹配"的数,浮点参数(如2.5)会被跳过,这正是"参数类型一致性"约束的体现。
静态类型语言落地:Go 与 Node.js 设计要点
原文档的"Useful links and resources"重点推荐了 Go 与 Node.js 两大生态,两者在参数校验上的取舍值得单独说明:
- Go(推荐 cobra):cobra 提供
AddCommand注册子命令、Flags()声明-f/--float、MarkFlagRequired强制必填参数,并自动生成两级 help 页面。由于 Go 是静态类型,add命令内部建议用[]int与[]float64两个分支接收参数——-f决定走浮点分支,其余走整型分支,恰好呼应文档注释中的"同类型参数"要求;--even/--odd筛选用v%2判断即可。 - Node.js(可选 yargs / commander):两者均支持
.command()定义子命令与.option()声明标志。动态类型下参数天然"同类型混存",因此必须显式校验:用Number.isInteger()判断整型参数,用Number.parseFloat统一转换后再做奇偶筛选,否则--even 1 2.5 3这类输入会产生非预期结果。
测试与验收建议
该项目规格以 User Stories 驱动,建议按以下矩阵编写测试用例:
| 用例 | 输入 | 期望输出 |
|---|---|---|
| 多参数相加 | add 1 2 3 | 6 |
| 浮点相加 | add -f 0.1 0.2 | 0.3(注意浮点误差) |
| 偶数筛选 | add --even 1 2 3 4 | 6 |
| 奇数筛选 | add --odd 1 2 3 4 | 4 |
| 互斥参数 | add --even --odd 1 2 | 解析器报错 |
| 非法输入 | add 1 a 3 | 明确错误信息 |
| 除零 | div 10 0 | Error: division by zero |
| 全局帮助 | --help | 列出全部子命令 |
| 子命令帮助 | add --help | 列出 add 专属参数 |
测试覆盖可以对照仓库的贡献规范(见 CONTRIBUTING.md)与项目模板(见 Example Guide):User Stories 即验收用例来源,每一项都对应一个可复现的命令场景。
从项目规格到完整作品
Calculator CLI 是 app-ideas 仓库中"小而完整"的典型项目:它把 CLI 开发的三个核心能力——参数解析、子命令组织、类型与边界处理——压缩到几十行代码内。完成必选 Stories 后,可继续按 Bonus Features 扩展算术命令集,再进一步加入链式表达式解析、历史记录、颜色化输出等进阶功能,作为练习 Go / Rust / Node.js 命令行开发的完美起点。若想对比图形界面版计算器的差异,可同时参考仓库中的 Calculator-App 规格。
- 文档
- 教程
【免费下载链接】app-ideas
A Collection of application ideas which can be used to improve your coding skills.
相关推荐
app-ideas 实战指南:从零构建一个带 localStorage 持久化的 To-Do App(2-Intermediate)
app ideas 实战指南:从零构建一个带 localStorage 持久化的 To Do App(2 Intermediate) 导读 本文以 app id
文档教程App-Store-Connect-CLI 的 StoreKit Retention Messaging 支持:架构设计与命令行实战指南
App Store Connect CLI 的 StoreKit Retention Messaging 支持:架构设计与命令行实战指南 导读 本篇技术指南聚焦
urfave/cli 子命令(Subcommands)实战指南:构建 Git 风格的多级命令行工具
urfave/cli 子命令(Subcommands)实战指南:构建 Git 风格的多级命令行工具 本指南围绕 docs/v2/examples/subcomm
CLI开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考