Posts

Showing posts from 2022

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

SOLID - Liskov Substitution Principle (LSP)

SOLID - Liskov Substitution Principle (LSP) The Liskov Substitution Principle (LSP) is a fundamental principle in object-oriented programming (OOP) that defines guidelines for substitutability of objects within a program's inheritance hierarchy. It states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program. In simpler terms, the LSP emphasizes that derived classes or subclasses must be able to be used in place of the base class without introducing unexpected behavior or breaking the functionality of the program. The principle can be summarized with the following statement: "If S is a subtype of T, then objects of type T can be replaced with objects of type S without altering the correctness of the program." Design by Contract (DbC) To adhere to the Liskov Substitution Principle, derived classes must follow these guidelines: Subtype Requirement: The contract or behavior defined by the base

SOLID - Open-Closed Principle (OCP)

SOLID - Open-Closed Principle (OCP) The Open-Closed Principle states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. It means that you should be able to extend the behavior of a software entity without modifying its existing code. from abc import ABC, abstractmethod class Area(ABC): @abstractmethod def calculate_area(self): pass class Rectangle(Area): def __init__(self, length, width): self.length = length self.width = width def calculate_area(self): return self.length * self.width class Circle(Area): def __init__(self, radius): self.radius = radius def calculate_area(self): return 3.14 * self.radius ** 2 def print_areas(shapes): for shape in shapes: area = shape.calculate_area() print(f"Area: {area}") # Client code shapes = [Rectangle(4, 5), Circle(3)] print_areas(shapes) SOLID and Design Pattern Open-Clos

SOLID Principles

SOLID Principles To identify when and where to apply the SOLID principles, it's important to understand the core principles and their purposes. Here are some guidelines to help you identify their application: Single Responsibility Principle (SRP): Identify distinct responsibilities or reasons for change within your system. If a class or module has multiple responsibilities, consider separating them into separate classes or modules. Look for classes or modules that have more than one reason to change and consider refactoring them. Open-Closed Principle (OCP): Identify components or modules that should be open for extension but closed for modification. Consider using abstraction, interfaces, or inheritance to allow for extension without modifying existing code. Look for areas where you anticipate future changes or variations and design them to be easily extended without modifying existing code. Liskov Substitution Principle (LSP): Assess whether derived classes ca

Design Patterns

Design Patterns Creational Patterns These patterns focus on object creation mechanisms, providing flexibility and decoupling the client code from the specific classes instantiated. Some examples of creational patterns are: Singleton: Ensures that only one instance of a class exists throughout the program. Factory: Provides an interface for creating objects, but allows subclasses to decide which class to instantiate. Builder: Separates the construction of complex objects from their representation, allowing the same construction process to create different representations. Abstract Factory: Provides an interface for creating families of related or dependent objects without specifying their concrete classes. Prototype: Creates new objects by cloning existing ones and modifying them as needed. Structural Patterns These patterns deal with the composition of classes and objects, focusing on how they can be organized to form larger structures while keeping them flexible and ef

Abstract Class and Interface usage in Python

Abstract Class and Interface usage in Python The choice between using an abstract class or an interface depends on the specific requirements and design goals of your application. Both abstract classes and interfaces have their own advantages and use cases. Here are some considerations: Abstract Classes Default Implementation Abstract classes can provide a default implementation for some methods, allowing subclasses to inherit and override only the necessary methods. This can help reduce code duplication and provide shared functionality. Code Reusability Abstract classes can contain common code or attributes that can be inherited by subclasses, promoting code reuse and maintaining a consistent implementation across related classes. Flexibility Abstract classes can define both abstract methods (to be implemented by subclasses) and concrete methods (with default implementation). This provides flexibility in designing class hierarchies and allows for a mix of common and specialized

Python Closure

In these days of high inflation and high interest rates, I am sharing if you a simple Python Closure to calculate compound interest. According to Wikipedia, "a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions". Closure is an elegant style that takes the global namespace of your code clean. It behaves like a class/object instantiation, but in a much simpler way. I will use the class/object language to refer to the closure itself and its elements always in quotes, even if I know that it is not syntactically correct, just for the sake of ease of understanding. Compound Interest Our closure will calculate the compound interest for an initial value (principal) during a period of time and a fixed interest rate that you can set, based on the market conditions. To create a closure the following criterias have to be met: Outer function and an inner function (

Machine Learning - Classification problem

Image
SciKit Learn library data classification problem. This experiment was split in two posts/notebooks, because the texts, code and outputs are extensive. To complement this experiment, I wisht to propose a real classification prediction scenario for this problem, and a minimum viable product for data analysis machine learning based, in the near future. This first post talks about Data analysis and the second one << yet to come >> talks about Selecting the Model for Prediction Data Analysis Just after data loading, you have to analyse it to clean, merge and transform to make it machine learning friendly. Check every variable to get a good idea of the kind of data is there on the dataset. Numerical or categorical? Continuous or discrete? And after the data fits the right layout, you have to analyse other aspects like its dimmensionality, correlations and repetitions, to make another transformation to work good with your models. So, let's jump into it.

Machine Learning - Moving Linear Regression

Image
About the Moving Linear Regression This type of regression to be used when data of sub periods are different inside periods. For example, hours of day, days of week, months of year. For example, the variance of  the frequency of people in a commercial mall varies when comparing the days of the week. The same applies to an amount of cars on downtown or roads when comparing the days in a week, or even when comparing months, due to holidays and vacancies. The chart bellow displays a seven year Moving Linear Regression applied to each month, for the number of ongoing research projects.  About the data The data is public available on the open government initiative of the State of São Paulo - Brazil. State of São Paulo / Brazil - Transparency Portal Disclaimer - The sole purpose of this presentation is to carry out tests with machine learning, using public and open data to improve the use of technology for future application in the FAPESP Virtual Library. Any resu

Machine Learning - Linear Regression

Image
A simple generic prediction  Maybe the most simple generic prediction is a collection of points, and a linear regression (when applicable) pointing to the future. However, aside from the uncertainty that surrounds most predictions, problem happens all the time along the way. In the very recent years, Covid-19, Russia invasion, and finally, China's lockdown again, and maybe this is not the last impacting event for the early 2020's. Which means that predictions have to be updated all the time. And it is also important to get track of the previous predictions for comparison and for impact analysis. Linear Regression The chart bellow can represent anything that relates to the stated use case above. Two lines which slopes varies, due to a great variation caused by an extremes events.  This model was used for the purpose of the exploration of the Scikit Learn library. The depicted problem is a time series, but the result variable has influence of other factors beyond t