猫史档案馆


解一元一次方程器(更新1次)

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


0.作品展示

center_imagecenter_image1.源代码

#导入图形化模块
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() 即可,这些在这里也不再多说,以及更多的细节问题,需要大家自己学习、自己理解。再见!

      


回复

上一页1 页 / 共 1下一页
­­­­­­­­­­­­­­

点赞1


评论


­­­­­­­­­­­­­­

可以集成exe程序呀

点赞0


评论


蒟蒻OIer1048576蒟蒻OIer1048576

不错,我能看懂

点赞0


评论


挖坟专家挖坟专家

c喵 = cmd

点赞0


评论