0% found this document useful (0 votes)
2 views32 pages

Python Module 4

The document provides an overview of Python programming, focusing on modules, random number generation, time management, and mathematical functions. It details key functions from the random and time modules, as well as the math module, and explains how to create custom modules and understand namespaces. Additionally, it discusses the concept of scope and lookup rules in Python, emphasizing the importance of managing identifiers across different namespaces.

Uploaded by

shamnachammu158
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views32 pages

Python Module 4

The document provides an overview of Python programming, focusing on modules, random number generation, time management, and mathematical functions. It details key functions from the random and time modules, as well as the math module, and explains how to create custom modules and understand namespaces. Additionally, it discusses the concept of scope and lookup rules in Python, emphasizing the importance of managing identifiers across different namespaces.

Uploaded by

shamnachammu158
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

KVG College Of Engineering

DEPARTMENT OF ECE

NOTES
PYTHON PROGRAMMING
1BPLC105B/205B

PYTHON PROGRAMMING
Module-4
Python Programming Dept. ECE

Modules

A module is a file containing Python definitions and statements intended for use in other Python
programs. There are many Python modules that come with Python as part of the standard library.
For example: math, random and time modules

The help system contains a listing of all the standard modules that are available with Python.

Random Numbers
We often want to use random numbers in programs, here are a few typical uses:

• To play a game of chance where the computer needs to throw some dice, pick a number, or flip
a coin,
• To shuffle a deck of playing cards randomly,

• To allow/make an enemy spaceship appear at a random location and start shooting at the player,

• To simulate possible rainfall when we make a computerized model for estimating the
environmental impact of building a dam

• For encrypting banking sessions on the Internet.

Generating random numbers in Python is primarily done using the built-in random module. This
module provides a wide array of functions for various random number generation and random
selection tasks.

The random module is a pseudo-random number generator (PRNG). This means the numbers
it generates aren't truly random but are calculated using a deterministic algorithm. However, for
most computer science applications, including simulations, games, and security (non-
cryptographic), they are sufficiently random.

To use any function from the module, you must first import it:

import random
Python Programming Dept. ECE

Key Functions for Random Number Generation


The random module offers several essential functions for generating different types of random
numbers.

1. [Link]()
 Purpose: Returns a random floating-point number.

 Range: - The number is greater than or equal to and strictly less than .

 Example:

float_val = [Link]()

# Example output: 0.87321654...

2. [Link](a, b)
 Purpose: Returns a random integer.

 Range: - The number is greater than or equal to and less than or equal to (inclusive on both
ends).
 Note: The arguments and must be integers.

 Example:

dice_roll = [Link](1, 6)

# Example output: 4 (could be 1, 2, 3, 4, 5, or 6)

3. [Link](a, b)
 Purpose: Returns a random floating-point number .

 Range: or depending on floating-point rounding. It's generally considered an inclusive


range for the numbers between and .

 Example:

rand_coord = [Link](-10.0, 10.0)

# Example output: 3.14159...


Python Programming Dept. ECE

4. [Link](start, stop, step)


 Purpose: Returns a randomly selected element from the range created by range(start, stop,
step).

 Range: Includes start but excludes stop.

 Note: Similar to the built-in range() function. The step argument is optional.

 Example:

even_number = [Link](2, 11, 2)

# Picks one from 2, 4, 6, 8, 10. Example output: 6

Functions for Sequence Selection


These functions are used to pick random items from lists, tuples, or strings (sequences).

1. [Link](sequence)
 Purpose: Returns a random single element from a non-empty sequence.

 Example:

colors = ['Red', 'Green', 'Blue']

rand_color = [Link](colors)

# Example output: 'Blue'

2. [Link](sequence, k=n)
 Purpose: Returns a list of elements randomly chosen from a sequence with replacement
(an item can be chosen multiple times).

 Example:

deck = ['A', 'K', 'Q']


hand = [Link](deck, k=5)

# Example output: ['A', 'A', 'K', 'Q', 'A']


Python Programming Dept. ECE

3. [Link](sequence, k=n)
 Purpose: Returns a list of elements randomly chosen from a sequence without
replacement (each item is unique). cannot be larger than the sequence length.

 Example:

numbers = list(range(1, 50)) # 1 to 49


