Python计算器程序实现,支持括号与符号检测、小数、负数运算

前几天看到某小学毕业模拟考试有一道编程题,编写一个简单的计算器程序,要求支持小数和负数运算,不能调用math库,还不能使用eval等表达式求值函数,这还不算完,居然还要求要能够提示输入错误,对于小学生来讲,这样的题目确实还是蛮麻烦的,所以有小学生找到我,让我帮帮忙,我没办法,只能尝试着写一写。

我写的这个程序虽然不是很完美,但是也算是符合要求了。完全没有调用math库,实现了常用的数学函数,如sin,log,pow等,而且还实现了和python中eval函数类似的功能,同时还支持括号匹配检测,包括括号的优先级(即小括号在内,中括号在外),而且对一些常见的错误都可以给出提示。

有需要的同学可以拿去参考参考,里面的括号匹配和表达式求值的过程还是很值得一看的。

下面给一个连接,里面包含了源程序、使用说明书和讲解视频,大家可以下载,我的建议是,大家在使用前一定先看一下使用说明书!一定先看一下使用说明书!一定先看一下使用说明书!

链接:https://pan.baidu.com/s/1vLbVC8seXCpWjcJNXEVFLA 
提取码:e2jd

下面展示一下效果吧!

 

 程序如下:

# -*- coding: utf-8 -*-
"""
Created on Fri May  6 01:14:57 2022
@author: 2540817538
环境:Windows 10     Spyder 4    Python 3.8
使用前请先查看使用说明书!!!!
"""

import re#导入re,用于正则表达式匹配
from tkinter import *#导入thinter用于用户图形界面制作
import tkinter.messagebox


###############################################################################
#创建栈类,后面的括号匹配和表达式求值会用到栈,不过也不一定非要用栈,直接进行字符串的处理也是可以的
class myStack(object):
    def __init__(self):# 初始化栈为空列表
        self.items = []
        
    def isEmpty(self):# 判断栈是否为空
        return self.items == []
    
    def peek(self): # 返回栈顶元素
        return self.items[len(self.items) - 1]
    
    def size(self): # 返回栈的大小
        return len(self.items)
    
    def push(self, item): # 进栈
        self.items.append(item)
        
    def pop(self): # 出栈
        return self.items.pop()
    
    def comlist(self):#返回整个栈
        return self.items
    
    
###############################################################################
####多种函数的实现,该部分相当于实现math库的部分功能
def sin(x):#正弦函数,利用的泰勒展开式,这里值列出了sin cos 和tan,arcsin等也是利用泰勒展开式,原理类似,
    x=x*pi()/180#因此就不单独去写arcsin,arccos,arctan等函数了,注意x应该是角度而非弧度
    s=1
    sinx=0
    a=x#a作为分子
    b=1#b作为分母
    i=1
    while(abs(a/b)>=1e-15):
        sinx=sinx+s*a/b#累加一项
        a=a*x*x#求下一项分子
        b=b*2*i*(2*i+1)
        s=s*(-1)
        i=i+1
    return round(sinx,6)#这里的精度会影响到后面cos和tan的计算,所以最好多保留几位有效数字

def cos(x) :#余弦函数
    return sin(90-x)

def tan(x):#正切函数
    if (x+90)%180!=0:#其实这里不必单独考虑x的取值范围,因为如果x为负数,后面的表达式检测函数会进行报警
        tanx=sin(x)/cos(x)
    return round(tanx,6)

def rootsqu(x):#开平方函数,这里不必单独考虑x的取值范围,因为如果x为负数,后面的表达式检测函数会进行报警
    root=x
    while  root*root>x:
        root=(root+x/root)/2
    return root

def pows(x,n):#指数函数,这里利用了分治策略,可以降低时间复杂度
    if n<0:
        n=-n
        result=1/pows(x,n)
    else:
       if n==0:
           result=1
       else:
           if n%2==0:
               result=pows(x*x,n/2)
           else:
               result=pows(x*x,(n-1)/2)*x
    return result

