吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1280|回复: 1
收起左侧

[Python 转载] 【中缀转后缀表达式】实现加减乘除计算器

[复制链接]
Lthero 发表于 2021-3-25 21:11


tkinter 实现加减乘除简单计算器,尝试模拟win10 UI

实现计算的核心算法为 中缀表达式 变成  后缀表达式 如a+b*c转成abc*+

利用栈实现(数据结构与算法部分)

===========实现计算的核心代码============
[Python] 纯文本查看 复制代码
    def True_cal(str1):
        stack = []
        final_res = []
        marks = ['+', '-', '*', '/']
        numbers = [str(i) for i in range(0, 10)]
        temp_11 = 0
        count = 0
        for i in str1:
            count += 1
            if i in numbers:
                temp_11 = temp_11 * 10 + int(i)
            if i in marks or count == len(str1):
                final_res.append(str(temp_11))
                temp_11 = 0
                if len(stack) != 0:
                    if i == '*' or i == '/':
                        while stack[-1] in ['*', '/']:
                            final_res.append(stack[-1])
                            stack.pop()
                            if len(stack) == 0:
                                break
                        stack.append(i)
                    if i == '+' or i == '-':
                        while stack[-1] in marks:
                            final_res.append(stack[-1])
                            stack.pop()
                            if len(stack) == 0:
                                break
                        stack.append(i)
                else:
                    if i in marks:
                        stack.append(i)
            if i == '(' or i == '(':
                stack.append(i)
            if i == ')' or i == ')':
                while stack[-1] != '(':
                    final_res.append(stack[-1])
                    stack.pop()
                    if len(stack) == 0:
                        break
                stack.pop()
        for i in range(len(stack)):
            final_res.append(stack.pop())
        stack = []
        f_res = 0
        for i in final_res:
            if i not in marks:
                stack.append(i)
            else:
                num_houmian = stack.pop()
                num_qianmian = stack.pop()
                res = str(num_qianmian + i + num_houmian)
                stack.append(str(eval(res)))
            f_res = stack[-1]
        return f_res


===========完整代码===========

[Python] 纯文本查看 复制代码
from tkinter import *
from tkinter import messagebox, font
from tkinter import Tk, ttk
import tkinter as tk
''