lottery_picks = [Link](numbers, k=6)

# Example output: [45, 12, 3, 29, 17, 48] (all unique)

4. [Link](x)
 Purpose: Shuffles (randomly reorders) the items of a list x in place. It modifies the
original list and returns None.

 Example:

my_list = [1, 2, 3, 4, 5]
[Link](my_list)

# my_list is now: [3, 5, 1, 4, 2] (example)

Time Module
The time module in Python provides essential functions for working with time, including
measuring performance, pausing execution, and formatting dates and times. It's crucial for
understanding execution speed and scheduling events in programs.

Measuring Time and Performance


These functions help you benchmark code and determine how long operations take.

1. time.perf_counter() - Best for Measurement


 Purpose: Returns the value of a high-resolution, monotonic (never decreases)
performance counter.

 Use: This is the preferred function for measuring the duration of short operations. Its
value is purely for difference calculation and isn't tied to the calendar date.

 Example (Benchmarking):
Python Programming Dept. ECE

import time
start = time.perf_counter()

# Code to measure...
end = time.perf_counter()

elapsed = end - start

print(f"Operation took {elapsed:.6f} seconds.")


2. [Link]() - For Epoch Time
 Purpose: Returns the current time as a floating-point number (seconds).

 Reference: This number is the count of seconds that have passed since the Epoch (January
1, 1970, 00:00:00 UTC).

 Use: Useful for storing timestamps, comparing large time intervals, or generating unique
IDs based on time.

3. [Link](secs) - Pausing Execution


 Purpose: Pauses the execution of the program for the specified number of seconds. secs
can be a float for fractional seconds.

 Use: Essential for simulations, slowing down code for visual output, or rate-limiting
interactions (e.g., waiting between sending requests to a server).

print("Starting...")

[Link](1.5) # Program waits for 1.5 seconds

print("...Resumed!")

Time Structures and Conversion


The time module uses different ways to represent time, requiring conversion functions.

1. Time in Seconds (Float)


 The raw numerical output from [Link]().

2. Time Tuple (Struct Time)


 A 9-element object (like a tuple) that breaks down a point in time into components like
year, month, day, hour, etc.
Python Programming Dept. ECE

 Functions that return a Time Tuple:


o [Link](): Converts Epoch seconds to the local time zone's time tuple.
o [Link](): Converts Epoch seconds to the UTC (Coordinated Universal
Time) time tuple.

Index Attribute Description Values

0 tm_year Year e.g., 2025

1 tm_mon Month 1 to 12

3 tm_hour Hour 0 to 23

6 tm_wday Day of the week 0 (Monday) to 6 (Sunday)

3. Key Conversion Functions

Function Input Output Purpose

Seconds
[Link](secs) Time Tuple Convert Epoch seconds to local time tuple.
(float)

Seconds Convert a local time tuple back to Epoch


[Link](tuple) Time Tuple
(float) seconds.

Time Formatting for Display


These functions are used to present time to users in a readable string format.

1. [Link](secs)
 Purpose: Converts time in seconds to a simple, fixed-format string representing the local
time.
 Example:

print([Link]())

# Output (example): 'Fri Sep 26 09:43:47 2025'


Python Programming Dept. ECE

2. [Link](format, t) - Custom Formatting


 Purpose: Formats a time tuple (t) into a custom string based on the provided format codes.
This gives you full control over the output.

 Example (Custom Format):

now_tuple = [Link]()
# Using format codes

date_str = [Link]("Date: %Y-%m-%d | Time: %I:%M %p", now_tuple)

# Output (example): 'Date: 2025-09-26 | Time: 09:43 AM'

 Common Format Codes:


o %Y: Full year (e.g., 2025)
o %m: Month (01-12)
o %d: Day of the month (01-31)
o %H: Hour (24-hour clock, 00-23)
o %M: Minute (00-59)
o %p: AM/PM indicator (e.g., AM)

Math Module
The math module provides access to mathematical functions and constants for advanced
operations beyond basic arithmetic. It is essential for engineering and complex computing tasks.

Remember to import the module before use:


import math

# Some the common math modules used in Python

# --- 1. Constants Examples ---


