← Computer Programming II

Variant 1: Library Book

A library needs a LibraryBook class to track its books. Each book has a title, total copies, and borrowed copies.

  1. title is read-only (protected attribute, getter only).
  2. total_copies must be at least 1 — otherwise raise ValueError with "Total copies must be at least 1". Use a property; route initial value through the setter.
  3. borrowed_copies (default 0) cannot be negative ("Borrowed copies cannot be negative") and cannot exceed total_copies ("Borrowed copies cannot exceed total copies"). Use a property; route initial value through the setter.
  4. Read-only computed property available_copies returns total_copies - borrowed_copies.
  5. Method borrow(amount) increases borrowed copies. Amount must be positive ("Borrow amount must be positive") and not exceed available copies ("Not enough available copies").
  6. Method return_book(amount) decreases borrowed copies. Amount must be positive ("Return amount must be positive") and not exceed borrowed copies ("Cannot return more than borrowed").

Input

b = LibraryBook("Python Basics", 5)
print(b.title, b.available_copies)

b.borrow(3)
print(b.borrowed_copies, b.available_copies)

b.return_book(1)
print(b.borrowed_copies)

try:
    b.borrow(4)
except ValueError as e:
    print(e)

try:
    b.title = "X"
except AttributeError:
    print("Cannot change title")

Expected Output

Python Basics 5
3 2
2
Not enough available copies
Cannot change title

Variant 2: Gym Membership

A fitness center needs a GymMembership class. Each membership has a member name, monthly fee, and remaining months.

  1. member_name is read-only (protected attribute, getter only).
  2. monthly_fee must be positive ("Monthly fee must be positive"). Use a property; route initial value through the setter.
  3. remaining_months must be between 1 and 36 inclusive ("Remaining months must be between 1 and 36"). Use a property; route initial value through the setter.
  4. Read-only computed property total_cost returns monthly_fee * remaining_months.
  5. Method extend(months) adds months. Must be positive ("Extension must be positive"). Result must not exceed 36 ("Cannot exceed 36 months").
  6. Method apply_discount(percent) reduces the monthly fee by the given percentage. Percent must be between 1 and 50 inclusive ("Discount must be between 1 and 50").

Input

g = GymMembership("Bobur", 50.0, 12)
print(g.member_name, g.total_cost)

g.extend(6)
print(g.remaining_months)

g.apply_discount(10)
print(g.monthly_fee, g.total_cost)

try:
    g.extend(25)
except ValueError as e:
    print(e)

try:
    g.member_name = "X"
except AttributeError:
    print("Cannot change member name")

Expected Output

Bobur 600.0
18
45.0 810.0
Cannot exceed 36 months
Cannot change member name

Variant 3: Parking Lot

A parking system needs a ParkingLot class. Each lot has a name, total spaces, and occupied spaces.

  1. name is read-only (protected attribute, getter only).
  2. total_spaces must be at least 1 ("Total spaces must be at least 1"). Use a property; route initial value through the setter.
  3. occupied_spaces (default 0) cannot be negative ("Occupied spaces cannot be negative") and cannot exceed total_spaces ("Occupied spaces cannot exceed total spaces"). Use a property; route initial value through the setter.
  4. Read-only computed property free_spaces returns total_spaces - occupied_spaces.
  5. Read-only computed property occupancy_rate returns the occupancy percentage as a float rounded to one decimal place.
  6. Method park(cars) increases occupied spaces. Must be positive ("Number of cars must be positive") and not exceed free spaces ("Not enough free spaces").
  7. Method leave(cars) decreases occupied spaces. Must be positive ("Number of cars must be positive") and not exceed occupied spaces ("Cannot remove more cars than parked").

Input

lot = ParkingLot("Central", 30)
print(lot.name, lot.free_spaces, lot.occupancy_rate)

lot.park(20)
print(lot.occupied_spaces, lot.occupancy_rate)

lot.leave(5)
print(lot.free_spaces)

try:
    lot.park(20)
except ValueError as e:
    print(e)

try:
    lot.name = "X"
except AttributeError:
    print("Cannot change lot name")

Expected Output

Central 30 0.0
20 66.7
15
Not enough free spaces
Cannot change lot name

Variant 4: Concert Hall

