← Computer Programming II

Variant 1: Time Duration Tracker

Create a TimeDuration class to track and combine time spent on tasks, handling hours and minutes properly using magic methods.

  1. Define a class TimeDuration with __init__ taking hours and minutes. Convert any excess minutes into hours (e.g., 1 hour and 75 minutes should be stored as 2 hours and 15 minutes).
  2. Implement __str__ to return exactly: "{hours}h {minutes}m"
  3. Implement __repr__ to return exactly: "TimeDuration({hours}, {minutes})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another TimeDuration, return a new TimeDuration with combined hours and minutes.
    • If adding an int or float, treat it as extra minutes and return a new TimeDuration with the added minutes.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two durations represent the exact same amount of time (same hours and minutes). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the total time is strictly greater than zero.

Input

t1 = TimeDuration(1, 45)
t2 = TimeDuration(0, 30)
t3 = TimeDuration(2, 15)

print(str(t1))
print(repr(t1))
print(t1 + t2)
print(t1 + 20)
print((t1 + t2) == t3)
print(bool(TimeDuration(0, 0)))

Expected Output

1h 45m
TimeDuration(1, 45)
2h 15m
2h 5m
True
False

Variant 2: Inventory Stock Item

Create a StockItem class to manage products in a store, allowing items of the same type to be combined naturally using arithmetic operators.

  1. Define a class StockItem with __init__ taking name (string), price (float), and quantity (int).
  2. Implement __str__ to return exactly: "{name}: {quantity} in stock at ${price}"
  3. Implement __repr__ to return exactly: "StockItem('{name}', {price}, {quantity})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another StockItem, check if they have the same name. If so, return a new StockItem with the combined quantity and the price of the first item. If the names differ, return NotImplemented.
    • If adding an int, return a new StockItem with the quantity increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two StockItem objects have the same name and price (ignoring quantity). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the item’s quantity is greater than 0.

Input

item1 = StockItem("Apples", 2.5, 10)
item2 = StockItem("Apples", 2.5, 15)
item3 = StockItem("Bananas", 3.0, 0)

print(str(item1))
print(repr(item1))
print(item1 + item2)
print(item1 + 5)
print(item1 == item2)
print(bool(item1))
print(bool(item3))

Expected Output

Apples: 10 in stock at $2.5
StockItem('Apples', 2.5, 10)
Apples: 25 in stock at $2.5
Apples: 15 in stock at $2.5
True
True
False

Variant 3: Cargo Train Fleet

Create a CargoTrain class that manages a sequence of cargo cars and utilizes collection-based magic methods.

  1. Define a class CargoTrain with __init__ taking train_id (string). Inside __init__, initialize an empty list self.cars to hold the weights of individual cargo cars.
  2. Create a method add_car(self, weight) that appends the provided weight to self.cars.
  3. Implement __len__ to return the total number of cars currently attached to the train.
  4. Implement __str__ to return exactly: "Train {train_id} with {length} cars" (use len(self) to retrieve the length dynamically).
  5. Implement __repr__ to return exactly: "CargoTrain('{train_id}')"
  6. Implement __add__ to combine two CargoTrain objects using isinstance(). Return a new CargoTrain with a train_id formatted as "{id1}-{id2}". Set its cars list to be the concatenation of the cars lists from both trains. If the operand is not a CargoTrain, return NotImplemented.
  7. Implement __eq__ using isinstance() to return True if two trains have the exact same number of cars. Return NotImplemented otherwise.
  8. Implement __bool__ to return True if the train has at least one car attached.

Input

t1 = CargoTrain("Express")
t1.add_car(50)
t1.add_car(40)

t2 = CargoTrain("Local")
t2.add_car(30)

t4 = CargoTrain("Empty")

print(str(t1))
print(repr(t1))
print(len(t1))

t3 = t1 + t2
print(str(t3))
print(t3.cars)

print(t1 == t2)
print(bool(t1))
print(bool(t4))

Expected Output

Train Express with 2 cars
CargoTrain('Express')
2
Train Express-Local with 3 cars
[50, 40, 30]
False
True
False

Variant 4: Restaurant Order Item