def multi(x,n):#n个x相乘
    result=1
    if n==0:
        return 1
    for i in range(n):
        result =result*x
    return result

def ln(x):#对数函数,如果要求log可以利用公式ln(a)/ln(b)求得
    ln10=2.302585
    k=0
    while x>1:
        x=x/10
        k=k+1
    y=x-1
    result=ln10*k
    s=i=1
    while i <100:
        result =s*multi(y,i)/i+result
        s=(-1)*s
        i=i+1
    return round(result,4)

def percent(x):#求百分数
    return x/100

def e():#e值计算,还是泰勒展开
    result=1
    cur=1
    i=1
    while i<=20:#迭代次数可以根据精度需求自行设置,一般设置在15次以上
        cur=cur *i
        result=result+1/cur
        i=i+1
    return result

def pi():#圆周率值
    result=0
    for i in range(20):#迭代次数可以根据精度需求自行设置,一般设置在15次以上
        result =result+1/pows(16,i)*(4/(8*i+1)-2/(8*i+4)-1/(8*i+5)-1/(8*i+6))
    return result

def sigmoid(x):#sigmiod函数实现
    return round(1.0/(1 + pows(e(),-x)),4)

def rootcub(x):#求取立方根,这里利用了牛顿迭代法
    result=x/2
    while abs(result*result*result-x)>1e-5:
        result=result-(result*result*result-x)/(3*result*result)
    return round(result ,4)

def log(x,y):#对数函数
    return round(ln(y)/ln(x),4)


##############################################################################
####下面是表达式求值的核心模块,包括三个核心函数,其功能与内置的eval函数大同小异
def compute (num1,num2,operator):#遍历到操作符时压栈方法
    result =0
    if operator=="+":
        result=num1+num2
    if operator=="-":
        result=num2-num1#接近栈底的是被减数
    if operator=="*":
        result=num1*num2
    if operator=="/":
        if num1!=0:
            result=num2/num1#接近栈底的是被除数
    return result
    
def priority(str1):#定义运算符优先级
    n=0
    if str1=="+" or str1=="-":
        n=-1
    if str1=="*" or str1=="/":
        n=1
    if str1=="(":
        n=-2
    if str1==")":
        n=2
    return n
        
def calculate(string):#计算后缀表达式并得到结果
    expression=[]
    expression=string.split(" ")#用空格分割字符串
    stack1=myStack()#实例化三个栈,一个存放后缀表达式,一个存放运算符,一个用于运算
    stack2=myStack()
    stack3=myStack()
    try:
        for i in range(len(expression)):
            if regulmatch(expression[i]):#正则表达式匹配浮点数
                stack1.push(expression[i])
            elif stack2.isEmpty(): #括号以及加减乘除的入栈操作
                stack2.push(expression[i])
            elif expression[i]=="(":
                stack2.push(expression[i])
            elif expression[i]==")":
                while not(stack2.peek()=="("):
                    stack1.push(stack2.pop())
                stack2.pop()
            elif expression[i] in '+-*/(' :#加减乘除入栈
                while not(stack2.isEmpty()) and (priority(expression[i])<=priority(stack2.peek())):
                    stack1.push(stack2.pop())
                stack2.push(expression[i])
            else :#小数点直接入栈
                stack1.push(expression[i])
        while not(stack2.isEmpty()):#当运算符栈不为空时,将运算符全部弹入 stack1
            stack1.push(stack2.pop())
        for j in range(stack1.size()):#遍历后缀表达式
            element=stack1.comlist()[j]
            if regulmatch(element):#正则表达式匹配数字
                stack3.push(element)
            else:
                if stack3.isEmpty():
                    num1="0"
                else:
                    num1=stack3.pop()
                if stack3.isEmpty():
                    num2="0"
                else:
                    num2=stack3.pop()
                result =compute(float(num1),float(num2),element)#计算
                stack3.push(str(result))
        return round(float(stack3.pop()),4)#为了方便,最后的结果就保留四位小数了
    except:
        tkinter.messagebox.showerror("表达式错误","表达式存在一些问题,例如数字直接连接函数或e、π,请仔细检查后重新输入")
        return string
    
    