print("--- 1. Mathematical Constants ---")
print(f"Value of Pi (π): {[Link]}")
print(f"Value of Euler's number (e): {math.e}")
print("-" * 30)
Python Programming Dept. ECE

# --- 2. Powers and Roots Examples ---


print("--- 2. Powers and Roots ---")
# [Link](x, y) - x raised to the power of y (returns float)
print(f"2 to the power of 5: {[Link](2, 5)}")

# [Link](x) - Square root


print(f"Square root of 81: {[Link](81)}")

# [Link](x) - e raised to x
print(f"e^3: {[Link](3)}")
print("-" * 30)

# --- 3. Rounding and Truncation Examples ---


print("--- 3. Rounding and Truncation ---")
value = 14.789
neg_value = -3.14

# [Link](x) - Rounds up to the nearest integer


print(f"Ceiling of {value}: {[Link](value)}")

# [Link](x) - Rounds down to the nearest integer


print(f"Floor of {value}: {[Link](value)}")

# [Link](x) - Truncates (removes the decimal part)


print(f"Truncation of {neg_value}: {[Link](neg_value)}")
print("-" * 30)

# --- 4. Logarithm Examples ---


print("--- 4. Logarithms ---")
# [Link](x) - Natural logarithm (base e)
print(f"Natural log of 1: {[Link](1)}")

# math.log10(x) - Logarithm base 10


print(f"Log base 10 of 1000: {math.log10(1000)}")

# [Link](x, base) - Logarithm with specified base


print(f"Log base 2 of 32: {[Link](32, 2)}")
print("-" * 30)

# --- 5. Trigonometry and Conversions ---


Python Programming Dept. ECE

print("--- 5. Trigonometry and Conversions ---")


angle_degrees = 90
print(f"Angle in Degrees: {angle_degrees}")

# [Link]() - Convert degrees to radians (required for sin/cos/tan)


angle_radians = [Link](angle_degrees)
print(f"Converted to Radians: {angle_radians:.4f}")

# [Link]() - Sine function


print(f"Sine of 90 degrees (pi/2 rad): {[Link](angle_radians):.1f}")

# [Link]() - Convert radians back to degrees


converted_degrees = [Link](angle_radians)
print(f"Converted back to Degrees: {converted_degrees:.1f}")
print("-" * 30)

# --- 6. Other Useful Functions ---


print("--- 6. Other Useful Functions ---")

# [Link](n) - Calculate n!
print(f"Factorial of 6 (6!): {[Link](6)}")

# [Link](a, b) - Greatest Common Divisor


print(f"GCD of 56 and 98: {[Link](56, 98)}")

# [Link](a, b) - Safe floating-point comparison


float_sum = 0.1 + 0.2
print(f"Is (0.1 + 0.2) close to 0.3? {[Link](float_sum, 0.3)}")

Creating your own modules


All we need to do to create our own modules is to save our script as a file with a .py extension.
Suppose, for example, this script is saved as a file named [Link]:

def remove_at(pos, seq):


return seq[:pos] + seq[pos+1:]
We can now use our module, both in scripts we write, or in the interactive Python interpreter.
Python Programming Dept. ECE

To do so, we must first import the module.

import seqtools

s = "A string!" >>>

seqtools.remove_at(4, s)
print(s)

Output: ‘A sting!’

We do not include the .py file extension when importing. Python expects the file names of Python
modules to end in .py, so the file extension is not included in the import statement.
The use of modules makes it possible to break up very large programs into manageable sized parts,
and to keep related parts together.

NameSpaces
A namespace is essentially a system that maps names to objects.

Key Purpose: Preventing Conflicts The main job of namespaces is to ensure that two identical
names do not accidentally refer to the same object when they shouldn't.

 If you define a function named calculate() in one module (global namespace A), and a
library you import defines its own calculate() function (global namespace B), Python uses
the module's namespace to keep them separate.

 If you are inside a function (Local Namespace) and use a variable i, it won't conflict with
a separate variable i used in the main part of your script (Global Namespace).
Python Programming Dept. ECE

Example code snippet to explain Namespaces

# GLOBAL NAMESPACE: The main house (Everyone can see)


# Global variable 'x' is set.
x = 10

