博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原创]python之简单计算器(超详解,只有基本功能+-*/,还有括号处理)
阅读量:4510 次
发布时间:2019-06-08

本文共 15660 字,大约阅读时间需要 52 分钟。

 

                           不想看过程的话,直接看文章最后的正式源码

 

 作业需求及分析:

 

 

流程图

 

https://www.processon.com/diagraming/580c5276e4b03c844a5a9716

 

 

 

初期感受

 

      今天10/23,这个作业是我19号拿到的,当时一脸蒙逼,知道么?这里我不可能不可能做出来的感觉!!!

觉得不可能不是没有理由的,

1. 有多括号要怎么区配出最里面那个?? 虽然我前两篇博文有写关与正则表达式的,但还是不会。

2.输入的可是字符串字符串啊

3.如何加减乘除

4.如何先乘除,后加减

实际上遇到比这些还多,但现在就只记起这些……

 

 

分析需求:

 

1.先判断有无括号,无括号直接+-*/

2.有括号先提取出最里面的括号(利用正则表达式)

3.括号外面还有括号怎么办?我这里是用迭代,直到没有括号

4.没有括号,再传给1处理,OK ,搞定

 

 

我不会,但我可以去我别人的博客么,但我也看不懂……

 

妈的,这怎么行!

 

先写加减乘除,试试吧

1 def mul_mov(s): 2     result = 0 3     if s[1] == '*': 4         result = int(s[0]) * int(s[2]) 5     elif s[1] == '/': 6         result = float(s[0]) / int(s[2]) 7         result = int(result) 8  9     for i in range(3):  # 去掉前三个10         s.remove(s[0])11 12     s.insert(0, result)   #局部变量引用赋值前的结果13 14     if len(s) == 1:15         print(result)16     else:17         mul_mov(s)18 19 20 def main():21     choose = input("请选择:1.加减;2.乘除")22     num = input("please input:")23     if choose == '1':24         sa = re.split(r'(\D)', num)25         add_substract(sa)26     elif choose == '2':27         sa = re.split(r'(\D)', num)28         mul_mov(sa)29 30 31 if __name__=="__main__":32     main()

 

大概花了半个晚上,死活总算是搞出来了!

 

但这样肯定还有问题。我当时是这样想的:

#问题:让用户选择1,2不现实,如何让用户输入然后自动加减乘除 #思考:现在已经能够处理,单个的加减或乘除 #可否在混合中先分组出(乘除) eg:  ['8+9+','9*4/3','-','4*2‘,‘+5-2’] #这样可以处理乘除,如何分组呢?? 再后来,我卡住了,我回去看我写正则表达式的文章一遍双一遍,还是想不出怎么分组? 感觉太难了,
eg:  ['8+9+','9*4/3','-','4*2‘,‘+5-2’] 如何单独的匹配出'9*4/3' ??
PS:如果大神你知道,可以评论和我说下,谢谢! 卡住怎么办?我+-*/乘除都做出来了,肯定不能就此打住的。 于是我打别人的博客看,终于找到一篇我看得懂看得懂的了!!http://www.cnblogs.com/loyfee/p/5764926.html#3538071 参考代码
# coding:utf-8# 将输入的字符串格式统一转换成列表,将数字、符号、括号都成一个独立元素,# 如: 12+3*(14+5)  ----> ["12","+","3","*","(","14","+","5",")"]def format_input(input_re_value):    input_re_value = input_re_value.replace(" ","")    format_list = []     for i in input_re_value:        format_list.append(i)    snum = 0    while 1:        try:            if format_list[snum].isnumeric():                if format_list[snum+1].isnumeric():                    format_list[snum] = format_list[snum] + format_list[snum+1]                    format_list.pop(snum+1)                else:                    snum += 1                                else:                snum += 1        except IndexError:            return format_list            break            # 计算没有括号的列表的值。def comput(re_value):    while "*" in re_value or "/" in re_value:        for i,j in enumerate(re_value):            if j == "*":                re_cheng = float(re_value[i-1])*float(re_value[i+1])                re_value.pop(i-1)                re_value.pop(i-1)                re_value.pop(i-1)                re_value.insert(i-1,re_cheng)            if j == "/":                re_chu = float(re_value[i-1])/float(re_value[i+1])                re_value.pop(i-1)                re_value.pop(i-1)                re_value.pop(i-1)                re_value.insert(i-1,re_chu)    while "+" in re_value or "-" in re_value:        for i,j in enumerate(re_value):            if j == "+":                re_jia = float(re_value[i-1])+float(re_value[i+1])                re_value.pop(i-1)                re_value.pop(i-1)                re_value.pop(i-1)                re_value.insert(i-1,re_jia)            if j == "-":                re_jian = float(re_value[i-1])-float(re_value[i+1])                re_value.pop(i-1)                re_value.pop(i-1)                re_value.pop(i-1)                re_value.insert(i-1,re_jian)    return re_value[0]# 通过循环,先查找列表的第一个")",然后在")"位置向列表前找到第一个"("所在位置,# 并将其中的元素提取出来,生成新的列表,交给comput计算,# 返回值再插入列表当中,继续循环,直到没有"("为止def bracket_filter(list1):    while "(" in list1:        i = list1.index(")")        for m in range(i,-1,-1):            if list1[m] == "(":                list_new = list1[(m+1):i]                re_res = comput(list_new)                list1.insert(m,str(re_res))                for item1 in range(i+1-m):                    list1.pop(m+1)                break    return comput(list1)    input_sn = input("pls input:")f_re = format_input(input_sn)result = bracket_filter(f_re)print("The result is:",result)
View Code

他思路和我一样一样的。这里他有一个BUG,等下讲。

我得到了启发!可以把输入的字符串分割成列表的一个一个元素。这样就可以解决+-*/的问题了!

 

 

接下来就是困惑我最久的括号问题。

在正式讲括号问题前,先看看我自己在这之中调试过一些例子,看下面:

1 s = ["12","pp"] 2 print(s[0].isnumeric())  #True     这里我了解了isnumeric()方法,新技能GET 3 s1 = ["pp","12"] 4 print(s1[0].isnumeric())  #False 5  6 s2 = '1' 7 s3 = '2' 8 s4 = s2 + s3 9 print(s4)           #输出1210 11 12 s5 = "eret67y"13 s6 = s5[3:6]14 print(s6)          输出:t6715 16 17 import re18 s7 = "5*4-2+((45/3-10*2)-2)"19 sa = re.split(r'(\D)', s7)     20 print(sa)21 #['5', '*', '4', '-', '2', '+', '', '(', '', '(', '45', '/', '3', '-', '10', '*', '2', ')', '', '-', '2', ')', '']22 while True:23     if "" in sa:24       sa.remove("")       #去掉""25     else:26         break27 print(sa)28 29 i =730 for m in range(i, -1, -1):    #start stop step31     print(m)  32 # 733 # 634 # 535 # 436 # 337 # 238 # 139 # 040 41 s8 = "(2+(1+(4+5)+9)*2)"42 s81= "(594)"43 44 45 s9 = re.split("\((\d+\))",s81)46 print(s9)             #获取括号内数字47 #['', '594', '']48 data = re.split(r'\(([^()]+)\)', s8)  #我觉得,()在这里是有特殊意义的,代表分组,要单纯表示括号,就得加转义字符49 print(data)    #['(2+(1+', '4+5', '+9)*2)']50 51 52 s10 = "abdcdeff"53 s11 = re.search("[^cd]+", s10)   #天呐!不是非c或d,而是非c且非d54 print(s11)     #<_sre.SRE_Match object; span=(0, 2), match='ab'>55 56 57 s12 = len("re")58 print(s12)  #259 60 61 re_str = "3455454+97"62 if "+" not in re_str and "-" not in re_str and "*" not in re_str \63         and "/" not in re_str and "(" not in re_str and ")" not in re_str:64     print("AA")65 else:66     print("BB")67 68 num = 50/269 print(num)    #25.0  #有小数点,这里我也蒙比了!等一下讲。70 num1 = 50 * 271 print(num1)

 

上面的懂了之后,我开始搞代码了

 

一、字符串分割为列表元素

# 将输入的字符串格式统一转换成列表,将数字、符号、括号都成一个独立元素,# 如: 12+3*(14+5)  ----> ["12","+","3","*","(","14","+","5",")"]def format_input(input_re_value):    input_re_value = input_re_value.replace(" ", "")     #去掉输入的空格    input_re_value = re.split(r'(\D)', input_re_value)    while True:        if "" in input_re_value:          input_re_value.remove("")     #将列表中""去掉        else:            break    return input_re_value

这里用了正则表达式的split(),不大懂的可以看我前面的博文,format_input()传入一个字符串,返回一个列表。

 

二、+-*/

# 计算没有括号的列表的值。加减乘除def comput(re_value):    while "*" in re_value or "/" in re_value:        for i, j in enumerate(re_value):            if j == "*":                re_cheng = int(re_value[i - 1]) * int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_cheng)                break            if j == "/":                re_chu = int(re_value[i - 1]) / int(re_value[i + 1])                re_chu = int(re_chu)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_chu)                break    while "+" in re_value or "-" in re_value:        for i, j in enumerate(re_value):            if j == "+":                re_jia = int(re_value[i - 1]) + int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jia)                print("re_jia",re_jia)                print("re_value",re_value)                break            if j == "-":                re_jian = int(re_value[i - 1]) - int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jian)                print(re_jian)                print(re_value)                break    return re_value[0]
View Code

这里有一个坑,就是我前面说参考别人的博文,但是他写的有一个BUG,有兴趣可以研究下。这上面的代码是我改正过的。

 

三、括号处理

这里不贴代码,下面源码有。就说下我的思路:

如果输入的有括号的话:   1.用li = re.split(r'\(([^()]+)\)', input_str)将其折分

             2.data = re.search(r'\(([^()]+)\)', input_str).group() 取出最里面括号的数(包括())               3.去除括号,找出最里面括号的数的下标,最后进行替换。             4.还有括号的话,进行迭代,直到无括号

调试代码:

import reimport sys# 将输入的字符串格式统一转换成列表,将数字、符号、括号都成一个独立元素,# 如: 12+3*(14+5)  ----> ["12","+","3","*","(","14","+","5",")"]def format_input(input_re_value):    input_re_value = input_re_value.replace(" ", "")     #去掉输入的空格    input_re_value = re.split(r'(\D)', input_re_value)    while True:        if "" in input_re_value:          input_re_value.remove("")     #将列表中""去掉        else:            break    return input_re_value# 计算没有括号的列表的值。加减乘除def comput(re_value):    while "*" in re_value or "/" in re_value:        for i, j in enumerate(re_value):            if j == "*":                re_cheng = int(re_value[i - 1]) * int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_cheng)                break            if j == "/":                re_chu = int(re_value[i - 1]) / int(re_value[i + 1])                re_chu = int(re_chu)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_chu)                break    while "+" in re_value or "-" in re_value:        for i, j in enumerate(re_value):            if j == "+":                re_jia = int(re_value[i - 1]) + int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jia)                print("re_jia",re_jia)                print("re_value",re_value)                break            if j == "-":                re_jian = int(re_value[i - 1]) - int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jian)                print(re_jian)                print(re_value)                break    return re_value[0]def bracket(input_str):    if not re.search(r'\(([^()]+)\)', input_str):    #若没有括号        s = format_input(input_str)        print("s_format",s)        print("comput(s)",comput(s))        return comput(s)    else:      #有括号        li = re.split(r'\(([^()]+)\)', input_str)        print("li:",li)        #['(', '9+8', '-8)']   输入((9+8)-8)        data = re.search(r'\(([^()]+)\)', input_str).group()        print("data:",data)    # 输出:(9+8)        data_strip = data.strip("()")        print("data_strip:",data_strip)   #9+8        inde = li.index(data_strip)  #取得其下标        print("index:",inde)       # 1        ret = comput(format_input(data_strip))   #参数为列表形式        print("ret:",ret)    #17.0        # 如何把小括号计算后再替换进去        li.pop(inde)        li.insert(inde, str(ret))        print("li:",li)   #['(', '17.0', '-8)']        re_str = "".join(li)        print("re_str",re_str)   #(17.0-8)        if "+" not in re_str and "-" not in re_str and "*" not in re_str \                and "/" not in re_str and "(" not in re_str and ")" not in re_str:            print("有没有return ",re_str)            return re_str    #为什么没有return        else:            return bracket(re_str)   #迭代if __name__ == '__main__':    while True:        input_str = input("please input(q=quit):")        if input_str.strip() == "":            continue        elif input_str == 'q' or input_str == 'quit':            sys.exit()        else:            bracket_reture = bracket(input_str)            print("result:",bracket_reture,type(bracket_reture))
View Code
 
 

调试实例:

C:\Python34\python3.exe C:/Users/Administrator/PycharmProjects/laonanhai/day6_test/test1.pyplease input(q=quit):12+45-85+2s_format ['12', '+', '45', '-', '85', '+', '2']re_jia 57re_value [57, '-', '85', '+', '2']-28[-28, '+', '2']re_jia -26re_value [-26]comput(s) -26result: -26 
please input(q=quit):please input(q=quit): please input(q=quit):(((9+9)-6)+45)+45/3*2li: ['((', '9+9', '-6)+45)+45/3*2']data: (9+9)data_strip: 9+9index: 1re_jia 18re_value [18]ret: 18li: ['((', '18', '-6)+45)+45/3*2']re_str ((18-6)+45)+45/3*2li: ['(', '18-6', '+45)+45/3*2']data: (18-6)data_strip: 18-6index: 112[12]ret: 12li: ['(', '12', '+45)+45/3*2']re_str (12+45)+45/3*2li: ['', '12+45', '+45/3*2']data: (12+45)data_strip: 12+45index: 1re_jia 57re_value [57]ret: 57li: ['', '57', '+45/3*2']re_str 57+45/3*2s_format ['57', '+', '45', '/', '3', '*', '2']re_jia 87re_value [87]comput(s) 87result: 87
please input(q=quit):qProcess finished with exit code 0
View Code

 

 

正式源码:

import reimport sys# 将输入的字符串格式统一转换成列表,将数字、符号、括号都成一个独立元素,# 如: 12+3*(14+5)  ----> ["12","+","3","*","(","14","+","5",")"]def format_input(input_re_value):    input_re_value = input_re_value.replace(" ", "")     #去掉输入的空格    input_re_value = re.split(r'(\D)', input_re_value)    while True:        if "" in input_re_value:          input_re_value.remove("")     #将列表中""去掉        else:            break    return input_re_value# 计算没有括号的列表的值。加减乘除def comput(re_value):    while "*" in re_value or "/" in re_value:        for i, j in enumerate(re_value):            if j == "*":                re_cheng = int(re_value[i - 1]) * int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_cheng)                break            if j == "/":                re_chu = int(re_value[i - 1]) / int(re_value[i + 1])                re_chu = int(re_chu)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_chu)                break    while "+" in re_value or "-" in re_value:        for i, j in enumerate(re_value):            if j == "+":                re_jia = int(re_value[i - 1]) + int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jia)                break            if j == "-":                re_jian = int(re_value[i - 1]) - int(re_value[i + 1])                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.pop(i - 1)                re_value.insert(i - 1, re_jian)                break    return re_value[0]def bracket(input_str):    if not re.search(r'\(([^()]+)\)', input_str):    #若没有括号        s = format_input(input_str)        return comput(s)    else:      #有括号        li = re.split(r'\(([^()]+)\)', input_str)        data = re.search(r'\(([^()]+)\)', input_str).group()        data_strip = data.strip("()")        inde = li.index(data_strip)  #取得其下标        ret = comput(format_input(data_strip))   #参数为列表形式        li.pop(inde)        li.insert(inde, str(ret))        re_str = "".join(li)        if "+" not in re_str and "-" not in re_str and "*" not in re_str \                              and "/" not in re_str and "(" not in re_str and ")" not in re_str:            return re_str    #为什么没有return        else:            return bracket(re_str)   #迭代if __name__ == '__main__':    while True:        input_str = input("please input(q=quit):")        if input_str.strip() == "":            continue        elif input_str == 'q' or input_str == 'quit':            sys.exit()        else:            bracket_reture = bracket(input_str)            print("result:",bracket_reture)
View Code

 

输出源码:

C:\Python34\python3.exe C:/Users/Administrator/PycharmProjects/laonanhai/day6_test/fina_howo.pyplease input(q=quit):50+48*82/2result: 2018please input(q=quit):100+15result: 115please input(q=quit):(((9+9)-9)+9)result: 18please input(q=quit):15/3*2*8/4result: 20please input(q=quit):Process finished with exit code 1
View Code

 

 

欢迎转发!

This is zcl‘s article! Thanks for your support!
文章出处:http://www.cnblogs.com/0zcl
作者:zcl

 

转载于:https://www.cnblogs.com/0zcl/p/5983236.html

你可能感兴趣的文章
python基础——面向对象进阶下
查看>>
Linux vi 命令详解
查看>>
本地如何搭建IPv6环境测试你的APP
查看>>
oracle、mysql新增字段,字段存在则不处理
查看>>
C++ NULL与nullptr的区别
查看>>
Discretized Streams, 离散化的流数据处理
查看>>
Spark源码分析 – SchedulerBackend
查看>>
黑马程序员 Java输入\输出
查看>>
python字符串处理
查看>>
live555学习笔记4-计划任务(TaskScheduler)深入探讨
查看>>
【Unity3D】获取鼠标在三维空间(世界坐标系)的位置
查看>>
Python虚拟机函数机制之名字空间(二)
查看>>
线段树
查看>>
SharePoint2010联合搜索——Google、百度
查看>>
php静态
查看>>
python基础之文件操作
查看>>
在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因...
查看>>
个人github链接及git学习心得总结
查看>>
c++ 计算器 带括号 代码实现
查看>>
objective -c初写
查看>>