A venue management system needs a ConcertHall class. Each hall has a name, total seats, and booked seats.

  1. name is read-only (protected attribute, getter only).
  2. total_seats must be at least 1 ("Total seats must be at least 1"). Use a property; route initial value through the setter.
  3. booked_seats (default 0) cannot be negative ("Booked seats cannot be negative") and cannot exceed total_seats ("Booked seats cannot exceed total seats"). Use a property; route initial value through the setter.
  4. Read-only computed property available_seats returns total_seats - booked_seats.
  5. Read-only computed property booking_rate returns the booking percentage as a float rounded to one decimal place.
  6. Method reserve(seats) increases booked seats. Must be positive ("Number of seats must be positive") and not exceed available seats ("Not enough available seats").
  7. Method cancel(seats) decreases booked seats. Must be positive ("Number of seats must be positive") and not exceed booked seats ("Cannot cancel more than booked").

Input

h = ConcertHall("Grand", 200)
print(h.name, h.available_seats, h.booking_rate)

h.reserve(150)
print(h.booked_seats, h.booking_rate)

h.cancel(30)
print(h.available_seats)

try:
    h.reserve(100)
except ValueError as e:
    print(e)

try:
    h.name = "X"
except AttributeError:
    print("Cannot change hall name")

Expected Output

Grand 200 0.0
150 75.0
80
Not enough available seats
Cannot change hall name

Variant 5: Warehouse

A logistics company needs a Warehouse class. Each warehouse has a name, total capacity (in crates), and stored crates.

  1. name is read-only (protected attribute, getter only).
  2. total_capacity must be at least 1 ("Total capacity must be at least 1"). Use a property; route initial value through the setter.
  3. stored_crates (default 0) cannot be negative ("Stored crates cannot be negative") and cannot exceed total_capacity ("Stored crates cannot exceed total capacity"). Use a property; route initial value through the setter.
  4. Read-only computed property free_space returns total_capacity - stored_crates.
  5. Read-only computed property usage_rate returns the usage percentage as a float rounded to one decimal place.
  6. Method store(crates) increases stored crates. Must be positive ("Number of crates must be positive") and not exceed free space ("Not enough free space").
  7. Method ship(crates) decreases stored crates. Must be positive ("Number of crates must be positive") and not exceed stored crates ("Cannot ship more than stored").

Input

w = Warehouse("East", 500)
print(w.name, w.free_space, w.usage_rate)

w.store(350)
print(w.stored_crates, w.usage_rate)

w.ship(100)
print(w.free_space)

try:
    w.store(300)
except ValueError as e:
    print(e)

try:
    w.name = "X"
except AttributeError:
    print("Cannot change warehouse name")

Expected Output

East 500 0.0
350 70.0
250
Not enough free space
Cannot change warehouse name

Variant 6: Hotel Floor

A hotel system needs a HotelFloor class. Each floor has a name, total rooms, and occupied rooms.

  1. name is read-only (protected attribute, getter only).
  2. total_rooms must be at least 1 ("Total rooms must be at least 1"). Use a property; route initial value through the setter.
  3. occupied_rooms (default 0) cannot be negative ("Occupied rooms cannot be negative") and cannot exceed total_rooms ("Occupied rooms cannot exceed total rooms"). Use a property; route initial value through the setter.
  4. Read-only computed property vacant_rooms returns total_rooms - occupied_rooms.
  5. Read-only computed property occupancy_rate returns the occupancy percentage as a float rounded to one decimal place.
  6. Method check_in(rooms) increases occupied rooms. Must be positive ("Number of rooms must be positive") and not exceed vacant rooms ("Not enough vacant rooms").
  7. Method check_out(rooms) decreases occupied rooms. Must be positive ("Number of rooms must be positive") and not exceed occupied rooms ("Cannot check out more than occupied").

Input

f = HotelFloor("Floor 3", 40)
print(f.name, f.vacant_rooms, f.occupancy_rate)

f.check_in(25)
print(f.occupied_rooms, f.occupancy_rate)

f.check_out(10)
print(f.vacant_rooms)

try:
    f.check_in(30)
except ValueError as e:
    print(e)

try:
    f.name = "X"
except AttributeError:
    print("Cannot change floor name")

Expected Output

Floor 3 40 0.0
25 62.5
25
Not enough vacant rooms
Cannot change floor name

Variant 7: Swimming Pool

