python之計算器(第四天)

做業:python

     使用正則表達式和遞歸實現計算器功能。正則表達式

 

 實現:express

       一、實現帶括號的計算函數

       二、實現指數、加減乘除求餘等功能spa

       

1、實例說明:code

本實例本身寫了個版本,但依舊存在一點bug,例:-2-2等計算問題,故最後在武SIR的代碼基礎上加了指數、求餘等功能。blog

該計算器思路:
一、遞歸尋找表達式中只含有 數字和運算符的表達式,並計算結果
二、因爲整數計算會忽略小數,全部的數字都認爲是浮點型操做,以此來保留小數
使用技術:
一、正則表達式
二、遞歸遞歸

 

2、流程圖:utf-8

 

3、代碼:input

 
  

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

 
  

 

 
  


'''
該計算器思路:
一、遞歸尋找表達式中只含有 數字和運算符的表達式,並計算結果
二、因爲整數計算會忽略小數,全部的數字都認爲是浮點型操做,以此來保留小數
使用技術:
一、正則表達式
二、遞歸

 
  

執行流程以下:
******************** 請計算表達式: 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
'''

 
  


import re,os,sys

 
  

def compute_exponent(arg):
""" 操做指數
:param expression:表達式
:return:計算結果
"""

 
  

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

 
  

if len(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)

 
  

def compute_mul_div(arg):
""" 操做乘除
:param expression:表達式
:return:計算結果
"""

 
  

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

 
  

if len(content.split('*'))>1:
n1, n2 = content.split('*')
value = float(n1) * float(n2)
elif len(content.split('//'))>1:
n1, n2 = content.split('//')
value = float(n1) // float(n2)
elif len(content.split('%'))>1:
n1, n2 = content.split('%')
value = float(n1) % float(n2)
elif len(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)

 
  


def compute_add_sub(arg):
""" 操做加減
:param expression:表達式
:return:計算結果
"""
while True:
if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"):
arg[0] = arg[0].replace('+-','-')
arg[0] = arg[0].replace('++','+')
arg[0] = arg[0].replace('-+','-')
arg[0] = arg[0].replace('--','+')
else:
break

 
  


if arg[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)
if not mch:
return
content = pattern.search(val).group()
if len(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)

 
  


def compute(expression):
""" 操做加減乘除
:param expression:表達式
:return:計算結果
"""
inp = [expression,0]

 
  

# 處理表達式中的指數
compute_exponent(inp)

 
  

# 處理表達式中的乘除求餘等
compute_mul_div(inp)

 
  

# 處理表達式的加減
compute_add_sub(inp)
if divmod(inp[1],2)[1] == 1:
result = float(inp[0])
result = result * -1
else:
result = float(inp[0])
return result

 
  


def exec_bracket(expression):
""" 遞歸處理括號,並計算
:param expression: 表達式
:return:最終計算結果
"""
pattern = re.compile(r'\(([\+\-\*\/\%\/\/\*\*]*\d+\.*\d*){2,}\)')
# 若是表達式中已經沒有括號,則直接調用負責計算的函數,將表達式結果返回,如:2*1-82+444
#if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression):
if not pattern.search(expression):
final = compute(expression)
return final
# 獲取 第一個 只含有 數字/小數 和 操做符 的括號
# 如:
# ['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,'previous result is',"="*10)

 
  

# 循環繼續下次括號處理操做,本次攜帶者的是已被處理後的表達式,即:
# ['1-2*((60-30+ -8.0 *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']

 
  

# 如此周而復始的操做,直到表達式中再也不含有括號
return exec_bracket(expression)

 
  

 

 
  

# 使用 __name__ 的目的:
# 只有執行 python index.py 時,如下代碼才執行
# 若是其餘人導入該模塊,如下代碼不執行
if __name__ == "__main__":
flag = True

 
  

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

 
  

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

 
  

 

 
  

while flag:
calculate_input = raw_input('\033[32m請輸入計算的表達式 | (退出:q)\033[0m')
calculate_input = re.sub('\s*','',calculate_input)
if len(calculate_input) == 0:
continue
elif calculate_input == 'q':
sys.exit('退出程序')
elif re.search('[^0-9\.\-\+\*\/\%\/\/\*\*\(\)]',calculate_input):
print('\033[31m 輸入錯誤,請從新輸入!!!\033[0m')
else:
result = exec_bracket(calculate_input)
print('the expression result is %s' % result)

 
  

計算器

相關文章
相關標籤/搜索