用python实现一个简单计算器(完整DEMO)

一、功能目标

用户输入一个类似  1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))  这样的表达式,假设表达式里面除了包含空格、'+'、'-'、'*'、'/'和括号再无其他特殊符号,然后自己动手写代码解析其中的表达式,实现加减乘除最后得出的结果与真实的计算机所算的结果必须一致。

二、解题思路

1、为了分开运算符和数字,因此把输入的字符串格式转换为 列表的格式进行处理,这样子就可以按位进行 处理了

2、实现功能的核心点在于括号、乘除、加减的优先级排序,因此我们先想办法一层一层的去括号,即从最里层的括号开始计算,然后去掉第一层括号,然后一直继续这个 过程,最后得到一个没有括号的列表,再进行计算得出结果

3、去括号方式:最内层的括号内的表达式就可以当做一个无括号表达式,通过先 运算出乘除,再运算出加减得出整个括号内的值,用这个结果值整体替换括号内的内容即实现了去一层括号,然后通过递归去除所有的括号

4、去除乘除号方式:见 remove_multiplication_division(eq) 函数部分

5、去除加减号 方式:见 remove_plus_minus(eq) 函数部分

三、函数说明

1、主函数

def caculator(eq):
  format_list = eq_format(eq) # 把字符串变成格式化列表形式
  s_eq = simplify(format_list) # 去括号,得到无括号的一个格式化列表
  ans = calculate(s_eq)    # 计算最终结果
  if len(ans) == 2:      # 判断最终结果为正数还是负数
    ans = -float(ans[1])
  else:
    ans = float(ans[0])
  return ans

2、eq_format( )函数

def eq_format(eq):
  '''
  :param eq: 输入的算式字符串
  :return: 格式化以后的列表,如['60','+','7','*','8']
  '''
  format_list = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)',eq)
  return format_list

2.1 这个函数的作用是把输入的算式通过re模块,用正则表达式把算术符号和数字分开。

2.2  [\d\.]+ | \( | \+ | \- | \* | \/ | \)意思:按管道符号 | (| 表示 或 的意思)可分为几部分,[\d\.]+  是指匹配数字或小数点一次或多次,\(是指左括号,\+ 是指 加号,\- 是指减号,\* 是指乘号,\/ 是指除号, \) 是指右括号,整个正则表达式会把字符串变成类似['(','6','*','5','-''7',')' ]这样子的格式列表

3、simplify( ) 函数

def simplify(format_list):
  '''
  :param format_list: 输入的算式格式化列表如['60','+','7','*','8']
  :return: 通过递归去括号,返回简化后的列表
  '''

  bracket = 0   # 用于存放左括号在格式化列表中的索引
  count = 0
  for i in format_list:
    if i == '(':
      bracket = count
    elif i == ')':
      temp = format_list[bracket + 1 : count]
      # print(temp)
      new_temp = calculate(temp)
      format_list = format_list[:bracket] + new_temp + format_list[count+1:]
      format_list = change(format_list,bracket)   # 解决去括号后会出现的-- +- 问题
      return simplify(format_list)      # 递归去括号
    count = count + 1
  return format_list           # 当递归到最后一层的时候,不再有括号,因此返回列表

3.1 这个函数的作用是:把输入的带有括号的格式化列表,用递归的方式去除括号,每一次递归去一个括号, 直到没有括号则返回去完括号的格式化列表

3.2 找到最内层括号的方法:遍历列表,如果遇到左括号,则把当前左括号的索引赋值给参数bracket,直到遇到第一个右括号,此时的索引与bracket中间的元素即为最内层括号的元素,用切片的方式提取出来,通过 calculate() 函数计算出值,然后用计算结果去替换掉此时左括号到第一个右括号的元素,此时去除第一层括号,然后进入递归,不断递归直至去除所有括号

3.3 可能遇到的问题:

首先是不要用index的方式去取当前左括号的索引,因为列表的index方法返回的一直都是第一个左括号的索引,而不是当前左括号的索引,会导致出错。因此我在函数内用参数 count 进行计数当前索引值。

然后是用计算得出的值来替换掉第一层括号部分后,有可能会出现 ‘+-' ,‘ - -'的情况,要记得处理,我的函数中写了一个change() 函数进行处理

4、caculate()函数

def calculate(s_eq):
  '''
  :param s_eq: 不带括号的格式化列表
  :return: 计算结果
  '''
  if '*' or '/' in s_eq:
    s_eq = remove_multiplication_division(s_eq)
  if '+' or '-' in s_eq:
    s_eq = remove_plus_minus(s_eq)
  return s_eq