###############################################################################
#正则表达式匹配数字
def regulmatch(ch):
    return re.match( "-?\\d+\\.*\\d*",ch)


#cal_raplace函数用来对对输入的表达式进行一些预处理,主要是将函数的值先求出来,让表达式不在含有各个函数,而是将其替换成函数的计算结果
#请注意,函数会优先选择匹配数字,比如输入- 2 pows 4,程序默认为输入的是-( 2 pows 4 )
#并且程序不支持链接括号,比如sin(30 + 30)是非法的,应该直接写成sin 60
def cal_replace(string):
    string=string.replace('  ',' ')
    expression=string.split(" ")#用空格分割字符串
    flag=0#这个标志用来记录表达式中是否有替换的地方,用以解决函数嵌套问题,例如ln ln 5的情况
    set1={'sin','cos','tan','rootcub','rootsqu','pows','sigmoid'}
    try:
        for i in range(len(expression)):
            if expression[i]=='(' and  expression[i+1]=='-':#这里的处理是为了方便复数的运算,例如1-(-2)
                string=string.replace('( - ','( -')
                flag=1
            if expression[i]=="e":#以下内容基本上都是求函数值,比如将表达式中的sin30替换成0.5
                result=e()
                string=string.replace('e', str(result))
                flag=1
            if expression[i]=="π":
                result=pi()
                string=string.replace('π', str(result))
                flag=1
            if expression[i] in set1 and expression[i+1] in '-' and regulmatch(expression[i+2]):
                string=string.replace(expression[i+1]+' '+expression[i+2], str(float(expression[i+2])*(-1)))
                flag=1
            if expression[i]=="pows" and  regulmatch(expression[i+1]) and regulmatch(expression[i-1]) and float(expression[i+1]).is_integer():
                result=pows(float(expression[i-1]),float(expression[i+1]))
                string=string.replace(expression[i-1]+' pows '+expression[i+1], str(result))
                flag=1
            if expression[i]=="log" and  regulmatch(expression[i+1]) and  regulmatch(expression[i-1]) and float(expression[i-1])>0 and float(expression[i+1])>0:
                result=log(float(expression[i-1]),float(expression[i+1]))
                string=string.replace(expression[i-1]+' log '+expression[i+1], str(result))
                flag=1
            if expression[i]=="sin"and  regulmatch(expression[i+1]):
                result=sin(float(expression[i+1]))
                string=string.replace('sin '+expression[i+1], str(result))
                flag=1
            if expression[i]=="cos" and  regulmatch(expression[i+1]):
                result=cos(float(expression[i+1]))
                string=string.replace('cos '+expression[i+1], str(result))
                flag=1
            if expression[i]=="tan" and  regulmatch(expression[i+1]) and (float(expression[i+1])+90)%180!=0:
                result=tan(float(expression[i+1]))
                string=string.replace('tan '+expression[i+1], str(result))
                flag=1
            if expression[i]=="rootsqu" and  regulmatch(expression[i+1]) and float(expression[i+1])>=0:
                result=rootsqu(float(expression[i+1]))
                string=string.replace('rootsqu '+expression[i+1], str(result))
                flag=1
            if expression[i]=="rootcub" and  regulmatch(expression[i+1]):
                result=rootcub(float(expression[i+1]))
                string=string.replace('rootcub '+expression[i+1], str(result))
                flag=1
            if expression[i]=="ln" and regulmatch(expression[i+1]) and float(expression[i+1])>0:
                result=ln(float(expression[i+1]))
                string=string.replace('ln '+expression[i+1], str(result))
                flag=1
            if expression[i]=="%" and regulmatch(expression[i-1]) :
                result=percent(float(expression[i-1]))
                string=string.replace(expression[i-1]+" %", str(result))
                flag=1
            if expression[i]=="sigmoid" and regulmatch(expression[i+1]) and float(expression[i+1]).is_integer():
                result=sigmoid(float(expression[i+1]))#因为用到了pows函数,pows不支持指数为小数
                string=string.replace('sigmoid '+expression[i+1], str(result))
                flag=1
        if flag==1:#如果表达式中出现替换,那么就需要递归调用该函数,解决例如sin sin 30的问题
            string=cal_replace(string)
        return string
    except :#并不能保证表达式能够正常替换,比如输入tan tan tan,最后没有数字,这种情况显然不合理,因此需要抛出异常
        tkinter.messagebox.showerror("表达式错误",'表达式存在一些问题,请仔细检查后输入正确的表达式')
        return string
    
    
