首页 > 编程语言 >Python 设计一个简单的计算器

Python 设计一个简单的计算器

时间:2023-06-23 14:33:58浏览次数:39  
标签:index 12 sub Python 计算器 list value 简单 calc

Python 设计一个简单的计算器

设计目标

  • 实现加减乘除及拓号优先级解析
  • 用户输入 1 - 2 * ( (6-3 +(-5/5)*(9-2*3/3 + 7/3*7/4*12 +10 * 5/5 )) - (-4*3)/ (12-3*2) ) 等类似公式后,
  • 必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致  

流程图

代码

1、主文件

#!/usr/bin/env python
 
import re
 
 
def multi_or_divi(string):
    # 乘除法函数
    # 去掉括号
    calc_list = re.search("[^()]+", string)
    # 以乘除符号分割
    sub_calc_list = re.split("[*/]", calc_list.group())
    # 获取到字符串中的乘除符号
    sub_operator_list = re.findall("[*/]", calc_list.group())
    sub_res = None
    for index in range(len(sub_calc_list)):
        if sub_res:
            if sub_operator_list[index-1] == "*":
                sub_res *= float(sub_calc_list[index])
            else:
                sub_res /= float(sub_calc_list[index])
        else:
            sub_res = float(sub_calc_list[index])
    return float(sub_res)
 
 
def add_or_sub(string):
    # 加减法函数
    # 去掉括号
    calc_list = re.search("[^()]+", string)
    # 以加减符号分割
    sub_calc_list = re.split("[+-]", calc_list.group())
    # 获取到字符串中的加减符号
    sub_operator_list = re.findall("[+-]", calc_list.group())
    # 如果字符串已减号开头,需要特殊处理
    if re.match("[-+]", calc_list.group()):
        if sub_operator_list[0] == "-":
            sub_calc_list[1] = -float(sub_calc_list[1])
        # 对sub_operator_list和sub_calc_list进行字符串切割,或者到正确数据
        sub_operator_list = sub_operator_list[1:]
        sub_calc_list = sub_calc_list[1:]
        # 对字符串切割后,如何sub_calc_list为空,表示传过来的数为-X,直接返回sub_calc_list[0]即可,无需乘除运算
        if len(sub_operator_list) == 0:
            return sub_calc_list[0]
    sub_res = None
    for index in range(len(sub_calc_list)):
        if sub_res:
            if sub_operator_list[index-1] == "+":
                sub_res += float(sub_calc_list[index])
            else:
                sub_res -= float(sub_calc_list[index])
        else:
            sub_res = float(sub_calc_list[index])
    return float(sub_res)
 
 
def deal_minus_issue(ret):
    # 处理减法字符串
    # 创建一个新字符串用于返回处理后的字符串
    new_ret = []
    for index, item in enumerate(ret):
        if item.endswith("*") or item.endswith("/"):
            new_ret.append("%s-%s" %(ret[index], ret[index+1]))
        elif re.search("[*/]", ret[index]):
            new_ret.append(ret[index])
    return new_ret
 
 
def main():
    # 输入字符串
    a = '1 - 2 * ( (6-3 +(-5/5)*(9-2*3/3 + 7/3*7/4*12 +10 * 5/5 )) - (-4*3)/ (12-3*2) )'
    # a = '+(-40/5+3*(-12))'
    # 去空格
    a = a.replace(" ", "")
    # 设置循环退出的条件
    count = 2
    while True and count > 0:
        # 最内行括号
        calc_list = re.search(r'\([^()]+\)', a)
        if calc_list:
            # 如果能取到括号,把正则匹配结果赋值给calc_list_value
            calc_list_value = calc_list.group()
        else:
            # 如果不能取到括号,说明已经没有括号了,这只有加减乘除,对多只需要2次计算即可得出结果
            # 把a字符串赋值给calc_list_value
            count -= 1
            calc_list_value = a
        if "+" in calc_list_value or "-" in calc_list_value:
            if "*" in calc_list_value or "/" in calc_list_value:
                # 去掉括号以便以加减符号分割字符串
                calc_list1 = re.findall(r'[^()]+', calc_list_value)
                # 以加减符号去分割
                calc_list2 = re.split(r'[-+]', calc_list1[0])
                # 调用处理减法字符串函数,处理下*-或者/-这类问题
                calc_list2 = deal_minus_issue(calc_list2)
                # 返回后的calc_list列表只有包含乘除的式子
                for item in calc_list2:
                    # 对每一个乘除调用乘除函数
                    value = multi_or_divi(item)
                    # 把计算后的结果替换掉原来的值
                    a = a.replace(item, str(value))
                    # 处理下字符串中出现的++或+-问题
                    a = a.replace("+-", "-")
                    a = a.replace("--", "+")
            else:
                # 式子中没有乘除符号,那就只有加减符号,调用加减函数
                value = add_or_sub(calc_list_value)
                # 把计算后的结果替换掉原来的值
                a = a.replace(calc_list_value, str(value))
                # 处理下字符串中出现的++或+-问题
                a = a.replace("+-", "-")
                a = a.replace("--", "+")
        else:
            if "*" in calc_list_value or "/" in calc_list_value:
                # 式子中没有加减符号,那就只有乘除符号,调用处理减法字符串函数,处理下*-或者/-这类问题
                value = multi_or_divi(calc_list_value)
                # 把计算后的结果替换掉原来的值
                a = a.replace(calc_list_value, str(value))
                # 处理下字符串中出现的++或+-问题
                a = a.replace("+-", "-")
                a = a.replace("--", "+")
        print("运行结果:", a)
 
