├── .vscode └── settings.json ├── OOP ├── 1_class.py ├── 2_object.py ├── 3_inheritance.py ├── 4_polymorphism.py ├── 5_encapsulation.py ├── 6_abstraction.py ├── README.md ├── class_point.py ├── items.csv └── main.py ├── README.md ├── convert-dictionary-into-dataframe.py ├── data-structure ├── list.py └── set.py ├── hash-table.py ├── oop.py ├── sliding-window-technique.py ├── sorting-algo └── binary_search_algo.py ├── trick_1_dictionary_compare.py └── trick_2_missing_unique_elements_in_2_lists.py /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.autopep8" 4 | }, 5 | "python.formatting.provider": "none" 6 | } -------------------------------------------------------------------------------- /OOP/1_class.py: -------------------------------------------------------------------------------- 1 | # In Python, a class is a blueprint for creating objects (instances) 2 | # that share similar attributes and behavior. It provides a way to 3 | # define and organize code in a structured manner, allowing you to 4 | # create reusable and modular code. 5 | 6 | class MyClass: 7 | def __init__(self, name, age): 8 | self.name = name 9 | self.age = age 10 | 11 | def greet(self): 12 | print(f"Hello, {self.name}!") 13 | 14 | # Creating an instance of the class 15 | obj1 = MyClass("Alice", 32) 16 | obj2 = MyClass("Shaon", 24) 17 | 18 | print(obj1.age) # Output: 32 19 | print(obj2.age) # Output: 24 20 | 21 | obj1.greet() # Output: Hello, Alice! 22 | obj2.greet() # Output: Hello, Shaon! 23 | -------------------------------------------------------------------------------- /OOP/2_object.py: -------------------------------------------------------------------------------- 1 | # In object-oriented programming (OOP), an object is 2 | # an instance of a class. It is a fundamental concept 3 | # that represents a specific entity or data structure 4 | # with its own set of attributes (data) and behaviors (methods). 5 | # Objects are created based on a class definition, which 6 | # serves as a blueprint or template for creating multiple 7 | # instances of the same type. 8 | 9 | # Here are some key points about objects: 10 | 11 | # Instance: An object is an instance of a class. 12 | # When you create an object, you are creating a 13 | # unique instance of that class, with its own set 14 | # of attribute values. 15 | 16 | # Attributes: Objects have attributes, also known 17 | # as properties or instance variables, which store 18 | # the object's data. These attributes can be of 19 | # different data types, such as integers, strings, 20 | # lists, or even other objects. 21 | 22 | # Methods: Objects have methods, which are functions 23 | # associated with the object's behavior. Methods 24 | # define the actions that an object can perform 25 | # and can interact with the object's attributes. 26 | 27 | # Identity: Each object has a unique identity that 28 | # distinguishes it from other objects. The identity 29 | # is usually assigned automatically by the programming 30 | # language and can be used to compare or identify objects. 31 | 32 | # Encapsulation: Objects encapsulate their data and 33 | # methods, meaning they bundle related data and behavior 34 | # together into a single entity. This helps in organizing 35 | # and managing complex systems and promotes code reusability. 36 | 37 | # Abstraction: Objects provide abstraction by hiding the 38 | # internal details of their implementation and exposing 39 | # only the necessary interfaces. This allows users of the 40 | # object to interact with it without needing to know the 41 | # underlying implementation. 42 | 43 | # Interactions: Objects can interact with each other by 44 | # invoking methods or accessing attributes of other objects. 45 | # These interactions enable collaboration and communication 46 | # between different objects in an object-oriented system. 47 | 48 | # By creating and manipulating objects, you can model real-world 49 | # entities or abstract concepts in your code, representing them 50 | # as self-contained units with their own state and behavior. 51 | # Objects facilitate the organization, modularity, and reusability 52 | # of code in object-oriented programming. 53 | 54 | class Car: 55 | def __init__(self, make, model, year): 56 | self.make = make 57 | self.model = model 58 | self.year = year 59 | self.is_running = False 60 | 61 | def start_engine(self): 62 | if not self.is_running: 63 | self.is_running = True 64 | print(f"The {self.make} {self.model}'s engine is now running.") 65 | else: 66 | print(f"The {self.make} {self.model}'s engine is already running.") 67 | 68 | def stop_engine(self): 69 | if self.is_running: 70 | self.is_running = False 71 | print(f"The {self.make} {self.model}'s engine has been stopped.") 72 | else: 73 | print(f"The {self.make} {self.model}'s engine is already stopped.") 74 | 75 | def drive(self): 76 | if self.is_running: 77 | print(f"The {self.make} {self.model} is now driving.") 78 | else: 79 | print(f"Cannot drive the {self.make} {self.model} because the engine is not running.") 80 | 81 | 82 | # Creating car objects 83 | car1 = Car("Honda", "Civic", 2021) 84 | car2 = Car("Toyota", "Corolla", 2022) 85 | 86 | # Accessing attributes 87 | print(car1.make) # Output: Honda 88 | print(car2.year) # Output: 2022 89 | 90 | # Calling methods 91 | car1.start_engine() # Output: The Honda Civic's engine is now running. 92 | car2.drive() # Output: Cannot drive the Toyota Corolla because the engine is not running. 93 | 94 | car1.drive() # Output: The Honda Civic is now driving. 95 | 96 | car2.start_engine() # Output: The Toyota Corolla's engine is now running. 97 | car2.stop_engine() # Output: The Toyota Corolla's engine has been stopped. 98 | -------------------------------------------------------------------------------- /OOP/3_inheritance.py: -------------------------------------------------------------------------------- 1 | # Inheritance is a fundamental concept in object-oriented 2 | # programming (OOP) that allows classes to inherit attributes 3 | # and methods from other classes. It is a mechanism that promotes 4 | # code reuse and facilitates the creation of hierarchical 5 | # relationships between classes. 6 | 7 | # Inheritance involves two types of classes: a base class (also 8 | # called a superclass or parent class) and a derived class (also 9 | # called a subclass or child class). The derived class inherits 10 | # the attributes and methods of the base class, extending or 11 | # modifying them as needed. 12 | 13 | # Here are the key points about inheritance: 14 | 15 | # Base Class: The base class is the class that is being inherited 16 | # from. It defines the common attributes and methods shared by 17 | # multiple related classes. 18 | 19 | # Derived Class: The derived class is the class that inherits 20 | # from the base class. It extends or specializes the base class 21 | # by adding new attributes or methods, or by overriding existing ones. 22 | 23 | # Inheritance Syntax: To define a derived class, you specify the 24 | # base class name in parentheses after the derived class name in 25 | # the class definition. 26 | 27 | # Attributes and Methods Inheritance: The derived class inherits 28 | # all the attributes and methods of the base class. It can access 29 | # and use them as if they were defined in the derived class itself. 30 | 31 | # Overriding: The derived class can override (redefine) the methods 32 | # of the base class to provide its own implementation. This allows 33 | # customization and specialization of behavior. 34 | 35 | # Access Modifiers: In some programming languages, inheritance can be 36 | # affected by access modifiers such as public, protected, or private, 37 | # which control the visibility and accessibility of inherited members. 38 | 39 | # Multiple Inheritance: Some languages support multiple inheritance, 40 | # where a derived class can inherit from multiple base classes. This allows 41 | # a class to inherit attributes and methods from multiple sources. 42 | 43 | # Inheritance promotes code reuse, modularity, and extensibility. It allows 44 | # you to create a hierarchy of classes, with more specialized subclasses 45 | # inheriting from more general base classes. This approach facilitates the 46 | # organization and maintenance of code by grouping related functionality 47 | # together and reducing duplication. 48 | 49 | class Animal: 50 | def __init__(self, name): 51 | self.name = name 52 | 53 | def speak(self): 54 | print("The animal makes a sound.") 55 | 56 | 57 | class Dog(Animal): 58 | def speak(self): 59 | print("The dog barks.") 60 | 61 | 62 | class Cat(Animal): 63 | def speak(self): 64 | print("The cat meows.") 65 | 66 | 67 | animal = Animal("Generic Animal") 68 | animal.speak() # Output: The animal makes a sound. 69 | 70 | dog = Dog("Rex") 71 | dog.speak() # Output: The dog barks. 72 | 73 | cat = Cat("Whiskers") 74 | cat.speak() # Output: The cat meows. 75 | -------------------------------------------------------------------------------- /OOP/4_polymorphism.py: -------------------------------------------------------------------------------- 1 | # Polymorphism is a core concept in object-oriented programming (OOP) 2 | # that allows objects of different classes to be treated as objects 3 | # of a common superclass. It enables the same code to be used with 4 | # different types of objects, providing flexibility and extensibility 5 | # in software design. 6 | 7 | # Polymorphism involves the following key ideas: 8 | 9 | # Inheritance: Polymorphism relies on inheritance to create a hierarchical 10 | # relationship between classes. By defining a common superclass and deriving 11 | # multiple subclasses from it, polymorphism allows objects of these subclasses 12 | # to be treated as instances of the superclass. 13 | 14 | Method Overriding: Polymorphism is often achieved through method overriding. Subclasses can override methods inherited from the superclass, providing their own implementation while keeping the method signature (name and parameters) the same. This allows different subclasses to have specialized behavior for the same method. 15 | 16 | # Method Invocation: Polymorphism enables objects of different classes to be 17 | # invoked using the same method name. The actual behavior of the method is determined dynamically at runtime based on the actual type of the object being referenced. 18 | 19 | # Interface Compatibility: Polymorphism requires that the objects involved 20 | # exhibit interface compatibility. This means that they share a common set of 21 | # methods or behaviors defined in a common superclass or interface. The code 22 | # that interacts with these objects can use the methods defined in the common 23 | # interface, regardless of the specific type of object. 24 | 25 | # The key benefit of polymorphism is that it allows for code reuse, extensibility, 26 | # and flexibility. It promotes modular and flexible designs by allowing different 27 | # classes to conform to a common interface and be used interchangeably where the 28 | # common interface is expected. 29 | 30 | 31 | 32 | import turtle 33 | 34 | 35 | 36 | class Polygon: 37 | def __init__(self, sides, name, size=100, color="black", line_thickness=1): 38 | self.sides = sides 39 | self.name = name 40 | self.size = size 41 | self.color = color 42 | self.line_thickness = line_thickness 43 | self.interior_angles = (self.sides - 2) * 180 44 | self.angle = self.interior_angles / self.sides 45 | 46 | 47 | def draw(self): 48 | turtle.color(self.color) 49 | turtle.pensize(self.line_thickness) 50 | 51 | for i in range(self.sides): 52 | turtle.forward(self.size) 53 | turtle.right(180 - self.angle) 54 | 55 | 56 | # Below example instance of Polymorphism examples 57 | 58 | # square = Polygon(4, 'Square') 59 | # pentagon = Polygon(5, 'Pentagon') 60 | # hexagon = Polygon(6, 'Hexagon', 50, 'Red', line_thickness=5) 61 | 62 | # square.draw() 63 | # pentagon.draw() 64 | # hexagon.draw() 65 | 66 | 67 | # The blow example is Inheritance and Polymorphism 68 | 69 | class Square(Polygon): 70 | # Constructor of Square 71 | def __init__(self, size=100, color="black", line_thickness=1): 72 | # Constructure of inherited class/parent class/super class 73 | super().__init__(4, "Square", size, color, line_thickness) 74 | 75 | 76 | def draw(self): 77 | turtle.begin_fill() 78 | # Parent class's method 79 | super().draw() 80 | turtle.end_fill() 81 | 82 | 83 | 84 | square = Square(color='green', line_thickness=3) 85 | 86 | print(f"Side: {square.sides}, Angle: {square.angle}") 87 | square.draw() 88 | # turtle.done() 89 | 90 | 91 | 92 | class Pentagon(Polygon): 93 | # Constructor of Pentagon 94 | def __init__(self, size=100, color="black", line_thickness=1): 95 | super().__init__(5, "Pentagon", size, color, line_thickness) 96 | 97 | 98 | def draw(self): 99 | turtle.begin_fill() 100 | # Parent class's method 101 | super().draw() 102 | turtle.end_fill() 103 | 104 | 105 | pentagon = Pentagon(color='blue', line_thickness=3) 106 | 107 | print(f"Side: {pentagon.sides}, Angle: {pentagon.angle}") 108 | pentagon.draw() 109 | turtle.done() -------------------------------------------------------------------------------- /OOP/5_encapsulation.py: -------------------------------------------------------------------------------- 1 | # Encapsulation is a fundamental principle in object-oriented programming (OOP) 2 | # that combines data and the methods (functions) that operate on that data into 3 | # a single unit called an object. It involves bundling the data and methods 4 | # together, and controlling access to them through a well-defined interface. 5 | 6 | # Here are the key aspects of encapsulation: 7 | 8 | # Data and Methods: Encapsulation allows you to group related 9 | # data (attributes or variables) and methods (functions or procedures) 10 | # into a cohesive entity, known as an object. The data represents the 11 | # state or properties of the object, while the methods define its 12 | # behavior or operations. 13 | 14 | # Access Modifiers: Encapsulation uses access modifiers, such as 15 | # public, private, and protected, to control the visibility and 16 | # accessibility of the attributes and methods. These modifiers 17 | # specify who can access and modify the data and methods from 18 | # within and outside the object. 19 | 20 | # Public: Public attributes and methods are accessible from 21 | # anywhere, both inside and outside the object. They form the 22 | # public interface or API (Application Programming Interface) 23 | # of the object, allowing other objects or code to interact 24 | # with it. 25 | 26 | # Private: Private attributes and methods are only accessible within 27 | # the object itself. They cannot be accessed or modified directly 28 | # from outside the object. Private members are typically accessed 29 | # through public methods, which provide controlled and validated 30 | # access to the private data. 31 | 32 | # Protected: Protected attributes and methods are similar to private 33 | # members but are also accessible within subclasses or derived classes. 34 | # They provide a limited level of accessibility and are often used for 35 | # inheritance purposes. 36 | 37 | # Information Hiding: Encapsulation facilitates information hiding, which 38 | # means hiding the internal details and complexities of the object from 39 | # other objects or code. The object exposes only the necessary information 40 | # and functionality through its public interface, while keeping the internal 41 | # implementation hidden. 42 | 43 | # Data Encapsulation: Encapsulation allows you to encapsulate the data within 44 | # an object, providing a level of protection against unauthorized access or 45 | # modifications. By making the attributes private or using accessors and 46 | # mutators (getters and setters), you can enforce data integrity and ensure 47 | # that the data is accessed and modified through controlled methods. 48 | 49 | # Benefits of Encapsulation: Encapsulation offers several benefits, including: 50 | 51 | # Modularity and Maintainability: Encapsulation promotes modular and organized 52 | # code by encapsulating related data and behavior into self-contained objects. 53 | # This makes the code easier to understand, maintain, and update. 54 | 55 | # Data Protection and Security: Encapsulation helps protect the integrity of the 56 | # data by controlling access to it. By hiding the internal details and providing 57 | # controlled access through methods, you can prevent accidental or unauthorized 58 | # modifications to the data. 59 | 60 | # Code Reusability: Encapsulated objects can be easily reused in different parts 61 | # of a program or in different programs altogether. The public interface of the 62 | # object provides a consistent way to interact with it, regardless of its internal 63 | # implementation. 64 | 65 | class Car: 66 | def __init__(self): 67 | self.__fuel = 0 68 | 69 | def add_fuel(self, amount): 70 | self.__fuel += amount 71 | 72 | def drive(self): 73 | if self.__fuel > 0: 74 | print("The car is driving.") 75 | self.__fuel -= 1 76 | else: 77 | print("Out of fuel. Please add fuel.") 78 | 79 | def get_fuel_level(self): 80 | return self.__fuel 81 | 82 | 83 | my_car = Car() 84 | my_car.add_fuel(50) 85 | my_car.drive() 86 | fuel_level = my_car.get_fuel_level() 87 | print(f"Fuel level: {fuel_level}") 88 | -------------------------------------------------------------------------------- /OOP/6_abstraction.py: -------------------------------------------------------------------------------- 1 | # Abstraction is a fundamental concept in object-oriented programming (OOP) 2 | # that focuses on representing essential features and behavior while hiding 3 | # unnecessary details. It allows you to create simplified models of real-world 4 | # entities or systems, emphasizing what is important and suppressing the 5 | # irrelevant or complex aspects. 6 | 7 | # Here are the key aspects of abstraction: 8 | 9 | # Simplification: Abstraction simplifies the representation of complex 10 | # systems or entities by focusing on the essential features and behavior. 11 | # It captures the core attributes, methods, and relationships that are 12 | # relevant to the problem domain, while omitting the intricate details. 13 | 14 | # Data Abstraction: Data abstraction involves representing data by abstracting 15 | # away the internal implementation details and exposing only the necessary 16 | # information. It defines the properties (attributes) of an object without 17 | # specifying how they are implemented. Data abstraction provides a way to 18 | # define the structure and behavior of data types without revealing the 19 | # underlying complexity. 20 | 21 | # Procedure Abstraction: Procedure abstraction focuses on hiding the 22 | # implementation details of methods or functions. It defines the 23 | # interface (method signature) and functionality of a method without 24 | # exposing the internal workings. Procedure abstraction allows users 25 | # to interact with the methods without needing to know the underlying 26 | # implementation. 27 | 28 | # Encapsulation and Abstraction: Abstraction is closely related to 29 | # encapsulation. Encapsulation combines data and methods into a single 30 | # unit (object) and provides controlled access to them. Abstraction, on 31 | # the other hand, focuses on presenting a simplified view of the object's 32 | # essential features and behavior while hiding the internal details. 33 | # Encapsulation supports abstraction by providing a way to encapsulate 34 | # the implementation details within an object. 35 | 36 | # Class and Interface: Abstraction is often achieved through the use of 37 | # classes and interfaces in OOP. A class represents a blueprint for creating 38 | # objects and defines the structure, behavior, and relationships of objects. 39 | # An interface defines a contract or set of method signatures that a class must 40 | # implement. Both classes and interfaces can serve as abstractions by providing 41 | # a simplified view and hiding the implementation details. 42 | 43 | # Benefits of Abstraction: Abstraction offers several benefits, including: 44 | 45 | # Simplification and Focus: Abstraction simplifies complex systems by focusing 46 | # on the essential aspects, making the code easier to understand, manage, and maintain. 47 | 48 | # Modularity and Flexibility: Abstraction promotes modularity by breaking down 49 | # complex systems into smaller, self-contained units. This allows for easier 50 | # development, testing, and modification of the system's components without 51 | # impacting the entire system. 52 | 53 | # Code Reusability: Abstraction facilitates code reuse by providing abstract 54 | # classes or interfaces that can be implemented by multiple classes. This promotes 55 | # code modularity and reduces redundancy. 56 | 57 | # Security and Privacy: Abstraction allows you to hide sensitive or private 58 | # information and expose only what is necessary. It helps in protecting the 59 | # integrity of data and preventing unauthorized access. 60 | 61 | from abc import ABC, abstractmethod 62 | 63 | class Animal(ABC): 64 | def __init__(self, name): 65 | self.name = name 66 | 67 | @abstractmethod 68 | def make_sound(self): 69 | pass 70 | 71 | def eat(self): 72 | print(f"{self.name} is eating.") 73 | 74 | class Dog(Animal): 75 | def make_sound(self): 76 | print("Woof!") 77 | 78 | class Cat(Animal): 79 | def make_sound(self): 80 | print("Meow!") 81 | 82 | # Creating objects of different subclasses 83 | dog = Dog("Buddy") 84 | cat = Cat("Whiskers") 85 | 86 | # Polymorphic behavior through abstraction 87 | animals = [dog, cat] 88 | 89 | for animal in animals: 90 | animal.make_sound() 91 | animal.eat() 92 | -------------------------------------------------------------------------------- /OOP/README.md: -------------------------------------------------------------------------------- 1 | # OOP in Python 2 | Object oriented programming (OOP) in Python is a programming paradigm that uses objects and classes to model real-world entities and their relations. Some main features of OOP in Python are: 3 | - Classes 4 | - Objects 5 | - Inheritance 6 | - Polymorphism 7 | - Encapsulation 8 | - Abstraction 9 | - Modularity 10 | 11 | # Class 12 | In Python, a class is a blueprint for creating objects (instances) that share similar attributes and behavior. It provides a way to define and organize code in a structured manner, allowing you to create reusable and modular code. 13 | 14 | Class [Example](https://github.com/rkshaon/python-and-data-structure-and-algorithm/blob/master/OOP/1_class.py). 15 | 16 | # Object 17 | In object-oriented programming (OOP), an object is an instance of a class. It is a fundamental concept that represents a specific entity or data structure with its own set of attributes (data) and behaviors (methods). Objects are created based on a class definition, which serves as a blueprint or template for creating multiple instances of the same type. 18 | 19 | Here are some key points about objects: 20 | - Instance: An object is an instance of a class. When you create an object, you are creating a unique instance of that class, with its own set of attribute values. 21 | - Attributes: Objects have attributes, also known as properties or instance variables, which store the object's data. These attributes can be of different data types, such as integers, strings, lists, or even other objects. 22 | - Methods: Objects have methods, which are functions associated with the object's behavior. Methods define the actions that an object can perform and can interact with the object's attributes. 23 | - Identity: Each object has a unique identity that distinguishes it from other objects. The identity is usually assigned automatically by the programming language and can be used to compare or identify objects. 24 | - Encapsulation: Objects encapsulate their data and methods, meaning they bundle related data and behavior together into a single entity. This helps in organizing and managing complex systems and promotes code reusability. 25 | - Abstraction: Objects provide abstraction by hiding the internal details of their implementation and exposing only the necessary interfaces. This allows users of the object to interact with it without needing to know the underlying implementation. 26 | - Interactions: Objects can interact with each other by invoking methods or accessing attributes of other objects. These interactions enable collaboration and communication between different objects in an object-oriented system. 27 | 28 | By creating and manipulating objects, you can model real-world entities or abstract concepts in your code, representing them as self-contained units with their own state and behavior. Objects facilitate the organization, modularity, and reusability of code in object-oriented programming. 29 | 30 | Object [Example](https://github.com/rkshaon/python-and-data-structure-and-algorithm/blob/master/OOP/2_object.py). 31 | 32 | # Inheritance 33 | Inheritance is a fundamental concept in object-oriented programming (OOP) that allows classes to inherit attributes and methods from other classes. It is a mechanism that promotes code reuse and facilitates the creation of hierarchical relationships between classes. 34 | 35 | Inheritance involves two types of classes: a base class (also called a superclass or parent class) and a derived class (also called a subclass or child class). The derived class inherits the attributes and methods of the base class, extending or modifying them as needed. 36 | 37 | Here are the key points about inheritance: 38 | - Base Class: The base class is the class that is being inherited from. It defines the common attributes and methods shared by multiple related classes. 39 | - Derived Class: The derived class is the class that inherits from the base class. It extends or specializes the base class by adding new attributes or methods, or by overriding existing ones. 40 | - Inheritance Syntax: To define a derived class, you specify the base class name in parentheses after the derived class name in the class definition. 41 | - Attributes and Methods Inheritance: The derived class inherits all the attributes and methods of the base class. It can access and use them as if they were defined in the derived class itself. 42 | - Overriding: The derived class can override (redefine) the methods of the base class to provide its own implementation. This allows customization and specialization of behavior. 43 | - Access Modifiers: In some programming languages, inheritance can be affected by access modifiers such as public, protected, or private, which control the visibility and accessibility of inherited members. 44 | - Multiple Inheritance: Some languages support multiple inheritance, where a derived class can inherit from multiple base classes. This allows a class to inherit attributes and methods from multiple sources. 45 | 46 | Inheritance promotes code reuse, modularity, and extensibility. It allows you to create a hierarchy of classes, with more specialized subclasses inheriting from more general base classes. This approach facilitates the organization and maintenance of code by grouping related functionality together and reducing duplication. 47 | 48 | Inheritance [Example](https://github.com/rkshaon/python-and-data-structure-and-algorithm/blob/master/OOP/3_inheritance.py). 49 | 50 | # Polymorphism 51 | Polymorphism is a core concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It enables the same code to be used with different types of objects, providing flexibility and extensibility in software design. 52 | 53 | Polymorphism involves the following key ideas: 54 | - Inheritance: Polymorphism relies on inheritance to create a hierarchical relationship between classes. By defining a common superclass and deriving multiple subclasses from it, polymorphism allows objects of these subclasses to be treated as instances of the superclass. 55 | - Method Overriding: Polymorphism is often achieved through method overriding. Subclasses can override methods inherited from the superclass, providing their own implementation while keeping the method signature (name and parameters) the same. This allows different subclasses to have specialized behavior for the same method. 56 | - Method Invocation: Polymorphism enables objects of different classes to be invoked using the same method name. The actual behavior of the method is determined dynamically at runtime based on the actual type of the object being referenced. 57 | - Interface Compatibility: Polymorphism requires that the objects involved exhibit interface compatibility. This means that they share a common set of methods or behaviors defined in a common superclass or interface. The code that interacts with these objects can use the methods defined in the common interface, regardless of the specific type of object. 58 | 59 | The key benefit of polymorphism is that it allows for code reuse, extensibility, and flexibility. It promotes modular and flexible designs by allowing different classes to conform to a common interface and be used interchangeably where the common interface is expected. 60 | 61 | Polymorphism [Example](https://github.com/rkshaon/python-and-data-structure-and-algorithm/blob/master/OOP/4_polymorphism.py). 62 | 63 | 64 | 65 | # Encapsulation 66 | 67 | # Abstraction 68 | 69 | # Modularity 70 | -------------------------------------------------------------------------------- /OOP/class_point.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | class Point: 4 | def __init__(self, x, y): 5 | self.x = x 6 | self.y = y 7 | 8 | # Operator overloading 9 | def __add__(self, other): 10 | if isinstance(other, Point): 11 | x = self.x + other.x 12 | y = self.y + other.y 13 | else: 14 | x = self.x + other 15 | y = self.y + other 16 | 17 | return Point(x, y) 18 | 19 | def plot(self): 20 | plt.scatter(self.x, self.y) 21 | 22 | a = Point(1, 1) 23 | b = Point(2, 2) 24 | c = a + b 25 | # d = Point(5, 5) 26 | # c += d 27 | d = a + 5 28 | 29 | # print(c.x, c.y) 30 | # c.plot() 31 | d.plot() 32 | # a.plot() 33 | plt.show() 34 | -------------------------------------------------------------------------------- /OOP/items.csv: -------------------------------------------------------------------------------- 1 | name,price,quantity 2 | "iPhone",699,3 3 | "MacBook",1499,5 4 | "Apple Watch",399,6 -------------------------------------------------------------------------------- /OOP/main.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import os 3 | 4 | 5 | 6 | class Item: 7 | # Note 8 | # Class has magic methods, and magic attributes 9 | 10 | # Class attribute 11 | pay_rate = 0.8 # Price after discount 12 | all = [] 13 | 14 | # Constructor, this is magic method 15 | def __init__(self, name: str, price: float, quantity=0): 16 | # Validation 17 | assert price >= 0, f"Price {price} can not be less than ZERO." 18 | assert quantity >= 0, f"Quantity {quantity} can not be less than ZERO." 19 | 20 | # Assignment 21 | self.name = name 22 | self.price = price 23 | self.quantity = quantity 24 | 25 | # Actions 26 | Item.all.append(self) 27 | 28 | 29 | def __repr__(self): 30 | return f"Item('{self.name}', '{self.price}', '{self.quantity}')" 31 | 32 | 33 | def calculate_total_price(self): 34 | return self.price * self.quantity 35 | 36 | 37 | def apply_discount(self): 38 | # Here accessing from Class Level, so value will not never update at instance level 39 | # self.price = self.price * Item.pay_rate 40 | # Here accessing from instance level, so value will be update at instance level 41 | self.price = self.price * self.pay_rate 42 | 43 | 44 | @classmethod 45 | def instantiate_from_csv(cls): 46 | file_path = os.path.join(os.getcwd(), 'OOP/items.csv') 47 | 48 | with open(file_path, 'r') as f: 49 | reader = csv.DictReader(f) 50 | items = list(reader) 51 | 52 | for item in items: 53 | Item( 54 | name=item.get('name'), 55 | price=float(item.get('price')), 56 | quantity=int(item.get('quantity')) 57 | ) 58 | 59 | 60 | 61 | Item.instantiate_from_csv() 62 | print(Item.all) 63 | # item1 = Item(name="iPhone", price=150, quantity=5) 64 | # item2 = Item(name="MacBook", price=1000, quantity=3) 65 | # item3 = Item(name=1, price=100, quantity=5) 66 | 67 | # print(item1.name) 68 | # print(item2.name) 69 | # print(item3.name) 70 | # print(item1.calculate_total_price()) 71 | # print(item2.calculate_total_price()) 72 | # print(item3.calculate_total_price()) 73 | 74 | # print(Item.__dict__) # All attributes for Class Level 75 | # print(item1.__dict__) # All attributes for Instance Level 76 | 77 | # item2.pay_rate = 0.7 78 | # item2.apply_discount() 79 | # print(item2.price) 80 | 81 | # print(Item.all) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python and Data Structure and Algorithm 2 | 3 | ## OOP 4 | Object oriented programming (OOP) in Python is a programming paradigm that uses objects and classes to model real-world entities and their relations. 5 | 6 | [Details](https://github.com/rkshaon/python-and-data-structure-and-algorithm/tree/master/OOP) 7 | 8 | ## Data Structure 9 | - Hash Table 10 | - List 11 | - Set 12 | 13 | ## Algorithm 14 | - Binary Search 15 | -------------------------------------------------------------------------------- /convert-dictionary-into-dataframe.py: -------------------------------------------------------------------------------- 1 | # Input 2 | emp_details = { 3 | "Employee": { 4 | "Jessica": {"ID": "001", "Salary": "2000", "Designation": "Team Lead"}, 5 | "Alba": {"ID": "002", "Salary": "1800", "Designation": "Associate Team Lead"}, 6 | "Scarlett": {"ID": "003", "Salary": "1500", "Designation": "Senior Developer"}, 7 | "Johansson": {"ID": "004", "Salary": "1200", "Designation": "Developer"} 8 | } 9 | } 10 | 11 | # Output 1 12 | # Jessica Alba Scarlett Johansson 13 | # ID 001 002 003 004 14 | # Salary 2000 1800 1500 1200 15 | # Designation Team Lead Associate Team Lead Senior Developer Developer 16 | 17 | # Output 2 18 | # ID Salary Designation 19 | # Jessica 001 2000 Team Lead 20 | # Alba 002 1800 Associate Team Lead 21 | # Scarlett 003 1500 Senior Developer 22 | # Johansson 004 1200 Developer 23 | 24 | import pandas as pd 25 | 26 | data_frame = pd.DataFrame(emp_details["Employee"]) 27 | 28 | # Output 1 29 | print(data_frame) 30 | # Output 2 31 | print(data_frame.T) -------------------------------------------------------------------------------- /data-structure/list.py: -------------------------------------------------------------------------------- 1 | # What is List? 2 | # In Python, a list is a built-in data structure that allows you to store 3 | # and organize a collection of items in a particular order. A list is an 4 | # ordered sequence of objects, where each object can be of any type, such 5 | # as integers, floats, strings, or other objects. Lists are created by 6 | # enclosing a comma-separated sequence of values within square brackets [ ]. 7 | # Example 8 | # my_list = [1, 2, 3, 4, 5] 9 | # Lists are mutable, which means you can add, remove, or modify elements after 10 | # the list has been created. You can access individual elements in a list by 11 | # their index, starting with 0 for the first element, and you can use slicing 12 | # to extract a subset of the list. 13 | 14 | # append - Adds an element `x` to the end of the list. 15 | my_list = [1, 2, 3, 4, 5] 16 | my_list.append(10) # [1, 2, 3, 4, 5, 10] 17 | # A single value required to append in a list 18 | print(f"After append: {my_list}") 19 | 20 | # extend - Adds elements from an iterable to the end of the list. 21 | my_list = [1, 2, 3, 4, 5] 22 | my_list.extend([10, 11, 12]) # [1, 2, 3, 4, 5, 10, 11, 12] 23 | # Another list required to extend in a list 24 | print(f"After extend: {my_list}") 25 | 26 | # insert - Inserts element `x` at position `i` in the list. 27 | my_list = [1, 2, 3, 4, 5] 28 | my_list.insert(2, 10) # [1, 2, 10, 3, 4, 5] 29 | # An index and a value required to insert in a list 30 | print(f"After insert: {my_list}") 31 | 32 | # remove - Removes the first occurrence of element `x` from the list. 33 | my_list = [1, 2, 3, 4, 5, 3] 34 | my_list.remove(3) # [1, 2, 4, 5, 3] 35 | # A single value required to remove from a list 36 | print(f"After remove: {my_list}") 37 | 38 | # pop([i]) - Removes and returns the element at position i in the list. If i is not specified, removes and returns the last element. 39 | fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry'] 40 | 41 | # Remove and return the third element (index 2) 42 | removed_fruit = fruits.pop(2) 43 | print(removed_fruit) # Output: 'cherry' 44 | print(f"After pop: {fruits}") # Output: ['apple', 'banana', 'date', 'elderberry'] 45 | 46 | # Remove and return the last element 47 | last_fruit = fruits.pop() 48 | print(last_fruit) # Output: 'elderberry' 49 | print(f"After pop: {fruits}") # Output: ['apple', 'banana', 'date'] 50 | # Requires a index number, otherwise it will pop the last element 51 | 52 | # index(x[, start[, end]]) - returns the first occurrence of element in the list, optional arguments start and end specify the starting and ending positions for the search. 53 | my_list = ['Cat', 'Dog', 'Elephant', 'Cat', 123, 'Cat', 1] 54 | my_list.index('Cat') # 0 55 | my_list.index('Elephant') # 2 56 | # start optional arg 57 | my_list.index('Cat', 1) # 3 58 | # end optional arg 59 | my_list.index('Cat', 4, 6) # 5 60 | print(f"After search index of 'Cat': {my_list.index('Cat')}") 61 | print(f"After search index of 'Elephant': {my_list.index('Elephant')}") 62 | print(f"After search index of 'Cat' using start arg: {my_list.index('Cat', 1)}") 63 | print(f"After search index of 'Cat' using end arg: {my_list.index('Cat', 4, 6)}") 64 | 65 | # count(x) - Returns the number of occurrences of element x in the list. 66 | fruits = ["apple", "banana", "cherry", "apple", "banana", "cherry"] 67 | fruits.count("cherry") # 2 68 | print(f"After count: {fruits.count('cherry')}") 69 | 70 | # sort(key=None, reverse=False) - Sorts the list in ascending order. Optional arguments key and reverse allow customization of the sorting behavior. 71 | cars = ['Ford', 'BMW', 'Volvo', 'Mazda'] 72 | cars.sort() # ['BMW', 'Ford', 'Mazda', 'Volvo'] 73 | print(f"After sort: {cars}") 74 | cars.sort(reverse=True) # ['Volvo', 'Mazda', 'Ford', 'BMW'] 75 | print(f"After sort reverse: {cars}") 76 | 77 | # Here we want sort by the length of the item 78 | def myFunc(e): 79 | return len(e) 80 | 81 | cars = ['Ford', 'Mitsubishi', 'BMW', 'VW', 'Volkswagen'] 82 | cars.sort(key=myFunc) # ['VW', 'BMW', 'Ford', 'Mitsubishi', 'Volkswagen] 83 | print(f"After sort using key: {cars}") 84 | cars.sort(key=myFunc, reverse=True) # ['Mitsubishi', 'Volkswagen', 'Ford', 'BMW', 'VW'] 85 | print(f"After sort using key and reverse: {cars}") 86 | 87 | # Here we want to sort by year of the item 88 | def myFunc(e): 89 | return e['year'] 90 | 91 | cars = [ 92 | {'car': 'Ford', 'year': 2005}, 93 | {'car': 'Mitsubishi', 'year': 2000}, 94 | {'car': 'BMW', 'year': 2019}, 95 | {'car': 'VW', 'year': 2011} 96 | ] 97 | 98 | cars.sort(key=myFunc) # [{'car': 'Mitsubishi', 'year': 2000}, {'car': 'Ford', 'year': 2005}, {'car': 'VW', 'year': 2011}, {'car': 'BMW', 'year': 2019}] 99 | print(f"After sort using key: {cars}") 100 | cars.sort(key=myFunc, reverse=True) # [{'car': 'BMW', 'year': 2019}, {'car': 'VW', 'year': 2011}, {'car': 'Ford', 'year': 2005}, {'car': 'Mitsubishi', 'year': 2000}] 101 | print(f"After sort using key and reverse: {cars}") 102 | 103 | # reverse() - Reverses the order of elements in the list 104 | fruits = ['apple', 'banana', 'cherry'] 105 | fruits.reverse() # ['cherry', 'banana', 'apple'] 106 | print(f"After reverse: {fruits}") 107 | 108 | # copy() - Returns a shallow copy of the list 109 | # The copy() method returns a copy of the specified list. 110 | fruits = ['apple', 'banana', 'cherry', 'orange'] 111 | x = fruits.copy() # ['apple', 'banana', 'cherry', 'orange'] 112 | print(f"After copy: {fruits, x}") 113 | 114 | # clear() - The clear() method removes all the elements from a list 115 | fruits = ['apple', 'banana', 'cherry', 'orange'] 116 | fruits.clear() # [] 117 | print(f"After clear: {fruits}") 118 | -------------------------------------------------------------------------------- /data-structure/set.py: -------------------------------------------------------------------------------- 1 | # What is Set? 2 | # In Python, a set is an unordered collection of unique elements. 3 | # It is defined using curly braces {} or the set() constructor. 4 | # Sets are mutable, meaning you can add, remove, and modify their 5 | # elements. 6 | 7 | # Example 8 | # my_set = {1, 2, 3} 9 | 10 | # create set 11 | my_set = {1, 2, 3} # Using curly braces 12 | print(my_set) # {1, 2, 3} 13 | my_set = set([1, 2, 3]) # Using the set() constructor 14 | print(my_set) # {1, 2, 3} 15 | 16 | # access set 17 | for element in my_set: 18 | print(element) # 1 \n 2 \n 3 19 | 20 | if 1 in my_set: 21 | print("1 is in the set") # 1 is in the set 22 | 23 | # modify set 24 | # add 25 | my_set.add(4) # Add a single element 26 | print(my_set) # {1, 2, 3, 4} 27 | my_set.update([5, 6]) # Add multiple elements from an iterable 28 | print(my_set) # {1, 2, 3, 4, 5, 6} 29 | 30 | 31 | # remove 32 | my_set.remove(3) # Remove an element by value (raises KeyError if not found) 33 | print(my_set) # {1, 2, 4, 5, 6} 34 | my_set.discard(2) # Remove an element by value (does nothing if not found) 35 | print(my_set) # {1, 4, 5, 6} 36 | popped_element = my_set.pop() # Remove and return an arbitrary element from the set 37 | print(my_set) # {4, 5, 6} 38 | print(popped_element) # 1 39 | my_set.clear() # Remove all elements from the set 40 | print(my_set) # set() 41 | 42 | # set operations 43 | # union 44 | set1 = {1, 3, 5} 45 | set2 = {2, 4, 6} 46 | union_set = set1 | set2 # union operation 47 | print(union_set) # {1, 2, 3, 4, 5, 6} 48 | union_set = set1.union(set2) 49 | print(union_set) # {1, 2, 3, 4, 5, 6} 50 | 51 | # intersection 52 | set1 = {1, 2, 3, 5} 53 | set2 = {2, 4, 6} 54 | intersection_set = set1 & set2 # intersection operation 55 | print(intersection_set) # {2} 56 | intersection_set = set1.intersection(set2) 57 | print(intersection_set) # {2} 58 | 59 | # diffrence 60 | set1 = {1, 2, 3, 5} 61 | set2 = {2, 4, 5, 6} 62 | difference_set = set1 - set2 # difference operation 63 | print(difference_set) # {1, 3} 64 | difference_set = set1.difference(set2) 65 | print(difference_set) # {1, 3} 66 | 67 | # symmetric difference 68 | set1 = {1, 2, 3, 5} 69 | set2 = {2, 4, 5, 6} 70 | symmetric_diff_set = set1 ^ set2 71 | print(symmetric_diff_set) # {1, 3, 4, 6} 72 | symmetric_diff_set = set1.symmetric_difference(set2) 73 | print(symmetric_diff_set) # {1, 3, 4, 6} 74 | 75 | # Set comprehension 76 | my_set = {x for x in range(1, 5)} 77 | print(my_set) # {1, 2, 3, 4} 78 | 79 | # Set methods 80 | # len(): Returns the number of elements in the set. 81 | print(len(my_set)) # 4 82 | 83 | # copy(): Returns a shallow copy of the set. 84 | my_set2 = my_set.copy() 85 | print(my_set2) # {1, 2, 3, 4} 86 | 87 | # isdisjoint(other_set): Returns True if the set has no common elements with other_set. 88 | set1 = {1, 3, 5} 89 | set2 = {2, 4, 6} 90 | print(set1.isdisjoint(set2)) # True 91 | 92 | set1 = {1, 2, 3, 5} 93 | set2 = {2, 4, 6} 94 | print(set1.isdisjoint(set2)) # False 95 | 96 | # issubset(other_set): Returns True if every element in the set is also in other_set. 97 | set1 = {2, 6} 98 | set2 = {1, 2, 3, 4, 5, 6} 99 | print(set1.issubset(set2)) # True 100 | 101 | # issuperset(other_set): Returns True if every element in other_set is also in the set. 102 | set1 = {1, 2, 3, 4, 5, 6} 103 | set2 = {2, 6} 104 | print(set1.issuperset(set2)) # True -------------------------------------------------------------------------------- /hash-table.py: -------------------------------------------------------------------------------- 1 | # Defination 2 | 3 | # In computing, a hash table, also known as hash map, 4 | # is a data structure that implements an associative array 5 | # or dictionary. It is an abstract data type that maps 6 | # keys to values 7 | 8 | # A hash table uses a hash function to compute an index, 9 | # also called a hash code, into an array of buckets or slots, 10 | # from which the desired value can be found. During lookup, 11 | # the key is hashed and the resulting hash indicates where 12 | # the corresponding value is stored. 13 | 14 | # In Python, the Dictionary data types represent the implementation of hash tables. 15 | 16 | # Visual Example 17 | # https://d33wubrfki0l68.cloudfront.net/87075beeda9ac5cf3bc104aaca45d231ef42aaea/56f14/img/blog/data-structures/hash-tables/hash-table.png 18 | 19 | # Example, Complexity, Usage, Implementation 20 | # https://khalilstemmler.com/blogs/data-structures-algorithms/hash-tables/ 21 | 22 | # Resources 23 | # https://youtu.be/APAbRkrqDVI 24 | # https://realpython.com/python-hash-table/ 25 | # https://www.tutorialspoint.com/python_data_structure/python_hash_table.htm 26 | 27 | # Creating dictionary 28 | # Way 1 29 | my_dict = {"Jessica": "001", "Alba": "002", "Scarlett": "003", "Johansson": "004"} 30 | # Way 2 31 | my_dict = dict(Jessica="001", Alba="002", Scarlett="003", Johansson="004") 32 | 33 | # Nested dictionary 34 | emp_details = { 35 | "Employee": { 36 | "Jessica": { 37 | "ID": "001", 38 | "Salary": "2000", 39 | "Designation": "Team Lead" 40 | }, 41 | "Alba": { 42 | "ID": "002", 43 | "Salary": "1800", 44 | "Designation": "Associate Team Lead" 45 | }, 46 | "Scarlett": { 47 | "ID": "003", 48 | "Salary": "1500", 49 | "Designation": "Senior Developer" 50 | }, 51 | "Johansson": { 52 | "ID": "004", 53 | "Salary": "1200", 54 | "Designation": "Developer" 55 | } 56 | } 57 | } 58 | 59 | # Performing operations on Hash Table 60 | # 1. Accessing Items 61 | # 2. Updating Values 62 | # 3. Deleting Entries 63 | 64 | print(my_dict) 65 | # Getting keys of the dictionary 66 | print(my_dict.keys()) 67 | # Getting values of the dictionary 68 | print(my_dict.values()) 69 | # Getting a specific key's value 70 | print(my_dict.get("Alba")) 71 | # Iterating all the keys present in the dictionary 72 | # Way 1 73 | for x in my_dict: 74 | print(x) 75 | # Way 2 76 | for x in my_dict.keys(): 77 | print(x) 78 | # Iterating all the values of the dictionary 79 | for x in my_dict.values(): 80 | print(x) 81 | # Retrive all the key, value pairs of the dictionary 82 | for x, y in my_dict.items(): 83 | print(x, y) 84 | 85 | # Dictionary is mutable data type 86 | # Updating dictionary 87 | my_dict["Alba"] = "005" # Exists, so value updated 88 | my_dict["Shaon"] = "006" # Doesn't exist, so a new key, value pair added 89 | print(my_dict) 90 | 91 | # Deleting dictionary key, value pair 92 | my_dict.pop("Johansson") 93 | my_dict.popitem() # Delete the last item of the dictionary 94 | del my_dict["Jessica"] 95 | 96 | # Dataframe Defination 97 | 98 | # Two-dimensional, size-mutable, potentially heterogeneous tabular data. 99 | 100 | # Data structure also contains labeled axes (rows and columns). 101 | # Arithmetic operations align on both row and column labels. 102 | # Can be thought of as a dict-like container for Series objects. 103 | # The primary pandas data structure. 104 | 105 | # References 106 | # https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html 107 | 108 | # Converting Dictionary into a Dataframe 109 | 110 | import pandas as pd 111 | 112 | data_frame = pd.DataFrame(emp_details["Employee"]) 113 | print(data_frame) 114 | 115 | # print(my_dict) 116 | 117 | # print(emp_details) 118 | 119 | # print(type(my_dict)) -------------------------------------------------------------------------------- /oop.py: -------------------------------------------------------------------------------- 1 | class Car: 2 | def __init__(self, make, model, year): 3 | self.make = make 4 | self.model = model 5 | self.year = year 6 | 7 | def drive(self): 8 | print("The car is driving.") 9 | 10 | my_car = Car("Toyota", "Corolla", 2020) 11 | 12 | print(my_car.make) # Output: "Toyota" 13 | 14 | my_car.drive() # Output: "The car is driving." 15 | 16 | my_car2 = Car("BMW", "760i xDrive Sedan", 2023) 17 | # print(my_car2) 18 | print(f"Car: {my_car2.make}, Model: {my_car2.model}, Year: {my_car2.year}") 19 | my_car2.drive() -------------------------------------------------------------------------------- /sliding-window-technique.py: -------------------------------------------------------------------------------- 1 | # Reference 2 | # 1. https://youtu.be/9-3BXsfrpbY 3 | # 2. https://www.geeksforgeeks.org/window-sliding-technique/ 4 | # 3. ChatGPT answer 5 | 6 | # Sliding Window Technique 7 | # Aims to reduce the use of nested loop and replace i single loop, thereby reducing the time complexity. 8 | # The `window` is a subset of the data, and `slides` through the larger data structure, performing 9 | # operation on each subset of the elements as it moves. 10 | 11 | # Prerequisite 12 | # Where size of the window for computation is fixed 13 | 14 | # How to use 15 | # 1. Find the size of window required 16 | # 2. Complete the result for 1st window 17 | # 3. Then use a loop to slide the window by 1, and loop computing the result 18 | # window by window. 19 | 20 | -------------------------------------------------------------------------------- /sorting-algo/binary_search_algo.py: -------------------------------------------------------------------------------- 1 | # The basic steps to perform Binary Search are: 2 | # 1. Sort the array in ascending order. 3 | # 2. Set the low index to the first element of the array and the high index to the last element. 4 | # 3. Set the middle index to the average of the low and high indices. 5 | # 4. If the element at the middle index is the target element, return the middle index. 6 | # 5. If the target element is less than the element at the middle index, set the high index to the middle index – 1. 7 | # 6. If the target element is greater than the element at the middle index, set the low index to the middle index + 1. 8 | # 7. Repeat steps 3-6 until the element is found or it is clear that the element is not present in the array. 9 | 10 | # Binary Search Algorithm can be implemented in the following two ways 11 | # 1. Iterative Method 12 | # 2. Recursive Method 13 | 14 | # 1. Iterative Method Binary Search Algorithm: 15 | # binarySearch(arr, x, low, high) 16 | # repeat till low = high 17 | # mid = (low + high)/2 18 | # if (x == arr[mid]) 19 | # return mid 20 | # else if (x > arr[mid]) // x is on the right side 21 | # low = mid + 1 22 | # else // x is on the left side 23 | # high = mid - 1 24 | 25 | # 2. Recursive Method (The recursive method follows the divide and conquer approach) Binary Search Algorithm: 26 | # binarySearch(arr, x, low, high) 27 | # if low > high 28 | # return False 29 | # else 30 | # mid = (low + high) / 2 31 | 32 | # if x == arr[mid] 33 | # return mid 34 | # else if x > arr[mid] // x is on the right side 35 | # return binarySearch(arr, x, mid + 1, high) 36 | # else // x is on the left side 37 | # return binarySearch(arr, x, low, mid - 1) 38 | 39 | # Iterative method 40 | def binarySearchIterative(v, To_Find): 41 | lo = 0 42 | hi = len(v) - 1 43 | 44 | # This below check covers all cases , so need to check 45 | # for mid=lo-(hi-lo)/2 46 | while hi - lo > 1: 47 | mid = (hi + lo) // 2 48 | if v[mid] < To_Find: 49 | lo = mid + 1 50 | else: 51 | hi = mid 52 | 53 | if v[lo] == To_Find: 54 | print("Found At Index", lo) 55 | elif v[hi] == To_Find: 56 | print("Found At Index", hi) 57 | else: 58 | print("Not Found") 59 | 60 | # def binary_search(arr, target): 61 | # left = 0 62 | # right = len(arr) - 1 63 | 64 | # while left <= right: 65 | # mid = (left + right) // 2 66 | # if arr[mid] == target: 67 | # return mid 68 | # elif arr[mid] < target: 69 | # left = mid + 1 70 | # else: 71 | # right = mid - 1 72 | 73 | # return -1 74 | 75 | 76 | # Recursive method 77 | def binarySearchRecursive(arr, l, r, x): 78 | # Check base case 79 | if r >= l: 80 | mid = l + (r - l) // 2 81 | # If element is present at the middle itself 82 | if arr[mid] == x: 83 | return mid 84 | # If element is smaller than mid, then it 85 | # can only be present in left subarray 86 | elif arr[mid] > x: 87 | return binarySearchRecursive(arr, l, mid-1, x) 88 | # Else the element can only be present 89 | # in right subarray 90 | else: 91 | return binarySearchRecursive(arr, mid + 1, r, x) 92 | else: 93 | # Element is not present in the array 94 | return -1 95 | 96 | # Driver Code 97 | arr = [2, 3, 4, 10, 40] 98 | x = 10 99 | 100 | # Function call 101 | binarySearchIterative(v=arr, To_Find=x) 102 | 103 | result = binarySearchRecursive(arr, 0, len(arr)-1, x) 104 | 105 | if result != -1: 106 | print("Element is present at index % d" % result) 107 | else: 108 | print("Element is not present in array") 109 | -------------------------------------------------------------------------------- /trick_1_dictionary_compare.py: -------------------------------------------------------------------------------- 1 | # You can compare 2 dictionary 2 | # that does they have same values 3 | # They have to have same keys with same values 4 | # They can have different order 5 | # If keys and values are same 6 | # Then they are same 7 | 8 | dict1 = { 9 | 'a': 3, 10 | 'b': 10, 11 | 'c': 19 12 | } 13 | 14 | dict2 = { 15 | 'c': 19, 16 | 'a': 3, 17 | 'b': 10 18 | } 19 | 20 | dict3 = { 21 | 'a': 3, 22 | 'b': 10, 23 | 'c': 10 24 | } 25 | 26 | print(dict1) 27 | print(dict2) 28 | print(dict3) 29 | print(dict1 == dict2) 30 | print(dict1 == dict3) 31 | print(dict2 == dict3) -------------------------------------------------------------------------------- /trick_2_missing_unique_elements_in_2_lists.py: -------------------------------------------------------------------------------- 1 | # You can be given 2 lists 2 | # You may need to find the missing unique elements 3 | 4 | list1 = ['a', 'b', 'b', 'c', 'd', 'd', 'e'] 5 | list2 = ['a', 'c', 'b'] 6 | 7 | print(set(list1) - set(list2)) 8 | 9 | # You can get missing elements in a list 10 | print(list(set(list1) - set(list2))) --------------------------------------------------------------------------------