###############################################################################
#将表达式中的括号提取出来方便处理,不过不提出来影响也不大
def find_bra(string):
    result=''
    for i in string:
        if i in "[]()":
            result=result+i
    return result

#match函数是用于括号匹配的函数,因为这里的[]()存在优先级的关系,所以直接用栈来完成会很复杂,比较方便的一种方式是
#用栈配合和字符串的检测来完成
def match(string):
    string=find_bra(string)
    bracket=[]
    try:
        for i in range(len(string)):
            if string[i] in "[](){}" :#由于{}判断原理与()[]相同,且本计算器中没有{},所以后面的部分讨论就没有再考虑{}
                bracket.append(string[i])
        if len(bracket)%2!=0:#括号数为奇数的直接进行报错
            ans=string
            if "()" in string:
                ans=ans.replace("()", "")
            if "[]" in string:
                ans=ans.replace("[]", "")
            tkinter.messagebox.showerror("括号匹配错误",'对不起,语法错误,'+ans+'使用不合理')
            return False
        if "[]" in string:#这一部分可以检测出括号优先级出错的情况,这里不需要考虑{}的情况
            tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误,[ ]使用不合理,使用( )后才能使用[ ]")
            return False
        if "((" in string:
            tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误,( )使用不合理,内层使用( )后外层应使用[ ]")
            return False
        if "[[" in string:
            tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误,[ ]使用不合理,内层使用[ ]后外层应使用{ }")
            return False
        if "([" in string:
            tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误,([ ])使用不合理,( )应放在[ ]内层")
            return False
        braStack = myStack()#创建类实例
        leftbkt = "{[("
        rightbkt = "}])"
        for i in string:#这一部分用于检测左括号和右括号不匹配的情况
            if i in leftbkt:
                braStack.push(i)
            elif i in rightbkt:
                if braStack.isEmpty():
                    tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误, "+i+" 使用不合理")
                    return False
                if rightbkt.index(i) != leftbkt.index(braStack.pop()):
                     if '[)' in string:
                        i='['
                     tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误, "+i+" 使用不合理")
                     return False
        if braStack.isEmpty():
            return True
        else:
            tkinter.messagebox.showerror("括号匹配错误","对不起,语法错误, "+braStack.pop()+" 使用不合理")
            return False
    except:
        tkinter.messagebox.showerror("括号匹配错误","在括号匹配过程中遇到一些错误,请重新输入表达式")
        return False
    
###############################################################################
#这个函数输出字符串中小数点数目主要是用来检测小数点是否错误,比如出现1.2.3这种错误的格式
def count_char(str):
    dict = 0
    for i in str:
        if i =='.':
            dict += 1
    return dict

#char_judge函数主要是用来解决e和π连续输入,跟数字和函数时出错的情况,例如etan、e9等情况
def char_judge(string):
    setwrong={'πe','eπ','ππ','ee','πt','πs','πc','πl','et','es','ec','el','πr','er'}
    setwrong2={'π0','π1','π2','π3','π4','π5','π6','π7','π8','π9','e1','e0','e2','e3','e4','e5','e6','e7','e8','e9'}
    for i in setwrong :
        if i in string:
            return True
    for i in setwrong2 :
        if i in string:
            return True
    return False
  
