99
1010
1111class Model (ABC ):
12+ """The Model is the data layer of the application."""
1213 @abstractmethod
1314 def __iter__ (self ):
1415 pass
1516
1617 @abstractmethod
17- def get (self , item ) :
18+ def get (self , item : str ) -> dict :
1819 """Returns an object with a .items() call method
1920 that iterates over key,value pairs of its information."""
2021 pass
2122
2223 @property
2324 @abstractmethod
24- def item_type (self ):
25+ def item_type (self ) -> str :
2526 pass
2627
2728
2829class ProductModel (Model ):
30+ """The Model is the data layer of the application."""
2931 class Price (float ):
3032 """A polymorphic way to pass a float with a particular
3133 __str__ functionality."""
3234
33- def __str__ (self ):
35+ def __str__ (self ) -> str :
3436 return f"{ self :.2f} "
3537
3638 products = {
@@ -44,92 +46,98 @@ def __str__(self):
4446 def __iter__ (self ):
4547 yield from self .products
4648
47- def get (self , product ) :
49+ def get (self , product : str ) -> dict :
4850 try :
4951 return self .products [product ]
5052 except KeyError as e :
5153 raise KeyError (str (e ) + " not in the model's item list." )
5254
5355
5456class View (ABC ):
57+ """The View is the presentation layer of the application."""
5558 @abstractmethod
56- def show_item_list (self , item_type , item_list ) :
59+ def show_item_list (self , item_type : str , item_list : dict ) -> None :
5760 pass
5861
5962 @abstractmethod
60- def show_item_information (self , item_type , item_name , item_info ) :
63+ def show_item_information (self , item_type : str , item_name : str , item_info : dict ) -> None :
6164 """Will look for item information by iterating over key,value pairs
6265 yielded by item_info.items()"""
6366 pass
6467
6568 @abstractmethod
66- def item_not_found (self , item_type , item_name ) :
69+ def item_not_found (self , item_type : str , item_name : str ) -> None :
6770 pass
6871
6972
7073class ConsoleView (View ):
71- def show_item_list (self , item_type , item_list ):
74+ """The View is the presentation layer of the application."""
75+ def show_item_list (self , item_type : str , item_list : dict ) -> None :
7276 print (item_type .upper () + " LIST:" )
7377 for item in item_list :
7478 print (item )
7579 print ("" )
7680
7781 @staticmethod
78- def capitalizer (string ):
82+ def capitalizer (string : str ) -> str :
83+ """Capitalizes the first letter of a string and lowercases the rest."""
7984 return string [0 ].upper () + string [1 :].lower ()
8085
81- def show_item_information (self , item_type , item_name , item_info ):
86+ def show_item_information (self , item_type : str , item_name : str , item_info : dict ) -> None :
87+ """Will look for item information by iterating over key,value pairs"""
8288 print (item_type .upper () + " INFORMATION:" )
8389 printout = "Name: %s" % item_name
8490 for key , value in item_info .items ():
8591 printout += ", " + self .capitalizer (str (key )) + ": " + str (value )
8692 printout += "\n "
8793 print (printout )
8894
89- def item_not_found (self , item_type , item_name ) :
95+ def item_not_found (self , item_type : str , item_name : str ) -> None :
9096 print (f'That { item_type } "{ item_name } " does not exist in the records' )
9197
9298
9399class Controller :
94- def __init__ (self , model , view ):
95- self .model = model
96- self .view = view
100+ """The Controller is the intermediary between the Model and the View."""
101+ def __init__ (self , model_class : Model , view_class : View ) -> None :
102+ self .model : Model = model_class
103+ self .view : View = view_class
97104
98- def show_items (self ):
105+ def show_items (self ) -> None :
99106 items = list (self .model )
100107 item_type = self .model .item_type
101108 self .view .show_item_list (item_type , items )
102109
103- def show_item_information (self , item_name ) :
110+ def show_item_information (self , item_name : str ) -> None :
104111 """
105112 Show information about a {item_type} item.
106113 :param str item_name: the name of the {item_type} item to show information about
107114 """
108115 try :
109- item_info = self .model .get (item_name )
116+ item_info : str = self .model .get (item_name )
110117 except Exception :
111- item_type = self .model .item_type
118+ item_type : str = self .model .item_type
112119 self .view .item_not_found (item_type , item_name )
113120 else :
114- item_type = self .model .item_type
121+ item_type : str = self .model .item_type
115122 self .view .show_item_information (item_type , item_name , item_info )
116123
117124
118125class Router :
126+ """The Router is the entry point of the application."""
119127 def __init__ (self ):
120128 self .routes = {}
121129
122- def register (self , path , controller , model , view ) :
123- model = model ()
124- view = view ()
125- self .routes [path ] = controller ( model , view )
130+ def register (self , path : str , controller_class : Controller , model_class : Model , view_class : View ) -> None :
131+ model_instance : Model = model_class ()
132+ view_instance : View = view_class ()
133+ self .routes [path ] = controller_class ( model_instance , view_instance )
126134
127- def resolve (self , path ) :
135+ def resolve (self , path : str ) -> Controller :
128136 if self .routes .get (path ):
129- controller = self .routes [path ]
137+ controller : Controller = self .routes [path ]
130138 return controller
131139 else :
132- return None
140+ raise KeyError ( f"No controller registered for path ' { path } '" )
133141
134142
135143def main ():
@@ -168,13 +176,13 @@ def main():
168176if __name__ == "__main__" :
169177 router = Router ()
170178 router .register ("products" , Controller , ProductModel , ConsoleView )
171- controller = router .resolve (argv [1 ])
179+ controller : Controller = router .resolve (argv [1 ])
172180
173- command = str (argv [2 ]) if len (argv ) > 2 else None
174- args = ' ' .join (map (str , argv [3 :])) if len (argv ) > 3 else None
181+ action : str = str (argv [2 ]) if len (argv ) > 2 else ""
182+ args : str = ' ' .join (map (str , argv [3 :])) if len (argv ) > 3 else ""
175183
176- if hasattr (controller , command ):
177- command = getattr (controller , command )
184+ if hasattr (controller , action ):
185+ command = getattr (controller , action )
178186 sig = signature (command )
179187
180188 if len (sig .parameters ) > 0 :
@@ -185,7 +193,7 @@ def main():
185193 else :
186194 command ()
187195 else :
188- print (f"Command { command } not found in the controller." )
196+ print (f"Command { action } not found in the controller." )
189197
190198 import doctest
191199 doctest .testmod ()
0 commit comments