这个函数的作用是输入不带括号的格式化列表, 输出计算结果,然后返回结果列表

思路是先算乘除:remove_multiplication_division()函数,然后再从头到尾计算加减法:remove_plus_minus( )函数

5、remove_multiplication_division()函数

def remove_multiplication_division(eq):
  '''
  :param eq: 带有乘除号的格式化列表
  :return: 去除了乘除号的格式化列表
  '''
  count = 0
  for i in eq:
    if i == '*':
      if eq[count+1] != '-':
        eq[count-1] = float(eq[count-1]) * float(eq[count+1])
        del(eq[count])
        del(eq[count])
      elif eq[count+1] == '-':
        eq[count] = float(eq[count-1]) * float(eq[count+2])
        eq[count-1] = '-'
        del(eq[count+1])
        del(eq[count+1])
      eq = change(eq,count-1)
      return remove_multiplication_division(eq)
    elif i == '/':
      if eq[count+1] != '-':
        eq[count-1] = float(eq[count-1]) / float(eq[count+1])
        del(eq[count])
        del(eq[count])
      elif eq[count+1] == '-':
        eq[count] = float(eq[count-1]) / float(eq[count+2])
        eq[count-1] = '-'
        del(eq[count+1])
        del(eq[count+1])
      eq = change(eq,count-1)
      return remove_multiplication_division(eq)
    count = count + 1
  return eq

这个函数的作用是计算乘除,去乘除号。方法也是递归的方法,每次处理完一个乘号或者除号都可能出现符号问题,记得处理后再进入下一次递归

6、remove_plus_minus( )函数

def remove_plus_minus(eq):
  '''
  :param eq: 只带有加减号的格式化列表
  :return: 计算出整个列表的结果
  '''
  count = 0
  if eq[0] != '-':
    sum = float(eq[0])
  else:
    sum = 0.0
  for i in eq:
    if i == '-':
      sum = sum - float(eq[count+1])
    elif i == '+':
      sum = sum + float(eq[count+1])
    count = count + 1
  if sum >= 0:
    eq = [str(sum)]
  else:
    eq = ['-',str(-sum)]
  return eq

这个函数输入一个只有加减号的格式化列表,然后从头到尾的计算,得出最终结果,返回最终结果(结果形式也是列表)

7、change()函数

def change(eq,count):
  '''
  :param eq: 刚去完括号或者乘除后的格式化列表
  :param count: 发生变化的元素的索引
  :return: 返回一个不存在 '+-' ,'--'类的格式化列表
  '''
  if eq[count] == '-':
    if eq[count-1] == '-':
      eq[count-1] = '+'
      del eq[count]
    elif eq[count-1] == '+':
      eq[count-1] = '-'
      del eq[count]
  return eq

这个函数的作用是解决符号输入两个问题。输入参数1:刚去完括号的或者刚 计算完乘除的 格式化列表,输入参数2: 列表元素发生变化的索引(如去括号时,这个索引则为去括号前列表的最内层左括号的索引),输出结果是一个处理完符号问题或者什么都不做直接返回的列表

四、完整代码

需要的小伙伴,请关注微信公众号: Python客栈, 或者扫描下方公众号二维码,回复关键字:计算器, 即可免费无套路获取

↑关注上方公众号回复计算器 即可↑

程序运行结果

(0)