def change_x_locally():
# LOCAL NAMESPACE: A specific room (Private scope)
# This 'x' is a NEW, local variable inside the function.
# It does NOT change the global 'x' defined above.
x=5
print(f"Inside function (Local x): {x}")

# --- Program Execution ---

print("1. Before calling function (Global x):", x)

# When this runs, a local namespace is temporarily created.


change_x_locally()

# After the function exits, we are back in the global namespace.


print("2. After calling function (Global x):", x)

Output:
1. Before calling function (Global x): 10
Inside function (Local x): 5
2. After calling function (Global x): 10
# Key Takeaway: The global 'x' stayed 10, proving the 'x' inside the function was separate.

Scope and Lookup Rules


The scope of an identifier is the region of program code in which the identifier can be accessed, or
used.
There are three important scopes in Python:

• Local scope refers to identifiers declared within a function. These identifiers are kept in the
namespace that belongs to the function, and each function has its own namespace.
• Global scope refers to all the identifiers declared within the current module, or file.
Python Programming Dept. ECE

• Built-in scope refers to all the identifiers built into Python — those like range and min that can
be used without having to import anything, and are (almost) always available.
Python can help you by telling you what is in which scope. Use the functions locals, globals, and
dir to see for yourself!
Python (like most other computer languages) uses precedence rules: the same name could occur
in more than one of these scopes, but the innermost, or local scope, will always take precedence
over the global scope, and the global scope always gets used in preference to the built-in scope.
Let’s start with a simple example:

def range(n):
return 123*n
print(range(10))

What gets printed? We’ve defined our own function called range, so there is now a potential
ambiguity. When we use range, do we mean our own one, or the built-in one? Using the scope
lookup rules determines this: our own range function, not the built-in one, is called, because our
function range is in the global namespace, which takes precedence over the built-in names.

So although names likes range and min are built-in, they can be “hidden” from your use if you
choose to define your own variables or functions that reuse those names. (It is a confusing practice
to redefine built-in names — so to be a good programmer you need to understand the scope rules
and understand that you can do nasty things that will cause confusion, and then you avoid doing
them!)

Now, a slightly more complex example:

n = 10
m=3
def f(n):
m=7
return 2*n+m
print(f(5), n, m)
This prints 17 10 3. The reason is that the two variables m and n in lines 1 and 2 are outside the
function in the global namespace. Inside the function, new variables called n and m are created
just for the duration of the execution of f. These are created in the local namespace of function f.
Within the body of f, the scope lookup rules determine that we use the local variables m and n. By
contrast, after we’ve returned from f, the n and m arguments to the print function refer to the
original variables on lines 1 and 2, and these have not been changed in any way by executing
function f.

Notice too that the def puts name f into the global namespace here. So it can be called on line 7.
Python Programming Dept. ECE

What is the scope of the variable n on line 1? Its scope — the region in which it is visible — is
lines 1, 2, 6, 7. It is hidden from view in lines 3, 4, 5 because of the local variable n.

Attributes and the dot operator


Variables defined inside a module are called attributes of the module. We’ve seen that objects
have attributes too: for example, most objects have a doc attribute, some functions have a
annotations attribute. Attributes are accessed using the dot operator (.).
Modules contain functions as well as attributes, and the dot operator is used to access them in the
same way.

When we use a dotted name, we often refer to it as a fully qualified name, because we’re saying
exactly which attribute we mean.

Three import statement variants


Here are three different ways to import names into the current namespace, and to use them:

import math

x = [Link](10)

Here just the single identifier math is added to the current namespace. If you want to access one
of the functions in the module, you need to use the dot notation to get to it.
Here is a different arrangement:

from math import cos, sin, sqrt

x = sqrt(10)

The names are added directly to the current namespace, and can be used without qualification. The
name math is not itself imported, so trying to use the qualified form [Link] would give an error.
Then we have a convenient shorthand:

from math import * # Import all the identifiers from math,


# adding them to the current namespace.

x = sqrt(10) # Use them without qualification.


Python Programming Dept. ECE

Of these three, the first method is generally preferred, even though it means a little more typing
each time. Although, we can make things shorter by importing a module under a different name:

import math as m

[Link]

#Output: 3.141592653589793

Finally, observe this case:

def area(radius):

import math

return [Link] * radius * radius

x = [Link](10) # This gives an error

