-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssignment06.py
More file actions
165 lines (144 loc) · 5.92 KB
/
Assignment06.py
File metadata and controls
165 lines (144 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# ------------------------------------------------------------------------------------------ #
# Title: Assignment06_Starter
# Desc: This assignment demonstrates using functions
# with structured error handling
# Change Log: (Who, When, What)
# RRoot,1/1/2030,Created Script
# <Kiem Hollis>,<3/7/2025>,<Created Script>
# ------------------------------------------------------------------------------------------ #
import json
# Define the Data Constants
MENU: str = '''
---- Course Registration Program ----
Select from the following menu:
1. Register a Student for a Course.
2. Show current data.
3. Save data to a file.
4. Exit the program.
-----------------------------------------
'''
FILE_NAME: str = "Enrollments.json"
# Define the Data Variables and constants
students: list = [] # a table of student data
menu_choice: str # Hold the choice made by the user.
# This is a class with the decorator command.
class FileProcessor:
@staticmethod
def read_data_from_file(file_name: str, student_data: list):
try:
file = open(file_name, "r")
student_data = json.load(file)
file.close()
except FileNotFoundError as e:
IO.output_error_messages("Text file must exit before running this script!", e)
except Exception as e:
IO.output_error_messages("There was a non-specific error!", e)
finally:
if file.closed == False:
file.close()
return student_data
# This is a class of input and outputs with the decorator command.
class IO:
@staticmethod
def output_error_messages(message: str, error: Exception = None):
""" This function displays the a custom error messages to the user
ChangeLog: (Who, When, What)
RRoot,1.3.2030,Created function
KHollis, 3/7/2025, Added function
:return: None
"""
print(message, end="\n\n")
if error is not None:
print("-- Technical Error Message -- ")
print(error, error.__doc__, type(error), sep='\n')
@staticmethod
def output_menu(menu: str):
""" This function displays the menu of choices to the user
ChangeLog: (Who, When, What)
RRoot,1.3.2030,Created function
KHollis, 3/7/2025, Added function
:return: None
"""
print() # Adding extra space to make it look nicer.
print(menu)
print() # Adding extra space to make it look nicer.
@staticmethod
def input_menu_choice():
""" This function gets a menu choice from the user
:return: string with the users choice
"""
choice = "0"
try:
choice = input("Enter your menu choice number: ")
if choice not in ("1", "2", "3", "4"): # Note these are strings
raise Exception("Please choose only 1, 2, 3, or 4")
except Exception as e:
IO.output_error_messages(e.__str__()) # Not passing e to avoid the technical message
return choice
@staticmethod
def input_student_data(student_data: list):
""" This function gets the first name, last name, and GPA from the user
ChangeLog: (Who, When, What)
RRoot,1.3.2030,Created function
KHollis, 3/7/2025, Added function
:return: str
"""
try:
student_first_name = input("Enter the student's first name: ")
if not student_first_name.isalpha():
raise ValueError("The last name should not contain numbers.")
student_last_name = input("Enter the student's last name: ")
if not student_last_name.isalpha():
raise ValueError("The last name should not contain numbers.")
course_name = input("Please enter the name of the course: ")
student_data = {"FirstName": student_first_name,
"LastName": student_last_name,
"CourseName": course_name}
students.append(student_data)
print(f"You have registered {student_first_name} {student_last_name} for {course_name}.")
except ValueError as e:
IO.output_error_messages("That value is not the correct type of data!", e)
except Exception as e:
IO.output_error_messages("There was a non-specific error!", e)
return student_data
@staticmethod
def output_student_courses(student_data: list):
print("-" * 50)
for student in student_data:
print(f'Student {student["FirstName"]} '
f'{student["LastName"]} is enrolled in {student["CourseName"]}')
print("-" * 50)
@staticmethod
def write_data_to_file(file_name: str, student_data: list):
# global file
# global students
try:
file = open(file_name, "w")
json.dump(student_data, file)
file.close()
except TypeError as e:
IO.output_error_messages("Please check that the data is a valid JSON format", e)
except Exception as e:
IO.output_error_messages("There was a non-specific error!", e)
finally:
if file.closed == False:
file.close()
students = FileProcessor.read_data_from_file(FILE_NAME, students)
while (True):
print(MENU)
menu_choice = IO.input_menu_choice()
if menu_choice == "1":
IO.input_student_data(students)
continue
elif menu_choice == "2":
IO.output_student_courses(students)
continue
elif menu_choice == "3":
IO.write_data_to_file(FILE_NAME, students)
print("The following data was saved to file!")
IO.output_student_courses(students)
continue
# Stop the loop
elif menu_choice == "4":
break # out of the loop
print("Program Ended")