From a0c93f674a4b8f4660aedb18886e2557e319641e Mon Sep 17 00:00:00 2001 From: Saphal47 Date: Sat, 10 Jan 2026 16:09:49 +0530 Subject: [PATCH] py implementation --- .../CommandPattern/python/commandInterface.py | 13 ++ .../CommandPattern/python/concreteCommand.py | 17 ++ .../CommandPattern/python/textEditor.py | 53 ++++++ .../IteratorPattern/python/Book.py | 12 ++ .../IteratorPattern/python/BookCollection.py | 52 ++++++ .../IteratorPattern/python/example1.py | 92 ++++++++++ .../IteratorPattern/python/main.py | 5 + .../python/airTrafficController.py | 165 ++++++++++++++++++ .../MediatorPattern/python/syntax.py | 87 +++++++++ .../MementoPattern/python/caretaker.py | 29 +++ .../MementoPattern/python/main.py | 32 ++++ .../MementoPattern/python/memento.py | 8 + .../MementoPattern/python/originator.py | 28 +++ .../ObserverPattern/python/main.py | 111 ++++++++++++ .../TemplateMethodPattern/python/csvParser.py | 11 ++ .../python/dataParser.py | 25 +++ .../python/jsonParser.py | 11 ++ .../TemplateMethodPattern/python/main.py | 26 +++ 18 files changed, 777 insertions(+) create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/commandInterface.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/concreteCommand.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/textEditor.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/Book.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/BookCollection.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/example1.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/main.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/airTrafficController.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/syntax.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/caretaker.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/main.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/memento.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/originator.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/ObserverPattern/python/main.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/csvParser.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/dataParser.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/jsonParser.py create mode 100644 design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/main.py diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/commandInterface.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/commandInterface.py new file mode 100644 index 0000000..7de6ada --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/commandInterface.py @@ -0,0 +1,13 @@ +# command interface +from abc import ABC, abstractmethod + + + +class CommandInterface: + """generic command interface""" + def __init__(self,editor): + self.editor = editor + + @abstractmethod + def execute(self): + pass diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/concreteCommand.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/concreteCommand.py new file mode 100644 index 0000000..4ca18e5 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/concreteCommand.py @@ -0,0 +1,17 @@ +#Implementing TextEditor and button operations via command pattern +from abc import ABC,abstractmethod +from commandInterface import CommandInterface + +class BoldCommand(CommandInterface): + """Bold command implemented via interface""" + + def execute(self): + return self.editor.boldText() + + +class ItalicCommand(CommandInterface): + """Italic command""" + + def execute(self): + return self.editor.italicText() + diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/textEditor.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/textEditor.py new file mode 100644 index 0000000..9825a76 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/CommandPattern/python/textEditor.py @@ -0,0 +1,53 @@ +from concreteCommand import BoldCommand,ItalicCommand + + +class TextEditor: + """Text editor class to process text""" + + def __init__(self,text): + self.text = text + + def boldText(self): + print(f"the {self.text} has been bolded!") + + def italicText(self): + print(f"the {self.text} has been italicized!") + + def underlineText(self): + print(f"the {self.text} has been underlined!") + + +class Button: + """Generic button class""" + def __init__(self): + self.command = None + + def setCommand(self, command): + self.command = command + + def click(self): + if self.command: + self.command.execute() + else: + print("Invalid command") + + + +def main(): + + editor = TextEditor("Hello world") + button = Button() + + + button.setCommand(BoldCommand(editor)) + button.click() + + button.setCommand(ItalicCommand(editor)) + button.click() + + +if __name__ == "__main__": + main() + + + diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/Book.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/Book.py new file mode 100644 index 0000000..892c910 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/Book.py @@ -0,0 +1,12 @@ +#Book class + +class Book: + + def __init__(self,title: str) -> None: + self.title = title + + def getTitle(self): + return self.title + + + \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/BookCollection.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/BookCollection.py new file mode 100644 index 0000000..22720cf --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/BookCollection.py @@ -0,0 +1,52 @@ +class Book: + def __init__(self, title): + self.title = title + + def __str__(self): + return f"Book{{title='{self.title}'}}" + + def __lt__(self, other): + return self.title < other.title + + +class BookCollectionV2: + def __init__(self): + self.books = [] + + def add_book(self, book): + self.books.append(book) + + def get_books(self): + return self.books + + def create_iterator(self): + return self.BookIterator(self.books) + + class BookIterator: + def __init__(self, books): + self.books = books + self.position = 0 + + def has_next(self): + return self.position < len(self.books) + + def next(self): + if not self.has_next(): + raise StopIteration + book = self.books[self.position] + self.position += 1 + return book + + +# Client Code +if __name__ == "__main__": + book_collection = BookCollectionV2() + book_collection.add_book(Book("C++ Book")) + book_collection.add_book(Book("Java Book")) + book_collection.add_book(Book("Python Book")) + + iterator = book_collection.create_iterator() + + while iterator.has_next(): + book = iterator.next() + print(book) diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/example1.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/example1.py new file mode 100644 index 0000000..a40f1ed --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/example1.py @@ -0,0 +1,92 @@ +from __future__ import annotations +from collections.abc import Iterable, Iterator +from typing import Any + + +""" + To create an iterator in Python, there are two abstract classes from the built- + in `collections` module - Iterable,Iterator. We need to implement the + `__iter__()` method in the iterated object (collection), and the `__next__ ()` + method in the iterator. +""" + + +class AlphabeticalOrderIterator(Iterator): + """ + Concrete Iterators implement various traversal algorithms. These classes + store the current traversal position at all times. + """ + + """ + `_position` attribute stores the current traversal position. An iterator may + have a lot of other fields for storing iteration state, especially when it + is supposed to work with a particular kind of collection. + """ + _position: int = None + """ + This attribute indicates the traversal direction. + """ + _reverse: bool = False + + def __init__(self, collection: WordsCollection, reverse: bool = False) -> None: + self._collection = collection + self._reverse = reverse + self._position = -1 if reverse else 0 + + + def __next__(self) -> Any: + """ + The __next__() method must return the next item in the sequence. On + reaching the end, and in subsequent calls, it must raise StopIteration. + """ + try: + value = self._collection[self._position] + self._position += -1 if self._reverse else 1 + except IndexError: + raise StopIteration() + + return value + + +class WordsCollection(Iterable): + """ + Concrete Collections provide one or several methods for retrieving fresh + iterator instances, compatible with the collection class. + """ + + def __init__(self, collection: list[Any] | None = None) -> None: + self._collection = collection or [] + + + def __getitem__(self, index: int) -> Any: + return self._collection[index] + + def __iter__(self) -> AlphabeticalOrderIterator: + """ + The __iter__() method returns the iterator object itself, by default we + return the iterator in ascending order. + """ + return AlphabeticalOrderIterator(self) + + def get_reverse_iterator(self) -> AlphabeticalOrderIterator: + return AlphabeticalOrderIterator(self, True) + + def add_item(self, item: Any) -> None: + self._collection.append(item) + + +if __name__ == "__main__": + # The client code may or may not know about the Concrete Iterator or + # Collection classes, depending on the level of indirection you want to keep + # in your program. + collection = WordsCollection() + collection.add_item("First") + collection.add_item("Second") + collection.add_item("Third") + + print("Straight traversal:") + print("\n".join(collection)) + print("") + + print("Reverse traversal:") + print("\n".join(collection.get_reverse_iterator()), end="") \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/main.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/main.py new file mode 100644 index 0000000..8ec73a4 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/IteratorPattern/python/main.py @@ -0,0 +1,5 @@ +#Designing a Book collection (library) which can be maintained in many ways +#list, set, tree etc. Provide an interface using Iterator to iterate over all the elements in the Collection +#hiding its internal implementation + + diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/airTrafficController.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/airTrafficController.py new file mode 100644 index 0000000..d3b72f8 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/airTrafficController.py @@ -0,0 +1,165 @@ +from __future__ import annotations +from typing import List +from abc import ABC + + + +# Flight Control System Application Exercise +# You are tasked with developing a Flight Control System for an airport. + +# The system should manage communication between different components, such as airplanes and the control tower, +# to ensure safe takeoffs and landings. To improve interactions and decrease dependencies among components, +# utilize the Mediator Design Pattern with a centralized communication method that enables effective coordination +# among the various components within the system. + +# Requirements: + # Airplane Class: Create an Airplane class representing different airplanes, with properties like ID, status (e.g., "waiting," "landing," "taking off"), and methods to request takeoff or landing. + # ControlTower Mediator: Implement a ControlTower class that serves as the mediator. It will manage the interactions between airplanes and handle their requests for takeoff and landing. + # Request Handling: Airplanes should be able to send requests to the control tower for takeoff or landing. The control tower should validate these requests based on the current air traffic. + # Notifications: The control tower should notify airplanes when their request is approved or denied. + + +# Implementation Steps: + # Define a Mediator interface with methods for registering airplanes and handling requests. + # Implement the ControlTower class that follows this interface. + # Implement the Airplane class with methods to request takeoff or landing and receive notifications from the control tower. + # Create a simple test case to demonstrate the functionality of the flight control system, including airplane registration and request handling. + + +# Output: + # After executing the code, it will simulate the following sequence of operations:# Airplanes are registered with the control tower. + # An airplane requests to take off or land. + # The control tower processes the request and sends notifications to the airplane regarding its status. + + +class Airplane: + + def __init__(self,id:str,status:str =None): + self._id = id, + self._status = status + + def request_takeoff(self,controlTower: ControlTower): + print(f"Airplane {self.get_airplane()} requesting Takeoff") + controlTower.handle_takeoff_request(self) + + def request_landing(self,controlTower: ControlTower): + print(f"Airplane {self.get_airplane()} requesting Landing") + controlTower.handle_landing_request(self) + + def get_airplane(self): + return self._id + + + def recieve_notification(self,message:str): + print(f"Airplane {self.get_airplane()} has {message}") + + + def takeoff_complete(self,controlTower: ControlTower): + controlTower.notify_takeoff_complete(self,message = f"{self.get_airplane()} takeoff done!") + + def landing_complete(self,controlTower: ControlTower): + controlTower.notify_landing_complete(self,message = f"{self.get_airplane()} landing done!") + + + + +class Mediator(ABC): + + def handle_takeoff_request(self,airplane:Airplane): + pass + + def handle_landing_request(self,airplane:Airplane): + pass + + def notify_takeoff_complete(self,airplane:Airplane): + pass + + def notify_landing_complete(self,airplane:Airplane): + pass + + +class ControlTower(Mediator): + """ + Class reponsible for handling the requests from airplanes' takeoff or landing. Keeping track of runways available + and accordingly notify the airplanes. + """ + + def __init__(self,airplanes:List[Airplane],takeoff_runways:int = 2,landing_runways:int = 2): + self._airplanes = airplanes + self._takeoff_runways = takeoff_runways + self._landing_runways = landing_runways + + print("No. of airplanes: ", len(airplanes)) + print(f"\nNo. of runways: Takeoff-> {self._takeoff_runways} Landing-> {self._landing_runways}") + + + def register_airplane(self,new_airplane:Airplane): + + for airplane in self._airplanes: + if(airplane.get_airplane() == new_airplane.get_airplane()): + print(f"Airplane is already registered with ID: {new_airplane.get_airplane()}") + return + + self._airplanes.append(new_airplane) + print(f"Airplane added!") + return + + + def notify_airplane(self,airplane:Airplane,message: str): + airplane.recieve_notification(message) + + def handle_landing_request(self, airplane:Airplane): + + if(self._takeoff_runways>0): + self._takeoff_runways -=1 + self.notify_airplane(airplane,message=f"Runway freed. Available runways!") + else: + self.notify_airplane(airplane,message=f"Landing not possible! Please wait") + + + def handle_takeoff_request(self, airplane:Airplane): + + if(self._takeoff_runways>0): + self._takeoff_runways -=1 + self.notify_airplane(airplane,message=f"Runway available for Takeoff!") + else: + self.notify_airplane(airplane,message=f"No runway available for Takeoff! Please wait") + + + def notify_takeoff_complete(self, airplane:Airplane): + + self._takeoff_runways +=1 + self.notify_airplane(airplane,message=f"Runway freed. Available takeoff runways {self._takeoff_runways}") + + + def notify_landing_complete(self, airplane:Airplane): + + self._landing_runways +=1 + self.notify_airplane(airplane,message=f"Runway freed. Available landing runways {self._landing_runways}") + + + + + + +if __name__ == "__main__": + + airplane1 = Airplane(id="airplane1") + airplane2 = Airplane(id="airplane2") + airplane3 = Airplane(id="airplane3") + airplane4 = Airplane(id="airplane4") + + airplanes = [airplane1,airplane2,airplane3,airplane4] + controlTower = ControlTower(airplanes,takeoff_runways=2,landing_runways=2) + [controlTower.register_airplane(Airplane(id=f"airplane{i+1}")) for i in range(4)] + + + + airplane1.request_takeoff(controlTower) + airplane2.request_takeoff(controlTower) + airplane3.request_takeoff(controlTower) + + + + + \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/syntax.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/syntax.py new file mode 100644 index 0000000..9d3b25f --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MediatorPattern/python/syntax.py @@ -0,0 +1,87 @@ +from __future__ import annotations +from abc import ABC + + +class BaseComponent: + """ + The Base Component provides the basic functionality of storing a mediator's + instance inside component objects. + """ + + def __init__(self, mediator: Mediator = None) -> None: + self._mediator = mediator + + @property + def mediator(self) -> Mediator: + return self._mediator + + @mediator.setter + def mediator(self, mediator: Mediator) -> None: + self._mediator = mediator + + +class Component1(BaseComponent): + def do_a(self) -> None: + print("Component 1 does A.") + self.mediator.notify(self, "A") + + + + +class BaseComponentV2: + + def __init__(self,mediator: Mediator = None) -> None: + self.mediator = mediator + + + +class Component2(BaseComponentV2): + def do_b(self) -> None: + print("Component 2 does B.") + self.mediator.notify(self,"B") + + + + +class Mediator(ABC): + """Mediator interface to implement loose coupling b/w components avoiding their direct interaction""" + + # def __init__(self): + # pass + + def notify(self,sender:object,message: str): + pass + + +class ConcreteMediator(Mediator): + def __init__(self, component1: Component1, component2: Component2) -> None: + self._component1 = component1 + self._component1.mediator = self + self._component2 = component2 + self._component2.mediator = self + + def notify(self, sender: object, event: str) -> None: + if event == "A": + print("Mediator reacts on A and triggers following operations:") + self._component2.do_b() + # elif event == "B": + # print("Mediator reacts on B and triggers following operations:") + # self._component1.do_a() + + + + +if __name__ == "__main__": + # The client code. + c1 = Component1() + c2 = Component2() + mediator = ConcreteMediator(c1, c2) + + print("\n\nClient triggers operation A.") + c1.do_a() + + print("\n", end="") + + print("Client triggers operation B.") + # c2.do_b() + \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/caretaker.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/caretaker.py new file mode 100644 index 0000000..d94e496 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/caretaker.py @@ -0,0 +1,29 @@ +from originator import Originator + + +class Caretaker: + """ + Caretaker class to capture originator's state and capture Memento's + history as a stack. + """ + def __init__(self, originator: Originator): + self._stack = [] + self.originator = originator + + def saveState(self): + currentState = self.originator.save() + self._stack.append(currentState) + print("--debug saving current state in caretaker:", currentState.getState()) + + def undo(self) -> None: + if not self._stack: + print("--debug No states to undo") + return + + lastState = self._stack.pop() + print("--debug restoring state to", lastState.getState()) + try: + self.originator.restore(lastState) + except Exception as e: + self.undo() + print("--debug error in state undo", e) diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/main.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/main.py new file mode 100644 index 0000000..d3bc335 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/main.py @@ -0,0 +1,32 @@ +from originator import Originator +from caretaker import Caretaker +import uuid + +def main(): + if __name__ == '__main__': + originator = Originator({ + "uuid": str(uuid.uuid1()) + }) + caretaker = Caretaker(originator) + + # Save the initial state + caretaker.saveState() + + # Perform some operations + originator.do_something() + print("--debug current State: ", originator.state) + + # Save another state + caretaker.saveState() + + # Perform some operations again + originator.do_something() + + # Undo operations + print("\nClient: Now, let's rollback!\n") + caretaker.undo() + + print("\nClient: Once more!\n") + caretaker.undo() + +main() diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/memento.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/memento.py new file mode 100644 index 0000000..adf6ab2 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/memento.py @@ -0,0 +1,8 @@ +class Memento: + """Memento class to capture a snapshot of state.""" + def __init__(self, state): + self._state = state + print(f"--debug state's snap in memento: {self._state}") + + def getState(self): + return self._state diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/originator.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/originator.py new file mode 100644 index 0000000..4d4b08a --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/MementoPattern/python/originator.py @@ -0,0 +1,28 @@ +from memento import Memento +import uuid + + +class Originator: + """ + The Originator holds some important state that may change over time. It also + defines a method for saving the state inside a memento and another method + for restoring the state from it. + """ + def __init__(self, state: dict): + self.state = state + print("--debug Originator initial state", self.state) + + def do_something(self): + """Business logic.""" + # print("--debug generating uuid for state") + self.state["uuid"] = str(uuid.uuid1()) + print("--debug state changed to: ", self.state) + + def save(self) -> Memento: + print("--debug saving current state in Memento") + return Memento(self.state.copy()) + + def restore(self, memento: Memento) -> None: + print("--debug retrieving last Memento's state") + self.state = memento.getState() + print("--debug originator's state changed to", self.state) diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/ObserverPattern/python/main.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/ObserverPattern/python/main.py new file mode 100644 index 0000000..1a002ca --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/ObserverPattern/python/main.py @@ -0,0 +1,111 @@ +from abc import ABC,abstractmethod + +#Observer Pattern +#Weather station and notificationSystem service for different devices + +class Observer(ABC): + """Observer Interface""" + + @abstractmethod + def update(self,temperature) : + print("--debug updating context for observer") + # self.temperature = temperature + pass + +class Subject(ABC): + """ + Subject interface: This interface will provide methods to the Concrete subject class + i.e. Weather station here to attach, detach and notify the Observer (interface) + Implements Observer interface. + """ + @abstractmethod + def attach(self, observer:Observer): + print("--debug attaching: ",observer) + + @abstractmethod + def detach(self, observer: Observer): + print("--debug detaching: ",observer) + + @abstractmethod + def notify(self, observer: Observer): + print("--debug notifying: ",observer) + + +class WeatherStation(Subject): + """Concrete Subject class - weather station""" + + def __init__(self): + self._observers = [] + + def setTemperature(self,temperature: int): + print("--debug setting weatherStation temp: ",temperature) + self.temperature = temperature + + #setting the temp and notify all the observers + self.notify() + + def attach(self, observer:Observer): + # print("--debug attaching :",observer) + if observer not in self._observers: + self._observers.append(observer) + # print("--debug observerList len, observer", len(self._observers),observer) + + def detach(self, observer:Observer): + if observer in self._observers: + print("--debug detaching: ",observer) + self._observers.remove(observer) + else: + print(f"-debug {observer} not present in list") + + def notify(self): + for Observer in self._observers: + # print("--debug notifiying : ", Observer) + Observer.update(self.temperature) + + +class Displaydevice(Observer): + + def __init__(self,name: str): + self.name = name + + def update(self, temperatrue: int): + self.temperature = temperatrue + print(f"--debug temp on {self.name} :{temperatrue} C") + + +class MobileDevice(Observer): + + def __init__(self,name: str): + super().__init__() + self.name = name + + def update(self,temperatrue: int): + self.temperature = temperatrue + print(f"--debug temp on {self.name} : {temperatrue} C") + + + +def main(): + weatherStation = WeatherStation() + displayDevice1 = Displaydevice("Samsung LCD") + displayDevice2 = Displaydevice("Micromax") + moblieDevice = MobileDevice("Redmi") + + weatherStation.attach(displayDevice1) + weatherStation.attach(moblieDevice) + weatherStation.attach(displayDevice2) + + weatherStation.setTemperature(20) + weatherStation.detach(moblieDevice) + weatherStation.setTemperature(45) + +if __name__ == '__main__': + main() + + + + + + + + diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/csvParser.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/csvParser.py new file mode 100644 index 0000000..4227841 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/csvParser.py @@ -0,0 +1,11 @@ +from dataParser import DataParser + +class CSVParser(DataParser): + def __init__(self): + super().__init__() + + + def parse(self, file): + print("debug parsing via CSVparser",file) + + \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/dataParser.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/dataParser.py new file mode 100644 index 0000000..75507b9 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/dataParser.py @@ -0,0 +1,25 @@ +from abc import ABC,abstractmethod + +class DataParser: + def __init__(self): + pass + + + def parse(self,file:str): + + self.openFile(file) + self.parseFile(file) + self.closeFile(file) + print("--debug file parsing done!") + + def openFile(self,file): + print("--debug opening file: ",file) + + @abstractmethod + #each child class will have its own implementation. + def parseFile(self,file): + pass + + def closeFile(self,file): + print("--debug closing file: ", file) + diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/jsonParser.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/jsonParser.py new file mode 100644 index 0000000..e719153 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/jsonParser.py @@ -0,0 +1,11 @@ +from dataParser import DataParser + +class JSONParser(DataParser): + def __init__(self): + super().__init__() + + + def parse(self, file): + print("debug parsing via JSONparser",file) + + \ No newline at end of file diff --git a/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/main.py b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/main.py new file mode 100644 index 0000000..fe8f827 --- /dev/null +++ b/design-patterns/src/main/java/org/prateek/BehaviouralPatterns/TemplateMethodPattern/python/main.py @@ -0,0 +1,26 @@ +# Implementing the Template pattern for DataParser + +from dataParser import DataParser +from csvParser import CSVParser +from jsonParser import JSONParser + + +def main(dataParser: DataParser,file: str): + + # csvparser = CSVParser() + # jsonparser = JSONParser() + + # csvparser.parse("file.csv") + # jsonparser.parse("file.json") + dataParser.parse(file) + + +if __name__ == "__main__": + + main(CSVParser(),"file.csv") + main(JSONParser(),"file.json") + + + + + \ No newline at end of file