Python计算器(模拟eval)

简介: 目的:实现同Python中eval函数一样,对于复杂算术运算提供一个简易的计算器;思路:1、通过正则表达式,将运算式子中所有的数字和运算符分割开来形成类表的方式,然后可以方便列表检索进行运算,eq_format(eq)函数;2、通过列表的检索,通过递归的运算,一层层的剥离掉(),然后进行+,-,*...

目的:实现同Python中eval函数一样,对于复杂算术运算提供一个简易的计算器;
思路:
1、通过正则表达式,将运算式子中所有的数字和运算符分割开来形成类表的方式,然后可以方便列表检索进行运算,eq_format(eq)函数;
2、通过列表的检索,通过递归的运算,一层层的剥离掉(),然后进行+,-,*,/,最终得到完全没有括号的算式,进行最后一步的运算,期间需要处理+-,--的情况出现,主要涉及到change(eq,count)函数;
(对于()剥离的情况,主要是通过遍历列表,如果遇到左括号,则把当前左括号的索引赋值给参数bracket,直到遇到第一个右括号,此时的索引与bracket中间的元素即为最内层括号的元素,用切片的方式提取出来,通过 calculate() 函数计算出值,然后用计算结果去替换掉此时左括号到第一个右括号的元素,此时去除第一层括号,然后进入递归,不断递归直至去除所有括号;
可能遇到的问题:

  不要用index的方式去取当前左括号的索引,因为列表的index方法返回的一直都是第一个左括号的索引,而不是当前左括号的索引,会导致出错。因此在函数内用参数 自定义的参数count 进行计数当前索引值。用计算得出的值来替换掉第一层括号部分后,有可能会出现 ‘+-’ ,‘ - -’的情况,然后用change() 函数进行处理)

3、去括号的方式,主要是从最内层开始突破,通过运算得到结果替换掉(),然后一层层向外运算剥离,最后得到结果,主要是simplify(format_list)函数中嵌套change()函数和calculate()函数进行运算取括号以及特殊处理;
4、对于乘除的运算详见deal_multiplication_division()函数部分,方法也是递归,处理掉一层乘除以后得到的结果进行判断处理掉+-,--的情况,然后进入下一步运算,其中嵌套change(eq,count)函数来进行特殊处理;
5、对于加减的运算详见deal_plus_minus()函数部分,方法同样是递归;
6、整体运算的过程主要是calculate(s_eq)函数,通过判断是加减还是乘除的方式嵌套deal_multiplication_division()函数和deal_plus_minus()函数,然后嵌套在simplify()函数当中进行运算;
7、最后使用calculator(eq)主函数,嵌套simplify()和calculate()函数进行最后的计算得到结果;

详细代码如下:

import re

def eq_format(eq): #格式化计算式函数
    '''
    :param eq:输入的算术字符串
    :return: 格式化后的列表,例如['-','2','+','3','*','12','/','123']
    '''
    format_list = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)',eq)
    #print(format_list)      '[\d\.]+|\(|\+|\-|\*|\/|\)'
    return format_list #返回格式化的列表形式内容

def change(eq,count): #解决同时出现+-,--类的格式化列表
    '''
    :param eq:去掉括号以后或者乘除后的格式化列表
    :param count: 发生变化的元素的索引位置
    :return: 返回一个没有+-,--等类的格式化列表内容
    '''
    if eq[count] == '-': #如果第count元素是-的话
        if eq[count-1] == '-': #且第count-1元素也是-
            eq[count-1] = '+' #那么调整count-1元素为+
            del eq[count] #删除第count元素内容
        elif eq[count-1] == '+':
            eq[count-1] = '-'
            del eq[count]
    return eq

def deal_multiplication_division(eq): #处理所有的乘除的计算方程式
    '''
    :param eq:处理带有乘除符号的格式化列表
    :return: 去掉乘除好以后的格式化列表
    '''
    count = 0
    for i in eq:
        if i == '*':
            if eq[count+1] != '-':
                eq[count-1] = float(eq[count-1]) * float(eq[count+1])
                del(eq[count])
                del(eq[count])
            elif eq[count+1] == '-':
                eq[count] = float(eq[count-1]) * float(eq[count+2])
                eq[count - 1] = '-'
                del(eq[count+1])
                del(eq[count+1])
            eq = change(eq,count-1)
            return deal_multiplication_division(eq)
        elif i == '/':
            if eq[count+1] != '-':
                eq[count-1] = float(eq[count-1]) / float(eq[count+1])
                del(eq[count])
                del(eq[count])
            elif eq[count+1] == '-':
                eq[count] = float(eq[count-1]) / float(eq[count+2])
                eq[count-1] = '-'
                del(eq[count+1])
                del(eq[count+1])
            eq = change(eq,count-1)
            return deal_multiplication_division(eq)
        count = count + 1
    return eq

