CMU Coding Bootcamp
1from typing import override
2
3
4class Room:
5 name: str
6 length: float
7 width: float
8
9 def __init__(self, name: str, length: float, width: float):
10 self.name = name
11 self.length = length
12 self.width = width
13
14 @override
15 def __repr__(self) -> str:
16 return f"Room({self.length}'x{self.width}' {self.name})"
17
18 def getArea(self) -> float:
19 return self.length * self.width
20
21
22class Floor:
23 name: str
24 room_map: dict[str, Room]
25
26 def __init__(self, name: str):
27 self.name = name
28 self.room_map = dict()
29
30 @override
31 def __repr__(self) -> str:
32 return f"Floor({self.name} with {len(self.room_map)} room(s))"
33
34 def addRoom(self, room: Room) -> None:
35 if room.name in self.room_map:
36 raise LookupError(f"{room.name} already exists on this floor")
37 else:
38 self.room_map[room.name] = room
39
40 def getRoomCount(self) -> int:
41 return len(self.room_map)
42
43 def getRoom(self, name: str) -> Room | None:
44 return self.room_map.get(name, None)
45
46 def getRoomNames(self) -> list[str]:
47 return sorted(self.room_map.keys())
48
49 def getArea(self) -> float:
50 return sum([r.getArea() for r in self.room_map.values()])
51
52
53class House:
54 floors: dict[str, Floor]
55
56 def __init__(self) -> None:
57 self.floors = dict()
58
59 @override
60 def __repr__(self) -> str:
61 return f"House({self.getFloorCount()} floor(s), {self.getRoomCount()} room(s), {self.getArea()} sq feet)"
62
63 def addFloor(self, floor: Floor) -> None:
64 if floor.name in self.floors:
65 raise LookupError(f"{floor.name} already exists on this floor")
66 else:
67 self.floors[floor.name] = floor
68
69 def getFloorCount(self) -> int:
70 return len(self.floors)
71
72 def getRoomCount(self) -> int:
73 return sum([f.getRoomCount() for f in self.floors.values()])
74
75 def getArea(self) -> float:
76 return sum([f.getArea() for f in self.floors.values()])
77
78 def getRoomFloor(self, room_name: str) -> Floor | None:
79 for floor in self.floors.values():
80 if room_name in floor.getRoomNames():
81 return floor
82 else:
83 return None
84
85 def getRoom(self, room_name: str) -> Room | None:
86 floor = self.getRoomFloor(room_name)
87 if floor == None:
88 return None
89 else:
90 return floor.getRoom(room_name)
91
92
93def testLevel1():
94 print("Testing Level 1 (Core) material...", end="")
95
96 # Note: a Room represents a room, on a Floor, in a House.
97
98 room1 = Room("Living Room", 15, 15) # name, length, width
99 assert str(room1) == "Room(15'x15' Living Room)"
100 assert str([room1]) == "[Room(15'x15' Living Room)]"
101 assert room1.getArea() == 225 # 15 * 15
102
103 room2 = Room("Kitchen", 10, 20)
104 assert str(room2) == "Room(10'x20' Kitchen)"
105 assert room2.getArea() == 200 # 10 * 20
106
107 # Notes:
108 # * Each Floor can contain 0 or more rooms.
109 # * Store the rooms in floor.roomMap, which is a dictionary
110 # mapping the room name to the room instance.
111 # * Do not store a floor's roomCount or roomNames separately.
112 # Instead, compute these based on the keys in floor.roomMap.
113
114 floor1 = Floor("1st Floor")
115 assert str(floor1) == "Floor(1st Floor with 0 room(s))"
116 assert floor1.getRoomCount() == 0
117 assert floor1.getRoomNames() == []
118 assert floor1.getArea() == 0
119
120 floor1.addRoom(room1)
121 assert str(floor1) == "Floor(1st Floor with 1 room(s))"
122 assert floor1.getRoomCount() == 1
123 assert floor1.getRoomNames() == ["Living Room"]
124 assert floor1.getArea() == 225
125
126 floor1.addRoom(room2)
127 assert str(floor1) == "Floor(1st Floor with 2 room(s))"
128 assert floor1.getRoomCount() == 2
129
130 # Note that getRoomNames returns a *sorted* list of room names:
131 assert floor1.getRoomNames() == ["Kitchen", "Living Room"]
132 assert floor1.getArea() == 425
133
134 # We will try to add the Kitchen room again.
135 # We are not allowed to add the same room twice,
136 # nor even two rooms with the same name on any floor.
137 error = None
138 try:
139 floor1.addRoom(room2)
140 except Exception as e:
141 error = str(e)
142 assert error == "Kitchen already exists on this floor"
143
144 assert floor1.getRoom("Living Room") == room1
145 assert floor1.getRoom("Kitchen") == room2
146 assert floor1.getRoom("Study") == None
147
148 room3 = Room("Attic", 20, 30)
149 assert str(room3) == "Room(20'x30' Attic)"
150 assert room3.getArea() == 600 # 20 * 30
151
152 floor2 = Floor("2nd Floor")
153 floor2.addRoom(room3)
154 assert str(floor2) == "Floor(2nd Floor with 1 room(s))"
155 assert floor2.getArea() == 600 # 20 * 30
156 print("Passed!")
157
158
159def testLevel2():
160 print("Testing Level 2+ (Not Core) material...", end="")
161 room1 = Room("Living Room", 15, 15)
162 room2 = Room("Kitchen", 10, 20)
163 floor1 = Floor("1st Floor")
164 floor1.addRoom(room1)
165 floor1.addRoom(room2)
166 room3 = Room("Attic", 20, 30)
167 floor2 = Floor("2nd Floor")
168 floor2.addRoom(room3)
169
170 house = House()
171 assert house.getFloorCount() == 0
172 assert house.getRoomCount() == 0
173 assert house.getArea() == 0
174 assert str(house) == "House(0 floor(s), 0 room(s), 0 sq feet)"
175
176 house.addFloor(floor1)
177 assert house.getFloorCount() == 1
178 assert house.getRoomCount() == 2
179 assert house.getArea() == 425
180 assert str(house) == "House(1 floor(s), 2 room(s), 425 sq feet)"
181
182 house.addFloor(floor2)
183 assert str(house) == "House(2 floor(s), 3 room(s), 1025 sq feet)"
184
185 assert house.getFloorCount() == 2
186 assert house.getRoomCount() == 3
187 assert house.getArea() == 1025
188
189 assert house.getRoomFloor("Kitchen") == floor1
190 assert house.getRoomFloor("Attic") == floor2
191 assert house.getRoomFloor("Study") == None
192
193 assert house.getRoom("Kitchen") == room2
194 assert house.getRoom("Attic") == room3
195 assert house.getRoom("Study") == None
196 print("Passed!")
197
198
199def main():
200 testLevel1()
201 testLevel2()
202
203
204main()