python學習之路之案例2---計算器

 

1.運用到的知識點

  1.python正則表達式的應用,re.search('pattern',str).group()

  2.函數中遞歸的使用

  3.python函數、基本語法、控制語句if ...else ...、for循環語句的使用

  4,字符串的格式化、字符串的拼接

  5,列表的使用

  6.while True:statement  死循環的使用

 

2.代碼

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import re


#處理乘除
def compute_mul_div(arg):
    #這裏需要傳入1個arg列表
    value = arg[0]
    #print value
    #mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*]',value)
    #對字符串進行乘除匹配:如1+2*3-3,就匹配:2*3
    mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',value)
    #沒匹配到就直接返回
    if not mch:
        return
    #將匹配到的內容保存在content中
    content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',value).group()
    #print content
    #對匹配到的內容進行*、/判斷,然後進行相應的計算,如2*3,先分割後計算
    if len(content.split('*'))>1:
        n1,n2 = content.split('*')
        get_value = float(n1) * float(n2)
    else:
        n1,n2 = content.split('/')
        get_value = float(n1) / float(n2)
    #取出匹配內容兩頭的內容:before,after
    before,after = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',value,1)
    #然後拼接成新的字符串
    new_str = "%s%s%s" %(before,get_value,after)
    #把new_str賦值到arg[0]中
    arg[0] = new_str
    #再遞歸進行乘除計算
    compute_mul_div(arg)

#compute_mul_div(["1+2*3-4",0])

#print compute_mul_div([])

#處理加減
def compute_add_sub(arg):
    #arg = ["3+4-2--4++2",0]
    #對傳進來的arg[0]表達式進行第1次處理,將表達式中的++\--變成+,+-、-+變成-,處理完成以後就直接break
    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
    #然後對傳進來的arg[0]表達式進行第2次處理,提取首位爲“-”,並將提取的次數保存在arg[1]中
    #並且沒提取1次:將表達式中的"+"替換成"-"."-"替換成"+",然後取arg[0]表達式字符串中第1到最後1位即可賦給arg[0]
    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:]
    value = arg[0]
    #對字符串value進行匹配,匹配加或減兩邊的內容,如1+2-3,就匹配1+2
    mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',value)
    #如果沒匹配到就直接發回
    if not mch:
        return
    #將匹配的內容保存在content中,如1+2
    content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',value).group()
    #對匹配的內容進行計算:先進行判斷+、-,判斷後進行分割,分割後在針對+、-進行計算
    if len(content.split('+'))>1:
        n1,n2 =content.split('+')
        get_value = float(n1)+float(n2)
    else:
        n1,n2 =content.split('-')
        get_value = float(n1)-float(n2)
    #取出匹配內容兩頭的內容,封裝在before,after中
    before,after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*',str(value),1)
    #before = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*',value,1)[0]
    #after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*',value,1)[1]
    #將計算後的:before+結果+after,進行拼接,
    new_str = "%s%s%s" %(before,get_value,after)
    #再把拼接後的字符串賦值到arg[0]中,然後再遞歸進行計算
    arg[0] = new_str
    compute_add_sub(arg)


#compute_add_sub(["1+3-2",0])
#計算取出來的表達式
#"""
def compute(expr):
    #先將表達式封裝在inp列表中,列表的第一個元素表示:待處理表達式,第二個元素代表在表達式中首位爲-號,然後我們進行提取的次數
    inp = [expr,0]
    #先進行乘除運算
    compute_mul_div(inp)
    #再進行加減運算
    compute_add_sub(inp)

    #判斷inp[1]是奇數還是偶數,若是奇數,表明結果爲負數,否則爲正數
    count = divmod(inp[1],2)
    result = float(inp[0])
    if count[1] == 1:
        result = result * (-1)

    return result

#執行取出表達式
def excute(expr):
    #匹配最裏層的括號,如:1+2*(3/(3-2)*2),這裏匹配的是(3-2)
    #若沒括號了 直接返回表達式
    if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)',expr):
        return expr

    #用正則表達式取出最裏括號的內容,並去掉2邊的括號,得到新的表達式:content
    content = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)',expr).group()
    #只取字符串中第1個到倒數第二個之間的內容,即取去掉兩側的括號。如"(2+3)"只取2+3,不取兩邊的括號
    new_content = content[1:len(content)-1]
    ##將expr按匹配的內容進行分割:得到--before,匹配內容,after,得到content兩側的內容,並賦值給before,after
    new_list = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)',expr)
    before = new_list[0]
    after = new_list[2]
    #before,nothing,after = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)',expr)

    #將new_content進行計算,計算得到result
    result = compute(new_content)
    #將before+result+after進行拼接,得到new_expr
    new_expr = "%s%s%s" %(before,result,after)
    #最終返回,遞歸執行excute(new_expr)
    return excute(new_expr)


#主函數
if __name__ == "__main__":
    #將帶計算的表達式中的所包含的空格先去掉,得到沒有空格的表達式
    str1 = "4*3-10*(3*2-1*9/3)  +10"
    no_space_str = re.sub('\s*','',str1)

    #執行括號處理函數,取出優先計算或處理的內層表達式
    ret = excute(no_space_str)
    #inp = [ret,0]
    #然後對取出來的內層表達式進行計算:包括先處理乘除後處理加減
    final = compute(ret)
    #打印最終計算的值

    print final
#"""

  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章