def deal_plus_minus(eq): #处理所有的加减方程式的计算
    '''
    :param eq:只带有加减号的格式化列表
    :return: 计算出整个列表的结果
    '''
    count = 0
    if eq[0] != '-':
        sum = float(eq[0])
    else:
        sum = 0.0
    for i in eq:
        if i == '-':
            sum = sum - float(eq[count+1])
        elif i == '+':
            sum = sum + float(eq[count+1])
        count = count + 1
    if sum >= 0:
        eq = [str(sum)]
    else:
        eq = ['-',str(-sum)]
    return eq

def calculate(s_eq): #处理进行加减乘除
    '''
    :param s_eq:不带括号的格式化列表
    :return: 返回最终的计算结果
    '''
    if '*' or '/' in s_eq:
        s_eq = deal_multiplication_division(s_eq)
    if '+' or '-' in s_eq:
        s_eq = deal_plus_minus(s_eq)
    return s_eq

def simplify(format_list): #递归方式去掉括号,并计算到最后一层没有括号
    '''
    :param format_list:输入的算是格式化列表如['-','2','+','3','*','12','/','123']
    :return:通过递归去掉括号,返回最终简化后没有括号的列表
    '''
    bracket = 0 #用于存放左括号在格式化列表中的索引
    count = 0
    for i in format_list:
        if i == '(':
            bracket = count
        elif i == ')':
            temp = format_list[bracket + 1 : count]
            new_temp = calculate(temp)
            format_list = format_list[:bracket] + new_temp + format_list[count+1:]
            format_list = change(format_list,bracket) #解决去括号后出现的'--','+-'问题
            return simplify(format_list) #递归去掉括号
        count = count + 1
    return format_list #当递归到最后一层层的时候,不在有括号,因此返回最后无括号的列表内容

def calculator(eq): #计算主函数,主要判断最终计算结果的正负值,并返回
    format_list = eq_format(eq) # 把字符串变成格式化的列表形式
    s_eq = simplify(format_list) #去掉括号,得到一个无括号的格式化列表
    ans = calculate(s_eq) #计算最终结果
    if len(ans) == 2: #判断最终结果的正负值并返回结果
        ans = -float(ans[1])
    else:
        ans = float(ans[0])
    return ans #返回最终的结果

if __name__ == '__main__':
    equation = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    ans = calculator(equation)
    print('eval运算结果:',eval(equation))
    print('程序运算结果:',ans)

_
参考链接:
link

目录
相关文章
|
7月前
|
Python
如何使用Python编写一个简单的计算器程序
如何使用Python编写一个简单的计算器程序
229 0
|
7月前
|
安全 Serverless Python
用Python实现计算器功能
用Python实现计算器功能
84 1
|
2月前
|
云计算 Python
用python给你写个简单的计算器功能网页啊
这张图片展示了阿里巴巴集团的组织架构图,涵盖了核心电商、云计算、数字媒体与娱乐、创新业务等主要板块,以及各板块下的具体业务单元和部门。
|
2月前
|
存储 IDE 数据处理
使用Python构建一个高级计算器
本文介绍如何使用Python和`tkinter`库构建一个高级计算器。该计算器支持基本运算(加、减、乘、除、求整、求余)、科学运算(平方根、幂等)以及简单的图形用户界面(GUI)。通过该项目,您将学习到如何处理用户输入、执行计算并显示结果。适合初学者提升编程技能。
127 0
|
4月前
|
Python
Python eval()函数的使用
Python eval()函数的使用
90 1
|
7月前
|
Python
python tkinter 最简洁的计算器按钮排列
python tkinter 最简洁的计算器按钮排列
62 0
|
5月前
|
Python
Python 中 eval 与 exec 的相同点和不同点
【7月更文挑战第17天】相同点: `eval` 和 `exec` 都能动态执行 Python 代码字符串。 不同点: 返回值 - `eval`: 计算表达式的值并返回结果。 - `exec`: 执行一系列语句,不返回任何值。 作用范围 - `eval`: 只能在当前作用域计算表达式。 - `exec`: 可以修改全局和局部变量。 输入的代码类型 - `eval`: 通常用于计算一个表达式。 - `exec`: 用于执行一系列语句。 总之,`eval` 更适合简单的表达式求值,而 `exec` 适用于执行更复杂的代码块。使用时需注意安全性,避免执行不可信的用户输入。
46 11
|
4月前
|
存储 数据可视化 Python
【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】
【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】
267 1
|
4月前
|
Python
【Leetcode刷题Python】224. 基本计算器
LeetCode上题目“224. 基本计算器”的Python解决方案,通过使用栈来解析和计算包含加减运算及括号的算术表达式。
49 1
|
3月前
|
开发者 Python
Python 编程入门:从零到一实现简单计算器
【8月更文挑战第31天】 在这个数字技术日益发展的时代,编程已成为一项基础技能。本文通过构建一个简单的Python计算器项目,引导初学者步入编程世界的大门。我们将一起学习如何定义函数、处理用户输入以及执行基本算术操作,最终实现一个能够进行加减乘除运算的小工具。无论你是编程新手还是想复习基础知识的开发者,这篇文章都将为你提供一次愉快的编程体验。

热门文章

最新文章