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