python基础(2):写一个简单的计算器,实现eval的功能

代码讲解:

总共分为个部分:

一.主函数:

def calc_my(str_num):
    #定义小括号的标志位
    parentheses_flag = True
    #去除参数中的空格字符
    str_num = re.sub(' ','',str_num)
    #如果有小括号
    while parentheses_flag:
        #查询第一个符合条件的小括号(这个小括号里面没有小括号)中的内容:如5+(1+2*(-4*5+2))-2中的(-4*5+2)
        parentheses_son = re.findall('\([^()]*\)', str_num)
        if parentheses_son:
            #以最小的小括号为一个单位,进行处理,返回一个字符串格式的计算结果
            str_num_small = delete_parentheses(parentheses_son[0])
            print("parentheses_son:%s" % parentheses_son[0])
            #将计算结果替换原表达式中的值
            str_num = str_num.replace(parentheses_son[0], str_num_small)
            # str_num = re.sub('\(%s\)' % parentheses_son[0], str_num_small, str_num)
        else:
            #没有小括号,则退出循环
            parentheses_flag = False
        #end
    #如果还有加减乘除治疗的运算符,则进行处理
    if re.findall('\d+[+\-*/]', str_num):
        num = delete_parentheses(str_num)
    return num

二.以第一个内部不包含小括号的小括号为单位,进行运算:

def delete_parentheses(parentheses_son_d):
    # 1去除最外面小括号
    parentheses_son_d = re.sub('[()]', '', parentheses_son_d)
    #字符串分割保存,如:-4*5+2;
    # real_num=['',4*5,2]
    # real_sign=[-,+]
    real_num = re.split('[\-+]',parentheses_son_d)
    real_sign = re.findall('[\-+]',parentheses_son_d)
    #如果real_num第一个值为空,那么此表达式中第一个元素一定是负数,将这个负号和第二个元素合并,删除第一个元素
    if real_num[0] =='':
        real_num[1] = real_sign[0] + real_num[1]
        del(real_num[0])
        del(real_sign[0])
    # real_num=[-4*5,2]
    # real_sign=[+]
    print("1.grouping:%s,%s" % (real_sign, real_num))
    #计算real_num中的乘除
    for index_first, i_first in enumerate(real_num):
        if re.findall('[*/]\d+', i_first):
            real_num[index_first] = calc_multi_divi(i_first)
        elif re.findall('[*/]$', i_first):
            real_num[index_first] = real_sign[index_first] + calc_multi_divi(i_first + real_num[index_first+1])
            del(real_num[index_first+1])
            del(real_sign[index_first])
    # real_num=[-20,2]
    # real_sign=[+]
    print("2.merge multi_divi:%s,%s" % (real_sign, real_num))
    #计算加减运算
    do_me = real_num[0]
    for index_second, i_second in enumerate(real_num):
        if index_second:
            do_me = calc_add_sub(do_me + real_sign[index_second-1] + real_num[index_second])
        #     if real_sign[index_second-1] =='+':
        #         do_me += real_num[index_second]
        #     else :
        #         do_me -= real_num[index_second]
    print("finally calc_add_sub:%s" % do_me)
    return do_me

三.乘除运算:

def calc_multi_divi(num):
    #-2*3*4
    #以'*'或'/'为分隔符,切分字符串,保存到数字列表real_num
    #查找字符串中的'*'或'/',保存到符号列表real_sign
    real_num = re.split('[\*/]', num)
    real_sign = re.findall('[\*/]', num)
    #如果数字列表的第一个元素中有负号,则将数字列表中的第二个元素改为负号,反之不动;
    if real_num[0][0] == '-':
        sum = -float(real_num[0][1:])
    else:
        sum = float(real_num[0])
    print("sum:%f" % sum)
    #开始乘除运算
    for index, i in enumerate(real_sign):
        if i == '*':
            sum *=float(real_num[index+1])
        else:
            sum /=float(real_num[index+1])
    str_num = str(sum)
    print("return calc_multi_divi:%s" % str_num)
    return str_num
    #end

四.加减运算:

def calc_add_sub(sign_num):
    #-2-3
    #处理类似‘2--3’,‘4+-5’格式的字符串
    sign_num = merge_add_sub(sign_num)
    #以'+'或'-'为分隔符,切分字符串,保存到数字列表real_num
    #查找字符串中的'+'或'-',保存到符号列表real_sign
    real_num = re.split('[+\-]', sign_num)
    real_sign = re.findall('[+\-]', sign_num)
    sum = 0
    #如果数字列表的第一个元素为空,则将符号列表第一个元素+数字列表中的第二个元素=数字列表中的第二个元素,删除数字列表第一个元素
    if real_num[0] == '':
        sum = 0
    else:
        sum = float(real_num[0])
    print("sum:%f" % sum)
    #加减运算
    for index, i in enumerate(real_sign):
        if i == '+':
            sum +=float(real_num[index+1])
        else:
            sum -=float(real_num[index+1])
    str_num = str(sum)
    print("return calc_multi_divi:%s" % str_num)
    return str_num
    #end

五.运算符合并:

def merge_add_sub(sign):
    sign = re.sub('\+-', '-', sign)
    sign = re.sub('--', '+', sign)
    sign = re.sub('\+\+', '+', sign)
    sign = re.sub('-\+', '-', sign)
    return sign

六.写调用代码,进行测试:

if __name__ == '__main__' :
    # final_num = calc_my(input("please input string to calc:"))
    input_num = "1+2*  3-((23-45*(-40   /5))+(122+(323/46+3)*4)-45)+156*(2+999/3+222*5)+3-2"
    final_num = calc_my(input_num)
    print("eval results:%s\nI want you:%s" % (eval(input_num),final_num))

七.运行结果:

 
 

'eval results:224927.91304347827''I want you:224927.91304347827''Process finished with exit code 0'

八.结束

大家伙一起努力吧,希望我也不会放弃,学习python,我还未入门,我,任重道远,我去。


猜你喜欢

转载自blog.csdn.net/chq1005613740/article/details/79423617