if __name__ == '__main__':
    main()

2、运行结果

运行结果: 1-2*((6-3-1.0*(9-2*3/3+7/3*7/4*12+10*1.0))-(-4*3)/(12-3*2))
运行结果: 1-2*((6-3-1.0*(9-2.0+49.00000000000001+10.0))-(-4*3)/(12-3*2))
运行结果: 1-2*((6-3-1.0*66.0)-(-4*3)/(12-3*2))
运行结果: 1-2*((6-3-66.0)-(-4*3)/(12-3*2))
运行结果: 1-2*(-63.0-(-4*3)/(12-3*2))
运行结果: 1-2*(-63.0-(-12.0)/(12-3*2))
运行结果: 1-2*(-63.0+12.0/(12-3*2))
运行结果: 1-2*(-63.0+12.0/(12-6.0))
运行结果: 1-2*(-63.0+12.0/6.0)
运行结果: 1-2*(-63.0+2.0)
运行结果: 1-2*-61.0
运行结果: 1+122.0
运行结果: 123.0

标签:index,12,sub,Python,计算器,list,value,简单,calc
From: https://www.cnblogs.com/evescn/p/17499117.html

相关文章

  • NLP实战必读-基于Python的文本分析实战
    本书介绍   从新闻和演讲到社交媒体上的非正式聊天,自然语言是最丰富、利用最少的数据来源之一。它不仅源源不断地供给,总是在环境中变化和适应;它还包含传统数据源无法传达的信息。解锁自然语言的关键是通过文本分析的创造性应用。本书展示了数据科学家用应用机器学习模型构建语......
  • Python 算法之冒泡排序
    Python算法之冒泡排序冒泡排序冒泡排序算法的原理如下:(从后往前)1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。3、针对所有的元素重复以上的步骤,除了最后一......
  • 将python程序打包为exe可执行文件方法
    将py打包为exe文件需要依赖pyinstaller第三方库-F:打包后只生成单个exe格式文件;-D:默认选项,创建一个目录,包含exe文件以及大量依赖文件;-c:默认选项,使用控制台(就是类似cmd的黑框);-w:不使用控制台;-p:添加搜索路径,让其找到对应的库;-i:改变生成程序的icon图标。1.单个py文件编......
  • Python 算法之二分查找
    Python算法之二分查找二分查找二分查找又称折半查找优点是比较次数少,查找速度快,平均性能好缺点是要求待查表为有序表,且插入删除困难折半查找方法适用于不经常变动而查找频繁的有序列表。猜数字游戏1、生成一个有序列表2、用户猜测某个数字是否在列表中代码#!/usr......
  • 密码学:凯撒密码(移位密码)原理、加密与解密(Python代码示例)
    原理凯撒密码(移位密码):是一种替换加密,明文中的所有字母都在字母表上向后或向前按照一个固定数目进行偏移后被替换成密文。例如,偏移量为3位的时候:A对应D,B对应E,C对应F等当偏移量为13位的时候,凯撒密码又叫回转密码(ROT13):明文加密得到密文,密文再加密就会得到明文(因为偏移量为13位,一共......
  • Python.re正则表达式的标记
    标记方式在Python的re模块中,有以下几种标记(flags)可用于修改正则表达式的匹配行为:re.I(或re.IGNORECASE):忽略大小写匹配。例如,正则表达式[a-z]+将匹配小写字母字符串,而使用re.I标记后,它将匹配大小写混合或大写字母字符串。re.M(或re.MULTILINE):多行模式匹配。默认情况下,正......
  • Python TTS 初体验
    最近有个需求由于刚入职公司不管是读写还是听说  都有很大的问题于是正好找到一本python的书准备把他再刷一遍  但是听力也想一起练了怎么办呢 TTS 百度,讯飞,这种还要钱 不考虑了打开gayhub 搜TTS GitHub-coqui-ai/TTS:......
  • Dapper简单使用读写分离
    usingDapper;usingSystem;usingSystem.Collections.Generic;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.Threading.Tasks;usingSystem.Linq;usingCloudCubic.Common.LogHelper;usingCloudcubic.Common;usingSystem.Diagnostics;namespace......
  • python 的方法与类
        ......
  • python: How to Create a Python Package
    上篇博文的两个类文件,拖着一个创建好的包名Model中,有些代码会自己生成变化"""StudentScoreInfo.py学生成绩类date2023-06-16edit:GeovinDu,geovindu,涂聚文ide:PyCharm2023.1python11"""importdatetimeimportsysimportosclassStudentScore(object):......