Xuanyi Wang_Day-4_Homework_04/03/23
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:
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.
1. One version of the object should be very simple, such as the hot dog example.
The Simple Version of Water Bottle Object:
class WaterBottle:
def __init__(self, max_uses):
self.uses = 0
self.max_uses = max_uses
def start(self):
pass
def stop(self):
pass
def tick(self):
self.uses += 1
if self.uses >= self.max_uses:
return False
return True
def get_uses(self):
return self.uses
def use(self):
return "You take a sip of water."
2. 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.
The complicated version of Water Bottle Object:
class WaterBottle:
def __init__(self, max_uses):
self.uses = 0
self.max_uses = max_uses
self.volume = 1000 # in milliliters
self.temperature = 20 # in celsius
self.color = "multi"
self.brand = "Takeya"
self.material = "stainless"
def start(self):
self.temperature = 25
def stop(self):
pass
def tick(self):
self.uses += 1
if self.uses >= self.max_uses:
return False
return True
def get_uses(self):
return self.uses
def use(self):
if self.volume >= 100:
self.volume -= 100
return "You take a sip of water."
else:
return "There is not enough water in the bottle."
def weigh(self):
return self.volume * 1.0 # density of water is 1 g/cm^3
def set_color(self, color):
self.color = color
def get_color(self):
return self.color
def set_brand(self, brand):
self.brand = brand
def get_brand(self):
return self.brand
def set_material(self, material):
self.material = material
def get_material(self):
return self.material
def set_temperature(self, temperature):
self.temperature = temperature
def get_temperature(self):
return self.temperature
def price_tag(self):
return "$26.50"
def BPA_Free_solution(self):
return "The water bottle is a BPA free one."
def Insulated_Spout_Lid(self):
return "This stainless steel water bottle comes with an innovative leakproof insulated spout lid that allows for easy one-handed drinking or pouring. It features a hinge lock that keeps the cap out of your way while drinking."
def freeze(self):
self.temperature = -5
def melt(self):
self.temperature = 20
def recycle(self):
self.material = "recycled stainless"
def refill(self):
self.volume = 1000
def pour_out(self, amount):
if self.volume >= amount:
self.volume -= amount
return "You pour out {} milliliters of water.".format(amount)
else:
return "There is not enough water in the bottle."
def add_water(self, amount):
self.volume += amount
return "You add {} milliliters of water.".format(amount)
def add_ice(self, amount):
self.volume += amount
self.temperature = -10
return "You add {} grams of ice.".format(amount)
def add_lemon(self):
return "You add a slice of lemon to the water."
def add_sugar(self, amount):
return "You add {} grams of sugar to the water.".format(amount)
def add_salt(self, amount):
return "You add {} grams of salt to the water.".format(amount)
def add_tea(self, amount):
return "You add {} grams of tea to the water.".format(amount)
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.