#find_wrong函数是用来检测表达式合法性的主要函数,主要检测一些比较容易描述的典型错误,主要包括复数的输入格式错误、eπ的使用问题,
#运算符、小数点的问题、函数的输入格式和取值范围问题等,一些不便于描述的错误直接统一报错
def find_wrong(string):
    string1=string.replace(" ", "")#一部分检测需要先将表达式中的空格去掉才能进行
    set1='*%/.'
    set3='+-*/'
    set2='0123456789'
    set4={"sin","cos",'tan',"ln","sigmoid","rootsqu","rootcub",'log','pows'}
    set5={'log','pows'}
    try:#前一部分检测的是去掉空格后的字符串
        if "+-" in string1 or "/-" in string1 or "--" in string1 or "*-" in string1:#表达式中间的复数最好写成(-x)的形式
            tkinter.messagebox.showerror('表达式输入错误',"请将复数写成0-x的形式,或者写成(-x)")
            return False
        if string1[0] in set1:#这些符号出现在表达式最前面显然是错误的
            tkinter.messagebox.showerror('表达式输入错误',"表达式的第一个符号使用不合理,请仔细检查后正确输入")
            return False
        if string1[-1] in set3:
            tkinter.messagebox.showerror('表达式输入错误',"表达式的最后一个符号使用不合理,请仔细检查后正确输入")
            return False
        if char_judge(string1) :
            tkinter.messagebox.showerror('表达式输入错误',"e或π的使用有问题,请仔细检查后正确输入")
            return False
        for i in range(len(string1)):#这里的i不用考虑越界问题,因为越界后后面会抛出异常
            if string1[i]=='.' and i!=0 and i!=len(string1)-1:#小数点必然在两个数字之间
                if (string1[i-1] not in set2) or (string1[i+1] not in set2):
                    tkinter.messagebox.showerror('表达式输入错误',".的使用不正确,请仔细检查后正确输入")
                    return False
            if string1[i]=='/' and i!=0 and i!=len(string1)-1:#加减乘除的判断,检测是否有连续输入运算符的情况,例如2++1,3*-1
                if (string1[i-1]  in '+-*/') or (string1[i+1]  in '+-*/%'):
                    tkinter.messagebox.showerror('表达式输入错误',"/的使用不正确,请仔细检查后正确输入")
                    return False
            if string1[i]=='+' and i!=0 and i!=len(string1)-1:
                if (string1[i-1]  in '+-*/') or (string1[i+1]  in '+-*/%'):
                    tkinter.messagebox.showerror('表达式输入错误',"+的使用不正确,请仔细检查后正确输入")
                    return False
            if string1[i]=='-' and i!=0 and i!=len(string1)-1:
                if (string1[i-1]  in '+-*/') or (string1[i+1]  in '+-*/%'):
                    tkinter.messagebox.showerror('表达式输入错误',"-的使用不正确,请仔细检查后正确输入")
                    return False
            if string1[i]=='*' and i!=0 and i!=len(string1)-1:
                if (string1[i-1]  in '+-*/') or (string1[i+1]  in '+-*/%'):
                    tkinter.messagebox.showerror('表达式输入错误',"*的使用不正确,请仔细检查后正确输入")
                    return False
            if string1[i]=='%' and (string1[i+1] not in '+-*/)]' or string[i-1] in set4 ):
                tkinter.messagebox.showerror('表达式输入错误','%的使用不正确,请仔细检查后正确输入')
                return False
            if string1[i]=='/' and string1[i+1]=='0':#除数不能为0的检测
                tkinter.messagebox.showerror('表达式错误',"语法错误,除数不能为0,请仔细检查后正确输入")
                return False
        expression=[]#以下部分需要将字符串通过空格进行分割后再检测
        string1=string.replace("  ", " ")
        expression=string.split(" ")#用空格分割字符串
        if expression[-1] in set4:
            tkinter.messagebox.showerror('表达式输入错误',"数学函数的使用存在问题,请仔细检查后正确输入")
            return False
        if expression[0] in set5:
            tkinter.messagebox.showerror('表达式输入错误',"数学函数的使用存在问题,请仔细检查后正确输入")
            return False
        for i in expression:
            if count_char(i)>1:
                tkinter.messagebox.showerror('表达式输入错误',"表达式中存在不正确的数字:"+i+',请仔细检查后正确输入')
                return False
        for i in range(len(expression)-1):#这里主要检测的是取值范围和函数的格式问题,例如sin(30+30)是不正确的,应该写为sin60
            if expression[i] in set4 and expression[i+1] =='(':
                tkinter.messagebox.showerror('表达式输入错误','该数学函数不支持嵌套表达式,请将括号内的式子单独计算,再使用该函数')
                return False
            if (expression[i]=='log' or  expression[i]=='pows' ) and expression[i-1]==')':
                tkinter.messagebox.showerror('表达式输入错误','该数学函数不支持嵌套表达式,请将括号内的式子单独计算,再使用该函数')
                return False
            if (expression[i]=='log' or  expression[i]=='pows' ) and (expression[i-1]=='' or expression[i-1] in "+-*/%."):
                tkinter.messagebox.showerror('表达式输入错误','函数缺少一个输入值,请仔细检查后正确输入')
                return False
            if (expression[i]=='log' or  expression[i]=='pows' ) and (expression[i+1]=='' or expression[i+1] in "+-*/%."):
                tkinter.messagebox.showerror('表达式输入错误','函数缺少一个输入值,请仔细检查后正确输入')
                return False
            if expression[i]=='tan' and (float(expression[i+1])+90)%180==0:
                tkinter.messagebox.showerror('表达式输入错误','tan取值有问题,请仔细检查后正确输入')
                return False
            if expression[i]=='ln'and expression[i+1]=='-':
                tkinter.messagebox.showerror('表达式输入错误','ln取值有问题,请仔细检查后正确输入')
                return False
            if expression[i]=='log'and (expression[i+1]=='-' or expression[i+1]=='0'):
                tkinter.messagebox.showerror('表达式输入错误','log取值有问题,请仔细检查后正确输入')
                return False
            if expression[i]=='ln'and (expression[i+1]=='0' or float(expression[i+1])<0):
                tkinter.messagebox.showerror('表达式输入错误','ln取值有问题,请仔细检查后正确输入')
                return False
            if expression[i]=='log'and (float(expression[i-1])<=0 or float(expression[i+1])<=0):
                tkinter.messagebox.showerror('表达式输入错误','log取值有问题,请仔细检查后正确输入')
                return False
            if expression[i]=='rootsqu'and float(expression[i+1])<0 :
                tkinter.messagebox.showerror('表达式输入错误','rootsqu取值有问题,请仔细检查后正确输入')
                return False 
            if (expression[i]=='sigmoid' or  expression[i]=='pows' ) and  not(float(expression[i+1]).is_integer()):
                tkinter.messagebox.showerror('表达式输入错误','该数学函数不支持小数,请仔细检查后正确输入')
                return False
        return True
    except:#这里主要是考虑到异常输入会使前面的检测出现越界的情况,比如tan%等,还有一些不便于描述的错误,在这里一起抛出
        tkinter.messagebox.showerror('表达式输入错误','表达式输入存在错误,请仔细检查后正确输入')
        return False
    
    
    