def main():
    root = Tk()
    root.title('简单的四则计算器')
    #root.iconbitmap('i1.ico')
    # 窗体居中
    Width = 600
    Height = 370
    canvas = Canvas(width=Width, height=Height, highlightthickness=0, borderwidth=0)
    canvas.create_rectangle(0, 0, Width, Height, outline='yellow', fill="pink")
    canvas.place(x=0, y=0)
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    alignstr = '%dx%d+%d+%d' % (Width, Height, (screenwidth - Width) / 2, (screenheight - Height) / 2)
    root.geometry(alignstr)

    root.focus_set()
    root.resizable(width=False, height=False)
    # 输入框
    input_label = tk.Entry(canvas, font=font.Font(size=20, weight='bold'), width=20)  # ,  height=1, width=15
    input_label.place(x=10, y=45)
    input_label.focus_set()

    sb = tk.Scrollbar(root)
    sb.pack(side="right", fill="y")

    # 结果保存
    lb = Listbox(canvas, height=14, width=25,font=('微软雅黑',12), yscrollcommand=sb.set)
    lb.place(x=350, y=40)

    sb.config(command=lb.yview)
    def helpme():
        # 说明
        win2=Toplevel(root)
        win2.title('说明文档')
        width = 300
        height = 250
        screenwidth = root.winfo_screenwidth()
        screenheight = root.winfo_screenheight()
        alignstr2 = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        win2.geometry(alignstr2)
        win2.resizable(width=False,height=False)
        win2.focus_set()
        Help=Label(win2,text='可以从键盘输入,可以鼠标点击选择\n\n只支持加减乘除四则运算。\n\n允许使用括号运算符\n\nC 清除显示内容和输入内容\n\nCE 只清除输入内容',  font=('微软雅黑',10))
        Help.place(x=40,y=20)

    def about():
        #关于
        win2 = Toplevel(root)
        win2.title('关于')
        width = 200
        height = 200
        screenwidth = root.winfo_screenwidth()
        screenheight = root.winfo_screenheight()
        alignstr2 = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        win2.geometry(alignstr2)
        win2.resizable(width=False, height=False)
        win2.focus_set()
        Help = Label(win2, text='#lthero\n\n2021年某月某日\n\n喜欢可打赏', font=('微软雅黑',10))
        Help.place(x=50, y=50)

    # 头部菜单
    menu = Menu(root, tearoff=False)
    Cmenu = Menu(menu, tearoff=False)  # 新建菜单,删除顶部虚线
    Cmenu.add_command(label='说明', command=helpme)  # 将内容添加至菜单
    Cmenu.add_separator()
    Cmenu.add_command(label='关于',command=about)
    menu.add_cascade(label='菜单(点我点我)',menu=Cmenu)  # 实例化菜单
    root.config(menu=menu)  # 实例化菜单


    # 退出
    def esc():
        root.quit()

    ex = ttk.Button(canvas, text='毁灭吧赶紧的', command=esc)
    ex.place(x=100, y=300)

    # 公式展示
    gongshi_temp=''
    temp = StringVar()
    temp_res = Label(root, textvariable=temp, font=font.Font(size=16, weight='bold'))
    temp_res.place(x=6, y=8)

    def True_cal(str1):
        stack = []
        final_res = []
        marks = ['+', '-', '*', '/']
        numbers = [str(i) for i in range(0, 10)]
        temp_11 = 0
        count = 0
        for i in str1:
            count += 1
            if i in numbers:
                temp_11 = temp_11 * 10 + int(i)
            if i in marks or count == len(str1):
                final_res.append(str(temp_11))
                temp_11 = 0
                if len(stack) != 0:
                    if i == '*' or i == '/':
                        while stack[-1] in ['*', '/']:
                            final_res.append(stack[-1])
                            stack.pop()
                            if len(stack) == 0:
                                break
                        stack.append(i)
                    if i == '+' or i == '-':
                        while stack[-1] in marks:
                            final_res.append(stack[-1])
                            stack.pop()
                            if len(stack) == 0:
                                break
                        stack.append(i)
                else:
                    if i in marks:
                        stack.append(i)
            if i == '(' or i == '(':
                stack.append(i)
            if i == ')' or i == ')':
                while stack[-1] != '(':
                    final_res.append(stack[-1])
                    stack.pop()
                    if len(stack) == 0:
                        break
                stack.pop()
        for i in range(len(stack)):
            final_res.append(stack.pop())
        stack = []
        f_res = 0
        for i in final_res:
            if i not in marks:
                stack.append(i)
            else:
                num_houmian = stack.pop()
                num_qianmian = stack.pop()
                res = str(num_qianmian + i + num_houmian)
                stack.append(str(eval(res)))
            f_res = stack[-1]
        return f_res

    first_part = ['']
    second_part = ['0']

    second_part_cheng=['1']
    all_part=['']
    def cal():
        try:
            text_ = temp.get()
            str1=text_+input_label.get()
            #print(str1)
            temp.set(str1)
            res = True_cal(str1)
            input_label.insert(INSERT, res)
            # 清空输入,输出结果
            input_label.delete(0, END)
            input_label.insert(END, res)
            # 保存到记录
            lb.insert(END, str1 + '=')
            lb.insert(END, res)
            input_label.focus_set()
            temp.set('')
        except(ZeroDivisionError, SyntaxError):
            messagebox.showerror('!!!', '输入不规范!!!')
            input_label.focus_set()


    # 清除历史记录
    def clear_history():
        lb.delete(0, END)

    the_button = ttk.Button(root, text='历史记录点我清除,内容可直接复制', command=clear_history).place(x=370, y=5)

    flag=[0]
    # 全部按键
    def start():
        # 重复内容
        def input_0():
            if flag[0]==0:
                input_label.delete(0,END)
                flag[0]=1
            if input_label.get()!='':
                input_label.insert(INSERT, '0')
            input_label.focus_set()
        def input_1():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '1')

        def input_2():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '2')

        def input_3():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '3')

        def input_4():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '4')

        def input_5():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '5')

        def input_6():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '6')

        def input_7():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '7')

        def input_8():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '8')

        def input_9():
            if flag[0] == 0:
                input_label.delete(0, END)
                flag[0] = 1
            input_label.insert(INSERT, '9')

        def input_Point():
            input_label.insert(INSERT, '.')


        def fun_1():
            flag[0] = 0
            first_part[0] = second_part[0]
            second_part[0] = input_label.get()
            input_label.delete(0, END)
            str3 = temp.get() + second_part[0]
            get_res = True_cal(str3[0:-1])
            text_ = temp.get()
            temp.set(text_ + second_part[0])
            input_label.insert(END, get_res)
            second_part[0] = get_res
            input_label.focus_set()

        def fun_2():
            flag[0] = 0
            first_part[0] = second_part_cheng[0]
            second_part_cheng[0] = input_label.get()
            input_label.delete(0, END)
            str3 = temp.get() + second_part_cheng[0]
            get_res = True_cal(str3[0:-1])
            text_ = temp.get()
            temp.set(text_ + second_part_cheng[0])
            input_label.insert(END, get_res)
            second_part_cheng[0] = get_res
            input_label.focus_set()
        def input_plus():
            input_label.insert(INSERT, '+')
            fun_1()

        def input_minus(*args):
            input_label.insert(INSERT, '-')
            fun_1()

        def input_mul():
            input_label.insert(INSERT, '*')
            fun_2()

        def input_div():
            input_label.insert(INSERT, '/')
            fun_2()

        def input_equal(*args):
            cal()
            flag[0] = 0


        def input_open():
            text_=temp.get()
            temp.set(text_+'(')

        def input_close():
            input_label.insert(INSERT, ')')

        def input_clear():
            input_label.delete(0, END)

        def input_back():
            cop = str(input_label.get())[0:-1]
            input_label.delete(0, END)
            input_label.insert(INSERT, cop)

        def input_all_clear():
            input_label.delete(0, END)
            first_part[0]=''
            second_part[0]='0'
            temp.set('')

        def input_pai():
            if flag[0]==1:
                input_label.delete(0,END)
                flag[0]=0
            input_label.insert(END,'3.14159')

        def input_e():
            if flag[0]==1:
                input_label.delete(0,END)
                flag[0]=0
                flag[0]=0
            input_label.insert(END,'2.71828')

        def ttt():
            messagebox.showinfo('!!!!','    今天是个好日子\n\n'
                                        'today is a good day!')

        col_0 = 30
        row_0 = 100
        row_1 = 130
        col_1 = 85
        row_2 = 160
        col_2 = 140
        row_3 = 190
        col_3 = 195
        col_4 = 250
        row_4 = 220
        B0 = ttk.Button(root, text='0', command=input_0,  width=6)
        B0.place(x=col_2, y=row_4)

        B1 = ttk.Button(root, text='1', command=input_1,  width=6)
        B1.place(x=col_1, y=row_3)
        B2 = ttk.Button(root, text='2', command=input_2,  width=6)
        B2.place(x=col_2, y=row_3)
        B3 = ttk.Button(root, text='3', command=input_3,  width=6)
        B3.place(x=col_3, y=row_3)
        B4 = ttk.Button(root, text='4', command=input_4,  width=6)
        B4.place(x=col_1, y=row_2)
        B5 = ttk.Button(root, text='5', command=input_5,  width=6)
        B5.place(x=col_2, y=row_2)
        B6 = ttk.Button(root, text='6', command=input_6,  width=6)
        B6.place(x=col_3, y=row_2)
        B7 = ttk.Button(root, text='7', command=input_7,  width=6)
        B7.place(x=col_1, y=row_1)
        B8 = ttk.Button(root, text='8', command=input_8,  width=6)
        B8.place(x=col_2, y=row_1)
        B9 = ttk.Button(root, text='9', command=input_9,  width=6)
        B9.place(x=col_3, y=row_1)
        BPoint = ttk.Button(root, text='.', command=input_Point,  width=6)
        BPoint.place(x=col_3, y=row_4)
        Bplus = ttk.Button(root, text='+', command=input_plus,  width=6)
        Bplus.place(x=col_4, y=row_3)
        Bminus = ttk.Button(root, text='-', command=input_minus,  width=6)
        Bminus.place(x=col_4, y=row_2)
        root.bind('<KeyPress-KP_Subtract>', input_minus)
        Bmul = ttk.Button(root, text='*', command=input_mul,  width=6)
        Bmul.place(x=col_4, y=row_1)
        Bdiv = ttk.Button(root, text='/', command=input_div,  width=6)
        Bdiv.place(x=col_4, y=row_0)
        Bequal = ttk.Button(root, text='=', command=input_equal, width=6)
        Bequal.place(x=col_4, y=row_4)
        root.bind('<Return>',input_equal)
        Bclose = ttk.Button(root, text=')', command=input_close, width=6)
        Bclose.place(x=col_1, y=row_4)
        Bclear = ttk.Button(root, text='CE', command=input_clear, width=6)
        Bclear.place(x=col_1, y=row_0)
        Bback = ttk.Button(root, text='<-', command=input_back, width=6)
        Bback.place(x=col_3, y=row_0)
        Ball_clear = ttk.Button(root, text='C', command=input_all_clear, width=6)
        Ball_clear.place(x=col_2, y=row_0)
        Bopen = ttk.Button(root,text='(', command=input_open, width=6)
        Bopen.place(x=col_0, y=row_4)
        Bt1 = ttk.Button(root, text='π', command=input_pai, width=6)
        Bt1 .place(x=col_0, y=row_0)
        Bt2 = ttk.Button(root, text='e', command=input_e, width=6)
        Bt2.place(x=col_0, y=row_1)
        Bt3 = ttk.Button(root, text='n!', command=ttt, width=6)
        Bt3.place(x=col_0, y=row_2)
        Bt4 = ttk.Button(root, text='', command=ttt, width=6)
        Bt4.place(x=col_0, y=row_3)

    start()
    root.mainloop()

if __name__ == '__main__':
    main()




发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lkocok 发表于 2021-3-25 21:44
收藏学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 17:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表