Posts

SOLID - Training models in TensorFlow

SOLID - Training models in TensorFlow The SOLID principles can be applied to the software architecture surrounding the machine learning models. Here's how the principles can be relevant: Single Responsibility Principle (SRP) Each class or module in your TensorFlow project should have a clear and single responsibility. For example, you can have separate modules for data preprocessing, model training, model evaluation, and model deployment. This promotes modularity and makes it easier to understand, test, and maintain each component. Open-Closed Principle (OCP) By designing your TensorFlow project with the OCP in mind, you can make it easier to extend the functionality without modifying existing code. For example, you can define abstract base classes or interfaces that define the common behavior expected from different models, allowing you to add new models by implementing these interfaces without modifying the existing code that consumes them. Liskov Substitution Principle (LS...

Hiring Process Interviews

Hiring Process Interviews First Round Hiring Process IT team structure Second Round IT team structure Job description Have to talk to management? Have to gather requirements? Code only? Nature of the system? Web Large System Distributed Code what? Infrastrucure? System Architect? Design Patterns Creational Patterns Builder class Pizza: def init(self): def str(self): class PizzaBuilder def init(self): def set_size(self, size): def add_cheese(self): def add_pepperoni(self): def add_bacon(self): def build(self): pizza = builder.set_size("Large").add_cheese().add_pepperoni().build() Factory class DataProcessor def process(self) class DatabaseExtractor(DataProcessor) def process(self): class APIExtractor(DataProcessor) def process(self) class FileExtractor(DataProcessor) def process(self) class DataProcessorFactory: def create_data_processor(source) Structural Patterns Adapter class MediaPlayer: def play(self...

Design Patterns - Observer

Design Patterns - Observer A simple Python code example to illustrate the Observer Pattern for an ETL-like scenario. The "Extract Microservice" observes changes in a data source and notifies its registered observers (data extractors) to perform data extraction. We'll use a basic Publisher-Subscriber pattern to demonstrate the concept of the Observer Pattern. Observer interface class Observer: def update(self, data): pass Extract Microservice (Subject) class ExtractMicroservice: def __init__(self): self.observers = [] def register_observer(self, observer): self.observers.append(observer) def unregister_observer(self, observer): self.observers.remove(observer) def notify_observers(self, data): for observer in self.observers: observer.update(data) def start_extraction(self): # Simulate data extraction process data = ["Data 1", "Data 2", "Data 3",...

Design Patterns - Adapter

Design Patterns - Adapter The Adapter design pattern is a structural design pattern that allows objects with incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces, converting the interface of one class into another interface that clients expect. This pattern enables classes to collaborate that otherwise wouldn't be able to due to their incompatible interfaces. Let's say we have an existing client code that expects a certain interface to interact with a target class. However, we want to use a different class that has a different interface. Instead of modifying the client code or the existing class, we can introduce an adapter class that implements the expected interface and internally delegates the calls to the different class. The components of the Adapter pattern are: Target: This is the interface that the client code expects to interact with. It defines the operations that the client can use. Adaptee: This is the existing clas...

Design Patterns - Command

Design Patterns - Command Behavioral Pattern The Command design pattern is a behavioral design pattern that encapsulates a request or action as an object, allowing you to parameterize clients with different requests, queue or log requests, and support undoable operations The concrete command classes (TurnOnCommand and TurnOffCommand) implement the Command interface and are associated with the Light receiver. Each concrete command encapsulates a specific action. This example demonstrates how the Command pattern separates the requester of an action (the invoker) from the object that performs the action (the receiver), allowing different commands to be executed dynamically. from abc import ABC, abstractmethod # Command interface class Command(ABC): @abstractmethod def execute(self): pass # Receiver class class Light: def turn_on(self): print("Light is on.") def turn_off(self): print("Light is off.") # Concrete comman...

SOLID - Single Responsibility Principle (SRP)

SOLID - Single Responsibility Principle (SRP) The Single Responsibility Principle states that a class should have only one reason to change. In other words, a class should have a single responsibility or purpose. Here's an example: class FileManager: def read_file(self, file_path): # Code to read the file def write_file(self, file_path, content): # Code to write content to the file def compress_file(self, file_path): # Code to compress the file def decompress_file(self, file_path): # Code to decompress the file In the above example, the FileManager class violates the SRP because it has multiple responsibilities. It handles file reading, writing, compression, and decompression. A better approach would be to separate these responsibilities into distinct classes, each with a single responsibility. For example: class FileReader: def read_file(self, file_path): # Code to read the file class FileWriter: def write_fil...

SOLID - Dependency Inversion Principle (DIP)

SOLID - Dependency Inversion Principle (DIP) Dependency Inversion Principle emphasizes decoupling and abstraction in software systems by defining guidelines for dependency relationships between modules or classes. High-level modules should not depend on low-level modules. Both should depend on abstractions. In simpler terms, DIP encourages the use of interfaces or abstract classes to define contracts and dependencies between modules, rather than depending on concrete implementations. This allows for flexibility, extensibility, and easier maintenance of the codebase. To adhere to DIP, the following practices are recommended: Programming to interfaces or abstract classes rather than concrete implementations. Using dependency injection to provide dependencies to classes rather than instantiating them directly. Employing dependency inversion frameworks or inversion of control containers to manage object dependencies. DIP and Multiple Inheritance This is a special case of Depende...