Here, I have two classes. First one (MedicalDevices.py) has the functions that I wanna use on the second class (tkinter_devices.py).
I am new to python and the help is appreciate it
Issue I am facing: I am trying to enter information of devices to excel sheet, but every time I entered more than one device's information, it only save the last entries that I entered while the tkinter running.
MedicalDevices.py
import datetime
import pandas as pd
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDevices:
# class attributes: to keep truck the number of the objects that been made.
num_of_devices = 0
# initialization/ construction
def __init__(self, name, sn, manufacture, model, supplier, department='In Store', warranty_expire="Expired"):
# object attributes (to make private attribute, add __ before the name
self.name = name
self.sn = sn
self.manufacture = manufacture
self.model = model
self.supplier = supplier
self.department = department
self.warranty_expire = warranty_expire
# increase number of devices made with every initialization
MedicalDevices.num_of_devices = 1
# dunder (double underscore)method
# override function to print string instead of printing the memory address of an object
def __str__(self):
return f"Name: {self.name}\nSerial#: {self.sn}\nManufacture: {self.manufacture}\n" \
f"Model: {self.model}\nSupplier: {self.supplier}\nDepartment: {self.department}\n" \
f"Warranty expire on: {self.warranty_expire}"
def add_new_device(newDevice):
SerA = df["Name"]
SerB = df["Serial"]
SerC = df["Manufacture"]
SerD = df["Model"]
SerE = df["Supplier"]
SerF = df["Department"]
SerG = df["Warranty"]
# this must be Series type to be able to concatenate with DataFrame
A = pd.Series(newDevice.name)
B = pd.Series(newDevice.sn)
C = pd.Series(newDevice.manufacture)
D = pd.Series(newDevice.model)
E = pd.Series(newDevice.supplier)
F = pd.Series(newDevice.department)
G = pd.Series(newDevice.warranty_expire)
SerA = SerA.append(A)
SerB = SerB.append(B)
SerC = SerC.append(C)
SerD = SerD.append(D)
SerE = SerE.append(E)
SerF = SerF.append(F)
SerG = SerG.append(G)
df2 = pd.DataFrame({"Name": SerA,
"Serial": SerB,
"Manufacture": SerC,
"Model": SerD,
"Department": SerE,
"Supplier": SerF,
"Warranty": SerG})
df2.to_excel(f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")
#
# def search_by_sn(self, sn):
# if sn in df.values:
# print("Got it. Here is the device(s) info: \n-------------------------------")
# print(df.loc[df.Serial == sn])
# else:
# print("Not found")
# newInput = input("Do you want to add a new device (yes/ no): ")
# if newInput == "yes":
# self.add_new_device(DC_1)
# else:
# print("Ok")
# To check Warranty
def check_warranty(self):
date = datetime.datetime.strptime(self.warranty_expire, '%Y/%m/%d').date()
if date >= datetime.date.today():
print(self.name " is still in Warranty\n" "Warranty expires on " self.warranty_expire)
else:
print("Attention, Warranty expired on " self.warranty_expire)
tkinter_devices.py
import tkinter as tk
from tkinter import ttk
import pandas as pd
from MedicalDevices import MedicalDevices
font1 = ("Verdana", 12)
font2 = ("Verdana", 10)
pageSize = "500x300"
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDeviceApp(tk.Tk):
# args=argument (any number of argument (unlimited))
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Medical Devices Data")
tk.Tk.wm_geometry(self, pageSize) # (width x height)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, AddDevice, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Start Page", font=font1)
label.grid(row=0, column=5, sticky="nsew")
bot1 = ttk.Button(self, text="Add a new device",
command=lambda: controller.show_frame(AddDevice))
bot1.grid(row=1, column=0, sticky="nsew", columnspan=1, ipadx=5)
bot2 = ttk.Button(self, text="Page Two",
command=lambda: controller.show_frame(PageTwo))
bot2.grid(row=2, column=0, sticky="nsew")
bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
bot_exit.grid(row=3, column=0, sticky="nsew")
class AddDevice(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# Labels
label1 = ttk.Label(self, text="Enter a new device information", font=font1)
label1.grid(row=0, column=1)
label2 = ttk.Label(self, text="Required information with *")
label2.grid(row=1, column=1, pady=5)
label_name = ttk.Label(self, text="Device Name:", font=font2)
label_name.grid(row=2, column=0, sticky="w")
label_serial = ttk.Label(self, text="Serial Number:", font=font2)
label_serial.grid(row=3, column=0, sticky="w")
label_manf = ttk.Label(self, text="Manufacture:", font=font2)
label_manf.grid(row=4, column=0, sticky="w")
label_model = ttk.Label(self, text="Model:", font=font2)
label_model.grid(row=5, column=0, padx=2, sticky="w")
label_supplier = ttk.Label(self, text="Supplier:", font=font2)
label_supplier.grid(row=6, column=0, padx=2, sticky="w")
label_depart = ttk.Label(self, text="Department:", font=font2)
label_depart.grid(row=7, column=0, padx=2, sticky="w")
label_expire = ttk.Label(self, text="Expire Date:", font=font2)
label_expire.grid(row=8, column=0, padx=2, sticky="w")
# Entries
self.entry_name = ttk.Entry(self)
self.entry_name.grid(row=2, column=1, ipadx=20, pady=5)
self.entry_serial = ttk.Entry(self)
self.entry_serial.grid(row=3, column=1, ipadx=20, pady=5)
self.entry_manf = ttk.Entry(self)
self.entry_manf.grid(row=4, column=1, ipadx=20, pady=5)
self.entry_model = ttk.Entry(self)
self.entry_model.grid(row=5, column=1, ipadx=20, pady=5)
self.entry_supplier = ttk.Entry(self)
self.entry_supplier.grid(row=6, column=1, ipadx=20, pady=5)
self.entry_depart = ttk.Entry(self)
self.entry_depart.grid(row=7, column=1, ipadx=20, pady=5)
self.entry_expire = ttk.Entry(self)
self.entry_expire.grid(row=8, column=1, ipadx=20, pady=5)
# Bottoms
self.bot_save = ttk.Button(self, text="Save", command=self.save)
self.bot_save.grid(row=2, column=2, ipadx=20, pady=5, columnspan=1)
self.bot_clear = ttk.Button(self, text="Clear", command=self.delete)
self.bot_clear.grid(row=4, column=2, ipadx=20, pady=2, columnspan=1)
self.bot_back = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
self.bot_back.grid(row=6, column=2, ipadx=20)
self.bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
self.bot_exit.grid(row=8, column=2, ipadx=25)
def delete(self):
self.entry_name.delete(0, 'end')
self.entry_serial.delete(0, 'end')
self.entry_manf.delete(0, 'end')
self.entry_model.delete(0, 'end')
self.entry_supplier.delete(0, 'end')
self.entry_depart.delete(0, 'end')
self.entry_expire.delete(0, 'end')
def save(self):
if int(self.entry_serial.get()) in df.values:
print("found it ")
self.delete()
else:
device = MedicalDevices(self.entry_name.get(), self.entry_serial.get(), self.entry_manf.get(),
self.entry_model.get(), self.entry_supplier.get(), self.entry_depart.get(),
self.entry_expire.get())
MedicalDevices.add_new_device(device)
self.delete()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Page Tow", font=font1)
label.pack(pady=10, padx=10)
bot1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
bot1.pack()
app = MedicalDeviceApp()
app.mainloop()
CodePudding user response:
Inside add_new_device()
, you copy serise from the global df
and append the new record, then create a new dataframe df2
with the new series and save to file. However you forget to update the global df
so that it does not include the new device. Next time another new device is to be added, you copy series from the global df
again which does not have the previously added device, append the current new device and save to file. The file will then be overwritten without the previously added device.
To fix that you need to update the global df
instead of creating a new dataframe df2
. Also suggest to move the global df
into MedicalDevices
as a class variable:
class MedicalDevices:
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
...
def add_new_device(newDevice):
# update class dataframe `df` instead of creating new one
MedicalDevices.df = MedicalDevices.df.append({
"Name": newDevice.name,
"Serial": newDevice.sn,
"Manufacture": newDevice.manufacture,
"Model": newDevice.model,
"Supplier": newDevice.supplier,
"Department": newDevice.department,
"Warranty": newDevice.warranty_expire
}, ignore_index=True)
# export to file
MedicalDevices.df.to_excel(MedicalDevices.f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")