###############################################################################
#######下面主要是和GUI生成的模块
#这个函数将[]转换成(),在进行括号匹配检测后,[]已经没有意义,正常的计算器只需要()就足够了,calculate函数也不需要单独用[]
def transbra(string):
    string=string.replace('[','(')
    string=string.replace(']',')')
    return string

def button_click(string):#数字和函数按钮的相应
    global calc_operator#calc_operator必须设置成全局变量,因为在多个函数中都将对其进行操作
    calc_operator=calc_operator+string
    calc_operator1=calc_operator.replace(' ',"")#将表达式中大量的空格去掉后再显示
    text_input.set(calc_operator1)

def button_clear_all():#AC按钮的响应
    global calc_operator
    calc_operator=""
    text_input.set("")

def button_delete():#⌫按钮的响应
    global calc_operator
    text=calc_operator[:-1]
    calc_operator=text
    text_input.set(text)


def button_equal():#=按钮的响应
    global calc_operator
    string=calc_operator
    string=string.replace('  ',' ')#部分情况下表达式中会出现连续两个空格,这时候需要去掉一个空格,以免影响后续使用
    a=match(string)
    string=cal_replace(string)
    b=find_wrong(string)#这里可以改成a为True的时候才执行,就可以减少执行量,提高速度
    if a and b:
        string=transbra(string)#[]转化为()
        print('计算的表达式为:',calc_operator.replace(' ',''))
        temp_op=str(calculate(string))
        text_input.set(temp_op)
        calc_operator=temp_op
    else:
        print('计算的表达式为:',string.replace(' ',''))
        calc_operator=""