A sports complex needs a SwimmingPool class. Each pool has a name, total lanes, and occupied lanes.

  1. name is read-only (protected attribute, getter only).
  2. total_lanes must be at least 1 ("Total lanes must be at least 1"). Use a property; route initial value through the setter.
  3. occupied_lanes (default 0) cannot be negative ("Occupied lanes cannot be negative") and cannot exceed total_lanes ("Occupied lanes cannot exceed total lanes"). Use a property; route initial value through the setter.
  4. Read-only computed property free_lanes returns total_lanes - occupied_lanes.
  5. Read-only computed property occupancy_rate returns the occupancy percentage as a float rounded to one decimal place.
  6. Method assign(lanes) increases occupied lanes. Must be positive ("Number of lanes must be positive") and not exceed free lanes ("Not enough free lanes").
  7. Method release(lanes) decreases occupied lanes. Must be positive ("Number of lanes must be positive") and not exceed occupied lanes ("Cannot release more than occupied").

Input

p = SwimmingPool("Olympic", 8)
print(p.name, p.free_lanes, p.occupancy_rate)

p.assign(6)
print(p.occupied_lanes, p.occupancy_rate)

p.release(2)
print(p.free_lanes)

try:
    p.assign(5)
except ValueError as e:
    print(e)

try:
    p.name = "X"
except AttributeError:
    print("Cannot change pool name")

Expected Output

Olympic 8 0.0
6 75.0
4
Not enough free lanes
Cannot change pool name

Variant 8: Server Rack

A data center needs a ServerRack class. Each rack has a name, total slots, and used slots.

  1. name is read-only (protected attribute, getter only).
  2. total_slots must be at least 1 ("Total slots must be at least 1"). Use a property; route initial value through the setter.
  3. used_slots (default 0) cannot be negative ("Used slots cannot be negative") and cannot exceed total_slots ("Used slots cannot exceed total slots"). Use a property; route initial value through the setter.
  4. Read-only computed property free_slots returns total_slots - used_slots.
  5. Read-only computed property usage_rate returns the usage percentage as a float rounded to one decimal place.
  6. Method install(servers) increases used slots. Must be positive ("Number of servers must be positive") and not exceed free slots ("Not enough free slots").
  7. Method remove(servers) decreases used slots. Must be positive ("Number of servers must be positive") and not exceed used slots ("Cannot remove more than installed").

Input

r = ServerRack("Rack-A1", 42)
print(r.name, r.free_slots, r.usage_rate)

r.install(30)
print(r.used_slots, r.usage_rate)

r.remove(6)
print(r.free_slots)

try:
    r.install(20)
except ValueError as e:
    print(e)

try:
    r.name = "X"
except AttributeError:
    print("Cannot change rack name")

Expected Output

Rack-A1 42 0.0
30 71.4
18
Not enough free slots
Cannot change rack name

Variant 9: Classroom

A school system needs a Classroom class. Each classroom has a name, total desks, and occupied desks.

  1. name is read-only (protected attribute, getter only).
  2. total_desks must be at least 1 ("Total desks must be at least 1"). Use a property; route initial value through the setter.
  3. occupied_desks (default 0) cannot be negative ("Occupied desks cannot be negative") and cannot exceed total_desks ("Occupied desks cannot exceed total desks"). Use a property; route initial value through the setter.
  4. Read-only computed property empty_desks returns total_desks - occupied_desks.
  5. Read-only computed property fill_rate returns the fill percentage as a float rounded to one decimal place.
  6. Method seat(students) increases occupied desks. Must be positive ("Number of students must be positive") and not exceed empty desks ("Not enough empty desks").
  7. Method dismiss(students) decreases occupied desks. Must be positive ("Number of students must be positive") and not exceed occupied desks ("Cannot dismiss more than seated").

Input

c = Classroom("Room 101", 35)
print(c.name, c.empty_desks, c.fill_rate)

c.seat(20)
print(c.occupied_desks, c.fill_rate)

c.dismiss(8)
print(c.empty_desks)

try:
    c.seat(25)
except ValueError as e:
    print(e)

try:
    c.name = "X"
except AttributeError:
    print("Cannot change classroom name")

Expected Output

Room 101 35 0.0
20 57.1
23
Not enough empty desks
Cannot change classroom name

Variant 10: Bike Station

