首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >员工管理器Windows应用程序-Python

员工管理器Windows应用程序-Python
EN

Code Review用户
提问于 2021-09-29 15:50:13
回答 2查看 88关注 0票数 3

下面是我的应用程序员工经理的完整代码。该应用程序确实允许基本的员工管理,比如添加、删除或更改员工的详细信息。因为这是我的第一个GUI应用程序之一,我是自学的(我已经学习了大约6个月,每天工作几个小时),我想看看你们对我的代码的看法。想听听别人的意见。任何关于改进(我的工作和代码)的建议都是欢迎的。如果我受到批评就不会生气。在这里学习和提高。

代码语言:javascript
复制
from json.decoder import JSONDecodeError
import tkinter as tk
from tkinter import StringVar, Toplevel, ttk
import os, json
import copy


class Staff_Manager(tk.Tk):
    def __init__(self) -> None:
        super().__init__()
        self.check_save_file()
        self.geometry("1520x600")
        self.title("Staff Manager")
        self.iconbitmap("icon.ico")
        

        self.buttons()
        self.data_view()
        self.update
        self.delete
        self.is_retired


    # check if data save file exists and if not create one.
    def check_save_file(self):
        current_path = os.path.dirname(__file__)
        json_file = f'{current_path}\\emp_data.json'
        if os.path.isfile(json_file) == True and os.stat(json_file).st_size != 0:
            pass
        else:
            with open(json_file, 'w+') as f:
                data = {"people": []}
                json.dump(data, f)
    

    def buttons(self):
        # managing buttons, main window
        add = ttk.Button(self, text= 'Add', command= Add_New_Emp)
        add.place(x= 10, y= 10, width= 75)
        
        amend = ttk.Button(self, text= 'Amend', command= self.amend)
        amend.place(x= 10, y= 45, width= 75)

        refresh = ttk.Button(self, text= 'Refresh', command= self.update)
        refresh.place(x= 10, y= 80, width= 75)
        
        retire = ttk.Button(self, text= 'Retire', command= self.is_retired)
        retire.place(x= 10, y= 135, width= 75, height= 40)
        
        remove = ttk.Button(self, text= 'Remove', command= self.delete)
        remove.place(x= 10, y= 230, width= 75, height= 40)

        exit_button = ttk.Button(self, text= 'EXIT', command= self.destroy)
        exit_button.place(x= 10, y= 538, width= 75, height= 40)        


    def data_view(self):
        #create columns for tree view
        columns = ('#1', '#2', '#3', '#4', '#5', '#6', '#7')
        self.view_panel = ttk.Treeview(self, columns= columns, show= 'headings', height= 27)
        self.view_panel.place(x= 90, y= 10)

        # headings
        self.view_panel.heading('#1', text= 'Name')
        self.view_panel.heading('#2', text= 'Surname')
        self.view_panel.heading('#3', text= 'Position')
        self.view_panel.heading('#4', text= 'DoB')
        self.view_panel.heading('#5', text= 'Start Date')
        self.view_panel.heading('#6', text= 'End Date')
        self.view_panel.heading('#7', text= 'Retired?')

        # set up the scrollbar
        scrollbar = ttk.Scrollbar(self, orient= tk.VERTICAL, command= self.view_panel.yview)
        self.view_panel.configure(yscrollcommand= scrollbar.set)
        scrollbar.place(x= 1495, y= 10, height= 575)

        # insert data
        with open('emp_data.json', 'r') as f:
            empty_file = False
            try:    
                data = json.load(f)
            except JSONDecodeError:
                empty_file = True
                pass
            employees = []
            if empty_file == False:
                
                for item in data["people"]:
                    name = item["name"]
                    surname = item["surname"]
                    position = item["position"]
                    dob = item["dob"]
                    start = item["start"]
                    end = item["end"]
                    retired = item["retired"]

                    employees.append((name, surname, position, dob, start, end, retired))

            # insert all the data to the view panel
            for emp in employees:
                self.view_panel.insert('', tk.END, values= emp)


    # update information on the view panel
    def update(self):
        self.data_view()

    # amend emp data
    def amend(self):
        amend_win = tk.Tk()
        amend_win.geometry('350x250')
        amend_win.title('Amend Employee Details')
        amend_win.iconbitmap('icon.ico')
        
        # cancel button
        def is_cancel():
            amend_win.destroy()
        
        # change button
        def is_amended(to_change, new_personal_data):
            current_item = self.view_panel.focus()
            info = self.view_panel.item(current_item)
            details = info["values"]

            to_remove = {
                "name": str(details[0]),
                "surname": str(details[1]),
                "position": str(details[2]),
                "dob": str(details[3]),
                "start": str(details[4]),
                "end": str(details[5]),
                "retired": str(details[6])
            }
            to_remove = copy.deepcopy(to_remove)

            details_dict = {
                "name": str(details[0]),
                "surname": str(details[1]),
                "position": str(details[2]),
                "dob": str(details[3]),
                "start": str(details[4]),
                "end": str(details[5]),
                "retired": str(details[6])
            }
            
            
            for key, value in details_dict.items():
                if key == to_change:
                    details_dict[f"{to_change}"] = new_personal_data
            
            with open('emp_data.json', 'r') as f:
                data = json.load(f)

                new_data = {
                    "people": []
                }

                for emp_dict in data["people"]:
                    if to_remove != emp_dict:
                        new_data["people"].append(emp_dict)

                new_data["people"].append(details_dict)
                
                with open('emp_data.json', 'w') as f:
                    json.dump(new_data, f, indent= 4)

            amend_win.destroy()
        
        # check if data is not empty, if is: n/a
        def is_empty(data):
            if len(data) == 0:
                return 'n/a'
            else:
                return data


        main_choice_lbl = ttk.Label(amend_win, text= 'What would you like to change?', font= ('Arial', 12))
        main_choice_lbl.place(x= 10, y= 10)

        self.data_options = ('name', 'surname', 'position', 'dob', 'start', 'end')
        self.choice = StringVar()
        options = ttk.OptionMenu(amend_win,
                                self.choice,
                                self.data_options[0],
                                *self.data_options)
        options.place(x= 10, y= 47)
        options.config(width= 15)


        new_emp_data = ttk.Label(amend_win, text= 'New data:', font= ('Arial', 12))
        new_emp_data.place(x= 10, y= 90)


        main_entry = ttk.Entry(amend_win, justify= 'right')
        main_entry.place(x= 10, y= 130)


        ok_button = ttk.Button(amend_win, text= 'CHANGE', command= lambda: is_amended(self.choice.get(), is_empty(main_entry.get())))
        ok_button.place(x= 60, y= 200)

        cancel_button = ttk.Button(amend_win, text= 'CANCEL', command= is_cancel)
        cancel_button.place(x= 150, y= 200)
            

    def delete(self):
        # get the "clicked" emp
        current_item = self.view_panel.focus()
        # get the info of "clicked" emp : dict
        info = self.view_panel.item(current_item)
        # get details of "clicked" emp, "values" are stored emp data : list
        details = info["values"]
        # set the data to json format (need to convert some int to str as program is creating all data as strings)
        details_dict = {
            "name": str(details[0]),
            "surname": str(details[1]),
            "position": str(details[2]),
            "dob": str(details[3]),
            "start": str(details[4]),
            "end": str(details[5]),
            "retired": str(details[6])
        }

        with open('emp_data.json', 'r') as f:
            data = json.load(f)
            
            new_data = {
                "people": []
            }

            for emp_dict in data["people"]:
                if details_dict != emp_dict:
                    new_data['people'].append(emp_dict)

            with open('emp_data.json', 'w') as f:
                json.dump(new_data, f, indent= 4)
        

    def is_retired(self):
        retired_win = tk.Tk()
        retired_win.geometry('280x130')

        # cancel button
        def is_cancel():
            retired_win.destroy()


        def is_ok():
            current_item = self.view_panel.focus()
            info = self.view_panel.item(current_item)
            details = info["values"]

            to_remove = {
                "name": str(details[0]),
                "surname": str(details[1]),
                "position": str(details[2]),
                "dob": str(details[3]),
                "start": str(details[4]),
                "end": str(details[5]),
                "retired": str(details[6])
            }
            to_remove = copy.deepcopy(to_remove)

            details_dict = {
                "name": str(details[0]),
                "surname": str(details[1]),
                "position": str(details[2]),
                "dob": str(details[3]),
                "start": str(details[4]),
                "end": str(details[5]),
                "retired": str(details[6])
            }
            
            
            # for key, value in details_dict.items():
            details_dict["retired"] = "Yes"
            
            with open('emp_data.json', 'r') as f:
                data = json.load(f)

                new_data = {
                    "people": []
                }

                for emp_dict in data["people"]:
                    if to_remove != emp_dict:
                        new_data["people"].append(emp_dict)

                new_data["people"].append(details_dict)
                
                with open('emp_data.json', 'w') as f:
                    json.dump(new_data, f, indent= 4)

            retired_win.destroy()

        ret_lbl = ttk.Label(retired_win, text= "Are you sure you want to RETIRE your employee?")
        ret_lbl.place(x= 10, y= 20)

        ok_button = ttk.Button(retired_win, text= 'RETIRE', command= is_ok)
        ok_button.place(x= 40, y= 60)

        cancel_button = ttk.Button(retired_win, text= 'CANCEL', command= is_cancel)
        cancel_button.place(x= 150, y= 60)
        