tk_calculate=Tk()
tk_calculate.configure(bg="#d3d7d4", bd=10)
tk_calculate.title("网宿科技")

calc_operator=""
text_input=StringVar()

#文本框
text_display=Entry(tk_calculate, font=('sans-serif', 27, 'bold'), textvariable=text_input,
            bd=5, insertwidth = 5, bg='#fffffb', justify='right').grid(columnspan=5, padx = 10, pady = 15)
button_params={'bd':5, 'fg':'#BBB', 'bg':'#3C3636', 'font':('sans-serif', 20, 'bold')}#按钮格式的统一设置
button_params_main={'bd':5, 'fg':'#000', 'bg':'#BBB', 'font':('sans-serif', 20, 'bold')}


#下面是各个按钮的排列,格式基本上都一样
#第一行
button_sin=Button(tk_calculate, button_params, text='sin',
        command=lambda:button_click('sin ')).grid(row=1, column=0, sticky="nsew")
button_cos=Button(tk_calculate, button_params, text='cos',
        command=lambda:button_click('cos ')).grid(row=1, column=1, sticky="nsew")
button_tan=Button(tk_calculate, button_params, text='tan',
        command=lambda:button_click('tan ')).grid(row=1, column=2, sticky="nsew")
button_e=Button(tk_calculate, button_params, text=' e ',
        command=lambda:button_click('e')).grid(row=1, column=3, sticky="nsew")
button_pi=Button(tk_calculate, button_params, text=' π ',
         command=lambda:button_click('π')).grid(row=1, column=4, sticky="nsew")
#第二行
button_root2=Button(tk_calculate, button_params, text='\u00B2\u221A',
        command=lambda:button_click('rootsqu ')).grid(row=2, column=0, sticky="nsew")
button_root3=Button(tk_calculate, button_params, text='\u00B3\u221A',
        command=lambda:button_click('rootcub ')).grid(row=2, column=1, sticky="nsew")
button_pows=Button(tk_calculate, button_params, text='x^n',
        command=lambda:button_click(' pows ')).grid(row=2, column=2, sticky="nsew")
button_sigmoid=Button(tk_calculate, button_params, text='sigmoid',font=("宋体",10),
        command=lambda:button_click('sigmoid ')).grid(row=2,  column=3, sticky="nsew")
button_log=Button(tk_calculate, button_params, text='log ',
        command=lambda:button_click(' log ')).grid(row=2,  column=4, sticky="nsew")
#第三行
button_kuol1=Button(tk_calculate, button_params, text='(',
        command=lambda:button_click('( ')).grid(row=3, column=0, sticky="nsew")
