1. 模块化计算器

模块化计算器 学习卡片

任务说明

本案例要求实现一个支持加、减、乘、除四种基本运算的计算器,核心目标在于演示Python项目的模块化拆分方式:将运算逻辑、输入解析与用户界面分离到独立模块中,并通过清晰的函数接口进行协作。最终交付一个可在命令行直接运行的最小可复现程序。

模块划分与接口定义

整个项目拆分为三个模块,职责边界如下:

  • calculator/operations.py:仅包含四则运算的纯函数,不涉及任何输入输出;
  • calculator/parser.py:负责将用户输入的字符串解析为运算类型与操作数,并调用operations中的函数完成计算;
  • main.py:程序入口,负责读取命令行输入、调用parser模块并打印结果。

模块间的调用关系与数据流向如下图所示:

main.py 入口:读取输入 调用 parse_expression() parser.py 解析表达式 调用 operations 函数 operations.py add / subtract multiply / divide 表达式字符串 操作数 + 运算符 返回数值结果 返回数值结果

代码实现

项目文件结构如下:

module_calculator/
├── calculator/
│   ├── __init__.py
│   ├── operations.py
│   └── parser.py
└── main.py

calculator/operations.py —— 纯运算函数模块:

"""四则运算核心逻辑,不依赖任何外部输入。"""

def add(a: float, b: float) -> float:
    """返回 a + b 的结果。"""
    return a + b

def subtract(a: float, b: float) -> float:
    """返回 a - b 的结果。"""
    return a - b

def multiply(a: float, b: float) -> float:
    """返回 a * b 的结果。"""
    return a * b

def divide(a: float, b: float) -> float:
    """返回 a / b 的结果,除数为零时抛出 ValueError。"""
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

calculator/parser.py —— 表达式解析与调度模块:

"""将用户输入的字符串解析为运算并调用 operations 模块。"""
from calculator import operations

# 运算符到函数的映射表
_OPERATORS = {
    "+": operations.add,
    "-": operations.subtract,
    "*": operations.multiply,
    "/": operations.divide,
}

def parse_expression(expression: str) -> float:
    """
    解析形如 "3 + 5" 的表达式字符串,返回计算结果。

    参数:
        expression: 包含两个操作数和一个运算符的字符串,例如 "10 / 4"。

    返回:
        计算结果(float)。

    异常:
        ValueError: 表达式格式不正确、运算符不支持或除数为零时抛出。
    """
    parts = expression.strip().split()
    if len(parts) != 3:
        raise ValueError("表达式格式错误,应为:操作数 运算符 操作数,例如 3 + 5")

    a_str, op, b_str = parts

    try:
        a = float(a_str)
        b = float(b_str)
    except ValueError:
        raise ValueError("操作数必须是有效数字")

    if op not in _OPERATORS:
        raise ValueError(f"不支持的运算符: {op},仅支持 + - * /")

    return _OPERATORS[op](a, b)

calculator/__init__.py —— 包标识文件(内容为空):

# 本文件用于将 calculator 目录标记为 Python 包

main.py —— 程序入口:

"""命令行计算器入口:读取用户输入并输出结果。"""
from calculator.parser import parse_expression

def main() -> None:
    print("模块化计算器(输入 q 退出)")
    print("支持格式:操作数 运算符 操作数,例如:5 * 3")
    while True:
        user_input = input("> ").strip()
        if user_input.lower() == "q":
            print("已退出")
            break
        if not user_input:
            continue
        try:
            result = parse_expression(user_input)
            # 若结果为整数则按整数显示,否则保留适当小数位
            if result == int(result):
                print(f"= {int(result)}")
            else:
                print(f"= {result:.6f}".rstrip("0").rstrip("."))
        except ValueError as e:
            print(f"错误: {e}")

if __name__ == "__main__":
    main()

运行与验证

运行方式:在项目根目录(module_calculator/)下执行:

python main.py

验证步骤与判定标准:

  1. 在交互提示符后输入 8 + 12,程序应输出 = 20;
  2. 输入 7.5 * 2,程序应输出 = 15;
  3. 输入 10 / 4,程序应输出 = 2.5;
  4. 输入 5 / 0,程序应输出 错误: 除数不能为零;
  5. 输入 3 % 2,程序应输出 错误: 不支持的运算符: %,仅支持 + - * /;
  6. 输入 q,程序应输出 已退出 并结束。

以上预期输出均由代码逻辑直接唯一推出。若实际运行结果与上述一致,则判定案例实现正确,模块划分与接口定义满足任务目标。