python 编程之计算器

Posted 哈嘉好啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 编程之计算器相关的知识,希望对你有一定的参考价值。

 

作业:

     使用正则表达式和递归实现计算器功能。

 

 实现:

       1、实现带括号的计算

       2、实现指数、加减乘除求余等功能

       

一、实例说明:

本实例自己写了个版本,但依旧存在一点bug,例:-2-2等计算问题,故最后在武SIR的代码基础上加了指数、求余等功能。

该计算器思路:
1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
使用技术:
1、正则表达式
2、递归

 

二、流程图:

 

三、代码:

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

\'\'\'
\'\'\'


\'\'\'
该计算器思路:
    1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
    2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
使用技术:
    1、正则表达式
    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: [\'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)

 

 

 

 

四、针对python2.7和python3.4无太大差别,故只需要一个版本即可。

做人一定要靠自己

以上是关于python 编程之计算器的主要内容,如果未能解决你的问题,请参考以下文章

Python 之 Socket编程(TCP/UDP)

python之模块和包

python 之函数式编程

PYTHON之计算机语言基础知识 —— 编程语言的分类

Python进阶之函数式编程

Python基础之注意事项