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

作业需求及分析:

流程图

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

初期感受

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

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

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

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

3.如何加减乘除

4.如何先乘除,后加减

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

分析需求:

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

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

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

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

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

妈的,这怎么行!

先写加减乘除,试试吧

 def mul_mov(s):
result =
if s[] == '*':
result = int(s[]) * int(s[])
elif s[] == '/':
result = float(s[]) / int(s[])
result = int(result) for i in range(): # 去掉前三个
s.remove(s[]) s.insert(, result) #局部变量引用赋值前的结果 if len(s) == :
print(result)
else:
mul_mov(s) def main():
choose = input("请选择:1.加减;2.乘除")
num = input("please input:")
if choose == '':
sa = re.split(r'(\D)', num)
add_substract(sa)
elif choose == '':
sa = re.split(r'(\D)', num)
mul_mov(sa) if __name__=="__main__":
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)

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

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

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

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

 s = ["","pp"]
print(s[0].isnumeric()) #True 这里我了解了isnumeric()方法,新技能GET
s1 = ["pp",""]
print(s1[0].isnumeric()) #False s2 = ''
s3 = ''
s4 = s2 + s3
print(s4) #输出12 s5 = "eret67y"
s6 = s5[3:6]
print(s6) 输出:t67 import re
s7 = "5*4-2+((45/3-10*2)-2)"
sa = re.split(r'(\D)', s7)
print(sa)
#['5', '*', '4', '-', '2', '+', '', '(', '', '(', '45', '/', '3', '-', '10', '*', '2', ')', '', '-', '2', ')', '']
while True:
if "" in sa:
sa.remove("") #去掉""
else:
break
print(sa) i =7
for m in range(i, -1, -1): #start stop step
print(m)
#
#
#
#
#
#
#
# s8 = "(2+(1+(4+5)+9)*2)"
s81= "(594)" s9 = re.split("\((\d+\))",s81)
print(s9) #获取括号内数字
#['', '594', '']
data = re.split(r'\(([^()]+)\)', s8) #我觉得,()在这里是有特殊意义的,代表分组,要单纯表示括号,就得加转义字符
print(data) #['(2+(1+', '4+5', '+9)*2)'] s10 = "abdcdeff"
s11 = re.search("[^cd]+", s10) #天呐!不是非c或d,而是非c且非d
print(s11) #<_sre.SRE_Match object; span=(0, 2), match='ab'> s12 = len("re")
print(s12) # re_str = "3455454+97"
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("AA")
else:
print("BB") num = 50/2
print(num) #25.0 #有小数点,这里我也蒙比了!等一下讲。
num1 = 50 * 2
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]

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

三、括号处理

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

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

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

调试代码:

import re
import 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) # 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))

 

调试实例:

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

正式源码:

import re
import 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)

输出源码:

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

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

[原创]python之简单计算器(超详解,只有基本功能+-*/,还有括号处理)的更多相关文章

  1. Python包模块化调用方式详解

    Python包模块化调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一般来说,编程语言中,库.包.模块是同一种概念,是代码组织方式. Python中只有一种模块对象类型 ...

  2. Python3调用C程序(超详解)

    Python3调用C程序(超详解) Python为什么要调用C? 1.要提高代码的运算速度,C比Python快50倍以上 2.对于C语言里很多传统类库,不想用Python重写,想对从内存到文件接口这样 ...

  3. Python安装、配置图文详解(转载)

    Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境(I ...

  4. 【和我一起学python吧】Python安装、配置图文详解

     Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境( ...

  5. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  6. python设计模式之装饰器详解(三)

    python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...

  7. Python调用windows下DLL详解

    Python调用windows下DLL详解 - ctypes库的使用 2014年09月05日 16:05:44 阅读数:6942 在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分 ...

  8. Python操作redis字符串(String)详解 (三)

    # -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1.SET 命令用于设置 ...

  9. 【Python】Python内置函数dir详解

    1.命令介绍 最近学习并使用了一个python的内置函数dir,首先help一下: 复制代码代码如下: >>> help(dir)Help on built-in function ...

随机推荐

  1. 使用Ubuntu 12.04作为日常电脑环境

    搜狗输入法出来之后,我觉得有必要写一篇博客说明一下,如何使用Ubuntu作为日常的电脑系统.我使用的Ubuntu版本是12.04,没有使用Ubuntukylin,因为的电脑比较老,使用那个版本,电脑有 ...

  2. 利用pixi.js制作精灵动画

    CSS Sprites 技术对于广大的前端工程师来说应该是一点也不陌生.国内开发者昵称为CSS精灵,通过一定的技术手段,让精灵动起来,我称其为精灵动画,那么目前有哪些实现方式 呢?下面让我们详细的聊聊 ...

  3. 基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用

    Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使用的时候,也是一步一个脚印一样摸着石头过河,这个控件在界面呈现上,叫我之前使用过的Uploadi ...

  4. Android APK如何签名

    Android项目以它的包名作为唯一标识,如果在同一设备上安装两个相同的应用,后面安装的应用就会覆盖前面安装的应用.为了避免这种情况的发生,我们需要对作为产品发布的应用进行签名. 签名其实有两个作用: ...

  5. 将DataTable转换成CSV文件

    DataTable用于在.net项目中,用于缓存数据,DataTable表示内存中数据的一个表.CSV文件最早用在简单的数据库里,由于其格式简单,并具备很强的开放性,所以起初被扫图家用作自己图集的标记 ...

  6. c#和Javascript中去重总结

    一.前言 去重在我们的开发过程中经常遇到,避免重复元素的添加,我们需要对获取到的集合(包括List.Array等) 做相关的过滤操作.确保对象的唯一性,从而达到保证数据不冗余重复.由于自己是做.net ...

  7. 【Java】记录一次代码优化

    前不久的项目时间紧张,为了尽快完成原型开发,写了一段效率相当低的代码. 最近几天闲下来,主动把之前的代码优化了一下:)   标签:Java.Mybatis.MySQL 概况:本地系统从另外一个系统得到 ...

  8. sed命令使用详解归纳

    用法 sed [option] 'Address Command' yourfile e.g. sed -n '2,13p' lineuser #打印文件lineuser中第2~13行的内容,-n为o ...

  9. 用JAVA日志来写诗

    工欲善其事,必先利其器 很多程序员可能都忘了记录应用程序的行为是一件多么重要的事,当遇到多线程环境下高压力导致的并发bug时,你就能体会到记录log的重要性. 有的人很高兴的就在代码里加上了这么句: ...

  10. ASP.NET MVC动作过滤器

    ASP.NET MVC提供了4种不同的动作过滤器(Aciton Filter). 1.Authorization Filter 在执行任何Filter或Action之前被执行,用于身份验证 2.Act ...