update,
This commit is contained in:
508
hdhdjshxh/task2/project/src/Assignment.py
Normal file
508
hdhdjshxh/task2/project/src/Assignment.py
Normal file
@@ -0,0 +1,508 @@
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import datetime
|
||||
|
||||
import tkinter
|
||||
import tkinter.ttk
|
||||
|
||||
import tkinter.messagebox
|
||||
import tkinter.scrolledtext
|
||||
from tkinter import *
|
||||
|
||||
# class starts
|
||||
|
||||
|
||||
class HDinfo():
|
||||
# Attributes:
|
||||
# institutionName– a non-public string to store the HD institution name of the applicant.
|
||||
# programmeTitle – a non-public string to store the HD programme name of the applicant.
|
||||
# gpa – a non-public double to store the HD GPA of the applicant.
|
||||
# expectedGradeYear– a non-public int to store the Expected HD Graduation Year of the applicant.
|
||||
|
||||
# Methods:
|
||||
# init – initialize all attributes in HDinfo object. It is a Parameterized constructor.
|
||||
# str – return a string containing the Attributes of HDinfo object. This method is used to display in Summary ScrolledText.
|
||||
|
||||
# constructor __init__
|
||||
def __init__(self, institutionName="", programmeTitle="", gpa="", expectedGraYear=""):
|
||||
self.institutionName = institutionName
|
||||
self.programmeTitle = programmeTitle
|
||||
self.gpa = gpa
|
||||
self.expectedGraYear = expectedGraYear
|
||||
pass
|
||||
|
||||
# __str__ method
|
||||
def __str__(self):
|
||||
return """
|
||||
Higher Diploma Information:
|
||||
Institution Name: {hd_institution_name}
|
||||
Programme Title: {hd_programme_title}
|
||||
GPA: {hd_gpa}
|
||||
Expected Graduation Year: {expectedGraYear}
|
||||
""".strip().format(
|
||||
hd_institution_name=self.institutionName,
|
||||
hd_programme_title=self.programmeTitle,
|
||||
hd_gpa=self.gpa,
|
||||
expectedGraYear=self.expectedGraYear,
|
||||
)
|
||||
|
||||
|
||||
class Applicant():
|
||||
# Attributes:
|
||||
# name – a non-public string to store the name of the applicant.
|
||||
# email – a non-public string to store the email of the applicant.
|
||||
# gender – a non-public string to store the gender of the applicant.
|
||||
# dateOfBirth – a non-public string to store the applicant date of birth.
|
||||
# applyDegreeProgramme – a non-public string to store the applicant selected
|
||||
# degree programme
|
||||
# hdInfo– a non-public HDinfo(self-defined class) to store the applicant Higher
|
||||
# Diploma information
|
||||
|
||||
# Methods:
|
||||
# init – initialize all attributes in Applicant object. It is a Parameterized constructor.
|
||||
# setPeronalInfo – setter method to set the name, email, gender, dateOfBirth, applyDegreeProgrmme into the Applicant object.
|
||||
# setHDinfo – setter method to set the HDinfo object into the Applicant object.
|
||||
# str – return a string containing the Attributes of this Applicant. This function is used to display in Summary ScrolledText.
|
||||
|
||||
# constructor __init__
|
||||
def __init__(self, name="", email="", gender="", dateOfBirth="", applyDegreeProgramme="", hdInfo=HDinfo()):
|
||||
self.name = name
|
||||
self.email = email
|
||||
self.gender = gender
|
||||
self.dateOfBirth = dateOfBirth
|
||||
self.applyDegreeProgramme = applyDegreeProgramme
|
||||
pass
|
||||
|
||||
# Set Personal Info Method
|
||||
def setPeronalInfo(self, name, email, gender, dateOfBirth, applyDegreeProgramme):
|
||||
self.name = name
|
||||
self.email = email
|
||||
self.gender = gender
|
||||
self.dateOfBirth = dateOfBirth
|
||||
self.applyDegreeProgramme = applyDegreeProgramme
|
||||
|
||||
# Set HD Info Method
|
||||
def setHDInfo(self, hd):
|
||||
self.hd = hd
|
||||
pass
|
||||
|
||||
# __str__ method
|
||||
def __str__(self):
|
||||
"""
|
||||
Returns a string representation of the Applicant object.
|
||||
|
||||
Returns:
|
||||
str: A formatted string containing the applicant's name, email, gender, date of birth, and applied degree programme.
|
||||
Also includes a string representation of the Higher Diploma object.
|
||||
"""
|
||||
return """
|
||||
Applicant Name: {applicant_name}
|
||||
Applicant Email: {applicant_email}
|
||||
Gender: {gender}
|
||||
Date of Birth: {DOB}
|
||||
Apply Degree Programme: {applyDegreeProgramme}
|
||||
""".strip().format(
|
||||
applicant_name=self.name,
|
||||
applicant_email=self.email,
|
||||
gender=self.gender,
|
||||
DOB=self.dateOfBirth,
|
||||
applyDegreeProgramme=self.applyDegreeProgramme,
|
||||
) + '\n' + self.hd.__str__()
|
||||
|
||||
|
||||
applicant = Applicant()
|
||||
# class ends
|
||||
|
||||
|
||||
# Tkinter starts
|
||||
|
||||
|
||||
# Parent class for Personal and HighDiploma
|
||||
class ApplicationPage(tkinter.Frame):
|
||||
"""Base class for managed pages. Provides methods to be overridden by subclasses."""
|
||||
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
|
||||
def is_complete(self) -> bool:
|
||||
"""Check if the current page is complete."""
|
||||
return True
|
||||
|
||||
|
||||
class Personal(ApplicationPage):
|
||||
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
|
||||
frm_base = tkinter.Frame(self)
|
||||
frm_base.pack(fill=tkinter.BOTH, expand=True)
|
||||
|
||||
frm_title = tkinter.Frame(frm_base)
|
||||
frm_title.pack(fill=tkinter.BOTH)
|
||||
|
||||
lbl_title = tkinter.Label(
|
||||
frm_title, text="Personal Infromation", font=("bold", 15))
|
||||
lbl_title.pack(anchor=tkinter.W)
|
||||
|
||||
###
|
||||
# Write your coding here
|
||||
# Frame for the content
|
||||
frm_content = tkinter.Frame(frm_base)
|
||||
frm_content.pack(fill=tkinter.BOTH, expand=True)
|
||||
frm_content.grid_columnconfigure(2, weight=1)
|
||||
|
||||
# Row counter, to advance row in screen
|
||||
row = 0
|
||||
|
||||
# Label for applicant name
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Applicant Name", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
# Entry box for applicant name
|
||||
self.ent_applicant_name = tkinter.Entry(frm_content)
|
||||
self.ent_applicant_name.insert(0, "")
|
||||
self.ent_applicant_name.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# Label for applicant email
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Applicant Email", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
# Entry box for applicant email
|
||||
self.ent_applicant_email = tkinter.Entry(frm_content)
|
||||
self.ent_applicant_email.insert(0, "")
|
||||
self.ent_applicant_email.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# String variable to store the selected gender
|
||||
self.gender_select = tkinter.StringVar(value="Male")
|
||||
|
||||
# Label for gender
|
||||
lbl_gender = tkinter.Label(
|
||||
frm_content, text="Gender", anchor="w", justify="left", width=20)
|
||||
lbl_gender.grid(row=row, column=0)
|
||||
|
||||
# Radio buttons for gender selection
|
||||
rad_male = tkinter.Radiobutton(
|
||||
frm_content, variable=self.gender_select, text="Male", value="Male")
|
||||
rad_male.grid(row=row, column=1)
|
||||
|
||||
rad_female = tkinter.Radiobutton(
|
||||
frm_content, variable=self.gender_select, text="Female", value="Female")
|
||||
rad_female.grid(row=row, column=2)
|
||||
|
||||
row += 1
|
||||
|
||||
# Label for date of birth
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Date of Birth", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
|
||||
# Entry box for date of birth
|
||||
self.ent_applicant_DOB = tkinter.Entry(frm_content)
|
||||
self.ent_applicant_DOB.insert(0, "")
|
||||
self.ent_applicant_DOB.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# Label for apply programme
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Apply Programme", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
|
||||
# List of programme options and combobox for apply programme
|
||||
lst_programme = ["Bachelor of Science in Cybersecurity",
|
||||
"Bachelor of Science in Computer Science and AI"]
|
||||
self.applicant_programme = tkinter.ttk.Combobox(
|
||||
frm_content, textvariable=lst_programme, values=lst_programme, state="readonly",)
|
||||
self.applicant_programme.current(0)
|
||||
self.applicant_programme.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
def is_complete(self):
|
||||
|
||||
###
|
||||
# Write your coding here
|
||||
entry_valid = True
|
||||
if self.ent_applicant_name.get() == "":
|
||||
tkinter.messagebox.showinfo("Information", "name cannot empty.")
|
||||
entry_valid = False
|
||||
|
||||
if self.ent_applicant_email.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "email field cannot empty.")
|
||||
entry_valid = False
|
||||
else:
|
||||
# check if email field valid
|
||||
# https://www.geeksforgeeks.org/check-if-email-address-valid-or-not-in-python/
|
||||
if not re.match(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b', self.ent_applicant_email.get()):
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "email: format error, it should be email.")
|
||||
entry_valid = False
|
||||
|
||||
if self.ent_applicant_DOB.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "dob field cannot empty.")
|
||||
entry_valid = False
|
||||
else:
|
||||
# python re to check if yyyy/mm/dd
|
||||
if not re.match(r'^\d{4}/\d{2}/\d{2}$', self.ent_applicant_DOB.get()):
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "DOB format error, it should be yyyy/mm/dd.")
|
||||
entry_valid = False
|
||||
|
||||
# ptyhon to check if the day entered is latter than today
|
||||
today = datetime.date.today()
|
||||
if datetime.datetime.strptime(self.ent_applicant_DOB.get(), '%Y/%m/%d').date() > today:
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "DOB the day enter is latter than today.")
|
||||
entry_valid = False
|
||||
|
||||
if (entry_valid):
|
||||
applicant.setPeronalInfo(
|
||||
self.ent_applicant_name.get(),
|
||||
self.ent_applicant_email.get(),
|
||||
self.gender_select.get(),
|
||||
self.ent_applicant_DOB.get(),
|
||||
self.applicant_programme.get()
|
||||
)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class HighDiploma(ApplicationPage):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
|
||||
frm_base = tkinter.Frame(self)
|
||||
frm_base.pack(fill=tkinter.BOTH, expand=True)
|
||||
|
||||
frm_title = tkinter.Frame(frm_base)
|
||||
frm_title.pack(fill=tkinter.BOTH)
|
||||
|
||||
lbl_title = tkinter.Label(
|
||||
frm_title, text="Higher Diploma Information", font=("bold", 15))
|
||||
lbl_title.pack(anchor=tkinter.W)
|
||||
|
||||
###
|
||||
# Write your coding here
|
||||
# Content frame for the form entries
|
||||
row = 0 # row counter for the form
|
||||
frm_content = tkinter.Frame(frm_base)
|
||||
frm_content.pack(fill=tkinter.BOTH)
|
||||
frm_content.grid_columnconfigure(2, weight=1)
|
||||
|
||||
# Label and entry for Institution name
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Institution Name", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
self.ent_institution_name = tkinter.Entry(frm_content)
|
||||
self.ent_institution_name.insert(0, "")
|
||||
self.ent_institution_name.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# Label and entry for Programme Title
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Programme Title", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
self.ent_programme_title = tkinter.Entry(frm_content)
|
||||
self.ent_programme_title.insert(0, "")
|
||||
self.ent_programme_title.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# Label and entry for GPA
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="GPA", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
self.ent_GPA = tkinter.Entry(frm_content)
|
||||
self.ent_GPA.insert(0, "")
|
||||
self.ent_GPA.grid(row=row, column=1, columnspan=2,
|
||||
sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
# Label and entry for Expected Graduation Year
|
||||
lbl_name = tkinter.Label(
|
||||
frm_content, text="Expected Graduation Year", anchor="w", justify="left", width=20)
|
||||
lbl_name.grid(row=row, column=0)
|
||||
self.expected_grad_year = tkinter.Entry(frm_content)
|
||||
self.expected_grad_year.insert(0, "")
|
||||
self.expected_grad_year.grid(
|
||||
row=row, column=1, columnspan=2, sticky="nsew", pady=(10, 10), padx=(10, 10))
|
||||
row += 1
|
||||
|
||||
###
|
||||
|
||||
def is_complete(self):
|
||||
###
|
||||
# Write your coding here
|
||||
|
||||
entry_valid = True
|
||||
if self.ent_institution_name.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "institution name field cannot empty.")
|
||||
entry_valid = False
|
||||
if self.ent_programme_title.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "programme title field cannot empty.")
|
||||
entry_valid = False
|
||||
|
||||
if self.ent_GPA.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "GPA field cannot empty.")
|
||||
entry_valid = False
|
||||
else:
|
||||
|
||||
# check if gpa field is a number
|
||||
try:
|
||||
float(self.ent_GPA.get())
|
||||
except ValueError:
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "GPA field should be a number.")
|
||||
entry_valid = False
|
||||
|
||||
if self.expected_grad_year.get() == "":
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "Expected graduation year field cannot empty.")
|
||||
entry_valid = False
|
||||
else:
|
||||
|
||||
# check if gpa field is a number
|
||||
try:
|
||||
int(self.expected_grad_year.get())
|
||||
|
||||
# check if expected grad year is after current year
|
||||
today = datetime.date.today()
|
||||
if int(self.expected_grad_year.get()) < today.year:
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "Expected graduation year should be after current year.")
|
||||
entry_valid = False
|
||||
|
||||
except ValueError:
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "Expected graduation year field should be a number.")
|
||||
entry_valid = False
|
||||
|
||||
hd = HDinfo(
|
||||
self.ent_institution_name.get(),
|
||||
self.ent_programme_title.get(),
|
||||
self.ent_GPA.get(),
|
||||
self.expected_grad_year.get()
|
||||
)
|
||||
|
||||
if (entry_valid):
|
||||
applicant.setHDInfo(hd)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class Result(ApplicationPage):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
|
||||
frm_base = tkinter.Frame(self)
|
||||
frm_base.pack(fill=tkinter.BOTH, expand=True)
|
||||
|
||||
frm_title = tkinter.Frame(frm_base)
|
||||
frm_title.pack(fill=tkinter.BOTH)
|
||||
|
||||
lbl_title = tkinter.Label(frm_base, text="Summary", font=("bold", 15))
|
||||
lbl_title.pack(anchor=tkinter.W)
|
||||
|
||||
# Summary Output
|
||||
###
|
||||
# Write your coding here
|
||||
row = 0
|
||||
frm_content = tkinter.Frame(frm_base)
|
||||
frm_content.pack(fill=tkinter.BOTH)
|
||||
frm_content.grid_columnconfigure(2, weight=1)
|
||||
|
||||
# textbox for summary
|
||||
self.txt_summary = tkinter.Text(frm_content, height=12)
|
||||
self.txt_summary.grid(row=row, column=1, columnspan=2,
|
||||
sticky="nsew", pady=(1, 1), padx=(1, 1))
|
||||
row += 1
|
||||
|
||||
# right justify button with text "show"
|
||||
btn_show = tkinter.Button(frm_base, text="Show", anchor=tkinter.E)
|
||||
btn_show.pack(side=tkinter.RIGHT)
|
||||
|
||||
# tkinter bind button click
|
||||
btn_show.bind("<Button-1>", self.show)
|
||||
|
||||
###
|
||||
|
||||
def show(self, _): # Show Button method
|
||||
###
|
||||
# Write your coding here
|
||||
self.txt_summary.insert(tkinter.INSERT, str(applicant))
|
||||
###
|
||||
|
||||
|
||||
class Application(tkinter.Tk):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Configure GUI
|
||||
self.title("Undergraduate Application Form")
|
||||
self.geometry("450x300")
|
||||
|
||||
# Content Frame
|
||||
frm_content = tkinter.Frame(self, relief=tkinter.RIDGE, borderwidth=1)
|
||||
frm_content.pack(fill=tkinter.BOTH, expand=True)
|
||||
frm_content.rowconfigure(0, weight=1)
|
||||
frm_content.columnconfigure(0, weight=1)
|
||||
|
||||
# Application Pages
|
||||
self.__frames: list[ApplicationPage] = [
|
||||
Personal(frm_content),
|
||||
HighDiploma(frm_content),
|
||||
Result(frm_content),
|
||||
]
|
||||
for i in self.__frames:
|
||||
i.grid(row=0, column=0, sticky=tkinter.NSEW)
|
||||
self.__current_page = 0
|
||||
self.__frames[self.__current_page].tkraise()
|
||||
|
||||
# Bottom Frame
|
||||
frm_button = tkinter.Frame(self, padx=4, pady=4)
|
||||
frm_button.pack(side=tkinter.BOTTOM, fill=tkinter.X)
|
||||
|
||||
# Next Button
|
||||
self.btn_next = tkinter.Button(
|
||||
frm_button, text="Next", command=self.next_page)
|
||||
self.btn_next.pack(side=tkinter.RIGHT)
|
||||
|
||||
# Quit Button
|
||||
self.btn_quit = tkinter.Button(
|
||||
frm_button, text="Quit", command=self.destroy)
|
||||
|
||||
def next_page(self):
|
||||
# Check if the current page is complete
|
||||
if not self.__frames[self.__current_page].is_complete():
|
||||
tkinter.messagebox.showinfo(
|
||||
"Information", "Please fill the missing fields."
|
||||
)
|
||||
return
|
||||
|
||||
# Navigate to next page
|
||||
self.__current_page += 1
|
||||
self.__frames[self.__current_page].tkraise()
|
||||
|
||||
# If we reached the last page, replace the next button with quit button
|
||||
if self.__current_page + 1 == len(self.__frames):
|
||||
self.btn_next.pack_forget()
|
||||
self.btn_quit.pack(side=tkinter.RIGHT)
|
||||
# Tkinter ends
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.mainloop()
|
10
hdhdjshxh/task2/project/src/test.bat
Normal file
10
hdhdjshxh/task2/project/src/test.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
@REM rm *.bas
|
||||
@REM rm *.frm
|
||||
@REM rm *.frx
|
||||
@REM timeout 1
|
||||
|
||||
:loop
|
||||
python ./Assignment.py
|
||||
timeout /t 1
|
||||
goto loop
|
Reference in New Issue
Block a user