实验项目一:支持算数表达式求解的计算器源代码

run:

from calculator import *
import tkinter
import tkinter as TK
from turtle import back


# 主窗口
root = TK.Tk()
root.title("Calculator")
root.resizable(0, 0)
root.geometry('280x500')


result = TK.StringVar()  # 用来显示结果的可变文本
equation = TK.StringVar()  # 用来显示算式的可变文本
result.set(' ')  # 赋初始值
equation.set('0')  # 赋初始值


# 撤销:按下退格键时,去除最后一个字符
def back():
    temp = equation.get()
    equation.set(temp[:-1])


# 按下AC时,清空算式行与结果行
def clear():
    equation.set('0')
    result.set(' ')

# 获得数字与运算符
def getnum(num):
    temp = equation.get()
    temp2 = result.get()
    print(temp)
    print(temp2)
    if temp2 != ' ':
        temp = '0'
        temp2 = ' '
        result.set(temp2)
    if temp == '0':
        temp = ''
    temp = temp + num
# 出现连续+,则第二个+为无效输入,不做任何处理
    if (temp[-2:] == '++') and (num == '+'):
        return
    # 出现连续+--,则第三个-为无效输入,不做任何处理
    if (temp[-2:] == '+-') and (num == '-'):
        return
    # 窗口已经有--后面字符不能为+或-
    if (temp[-2:] == '--') and (num in ['-', '+']):
        return
    # 窗口已经有 xx 后面字符不能为 x 或 ÷
    if (temp[-2:] == 'xx') and (num in ['x', '÷']):
        return
    # 窗口已经有 ÷÷ 后面字符不能为 x 或 ÷
    if (temp[-2:] == '÷÷') and (num in ['÷', 'x']):
        return
    # 出现连续.,则第二个+为无效输入,不做任何处理
    if (temp[-2:] == '..') and (num == '.'):
        return

    equation.set(temp)
    print(equation)

#等号运行结果
def run():
    temp = equation.get()
    temp = temp.replace('x', '*')
    temp = temp.replace('÷', '/')
    answer = calculator(temp)
    result.set(str(answer))


# 记录运算历史

def history():
    #历史记录窗口
    History = TK.Tk()
    History.title("History")
    History.resizable(0, 0)
    History.geometry('280x500')
    h=tkinter.StringVar()
    h.set('')
    label0 = tkinter.Label(History, text = str(equation.get() + "=" +result.get()),font=('微软雅黑', 20), bg='#EEE9E9', bd='9',
                           fg='#828282',anchor='se', textvariable=h)
    label0.place(width=280, height=170)
    history_label_list = []
    h= str(equation.get() + "=" +result.get())
    h.pack()
    history_label_list.append(h)



# 显示版
label = tkinter.Label(root, font=('微软雅黑', 20), bg='#EEE9E9', bd='9', fg='#828282', anchor='se', textvariable=result)
label.place(width=280, height=170)
label2 = tkinter.Label(root, font=('微软雅黑', 30), bg='#EEE9E9', bd='9', fg='black', anchor='se', textvariable=equation)
label2.place(y=170, width=280, height=60)

# 数字
btn7 = tkinter.Button(root, text='7', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('7'))
btn7.place(x=0, y=285, width=70, height=55)
btn8 = tkinter.Button(root, text='8', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('8'))
btn8.place(x=70, y=285, width=70, height=55)
btn9 = tkinter.Button(root, text='9', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('9'))
btn9.place(x=140, y=285, width=70, height=55)

btn4 = tkinter.Button(root, text='4', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('4'))
btn4.place(x=0, y=340, width=70, height=55)
btn5 = tkinter.Button(root, text='5', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('5'))
btn5.place(x=70, y=340, width=70, height=55)
btn6 = tkinter.Button(root, text='6', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('6'))
btn6.place(x=140, y=340, width=70, height=55)

btn1 = tkinter.Button(root, text='1', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('1'))
btn1.place(x=0, y=395, width=70, height=55)
btn2 = tkinter.Button(root, text='2', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('2'))
btn2.place(x=70, y=395, width=70, height=55)
btn3 = tkinter.Button(root, text='3', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('3'))
btn3.place(x=140, y=395, width=70, height=55)
btn0 = tkinter.Button(root, text='0', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('0'))
btn0.place(x=70, y=450, width=70, height=55)

