1.极限压缩版

import re, functools
def cal(formula):
while re.search('(?:\d+\.?\d+|\d+)[+\-*/]', formula):
while re.search('[*/]', formula): formula = re.sub('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) * float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('*')) if '*' in re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) / float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('/'))), formula, 1)
if re.search('(?:\d+\.?\d+|\d+)[+\-]', formula): formula = re.sub('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) + float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('+', 1)) if '+' in re.search('(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) - float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('-', 1))), formula, 1)
return formula
formula = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
while re.search('\([^\(\)]+\)', formula):
formula = re.sub('\([^\(\)]+\)', cal(re.search('\([^\(\)]+\)', re.sub('\s', '', formula)).group()).strip('()'), formula, 1)
while re.search('[+\-*/]-', formula): formula = re.sub('[+]-', '-', formula) if '+-' in formula else re.sub('--', '', formula) if formula.startswith('--') else re.sub('(?:\d+\.?\d+|\d+)[*/]-', '-' + re.findall('(?:\d+\.?\d+|\d+)[*/](?=-)', formula)[0], formula) if re.search('[*/]-', formula) else re.sub('--', '+', formula)
print(cal(formula).split('.0')[0] if cal(formula).endswith('.0') else cal(formula))

2.完整版

import re
from functools import reduce def plus_minus(formula):
'''
计算无括号的加减法算式
:param formula: 等待计算的只包含加减法的字符串
:return: 计算结果的字符串
'''
p1 = re.compile('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)') # 匹配一次加减法
while re.search(p1, formula): # 每次计算一个二元加减,并替换到原字符串上,直到计算并计算完所有数
x = re.search(p1, formula).group() # 匹配出一次计算,判断是加法还是减法,再由reduce把分割后的两个数交给匿名函数去计算。
formula = re.sub(p1, str(reduce(lambda i, j: float(i) + float(j), x.rsplit('+', 1)) if '+' in x else reduce(lambda i, j: float(i) - float(j), x.rsplit('-', 1))), formula, 1)
return formula
# ps.计算加减法可以采用与乘除法不同的方式,可以把所有数全匹配出来再一起计算出来 def multi_divi(formula):
'''
计算无括号的乘除法算式
:param formula: 等待计算的只包含乘除法的字符串
:return: 计算结果的字符串
'''
p = re.compile('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)')
while re.search(p, formula):
y = re.search(p, formula).group()
formula = re.sub(p, str(reduce(lambda i, j: float(i) * float(j), y.split('*')) if '*' in y else reduce(lambda i, j: float(i) / float(j), y.split('/'))), formula, 1)
return formula def parentheses_parse(formula):
'''
用来处理括号,并调用加减乘除完成计算
:param formula: 数学算式的字符串,支持加减乘除和括号
:return: 最终结果的整型或浮点型
'''
formula = re.sub('\s', '', formula)
p = re.compile('\([^\(\)]+\)') # 匹配内层括号
while re.search(p, formula): # 循环到没有括号为止
f = re.search(p, formula).group()
formula = re.sub(p, plus_minus(multi_divi(f)).strip('()'), formula, 1) # 调用加减法嵌套乘除法,计算完括号内的式子,并去除括号 # 处理去除括号后可能出现的其他符号与负号相连的情况
while re.search('[+\-*/]-', formula):
formula = re.sub('[+]-', '-', formula)
formula = re.sub('--', '', formula) if formula.startswith('--') else re.sub('--', '+', formula) # 正负为负,负负为正,并且避免正号出现在最前端
if re.search('[*/]-', formula): # 遇到乘除连接负号的情况时,需要先把负号前置,再进行一次上面加减连接负号的处理
n = re.search('(?:\d+\.?\d+|\d+)[*/](?=-)', formula).group() # 这里使用正向预匹配获得如'7*-'这样的序列中的'7*'的部分
formula = re.sub('(?:\d+\.?\d+|\d+)[*/]-', '-' + n, formula) # 使用刚获得的字符串进行替换,来使‘7*-’变成‘-7*’的样子
formula = plus_minus(multi_divi(formula)) # 没有括号了,再计算最后一次
if formula.endswith('.0'): # 优化显示
formula = int(formula.split('.0')[0])
else:
formula = float(formula)
return formula # 在此处输入算式
print(parentheses_parse('1-2*((60- 30+(-40/5)*(9 -2*5/3+7/3*99/4*2998+1 0*568/14))-(-4*3)/(16-3*2))'))

3.思路清晰版

