To Solve this Problem , Please read OOP Part I : https://udus.online/object-oriented-programming-i/

Write OOP classes to handle the following scenarios:

  • A user can create and view 2D coordinates
  • A user can find out the distance between 2 coordinates
  • A user can find find the distance of a coordinate from origin
  • A user can check if a point lies on a given line
  • A user can find the distance between a given 2D point and a given line

Point Class:

class Point:
    def __init__(self, x, y):
        # Constructor to initialize x and y coordinates
        self.x_cod = x
        self.y_cod = y
    def __str__(self):
        # String representation of the Point object
        return '<{},{}>'.format(self.x_cod, self.y_cod)
    def euclidean_distance(self, other):
        # Method to calculate the Euclidean distance between two points
        return ((self.x_cod - other.x_cod)**2 + (self.y_cod - other.y_cod)**2)**0.5
    def distance_from_origin(self):
        # Method to calculate the distance of the point from the origin
        return (self.x_cod**2 + self.y_cod**2)**0.5
        # Alternative method using euclidean_distance: return self.euclidean_distance(Point(0,0))

Explanation:

  • The Point class represents a 2D point with x and y coordinates.
  • The constructor __init__ initializes the point with given x and y values.
  • The __str__ method provides a string representation of the point.
  • euclidean_distance calculates the Euclidean distance between the current point and another point passed as an argument.
  • distance_from_origin calculates the distance of the point from the origin.

Line Class:

class Line:
    def __init__(self, A, B, C):
        # Constructor to initialize coefficients of the line equation (Ax + By + C = 0)
        self.A = A
        self.B = B
        self.C = C
    def __str__(self):
        # String representation of the Line object
        return '{}x + {}y + {} = 0'.format(self.A, self.B, self.C)
    def point_on_line(line, point):
        # Method to check if a given point lies on the line
        if line.A*point.x_cod + line.B*point.y_cod + line.C == 0:
            return "lies on the line"
        else:
            return "does not lie on the line"
    def shortest_distance(line, point):
        # Method to calculate the shortest distance from a point to the line
        return abs(line.A*point.x_cod + line.B*point.y_cod + line.C) / (line.A**2 + line.B**2)**0.5

Explanation:

  • The Line class represents a line in the form Ax + By + C = 0.
  • The constructor __init__ initializes the line with coefficients A, B, and C.
  • The __str__ method provides a string representation of the line equation.
  • point_on_line checks if a given point lies on the line.
  • shortest_distance calculates the shortest distance from a given point to the line.

Example Usage:

# Example usage of the classes
l1 = Line(1, 1, -2)
p1 = Point(1, 10)
# Display the line equation and the point
print(l1)
print(p1)
# Calculate and print the shortest distance from the point to the line
print(l1.shortest_distance(p1))

Explanation:

  • An instance of the Line class (l1) and an instance of the Point class (p1) are created.
  • The line equation and the point are printed.
  • The shortest distance from the point to the line is calculated and printed.

This code demonstrates the use of object-oriented programming (OOP) to model 2D points and lines, providing methods to perform common operations related to points and lines.

How Objects Access Attributes:

class Person:
    def __init__(self, name_input, country_input):
        self.name = name_input
        self.country = country_input
    def greet(self):
        if self.country == 'india':
            print('Namaste', self.name)
        else:
            print('Hello', self.name)
# Creating an instance of the Person class
p = Person('nabin', 'nepal')
# Accessing attributes
print(p.name)  # Output: nabin
print(p.country)  # Output: nepal
# Accessing methods
p.greet()  # Output: Hello nabin
# Trying to access a non-existent attribute
# This will result in an AttributeError
# Uncommenting the line below will result in an error
# print(p.gender)

Explanation:

  • An instance of the Person class is created with the name ‘nabin’ and the country ‘nepal’.
  • The name and country attributes are accessed using dot notation (p.name and p.country).
  • The greet method is called on the instance, displaying a greeting based on the country.
  • Attempting to access a non-existent attribute (p.gender) will result in an AttributeError because gender was not defined in the class.

Attribute Creation from Outside the Class:

# Creating an attribute 'gender' from outside the class
p.gender = 'male'
# Accessing the newly created attribute
print(p.gender)  # Output: male

Explanation:

  • Outside the class, a new attribute gender is assigned to the instance p.
  • The newly created attribute is then accessed using dot notation (p.gender).
  • This demonstrates that in Python, you can dynamically add attributes to an object, even if they were not initially defined in the class.

Note: Dynamically adding attributes from outside the class can be done, but it’s generally recommended to define all attributes in the class to maintain clarity and avoid unexpected issues.

Reference Variables in Python:

Reference Variables

  • Reference variables hold the objects
  • We can create objects without reference variable as well
  • An object can have multiple reference variables
  • Assigning a new reference variable to an existing object does not create a new object
# Define a class named Person
class Person:
    # Constructor method to initialize attributes
    def __init__(self):
        self.name = 'nabin'
        self.gender = 'male'
