用户:
开源盛世查看:0 回复:4 评论:0 创建时间:2020-07-21T18:38:42
0.作品展示

1.源代码
#导入图形化模块
from tkinter import *
from tkinter.messagebox import *
#主窗口
root=Tk()
root.title("解一元一次方程")
root.geometry("280x280")
root.resizable(False,False)
#定义每个项
class term:
#属性说明
#int coef 当前项的系数(coefficient 系数的缩写)
#str type_ 类型(常数项或含有x的一次项)
def __init__(self, _t="1", _c=1):
self.type_ = _t
self.coef = _c
def __add__(self, o):
if o.type_ == self.type_:
self.coef = o.coef+self.coef
return self
else:
raise ValueError
def __sub__(self, o):
if o.type_ == self.type_:
self.coef = self.coef-o.coef
return self
else:
raise ValueError
def __str__(self):
if self.coef<0:
if self.coef==-1:
if self.type_=='x': return '-x'
elif self.type_=='1': return '-1'
else:
if self.type_=='x': return str(self.coef)+self.type_
elif self.type_=='1': return str(self.coef)
elif self.coef==0: return ' '
elif self.coef>0:
if self.coef==1:
if self.type_=='1': return "+1"
elif self.type_=='x': return "+x"
else:
if self.type_=='x': return '+'+str(self.coef)+self.type_
elif self.type_=='1': return '+'+str(self.coef)
def update():
#刷新上方方程
__temp = ''
for i in range(len(terms)):
__temp += str(terms[i])
z.set(__temp)
def make_new_term(t, p):
#两个添加项的键功能
newobj = term(t, p)
terms.append(newobj)
update()
def delete_last_term():
#“删除末尾项”键功能
try:
terms.pop()
except IndexError:
pass
update()
def cmd(x):
#“1”~“9”键功能
v.set(v.get()+str(x))
def add_point():
#“小数点”键功能
if '.' not in v.get() and len(v.get())!=1:
cmd('.')
else:
return
def change():
#“正负”键功能
if v.get()[0] == '+':
v.set('-'喵.get()[1:])
else:
v.set('+'喵.get()[1:])
def backspace():
#“删除”键功能
if v.get()[-1] in ('+', '-'):
pass
else:
v.set(v.get()[:-1])
def cmd0():
#输入0(特殊之处在于,0不能做第一位)
if len(v.get()) != 1:
v.set(v.get()+'0')
else:
return
def ok():
#“确定”键功能
try:
f=int(v.get())
except ValueError:
try:
f=float(v.get())
except ValueError:
f=0
try:
if f!=0:
terms[-1].coef=f
else:
terms.pop()
except IndexError:
pass
update()
def getans():
#把原方程化为最简形式并根据公式求解
__1=0
__x=0
for i in terms:
if i.type_=='1':
__1+=i.coef
elif i.type_=='x':
__x+=i.coef
try:
answer=(-__1)/__x
except ZeroDivisionError:
showerror('错误!','此方程无解!\n可能是因为未知项系数和为0')
answer=''
else:
showinfo('成功!','方程解是:x={:.10f}'.format(answer))
def show_help():
#显示帮助
helper_str="""快捷键帮助:
主键盘区1~0,小键盘区1~0:直接在“更改系数”输入对应数字
Enter:即“更改系数”的“确定”
Ctrl+1:输入常数项
Ctrl+2:输入x的一次项
Ctrl+Backspace:删除末尾项
Ctrl+Enter:求解
Esc:退出
Ctrl+H:打开此帮助页面
"""
showinfo("帮助",helper_str)
#菜单
menu=Menu(root)
root.config(menu=menu)
help_m=Menu(menu,tearoff=0)
help_m.add_command(label="快捷键帮助",command=show_help)
menu.add_cascade(label="帮助",menu=help_m)
z = StringVar()
z.set('')
v = StringVar()
v.set('+')
#“添加项”功能区
terms = []#项列表
f1 = LabelFrame(root, text="添加项",height=150,width=150)
f1.place(x=10, y=60)
a = Button(f1,text="...(常数项)",command=lambda:make_new_term("1",1))
a.place(x=0,y=0)
b = Button(f1, text="...x(含有x的一次项)", command=lambda:make_new_term("x", 1))
b.place(x=0, y=30)
c = Button(f1, text="删除末尾项", command=lambda:delete_last_term())
c.place(x=0, y=60)
#“更改系数”功能区
f2 = LabelFrame(root, text="更改系数", height=200, width=200)
f2.place(x=160, y=60)
Label0=Label(root,font=("Consolas",20),textvariable=z)
Label0.place(x=0,y=10)
Label(root,font=("Consolas",20),text="=0").place(x=240,y=10)
Label(f2, height=2).grid(column=1, row=0)
Label(f2, font=("Century Gothic", 20), textvariable=v).place(x=0, y=0)
#数字、符号按钮
Button(f2, text=' 7 ', command=lambda: cmd(7)).grid(column=1, row=1)
Button(f2, text=' 8 ', command=lambda: cmd(8)).grid(column=2, row=1)
Button(f2, text=' 9 ', command=lambda: cmd(9)).grid(column=3, row=1)
Button(f2, text=' 4 ', command=lambda: cmd(4)).grid(column=1, row=2)
Button(f2, text=' 5 ', command=lambda: cmd(5)).grid(column=2, row=2)
Button(f2, text=' 6 ', command=lambda: cmd(6)).grid(column=3, row=2)
Button(f2, text=' 1 ', command=lambda: cmd(1)).grid(column=1, row=3)
Button(f2, text=' 2 ', command=lambda: cmd(2)).grid(column=2, row=3)
Button(f2, text=' 3 ', command=lambda: cmd(3)).grid(column=3, row=3)
Button(f2, text=' +/- ', command=change).grid(column=1, row=4)
Button(f2, text=' 0 ', command=cmd0).grid(column=2, row=4)
Button(f2, text=' . ', command=add_point).grid(column=3, row=4)
Button(f2, text=' %s ' % chr(9003), command=backspace).grid(column=1, row=5)
Button(f2, text=' 确定 ', bg='yellow',command=ok).grid(column=2, row=5, columnspan=2)
Button(root,text='求解',bg='orange',command=getans,height=3,width=20).place(x=10,y=210)
#快捷键
root.bind('<KeyPress-1>', lambda event: cmd(1))
root.bind('<KeyPress-2>', lambda event: cmd(2))
root.bind('<KeyPress-3>', lambda event: cmd(3))
root.bind('<KeyPress-4>', lambda event: cmd(4))
root.bind('<KeyPress-5>', lambda event: cmd(5))
root.bind('<KeyPress-6>', lambda event: cmd(6))
root.bind('<KeyPress-7>', lambda event: cmd(7))
root.bind('<KeyPress-8>', lambda event: cmd(8))
root.bind('<KeyPress-9>', lambda event: cmd(9))
root.bind('<KeyPress-0>', lambda event: cmd(0))
root.bind('<Return>', lambda event: ok())
root.bind('<Control-KeyPress-1>', lambda event: make_new_term("1",1))
root.bind('<Control-KeyPress-2>', lambda event: make_new_term("x",1))
root.bind('<Control-BackSpace>',lambda event: delete_last_term())
root.bind('<KP_1>', lambda event: cmd(1))
root.bind('<KP_2>', lambda event: cmd(2))
root.bind('<KP_3>', lambda event: cmd(3))
root.bind('<KP_4>', lambda event: cmd(4))
root.bind('<KP_5>', lambda event: cmd(5))
root.bind('<KP_6>', lambda event: cmd(6))
root.bind('<KP_7>', lambda event: cmd(7))
root.bind('<KP_8>', lambda event: cmd(8))
root.bind('<KP_9>', lambda event: cmd(9))
root.bind('<KP_0>', lambda event: cmd(0))
root.bind('<BackSpace>', lambda event: backspace())
root.bind('<KP_Decimal>', lambda event: add_point())
root.bind('<Control-KeyPress-Return>',lambda event: getans())
root.bind('<Control-KeyPress-H>',lambda event: show_help())
root.bind('<Control-KeyPress-h>',lambda event: show_help())
root.bind('<Escape>',lambda event: root.quit())
mainloop()
2.说明
出于这次更新难度较大,以及空余时间有些少,断更了很长时间,不过你们的评论我都看了。
评论里有人让做解一元二次方程的,还跟以前那样一个公式就过去了,那还算个什么!所以,这次更新,则带给大家一个功能更加强大点的,解一元二次方程的以后就会出。
核心思想是,用一个列表存储等号左边的所有项,至于每个项,则使用 term 类的实例存储。求解时,把所有带未知数项的系数相加得到 a ,再用所有常数项的系数相加得到 b ,再根据公式得到解。
这次更新也加入了快捷键,使用 Tk().bind() 即可,这些在这里也不再多说,以及更多的细节问题,需要大家自己学习、自己理解。再见!