python之路day5_学习python之路--Day5 计算器
需求
可以处理带括号的加减乘除运算
需求分析
匹配括号
re.search('\(.*\)',a)
匹配最里面括号
re.search(r'\([^()]+\)')
可以用strip()方法去掉括号
计算公式
1.0-2.0((60.0-30.0+(-40.0/5.0)(9.0-2.05.0/3.0+7.0/3.099.0/4.02998.0+10.0568.0/14.0)))
匹配二级括号
re.search('\(\(.*\)\)',a)
确定以上方法之后我们先来画流程图
calculator
实现
可以看到我们的逻辑是用re.findall(r'\([^()]+\)')判断是否存在括号,如果存在,我们就进入处理([^()]+)最里面括号的内容
这是一个循环,直到处理的没有([^()]+)这一项,也就代表没有括号内的内容了
如果一开始就没有匹配到([^()]+),那我们就直接按加减乘除的规则处理他
一开始的循环可以这么写:
loop_flag2=True
while loop_flag2:
if re.findall('\([^()]+\)',enter):
enter=three_level_brackets_func(enter)
else:
loop_flag2=False
else:
finnal_result=no_brackets_func(enter)
print(finnal_result)
然后按着流程图,先处理高级运算符,也就是乘法和除法运算符,我们先处理除法,这是因为在实际操作中,除法必须按从左到右的顺序运算,除法运算符先算左边的和先算右边的结果,是天差地别的变化,乘法还好,先乘左边的还是先乘右边的结果都是一样,请看下面的列子:
>>> 3/4/5
0.15
>>> 3/(4/5)
3.75
#乘法
>>> 3*4*5
60
>>> 3*(4*5)
60
除法这部分的逻辑如下:
while True:
if operation.find('/') != -1:
division_cal=re.search('[0-9]+.[0-9]+/[\+\-]?[0-9]+.[0-9]+',operation).group()
num1=re.findall('([0-9]+.[0-9]+)/',operation)
num2=re.findall('/([\+\-]?[0-9]+.[0-9]+)',operation)
print('division left:',num1)
print('division right:',num2)
num1=float(num1[0])
num2=float(num2[0])
division_result=num1/num2
print('division result:',division_result)
operation=operation.replace(division_cal,str(division_result))
print('now operation is:',operation)
如果我们发现运算行里有'/'这个符号,代表除法,那么我们就把运算行第一个除法公式提取出来,用division_cal=re.search('[0-9]+.[0-9]+/[\+\-]?[0-9]+.[0-9]+',operation).group(),匹配出来的是[0-9]+.[0-9]+/[+-]?[0-9]+.[0-9]+,就是两个有小数点的数字中间是 / 除法运算符,例如34.5/-55.6这种。
然后把除法运算符左边的数字拿出来num1=re.findall('([0-9]+.[0-9]+)/',operation),是一个列表,会把所有'/'左边的数字拿出来
再把除法运算符右边的数字拿出来num2=re.findall('/([\+\-]?[0-9]+.[0-9]+)',operation),同理也是一个列表
num1=float(num1[0]) num2=float(num2[0])
我们算两个列表里第一位的数字,因为两个列表里项目是一一匹配的(如果输入的运算式正确的话),两个列表的第一位就代表他们是这个运算行第一个除法运算
算出的结果,用这个结果替换第一个除法公式 operation=operation.replace(division_cal,str(division_result))
这个运算行就少了一个除法公式
再循环,直到没有任何除法公式
接着,我们把没有除法公式了的运算行输入乘法函数里处理。目的是把所有乘法公式也替换掉
逻辑如下:
elif operation.find('*') != -1:
mutlip_cal=re.search('[0-9]+.[0-9]+\*[\+\-]?[0-9]+.[0-9]+',operation).group()
num1=re.findall('([0-9]+.[0-9]+)\*',operation)
num2=re.findall('\*([\+\-]?[0-9]+.[0-9]+)',operation)
print('multiplication left:',num1)
print('multiplication right:',num2)
num1=float(num1[0])
num2=float(num2[0])
mutlip_result=num1*num2
print('multiplication result:',mutlip_result)
operation=operation.replace(mutlip_cal,str(mutlip_result))
print('now operation is:',operation)
跟除法的规则一样,先找到第一个乘法公式,然后提取乘法符号'*'左边和右边的数字,相乘出结果,替换公式,再循环,直到没有任何乘法
如果乘法和除法的处理都做完了,那接下去可以想象,就只剩下加减了
while loop_flag:
new_operation=operation.strip('()')
if len(re.split('[+-]',new_operation)) > 1 and re.split('[+-]',new_operation)[0]:
pri_cal=re.search('[\+\-]?[0-9]+.[0-9]+[\+\-][0-9]+.[0-9]+',new_operation).group()
num1=re.findall('([\+\-]?[0-9]+.[0-9]+)[\+\-]',pri_cal)
num2=re.findall('[\+\-]?[0-9]+.[0-9]+([\+\-][0-9]+.[0-9]+)',pri_cal)
num1=float(num1[0])
num2=float(num2[0])
pri_result=num1+num2
operation=operation.replace(pri_cal,str(pri_result))
print('now operation is:',operation)
之前的运算可能还留下括号没有处理,我们用new_operation=operation.strip('()')这一句来去掉左右括号
if len(re.split('[+-]',new_operation)) > 1
这是判断除了'+-'号之外,还有几项数字,如果大于1,那就是还需要运算,当然这样就有个漏洞,如果是'-34.5'这种数字,re.split('[+-]','-34.5')这种方法分裂出来的项目是[],[34.5] 这样也是大于1项的,所以我们加一句
if re.split('[+-]',new_operation)[0]:
来判断分裂出来的第一位是不是空
接下来,pri_cal=re.search('[\+\-]?[0-9]+.[0-9]+[\+\-][0-9]+.[0-9]+',new_operation).group() 提取出第一个加减运算公式
num1=re.findall('([\+\-]?[0-9]+.[0-9]+)[\+\-]',pri_cal) 提取左边的数字
num2=re.findall('[\+\-]?[0-9]+.[0-9]+([\+\-][0-9]+.[0-9]+)',pri_cal 提取右边的数字
运算,因为我们匹配右边数字的时候已经把加减号也匹配进去了,python是支持1+-1这样运算的,所以我们运算直接就是把两个值加一起
operation=operation.replace(pri_cal,str(pri_result)) 拿运算结果替换加减运算式
循环
这里可能会遇到这么几种情况,一个是,经过一轮处理之后 34-(-5*11) 这种变成了34--55这种公式,到我们加减处理的逻辑里就无法匹配了,还有34+-55,34--55这种情况出现,[+-]?[0-9]+.[0-9]+([+-][0-9]+.[0-9]+匹配里也没有,当然我们也可以中间的[+-]写成[+-]{1,2}这种匹配一到两次的,但是接下去的运算可不能成功算出34+--55的结果,所以单独做个函数把这些不合法的运算符处理下
def symbol_judge(enter):
if '+-' in enter:
enter=enter.replace('+-','-')
elif '-+' in enter:
enter=enter.replace('-+','-')
elif '--' in enter:
enter=enter.replace('--','+')
return enter
完善一下之前的循环
def process(enter,re_result):
for i in re_result:
pre_symbol_result=pre_symbol_cal(i)
pri_symbol_result=pri_symbol_cal(pre_symbol_result)
pri_symbol_result=pri_symbol_result.strip('()')
enter=enter.replace(i,pri_symbol_result)
return enter
def three_level_brackets_func(enter):
re_result=re.findall(r'\([^()]+\)',enter)
print('brackets inner:',re_result)
enter=process(enter,re_result)
enter=symbol_judge(enter)
print(enter)
return enter
loop_flag2=True
while loop_flag2:
if re.findall('\([^()]+\)',enter):
enter=three_level_brackets_func(enter)
else:
loop_flag2=False
else:
finnal_result=no_brackets_func(enter)
print(finnal_result)
先处理括号内的内容,按照先乘除,再加减,结果去除左右括号,替换运算行里的(^[]+)内容,最后再对运算行里的不合法符号做个判断,传给开始的循环,再走一轮
终于我们的运算式里没有了括号,接着就该直接按先乘除后加减的四则运算逻辑,处理它们了
def no_brackets_func(enter):
print('HIT no_brackets')
if enter[0] == '-':
enter='0'+enter
raw_enter=pre_symbol_cal(enter)
raw_enter=symbol_judge(raw_enter)
enter=pri_symbol_cal(raw_enter)
print(enter)
return enter
这里面有个小细节,如果运算式开头是-34/55+66...这样子的,咱们之前写的逻辑就要再改了,好多地方也要调整,为了方便复用之前的代码,也是偷懒,其实只用在'-'号前面加一个0即可,逻辑走得通,同时不影响结果
好了,完整的代码如下:
#-*- coding:utf-8 -*-
#owner:houyizhong
import re
print('输入数字必须保留小数点一位\n例子:1.0-2.0*((60.0-30.0+(-40.0/5.0)*(9.0-2.0*5.0/3.0+7.0/3.0*99.0/4.0*2998.0+10.0*568.0/14.0))+(65.0+77.0)+6.0)')
enter=input('>>>')
def pre_symbol_cal(operation):
loop_flag=True
while loop_flag:
if operation.find('/') != -1:
division_cal=re.search('[0-9]+.[0-9]+/[\+\-]?[0-9]+.[0-9]+',operation).group()
num1=re.findall('([0-9]+.[0-9]+)/',operation)
num2=re.findall('/([\+\-]?[0-9]+.[0-9]+)',operation)
print('division left:',num1)
print('division right:',num2)
num1=float(num1[0])
num2=float(num2[0])
division_result=num1/num2
print('division result:',division_result)
operation=operation.replace(division_cal,str(division_result))
print('now operation is:',operation)
elif operation.find('*') != -1:
mutlip_cal=re.search('[0-9]+.[0-9]+\*[\+\-]?[0-9]+.[0-9]+',operation).group()
num1=re.findall('([0-9]+.[0-9]+)\*',operation)
num2=re.findall('\*([\+\-]?[0-9]+.[0-9]+)',operation)
print('multiplication left:',num1)
print('multiplication right:',num2)
num1=float(num1[0])
num2=float(num2[0])
mutlip_result=num1*num2
print('multiplication result:',mutlip_result)
operation=operation.replace(mutlip_cal,str(mutlip_result))
print('now operation is:',operation)
else:
loop_flag=False
return operation
def pri_symbol_cal(operation):
loop_flag=True
while loop_flag:
new_operation=operation.strip('()')
if len(re.split('[+-]',new_operation)) > 1 and re.split('[+-]',new_operation)[0]:
pri_cal=re.search('[\+\-]?[0-9]+.[0-9]+[\+\-][0-9]+.[0-9]+',new_operation).group()
num1=re.findall('([\+\-]?[0-9]+.[0-9]+)[\+\-]',pri_cal)
num2=re.findall('[\+\-]?[0-9]+.[0-9]+([\+\-][0-9]+.[0-9]+)',pri_cal)
num1=float(num1[0])
num2=float(num2[0])
pri_result=num1+num2
operation=operation.replace(pri_cal,str(pri_result))
print('now operation is:',operation)
else:
loop_flag=False
return operation
def symbol_judge(enter):
if '+-' in enter:
enter=enter.replace('+-','-')
elif '-+' in enter:
enter=enter.replace('-+','-')
elif '--' in enter:
enter=enter.replace('--','+')
return enter
def process(enter,re_result):
for i in re_result:
pre_symbol_result=pre_symbol_cal(i)
pri_symbol_result=pri_symbol_cal(pre_symbol_result)
pri_symbol_result=pri_symbol_result.strip('()')
enter=enter.replace(i,pri_symbol_result)
return enter
def three_level_brackets_func(enter):
re_result=re.findall(r'\([^()]+\)',enter)
print('brackets inner:',re_result)
enter=process(enter,re_result)
enter=symbol_judge(enter)
print(enter)
return enter
def no_brackets_func(enter):
print('HIT no_brackets')
if enter[0] == '-':
enter='0'+enter
raw_enter=pre_symbol_cal(enter)
raw_enter=symbol_judge(raw_enter)
enter=pri_symbol_cal(raw_enter)
print(enter)
return enter
loop_flag2=True
while loop_flag2:
if re.findall('\([^()]+\)',enter):
enter=three_level_brackets_func(enter)
else:
loop_flag2=False
else:
finnal_result=no_brackets_func(enter)
print(finnal_result)
python之路day5_学习python之路--Day5 计算器相关推荐
- 学python语言用什么软件-Python是什么?学习Python用什么编译器?
原标题:Python是什么?学习Python用什么编译器? Python是一个非常好用的程序语言,开发的速度非常快.Python的设计哲学是优雅.明确.简单.因此,Perl语言中总是有多种方法来做同一 ...
- python新手教程 从零开始-Python零基础从零开始学习Python十分钟快速入门
原标题:Python零基础从零开始学习Python十分钟快速入门 学习Python的,都知道Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.Python是一种动态解释型的 ...
- 初学者先学python语音好吗_献给Python初学者 零基础学习Python能学会吗
献给Python初学者 零基础学习Python能学会吗 时间:2018-01-08 来源:零基础学习Python方法讲解 零基础学习Python能学会吗?这个问题几乎是所有初学Python的小 ...
- 学python多贵_老男孩学习Python多少钱,学习Python贵吗?
而且现在不少人都想要参加python培训,在进行python培训之前,大家最关注的的莫过于培训机构好不好的问题了,当然了收费也是我们需要考虑的一点.当然选择培训机构不能只看费用方面的,还需要考虑师资力 ...
- 自学python需要的软件-学习Python,从入门到精通,其实只需要两个月就够了
毫无疑问,Python 是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握 Python 看似是一件十分困难的事.其实,只要掌握了科学的学习方法并制定了合理的学习计划, ...
- python自学教程推荐-学习python中的pandas有没有好的教程推荐?
上来就丢教程和资料,其实是把路带偏了!找到学习Pandas的方法比找教程重要的多!现在无论是学习Python还是Pandas,最大的问题不是没有资料,而恰恰是太多资料和教程,让人抓不住头绪. 很多凭着 ...
- 学习python需要什么基础-学习python需要什么基础
Python编程基础知识的学习最终目的是应用于项目中,因此,项目实战训练必不可少.下面小编给大家介绍学习python需要什么基础,一起来看看吧. 学习python需要掌握的基础 1.要有决心 做任何事 ...
- 初学者怎么自学python编程_怎样自学python编程?从零开始学习python,400集免费教程!...
作为小白,在学习Python的时候,必然会走一定的弯路,有人在弯路上走丢了,有人走出了弯路.我就是属于还未走出弯路的同学,所以我想谈谈我的Python学习之路. 01先了解一下什么是python? ...
- python作品代码_学习python的一些心得体会
初识python 专升本来到桂林电子科技大学的时候,谈及这个学校也许他是全国四所叫电子科技大学的学校,而我很幸运的从这个学校里毕业了,那个时候选修一门课程就是python的选修课,从此跟python结 ...
最新文章
- 我在 Spring 的 BeanUtils 踩到的那些坑,千万不要犯!
- Matlab入门笔记
- 程序员应该知道的七个图形工具
- python自建包的根目录可以直接import的方法
- FPL 2017最佳论文:如何对FPGA云发动DoS攻击?
- 1^2+2^2+……+n^2的公式证明
- html 图片防盗链,【反防盗链】介绍一个对付图片防盗链的方法
- php显示控制器不存在,解决ThinkPHP6提示控制器不存在问题
- VIM插件管理:管理插件的插件pathogen
- 惊!揭秘AI人工智能机器人自动写诗的奥秘!
- MP3 功能原理 及 软件方案设计(一)
- 重磅!2021年国内有名的编程培训机构排名公布啦
- 停止等待协议与连续 ARQ 协议
- Java微服务+分布式+全栈项目(一)---->项目介绍+MyBatis-Plus入门
- kubernetes 与 rook 架构说明
- 项目策划 文件管理系统
- 计算机基础:今天一次把 Unicode 和 UTF-8 说清楚
- GUI编程--PyQt5--QWidget2
- Python GUI编程 --转发:https://www.jianshu.com/p/91844c5bca78?tdsourcetag=s_pcqq_aiomsg
- J2EE金融项目开发实战视频教程
热门文章
- goland配置mysql失败_GoLand配置数据库、远程host以及远程调试
- Java多线程详解(线程池)
- c mysql linux,linux上C语言连接mysql
- mie散射理论方程_散射,原子分子散射
- mariadb不支持load data_不修改代码打包python机器学习工程
- SQL Server 2014安装图解
- 这是一台家庭计算机重启无效,我买了一台二手计算机,配置还可以,但有时会自动重启机器,这是为什? 爱问知识人...
- 企业云成本浪费高达30%!行云管家、Cloudyn等厂商给出解决方案...
- 澳大利亚超市巨头考虑设专门网站 方便代购买奶粉
- 默认conf指向位置