button_kuor1=Button(tk_calculate, button_params, text=')',
        command=lambda:button_click(' )')).grid(row=3, column=1, sticky="nsew")
button_kuol2=Button(tk_calculate, button_params, text='[',
        command=lambda:button_click('[ ')).grid(row=3, column=2, sticky="nsew")
button_kuor2=Button(tk_calculate, button_params, text=']',
        command=lambda:button_click(' ]')).grid(row=3, column=3, sticky="nsew")
button_ln=Button(tk_calculate, button_params, text='ln', font=('sans-serif', 15, 'bold'),
        command=lambda:button_click('ln ')).grid(row=3, column=4, sticky="nsew")
#第四行
button_0=Button(tk_calculate, button_params_main, text='0',
        command=lambda:button_click('0')).grid(row=4, column=0, sticky="nsew")
button_point=Button(tk_calculate, button_params_main, text='.',
        command=lambda:button_click('.')).grid(row=4, column=1, sticky="nsew")
button_percent=Button(tk_calculate, button_params_main, text='%',
        command=lambda:button_click(' %')).grid(row=4, column=2, sticky="nsew")
button_delete_one=Button(tk_calculate, bd=5, fg='#000', font=('sans-serif', 20, 'bold'),
        text='⌫', command=button_delete, bg='#db701f').grid(row=4, column=3, sticky="nsew")
button_delete_all=Button(tk_calculate, bd=5, fg='#000', font=('sans-serif', 20, 'bold'),
        text='AC', command=button_clear_all, bg='#db701f').grid(row=4, column=4, sticky="nsew")
#第五行
button_7=Button(tk_calculate, button_params_main, text='7',
        command=lambda:button_click('7')).grid(row=5, column=0, sticky="nsew")
button_8=Button(tk_calculate, button_params_main, text='8',
        command=lambda:button_click('8')).grid(row=5, column=1, sticky="nsew")
button_9=Button(tk_calculate, button_params_main, text='9',
        command=lambda:button_click('9')).grid(row=5, column=2, sticky="nsew")
button_mul=Button(tk_calculate, button_params_main, text='*',
        command=lambda:button_click(' * ')).grid(row=5, column=3, sticky="nsew")
button_dev=Button(tk_calculate, button_params_main, text='/',
        command=lambda:button_click(' / ')).grid(row=5, column=4, sticky="nsew")
#第六行
button_4=Button(tk_calculate, button_params_main, text='4',
        command=lambda:button_click('4')).grid(row=6, column=0, sticky="nsew")
button_5=Button(tk_calculate, button_params_main, text='5',
        command=lambda:button_click('5')).grid(row=6, column=1, sticky="nsew")
button_6=Button(tk_calculate, button_params_main, text='6',
        command=lambda:button_click('6')).grid(row=6, column=2, sticky="nsew")
button_add=Button(tk_calculate, button_params_main, text='+',
       command=lambda:button_click(' + ')).grid(row=6, column=3, sticky="nsew")
button_sub=Button(tk_calculate, button_params_main, text='-',
        command=lambda:button_click(' - ')).grid(row=6, column=4, sticky="nsew")
#第七行
button_1=Button(tk_calculate, button_params_main, text='1',
        command=lambda:button_click('1')).grid(row=7, column=0, sticky="nsew")
button_2=Button(tk_calculate, button_params_main, text='2',
        command=lambda:button_click('2')).grid(row=7, column=1, sticky="nsew")
button_3=Button(tk_calculate, button_params_main, text='3', font=('sans-serif', 16, 'bold'),
        command=lambda:button_click('3')).grid(row=7, column=2, sticky="nsew")
button_equal=Button(tk_calculate, button_params_main, text='=',
        command=button_equal).grid(row=7, columnspan=2, column=3, sticky="nsew")

tk_calculate.mainloop()
#转载请注明作者

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】适合专科和本科毕业生的【原创论文】【已降重】【万字】【本科】【专科】【毕业论文】【预览目录】【预览正文】

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值