Instructions
Requirements and Specifications
Source Code
EMPLOYEE
class Employee:
def __init__(self, id: int, name: str, workFromHome: bool):
self.__id = id
self.__name = name
self.__workFromHome = workFromHome
self.__leaveBalance = 0
def employeeId(self):
return self.__id
@property
def name(self):
return self.__name
@property
def workFromHome(self):
return self.__workFromHome
@workFromHome.setter
def workFromHome(self, atHome: bool):
self.__workFromHome = atHome
def getLeaveEntitlement(self):
return self.__leaveBalance
def adjustLeave(self, adjustment: int):
self.__leaveBalance += adjustment
def __str__(self):
WFH = "Yes"
if not self.__workFromHome:
WFH = "No"
return "ID: {0}\tName: {1}\tLeave Balance: {2}\tWFH: {3}".format(self.__id, self.__name, self.__leaveBalance, WFH)
COMPANY
from Question2.Department import *
class Company:
def __init__(self, name: str, uniqueEntityNumber: str):
self.__SAFE_MANAGEMENT_PERCENTAGE = 50.0
self.__name = name
self.__uniqueEntityNumber = uniqueEntityNumber
self.__departments = []
def getSafeManagementPercentage(self) -> float:
return self.__SAFE_MANAGEMENT_PERCENTAGE
def setSafeManagementPercentage(self, newPercentage: float):
self.__SAFE_MANAGEMENT_PERCENTAGE = newPercentage
def searchDepartment(self, name: str) -> Department:
if len(self.__departments) > 0:
for department in self.__departments:
if department.name == name:
return department
return None
def addDepartment(self, newDepartment: Department) -> bool:
# Check if the department is in the departments list
if len(self.__departments) > 0:
found = False
for department in self.__departments:
if department.name == newDepartment.name:
found = True
break
if not found: # department not present in departments list
self.__departments.append(newDepartment)
return True
else:
return False
else:
self.__departments.append(newDepartment)
return True
def __str__(self):
ret = "Company: " + self.__name + "\tUEN: " + self.__uniqueEntityNumber + "\n"
for department in self.__departments:
ret += str(department) + department.safeManagementCheck(self.getSafeManagementPercentage()) + "\n"
return ret
DEPARTMENT
from Question2.Employee import *
from Question2.Manager import *
class Department:
def __init__(self, name: str, manager: Employee, essentialServices: bool):
self.__name = name
self.__employees = []
self.__manager = manager
self.__essentialServices = essentialServices
@property
def name(self) -> str:
return self.__name
@property
def essentialServices(self) -> bool:
return self.__essentialServices
def searchEmployee(self, employeeId: int) -> Employee:
if len(self.__employees) > 0:
for employee in self.__employees:
if employee.employeeId() == employeeId:
return employee
return None
def addEmployee(self, newEmployee: Employee) -> bool:
# First, check if the employee is already in the department
if self.searchEmployee(newEmployee.employeeId()) == None:
# Check if the newEmployee is not manager
if not isinstance(newEmployee, Manager):
self.__employees.append(newEmployee)
return False
# If we reach this line it is because the employee was not added
return False
def safeManagementCheck(self, percentage: float) -> str:
# Calculate percentage of employees working from home
n_wfh = 0
for employee in self.__employees:
if employee.workFromHome:
n_wfh += 1
percent = n_wfh / (len(self.__employees) + 1) *100.0
passed = "passed requirement"
if percent < percentage:
passed = "failed requirement"
# However, if the department provided essential services, then it is exempted
if self.essentialServices:
passed = "exempted"
return "No. of Employees working from home: {0:.0f} ({1:.1f}%) - {2}".format(n_wfh, percent, passed)
def __str__(self):
essential = "Yes"
if not self.essentialServices:
essential = "No"
ret = "Department: " + self.name + "\tEssential Services: " + essential + "\n"
ret += "Manager " + str(self.__manager) + "\n"
# Now, append each employee
for employee in self.__employees:
ret += str(employee) + "\n"
return ret
LEAVE
from datetime import datetime
from Question3.Employee import *
from Question3.LeaveApplicationException import *
class Leave:
__NEXT_ID = 20210000
def __init__(self, applicant: Employee, fromDate: datetime, toDate: datetime):
self.__applicant = applicant
Leave.__NEXT_ID += 1
# Check if toDate is before or same than fromDate
if toDate < fromDate or toDate == fromDate:
raise LeaveApplicationException()
# Check if fromDate falls on saturday or sunday
if fromDate.weekday() == 1 or fromDate.weekday() == 7:
raise LeaveApplicationException()
self.__fromDate = fromDate
self.__toDate = toDate
self.__leaveRequestId = Leave.__NEXT_ID
self.__duration = (toDate-fromDate).days
self.__status = "Approved"
@property
def leaveRequest(self) -> int:
return self.__leaveRequestId
@property
def applicant(self) -> Employee:
return self.__applicant
@property
def fromDate(self) -> datetime:
return self.__fromDate
@property
def toDate(self) -> datetime:
return self.__toDate
@property
def duration(self) -> int:
return self.__duration
@property
def status(self) -> str:
return self.__status
@status.setter
def status(self, newStatus: str):
self.__status = newStatus
def __str__(self):
ret = "Leave Request ID: " + str(self.__leaveRequestId) + "\n"
ret += str(self.applicant) + "\n"
ret += "From: " + self.fromDate.strftime("%d %B %Y") + " to " + self.toDate.strftime("%d %B %Y") + "\n"
ret += "Duration: " + str(self.duration) + " days\n"
ret += "Status: " + self.status
return ret
MAIN
from tkinter import *
import random
# Declare the questions
questionBank = [
['Variable names cannot start with digit', True],
["x='1'+1 is a valid statement", False],
['= and == can be used interchangeably', False],
['logical operator and has a higher precedence than or', True],
['String type is immutable', True],
['x,y = y,x swaps the values of x and y', True],
['2=x is a valid statement', False],
['Variable names can be 50 letters long', True]
]
questions = None
QUESTION_INDEX = 0
n_correct = 0
def start(start_btn, question_label, submit_btn, rb1, rb2, text):
global n_correct, questions, QUESTION_INDEX
# Pick 4 random questions
questions = random.sample(questionBank, 4)
QUESTION_INDEX = 0
start_btn['state'] = DISABLED
submit_btn['state'] = NORMAL
question_label['text'] = questions[QUESTION_INDEX][0]
rb1['text'] = "True"
rb2['text'] = "False"
text.delete(1.0, END)
n_correct = 0
def submit(rb1, rb2, start_btn, submit_btn, next_btn, text, var):
global QUESTION_INDEX, n_correct, questions
# Check if an option is selected
if var.get() == 1 or var.get() == 2:
question = questions[QUESTION_INDEX]
answer = question[1]
if answer ==True and var.get() == 1:
display(text, f"Question {QUESTION_INDEX + 1} correct!\n")
n_correct += 1
elif answer == False and var.get() == 2:
display(text, f"Question {QUESTION_INDEX + 1} correct!\n")
n_correct += 1
else:
display(text, f"Question {QUESTION_INDEX + 1} incorrect!\n")
if QUESTION_INDEX < len(questions)-1:
next_btn['state'] = NORMAL
else: # All questions answered, display results
display(text, f"Quiz complete. Total {n_correct} answers correct.\n")
display(text, f"Click start to attemp quiz again.\n\n")
start_btn['state'] = NORMAL
submit_btn['state'] = DISABLED
else:
display(text, f"Please select answer for Question {QUESTION_INDEX + 1}\n")
def next(next_btn, question_label, rb1, rb2):
global QUESTION_INDEX, questions
QUESTION_INDEX += 1
question_label['text'] = questions[QUESTION_INDEX][0]
next_btn['state'] = DISABLED
submit_btn['state'] = NORMAL
def display(text, message):
text['state'] = NORMAL
text.insert(END, message)
text['state'] = DISABLED
if __name__ == '__main__':
window = Tk()
window.title("Python Quiz - done by XXX")
window.geometry('400x400')
# Add widgets
start_btn = Button(window, text='Start')
start_btn.pack(side='top')
question_label = Label(window, text='Question will appear here')
question_label.pack(side='top')
var = IntVar()
rb1 = Radiobutton(window, text='Option 1', variable=var, value=1)
rb1.pack(side='top')
rb2 = Radiobutton(window, text='Option 2', variable=var, value=2)
rb2.pack(side='top')
submit_btn = Button(window, text='Submit', state=DISABLED)
submit_btn.pack(side='top')
next_btn = Button(window, text='Next', state=DISABLED)
next_btn.pack(side='top')
# Text Area
text = Text(window)
#text['state'] = DISABLED
text.pack(side='top')
# Handlers
start_btn['command'] = lambda: start(start_btn, question_label, submit_btn, rb1, rb2, text)
submit_btn['command'] = lambda: submit(rb1, rb2, start_btn, submit_btn, next_btn, text, var)
next_btn['command'] = lambda: next(next_btn, question_label, rb1, rb2)
window.mainloop()