My QA Projects

QA Projects I was involded.

View on GitHub

Inheritance

Base class

Example Base Class: Shape

class Shape:
    def __init__(self):
        pass

    def area(self):
        raise NotImplementedError("Subclasses must implement this method")

    def __str__(self):
        return f"{self.__class__.__name__}"

Derived class

Syntax

class ChildClass(ParentClass):
    def __init__(self):
        super().__init__()
        # child initializer calls parent initializer

If you forget to invoke the __init__() of the parent class then its instance variables would not be available to the child class.

Initializer Method

Example Derived Class: Rectangle

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def __str__(self):
        return f"Rectangle(width={self.width}, height={self.height})"

Example Derived class 2

class Parent:
    def func1(self):
        print("This is function 1")
class Child(Parent):
    def __init__(self, name):
        self.name = name

    def func2(self):
        super().func1()
        print(f"This is function 2 for {self.name}")

ob = Child("Alice")
ob.func2()

OR

class Parent:
      def func1(self):
          print("this is function 1")
class Child(Parent):
      def func2(self):
          super().func1()
          print("this is function 2")
ob = Child()
ob.func2()

Let’s break down why the script works without an init() method in the Parent class:

Parent Class (Parent):

Child Class (Child):

Instance Creation and Method Invocation:


Easy Example 1

Shape is the base class

Rectangle and Triangle are the derived classes.

class Shape:
    def __init__(self):
        pass

    def area(self):
        return 0  # Default implementation returns 0

    def __str__(self):
        return f"{self.__class__.__name__}"

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def __str__(self):
        return f"Rectangle(width={self.width}, height={self.height})"

def create_rectangle():
    width = float(input("Enter the width of the rectangle: "))
    height = float(input("Enter the height of the rectangle: "))
    return Rectangle(width, height)

# Create a rectangle with user input
rectangle = create_rectangle()
print(rectangle) 
# Calls Rectangle's __str__ method
print(f"Area of the {rectangle}: {rectangle.area()}") 
# Calls Rectangle's area method
# Since create_rectangle() always returns a Rectangle object 
# when valid input is provided, there is no need for an additional check.

Easy Example #2 - Base Class: Shape & Derived Class: Rectangle

class Shape:
    def __init__(self):
        pass

    def area(self):
        return 0  # Default implementation returns 0

    def __str__(self):
        return f"{self.__class__.__name__}"

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def __str__(self):
        return f"Rectangle(width={self.width}, height={self.height})"

# Prompt user for dimensions of the rectangle
width = float(input("Enter the width of the rectangle: "))
height = float(input("Enter the height of the rectangle: "))

# Create a Rectangle object
rectangle = Rectangle(width, height)

# Print the Rectangle object and its area
print(rectangle)  
# Calls Rectangle's __str__ method
print(f"Area of the {rectangle}: {rectangle.area()}")  
# Calls Rectangle's area method

Advanced Example Base Class: Shape & Derived Class: Rectangle

class Shape:
    def __init__(self):
        pass

    def area(self):
        raise NotImplementedError("Subclasses must implement this method")

    def __str__(self):
        return f"{self.__class__.__name__}"

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def __str__(self):
        return f"Rectangle(width={self.width}, height={self.height})"

def create_rectangle():
    width = float(input("Enter the width of the rectangle: "))
    height = float(input("Enter the height of the rectangle: "))
    return Rectangle(width, height)

# Create a rectangle with user input
rectangle = create_rectangle()
if rectangle:
    print(rectangle)
    print(f"Area of the {rectangle}: {rectangle.area()}")
'''
Enter the width of the rectangle: 3
Enter the height of the rectangle: 3
Rectangle(width=3.0, height=3.0)
Area of the Rectangle(width=3.0, height=3.0): 9.0
'''

Example User can pick Rectangle and Triangle from Shape

class Shape:
    def __init__(self):
        pass

    def area(self):
        raise NotImplementedError("Subclasses must implement this method")

    def __str__(self):
        return f"{self.__class__.__name__}"

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def __str__(self):
        return f"Rectangle(width={self.width}, height={self.height})"

class Triangle(Shape):
    def __init__(self, base, height):
        super().__init__()
        self.base = base
        self.height = height

    def area(self):
        return 0.5 * self.base * self.height

    def __str__(self):
        return f"Triangle(base={self.base}, height={self.height})"

def create_shape():
    shape_type = input("Enter the type of shape (rectangle/triangle): ").lower()
    
    if shape_type == "rectangle":
        width = float(input("Enter the width of the rectangle: "))
        height = float(input("Enter the height of the rectangle: "))
        return Rectangle(width, height)
    
    elif shape_type == "triangle":
        base = float(input("Enter the base of the triangle: "))
        height = float(input("Enter the height of the triangle: "))
        return Triangle(base, height)
    
    else:
        print("Invalid shape type")
        return None

# Create a shape with user input
shape = create_shape()
if shape:
    print(shape)
    print(f"Area of the {shape}: {shape.area()}")

Types Of Inheritance

class Parent:
      def func1(self):
           print("this is function one")
class Child(Parent):
      def func2(self):
            print(" this is function 2 ")
ob = Child()
ob.func1()
ob.func2()
class Parent:
     def func1(self):
         print("this is function 1")
class Parent2:
      def func2(self):
           print("this is function 2")
class Child(Parent , Parent2):
     def func3(self):
          print("this is function 3")
ob = Child()
ob.func1()
ob.func2()
ob.func3()
class Parent:
      def func1(self):
           print("this is function 1")
class Child(Parent):
      def func2(self):
      print("this is function 2")
class Child2(Child):
      def func3("this is function 3")
ob = Child2()
ob.func1()
ob.func2()
ob.func3()
class Parent:
      def func1(self):
          print("this is function 1")
class Child(Parent):
      def func2(self):
          print("this is function 2")
class Child2(Parent):
     def func3(self):
         print("this is function 3")
ob = Child()
ob1 = Child2()
ob.func1()
ob.func2()
class Parent:
      def func1(self):
          print("this is function one")
class Child(Parent):
      def func2(self):
           print("this is function 2")
class Child1(Parent):
      def func3(self):
       print(" this is function 3"):
class Child3(Parent , Child1):
      def func4(self):
           print(" this is function 4")
ob = Child3()
ob.func1()

information flow

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def display(self):
        print(self.name, self.age)

class Student(Person):
    def __init__(self, name, age):
        self.sName = name
        self.sAge = age # inheriting the properties of parent
        super().__init__("Mike", age)

    def displayInfo(self):
        print(self.sName, self.sAge)

obj = Student("Maya", 53) # Object Creation
obj.display()
obj.displayInfo()
  1. When Student("Maya", 53) is executed, the __init__ method of the Student class is called with name="Maya" and age=53.
  2. Inside the Student’s __init__ Method:
    • self.sName is set to “Maya”.
    • self.sAge is set to 53.
    • The super().__init__("Mike", age) call invokes the __init__ method of the Person class with name="Mike" and age=53.
  3. Inside the Person’s __init__ Method:
    • self.name is set to “Mike”.
    • self.age is set to 53.
    • The control returns back to the Student’s __init__ method, completing the initialization of the obj.
  4. Calling obj.display():
    • The display method of the Person class is called.
    • It accesses self.name and self.age, which are “Mike” and 53 respectively.
    • It prints: Mike 53.
  5. Calling obj.displayInfo():
    • The displayInfo method of the Student class is called.
    • It accesses self.sName and self.sAge, which are “Maya” and 53 respectively.
    • It prints: Maya 53.

Key Points of Inheritance:

https://www.geeksforgeeks.org/inheritance-in-python/