class Add_New_Emp(Toplevel):
    def __init__(self) -> None:
        super().__init__()

        self.geometry('380x400')
        self.title('Employee Data')
        self.iconbitmap('icon.ico')

        self.labels()
        self.data_entry()


    # set labels
    def labels(self):
        name_lbl = ttk.Label(self, text= 'Name:', font= ('Arial', 12))
        name_lbl.place(x= 10, y= 10)
        
        surname_lbl = ttk.Label(self, text= 'Surname:', font= ('Arial', 12))
        surname_lbl.place(x= 10, y= 50)
        
        position_lbl = ttk.Label(self, text= 'Position:', font= ('Arial', 12))
        position_lbl.place(x= 10, y= 90)
        
        dob_lbl = ttk.Label(self, text= 'Date of Birth:', font= ('Arial', 12))
        dob_lbl.place(x= 10, y= 130)
        
        start_lbl = ttk.Label(self, text= 'Start Date:', font= ('Arial', 12))
        start_lbl.place(x= 10, y= 170)
        
        end_lbl = ttk.Label(self, text= 'End Date:', font= ('Arial', 12))
        end_lbl.place(x= 10, y= 210)
        
        retired_lbl = ttk.Label(self, text= 'Retired?', font= ('Arial', 12))
        retired_lbl.place(x= 10, y= 250)


    # set data entry points
    def data_entry(self):

        def is_empty(data):
            if len(data) == 0:
                return 'n/a'
            else:
                return data

        # accepting details, pressing ok button
        def is_ok():
            # get all the data
            name = is_empty(name_ent.get())
            surname = is_empty(surname_ent.get())
            position = is_empty(position_ent.get())
            dob = is_empty(dob_ent.get())
            start = is_empty(start_ent.get())
            end = is_empty(end_ent.get())
            retired = retired_var.get()
            # append row to the employee data file
            with open('emp_data.json', 'r+') as f:
                data = json.load(f)
           
                new_emp = {
                    "name": name,
                    "surname": surname,
                    "position": position,
                    "dob": dob,
                    "start": start,
                    "end": end,
                    "retired": retired
                }
            
            data["people"].append(new_emp)
            with open('emp_data.json', 'w') as f:    
                json.dump(data, f, indent= 4)
            
            self.destroy()
        
        # cancelation of adding new emp
        def is_cancel():
            self.destroy()


        name_ent = ttk.Entry(self, justify= 'right')
        name_ent.place(x= 215, y= 10)
        
        surname_ent = ttk.Entry(self, justify= 'right')
        surname_ent.place(x= 215, y= 50)
        
        position_ent = ttk.Entry(self, justify= 'right')
        position_ent.place(x= 215, y= 90)
        
        dob_ent = ttk.Entry(self, justify= 'right')
        dob_ent.place(x= 215, y= 130)
        
        start_ent = ttk.Entry(self, justify= 'right')
        start_ent.place(x= 215, y= 170)
        
        end_ent = ttk.Entry(self, justify= 'right')
        end_ent.place(x= 215, y= 210)

        retired_var = StringVar(value= 'No')
        retired_chk = ttk.Checkbutton(
                                        self,
                                        text= 'Yes',
                                        onvalue= 'Yes',
                                        offvalue= 'No',
                                        variable= retired_var)
        retired_chk.place(x= 215, y= 250)


        ok_button = ttk.Button(self, text= 'ADD', command= is_ok)
        ok_button.place(x= 100, y= 350)

        cancel_button = ttk.Button(self, text= 'CANCEL', command= is_cancel)
        cancel_button.place(x= 200, y= 350)

        

if __name__ == "__main__":
    Staff_Manager().mainloop()
EN

回答 2

Code Review用户

发布于 2021-09-29 19:25:58

PEP 8

在以下几个方面,您偏离了Python代码样式指南

  • 关键字参数不应该在等号周围有空格。例如,add = ttk.Button(self,text=' add ',command=Add_New_Emp)应该添加= ttk.Button(self,text= 'Add',command=Add_New_Emp)
  • 类名应该是CapitalizedWords,而不是Capitalized_Words_With_Underscores。所以Staff_ManagerAdd_New_Emp应该是StaffManagerAddNewEmp

类型提示

我所看到的唯一使用类型提示的地方是def __init__(self) -> None:。显然,您刚刚开始使用它们,但是您需要更多地使用它们,并通过检查器(mypypylint,.)运行您的and。

死码

代码语言:javascript
复制
        self.buttons()
        self.data_view()
        self.update
        self.delete
        self.is_retired

最后三个“声明”什么也不做,应该删除。

不良命名

名为is_xxx()的函数类似于不修改任何状态并返回TrueFalse结果的函数。您的函数更改程序的状态,而不返回任何内容。找到更好的名字,比如do_cancel()perform_amend

重用组件

每次调用.data_view()时,都会创建一个新的ttk.Treeview,并将其放在前面的位置上。

创建一次ttk.Treeview,并在信息更改时刷新其内容。

PathLib

os.path.isfile(file)os.stat(file)是老式的函数.您应该开始使用更新的pathlib。( Eg)

代码语言:javascript
复制
from pathlib import Path

...
    json_file = Path(__file__).parent / 'emp_data.json'
    if json_file.is_file() and json_file.stat().st_size != 0:
        ...

一致文件名

有时您使用f'{current_path}\\emp_data.json'来指定数据库文件,而另一些时候则使用with open('emp_data.json', 'w') as f:,这可能会写入一个完全不同的位置!

数据访问对象

我看到了大量重复的代码,用于读取和写入emp_data.json数据库。您应该创建并使用数据访问对象来管理数据库。

例如:

代码语言:javascript
复制
class EmployeeDB:

    def __init__(self, json_file: Path) -> None:
        self._file = json_file

        # Create an empty database, if file doesn't exist or is empty
        if not json_file.is_file() or json_file.stat().st_size == 0:
            self.save([])

    def load(self) -> list:
        employees = []
        with open(self._file, 'r') as f:
            data = json.load(f)
            for item in data['people']:
                ...
        return employees

    def save(self, employees: list) -> None:
        with open(self._file, 'w') as f:
            data = {"people": employees}
            json.dump(data, f, indent=4)

class StaffManager(tk.Tk):
    def __init__(self, database: EmployeeDB) -> None:
        self._db = database
        ...
    ...
...

if __name__ == '__main__':
    db = EmployeeDB(Path('emp_data.json'))
    StaffManager(db).mainloop()

Dataclass

每个员工都是一本字典。

您应该创建一个实际的Employee 数据集来保存信息。由此,您可以添加其他方法,比如.age(),它可以返回基于.dob的计算值。

代码语言:javascript
复制
from dataclasses import dataclass

@dataclass
class Employee:
    name: str
    surname: str
    position: str
    dob: str
    start: str
    end: str
    retired: str

EmployeeDB现在可以使用list[Employee]作为类型提示,而不是普通的list

我还会做更多的改变,但这是一个好的开始。我期待着审查下一次修订。

票数 1
EN

Code Review用户

发布于 2021-10-04 20:58:05

不确定我是否应该在这篇文章中创建一个新的帖子或答案。这是我的员工经理应用程序的修订版。

改进:

  • 类名
  • 函数名
  • 输入提示(是的,以前我以为我只需要做int,str等)。
  • PeP 8(一直在学习和改进这个)
  • 删除死代码
  • 创建数据访问对象(谢谢,这是一个绝妙的想法)
  • 文件名(在一个地方指定,必须始终相同)
  • 尝试更多地重用组件(如果有任何更改要显示,视图面板将被关闭并创建)

尚未发生:

  • Pathlib,是的,我以前从未使用过Pathlib,但仍然使用os,目前也在学习这个模块。
  • Dataclass,这个版本还没做过。实际上,现在计划创建一个具有更多功能的“适当”应用程序,我将在其中使用dataclass,因为这是一个很棒的想法,尽管这个应用程序非常简单。

如有任何建议和意见,将不胜感激。发生了一些小的变化,多亏了AJNeufeld,290个代码行减少到225行,而程序做的事情完全一样,所有的事情都像它想象的那样工作。该数据文件仍然以人类可读的形式存在(尽管将数据存储为列表并在应用程序中正确显示它们会更容易)。

代码语言:javascript
复制
import json
from os import path
import tkinter as tk
from tkinter import StringVar, ttk
import os
from tkinter.constants import CENTER, NO
from ttkbootstrap import Style


class Window(tk.Tk):
    def __init__(self, database: object) -> None:
        super().__init__()
        self._db = database

        self.geometry('1000x500')
        self.title('Staff Manager')
        self.iconbitmap('icon.ico')
        self.buttons()
        self.data_view()
        
        # set theme for the app (from ttkbootstrap)
        style = Style(theme='darkly')
        self = style.master


    def buttons(self) -> None:
        # managing buttons, main window
        add = ttk.Button(self, text='Add', command=self.add_new_emp)
        add.place(x=10, y=10, width=75, height=40)

        amend = ttk.Button(self, text='Amend', command=self.amend_emp)
        amend.place(x=10, y=55, width=75, height=40)

        retire = ttk.Button(self, text='Retire', command=self.retire_emp)
        retire.place(x=10, y=100, width=75, height=40)

        remove = ttk.Button(self, text='Remove', command=self.delete_emp)
        remove.place(x=10, y=180, width=75, height=40)

        exit_button = ttk.Button(self, text= 'EXIT', command=self.destroy)
        exit_button.place(x=10, y=450, width=75, height=40)

    
    def data_view(self) -> None:
        # create columns
        columns = ('#1', '#2', '#3', '#4', '#5', '#6', '#7')
        self.view_panel = ttk.Treeview(self, columns=columns, show='headings', height=27, selectmode='browse')
        self.view_panel.place(x=90, y=10, width=890, height=480)

        # headings
        self.view_panel.heading('#1', text='Name')
        self.view_panel.heading('#2', text='Surname')
        self.view_panel.heading('#3', text='Position')
        self.view_panel.heading('#4', text='DoB')
        self.view_panel.heading('#5', text='Start Date')
        self.view_panel.heading('#6', text='End Date')
        self.view_panel.heading('#7', text='Retired?')
        
        # set colums properties
        self.view_panel.column('#1', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#2', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#3', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#4', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#5', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#6', anchor=CENTER, stretch=NO, width=135)
        self.view_panel.column('#7', anchor=CENTER, stretch=NO, width=80)
        
        # set scrollbal for view panel
        scrollbar = ttk.Scrollbar(self, orient= tk.VERTICAL, command= self.view_panel.yview)
        self.view_panel.configure(yscrollcommand=scrollbar.set)
        scrollbar.place(x=980, y=10, width=20, height=480)

        for emp in EmployeeDatabase.load(self._db):
            self.view_panel.insert('', tk.END, values=emp)


    def refresh_view_panel(self) -> None:
        self.view_panel.destroy()
        self.data_view()


    def add_new_emp(self) -> None:
        new_emp_win = tk.Toplevel(self)
        new_emp_win.geometry('380x400')
        new_emp_win.title('Add New Employee')
        new_emp_win.iconbitmap('icon.ico')


        def check_empty_entry(data: str) -> str:
            if len(data) == 0:
                return 'n/a'
            else:
                return data



        def accept_new_emp() -> None:
            # get all the data
            name = check_empty_entry(name_ent.get())
            surname = check_empty_entry(surname_ent.get())
            position = check_empty_entry(position_ent.get())
            dob = check_empty_entry(dob_ent.get())
            start = check_empty_entry(start_ent.get())
            end = check_empty_entry(end_ent.get())
            retired = retired_var.get()

            new_emp = [name, surname, position, dob, start, end, retired]
            EmployeeDatabase.save(self._db, employees=new_emp)
            
            new_emp_win.destroy()
            self.refresh_view_panel()
            

        # set labels for Add New Emp window
        name_lbl = ttk.Label(new_emp_win, text='Name:', font=('Arial', 12))
        name_lbl.place(x=10, y=10)

        surname_lbl = ttk.Label(new_emp_win, text='Surname:', font=('Arial', 12))
        surname_lbl.place(x=10, y=50)

        position_lbl = ttk.Label(new_emp_win, text='Position:', font=('Arial', 12))
        position_lbl.place(x=10, y=90)

        dob_lbl = ttk.Label(new_emp_win, text='Date of Birth:', font=('Arial', 12))
        dob_lbl.place(x=10, y=130)

        start_lbl = ttk.Label(new_emp_win, text='Start Date:', font=('Arial', 12))
        start_lbl.place(x=10, y=170)

        end_lbl = ttk.Label(new_emp_win, text='End Date:', font=('Arial', 12))
        end_lbl.place(x=10, y=210)

        retired_lbl = ttk.Label(new_emp_win, text='Retired?', font=('Arial', 12))
        retired_lbl.place(x=10, y=250)

        # set entry points for data
        name_ent = ttk.Entry(new_emp_win, justify='right')
        name_ent.place(x=215, y=10)
        
        surname_ent = ttk.Entry(new_emp_win, justify='right')
        surname_ent.place(x=215, y=50)
        
        position_ent = ttk.Entry(new_emp_win, justify='right')
        position_ent.place(x=215, y=90)
        
        dob_ent = ttk.Entry(new_emp_win, justify='right')
        dob_ent.place(x=215, y=130)
        
        start_ent = ttk.Entry(new_emp_win, justify='right')
        start_ent.place(x=215, y=170)
        
        end_ent = ttk.Entry(new_emp_win, justify='right')
        end_ent.place(x=215, y=210)

        retired_var = StringVar(value='No')
        retired_chk = ttk.Checkbutton(
                                        new_emp_win,
                                        text='Yes',
                                        onvalue='Yes',
                                        offvalue='No',
                                        variable=retired_var)
        retired_chk.place(x=215, y=250)


        ok_button = ttk.Button(new_emp_win, text='ADD', command=accept_new_emp)
        ok_button.place(x=100, y=350)

        cancel_button = ttk.Button(new_emp_win, text='CANCEL', command=new_emp_win.destroy)
        cancel_button.place(x=200, y=350)


    def delete_emp(self) -> None:
        # get "clicked" emp
        current_emp = self.view_panel.focus()
        emp_info = self.view_panel.item(current_emp)
        emp_details = emp_info["values"]
        # need it as tuple for 'for loop' comparison
        emp_details = tuple(emp_details)

        # delete emp
        new_data = []
        for employee in EmployeeDatabase.load(self._db):
            if employee != emp_details:
                new_data.append(employee)

        EmployeeDatabase.create_new(self._db, [])
        
        for emp in new_data:
            EmployeeDatabase.save(self._db, emp)
        # update view panel
        self.refresh_view_panel()


    def change_details(self, change_detail_index: int, new_detail: str) -> None:
        # get 'clicked' emp
        current_emp = self.view_panel.focus()
        emp_info = self.view_panel.item(current_emp)
        details = emp_info["values"]
        # need it as tuple for 'for loop' comparison
        details_tup = tuple(details)

        emp_to_change = details

        # copy rest of emps
        new_data = []
        for employee in EmployeeDatabase.load(self._db):
            if employee != details_tup:
                new_data.append(employee)

        # append emp with changed detail
        details[change_detail_index] = new_detail
        new_data.append(details)

        EmployeeDatabase.create_new(self._db, [])
        # write to database
        for emp in new_data:
            EmployeeDatabase.save(self._db, emp)
            
        self.refresh_view_panel()



    def amend_emp(self) -> None:
        amend_win = tk.Toplevel()
        amend_win.geometry('250x250')
        amend_win.title('Amend Employee Details')
        amend_win.iconbitmap('icon.ico')

        
        # check if data is not empty, if is: n/a
        def is_empty(data: str) -> str:
            if len(data) == 0:
                return 'n/a'
            else:
                return data

    
        main_choice_lbl = ttk.Label(amend_win, text='What would you like to change?', font=('Arial', 12))
        main_choice_lbl.place(x=10, y=10)

        self.data_options = ('Name', 'Surname', 'Position', 'DoB', 'Start', 'End')
        self.choice = StringVar()
        options = ttk.OptionMenu(amend_win,
                                self.choice,
                                self.data_options[0],
                                *self.data_options)
        options.place(x=10, y=47)
        options.config(width=15)

        new_emp_data = ttk.Label(amend_win, text='New data:', font=('Arial', 12))
        new_emp_data.place(x=10, y=90)


        main_entry = ttk.Entry(amend_win, justify='right')
        main_entry.place(x=10, y=130)


        ok_button = ttk.Button(amend_win, text='CHANGE', command=lambda: [self.change_details(self.data_options.index(self.choice.get()), is_empty(main_entry.get())), amend_win.destroy()])
        ok_button.place(x=60, y=200)

        cancel_button = ttk.Button(amend_win, text='CANCEL', command=amend_win.destroy)
        cancel_button.place(x=150, y=200)


    def retire_emp(self) -> None:
        retired_win = tk.Toplevel()
        retired_win.geometry('280x130')

        ret_lbl = ttk.Label(retired_win, text="Are you sure you want to RETIRE your employee?")
        ret_lbl.place(x=10, y=20)
        
        ok_button = ttk.Button(retired_win, text='RETIRE', command=lambda: [self.change_details(6, "Yes"), retired_win.destroy()])
        ok_button.place(x=40, y=60)

        cancel_button = ttk.Button(retired_win, text='CANCEL', command=retired_win.destroy)
        cancel_button.place(x=150, y=60)

class EmployeeDatabase:
    def __init__(self, json_file: str) -> None:
        self._file = json_file
        

        if os.path.isfile(json_file) == True and os.stat(json_file).st_size != 0:
            pass
        else:
            self.create_new([])


    def load(self) -> list[str]:
        employees: list[str] = []
        with open(self._file, 'r') as f:
            data = json.load(f)
            for item in data["people"]:
                name: str = item["name"]
                surname: str = item["surname"]
                position: str = item["position"]
                dob: str = item["dob"]
                start: str = item["start"]
                end: str = item["end"]
                retired: str = item["retired"]
                
                employees.append((name, surname, position, dob, start, end, retired))
        return employees
    
    
    def create_new(self, employees: list) -> None:
        with open(self._file, 'w') as f:
            data = {"people": employees}
            json.dump(data, f, indent=4)


    def save(self, employees: list[str]) -> None:
        new_emp = {
                    "name": employees[0],
                    "surname": employees[1],
                    "position": employees[2],
                    "dob": employees[3],
                    "start": employees[4],
                    "end": employees[5],
                    "retired": employees[6]
                }
        with open(self._file, 'r') as f:
            data = json.load(f)
            data["people"].append(new_emp)
        with open(self._file, 'w') as f:
            json.dump(data, f, indent=4)


if __name__ == '__main__':
    path = f'{os.path.dirname(__file__)}\\emp_db.json'
    db = EmployeeDatabase(path)
    Window(database= db).mainloop()
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/268508

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档