用Python代码写的计算器
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代码写的计算器的更多相关文章
- [置顶]
如何用PYTHON代码写出音乐
如何用PYTHON代码写出音乐 什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深 ...
- python 之路,200行Python代码写了个打飞机游戏!
早就知道pygame模块,就是没怎么深入研究过,恰逢这周未没约到妹子,只能自己在家玩自己啦,一时兴起,花了几个小时写了个打飞机程序. 很有意思,跟大家分享下. 先看一下项目结构 "" ...
- 如何用PYTHON代码写出音乐
什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深度学习写歌词已经实现了,之后会分 ...
- 10 行 Python 代码写的模糊查询
导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...
- 用 150 行 Python 代码写的量子计算模拟器
简评:让你更轻松地明白,量子计算机如何遵循线性代数计算的. 这是个 GItHub 项目,可以简单了解一下. qusim.py 是一个多量子位的量子计算机模拟器(玩具?),用 150 行的 python ...
- 使用13行Python代码实现四则运算计算器函数
原创的刷新行数记录的代码!!! 支持带小括号,支持多个连续+-号,如-7.9/(-1.2-++--99.3/-4.44)*---(2998.654+-+-+-(+1.3-7.654/(-1.36-99 ...
- (转)python 之路,200行Python代码写了个打飞机游戏!
原文:https://www.cnblogs.com/alex3714/p/7966656.html
- 利用Python代码编写计算器小程序
import tkinter import tkinter.messagebox import math class JSQ: def __init__(self): #创建主界面 self.root ...
- python代码如何写的优雅?
简介 在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅.废话不多说,现在马上开始. 使用enumerate方法替代range ...
随机推荐
- CodeForces1006D-Two Strings Swaps
D. Two Strings Swaps time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- HashMap的常见问题
关于HashMap的一些常见的问题,自己总结一下: 首选HashMap在jdk1.7和jdk1.8里面的实现是不同的,在jdk1.7中HashMap的底层实现是通过数组+链表的形式实现的,在jdk1. ...
- eviews面板数据的操作
数据结构: 打开eviews File>new>workfile Object>new object > pool 输入城市名称: _bj 下划线加名称(必须是英文),竖着输入 ...
- 通过Centreon监控apache、MySQL、Hadoop服务状态
在上面的章节中,只是简单介绍了Centreon的几个基础监控项,例如添加主机.服务等,这些对于一个监控系统来说是远远不够的,本节将重点介绍对一些扩展服务的监控,也就是对一些常见应用的监控. 一. Na ...
- jwt Token验证与解析
网上似乎没有相关代码 贴上一段Token的解析认证 [TestMethod] public void TestMethod1() { string Token = "eyJhbGciOiJI ...
- RequireJS 打包工具
r.js是RequireJS的一个附产品,支持在 NodeJS环境下运行AMD程序,并且其包含了一个名为RequireJS Optimizer的工具,可以为项目完成合并脚本等优化操作 RequireJ ...
- Spring Boot 如何自定义返回错误码错误信息
说明 在实际的开发过程中,很多时候要定义符合自己业务的错误码和错误信息,而不是统一的而不是统一的下面这种格式返回到调用端 INTERNAL_SERVER_ERROR(500, "Intern ...
- 多个datasource的配置与实现原理
一般情况下,一个项目中只会有一个datasource,但是在某些情况.或者业务需求的情况下会出现一个项目有多个datasource的情况,当满足一定条件的时候,对数据库的操作就会从一个一个 ...
- TypeScript引入moment.js报错“无法找到moment模块”及解决方法
npm i moment下载moment完成后,在ts文件中引入 import * as moment from "moment"; 结果疯狂报错,未找到moment模块. 一开始 ...
- 数百道BAT等大厂最新Python面试真题,学到你手软!
春招临近,无论是要找工作的准毕业生,还是身在职场想要提升自己的程序员,提升自己的算法内功心法.提升 Python 编程能力,总是大有裨益的.今天,小编发现了一份好资源:Python 实现的面试题集锦! ...