用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 ...
随机推荐
- win7再分配磁盘新加卷
磁盘在系统刚分区的时候可以做磁盘分区最好 1.右键我的电脑,选在管理 2.在此窗口下依次展开选项,点击存储->磁盘管理,右边是我已经分好的盘不用看的 3.确认一下我的电脑的各个盘的空间,选择要压 ...
- vue+element 中 el-input框 限制只能输入数字及一位小数
仅个人经验,希望能帮到有需要的人. 第一次写 就话不多说了直接上代码. <el-input @keyup.native="proving(index)" v-model=&q ...
- 使用VS2005编译安装openssl1.1.1c
1.首先获取openssl源码包 openssl-1.1.1c.tar.gz: 2.安装 ActivePerl: 2.解压源码包,打开vs2005命令行工具,通过命令行进入openssl源码包根目录: ...
- C++之new关键字
我们都知道new是用来在程序运行过程中为变量临时分配内存的C++关键字,那它跟C语言中的malloc有什么区别呢,相比之下又为什么推荐使用new呢 c++ throwing() void* opera ...
- Beeline里面执行hive脚本 函数nvl2()与replace()报错
Beeline里面执行hive脚本函数nvl2()与replace()报错 写脚本的时候是在impala里面执行的,都正常,但是转换为调度的时候是在beeline里面执行的 就会有问题了. 详情如下: ...
- Leetcode题解 - DFS部分题目代码+思路(756、1034、1110、491、721、988)
756. 金字塔转换矩阵 """ 学到的新知识: from collections import defaultditc可以帮我们初始化字典,不至于取到某个不存在的值的时 ...
- 【AGC028D】Chord
Problem Description 给定一个圆,圆上均等地放着 \(2n\) 个点,已有 \(k\) 对点之间连好了边,从中选择剩下 \(n-k\) 对点随意连边. 求所有连边方案中,联通块的个数 ...
- 高级Java开发人员最常访问的几个网站
这是高级Java开发人员最常访问的几个网站. 这些网站提供新闻,一般问题或面试问题的答案,精彩的讲座等.质量是优秀网站的关键因素,这此网站都有较高的质量内容.下面逐一介绍: 1. Stackoverf ...
- HALCON数据类型和C#对应数据类型的对比
摘要:HALCON数据类型:Iconic Variables(图形变量).Control Variables(控制变量).在C#中,图形变量用HObject声明,控制变量用HTuple声明.(halc ...
- sudo go 找不到命令
我们使用 sudo 时,使用的配置文件是 /etc/sudoers. 解决配置 /etc/sudoers 文件中的 Defaults secure_path 这一项.将 $GOROOT/bin 目录加 ...