Skip to content

Instantly share code, notes, and snippets.

@komuw
Last active July 24, 2025 11:22
Show Gist options
  • Save komuw/1051fee3f90ff7f840b3f540ee98586d to your computer and use it in GitHub Desktop.
Save komuw/1051fee3f90ff7f840b3f540ee98586d to your computer and use it in GitHub Desktop.
xyz.py
# - OOPs helps users to understand the software easily,dont need to know actual implementation.
# - increase readability, maintainability of code.
# - Procedural programming specifies the steps a program must take to reach the desired state, usually read in order from top to bottom.
# (a) encapsulation - bundling up attributes & methods that operate on data into a single unit(eg, class)
# (b) abstraction - showing only essential info, hide implementation detail.
# (c) inheritance - derived class can inherit properties and behaviour
# (d) polymorphism - ability of obj to take many forms. different classes can be treated as an obj of a common type.
# access specifiers: public, private, etc
# class A(B): single inheritance.
# class A(B, C): multiple inheritance.
import logging
class Simple(logging.Logger):
def __init__( self, name, level,age ):
super(Simple, self).__init__(name=name, level= level)
isinstance(name, str)
self.age=age
sl=Simple("name", "INFO", 44)
print("isinstance(Simple(), logging.Logger): ", isinstance(sl, logging.Logger))
# interface: class which contains methods, but not their definition
import abc
class Shape(abc.ABC):
@abc.abstractmethod
def area(self):
pass
class Circle(Shape):
def area(self):
print("circle area: ", 40)
return 40
class Square(Shape): # TypeError
def no_area(self):
return 18
crl = Circle()
crl.area()
import sys
print("sys.getsizeof(crl): ", sys.getsizeof(crl))
print("sys.getsizeof(Circle): ", sys.getsizeof(Circle))
#### Design a musical jukebox using object-oriented principles.
import typing
from dataclasses import dataclass
@dataclass
class Song:
title: str
artist: str
genre: str
duration: int
# def __str__(self):
# return f"Song({self.title} by {self.artist} {self.duration}sec)"
def play(self):
print(f"Now playing: {self}")
import time;time.sleep(self.duration) # simulate play
print(f"Finished playing: {self.title}")
sng = Song(title="hey", artist="Solomon",genre="reggae", duration=1)
print("song: ", sng)
sng.play()
@dataclass
class Album:
title: str
artist: str
songs: typing.List[Song]
def add_song(self, song):
if not isinstance(song, Song):
raise TypeError(f"{song} is not of type Song")
self.songs.append(song)
print("added song to album: ", self.songs)
alb = Album(title="sunshine", artist="solomon", songs=[Song(title="hey", artist="Solomon",genre="reggae", duration=230)])
# alb.add_song(23)
alb.add_song(Song(title="two", artist="john",genre="reggae", duration=921))
@dataclass
class Playlist:
name: str
songs: typing.List[Song]
_current_index = 0
def add_song(self, song:Song):
if not isinstance(song, Song):
raise TypeError(f"{song} is not of type Song")
self.songs.append(song)
print("added song to Playlist: ", self.songs)
def play(self):
for sng in self.songs:
sng.play()
@dataclass
class Jukebox:
name :str
playlists: typing.Dict[str, Playlist]
def add_playlist(self, name:str, lst: Playlist):
if not isinstance(lst, Playlist):
raise TypeError(f"{lst} is not of type Playlist")
self.playlists[name] = lst
def add_song(self, playlist_name:str, song:Song):
if not isinstance(song, Song):
raise TypeError(f"{song} is not of type Song")
lst = self.playlists.get(playlist_name)
if lst is None:
# todo: create
pass
lst.add_song(song)
self.playlists[playlist_name] = lst
def play(self, playlist_name:str):
if playlist_name=="":
lst = self.playlists[list(self.playlists.keys())[0]]
lst.play()
else:
lst = self.playlists[playlist_name]
lst.play()
jk = Jukebox("my jukebox", playlists={})
jk.add_playlist("list1", Playlist("list1", songs=[Song(title="song1", artist="Solomon",genre="reggae", duration=2), Song(title="song2", artist="John",genre="reggae", duration=3)]))
jk.add_song("list1", Song(title="song3", artist="Solomon",genre="rap", duration=4))
# jk.play("")
# Design a parking lot using object-oriented principles.
import time, abc, uuid, datetime
@dataclass
class Vehicle(abc.ABC):
license_plate:str
type:str
ticket_id:str
@abc.abstractmethod
def can_fit_spot(self, spot_size):
pass
class Bus(Vehicle):
def can_fit_spot(self, spot_size):
return spot_size =="large"
class Car(Vehicle):
def can_fit_spot(self, spot_size):
return spot_size in ["large", "medium", "small"]
# bus=Bus(license_plate="kca 122g", type="bus")
@dataclass
class Spot:
name:str
size :str
is_occupied:bool=False
parked:Vehicle=None
def occupy(self, vehicle: Vehicle):
if not isinstance(vehicle, Vehicle):
raise TypeError(f"{vehicle} is not of type Vehicle")
if self.is_occupied:
return False
self.is_occupied = True
self.parked=vehicle
def vacate(self, vehicle: Vehicle):
if not isinstance(vehicle, Vehicle):
raise TypeError(f"{vehicle} is not of type Vehicle")
if vehicle==self.parked:
self.is_occupied=False
self.parked = None
@dataclass
class Ticket:
ticket_id:str
vehicle :Vehicle
spot :Spot
entry_time:time.time
exit_time = None
_fee :float = 0.0
rates = {"car": 100, "bus": 300} # shillings per hour.
def fee(self, exit_time):
self.exit_time = exit_time
duration = (self.exit_time - self.entry_time).total_seconds()/(60*60) # hours
return self.rates[self.vehicle.type] *duration
class ParkingLot:
def __init__(self, num_small_spots, num_medium_spots, num_large_spots):
self.spots: typing.Dict[str, Spot] = {'small': [], 'medium': [], 'large': []}
self.sizes = list(self.spots.keys())
self.occupied_spots = {} # {license_plate: Spot object}
self.tickets = {} # {ticket_id: Ticket object}
self._initialize_spots(num_small_spots, 'small')
self._initialize_spots(num_medium_spots, 'medium')
self._initialize_spots(num_large_spots, 'large')
def _initialize_spots(self, count, size_type):
for i in range(count):
sp = Spot(f"{size_type}-{count}", size_type)
self.spots[size_type].append(sp)
def park_vehicle(self, vehicle:Vehicle):
if vehicle.license_plate in self.occupied_spots:
return # raise error
spot=None
for _typ in self.sizes:
for spt in self.spots[_typ]:
if spt.is_occupied:
continue
if vehicle.can_fit_spot(spot_size=spt.size):
spot = spt
if not spot:
print("no spot available")
return
spot.occupy(vehicle)
self.occupied_spots[vehicle.license_plate] = spot
tkt = Ticket(ticket_id=uuid.uuid4(), vehicle=vehicle, spot=spot, entry_time=datetime.datetime.now())
self.tickets[tkt.ticket_id] = tkt
vehicle.ticket_id = tkt.ticket_id
print(f"\t parked vehicle{vehicle}, ticket: {tkt}")
return tkt
def exit_vehicle(self, vehicle:Vehicle):
if vehicle.license_plate not in self.occupied_spots:
return # error?
exit_time = datetime.datetime.now()
spot = self.occupied_spots[vehicle.license_plate]
ticket = self.tickets[vehicle.ticket_id]
fee = ticket.fee(exit_time)
spot.vacate(vehicle)
del self.occupied_spots[vehicle.license_plate]
del self.tickets[ticket.ticket_id]
print(f"\t exited vehicle{vehicle}, ticket: {ticket}, fee:{fee}")
parking_lot = ParkingLot( num_small_spots=2, num_medium_spots=3, num_large_spots=2 )
car1=Car(license_plate="kca 122g", type="car", ticket_id="")
parking_lot.park_vehicle(car1)
parking_lot.exit_vehicle(Car("ff","bus", "" ))
parking_lot.exit_vehicle(car1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment