Last active
July 24, 2025 11:22
-
-
Save komuw/1051fee3f90ff7f840b3f540ee98586d to your computer and use it in GitHub Desktop.
xyz.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# - 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