import re
from functools import reduce def mul_div(exp):
"""
计算两个数的乘法或者除法
:param exp:
:return:
"""
if '*' in exp:
a, b = exp.split('*')
return float(a)*float(b)
if '/' in exp:
a, b = exp.split('/')
return float(a) / float(b) def exp_fmt(exp):
"""
符号整理
:param exp:
:return:
"""
while re.search('[+-]{2,}',exp):
exp = exp.replace('--','+')
exp = exp.replace('+-','-')
exp = exp.replace('-+','-')
exp = exp.replace('++','+')
return exp def remove_addsub(exp):
"""
计算两个数的加减法
:param exp:
:return:
"""
ret = re.findall('[-+]?\d+(?:\.\d+)?',exp)
res = reduce(lambda a,b:float(a)+float(b),ret)
return res def remove_muldiv(exp):
"""
计算表达式中的所有的乘除法
:param exp:
:return:
"""
while True:
ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',exp)
if ret:
son_exp = ret.group()
res = mul_div(son_exp)
exp = exp.replace(son_exp,str(res))
else:return exp def cal(exp):
res = remove_muldiv(exp) # 计算乘除
res = exp_fmt(res) # 符号整理
ret = remove_addsub(res) # 计算加减
return ret def main(exp):
exp = exp.replace(' ','')
while True:
ret = re.search('\([^()]+\)', exp)
if ret:
res = cal(ret.group())
exp = exp.replace(ret.group(), str(res))
else: return cal(exp)
exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
ret = main(exp)
print(ret)

待续

用Python代码写的计算器的更多相关文章

  1. [置顶] 如何用PYTHON代码写出音乐

    如何用PYTHON代码写出音乐 什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深 ...

  2. python 之路,200行Python代码写了个打飞机游戏!

    早就知道pygame模块,就是没怎么深入研究过,恰逢这周未没约到妹子,只能自己在家玩自己啦,一时兴起,花了几个小时写了个打飞机程序. 很有意思,跟大家分享下. 先看一下项目结构 "" ...

  3. 如何用PYTHON代码写出音乐

    什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深度学习写歌词已经实现了,之后会分 ...

  4. 10 行 Python 代码写的模糊查询

    导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...

  5. 用 150 行 Python 代码写的量子计算模拟器

    简评:让你更轻松地明白,量子计算机如何遵循线性代数计算的. 这是个 GItHub 项目,可以简单了解一下. qusim.py 是一个多量子位的量子计算机模拟器(玩具?),用 150 行的 python ...

  6. 使用13行Python代码实现四则运算计算器函数

    原创的刷新行数记录的代码!!! 支持带小括号,支持多个连续+-号,如-7.9/(-1.2-++--99.3/-4.44)*---(2998.654+-+-+-(+1.3-7.654/(-1.36-99 ...

  7. (转)python 之路,200行Python代码写了个打飞机游戏!

    原文:https://www.cnblogs.com/alex3714/p/7966656.html

  8. 利用Python代码编写计算器小程序

    import tkinter import tkinter.messagebox import math class JSQ: def __init__(self): #创建主界面 self.root ...

  9. python代码如何写的优雅?

    简介 在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅.废话不多说,现在马上开始. 使用enumerate方法替代range ...

随机推荐

  1. kafka生产消息,streaming消费

    package com.bd.useranalysis.spark.streaming.kafka2es; import com.alibaba.fastjson.JSON; import com.b ...

  2. 常用eslint配置

    "off"或者0 //关闭规则关闭 "warn"或者1 //在打开的规则作为警告(不影响退出代码) "error"或者2 //把规则作为一个 ...

  3. Visual Studio2019及.NET CORE3.0的安装教程

    看到很多开发.net core的初学者在安装的时候就陷入问题了,不知道安装那些东西,好吧,既然要分享知识那么就尽量做得精细一点吧,我决定从零开始为大家讲解.net core,同时有.net core工 ...

  4. webpack实践(三)- html-webpack-plugin

    webpack系列博客中代码均在github上:https://github.com/JEmbrace/webpack-practice <webpack实践(一)- 先入个门> < ...

  5. NodeJS7-1本地构建_gulp入门学习

    NodeJS在前端最常用的两种方式: 1.做成webserver 2.做成前端开发的相关工具 本地构建:前端发布代码都会经过压缩(谁来处理) ,前端技术的日新月异,利用新特性代码变得易读,清晰,可是老 ...

  6. 由malloc和new引发的段错误

    class Queue{ private: struct node{ string data; struct node * next,*priv; } private: struct node * p ...

  7. 吃透Python上下文管理器

    什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...

  8. AI行业精选日报_人工智能(12·20)

    IDC:中国智能家居市场2020年十大预测 12 月 20 日消息,「IDC 咨询」官方公众号发布「中国智能家居 2020 年十大预测」.具体内容如下:互联平台加速整合.语音助手广泛赋能.智能电视显著 ...

  9. 弹性盒子中的order

    order order 属性 设置或检索弹性盒模型对象的子元素出现的順序.. 注意:如果元素不是弹性盒对象的元素,则 order 属性不起作用. <!DOCTYPE html> <h ...

  10. JS---案例:图标跟着鼠标飞(有bug)

    案例:图标跟着鼠标飞(有bug) <!DOCTYPE html> <html lang="en"> <head> <meta charse ...