Here we imported math, but we imported it into the local namespace of area. So the name is usable
within the function body, but not in the enclosing script, because it is not in the global namespace.

Mutable versus immutable and aliasing


Some datatypes in Python are mutable. This means their contents can be changed after they have
been created. Lists and dictionaries are good examples of mutable datatypes.

my_list = [2, 4, 5, 3, 6, 1]

my_list[0] = 9
my_list

Output: [9, 4, 5, 3, 6, 1]

Tuples and strings are examples of immutable datatypes, their contents cannot be changed after
they have been created:

my_tuple = (2, 5, 3, 1)

my_tuple[0] = 9

Output :

Traceback (most recent call last):


Python Programming Dept. ECE

File "<interactive input>", line 2, in <module>

TypeError: 'tuple' object does not support item assignment


Mutability is usually useful, but it may lead to something called aliasing. In this case, two variables
refer to the same object and mutating one will also change the other:

list_one = [1, 2, 3, 4, 6]

list_two = list_one
list_two[-1] = 5

list_one

Output:

[1, 2, 3, 4, 5]

This happens, because both list_one and list_two refer to the same memory address containing the
actual list. You can check this using the built-in function id:

list_one = [1, 2, 3, 4, 6]
list_two = list_one

id(list_one) == id(list_two)

Output:

True

You can escape this problem by making a copy of the list:

list_one = [1, 2, 3, 4, 6]

list_two = list_one[:]

check_id=(id(list_one) == id(list_two) )
check_id

list_two[-1] = 5
list_two

list_one
Python Programming Dept. ECE

Output

False

[1, 2, 3, 4, 5]

[1, 2, 3, 4, 6]

