· 4 years ago · Aug 29, 2021, 10:28 PM
1# ------------------------------------------#
2# Title: CD_Inventory.py
3# Desc: Assignnment 08 - Working with classes
4# Change Log: (Who, When, What)
5# Charles Hodges(hocdges11@uw.edu), 2021-Aug-29, created file
6# ------------------------------------------#
7
8import pickle
9
10# -- DATA -- #
11# String Variables
12str_file_name = 'cdInventory.dat'
13str_menu = (
14 '\n'
15 'MENU\n\n'
16 '[l] Load Inventory from file\n'
17 '[a] Add CD\n'
18 '[i] Display Current Inventory\n'
19 '[s] Save Inventory to file\n'
20 '[x] Exit\n'
21 )
22str_which_operation = (
23 'Which operation would you like to perform?'
24 '[l, a, i, s, or x]: '
25 )
26
27# Non-String Variables
28lst_input_options = ['l', 'a', 'i', 's', 'x']
29lst_of_cd_objects = []
30
31
32class CD():
33 """Stores data about a CD.
34
35 properties:
36 cd_id: (int) with CD ID
37 cd_title: (string) with the title of the CD
38 cd_artist: (string) with the artist of the CD
39 methods:
40 increment_cd: Increments the counter for each CD object created
41 how_many_cds: returns number of CDs objects created
42 """
43
44 # Constructor
45 def __init__(self, cd_id, cd_title, cd_artist):
46 # Attributes
47 print("\nA new CD was created!\n")
48 self.__cd_id = cd_id
49 self.__cd_title = cd_title
50 self.__cd_artist = cd_artist
51
52 # Getter and Setter for the CD's ID number
53 @property
54 def cd_id(self):
55 return self.__cd_id
56
57 @cd_id.setter
58 def cd_id(self, cd_id):
59 self.__cd_id = cd_id
60
61 # Getter and Setter for the CD's Title
62 @property
63 def cd_title(self):
64 return self.__cd_title
65
66 @cd_title.setter
67 def cd_title(self, cd_title):
68 self.__cd_title = cd_title
69
70 # Getter and Setter for the CD's Artist
71 @property
72 def cd_artist(self):
73 return self.__cd_artist
74
75 @cd_artist.setter
76 def cd_artist(self, cd_artist):
77 self.__cd_artist = cd_artist
78
79 # Methods
80 def __str__(self):
81 """Represents the class objects as a string."""
82 return ('{: <7} {: <20} {: <20}'.format(
83 str(self.__cd_id), str(self.__cd_title), str(self.__cd_artist)))
84
85
86# -- PROCESSING -- #
87class FileIO():
88 """Processes data to and from a file.
89
90 methods:
91 save_inventory(file_name, lst_Inventory): -> None
92 load_inventory(file_name): -> (a list of CD objects)
93 """
94
95 @staticmethod
96 def save_inventory(str: str_file_name, list: lst_of_cd_objects) -> None:
97 """Function to save a file.
98
99 After the User either confirms or declines saving this function
100 processes the answer and either completes the objective to save, or
101 returns the User back to the menu.
102
103 Args:
104 str_file_name(string): File name where the data will be saved
105 lst_of_cd_objects(list): List to hold data
106
107 Returns:
108 None.
109 """
110 # Save data
111 obj_file = open(str_file_name, 'wb')
112 pickle.dump(lst_of_cd_objects, obj_file)
113 obj_file.close()
114 print("\nInventory saved to file.\n")
115
116 @staticmethod
117 def load_inventory(str_file_name, lst_of_cd_objects):
118 """Function to manage data ingestion from file to a list of
119 CD Objects.
120
121 Reads the data from file identified by file_name into a 2D table
122 (list of CD objects).
123
124 Args:
125 str_file_name(string): File name from which the data will be read
126 lst_of_cd_objects(list): List of lists to hold data
127
128 Returns: None.
129 """
130 # Clears existing data
131 lst_of_cd_objects.clear()
132
133 # Loads data from file
134 obj_file = open(str_file_name, 'rb')
135 try:
136 lst_of_cd_objects = pickle.load(obj_file)
137 except EOFError:
138 pass
139 obj_file.close()
140 print("\nInventory loaded from file.")
141 return lst_of_cd_objects
142
143 @staticmethod
144 def create_file(str: str_file_name) -> None:
145 """Function to create a binary file.
146
147 Args:
148 str_file_name(string): File name where the data will be saved
149
150 Returns:
151 None.
152 """
153 # Create file with temp file object and close it immediately
154 obj_file = open(str_file_name, 'ab')
155 obj_file.close()
156
157
158# -- PRESENTATION (Input/Output) -- #
159class IO():
160 """Processes Input from the User, and Output to the User.
161
162 methods:
163 print_menu(str_menu): Prints a string displaying the menu of options
164 menu_choice(): Requests and accepts user input of their selection
165 show_inventory(lst_of_cd_objects): Shows current inventory of CD objects
166 add_cd(lst_of_cd_objects): Allows User to create a new CD object
167 """
168
169 @staticmethod
170 def print_menu(str_menu):
171 """Displays a menu of choices to the user.
172
173 Args:
174 str_menu(string): User options to interact with their Inventory
175
176 Returns:
177 None.
178 """
179 print(str_menu)
180
181 @staticmethod
182 def menu_choice():
183 """Requests and accepts user input for menu selection.
184
185 Args:
186 None.
187
188 Returns:
189 choice (string): a lower case string of the users input, out of
190 the choices: l, a, i, s, or x
191 """
192 choice = ' '
193 while choice not in lst_input_options:
194 choice = input(str_which_operation).lower().strip()
195 print() # Add extra line for layout
196 return choice
197
198 @staticmethod
199 def show_inventory(list: lst_of_cd_objects) -> None:
200 """Show the User their inventory, if any.
201
202 Args:
203 lst_of_cd_objects(list): List to hold data
204
205 Returns:
206 None.
207
208 """
209 print('\n======= The Current Inventory: =======')
210 print("{: <5} {: <20} {: <20}".format("ID", "| CD Title", "| Artist"))
211 print("{: <5} {: <20} {: <20}".format("--", "| --------", "| ------"))
212 counter = 0
213 for row in lst_of_cd_objects:
214 cd = lst_of_cd_objects[counter]
215 print(cd)
216 counter += 1
217 print('======================================')
218
219 @staticmethod
220 def add_cd(list: lst_of_cd_objects) -> None:
221 """Create a CD object and add it the User's Inventory'.
222
223 Accepts the User input of new CD information, and creates a CD
224 object, which is appended to the list table which makes up the
225 Inventory.
226
227 Args:
228 lst_of_cd_objects(list): List of CD Objects
229
230 Returns:
231 lst_of_cd_objects(list): Updated list of CD Objects
232 """
233 # Collect the CD ID
234 while True:
235 try:
236 cd_id = int(input("Enter the ID number of your CD: "))
237 break
238 except ValueError:
239 print("Please only enter whole numbers.")
240 # Collect the CD Title
241 cd_title = input("Enter the Title of the CD: ")
242 # Collect the CD Artist's Name
243 cd_artist = input("Enter the Artist who created the CD: ")
244 # Create a CD object with the provided information
245 cd = CD(cd_id, cd_title, cd_artist)
246 # Create CD with entered information
247 lst_of_cd_objects.append(cd)
248 IO.show_inventory(lst_of_cd_objects)
249 return lst_of_cd_objects
250
251
252# -- Main -- #
253# When program starts, read in the currently saved Inventory, if it exists.
254# Otherwise, create the inventory file.
255try:
256 lst_of_cd_objects = FileIO.load_inventory(str_file_name, lst_of_cd_objects)
257except FileNotFoundError:
258 FileIO.create_file(str_file_name)
259
260# Start main loop
261while True:
262 # Display Menu to user, and get choice
263 IO.print_menu(str_menu)
264 str_choice = IO.menu_choice()
265
266 # Exit
267 if str_choice == 'x':
268 break
269
270 # Load Inventory.
271 if str_choice == 'l':
272 lst_of_cd_objects = FileIO.load_inventory(
273 str_file_name, lst_of_cd_objects)
274 continue # start loop back at top.
275
276 # Add a CD.
277 elif str_choice == 'a':
278 # Ask user for new ID, CD Title and Artist,
279 lst_of_cd_objects = IO.add_cd(lst_of_cd_objects)
280 continue # start loop back at top.
281
282 # Display current inventory.
283 elif str_choice == 'i':
284 IO.show_inventory(lst_of_cd_objects)
285 continue # start loop back at top.
286
287 # Save inventory to file.
288 elif str_choice == 's':
289 FileIO.save_inventory(str_file_name, lst_of_cd_objects)
290 continue # start loop back at top.
291
292 # A catch-all, which should not be possible, as user choice gets
293 # vetted in IO, but to be safe.
294 else:
295 print("General Error!")
296