Design Pattern Examples
Overview of object-oriented design patterns
visitor_visitor_shop.py
Go to the documentation of this file.
6
7from abc import ABC, abstractmethod
8from typing import TypeAlias
9
10Visitor_Village : TypeAlias = "Visitor_Village"
11
12from .visitor_ordervisitor import OrderVisitor
13from .visitor_class import Visitor
14
15
16
17
27def are_list_contents_the_same(left: list, right: list):
28 matched = False
29 if len(left) == len(right):
30 matched = True
31 for left_item in left:
32 if left_item not in right:
33 matched = False
34 break
35 return matched
36
37
38
39
43class Visitor_Shop(ABC):
44
45
47
48
52 @property
53 def Name(self) -> str:
54 return self._shopName
55
56
57 @Name.setter
58 def Name(self, name : str) -> None:
59 self._shopName = name
60
61
67 @property
68 def Address(self) -> str:
69 return self._shopAddress
70
71
72 @Address.setter
73 def Address(self, address : str) -> None:
74 self._shopAddress = address
75
76
80 @property
81 def Village(self) -> Visitor_Village:
82 return self._village
83
84
85 @Village.setter
86 def Village(self, v : Visitor_Village) -> None:
87 self._village = v
88
89
95 @property
96 def IngredientsForItems(self) -> dict[str, list[str]]:
97 return self._ingredientsForItems
98
99
103 @IngredientsForItems.setter
104 def IngredientsForItems(self, ingredients : dict[str, list[str]]) -> None:
105 self._ingredientsForItems = ingredients
106
107
108 @property
109 def Inventory(self) -> dict[str, int]:
110 return self._inventory
111
112
113
114
115 def __init__(self) -> None:
116 self._shopName = ""
117 self._shopAddress = ""
118 self._village = None # type: Visitor_Village
119 self._ingredientsForItems = {} # type: dict[str, list[str]]
120 self._inventory = {} # type: dict[str, int]
121
122
133
134 #-------------------------------------------------------------------
135
136
142 def DoesShopSellItem(self, item : str) -> bool:
143 return item in self._ingredientsForItems
144
145
151 def IsItemInStock(self, item : str) -> bool:
152 return item in self.Inventory and self.Inventory[item] > 0
153
154
155
159 def AddItemToInventory(self, item : str) -> None:
160 if not item in self.Inventory:
161 self.Inventory[item] = 1
162 else:
163 self.Inventory[item] += 1
164
165
166
173 def StringizeList(self, items : list[str]) -> str:
174 return ", ".join(items)
175
176
177
188 def PlaceOrder(self, items : list[str]) -> bool:
189 orderPlaced = False
190 outOfStockItems = [] # type: list[str]
191 itemsInThisShop = [] # type: list[str]
192
193 for item in items:
194 if self.DoesShopSellItem(item):
195 if not self.IsItemInStock(item):
196 outOfStockItems.append(item)
197 itemsInThisShop.append(item)
198
199 if itemsInThisShop:
200 print(" {0}: Received an order for {1}.".format(
201 self.NameName, self.StringizeList(itemsInThisShop)))
202 orderPlaced = True
203
204 if outOfStockItems:
205 for itemToOrder in outOfStockItems:
206 if self._ingredientsForItems[itemToOrder]:
207 print(" {0}: {1} out of stock, ordering ingredients to make more...".format(
208 self.NameName, itemToOrder))
209 visitor = OrderVisitor(self._ingredientsForItems[itemToOrder])
210 self._village.Accept(visitor)
211 if are_list_contents_the_same(visitor.ItemsReceived, self._ingredientsForItems[itemToOrder]):
212 # verify the ingredients received matches the ingredients
213 # needed. Only then add 1 to the inventory.
214 self.AddItemToInventory(itemToOrder)
215 else:
216 # The ordered item has no ingredients so the
217 # ordered item will be magically added to inventory
218 print(" {0}: {1} out of stock, making...".format(
219 self.NameName, itemToOrder))
220 self.AddItemToInventory(itemToOrder)
221 return orderPlaced
222
223
224
233 def PickupOrder(self, items : list[str], itemsToBePickedUp : list[str]) -> None:
234 for item in items:
235 # If this shop sells the item and the item is in stock then
236 if self.DoesShopSellItem(item):
237 if self.IsItemInStock(item):
238 itemsToBePickedUp.append(item)
239 else:
240 print(" Error! {0}: Item {1} is not in the inventory when it should be.".format(
241 self.NameName, item))
242
243 if itemsToBePickedUp:
244 itemsReceivedFromThisShop = []
245 # Reduce inventory for the ordered items
246 for itemToBePickedUp in itemsToBePickedUp:
247 if self.DoesShopSellItem(itemToBePickedUp):
248 self.Inventory[itemToBePickedUp] -= 1
249 itemsReceivedFromThisShop.append(itemToBePickedUp)
250 output = self.StringizeList(itemsReceivedFromThisShop)
251 print(" {0}: Order picked up for {1}.".format(self.NameName, output))
252
253
254
260 @abstractmethod
261 def Accept(self, visitor : Visitor) -> None:
262 pass
263
A visitor used for ordering items from various shops.
None PickupOrder(self, list[str] items, list[str] itemsToBePickedUp)
Pick up the items sold by this shop (assumes the items were ordered already).
str Address(self)
Property getter for the address of the shop: value = o.Address.
None Accept(self, Visitor visitor)
The visitor will call this method on each element it wants to visit.
_ingredientsForItems
Map of ingredients required for inventory items.
bool PlaceOrder(self, list[str] items)
Place an order for the specified items.
_inventory
Inventory for this shop, keyed by ingredient name and holding the the count of each ingredient.
dict[str, int] Inventory(self)
Property getter for the inventory maintained by the shop: value = o.Inventory
bool IsItemInStock(self, str item)
Determine if this shop has the specified item in stock.
bool DoesShopSellItem(self, str item)
Determine if this shop sells the specified item.
None AddItemToInventory(self, str item)
Add the specified item to this shop's inventory.
str Name(self)
Property getter for the name of the shop: value = o.Name
None Name(self, str name)
Property setter for the name of the shop: o.Name = value
dict[str, list[str]] IngredientsForItems(self)
Property getter for the ingredients needed for each item sold by the shop: value = o....
str StringizeList(self, list[str] items)
Convert a string list to a comma-delimited string.
def are_list_contents_the_same(list left, list right)
Determine if the two string lists have the same contents.
Represents a collection of shops that can be visited.