首页 > 其他 > 详细

180119 计算器的优化版

时间:2018-01-19 23:54:11      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:lac   再次   其中   设定   nothing   bre   pil   第一个   com   

print("\033[31;1m欢迎使用计算器\033[0m".center(59,"-"))
import sys,time #导入模块 sys模块,time模块

f = open("intro.txt",r) #打开文件 同一个目录里的名为“intro”的文件,打开为读取

for line in f:  #循环读取刚刚打开的f的行line; for...in... 循环 ;for..in语句是个循环语句,它迭代一个对象的序列,现在,你需要知道的是一个序列只是一个有序的项目的集合。
    for i in line: #循环读取文字;读取上一行读取的行line里的每个文字,生成列表i
        sys.stdout.write(i) #标准输出 这就是导入sys模块的原因,用到其中的stdout.write,后面跟上(i)——标准输出上一行的文字列表i
        sys.stdout.flush() #刷新 这是间隔一段时间刷新的意思,sys.stdout        .flush ...
        time.sleep(0.05) #输出时间控制  再次看到time模块的.sleep ,参数设定为(0.1)秒
import re,os,sys  #导入 re os sys 模块 具体运用到的功能详解。

def compute_exponent(arg):  #定义一个函数 指数计算  ps() 里的arg 前几天的博文里有记录作用和含义
    """ 操作指数
    :param expression:表达式
    :return:计算结果
    """

    val = arg[0]  #声明一个变量 val = arg   ps.列表是零
    pattern = re.compile(r\d+\.?\d*[\*]{2}[\+\-]?\d+\.?\d*)    #有点复杂了,起码用上了re.compile 正则表达式……
    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(分解中:,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(下一步:,expression)
    print("~"*10,按优先级运算ing...,"~"*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




    while flag:
        calculate_input = input(\033[43m请输入要计算的算式 | (退出请按q)\033[0m)
        calculate_input = re.sub(\s*,‘‘,calculate_input)
        if len(calculate_input) == 0:
            continue
        elif calculate_input == q:
            print("欢迎使用,再见!".center(48, "-"))
            exit()
        elif re.search([^0-9\.\-\+\*\/\%\/\/\*\*\(\)],calculate_input):
            print(\033[31m 输入错误,请重新输入!!!\033[0m)
        else:
            result = exec_bracket(calculate_input)
            print(\033[31m最终的计算结果是: %s\033[0m % result)

好吧,这段代码比较长,而且个人感觉还不够完美,只解析了括号内的运算

180119 计算器的优化版

标签:lac   再次   其中   设定   nothing   bre   pil   第一个   com   

原文:https://www.cnblogs.com/cputn/p/8319201.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号