The Python Language Notes :
Unit – 𝐈𝐈
Functions –
A function is a reusable block of code
designed to perform a specific task.
Functions are useful for breaking down
complex problems into smaller,
manageable pieces and improving code
reusability and organization.
➢Defining a Function: Here's a basic syntax for
defining and calling a function in Python –
Syntax –
def function_name(parameters):
"""docstring (optional): Describes the function"""
# Code block (function body)
return result # (optional) returns a value
Example:
def greet(name):
return f"Hello, {name}!"
print(greet("Uttam")) # Output: Hello, Uttam!
1|Page
➢Calling a Function: If we run the above code,
we won't get an output. It's because creating a
function doesn't mean we are executing the
code inside it. It means the code is there for us
to use if we want to. To use that function, we
need to call the function.
Syntax –
print(function_name(parameters))
Example:
def my_function(fname):
print(fname + " Kumar")
# Calling the function
My_function();
➢Types of Functions: In Python, functions can
be categorized into several types based on
their definition, use case, and how they are
constructed.
Here's an overview of the types of functions
in Python:
2|Page
1. Built-in Functions –
These are functions that are pre-defined in Python
and available for use without any import.
Examples include:
• print(): Outputs data to the console.
• len(): Returns the length of an object.
• sum(): Returns the sum of all items in an
iterable.
Example:
print(len("Hello")) # Output: 5
2. User-Defined Functions –
These are functions created by the user to perform
specific tasks. You define them using the def
keyword.
Example:
def greet(name):
return f"Hello, {name}!"
print(greet("Uttam")) # Output: Hello, Uttam!
3. Anonymous (Lambda) Functions –
These are small, unnamed functions defined using
the lambda keyword. They are typically used for
short, simple operations.
3|Page
Example:
add = lambda x, y: x + y
print(add(3, 4)) # Output: 7
4. Recursive Functions –
A recursive function is a function that calls itself to
solve a problem. Recursion helps break down
complex problems into simpler sub-problems.
Example:
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # Output: 120
5. Generator Functions –
Generator functions use the yield keyword to return
an iterator that yields values one at a time. They are
memory efficient and great for handling large
datasets.
Example:
def count_up_to(max_value):
count = 1
while count <= max_value:
yield count
count += 1
4|Page
counter = count_up_to(3)
print(list(counter)) # Output: [1, 2, 3]
6. Static Methods –
Static methods, defined using the @staticmethod
decorator, belong to a class but do not operate on
instances of the class. They are used when the
method does not need access to the class or its
instances.
Example:
class MyClass:
@staticmethod
def static_method():
print("This is a static method.")
MyClass.static_method() # Output: This is a static method.
7. Class Methods –
Class methods, defined using the @classmethod
decorator, belong to a class and can modify class-
level attributes. The first parameter is cls, which
refers to the class itself.
Example:
class MyClass:
count = 0
@classmethod
def increment(cls):
cls.count += 1
5|Page
MyClass.increment()
print(MyClass.count) # Output: 1
➢ Function Arguments: In Python, function
arguments are used to pass data into a function
when it's called. Python functions can accept
different types of arguments, and these
arguments can be defined in various ways.
Here’s an overview of the different types of
function arguments in Python:
1. Positional Arguments –
These are the most common type of arguments
passed to a function. The values passed in the
function call are assigned to the parameters based
on their position.
Example:
def my_function(fname):
print(fname + " Kumar")
my_function("Uttam")
my_function("Ankit")
Output:
Uttam Kumar
Ankit Kumar
6|Page
2. Keyword Arguments –
You can also pass arguments using the parameter
names explicitly. This allows you to pass values out
of order, which makes the code more readable.
Example:
def greet(name, message):
print(f"Hello {name}, {message}")
greet(message="Good morning!", name="Uttam")
Output:
Hello Uttam, Good morning!
3. Default Arguments –
You can assign default values to parameters. If the
caller doesn't provide a value for that parameter,
the default value is used.
Example:
def greet(name, message="Hello!"):
print(f"Hello {name}, {message}")
greet("Uttam")
Output:
Hello Uttam, Hello!
7|Page
4. Variable-Length Arguments –
Python allows you to pass a variable number of
arguments to a function using special symbols:
• *args (Non-keyworded variable-length arguments): It
allows you to pass a variable number of positional
arguments.
Example:
def greet(*names):
for name in names:
print(f"Hello {name}!")
greet("Uttam", "Vaishali", "Ankit")
Output:
Hello Uttam!
Hello Vaishali!
Hello Ankit!
• **kwargs (Keyworded variable-length arguments): It
allows you to pass a variable number of keyword
arguments.
Example:
def person_info(**details):
for key, value in details.items():
print(f"{key}: {value}")
person_info(name="Uttam", age=30, location="Ddn")
8|Page
Output:
name: Uttam
age: 30
location: Ddn
5. Positional-Only Arguments –
You can force certain arguments to be passed by
position only, using the / symbol in the function
definition.
Example:
def divide(a, b, /):
return a / b
divide(10, 5) # This works
divide(a=10, b=5) # This will raise an error
Output:
2.0
6. Keyword-Only Arguments
You can enforce arguments to be passed only by
keyword using the * symbol in the function
definition.
Example:
def order_food(main, *, drink):
print(f"Main: {main}, Drink: {drink}")
order_food("Burger", drink="Coke") # Works
9|Page
order_food("Burger", "Coke") # Error: drink must be passed as a
keyword argument
Output:
Main: Burger, Drink: Cake
Introduction to List and Tuple -
Both lists and tuples are used to store
collections of items, but they have
important differences in terms of
mutability, syntax, and use cases.
1. Lists –
A list in Python is a mutable, ordered collection of
elements. Lists are highly versatile and allow
elements to be changed, added, or removed after
creation.
Key Characteristics of Lists:
• Mutable: You can modify lists after creation (add,
remove, change elements).
• Ordered: The order of the elements is maintained,
so they can be accessed using indexes.
10 | P a g e
• Heterogeneous: Lists can contain elements of
different types (integers, strings, other lists, etc.).
• Syntax: Lists are defined using square brackets [].
Basic List Operations:
# Creating a list
my_list = [1, 2, 3, "apple", 4.5]
# Accessing elements
print(my_list[0]) # Output: 1
print(my_list[-1]) # Output: 4.5
# Modifying elements
my_list[1] = "banana" # Change element at index 1
print(my_list) # Output: [1, 'banana', 3, 'apple', 4.5]
# Adding elements
my_list.append("orange") # Add an element to the end
print(my_list) # Output: [1, 'banana', 3, 'apple', 4.5, 'orange']
# Removing elements
my_list.remove(3) # Remove the element with value 3
print(my_list) # Output: [1, 'banana', 'apple', 4.5, 'orange']
11 | P a g e
# List length
print(len(my_list)) # Output: 5
Common List Methods:
• append(x): Adds element x to the end of the list.
• remove(x): Removes the first occurrence of element x.
• pop(): Removes and returns the last element.
• sort(): Sorts the list (if all elements are of the same type).
• extend([x, y]): Adds multiple elements to the list.
• insert(i, x): Inserts element x at index i.
2. Tuples –
A tuple in Python is an immutable, ordered
collection of elements. Tuples are faster than lists
because they cannot be changed once created.
They are often used when a fixed sequence of
items is required.
Key Characteristics of Tuples:
• Immutable: You cannot modify the elements of a
tuple after creation.
• Ordered: Elements in a tuple are ordered and can be
accessed by index.
12 | P a g e
• Heterogeneous: Like lists, tuples can contain
different types of elements.
• Syntax: Tuples are defined using parentheses ().
Basic Tuple Operations:
# Creating a tuple
my_tuple = (1, 2, 3, "apple", 4.5)
# Accessing elements
print(my_tuple[0]) # Output: 1
print(my_tuple[-1]) # Output: 4.5
# Tuples are immutable, so you can't modify elements
# my_tuple[1] = "banana" # This would raise an error
# Length of the tuple
print(len(my_tuple)) # Output: 5
# You can concatenate tuples
new_tuple = my_tuple + ("orange", "banana")
print(new_tuple) # Output: (1, 2, 3, 'apple', 4.5, 'orange', 'banana')
13 | P a g e
Common Tuple Methods:
• count(x): Returns the number of times element x appears
in the tuple.
• index(x): Returns the index of the first occurrence of
element x.
Comparison of Lists and Tuples:
Feature List Tuple
Mutability Mutable (can change) Immutable (cannot
change)
Syntax Defined with [] Defined with ()
Performance Slower than tuples Faster due to
immutability
Usage Used for dynamic Used for fixed collections
collections
Dictionaries -
A dictionary is an unordered, mutable
collection of key-value pairs. Each key is
mapped to a value, and keys must be
unique and immutable (like strings or
numbers). Dictionaries are often used to
14 | P a g e
represent real-world data where there's a
relationship between a unique identifier
(key) and a value (data associated with
that key).
Properties of Dictionaries:
• Mutable: You can modify, add, or remove key-value
pairs after the dictionary is created.
• Unordered: The order of insertion is preserved.
• Key-Value Pairs: Each element in a dictionary has a
key and a corresponding value, and you can access
the value using its key.
• Keys are unique: No two keys in a dictionary can be
the same.
• Keys are immutable: Keys must be of a type that is
immutable (strings, numbers, tuples), while values
can be of any type.
Creating and Accessing a Dictionary:
# Creating a dictionary
my_dict = {
"name": "Uttam",
"age": 25,
15 | P a g e
"location": "New York"
}
# Accessing values using keys
print(my_dict["name"]) # Output: Uttam
print(my_dict["age"]) # Output: 25
Modifying a Dictionary:
• Adding new key-value pairs:
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
my_dict["email"] = "[email protected]"
print(my_dict)
# Output: {'name': 'Uttam', 'age': 25, 'location': 'New York',
'email': '[email protected]'}
• Modifying existing values:
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
my_dict["age"] = 26
print(my_dict["age"]) # Output: 26
16 | P a g e
• Removing key-value pairs:
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
del my_dict["location"]
print(my_dict) # Output: {'name': 'Uttam', 'age': 26, 'email':
'[email protected]'}
Common Dictionary Methods:
• get(key, default): Returns the value for a key if it
exists, otherwise returns a default value.
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
print(my_dict.get("name")) # Output: Uttam
print(my_dict.get("address", "Not Found")) # Output: Not Found
• keys(): Returns a list of all keys in the dictionary.
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
17 | P a g e
}
print(my_dict.keys()) # Output: dict_keys(['name', 'age', 'email'])
• values(): Returns a list of all values in the dictionary.
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
print(my_dict.values()) # Output: dict_values(['Uttam', 26,
'
[email protected]'])
• items(): Returns a list of key-value pairs as tuples.
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
print(my_dict.items())
# Output: dict_items([('name', 'Alice'), ('age', 26), ('email',
'
[email protected]')])
• pop(key): Removes the key-value pair for the
specified key and returns the value.
my_dict = {
"name": "Uttam",
"age": 25,
"email": "
[email protected]"
}
18 | P a g e
email = my_dict.pop("email")
print(email) # Output: [email protected]
print(my_dict) # Output: {'name': 'Uttam', 'age': 26}
• update(): Updates the dictionary with key-value
pairs from another dictionary or iterable.
my_dict = {
"name": "Uttam",
"age": 25,
"location": "New York"
}
my_dict.update({"location": "New York", "phone":
"1234567890"})
print(my_dict)
# Output: {'name': 'Uttam', 'age': 26, 'location': 'New York',
'phone': '1111111111'}
Iterating Over a Dictionary: You can iterate over a
dictionary's keys, values, or both.
# Iterating over keys
for key in my_dict:
print(key)
# Output:
# name
# age
# location
19 | P a g e
# phone
# Iterating over values
for value in my_dict.values():
print(value)
# Output:
# Uttam
# 26
# New York
# 1111111111
# Iterating over key-value pairs
for key, value in my_dict.items():
print(f"{key}: {value}")
# Output:
# name: Uttam
# age: 26
# location: New York
# phone: 111111111
Nested Dictionaries: Dictionaries can contain other
dictionaries, which is useful for storing complex
data structures.
20 | P a g e
# A dictionary of dictionaries
students = {
"student1": {"name": "Uttam", "age": 25},
"student2": {"name": "Bob", "age": 22}
}
print(students["student1"]["name"]) # Output: Uttam
Module -
A module in Python is a file containing
Python definitions and statements, such
as functions, variables, classes, and other
code. Modules allow you to organize code
into manageable chunks, making it easier
to maintain and reuse across multiple
programs.
Modules can be either:
• Built-in (provided by Python standard library)
• User-defined (created by the user)
21 | P a g e
Creating a Module: To create a module, you simply
write Python code in a file and save it with the .py
extension.
For example, let's create a module named
my_module.py.
# my_module.py
def greet(name):
return f"Hello, {name}!"
def add(a, b):
return a + b
Importing Module: To use a module, you need to
import it into your program.
There are different ways to import a module in
Python.
1. Importing the Entire Module: You can import the
whole module using the import statement.
import my_module
# Using functions from the module
print(my_module.greet("Uttam")) # Output: Hello, Uttam!
print(my_module.add(5, 3)) # Output: 8
22 | P a g e
2. Importing Specific Functions or Variables: If you
want to import only specific functions or variables
from a module, use the “from” keyword.
from my_module import greet, add
print(greet("Bob")) # Output: Hello, Bob!
print(add(10, 20)) # Output: 30
3. Importing with an Alias: You can give the module a
custom name (alias) using the “as” keyword.
import my_module as mod
print(mod.greet("Charlie")) # Output: Hello, Charlie!
print(mod.add(7, 8)) # Output: 15
Built-in Python Modules: Python comes with a rich
standard library of built-in modules that you can
use without installing anything extra.
Some popular built-in modules include:
• math: Provides mathematical functions like square
root, sine, cosine, etc.
• random: Provides functions to generate random
numbers.
23 | P a g e
• datetime: Provides functions to manipulate dates
and times.
• os: Provides functions to interact with the operating
system.
math Module: The math module provides access
to mathematical functions defined by the C
standard. It includes a wide range of mathematical
operations, including trigonometry, logarithms,
and constants like π and e.
• Constants:
➔ math.pi: The value of PI (3.14159).
➔ math.e: Eular’s number (2.71828).
• Functions:
➔ math.sqrt(x): Square root of x.
➔ math.pow(x, y): x raised to the power y.
➔ math.log(x, base): Logarithm of x with specified
base.
➔ math.sin(x),math.cos(x),math.tan(x):
Trigonometric functions.
➔ math.factorial(x): Factorial of x.
➔ math.ceil(x),math.floor(x):Rounding functions.
24 | P a g e
random Module: The random module provides
functions to generate random numbers and
perform random operations such as shuffling or
selecting random elements from a list.
• Random Number Generation:
➔ random.random(): Random float between 0.0
and 1.0.
➔ random.randint(a,b): Random integer between
a and b.
➔ random.uniform(a,b): Random float between a
and b.
• Random Data Manipulation:
➔ random.choice(seq): Random element from a
sequence.
➔ random.sample(seq, k): Random sample of k
elements from a sequence.
➔ random.shuffle(seq): Shuffle a list in place.
Package: A package is a collection of modules
organized in directories.
To create a package, you need to:
1. Create a folder with a name (e.g., my_package).
25 | P a g e
2. Inside this folder, place an empty file named
__init__.py. This file tells Python that this directory
should be treated as a package.
3. Add your module files inside this folder.
For example, you can have the following structure:
my_package/
__init__.py
math_operations.py
string_operations.py
Using a Package: You can now import modules
from the package.
# Importing a module from the package
from my_package import math_operations
print(math_operations.add(5, 10))
Composition And The Distribution Utility -
In Python, composition refers to building
complex objects or systems by combining
26 | P a g e
simpler objects or components, typically
involving classes and modules. On the
other hand, distribution utilities allow
packaging and distributing your Python
code, modules, or libraries so that they
can be easily installed and reused by
others.
1. Composition: Composition in Python refers to
the concept of combining different objects or
components to form more complex systems. It
is a way of designing object-oriented programs
where one class contains an instance of
another class, enabling you to build
functionality by reusing code from other
classes.
This is often referred to as a "has-a"
relationship, meaning an object of one class
has an instance of another class.
Example:
class Engine:
def __init__(self, horsepower):
27 | P a g e
self.horsepower = horsepower
def start(self):
print(f"Engine with {self.horsepower} HP is starting.")
class Car:
def __init__(self, model, engine):
self.model = model
self.engine = engine # Composition: Car has an engine
def drive(self):
print(f"Driving {self.model}")
self.engine.start()
# Creating instances
engine = Engine(150)
car = Car("Toyota", engine)
# Using the composed object
car.drive()
2. Distribution Utility (Distutils): The distribution
utility, or Distutils, in Python provides the
functionality to package and distribute Python
code. Distutils allows you to share your Python
libraries and applications with others, making
it easy to install, distribute, and manage
dependencies.
28 | P a g e