相关推荐

  • python 简易计算器程序,代码就几行

    代码: 复制代码 代码如下: import os while True: dynamic = input('输入计算表达式:') if dynamic != 'cls': try: result = eval(dynamic) print('计算结果:'+str(result)) except: print('计算表达式输入有误!') else: command = 'cls' os.system(command)

  • 基于python的Tkinter实现一个简易计算器

    本文实例介绍了基于python的Tkinter实现简易计算器的详细代码,分享给大家供大家参考,具体内容如下 第一种:使用python 的 Tkinter实现一个简易计算器 #coding:utf-8 from Tkinter import * import time root = Tk() def cacl(input_str): if "x" in input_str: ret = input_str.split("x") return int(ret[0]) *

  • Python+tkinter使用80行代码实现一个计算器实例

    本文主要探索的是使用Python+tkinter编程实现一个简单的计算器代码示例,具体如下. 闲话不说,直奔主题.建议大家跟着敲一遍代码,体会一下代码复用.字符串方法的运用和动态创建组件的妙处,然后在这个框架的基础上进行补充和发挥. 选择任何一款Python开发环境,创建一个程序文件,命名为tkinter_Calculator.pyw,然后编写下面的代码: 1)导入标准库re和tkinter,创建并简单设置应用主程序,在窗口顶部放置一个只读的文本框用来显示信息. 2)编写计算器上各种按钮的通用处

  • 仅用50行代码实现一个Python编写的计算器的教程

     简介 在这篇文章中,我将向大家演示怎样向一个通用计算器一样解析并计算一个四则运算表达式.当我们结束的时候,我们将得到一个可以处理诸如 1+2*-(-3+2)/5.6+3样式的表达式的计算器了.当然,你也可以将它拓展的更为强大. 我本意是想提供一个简单有趣的课程来讲解 语法分析 和 正规语法(编译原理内容).同时,介绍一下PlyPlus,这是一个我断断续续改进了好几年的语法解析 接口.作为这个课程的附加产物,我们最后会得到完全可替代eval()的一个安全的四则运算器. 如果你想在自家的电脑上试试

  • Python开发的实用计算器完整实例

    本文实例讲述了Python开发的实用计算器.分享给大家供大家参考,具体如下: 实现功能:图形界面PyQt,输入框,+,-,*,/ :乘方 ,开方 ,取余,清零. 1. Python代码: #!/usr/bin/env python # -*- coding: utf-8 -*- ''' Author : Mr.LiuYC Created on 2014-09-30 E-Mail : liuyanchen0725@gmail.com Introduction: 简易计算器 实现图形界面PyQt,输

  • Python只用40行代码编写的计算器实例

    本文实例讲述了Python只用40行代码编写的计算器.分享给大家供大家参考,具体如下: 效果图: 代码: from tkinter import * reset=True def buttonCallBack(event): global label global reset num=event.widget['text'] if num=='C': label['text']="0" return if num in "=": label['text']=str(

  • Python设计实现的计算器功能完整实例

    本文实例讲述了Python设计实现的计算器功能.分享给大家供大家参考,具体如下: 通过利用PYTHON 设计处理计算器的功能如: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))- (-4*3)/(16-3*2)) 我的处理计算基本思路是: 解题思路是,需要优先处理内层括号运算--外层括号运算--先乘除后加减的原则: 1.正则处理用户输入的字符串,然后对其进行判断,判断计算公式是否有括号,有就先将计算公式进

  • Python实现简单的四则运算计算器

    一.算法 1.算法的主要思想就是将一个中缀表达式(Infix expression)转换成便于处理的后缀表达式(Postfix expression),然后借助于栈这个简单的数据结构,计算出表达式的结果. 2.关于如何讲普通的表达式转换成后缀表达式,以及如何处理后缀表达式并计算出结果的具体算法描述不在此叙述了,书上有详细的说明. 二.简易计算器 使用说明 使用该计算器类的简单示例如下: # usage c = Calculator() print('result: {:f}'.formart(c

  • python实现简易版计算器

    学了一周的Python,这篇文章算是为这段时间自学做的小总结. 一.Python简介 Python是一门十分优美的脚本语言,如果学过java.c++那入门Python是非常简单的.Python具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结在一起.常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写. 二.Python版计算器的实现 工具准备: 1.

  • 用python实现一个简单计算器(完整DEMO)

    一.功能目标 用户输入一个类似  1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))  这样的表达式,假设表达式里面除了包含空格.'+'.'-'.'*'.'/'和括号再无其他特殊符号,然后自己动手写代码解析其中的表达式,实现加减乘除,最后得出的结果与真实的计算机所算的结果必须一致. 二.解题思路 1.为了分开运算符和数字,因此把输入的字符串格式转换为 列表的格式进行处理,这样子就可以按位进行 处理了 2.

  • 利用Python实现一个简单的Web汇率计算器

    目录 Dash是什么 网页搭建步骤 安装相关依赖(库) 导入相关包 构建app 构建结果输出函数 网页结构Layout搭建 callback回调参数设定 界面效果 前段时间刚接触到前端网页开发,但是对于刚入门的小白而言,像flask.Django等这类稍大型的框架确实不太适合,今天这个Dash是集众家之长于一体的轻量化Web开发库. Dash是什么 Dash 是一个用于构建基于 Web 的应用程序的 Python 库,无需 JavaScript . Dash 同时也是用于创建分析 Web 应用程

  • Python实现的简单计算器功能详解

    本文实例讲述了Python实现的简单计算器功能.分享给大家供大家参考,具体如下: 使用python编写一款简易的计算器 计算器效果图 首先搭建计算器的面板: 计算器面板结构 建造一个继承于wx.Frame的frame,在init属性函数中搭建面板 class CalcFrame(wx.Frame):#建造一个继承于wx.Frame的frame def __init__(self,title): wx.Frame.__init__ (self,None,-1,title, pos=(100,300

  • 如何利用Python开发一个简单的猜数字游戏

    前言 本文介绍如何使用Python制作一个简单的猜数字游戏. 游戏规则 玩家将猜测一个数字.如果猜测是正确的,玩家赢.如果不正确,程序会提示玩家所猜的数字与实际数字相比是"大(high)"还是"小(low)",如此往复直到玩家猜对数字. 准备好Python3 首先,需要在计算机上安装Python.可以从Python官网下载并安装.本教程需要使用最新版的Python 3(版本3.x.x). 确保选中将Python添加到PATH变量的框.如果不这样做,将很难运行该程序.

  • 五分钟学会怎么用python做一个简单的贪吃蛇

    Pygame 是一组用来开发游戏软件的 Python 程序模块,基于 SDL 库的基础上开发.我们今天将利用它来制作一款大家基本都玩过的小游戏--贪吃蛇. 一.需要导入的包 import pygame import time import random pygame:获取图形组件构建游戏 time:主要用来设置帧率 random:主要用来设置食物的刷新位置 二.窗口界面设置 首先我们初始化游戏,建立一个窗口 pygame.init() 然后我们定义游戏中需要使用的颜色,在这个示例中,我们定义了六

  • Python实现一个简单三层神经网络的搭建及测试 代码解析

    目录 1.初始化 2.预测 3.训练 4.测试 废话不多说了,直接步入正题,一个完整的神经网络一般由三层构成:输入层,隐藏层(可以有多层)和输出层.本文所构建的神经网络隐藏层只有一层.一个神经网络主要由三部分构成(代码结构上):初始化,训练,和预测.首先我们先来初始化这个神经网络吧! 1.初始化 我们所要初始化的内容包括:神经网络每层上的神经元个数(这个是根据实际问题输入输出而得到的,我们将它设置为一个可自定义量). 不同层间数据互相传送的权重值. 激活函数(模拟自然界的神经元,刺激信号需要达到

  • 基于Python编写一个简单的端口扫描器

    目录 1.需要的库 2.获取一个 host 地址 3.循环所有的端口 4.完整脚本 端口扫描是非常实用的,不止用在信息安全方面,日常的运维也用得到.这方面的工具也不要太多,搞过 CTF 的朋友会告诉你有多少端口扫描工具,那为什么还要用 Python 再自己实现一遍?这个问题就像饭店里的菜已经很好吃了,为什么还要自己烧菜一样,主要还是为了适合自己的口味,添加自己需要的个性功能. 今天我们将用 20 行代码编写一个简单的端口扫描器.让我们开始吧! 1.需要的库 都是标准库,因此内网环境也不影响: i

  • Python实现一个简单的QQ截图

    目录 前言 一.需求分析 二.截图 三.矩形选择 四.按钮设置 总结 前言   毕设有一部分要用到类似QQ截图的功能,这里记录制作过程.因为后期要添加人工智能的功能,所以用python来写桌面应用. 一.需求分析   可以简单的将过程分为以下三步: 点击按钮或敲击快捷键进入截图模式:在截图模式通过鼠标左键按压/松开选取矩形区域:将矩形区域截图保存到指定目录或者剪贴板. 现在我将从第三步开始一步步向上搜索.编写.验证. 二.截图   通过对“python”和“截图”两个关键字搜索不难发现pytho

  • Python实现一个简单的验证码程序

    老师讲完random函数,自己写的,虽然和老师示例的不那么美观,智能,但是也自己想出来的,所以记录一下,代码就需要自己不断的自己练习,实战,才能提高啊!不然就像我们这些大部分靠自学的人,何时能学会.还有就是,这次听老师的,把自己的代码添加注释,所以这次把很简单的代码都写上了注释,而且很大白话,不管有没有接触过python的,我相信仔细看了,肯定能看懂.如果看完,再自己尝试着默写出来,那就是更好到了,好了进入正题: 自己写的: __Author__ = "Zhang Peng" impo

  • 基于JSP实现一个简单计算器的方法

    本文实例讲述了基于JSP实现一个简单计算器的方法.分享给大家供大家参考.具体实现方法如下: index.jsp 复制代码 代码如下: <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>  <%  String path = request.getContextPath();  String basePath = request.getSch

随机推荐