Create an OrderItem class to manage dishes ordered at a restaurant, allowing identical dishes to be combined naturally using arithmetic operators.

  1. Define a class OrderItem with __init__ taking dish_name (string), unit_price (float), and portions (int).
  2. Implement __str__ to return exactly: "{dish_name}: {portions} portion(s) at ${unit_price}"
  3. Implement __repr__ to return exactly: "OrderItem('{dish_name}', {unit_price}, {portions})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another OrderItem, check if they have the same dish_name. If so, return a new OrderItem with the combined portions and the price of the first item. If the names differ, return NotImplemented.
    • If adding an int, return a new OrderItem with the portions increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two OrderItem objects have the same dish_name and unit_price (ignoring portions). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the item’s portions is greater than 0.

Input

item1 = OrderItem("Burger", 8.5, 2)
item2 = OrderItem("Burger", 8.5, 3)
item3 = OrderItem("Salad", 5.0, 0)

print(str(item1))
print(repr(item1))
print(item1 + item2)
print(item1 + 2)
print(item1 == item2)
print(bool(item1))
print(bool(item3))

Expected Output

Burger: 2 portion(s) at $8.5
OrderItem('Burger', 8.5, 2)
Burger: 5 portion(s) at $8.5
Burger: 4 portion(s) at $8.5
True
True
False

Variant 5: Event Ticket Booking

