老男孩Day6作業:計算器


作業需求:

1、實現加減乘除及拓號優先級解析

2、用戶輸入
1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等類似公式后

3、必須自己解析里面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現),

4、運算后得出結果,結果必須與真實的計算器所得出的結果一致

 

1)流程圖

 

首先,根據計算符號的優先級考慮,帶有括號的優先級最高,需要優先計算括號內的式子,計算完括號內的式子之后,破除括號,再進行加減乘除的運算。在四則運算中,加減運算是一個優先級的,乘除運算是一個優先級的,那么我們就可以先行計算乘除,將整個式子中的乘除全部計算完成以后,再次進行加減的計算,最終可以得到運算的結果

2、程序會判斷用戶輸入的表達式是否符有效並給出相應提示

2、用戶在主界面中輸入:"q"程序會退出

3、程序通過eval函數計算出正確計算結果

 

二、具體實現

#-*- Coding:utf-8 -*-
# Author: D.Gray
import re,sys
'''
要求:
1\實現加減乘除及拓號優先級解析
2\用戶輸入
1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等類似公式后,必須自己解析里面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現),
運算后得出結果,結果必須與真實的計算器所得出的結果一致
'''
def compute_mul_div(mg):
    '''
    定義一個乘除函數
    :param mg:
    :return:
    '''
    num = mg[0]  #  -40/5
    match = re.search("\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*",num)
    if not match:
        return
    content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',num).group()
    if len(content.split('*')) > 1:
        v1,v2 = content.split('*')
        value = float(v1) * float(v2)
        # print('v1>>>%s and v2>>>%s'%(str(v1),str(v2)))
        # print('computer_mul:%s and %s'% (str(content),str(value)))
    else:
        v1, v2 = content.split('/')
        value = float(v1) / float(v2)
        # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2)))
        # print('computer_del:%s and %s' % (str(content),str(value)))
    pur,suf = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',num,1)
    new_str = '%s%s%s'%(pur,value,suf)
    mg[0] = new_str
    #print('pur>>>%s    value>>>%s     uer>>>%s   new_str>>>%s' % (pur, value,suf,new_str))
    compute_mul_div(mg)

def compute_add_sub(mg):
    '''
    運算表達式加減函數
    :param mg:
    :return:
    '''
    while True:
        if mg[0].__contains__('+-') or mg[0].__contains__('++') or mg[0].__contains__('-+') or mg[0].__contains__('--'):
            mg[0] = mg[0].replace('+-', '-')  # 將-替換掉+-
            mg[0] = mg[0].replace('++', '+')  # 將+替換掉++
            mg[0] = mg[0].replace('-+', '-')  # 將-替換掉-+
            mg[0] = mg[0].replace('--', '+')  # 將+替換掉--
        else:
            break
    if mg[0].startswith('-'):  # 如果arg的第0個元素是以-開頭
        mg[1] += 1  # arg的第一個元素自加1
        mg[0] = mg[0].replace('-', '&')
        mg[0] = mg[0].replace('+', '-')
        mg[0] = mg[0].replace('&', '+')  # 將-變+,+變-
        mg[0] = mg[0][1:]  # 將arg中第0個元素中前面多出來的符號去掉
    num = mg[0]  # -40/5
    match = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num)
    if not match:
        return
    content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num).group()
    if len(content.split('+')) > 1:
        v1, v2 = content.split('+')
        value = float(v1) + float(v2)
        # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2)))
        # print('computer_add:%s and %s' % (str(content),str(value)))
    else:
        v1, v2 = content.split('-')
        value = float(v1) - float(v2)
        # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2)))
        # print('computer_sub:%s and %s' % (str(content),str(value)))
    pur,suf = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num,1)
    new_str = '%s%s%s'%(pur,value,suf)
    mg[0] = new_str
    compute_add_sub(mg)

def calate(match_group):
    '''
    計算表達式函數
    :param match_group:
    :return:
    '''
    mg = [match_group.strip('()'),0]   # mg = ['-40/5']
    compute_mul_div(mg)     #調用乘除運算函數
    compute_add_sub(mg)     #調用加減運算函數
    if divmod(mg[1],2)[1] == 1:
        result = float(mg[0])
        result *= -1
        #print('divmod_result:%s'%result)
    else:
        result = float(mg[0])
    #print('in the calator-new_str():%s'%mg)
    return result

def kuohao(calculate):
    '''
    取出表達式中括號函數
    :param calculate:
    :return:
    '''
    while True:
        match = re.search('\([^()]+\)',calculate)   #使用正則表達式 取出優先級最高的括號 並計算
        if match:   #如果表達式中有括號
            match_group = match.group() #
            match_result = calate(match_group)  #調用計算函數
            calculate = calculate.replace(match_group,str(match_result)) #將括號計算后的結果替換原參數
        else:   #若表達式中沒有括號
            calate(calculate)
            break
    return calate(calculate)

print('\033[33m 歡迎使用計算器 :\033[0m'.center(50,'-'))
print('例:1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))')
while True:
    calculate_input = input('\033[32m請輸入計算的表達式 | (退出:q)>>>\033[0m')
    calculate_input = re.sub('\s*','',calculate_input)
    if calculate_input == 'q':
        exit('程序退出')
    if len(calculate_input) == 0:
        continue
    if re.search('[^\d\+\-\*/\(\)]',calculate_input):   #使用正則表達式判斷用戶輸入是否是數字、"+-*/"、"()"
        print('\033[31m 輸入錯誤,請重新輸入!!!\033[0m')
    else:
        result = kuohao(calculate_input)    #調用去除括號的函數
        print('\033[34m 計算結果>>>%s\033[0m'%result)
        print('\033[35m 正確結果>>>%s\033[0m' % eval(calculate_input))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM