There are no explanations provided here because no new concepts are introduced. It is simply all of the concepts previously introduced put together in a single application that contains both procedural and object oriented programming
The application allows the user to enter data into a database, modify individual records or delete them. The data can also be browsed sequentially.
"""
The short section below contains the imported libraries required for
for creating a GUI interface and processing a database
"""
import tkinter as tk
from tkinter import *
import sqlite3
"""
This class contains all of the data and methods required for simple
data processing for an employee
"""
class Employee:
__strIRD=""
__strName=""
__floatHours=0.0
__floatRate=0.0
__floatGross=0.0
__floatTax=0.0
__floatNet=0.0
__blnValidData=False
def __init__(self, ird, nme, hrs, rt):
if hrs >= 5 and hrs <= 60 and rt >=20 and rt <= 80:
self.__strIRD = ird
self.__strName = nme
self.__floatHours = hrs
self.__floatRate = rt
self.__blnValidData = True
self.__calculate()
def irdValue(self):
if self.__blnValidData:
return self.__strIRD
else:
return ""
def nameValue(self):
if self.__blnValidData:
return(self.__strName)
else:
return ""
def hoursValue(self):
if self.__blnValidData:
return self.__floatHours
else:
return -1
def rateValue(self):
if self.__blnValidData:
return self.__floatRate
else:
return -1
def grossValue(self):
if self.__blnValidData:
return self.__floatGross
else:
return -1
def taxValue(self):
if self.__blnValidData:
return self.__floatTax
return -1
def netValue(self):
if self.__blnValidData:
return self.__floatNet
else:
return -1
def __calculate(self):
self.__floatGross=self.__floatHours*self.__floatRate
self.__floatTax=self.__floatGross*0.25
self.__floatNet=self.__floatGross-self.__floatTax
def toString(self):
if self.__blnValidData:
strOutput = "IRD is " + self.__strIRD + "\n"
strOutput += "Name is " + self.__strName + "\n"
strOutput += "Hours worked is " + str(self.__floatHours) + "\n"
strOutput += "Hourly rate is " + str(self.__floatRate) + "\n"
strOutput += "Gross is " + str(self.__floatGross) + "\n"
strOutput += "Tax is " + str(self.__floatTax) + "\n"
strOutput += "Net is " + str(self.__floatNet) + "\n"
else:
strOutput = "Invalid data supplied to either hours or rate"
return strOutput
"""
This class contains the data members and the code required for opening
a database and reading, modifying and deleting its records
"""
class dBase():
__lstWorkers=[]
__position=int(-1)
__fileOpen=False
__fb=""
def __init__(self):
connection =sqlite3.connect("Workers.db")
cursor=connection.cursor()
cursor.execute("SELECT * from workers")
result=cursor.fetchall()
for rec in result:
emplIRD, emplname,hours,rate,gross,tax,net = rec
newWorker = Employee(emplIRD,emplname,hours,rate)
self.__lstWorkers.append(newWorker)
rec=None
self.__fileOpen=True
self.__fb = "Database contains " +str(len(self.__lstWorkers))+" records"
def payFirst(self):
if self.__fileOpen==True:
self.__position=0
return self.__lstWorkers[self.__position]
def payNext(self):
if self.__fileOpen==True:
self.__position+=1
if self.__position == len(self.__lstWorkers):
self.__position=0
return self.__lstWorkers[self.__position]
def payPrevious(self):
if self.__fileOpen==True:
self.__position-=1
if self.__position == -1:
self.__position=len(self.__lstWorkers)-1
return self.__lstWorkers[self.__position]
def payLast(self):
if self.__fileOpen==True:
self.__position = len(self.__lstWorkers)-1
return self.__lstWorkers[self.__position]
def newRecord(self, PIRD, PName, Hours,Rate):
if self.__fileOpen==True:
newWorker = Employee(PIRD, PName, Hours,Rate)
self.__lstWorkers.append(newWorker)
self.__saveList()
self.__fb = "Record for "+PIRD+", "+PName+" has been added"
def changeData(self,PIRD, PName, Hours,Rate):
if self.__fileOpen==True:
newWorker = Employee(PIRD, PName, Hours,Rate)
del self.__lstWorkers[self.__position]
self.__lstWorkers.insert(self.__position,newWorker)
strSQL="UPDATE workers SET emplname = '"+PName+"', hours ="+str(Hours)+", rate = "+str(Rate)+" where emplIRD = '"+PIRD+"'"
print(strSQL)
connection =sqlite3.connect("Workers.db")
cursor=connection.cursor()
cursor.execute(strSQL)
connection.commit()
cursor.close()
self.__fb = "Name for "+PIRD+", has been changed to "+PName
def deleteRecord(self):
if self.__fileOpen==True:
PIRD=self.__lstWorkers[self.__position].irdValue()
PName=self.__lstWorkers[self.__position].nameValue()
del self.__lstWorkers[self.__position]
if self.__position > len(self.__lstWorkers)-1:
self.__position = len(self.__lstWorkers)-1
strSQL="delete from workers where emplIRD = '"+PIRD+"'"
connection =sqlite3.connect("Workers.db")
cursor=connection.cursor()
cursor.execute(strSQL)
connection.commit()
cursor.close()
self.__fb = "Record for "+PIRD+", "+PName+" has been removed"
def __saveList(self):
self.__position = len(self.__lstWorkers)-1
currentObject= self.__lstWorkers[self.__position]
connection =sqlite3.connect("Workers.db")
cursor=connection.cursor()
strSQL="insert into workers values('"+currentObject.irdValue()+"', '" +currentObject.nameValue()+"', "+str(currentObject.hoursValue())+", "+str(currentObject.rateValue())
strSQL+=", "+str(currentObject.grossValue())+", "+str(currentObject.taxValue())+", "+str(currentObject.netValue())+")"
print(strSQL)
cursor.execute(strSQL)
connection.commit()
cursor.close()
def fileSize(self):
return(len(self.__lstWorkers))
def feedback(self):
return self.__fb
def currentRecord(self):
return self.__position
"""
The section below is procedural and contains the code for controllig the graphical
user interface
"""
def addRecord():
myWorker.newRecord(varIRD.get(),varName.get(),varHours.get(),varRate.get())
varFeedback.set(myWorker.feedback())
def modifyRecord():
myWorker.changeData(varIRD.get(),varName.get(),varHours.get(),varRate.get())
varFeedback.set(myWorker.feedback())
def deleteRecord():
myWorker.deleteRecord()
varFeedback.set(myWorker.feedback())
def firstRecord():
showData(myWorker.payFirst())
def lastRecord():
showData(myWorker.payLast())
def nextRecord():
showData(myWorker.payNext())
def previousRecord():
showData(myWorker.payPrevious())
def showData(currentObject):
varIRD.set(currentObject.irdValue())
varName.set(currentObject.nameValue())
varHours.set(currentObject.hoursValue())
varRate.set(currentObject.rateValue())
varGross.set(currentObject.grossValue())
varTax.set(currentObject.taxValue())
varNet.set(currentObject.netValue())
varFeedback.set("Record "+ str(myWorker.currentRecord()+1) +" of " + str(myWorker.fileSize()))
root = Tk()
frame1 = Frame(root, width = 420, height = 360)
frame1.pack()
varIRD=StringVar()
varName=StringVar()
varHours=DoubleVar()
varRate=DoubleVar()
varGross=DoubleVar()
varTax=DoubleVar()
varNet=DoubleVar()
varFeedback=StringVar()
irdLabel=tk.Label(master=frame1,text='IRD Number',width=15, anchor=E)
irdLabel.place(x = 60, y = 10)
nameLabel=tk.Label(master=frame1,text='Full Name',width=15, anchor=E)
nameLabel.place(x = 60, y = 45)
hoursLabel=tk.Label(master=frame1,text='Hours Worked',width=15, anchor=E)
hoursLabel.place(x = 60, y = 80)
rateLabel=tk.Label(master=frame1,text='Hourly Rate',width=15, anchor=E)
rateLabel.place(x = 60, y = 115)
grossLabel=tk.Label(master=frame1,text='Gross',width=15, anchor=E)
grossLabel.place(x = 60, y = 150)
taxLabel=tk.Label(master=frame1,text='Tax',width=15, anchor=E)
taxLabel.place(x = 60, y = 185)
netLabel=tk.Label(master=frame1,text='Net',width=15, anchor=E)
netLabel.place(x = 60, y = 220)
txtIRD=tk.Entry(master=frame1,relief=RAISED, textvariable=varIRD,width=15,bg="#ffffff", bd=1)
txtIRD.place(x = 180, y = 10)
txtName=tk.Entry(master=frame1,relief=RAISED, textvariable=varName,width=15,bg="#ffffff", bd=1)
txtName.place(x = 180, y = 45)
txtHours=tk.Entry(master=frame1,relief=RAISED, textvariable=varHours,width=15,bg="#ffffff", bd=1)
txtHours.place(x = 180, y = 80)
txtRate=tk.Entry(master=frame1,relief=RAISED, textvariable=varRate,width=15,bg="#ffffff", bd=1)
txtRate.place(x = 180, y = 115)
lblGross=tk.Label(master=frame1,relief=RAISED, textvariable=varGross,width=15,bg="#ffffff",bd=1)
lblGross.place(x = 180, y = 150)
lblTax=tk.Label(master=frame1,relief=RAISED, textvariable=varTax,width=15,bg="#ffffff", bd=1)
lblTax.place(x = 180, y = 185)
lblNet=tk.Label(master=frame1,relief=RAISED, textvariable=varNet,width=15,bg="#ffffff", bd=1)
lblNet.place(x = 180, y = 220)
addButton=tk.Button(master=frame1,text='Add', width=10, command=addRecord)
addButton.place(x = 80, y = 270)
modifyButton=tk.Button(master=frame1,text='Modify', width=10, command=modifyRecord)
modifyButton.place(x = 160, y = 270)
deleteButton=tk.Button(master=frame1,text='Delete', width=10, command=deleteRecord)
deleteButton.place(x = 240, y = 270)
firstButton=tk.Button(master=frame1,text='First', width=10, command=firstRecord)
firstButton.place(x = 40, y = 305)
lastButton=tk.Button(master=frame1,text='Last', width=10, command=lastRecord)
lastButton.place(x = 120, y = 305)
nextButton=tk.Button(master=frame1,text='Next', width=10, command=nextRecord)
nextButton.place(x = 200, y = 305)
previousButton=tk.Button(master=frame1,text='Previous',width=10,command=previousRecord)
previousButton.place(x = 280, y = 305)
feedbackLabel=tk.Label(master=frame1,textvariable=varFeedback,width=54)
feedbackLabel.place(x = 10, y = 340)
myWorker = dBase()
firstRecord()
root.title("Payroll")
root.mainloop()