当前位置: 首页 > article >正文

python小项目编程-初级(1、计算器)

1. 需求分析

1.1 功能需求

1)支持基本的四则运算:加法(+)、减法(-)、乘法(*)、除法(/);2)支持多步运算,例如 1 + 2 * 3;3)不支持括号,但运算符优先级遵循数学规则(先乘除,后加减)

1.3 非功能需求

1)提供简单的错误处理,例如除零错误或非法运算表达式输入;2)通过单元测试确保代码的正确性并人工测试保证可用性。

2、设计

2.1 总体设计

1、输入:用户通过命令行输入一个字符串表达式,例如1+2*2,

2、解析输入:将字符串解析为数字和操作符的列表,例如 [1, '+', 2, '*', 2]

3、计算:先计算乘法和除法(优先级高)再计算加法和减法(优先级低)

4、结果:返回最终的计算结果。

2.2 模块设计

1、parse_expression模块:将输入的字符串解析为数字和操作符的列表。使用正则表达式提取数字和操作符

2、calculate模块:按照运算符优先级计算表达式先处理乘和法,再处理加和减。

3、main模块:接收用户输入,处理输入异常,调用解析和计算模块,输出结果
 

2.3 数据结构

使用列表存储解析后的表达式,例如 [1, '+', 2, '*', 3]

2.4 错误处理

检查除零错误。检查非法输入进行输入规则校验保证合法输入,对非法输入抛出异常。使用正则表达式pattern来验证输入的表达式格式。正则表达式的规则确保了表达式只包含数字、运算符和括号,并且遵循正确的格式。如果输入不符合规则,抛出ValleError异常,并给出相应的错误提示。

实现

3.1 代码实现

import re

def parse_expression(expression):
    """
    将表达式字符串解析为数字和操作符的列表。
    例如:"1+2*3" -> [1, '+', 2, '*', 3]
    """
    # 使用正则表达式匹配数字和操作符
    
    tokens = re.findall(r'\d+|\+|\-|\*|\/', expression)
    # 将数字转换为整数或浮点数
    for i, token in enumerate(tokens):
        if token.isdigit():
            tokens[i] = int(token)
    return tokens

def calculate(tokens):
    """
    计算解析后的表达式列表。
    处理乘法和除法的优先级。
    """
    # 先处理乘法和除法
    i = 0
    while i < len(tokens):
        if tokens[i] == '*':
            tokens[i - 1] = tokens[i - 1] * tokens[i + 1]
            del tokens[i:i + 2]
        elif tokens[i] == '/':
            tokens[i - 1] = tokens[i - 1] / tokens[i + 1]
            del tokens[i:i + 2]
        else:
            i += 1

    # 再处理加法和减法
    result = tokens[0]
    i = 1
    while i < len(tokens):
        if tokens[i] == '+':
            result += tokens[i + 1]
        elif tokens[i] == '-':
            result -= tokens[i + 1]
        i += 2

    return result

def main():
    
    print("支持的运算:加(+)、减(-)、乘(*)、除(/)")
    print("输入 'exit' 退出计算器")
    pattern = r'^\s*[\d]+(\.\d+)?(\s*[\+\-\*\/]\s*[\d]+(\.\d+)?)*\s*$'
    
    while True:
        expression = input("请输入表达式(例如 1+2*3):")
        if expression.lower() == 'exit':
            print("感谢使用,再见!")
            break
        try:
            if not re.match(pattern, expression):
                raise ValueError("输入格式错误,请确保只包含数字、运算符,并遵循正确的格式。")
            tokens = parse_expression(expression)
            result = calculate(tokens)
            print(f"结果: {result}")
        except Exception as e:
            print(f"输入错误:{e}")
if __name__ == "__main__":
    main()

测试:

测试用例

测试样例测试结果预期
1+122   PASS
2*3+61212 PASS
10 - 4/28.08.0 PASS
1+2*377 PASS
10/0输入错误:除零错误输入错误:除零错误 PASS
1+a输入错误输入错误 PASS

UT单元测试

import unittest
from calculator import parse_expression, calculate

class TestCalculator(unittest.TestCase):
    def test_parse_expression(self):
        self.assertEqual(parse_expression("1+2*3"), [1, '+', 2, '*', 3])
        self.assertEqual(parse_expression("10-4/2"), [10, '-', 4, '/', 2])

    def test_calculate(self):
        self.assertEqual(calculate([1, '+', 2, '*', 3]), 7)
        self.assertEqual(calculate([10, '-', 4, '/', 2]), 8.0)
        with self.assertRaises(ValueError):
            calculate([10, '/', 0])

if __name__ == "__main__":
    unittest.main()


http://www.kler.cn/a/536590.html

相关文章:

  • 利用matlab寻找矩阵中最大值及其位置
  • 高端入门:Ollama 本地高效部署DeepSeek模型深度搜索解决方案
  • C++, STL容器 array:固定大小数组深度解析
  • 通过多层混合MTL结构提升股票市场预测的准确性,R²最高为0.98
  • 【QT笔记】使用QScrollArea实现多行文本样式显示
  • OpenAI 实战进阶教程 - 第六节: OpenAI 与爬虫集成实现任务自动化
  • 使用动态协议包,实现客户端与服务器端
  • 【探商宝】DeepSeek 最新模型对 ChatGPT 的影响及行业新变革
  • Java全栈项目:酒店客房管理系统
  • 【华为OD机考】2024E+D卷真题【完全原创题解 详细考点分类 不断更新题目 六种主流语言Py+Java+Cpp+C+Js+Go】
  • Java基础知识总结(四十八)--TCP传输、TCP客户端、TCP服务端
  • OnlyOffice 全面指南:从基础使用到深度自定义
  • postgreSQL16.6源码安装
  • unity学习29:摄像机camera相关skybox 和 Render Texture测试效果
  • IDEA启动项目慢问题处理
  • 详解代理模式
  • VSCode便捷开发
  • JS逆向案例-ali231补环境 - 14
  • 日本游戏机市场5年来首次陷入萎缩;特斯拉招人推进人形机器人量产;任天堂专利显示Switch2手柄可用作鼠标...| 游戏智眼日报
  • AWS SMS短信通知实战:使用 Pinpoint SMS Voice V2 完整指南
  • MFC 应用最小化到系统托盘
  • NetCore Consul动态伸缩+Ocelot 网关 缓存 自定义缓存 + 限流、熔断、超时 等服务治理
  • 如何轻松将Matlab生成的图表嵌入PowerPoint演示文稿
  • 23、深入理解 Java Stream:高效处理数据的利器
  • 什么是高光谱成像相机?
  • .NET周刊【1月第3期 2025-01-19】