A city bike-sharing system needs a BikeStation class. Each station has a name, total docks, and rented bikes.

  1. name is read-only (protected attribute, getter only).
  2. total_docks must be at least 1 ("Total docks must be at least 1"). Use a property; route initial value through the setter.
  3. rented_bikes (default 0) cannot be negative ("Rented bikes cannot be negative") and cannot exceed total_docks ("Rented bikes cannot exceed total docks"). Use a property; route initial value through the setter.
  4. Read-only computed property available_bikes returns total_docks - rented_bikes.
  5. Read-only computed property rental_rate returns the rental percentage as a float rounded to one decimal place.
  6. Method rent(bikes) increases rented bikes. Must be positive ("Number of bikes must be positive") and not exceed available bikes ("Not enough available bikes").
  7. Method dock(bikes) decreases rented bikes. Must be positive ("Number of bikes must be positive") and not exceed rented bikes ("Cannot dock more than rented").

Input

s = BikeStation("Central Park", 25)
print(s.name, s.available_bikes, s.rental_rate)

s.rent(15)
print(s.rented_bikes, s.rental_rate)

s.dock(5)
print(s.available_bikes)

try:
    s.rent(20)
except ValueError as e:
    print(e)

try:
    s.name = "X"
except AttributeError:
    print("Cannot change station name")

Expected Output

Central Park 25 0.0
15 60.0
15
Not enough available bikes
Cannot change station name

Variant 11: Flight

An airline system needs a Flight class. Each flight has a flight number, total seats, and booked seats.

  1. flight_number is read-only (protected attribute, getter only).
  2. total_seats must be at least 1 ("Total seats must be at least 1"). Use a property; route initial value through the setter.
  3. booked_seats (default 0) cannot be negative ("Booked seats cannot be negative") and cannot exceed total_seats ("Booked seats cannot exceed total seats"). Use a property; route initial value through the setter.
  4. Read-only computed property open_seats returns total_seats - booked_seats.
  5. Read-only computed property booking_rate returns the booking percentage as a float rounded to one decimal place.
  6. Method book(tickets) increases booked seats. Must be positive ("Number of tickets must be positive") and not exceed open seats ("Not enough open seats").
  7. Method cancel(tickets) decreases booked seats. Must be positive ("Number of tickets must be positive") and not exceed booked seats ("Cannot cancel more than booked").

Input

f = Flight("UZ-101", 180)
print(f.flight_number, f.open_seats, f.booking_rate)

f.book(120)
print(f.booked_seats, f.booking_rate)

f.cancel(30)
print(f.open_seats)

try:
    f.book(100)
except ValueError as e:
    print(e)

try:
    f.flight_number = "X"
except AttributeError:
    print("Cannot change flight number")

Expected Output

UZ-101 180 0.0
120 66.7
90
Not enough open seats
Cannot change flight number

Variant 12: Cinema Screen

A cinema needs a CinemaScreen class. Each screen has a name, total chairs, and taken chairs.

  1. name is read-only (protected attribute, getter only).
  2. total_chairs must be at least 1 ("Total chairs must be at least 1"). Use a property; route initial value through the setter.
  3. taken_chairs (default 0) cannot be negative ("Taken chairs cannot be negative") and cannot exceed total_chairs ("Taken chairs cannot exceed total chairs"). Use a property; route initial value through the setter.
  4. Read-only computed property open_chairs returns total_chairs - taken_chairs.
  5. Read-only computed property fill_rate returns the fill percentage as a float rounded to one decimal place.
  6. Method sell(tickets) increases taken chairs. Must be positive ("Number of tickets must be positive") and not exceed open chairs ("Not enough open chairs").
  7. Method refund(tickets) decreases taken chairs. Must be positive ("Number of tickets must be positive") and not exceed taken chairs ("Cannot refund more than sold").

Input

s = CinemaScreen("Screen 1", 120)
print(s.name, s.open_chairs, s.fill_rate)

s.sell(80)
print(s.taken_chairs, s.fill_rate)

s.refund(20)
print(s.open_chairs)

try:
    s.sell(70)
except ValueError as e:
    print(e)

try:
    s.name = "X"
except AttributeError:
    print("Cannot change screen name")

Expected Output

Screen 1 120 0.0
80 66.7
60
Not enough open chairs
Cannot change screen name