# 运算符号按钮
btn_back = tkinter.Button(root, text='←', bd=0.5, font=('微软雅黑', 20), fg='#4F4F4F', command=back)
btn_back.place(x=0, y=230, width=70, height=55)
btn_left = tkinter.Button(root, text='(', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('('))
btn_left.place(x=70, y=230, width=70, height=55)
btn_right = tkinter.Button(root, text=')', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum(')'))
btn_right.place(x=140, y=230, width=70, height=55)
btn_mul = tkinter.Button(root, text='×', font=('微软雅黑', 20), fg="#4F4F4F", bd=0.5, command=lambda: getnum('x'))
btn_mul.place(x=210, y=230, width=70, height=55)
btn_sub = tkinter.Button(root, text='-', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('-'))
btn_sub.place(x=245, y=285, width=35, height=55)
btn_add = tkinter.Button(root, text='+', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('+'))
btn_add.place(x=210, y=285, width=35, height=55)
btn_history = tkinter.Button(root,text='h',font =('黑体', 20), fg='#4F4F4F', bd=0.5, command=history)
btn_history.place(x=210, y=340, width=70, height=55)
btn_division = tkinter.Button(root, text='÷', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('÷'))
btn_division.place(x=210, y=395, width=70, height=55)
btn_equal = tkinter.Button(root, text='=', bg='orange', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5,
                           command=run)
btn_equal.place(x=210, y=450, width=70, height=55)
btnAC = tkinter.Button(root, text='AC', font=('黑体', 20), fg='orange', bd=0.5, command=clear)
btnAC.place(x=0, y=450, width=70, height=55)
btn_point = tkinter.Button(root, text='.', font=('微软雅黑', 20), fg='#4F4F4F', bd=0.5, command=lambda: getnum('.'))
btn_point.place(x=140, y=450, width=70, height=55)



root.mainloop()

calculator:

import re


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


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


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


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


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


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  # 当递归到最后一层的时候,不再有括号,因此返回列表


def calculator(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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
表达式计算说明 很久就想编一个这样的计算器,只可惜一直没什么思路,最近突然灵感来了,所以就写下 这个程序。现在还在测试阶段,所以功能不是很完善。 程序功能:基本的表达式运算,可以自定义函数跟常量,分别保存在 “常数.txt” 和 “函数.txt”,方便自己添加。双击相应的函数名或常数名就可以将函数或常量添加到表达式中。 计算过程只能当表达式只有一行时有效。 实例1:计算sqr(19+tan(98)*tan(91)-sin(122)*(5*5-(19-11)))/2 计算过程sqr(19+tan(98)*tan(91)-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*tan(91)-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*(5*5-8))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*17)/2 =20.3032618253667/2 =10.1516309126834 实例2:计算 a=34 b=55 c=a+1 圆的面积(c) a*b c=a+b 圆的面积(c) 以下是计算结果: 圆的面积(c)=3848.4510006475 a*b=1870 圆的面积(c)=24884.5554090847 内置函数: !(x) - x 的阶乘 lg(x),log(x) 以10为底的对数 ln(x) 以 e为底x的对数 pow(x,y) x的y方次幂 prime(x) 判定x是否是素数,如果是直接将s2返回,否则将其各因子用连乘返回 sqr(x),sqrt(x) - x 的二次方根 arcsin(x) - x 的反正弦 arccos(x) - x 的反余弦 arcsec(x) - x 的反正割 arccsc(x) - x 的反余割 atn(x),arctg(x) - x 的反正切 arcctg(x) - x 的反余切 sin(x) - x 的正弦 cos(x) - x 的余弦 sec(x) - x 的正割 csc(x) - x 的余割 tg(x),tan(x) - x 的正切 ctg(x) - x 的余切 harcsin(x) - x 的反双曲正弦 harccos(x) - x 的反双曲余弦 harcsec(x) - x 的反双曲正割 harccsc(x) - x 的反双曲余割 harctg(x),harctan(x) - x 的反双曲正切 harcctg(x) - x 的反双曲余切 hsin(x) - x 的双曲正弦 hcos(x) - x 的双曲余弦 hsec(x) - x 的双曲正割 hcsc(x) - x 的双曲余割 htg(x),htan(x) - x 的双曲正切 hctg(x) - x 的双曲余切 有什么意见或建议可以跟我联系Email: ldm.menglv@gmail.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值