# Create an object of the Person class
p = Person()
# Create another reference variable 'q' pointing to the same object as 'p'
q = p
# Display the memory addresses of objects (p and q)
print("Memory address of p:", id(p))
print("Memory address of q:", id(q))
# Display the current value of the 'name' attribute for both references
print("Name attribute of p:", p.name)
print("Name attribute of q:", q.name)
# Change the value of 'name' attribute using the 'q' reference
q.name = 'naksh'
# Display the updated value of 'name' attribute for both references
print("Updated name attribute of q:", q.name)
print("Updated name attribute of p:", p.name)

Explanation:

  • Person class is defined with a constructor that initializes two attributes (name and gender).
  • An object p of the Person class is created.
  • Another reference variable q is assigned to the same object as p. Both p and q now reference the same object in memory.
  • The id() function is used to display the memory addresses of objects p and q.
  • Initially, both p and q have the same value for the name attribute (‘nabin’).
  • The value of the name attribute is then changed using the q reference, and this change is reflected when accessing the name attribute through the p reference.

Note:

  • In Python, objects are created in memory, and reference variables hold references to these objects rather than the objects themselves.
  • Multiple reference variables can refer to the same object.
  • Modifying the object through one reference (e.g., q) will affect the object accessed through other references (e.g., p), as they point to the same underlying object in memory.

Pass by Reference in Python:

# Define a class named Person
class Person:
    # Constructor method to initialize attributes
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
# Function to greet a person and modify the person's name
def greet(person):
    print('Hi, my name is', person.name, 'and I am a', person.gender)
    person.name = 'naksh'
    print('Inside function:', person.name)
    # Creating a new Person object within the function
    p1 = Person('new_person', 'female')
    return p1
# Create an instance of the Person class
p = Person('nabin', 'male')
# Call the greet function, which modifies the name and returns a new Person object
x = greet(p)
# Print the name and gender of the modified object returned from the function
print('Outside function - Name:', x.name)
print('Outside function - Gender:', x.gender)
# Redefine the Person class (for the second part of the code)
class Person:
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
# Function to modify the name attribute of a person
def modify_name(person):
    print('Memory address inside function:', id(person))
    person.name = 'naksh'
    print('Inside function - Name:', person.name)
# Create a new instance of the Person class
p = Person('nabin', 'male')
# Print the memory address of the object before calling the function
print('Memory address outside function:', id(p))
# Call the function to modify the name attribute
modify_name(p)
# Print the modified name attribute outside the function
print('Outside function - Name:', p.name)

Explanation:

  • In Python, everything is passed by object reference, meaning that the reference to the object is passed to functions, not the actual object.
  • The greet function modifies the name attribute of the passed person object. It also creates a new Person object (p1) within the function and returns it.
  • The x variable outside the function references the same object as p, and modifications to x affect the original object.
  • The second part of the code demonstrates that modifying the attributes of an object inside a function reflects those changes outside the function. The memory address of the object is the same both inside and outside the function, confirming pass by reference behavior in Python.

Object Mutability in Python:

# Define a class named Person
class Person:
    # Constructor method to initialize attributes
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
# Function to greet a person and modify the person's name
def greet(person):
    person.name = 'naksh'
    return person
# Create an instance of the Person class
p = Person('nabin', 'male')
# Print the memory address of the original object
print('Memory address of p:', id(p))
# Call the greet function, which modifies the name attribute and returns the modified object
p1 = greet(p)
# Print the memory address of the modified object
print('Memory address of p1:', id(p1))

Explanation:

  • In this example, a Person class is defined with attributes name and gender.
  • An instance of the Person class (p) is created with the name ‘nabin’ and gender ‘male’.
  • The greet function takes a person parameter and modifies the name attribute of the passed object to ‘naksh’.
  • After calling the greet function with the p object, the modified object is assigned to p1.
  • Both p and p1 reference the same object in memory, and the memory address of p1 is printed.

Object Mutability in Python:

  • In Python, mutable objects can be modified in-place. Lists, dictionaries, and custom objects (instances of classes) are mutable.
  • When you modify an attribute of an object (like changing the name attribute of the Person object in this example), the change is reflected in all references to that object.
  • The memory address of the object remains the same before and after the modification.
  • Immutable objects, on the other hand, cannot be modified after creation. Examples of immutable objects in Python include integers, floats, strings, and tuples.

18 Replies to “Object Oriented Programming (II)”

  1. Come in a jurisdiction of fear and irresolution in https://gamesonicexe.com, a game that reimagines the iconic Sonic franchise as a chilling fear experience. Players forced to outwit and outrun the malevolent Sonic.exe as they cruise through haunting levels filled with liable to be and dread. Can you last the nightmare and break out its clutches?

  2. You hold a brief for your accommodations against hordes of zombies using a variety of plants, each with one of a kind abilities, in https://plantszombiegame.com. The game’s judicious is to survive waves of zombies nearby strategically placing plants. This tourney challenges players to think vanguard and avail oneself of resources wisely to fend supplied the undead.

  3. Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?

Leave a Reply

Your email address will not be published. Required fields are marked *