Create a TicketBooking class to manage ticket reservations for events, allowing identical bookings to be combined naturally using arithmetic operators.

  1. Define a class TicketBooking with __init__ taking event_name (string), ticket_price (float), and seat_count (int).
  2. Implement __str__ to return exactly: "{event_name}: {seat_count} seat(s) at ${ticket_price}"
  3. Implement __repr__ to return exactly: "TicketBooking('{event_name}', {ticket_price}, {seat_count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another TicketBooking, check if they have the same event_name. If so, return a new TicketBooking with the combined seat count and the price of the first booking. If the names differ, return NotImplemented.
    • If adding an int, return a new TicketBooking with the seat count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two TicketBooking objects have the same event_name and ticket_price (ignoring seat count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the booking’s seat_count is greater than 0.

Input

booking1 = TicketBooking("Concert", 50.0, 4)
booking2 = TicketBooking("Concert", 50.0, 2)
booking3 = TicketBooking("Play", 30.0, 0)

print(str(booking1))
print(repr(booking1))
print(booking1 + booking2)
print(booking1 + 3)
print(booking1 == booking2)
print(bool(booking1))
print(bool(booking3))

Expected Output

Concert: 4 seat(s) at $50.0
TicketBooking('Concert', 50.0, 4)
Concert: 6 seat(s) at $50.0
Concert: 7 seat(s) at $50.0
True
True
False

Variant 6: Bookstore Cart Item

Create a CartItem class to manage books in a shopping cart, allowing identical books to be combined naturally using arithmetic operators.

  1. Define a class CartItem with __init__ taking book_title (string), unit_price (float), and copies (int).
  2. Implement __str__ to return exactly: "{book_title}: {copies} copy(ies) at ${unit_price}"
  3. Implement __repr__ to return exactly: "CartItem('{book_title}', {unit_price}, {copies})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another CartItem, check if they have the same book_title. If so, return a new CartItem with the combined copies and the price of the first item. If the titles differ, return NotImplemented.
    • If adding an int, return a new CartItem with the copies increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two CartItem objects have the same book_title and unit_price (ignoring copies). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the item’s copies is greater than 0.

Input

item1 = CartItem("Python 101", 20.0, 1)
item2 = CartItem("Python 101", 20.0, 4)
item3 = CartItem("Data Science", 35.0, 0)

print(str(item1))
print(repr(item1))
print(item1 + item2)
print(item1 + 2)
print(item1 == item2)
print(bool(item1))
print(bool(item3))

Expected Output

Python 101: 1 copy(ies) at $20.0
CartItem('Python 101', 20.0, 1)
Python 101: 5 copy(ies) at $20.0
Python 101: 3 copy(ies) at $20.0
True
True
False

Variant 7: Game Loot Drop

Create a LootDrop class to manage items collected in a game, allowing identical loot items to be combined naturally using arithmetic operators.

  1. Define a class LootDrop with __init__ taking item_name (string), gold_value (float), and count (int).
  2. Implement __str__ to return exactly: "{item_name}: {count} drop(s) worth {gold_value}g"
  3. Implement __repr__ to return exactly: "LootDrop('{item_name}', {gold_value}, {count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another LootDrop, check if they have the same item_name. If so, return a new LootDrop with the combined count and the value of the first drop. If the names differ, return NotImplemented.
    • If adding an int, return a new LootDrop with the count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two LootDrop objects have the same item_name and gold_value (ignoring count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the drop’s count is greater than 0.

Input

drop1 = LootDrop("Health Potion", 15.0, 3)
drop2 = LootDrop("Health Potion", 15.0, 2)
drop3 = LootDrop("Mana Potion", 20.0, 0)

print(str(drop1))
print(repr(drop1))
print(drop1 + drop2)
print(drop1 + 5)
print(drop1 == drop2)
print(bool(drop1))
print(bool(drop3))

Expected Output

Health Potion: 3 drop(s) worth 15.0g
LootDrop('Health Potion', 15.0, 3)
Health Potion: 5 drop(s) worth 15.0g
Health Potion: 8 drop(s) worth 15.0g
True
True
False

Variant 8: Crypto Portfolio Holding

Create a CryptoHolding class to manage digital currency assets, allowing identical coin holdings to be combined naturally using arithmetic operators.

  1. Define a class CryptoHolding with __init__ taking token_name (string), usd_price (float), and coin_amount (int).
  2. Implement __str__ to return exactly: "{token_name}: {coin_amount} coin(s) at ${usd_price}"
  3. Implement __repr__ to return exactly: "CryptoHolding('{token_name}', {usd_price}, {coin_amount})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another CryptoHolding, check if they have the same token_name. If so, return a new CryptoHolding with the combined coin amount and the price of the first holding. If the names differ, return NotImplemented.
    • If adding an int, return a new CryptoHolding with the coin amount increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two CryptoHolding objects have the same token_name and usd_price (ignoring coin amount). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the holding’s coin_amount is greater than 0.

Input

holding1 = CryptoHolding("Bitcoin", 65000.0, 2)
holding2 = CryptoHolding("Bitcoin", 65000.0, 1)
holding3 = CryptoHolding("Ethereum", 3500.0, 0)

print(str(holding1))
print(repr(holding1))
print(holding1 + holding2)
print(holding1 + 4)
print(holding1 == holding2)
print(bool(holding1))
print(bool(holding3))

Expected Output

Bitcoin: 2 coin(s) at $65000.0
CryptoHolding('Bitcoin', 65000.0, 2)
Bitcoin: 3 coin(s) at $65000.0
Bitcoin: 6 coin(s) at $65000.0
True
True
False

Variant 9: Construction Material Batch

Create a MaterialBatch class to manage construction supplies, allowing batches of the same material to be combined naturally using arithmetic operators.

  1. Define a class MaterialBatch with __init__ taking material_name (string), cost_per_unit (float), and unit_count (int).
  2. Implement __str__ to return exactly: "{material_name}: {unit_count} unit(s) at ${cost_per_unit}"
  3. Implement __repr__ to return exactly: "MaterialBatch('{material_name}', {cost_per_unit}, {unit_count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another MaterialBatch, check if they have the same material_name. If so, return a new MaterialBatch with the combined unit count and the cost of the first batch. If the names differ, return NotImplemented.
    • If adding an int, return a new MaterialBatch with the unit count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two MaterialBatch objects have the same material_name and cost_per_unit (ignoring unit count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the batch’s unit_count is greater than 0.

Input

batch1 = MaterialBatch("Bricks", 0.5, 100)
batch2 = MaterialBatch("Bricks", 0.5, 50)
batch3 = MaterialBatch("Cement", 8.0, 0)

print(str(batch1))
print(repr(batch1))
print(batch1 + batch2)
print(batch1 + 200)
print(batch1 == batch2)
print(bool(batch1))
print(bool(batch3))

Expected Output

Bricks: 100 unit(s) at $0.5
MaterialBatch('Bricks', 0.5, 100)
Bricks: 150 unit(s) at $0.5
Bricks: 300 unit(s) at $0.5
True
True
False

Variant 10: Pharmacy Prescription

Create a Prescription class to manage medication orders, allowing identical medications to be combined naturally using arithmetic operators.

  1. Define a class Prescription with __init__ taking medication_name (string), price_per_pill (float), and pill_count (int).
  2. Implement __str__ to return exactly: "{medication_name}: {pill_count} pill(s) at ${price_per_pill}"
  3. Implement __repr__ to return exactly: "Prescription('{medication_name}', {price_per_pill}, {pill_count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another Prescription, check if they have the same medication_name. If so, return a new Prescription with the combined pill count and the price of the first prescription. If the names differ, return NotImplemented.
    • If adding an int, return a new Prescription with the pill count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two Prescription objects have the same medication_name and price_per_pill (ignoring pill count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the prescription’s pill_count is greater than 0.

Input

script1 = Prescription("Amoxicillin", 1.2, 30)
script2 = Prescription("Amoxicillin", 1.2, 15)
script3 = Prescription("Ibuprofen", 0.8, 0)

print(str(script1))
print(repr(script1))
print(script1 + script2)
print(script1 + 10)
print(script1 == script2)
print(bool(script1))
print(bool(script3))

Expected Output

Amoxicillin: 30 pill(s) at $1.2
Prescription('Amoxicillin', 1.2, 30)
Amoxicillin: 45 pill(s) at $1.2
Amoxicillin: 40 pill(s) at $1.2
True
True
False

Variant 11: Office Supply Order

Create an OfficeSupply class to manage corporate stationary orders, allowing identical items to be combined naturally using arithmetic operators.

  1. Define a class OfficeSupply with __init__ taking item_name (string), price_per_box (float), and box_count (int).
  2. Implement __str__ to return exactly: "{item_name}: {box_count} box(es) at ${price_per_box}"
  3. Implement __repr__ to return exactly: "OfficeSupply('{item_name}', {price_per_box}, {box_count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another OfficeSupply, check if they have the same item_name. If so, return a new OfficeSupply with the combined box count and the price of the first item. If the names differ, return NotImplemented.
    • If adding an int, return a new OfficeSupply with the box count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two OfficeSupply objects have the same item_name and price_per_box (ignoring box count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the item’s box_count is greater than 0.

Input

supply1 = OfficeSupply("Printer Paper", 25.0, 5)
supply2 = OfficeSupply("Printer Paper", 25.0, 3)
supply3 = OfficeSupply("Stapler", 12.5, 0)

print(str(supply1))
print(repr(supply1))
print(supply1 + supply2)
print(supply1 + 2)
print(supply1 == supply2)
print(bool(supply1))
print(bool(supply3))

Expected Output

Printer Paper: 5 box(es) at $25.0
OfficeSupply('Printer Paper', 25.0, 5)
Printer Paper: 8 box(es) at $25.0
Printer Paper: 7 box(es) at $25.0
True
True
False

Variant 12: Bakery Pastry Batch

Create a PastryBatch class to manage baked goods, allowing batches of the same pastry to be combined naturally using arithmetic operators.

  1. Define a class PastryBatch with __init__ taking pastry_name (string), price_per_piece (float), and piece_count (int).
  2. Implement __str__ to return exactly: "{pastry_name}: {piece_count} piece(s) at ${price_per_piece}"
  3. Implement __repr__ to return exactly: "PastryBatch('{pastry_name}', {price_per_piece}, {piece_count})"
  4. Implement __add__ to handle two cases using isinstance():
    • If adding another PastryBatch, check if they have the same pastry_name. If so, return a new PastryBatch with the combined piece count and the price of the first batch. If the names differ, return NotImplemented.
    • If adding an int, return a new PastryBatch with the piece count increased by that integer value.
    • Otherwise, return NotImplemented.
  5. Implement __eq__ using isinstance() to return True if two PastryBatch objects have the same pastry_name and price_per_piece (ignoring piece count). Return NotImplemented otherwise.
  6. Implement __bool__ to return True if the batch’s piece_count is greater than 0.

Input

batch1 = PastryBatch("Croissant", 3.5, 12)
batch2 = PastryBatch("Croissant", 3.5, 6)
batch3 = PastryBatch("Muffin", 4.0, 0)

print(str(batch1))
print(repr(batch1))
print(batch1 + batch2)
print(batch1 + 10)
print(batch1 == batch2)
print(bool(batch1))
print(bool(batch3))

Expected Output

Croissant: 12 piece(s) at $3.5
PastryBatch('Croissant', 3.5, 12)
Croissant: 18 piece(s) at $3.5
Croissant: 22 piece(s) at $3.5
True
True
False