Object-oriented programming
Python is an object-oriented programming language, which means that it provides features that
support object-oriented programming (OOP

Up to now, most of the programs we have been writing use a procedural programming paradigm.
In procedural programming the focus is on writing functions or procedures which operate on data.
In object-oriented programming the focus is on the creation of objects which contain both data
and functionality together.
Usually, each object definition corresponds to some object or concept in the real world, and the
functions that operate on that object correspond to the ways real-world objects interact.

Classes and Objects – Basics


Classes and Objects are the fundamental building blocks of Object-Oriented Programming (OOP).
Understanding this relationship is crucial for writing scalable and organized code.

1. The Class: The Blueprint

 Definition: A class is a template, blueprint, or definition used to create objects. It defines


what attributes (data) and methods (behavior) all objects of that type will possess.
 Analogy: Think of a class like the design plans for a standard house model. It specifies that
every house will have 3 bedrooms, 2 bathrooms, and a kitchen, but it's not a physical house
yet.

 In Python: Defined using the class keyword.

class Robot:

# Attributes (Characteristics)
# These define the state (data) of the object
Python Programming Dept. ECE

color = "Silver"

# Methods (Behaviors/Actions)

# These are functions that define what the object can do


def perform_task(self):

print("Processing data...")

2. The Object: The Instance

 Definition: An object is a concrete, real-world entity created from a class blueprint. It is an


instance of the class, meaning it occupies memory and has its own unique set of attributes.

 Analogy: An object is the actual physical house built from the plans. You can build many
houses (objects) from the same single blueprint (class).

 In Python: Creating an object is called instantiation.

# Instantiation: creating two distinct objects from the Robot class

robot_alpha = Robot()
robot_beta = Robot() # Changing an attribute on one object does not affect the other
robot_alpha.color = "Red"
robot_beta.color = "Blue"

print(f"Alpha's color: {robot_alpha.color}") # Output: Red

print(f"Beta's color: {robot_beta.color}") # Output: Blue

Key Terminology
Python Programming Dept. ECE

The Constructor ( init Method)


The constructor allows you to set the initial, unique state of an object when it is created, making it
distinct from all other objects of that class.

class Student:
# The Constructor Method

# It takes starting parameters (name, id) and assigns them to the object using 'self'.
def init (self, name, student_id):

[Link] = name # [Link] is the object's attribute

self.student_id = student_id

def get_greeting(self):
# The method uses 'self' to access the unique data of the specific object.
return f"Hello, I am {[Link]} (ID: {self.student_id})."

# Creating objects with initial data


s_engineer = Student("Anya", "ENG101")
s_science = Student("Ben", "SCI205")
Python Programming Dept. ECE

# Calling methods on separate objects

print(s_engineer.get_greeting())

print(s_science.get_greeting())

Output:

Hello, I am Anya (ID: ENG101).

Hello, I am Ben (ID: SCI205).

Attributes
An Attribute is simply a data variable that holds information (the state) associated with a Class or
an Object. They define the characteristics of the entity they belong to.

1. Instance Attributes (The Most Common Type)

These are the attributes that are unique to each specific object (instance) created from the class.

 Analogy: If the class is the blueprint for a cell phone, the instance attributes are the phone's
serial number, its current battery percentage, and the color it was painted.
 Definition: Instance attributes are almost always defined and initialized inside the special
constructor method, init , using the self keyword.
 Access: Accessed using the specific object name followed by the dot operator (e.g.,
[Link]).

Example of Instance Attributes:

class Phone:
# 1. Defined in init using 'self'

def init (self, color, storage_gb):

[Link] = color # Instance Attribute 1 (unique to this object)

[Link] = storage_gb # Instance Attribute 2 (unique to this object)

[Link] = 100 # Default instance attribute


Python Programming Dept. ECE

# Creating two instances (objects)

phone1 = Phone("Red", 128)

phone2 = Phone("Black", 256)

# Accessing and modifying instance attributes

print(f"Phone 1 Color: {[Link]}") # Output: Red


print(f"Phone 2 Storage: {[Link]}GB") # Output: 256GB

[Link] = 50 # Modifying phone1's state


print(f"Phone 1 Battery: {[Link]}%")

2. Class Attributes (Shared by all Instances)

These are attributes that are shared equally by all objects created from the class. They hold data
that is common to the entire class type.

Analogy: For the cell phone class, the class attribute might be manufacturer = "TechCorp" or
default_screen_size = 6.5. Every phone object shares this same value.

Definition: Defined directly inside the class body, but outside any method.

Access: Accessed either through the Class itself ([Link]) or via an instance
([Link]).

Example of Class Attributes:

class Phone:
# 1. Defined outside of init
manufacturer = "GlobalTech" # Class Attribute
default_os = "PyOS 10" # Class Attribute

def init (self, model):


Python Programming Dept. ECE

[Link] = model # Instance Attribute

# Accessing Class Attributes via the Class itself


print(f"Manufacturer: {[Link]}")

phone_x = Phone("X1 Pro")


phone_y = Phone("Y2 Lite")

# Accessing Class Attributes via instances (they share the same value)
print(f"{phone_x.model} OS: {phone_x.default_os}")
print(f"{phone_y.model} Manufacturer: {phone_y.manufacturer}")

# If you change the Class Attribute, it changes for all instances

[Link] = "NewTech Inc."

print(f"Updated Manufacturer: {phone_y.manufacturer}") # Output: NewTech Inc.

Summary of Differences

Feature Instance Attribute Class Attribute

Shared by the entire class and all


Scope Unique to each object.
objects.

Definition Inside init using


Directly inside the class body.
Location [Link].

To store constant or shared


To define the unique state of an
Purpose information (e.g., PI, gravity,
object (e.g., color, name, health).
species name).
Python Programming Dept. ECE

Adding Methods to our class


A Method is essentially a function defined inside a Class. Methods define the behavior or
actions that an object can perform, allowing objects to interact with their own unique data
(attributes).

1. The Structure of a Method


Methods look just like standard Python functions, but they must always accept the self parameter
as their first argument.
Example:

class Device:
# Constructor: initializes the unique state of the object
def init (self, serial_number):

self.serial_number = serial_number # Instance Attribute

self.is_on = False # State attribute

# Method: Defines an action/behavior


def toggle_power(self):

# The method uses 'self' to access and change the instance attribute 'is_on'
self.is_on = not self.is_on

status = "ON" if self.is_on else "OFF"


print(f"Device {self.serial_number} is now {status}.")

2. The Essential Role of self


The self-parameter is the most critical element of any instance method in Python:

 Reference to the Instance: self is a required convention (it's short for "self-reference")
that refers to the specific object (instance) that called the method.

 Access to Attributes: It provides the method with access to the object's unique data. You
must use self. before any attribute or other method you want to access within the class
(e.g., self.serial_number).
Python Programming Dept. ECE

 Implicit Passing: When you call a method on an object (e.g., device1.toggle_power()),


you do not manually pass the self argument. Python handles this automatically, passing the
device1 object itself as the self parameter behind the scenes.

3. Method Interaction Example


This demonstrates how methods use self to operate on distinct object states:

# Create two separate objects

device1 = Device("A001")

device2 = Device("B002")

# Calling the same method, but 'self' refers to device1


device1.toggle_power() # Output: Device A001 is now ON.

# Calling the same method, but 'self' refers to device2


device2.toggle_power() # Output: Device B002 is now ON.

# Calling device1 again changes only device1's state

device1.toggle_power() # Output: Device A001 is now OFF.

Instances as arguments and parameters


Once you create an object (an instance) from a class, that object behaves just like any other piece
of data in Python—like an integer, a string, or a list. This means you can:
1. Pass an object as an argument to a function.

2. Receive an object as a parameter within a function or method.

This is fundamental for building systems where objects interact with each other.

1. The Concept: Object Interaction


Python Programming Dept. ECE

Imagine you have two classes: Robot and Charger. A robot needs to be charged by the charger.
The charging function must know which robot it is supposed to charge. The way to tell the function
is by passing the specific Robot object to the Charger's method.

Example :

We define a simple class Battery to represent a power source.

class Battery:

def init (self, charge_level):

[Link] = charge_level

def report_charge(self):

return f"Battery is at {[Link]}%."

# A Function that takes an INSTANCE as a parameter

def check_power(device_battery):

"""

This function accepts an object (device_battery) of type Battery

and uses its methods/attributes.

"""
print("--- Power Check ---")

if device_battery.level < 20:

print("ALERT: Charge immediately!")


print(device_battery.report_charge())

2. Passing Instances as Arguments


Python Programming Dept. ECE

In the main program, we create an instance of the Battery class and then pass that instance directly
into the generic check_power function.

# 1. Create the instance (Object)

car_battery = Battery(charge_level=95)

drone_battery = Battery(charge_level=15)

# 2. Pass the instance as an argument

print("Checking Car Battery:")

check_power(car_battery)

# The 'car_battery' object is passed to the 'device_battery' parameter.

print("\nChecking Drone Battery:")


check_power(drone_battery)

# The 'drone_battery' object is passed to the 'device_battery' parameter.

Output:
Checking Car Battery:

--- Power Check ---


Battery is at 95%.

Checking Drone Battery:

--- Power Check ---

ALERT: Charge immediately!

Battery is at 15%.

3. Instances as Parameters in Class Methods

This concept is often used when one object needs to perform an action on another object.

class RepairShop:

def repair_device(self, item_to_fix):


Python Programming Dept. ECE

"""
Takes another object (item_to_fix) as a parameter.

The type of item_to_fix isn't fixed, but it's expected

to have a 'level' attribute.

"""
print(f"\nRepairing device...")

if item_to_fix.level < 50:

item_to_fix.level = 100 # Modifies the state of the passed object

print("Repair complete: Charge set to 100%.")


else:
print("Device was already well charged, no repair needed.")

# Interaction

shop = RepairShop()

# The RepairShop object (shop) calls its method, passing the drone_battery object
# as an argument.

shop.repair_device(drone_battery)

# Check the state of the drone_battery object after the method ran
print(drone_battery.report_charge()) # Output: Battery is at 100%.

Converting an instance to a string


In Python, when you want to display an object, log its status, or print it to the console, Python
needs a way to convert that complex object (which holds attributes and methods) into a simple,
readable string.
This conversion is handled by implementing two special methods within your class: repr and
str .

1. The Default Representation (The Problem)


Python Programming Dept. ECE

If you don't define a custom string method, Python defaults to showing the object's type and its
memory location, which is usually not helpful to a user.

class Point:

def init (self, x, y):

self.x = x

self.y = y
p1 = Point(5, 10)

print(p1)

# Default Output (Unhelpful): < main .Point object at 0x10f3c5550>

2. The repr Method (For Developers)


The repr method (pronounced "rep-er") is the "official" string representation of an object.

 Purpose: It's primarily used for debugging, logging, and inspection by developers. It
should be unambiguous and, if possible, look like valid Python code that could recreate the
object.

 Goal: To answer the question: "How can I reconstruct this object?"

 Rule of Thumb: Always include all key attributes in your repr output.

class Point:

# ... init as before ...

def repr (self):

# Format shows the class name and constructor arguments

return f"Point(x={self.x}, y={self.y})"

p1 = Point(5, 10)

print(repr(p1))
# Output (Developer-friendly): Point(x=5, y=10)

3. The str Method (For Users)


The str method is the "informal" or user-friendly string representation of an object.
Python Programming Dept. ECE

 Purpose: It's used when an object needs to be displayed to an end-user or included in a


human-readable log file.
 Goal: To answer the question: "What does this object look like?"

 Rule of Thumb: Be concise, elegant, and focus on the most important information.

class Point:

# ... init and repr ...


def str (self):

# Format is simple and easy to read

return f"({self.x}, {self.y})"


p1 = Point(5, 10)
print(p1)

# Output (User-friendly): (5, 10)

4. How Python Chooses Which Method to Use


Python has a clear priority when deciding how to display an object:

Action Method Used

print(object) Python looks for str . If str is not defined, it falls back to repr .

str(object) Calls str .

repr(object) Calls repr .

Interactive Console Uses repr by default.

Instances as return values.


In Python, when a method or function finishes its job, it always returns something (like a number,
a boolean, or a string). In Object-Oriented Programming (OOP), that "something" is very often a
full-fledged object (instance).
This is fundamental because it allows objects to participate actively in the flow of your program—
they can be created, processed, and passed along from one step to the next.
Python Programming Dept. ECE

1. The Factory Pattern: Returning a New Object

A Factory Method is a function or class method whose sole job is to construct and return a new
instance of a class.

 Analogy: Imagine a special button on a 3D Printer. You press the "Print Cube" button, and
the printer (the method) constructs a new physical Cube object and hands it to you (returns
it).

 Use Case: You use this when you need a standardized way to create objects with specific,
common initial settings.

Example: Creating a Standardized Sensor

class Sensor:

def init (self, sensitivity, power_mode="Standard"):

[Link] = sensitivity

self.power_mode = power_mode

def repr (self):

return f"Sensor(Mode={self.power_mode}, Sensitivity={[Link]})"

# Factory Method: A function that CREATES and returns a new Sensor object
@staticmethod

def create_low_power_sensor():

"""Creates a new Sensor object optimized for low power."""


# The function creates the object...

new_sensor = Sensor(sensitivity=0.5, power_mode="Low")

# ... and returns the newly created instance.

return new_sensor

# Usage:

# The variable 's_low' now holds a reference to a fully initialized Sensor object.
Python Programming Dept. ECE

s_low = Sensor.create_low_power_sensor()

print(s_low)

# Output: Sensor(Mode=Low, Sensitivity=0.5)


The method create_low_power_sensor() acts as a factory, giving you a ready-to-use Sensor object.

2. Method Chaining: Returning self

Method chaining is a powerful technique where methods are designed to modify the object's state
and then immediately return the object itself (return self). This allows you to call multiple methods
on the same object in a single, clean line.

 Analogy: Imagine assembling a product on a sequential assembly line. Each station


(method) does its small job (e.g., attach wheel, paint) and then hands the product back to
the line so the next station can work on it immediately.

 Use Case: Common in configuration or setup steps where you need to perform sequential
actions on one specific object.
Example: Configuring a Logging System

class LoggerConfig:
def init (self):
[Link] = "INFO"
[Link] = "Console"

def set_level(self, level_str):


[Link] = level_str # Modify the object's state

return self # Return the modified object itself!

def set_output(self, output_str):


[Link] = output_str # Modify the object's state

return self # Return the modified object itself!


Python Programming Dept. ECE

def show_config(self):
print(f"Logger: {[Link]} -> {[Link]}")

# Usage (Method Chaining):

# The result of set_level() is the LoggerConfig object, which immediately calls set_output().

# The result of set_output() is the LoggerConfig object, which immediately calls show_config().

#
config = LoggerConfig()

config.set_level("DEBUG").set_output("File").show_config()

# Output: Logger: DEBUG -> File

You might also like