在使用括号like->计算表达式时显示此错误86 * 4(3 + 5)88:
TypeError:'int'对象不可调用
当我不使用计算器按钮并使用我的键盘按钮键入时,它不显示任何错误,但按下等于它会给出错误答案。
请检查我的代码并指出错误。
from tkinter import *
cal = Tk()
cal.title("Smart Calculator")
txtDisplay = Entry(cal, font=('arial', 20, 'bold'), bd=30, insertwidth=4,
bg="powder blue", justify='right')
class Calculator:
def __init__(self):
self.result = 0
self.current = 0
self.operator = ""
def btnClick(self, num):
self.operator = self.operator + str(num)
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.expOutput(self.operator)
def expOutput(self, operator):
try:
self.result = str(eval(operator))
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator + "=" + self.result)
self.current = 0
except SyntaxError:
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
def oprtrClick(self, op):
if self.current is 0:
self.current = 1
self.operator = self.operator + op
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator)
else:
self.operator = self.operator + op
self.expOutput(self.operator)
def equals(self):
self.operator = self.result
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator)
def clear(self):
self.__init__()
txtDisplay.delete(0, END)
def delete(self):
self.operator = self.operator[: -1]
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator)
smartCal = Calculator()
btn0 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20,
'bold'), text="0",bg="powder blue", command=lambda: smartCal.btnClick(0))
btn1 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20,
'bold'), text="1",
bg="powder blue", command=lambda: smartCal.btnClick(1))
btn2 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20,
'bold'), text="2",bg="powder blue", command=lambda: smartCal.btnClick(2))
btn3 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20,
'bold'), text="3",
bg="powder blue", command=lambda: smartCal.btnClick(3))
btn4 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="4",
bg="powder blue", command=lambda: smartCal.btnClick(4))
btn5 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="5",
bg="powder blue", command=lambda: smartCal.btnClick(5))
btn6 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="6",
bg="powder blue", command=lambda: smartCal.btnClick(6))
btn7 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="7",
bg="powder blue", command=lambda: smartCal.btnClick(7))
btn8 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="8",
bg="powder blue", command=lambda: smartCal.btnClick(8))
btn9 = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="9",
bg="powder blue", command=lambda: smartCal.btnClick(9))
btnDecimal = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text=".",
bg="powder blue", command=lambda: smartCal.btnClick("."))
btnLeftParen = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="(",
bg="powder blue", command=lambda: smartCal.btnClick("("))
btnRightParen = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text=")",
bg="powder blue", command=lambda: smartCal.btnClick(")"))
Add_btn = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="+",
bg="powder blue", command=lambda: smartCal.oprtrClick("+"))
Sub_btn = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="-",
bg="powder blue", command=lambda: smartCal.oprtrClick("-"))
Mul_btn = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="*",
bg="powder blue", command=lambda: smartCal.oprtrClick("*"))
Div_btn = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="/",
bg="powder blue", command=lambda: smartCal.oprtrClick("/"))
btnEquals = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="=",
bg="powder blue", command=smartCal.equals)
btnClear = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="C",
bg="powder blue", command=smartCal.clear)
btnBackspace = Button(cal, padx=16, pady=16, bd=8, fg="black", font=('arial', 20, 'bold'), text="⌫",
bg="powder blue", command=smartCal.delete)
# ~*~*~Positioning~*~*~
txtDisplay.grid(columnspan=4)
# =========ROW1================== #
btn7.grid(row=1, column=0)
btn8.grid(row=1, column=1)
btn9.grid(row=1, column=2)
Add_btn.grid(row=1, column=3)
# =========ROW2================== #
btn4.grid(row=2, column=0)
btn5.grid(row=2, column=1)
btn6.grid(row=2, column=2)
Sub_btn.grid(row=2, column=3)
# =========ROW3================== #
btn1.grid(row=3, column=0)
btn2.grid(row=3, column=1)
btn3.grid(row=3, column=2)
Mul_btn.grid(row=3, column=3)
# =========ROW4================== #
btn0.grid(row=4, column=0)
btnClear.grid(row=4, column=1)
btnEquals.grid(row=4, column=2)
Div_btn.grid(row=4, column=3)
# =========ROW5================== #
btnDecimal.grid(row=5, column=0)
btnLeftParen.grid(row=5, column=1)
btnRightParen.grid(row=5, column=2)
btnBackspace.grid(row=5, column=3)
cal.mainloop()
答案 0 :(得分:1)
在您的方法expOutput
中,您应该在开始或结束括号前后的*
字符串中添加缺少的operator
符号。
这需要在调用eval(operator)
之前通过调用解析函数来完成,比如add_missing_mult
。
解析函数的简单实现可能如下所示:
def add_missing_mult(s):
splitted = s.split('(')
for i, sub in enumerate(splitted[:-1]):
if sub[-1].isdigit() or sub[-1] == '.':
splitted[i] += "*"
s = '('.join(splitted)
splitted = s.split(')')
for i, sub in enumerate(splitted[1:]):
if sub[0].isdigit():
splitted[i+1] = "*" + splitted[i+1]
return ')'.join(splitted)
add_missing_mult('86*4(3+5)88')
>>>'86*4*(3+5)*88'
然后在expOutput
:
operator = add_missing_mult(operator)
try:
self.result = str(eval(operator))
txtDisplay.delete(0, END)
...
但是在一个真实的项目中,你会看到使用像this question
这样的正则表达式答案 1 :(得分:1)
我在不使用解析功能的情况下解决了问题。我使用了两个新变量 - isButton和isRightParen以及两个新函数 - leftParenthesesClick()和rightParenthesesClick()。 isButton会跟踪最后一个按下的按钮是否为数字(0-9)。当用户按下左括号时,首先它检查isRightParen是否为1然后它在左括号前包含*符号,然后如果isButton为1则还包括*,否则左括号将按原样打印。
请检查我的代码并告诉我这种方式是否正常,是否存在错误,或者有更好更短的方法来执行此操作。 @Jacques Gaudin @PM 2Ring 我稍后会尝试使用解析函数以及建议。 :)
def __init__(self):
self.var1 = ""
self.var2 = ""
self.output = 0
self.current = 0
self.operator = ""
self.isButton = 0
self.isRightParen = 0
def btnClick(self, num):
if self.isRightParen is 1:
self.operator = self.operator + "*" + str(num)
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.expOutput(self.operator)
self.isButton = 1
self.isRightParen = 0
elif self.isRightParen is 0:
self.operator = self.operator + str(num)
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.expOutput(self.operator)
self.isButton = 1
self.isRightParen = 0
def leftParenthesesClick(self):
if self.isRightParen is 1:
self.operator = self.operator + "*" + "("
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.isRightParen = 0
elif self.isButton is 0:
self.operator = self.operator + "("
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.isRightParen = 0
elif self.isButton is 1:
self.operator = self.operator + "*" + "("
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.isRightParen = 0
def rightParenthesesClick(self):
self.operator = self.operator + ")"
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
self.expOutput(self.operator)
self.isRightParen = 1
def expOutput(self, operator):
try:
self.output = str(eval(operator))
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator + "=" + self.output)
self.current = 0
except SyntaxError:
txtDisplay.delete(0, END)
txtDisplay.insert(0, self.operator)
def oprtrClick(self, op):
if self.current is 0:
self.current = 1
self.operator = self.operator + op
txtDisplay.delete(0, END)
txtDisplay.insert(0, string=self.operator)
self.isButton = 0
self.isRightParen = 0
else:
self.operator = self.operator + op
self.isButton = 0
self.isRightParen = 0
self.expOutput(self.operator)