您的位置:首页 > 编程语言 > Python开发

python之计算器(第四天)

2016-02-18 10:34 585 查看
作业:

使用正则表达式和递归实现计算器功能。

实现:

1、实现带括号的计算

2、实现指数、加减乘除求余等功能

一、实例说明:

本实例自己写了个版本,但依旧存在一点bug,例:-2-2等计算问题,故最后在武SIR的代码基础上加了指数、求余等功能。

该计算器思路:
1、递归寻找表达式中只含有数字和运算符的表达式,并计算结果
2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
使用技术:
1、正则表达式
2、递归

二、流程图:



三、代码:


#!/usr/bin/python27
#_*_coding=utf-8_*_





'''
该计算器思路:
1、递归寻找表达式中只含有数字和运算符的表达式,并计算结果
2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
使用技术:
1、正则表达式
2、递归


执行流程如下:
********************请计算表达式:1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))********************
before:['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
-40.0/5=-8.0
after:['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
==========上一次计算结束==========
before:['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953
after:['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
==========上一次计算结束==========
before:['1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))']
60-30+-8.0*173545.880953=-1388337.04762
after:['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
==========上一次计算结束==========
before:['1-2*(-1388337.04762-(-4*3)/(16-3*2))']
-4*3=-12.0
after:['1-2*(-1388337.04762--12.0/(16-3*2))']
==========上一次计算结束==========
before:['1-2*(-1388337.04762--12.0/(16-3*2))']
16-3*2=10.0
after:['1-2*(-1388337.04762--12.0/10.0)']
==========上一次计算结束==========
before:['1-2*(-1388337.04762--12.0/10.0)']
-1388337.04762--12.0/10.0=-1388335.84762
after:['1-2*-1388335.84762']
==========上一次计算结束==========
我的计算结果:2776672.69524
'''



importre,os,sys


defcompute_exponent(arg):
"""操作指数
:paramexpression:表达式
:return:计算结果
"""


val=arg[0]
pattern=re.compile(r'\d+\.?\d*[\*]{2}[\+\-]?\d+\.?\d*')
mch=pattern.search(val)
ifnotmch:
return
content=pattern.search(val).group()


iflen(content.split('**'))>1:
n1,n2=content.split('**')
value=float(n1)**float(n2)
else:
pass


before,after=pattern.split(val,1)
new_str="%s%s%s"%(before,value,after)
arg[0]=new_str
compute_exponent(arg)


defcompute_mul_div(arg):
"""操作乘除
:paramexpression:表达式
:return:计算结果
"""


val=arg[0]
pattern=re.compile(r'\d+\.?\d*[\*\/\%\/\/]+[\+\-]?\d+\.*\d*')
mch=pattern.search(val)
ifnotmch:
return
content=pattern.search(val).group()


iflen(content.split('*'))>1:
n1,n2=content.split('*')
value=float(n1)*float(n2)
eliflen(content.split('//'))>1:
n1,n2=content.split('//')
value=float(n1)//float(n2)
eliflen(content.split('%'))>1:
n1,n2=content.split('%')
value=float(n1)%float(n2)
eliflen(content.split('/'))>1:
n1,n2=content.split('/')
value=float(n1)/float(n2)
else:
pass


before,after=pattern.split(val,1)
new_str="%s%s%s"%(before,value,after)
arg[0]=new_str
compute_mul_div(arg)



defcompute_add_sub(arg):
"""操作加减
:paramexpression:表达式
:return:计算结果
"""
whileTrue:
ifarg[0].__contains__('+-')orarg[0].__contains__("++")orarg[0].__contains__('-+')orarg[0].__contains__("--"):
arg[0]=arg[0].replace('+-','-')
arg[0]=arg[0].replace('++','+')
arg[0]=arg[0].replace('-+','-')
arg[0]=arg[0].replace('--','+')
else:
break



ifarg[0].startswith('-'):


arg[1]+=1
arg[0]=arg[0].replace('-','&')
arg[0]=arg[0].replace('+','-')
arg[0]=arg[0].replace('&','+')
arg[0]=arg[0][1:]
val=arg[0]


pattern=re.compile(r'\d+\.?\d*[\+\-]{1}\d+\.?\d*')
mch=pattern.search(val)
ifnotmch:
return
content=pattern.search(val).group()
iflen(content.split('+'))>1:
n1,n2=content.split('+')
value=float(n1)+float(n2)
else:
n1,n2=content.split('-')
value=float(n1)-float(n2)


before,after=pattern.split(val,1)
new_str="%s%s%s"%(before,value,after)
arg[0]=new_str
compute_add_sub(arg)



defcompute(expression):
"""操作加减乘除
:paramexpression:表达式
:return:计算结果
"""
inp=[expression,0]


#处理表达式中的指数
compute_exponent(inp)


#处理表达式中的乘除求余等
compute_mul_div(inp)


#处理表达式的加减
compute_add_sub(inp)
ifdivmod(inp[1],2)[1]==1:
result=float(inp[0])
result=result*-1
else:
result=float(inp[0])
returnresult



defexec_bracket(expression):
"""递归处理括号,并计算
:paramexpression:表达式
:return:最终计算结果
"""
pattern=re.compile(r'\(([\+\-\*\/\%\/\/\*\*]*\d+\.*\d*){2,}\)')
#如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444
#ifnotre.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)',expression):
ifnotpattern.search(expression):
final=compute(expression)
returnfinal
#获取第一个只含有数字/小数和操作符的括号
#如:
#['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
#找出:(-40.0/5)
content=pattern.search(expression).group()



#分割表达式,即:
#将['1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
#分割更三部分:['1-2*((60-30+((-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
before,nothing,after=pattern.split(expression,1)


print('before:',expression)
content=content[1:len(content)-1]


#计算,提取的表示(-40.0/5),并活的结果,即:-40.0/5=-8.0
ret=compute(content)


print('%s=%s'%(content,ret))


#将执行结果拼接,['1-2*((60-30+(-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
expression="%s%s%s"%(before,ret,after)
print('after:',expression)
print("="*10,'previousresultis',"="*10)


#循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:
#['1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']


#如此周而复始的操作,直到表达式中不再含有括号
returnexec_bracket(expression)




#使用__name__的目的:
#只有执行pythonindex.py时,以下代码才执行
#如果其他人导入该模块,以下代码不执行
if__name__=="__main__":
flag=True


os.system('clear')###清屏###


print('\n================================================================')
print('\033[33m欢迎使用计算器:\033[0m')
print('\n================================================================')




whileflag:
calculate_input=raw_input('\033[32m请输入计算的表达式|(退出:q)\033[0m')
calculate_input=re.sub('\s*','',calculate_input)
iflen(calculate_input)==0:
continue
elifcalculate_input=='q':
sys.exit('退出程序')
elifre.search('[^0-9\.\-\+\*\/\%\/\/\*\*\(\)]',calculate_input):
print('\033[31m输入错误,请重新输入!!!\033[0m')
else:
result=exec_bracket(calculate_input)
print('theexpressionresultis%s'%result)


计算器


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: