Update page 'Day 4 Homework'

2023-04-04 23:18:47 +02:00
parent 46bd4cdef9
commit 9540a45ad0
+205
@@ -0,0 +1,205 @@
As a recap, we've talked about how numbers work, how characters work, how characters are combined into text via lexers and parsers, and how numbers and text are combined via operators in custom classes:
```
Numbers ------------------------> Operators -> ?
Characters --(Lexers/Parsers) --> Operators -> ?
```
Today's homework is to think about how to design classes, or what the industry calls "object-oriented design." You have to be careful to minimize complexity when designing public interfaces and APIs to your code, otherwise this happens:
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition/blob/uinverse/src/main/java/com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/loop/LoopCondition.java
Remember fizzbuzz? This is a satirical version built using every object-oriented pattern in the book. There is an actual book on the subject, which is widely respected throughout the industry, and in some cases misused to overcomplicate code:
https://en.wikipedia.org/wiki/Design_Patterns
The assignment for today is to think about some everyday thing you interact with, such as an elevator, a pet, or anything which has tangible and measurable *inputs* and *outputs*. There are three files to look at in the `simulation` directory in this repository:
* SimulationRunner: a program to run simulation classes.
* Simulation: the interface definition for a simulation.
* HotdogSimulation: a class simulating a hot dog.
Design two versions of this object with the following shared criteria:
* Define the start, stop, tick, get_uses, and use methods.
* Ensure that the object expires when a reasonable number of ticks have passed.
One version of the object should be very simple, such as the hot dog example.
The other version of the object should be overly complicated, with verbs such as `weigh` to get its mass, `mood` to get its mood, `price_tag` to have it return its estimated value, and `go_to_moon` to send the object to the moon (in the case of the pet, it would probably explode and `use()` should return `False`). Try to define at least 20 different verbs you could use on the object, with associated instance variables to track its state so the verbs interact correctly. For example, a `throw` verb on a hot dog should reduce its mass, because some of its condiments will end up on the target.
Although it would be preferred to create a Python file that can be run under the simulator, a text specification is also acceptable. The important thing is for the object to have a consistent model of its state which accurately represents what would happen in real life when methods (verbs) are applied to it.
```
class Toaster:
def __init__(self):
self.ticks_left = 10
self.is_on = False
def get_uses(self):
return {
'toast': "Put bread in the toaster to make toast."
}
def start(self):
print("Toaster started.")
def use(self, *args, **kwargs):
if 'toast' in args:
if not self.is_on:
print("Turn the toaster on first!🔌")
return True
print("Toasting...")
self.ticks_left -= 1
if self.ticks_left == 0:
print("Toasting complete! 🍞")
return False
return True
def tick(self):
return True
def stop(self):
print("Toaster stopped. ⏸")
```
```
class AdvancedToaster:
def __init__(self):
self.ticks_left = 10
self.is_on = False
self.toastiness = 0
self.bread_count = 0
self.crumb_tray = []
self.temperature = None
self.weight = 1.5 # kg
self.voltage = 120 # V
self.power = 750 # W
self.materials = ['stainless steel', 'plastic', 'copper']
self.dimensions = {'length': 30, 'width': 20, 'height': 25} # cm
self.color = 'silver'
self.price = 50 # USD
def get_uses(self):
return {
'turn_on': "Turn on the toaster.",
'turn_off': "Turn off the toaster.",
'insert_bread': "Insert bread into the toaster.",
'eject_bread': "Eject bread from the toaster.",
'increase_toastiness': "Increase the level of toastiness.",
'decrease_toastiness': "Decrease the level of toastiness.",
'add_bread': "Add a slice of bread to the toaster.",
'remove_bread': "Remove a slice of bread from the toaster.",
'toast': "Toast the bread in the toaster.",
'empty_crumb_tray': "Empty the crumb tray.",
'weigh': "Weigh the toaster.",
'measure_voltage': "Measure the voltage of the toaster.",
'measure_power': "Measure the power of the toaster.",
'get_materials': "Get the materials the toaster is made of.",
'get_dimensions': "Get the dimensions of the toaster.",
'get_color': "Get the color of the toaster.",
'get_price_tag': "Get the estimated value of the toaster."
}
def start(self):
print("Toaster started.")
def set_temperature(self, temperature):
self.temperature = temperature
print(f"Toaster temperature set to {temperature} degrees Celsius.")
def get_temperature(self):
if self.temperature is not None:
print(f"Toaster temperature is {self.temperature} degrees Celsius.")
else:
print("Toaster temperature has not been set yet.")
def use(self, *args, **kwargs):
if 'turn_on' in args:
self.is_on = True
print("Toaster turned on.")
elif 'turn_off' in args:
self.is_on = False
print("Toaster turned off.")
elif 'insert_bread' in args:
if not self.is_on:
print("Turn the toaster on first!")
return True
if self.bread_count > 2:
print("Too many bread slices! Maximum is 2.")
return True
self.bread_count += 1
print(f"{self.bread_count} bread slice{'s' if self.bread_count > 1 else ''} inserted.")
elif 'eject_bread' in args:
if self.bread_count == 0:
print("No bread slices to eject.")
return True
self.bread_count -= 1
print("Bread slice ejected.")
elif 'decrease_toastiness' in args:
if self.toastiness > 0:
self.toastiness -= 1
print(f"Toastiness decreased to {self.toastiness}.")
elif 'add_bread' in args:
if self.bread_count < 2:
self.bread_count += 1
print(f"{self.bread_count} slice(s) of bread added to the toaster.")
elif 'remove_bread' in args:
if self.bread_count > 0:
self.bread_count -= 1
print(f"{self.bread_count} slice(s) of bread removed from the toaster.")
elif 'toast' in args:
if self.is_on and self.bread_count > 0:
print("Toasting bread...")
for i in range(self.toastiness):
print("Tick...")
print("Bread toasted!")
self.bread_count -= 1
elif not self.is_on:
print("Toaster is not turned on.")
elif self.bread_count == 0:
print("Toaster does not contain any bread.")
else:
print(f"DEBUG:Invalid use of the toaster.")
return False
elif 'empty_crumb_tray' in args:
self.crumb_tray = []
print("Crumb tray emptied.")
def weigh(self):
print(f"The weight of the toaster is {self.weight} kg.")
def measure_voltage(self):
# Method to measure the voltage of the toaster
print(f"The voltage of the toaster is {self.voltage} V.")
def measure_power(self):
# Method to measure the power of the toaster
print(f"The power of the toaster is {self.power} W.")
defer get_materials(self):
print(f"The toaster is made of: {', '.join(self.materials)}.")
defer get_dimensions(self):
print(f"The dimensions of the toaster are: {self.dimensions['length']} cm x {self.dimensions['width']} cm x {self.dimensions['height']} cm.")
defer get_color(self):
print(f"The color of the toaster is {self.color}.")
defer get_price_tag(self):
print(f"The estimated value of the toaster is {self.price_tag}.")
```