Python Fullstack Visvodaya
Python Fullstack Visvodaya
introduction to python
Python is a high-level, interpreted, and general-purpose programming language known for its
simplicity, readability, and broad applicability. Created by Guido van Rossum and first released
in 1991, Python emphasizes code readability and allows developers to express concepts in fewer
lines of code compared to other programming languages like Java or C++.
Advantages of Python
Applications of Python
Python is a high-level, open-source programming language created by Guido van Rossum in the
late 1980s. Officially released in 1991, Python was designed to be simple, readable, and
powerful, drawing inspiration from the ABC language and influenced by Modula-3, C, and Unix
shell scripting. It has evolved into one of the most widely used languages across various domains
including web development, data science, automation, and artificial intelligence.
3 of 107
3.10 2021 Structural pattern matching
3.11 2022 Major performance boost
3.12+ 2023+ Further speed, typing, and internal updates
4. Conclusion
Python has grown from a simple scripting language into a robust, multi-paradigm language
embraced across industries. The transition from Python 2 to Python 3 marked a major shift in
design philosophy, making Python future-ready and developer-friendly. With continuous updates
and community-driven development, Python remains a top choice for modern full stack
development.
Python is known for its simplicity, versatility, and wide adoption in various fields like web
development, data science, artificial intelligence, automation, and more. Its features are designed
to enhance developer productivity and code maintainability.
• Python has a clean and readable syntax that mimics natural language.
• It reduces the learning curve for beginners and increases development speed for
experienced programmers.
• Example:
print("Hello, World!")
2. Interpreted Language
3. Dynamically Typed
x = 10 # Integer
x = "Hi" # Now a String
4 of 107
4. Object-Oriented Programming (OOP)
class Car:
def __init__(self, brand):
self.brand = brand
import math
print(math.sqrt(16)) # Outputs: 4.0
6. Cross-Platform Compatibility
• Python is platform-independent and can run on Windows, macOS, Linux, and more
without code modification.
• It enhances portability for developers building cross-platform applications.
8. High-Level Language
• Python handles memory management, garbage collection, and other low-level tasks,
allowing developers to focus on solving problems rather than managing system-level
details.
5 of 107
10. Rich Third-Party Ecosystem
• Python has a vast ecosystem of third-party libraries and frameworks for web (Django,
Flask), data science (NumPy, pandas), automation (Selenium), and machine learning
(TensorFlow, scikit-learn).
• Python supports:
o Procedural programming
o Object-oriented programming
o Functional programming (using lambda, map, filter, etc.)
Conclusion
Python’s feature set makes it a powerful and flexible tool for building modern software
solutions. Its simplicity, combined with robust capabilities, makes it the preferred language for
developers across industries.
🔹 1. Download Python
6 of 107
🔹 2. Install Python
Windows:
bash
python --version
macOS:
bash
python3 --version
Linux (Debian/Ubuntu-based):
bash
sudo apt update
sudo apt install python3
2. Verify:
bash
python3 --version
7 of 107
• Verify installation:
bash
pip --version
Recommended editors:
print("Hello, Python!")
bash
python hello.py
Python Identifiers
Identifiers in Python are the names used to identify variables, functions,
classes, modules, and other objects. They are fundamental elements in Python
programming, allowing developers to reference data and operations.
1. Can contain:
a. Letters (A–Z, a–z)
b. Digits (0–9)
c. Underscore (_)
2. Must begin with:
8 of 107
a. A letter or an underscore (_)
b. Cannot begin with a digit
3. Case-sensitive:
a. Name, name, and NAME are all different identifiers
4. Cannot be a keyword:
a. Reserved words like class, if, return, etc., cannot be used as identifiers
Valid Invalid
user_name 2username
_temp user-name
Age class (keyword)
1. Numeric Types
2. Sequence Types
3. Set Types
4. Mapping Type
5. Boolean Type
6. Binary Types
10 of 107
Python Comments
Comments in Python are non-executable lines in the code that help explain what the code does.
They are ignored by the Python interpreter and serve only for documentation and clarity.
1. Single-line Comments
Example:
python
# This is a single-line comment
name = "Alice" # Assigning value to variable
• Python does not have a native multi-line comment syntax like some other languages.
• However, you can use a series of # symbols, or a multi-line string (triple quotes) as a
workaround.
Using multiple #:
python
# This is a multi-line
# comment using multiple
# hash symbols
python
"""
This is a multi-line string
used as a comment. Technically,
it's a string not assigned to a variable.
"""
11 of 107
Note: Triple-quoted strings are often used as docstrings when placed at the beginning of
functions, classes, or modules.
Operators in Python
Operators in Python are special symbols or keywords used to perform operations on variables
and values. Python supports a wide variety of operators, categorized by the type of operation
they perform.
🔹 1. Arithmetic Operators
12 of 107
Used to compare the values
🔹 3. Logical Operators
🔹 4. Assignment Operators
🔹 5. Bitwise Operators
13 of 107
>> Right shift 5 >> 1 2
🔹 6. Identity Operators
🔹 7. Membership Operators
Python Keywords
Keywords are reserved words in Python that have special meaning and cannot be used as
identifiers (like variable names, function names, etc.). They form the syntax and structure of
Python programs.
Python keywords are case-sensitive and are always written in lowercase, except for True,
False, and None.
🔹 Purpose of Keywords
14 of 107
🔹 List of Python Keywords (Python 3.10+)
Use help("keywords") or keyword.kwlist in the Python interpreter to view the current list of
keywords.
🔹 Examples
python
if True:
print("Condition is True") # 'if' and 'True' are keywords
def greet():
pass # 'def' and 'pass' are keywords
🔹 Best Practices
15 of 107
Understanding precedence is crucial for writing accurate and predictable code, especially in
complex expressions.
Precedence
Operator(s) Description
Level
1 () Parentheses (expression grouping)
2 ** Exponentiation
3 +x, -x, ~x Unary plus, minus, bitwise NOT
Multiplication, division, floor division,
4 *, /, //, %
modulus
5 +, - Addition and subtraction
6 <<, >> Bitwise shift operators
7 & Bitwise AND
8 ^ Bitwise XOR
9 ` `
==, !=, >, <, >=, <=, is, is not, in, not
10 Comparison and membership operators
in
11 not Logical NOT
12 and Logical AND
13 or Logical OR
14 if – else Conditional expressions
15 lambda Lambda function expression
16 =, +=, -=, etc. Assignment operators
🔹 Example:
python
CopyEdit
result = 3 + 4 * 2 ** 2
# Evaluation order:
# 2 ** 2 = 4
# 4 * 4 = 16
# 3 + 16 = 19
16 of 107
python
result = (3 + 4) * 2 ** 2 # (3 + 4) = 7, 7 * 4 = 28
Best Practices
In implicit conversion, Python automatically converts one data type to another without user
intervention. This usually happens when a smaller data type is promoted to a larger one to avoid
data loss.
Example:
python
x = 10 # Integer
y = 3.5 # Float
result = x + y
print(result) # 13.5
print(type(result)) # <class 'float'>
17 of 107
🔹 2. Explicit Type Conversion (Type Casting)
In explicit conversion, the programmer manually converts one data type to another using built-
in functions.
python
a = "123"
b = int(a) # Convert string to integer
print(b + 1) # Output: 124
Best Practices
18 of 107
🔹 1. Output in Python
Syntax:
Examples:
🔸 Multiple arguments:
python
x = 10
y = 20
print("Sum of", x, "and", y, "is", x + y)
🔹 2. Input in Python
Syntax:
python
variable = input("Prompt message")
Example:
python
name = input("Enter your name: ")
print("Welcome,", name)
📌 Note: input() always returns data as a string, so explicit type conversion may be needed for
numbers.
19 of 107
age = int(input("Enter your age: "))
print("You will be", age + 1, "next year.")
python
name = "Alice"
score = 95.5
print(f"{name} scored {score:.2f} marks.")
🔸 format() method:
python
print("Hello, {}!".format("Bob"))
Best Practices
python
num = 100
print(num) # 100 (Decimal)
python
CopyEdit
bin_num = 0b1010
print(bin_num) # 10 (in Decimal)
python
oct_num = 0o12
print(oct_num) # 10 (in Decimal)
python
hex_num = 0xA
print(hex_num) # 10 (in Decimal)
21 of 107
Decimal → Octal oct(x) oct(10) → '0o12'
Decimal → Hexadecimal hex(x) hex(10) → '0xa'
Binary → Decimal int('0b1010', 2) → 10
Octal → Decimal int('0o12', 8) → 10
Hexadecimal → Decimal int('0xa', 16) → 10
print(bin(x)) # '0b1010'
print(oct(x)) # '0o12'
print(hex(x)) # '0xa'
Controll Statements
22 of 107
Control statements in Python are used to direct the flow of execution in a program. They allow
the program to make decisions, repeat operations, and jump between different parts of code
based on specific conditions.
These statements control the order in which instructions are executed, enabling dynamic,
flexible, and intelligent behavior in Python programs.
• if Statement
• if-else Statement
• if-elif-else Ladder
• Nested if
23 of 107
Example:
python
x = 10
if x > 0:
print("Positive number")
elif x == 0:
print("Zero")
else:
print("Negative number")
python
for i in range(5):
print(i)
python
count = 0
while count < 5:
print(count)
count += 1
24 of 107
3. Jumping Statements (Flow Control Within Loops)
Used to alter the normal flow of loops and other code blocks.
Example:
for i in range(5):
if i == 3:
break
print(i)
Summary Table
Type Statements Purpose
Conditional if, if-else, if-elif-else Make decisions based on conditions
Looping for, while Repeat a block of code
Jumping break, continue, pass Control loop execution flow
Strings
What is a String in Python?
Examples:
python
str1 = 'Hello'
str2 = "World"
str3 = '''Python is fun'''
25 of 107
Creating Strings
# Single-line string
name = "Alice"
String Slicing
Python code:
text = "Programming"
print(text[0:6]) # Output: Progra
print(text[3:]) # Output: gramming
print(text[:4]) # Output: Prog
26 of 107
replace(old, "java".replace("j", "p") →
Replaces a substring with another
new) 'pava'
find(sub) Returns the index of first occurrence "code".find("d") → 2
count(sub) Counts occurrences of a substring "banana".count("a") → 3
startswith(s Checks if the string starts with a specific "hello".startswith("he") →
ub) substring True
endswith(sub Checks if the string ends with a specific "python".endswith("on") →
) substring True
split(delimi "a,b,c".split(",") → ['a',
Splits a string into a list
ter) 'b', 'c']
join(list) Joins elements of a list into a string ",".join(['a', 'b']) → 'a,b'
Python code:
name = "Alice"
age = 25
print(f"My name is {name} and I am {age} years old.")
python
print("My name is {} and I am {} years old.".format("Alice",
25))
Immutability of Strings
python
text = "hello"
# text[0] = "H" # Error! Strings are immutable
text = "Hello" # Reassigning is allowed
27 of 107
📚 Lists in Python – Complete Concept
🔷 1. Definition
A List in Python is an ordered, mutable, and indexed collection used to store multiple
items in a single variable. Lists allow heterogeneous elements and duplicate values.
A List is a built-in data type in Python used to store multiple values in a single variable.
It is:
0 1 2 3 4
List= [ 10 20 30 40 50 ]
-5 -4 -3 -2 -1
🔹 2. Creating a List
Python code
# Empty list
a = []
# List of numbers
nums = [1, 2, 3, 4]
# Mixed data types
info = ["Nasir", 21, True]
# Nested list
nested = [1, [2, 3], 4]
28 of 107
🔹 3. Accessing Elements
print(my_list[0]) # 'a'
print(my_list[-1]) # 'd' (last)
print(my_list[1:3]) # ['b', 'c'] (slicing)
🔹 4. Modifying Elements
🔹 5. Deleting Elements
python
del my_list[2] # Delete by index
my_list.remove('z') # Delete by value
popped = my_list.pop(0) # Remove and return item
my_list.clear() # Remove all items
Method Description
append(x) Add item to end
insert(i, x) Insert at index
extend(iter) Add multiple elements
remove(x) Remove first matching value
pop(i) Remove by index and return it
clear() Remove all elements
index(x) Return first index of value
count(x) Count how many times a value appears
sort() Sort in ascending order
reverse() Reverse list in-place
copy() Return a shallow copy
29 of 107
Python code:
nums = [3, 1, 4]
nums.append(2)
nums.sort()
print(nums) # [1, 2, 3, 4]
🔹 7. List Operations
Python code:
for item in ["a", "b", "c"]:
print(item)
Python code
squares = [x**2 for x in range(5)]
# [0, 1, 4, 9, 16]
With condition:
Python code
even = [x for x in range(10) if x % 2 == 0]
# [0, 2, 4, 6, 8]
Python code
30 of 107
matrix = [
[1, 2, 3],
[4, 5, 6]
]
print(matrix[1][2]) # 6
Feature Value
Ordered Yes
Indexed Yes
Mutable Yes
Allows Duplicates Yes
Heterogeneous Yes
Nesting Allowed Yes
🔹 1. append(x)
python
31 of 107
fruits = ["apple", "banana"]
fruits.append("cherry")
print(fruits) # ['apple', 'banana', 'cherry']
🔹 2. insert(i, x)
Description: Inserts an element x at a specified index i. All elements after index i shift
right.
python
fruits = ["apple", "banana"]
fruits.insert(1, "cherry")
print(fruits) # ['apple', 'cherry', 'banana']
🔹 3. extend(iter)
Description: Extends the list by appending elements from an iterable (e.g., list, tuple).
Python code
fruits = ["apple", "banana"]
fruits.extend(["cherry", "date"])
print(fruits) # ['apple', 'banana', 'cherry', 'date']
🔹 4. remove(x)
Description: Removes the first occurrence of x from the list. Raises a ValueError if x is
not in the list.
python
fruits = ["apple", "banana", "cherry"]
fruits.remove("banana")
print(fruits) # ['apple', 'cherry']
🔹 5. pop(i)
Description: Removes and returns the item at the given index i. If no index is provided,
removes and returns the last item. Raises an IndexError if the list is empty.
python
32 of 107
fruits = ["apple", "banana", "cherry"]
item = fruits.pop(1)
print(item) # 'banana'
print(fruits) # ['apple', 'cherry']
🔹 6. clear()
python
fruits = ["apple", "banana", "cherry"]
fruits.clear()
print(fruits) # []
🔹 7. index(x)
Description: Returns the index of the first occurrence of x in the list. Raises a ValueError
if x is not in the list.
python
fruits = ["apple", "banana", "cherry"]
index = fruits.index("banana")
print(index) # 1
🔹 8. count(x)
python
fruits = ["apple", "banana", "cherry", "apple"]
count = fruits.count("apple")
print(count) # 2
🔹 9. sort()
Description: Sorts the list in ascending order (in-place). To sort in descending order, use
reverse=True.
33 of 107
python
numbers = [4, 2, 8, 6]
numbers.sort()
print(numbers) # [2, 4, 6, 8]
🔹 10. reverse()
python
fruits = ["apple", "banana", "cherry"]
fruits.reverse()
print(fruits) # ['cherry', 'banana', 'apple']
🔹 11. copy()
python
fruits = ["apple", "banana", "cherry"]
new_fruits = fruits.copy()
print(new_fruits) # ['apple', 'banana', 'cherry']
Description: While not a direct method on lists, you can join a list of strings into a single
string using the join() method from the str class.
python
words = ["Hello", "World"]
sentence = " ".join(words)
print(sentence) # 'Hello World'
34 of 107
🔹 13. list() Constructor
python
CopyEdit
tuple_data = (1, 2, 3)
list_data = list(tuple_data)
print(list_data) # [1, 2, 3]
Description: Performs a deep copy of a list, where nested objects are copied as well.
python
import copy
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[0][0] = 9
print(original) # [[1, 2], [3, 4]]
print(deep_copy) # [[9, 2], [3, 4]]
Description: A concise way to create lists based on existing lists, with optional conditions.
python
CopyEdit
# Basic example
squares = [x**2 for x in range(5)]
print(squares) # [0, 1, 4, 9, 16]
# With condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # [0, 4, 16, 36, 64]
35 of 107
🔹 16. Summary Table of List Methods
36 of 107
Python List Operations
🔹 1. Indexing
Description: Lists are ordered, meaning each element has an index. You can access
elements by using indices.
Python code
fruits = ["apple", "banana", "cherry"]
print(fruits[1]) # 'banana'
print(fruits[-1]) # 'cherry'
🔹 2. Slicing
python
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[1:3]) # ['banana', 'cherry']
print(fruits[:2]) # ['apple', 'banana']
print(fruits[2:]) # ['cherry', 'date']
🔹 3. Concatenation (+)
Description: Combine two lists using the + operator to form a new list.
python
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = list1 + list2
print(result) # [1, 2, 3, 4, 5, 6]
37 of 107
🔹 4. Repetition (*)
python
fruits = ["apple", "banana"]
print(fruits * 2) # ['apple', 'banana', 'apple', 'banana']
python
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("date" not in fruits) # True
🔹 6. Length (len())
python
fruits = ["apple", "banana", "cherry"]
print(len(fruits)) # 3
Description: Get the smallest and largest element in a list (works with numeric lists).
python
numbers = [1, 2, 3, 4, 5]
print(min(numbers)) # 1
print(max(numbers)) # 5
🔹 8. Sum (sum())
Description: Return the sum of elements in a list (works with numeric lists).
38 of 107
python
numbers = [1, 2, 3, 4]
print(sum(numbers)) # 10
python
numbers = [5, 2, 9, 1]
numbers.sort()
print(numbers) # [1, 2, 5, 9]
python
fruits = ["apple", "banana", "cherry"]
fruits.reverse()
print(fruits) # ['cherry', 'banana', 'apple']
Description:
python
fruits = ["apple", "banana", "cherry"]
new_fruits = fruits.copy() # or new_fruits = list(fruits)
39 of 107
new_fruits.append("date")
print(fruits) # ['apple', 'banana', 'cherry']
print(new_fruits) # ['apple', 'banana', 'cherry', 'date']
python
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares) # [1, 4, 9, 16, 25]
python
names = ["John", "Jane", "Jack"]
ages = [25, 30, 35]
zipped = zip(names, ages)
print(list(zipped)) # [('John', 25), ('Jane', 30), ('Jack', 35)]
Description: Lists can contain other lists as elements (nested lists). You can perform
operations on nested lists like accessing, modifying, and iterating through them.
python
nested_list = [[1, 2], [3, 4], [5, 6]]
print(nested_list[1][0]) # 3
nested_list[0][1] = 8
print(nested_list) # [[1, 8], [3, 4], [5, 6]]
40 of 107
🔹 15. Example Use Case: List Operations
python
# List with initial elements
fruits = ["apple", "banana", "cherry"]
# Add elements
fruits.append("date")
fruits.insert(1, "orange")
# Remove an element
fruits.remove("banana")
# Final result
print(all_fruits) # ['date', 'cherry', 'orange', 'apple', 'fig',
'grape', 'fig', 'grape']
41 of 107
Sorting (sort()) Sort list in ascending order fruits.sort()
Reversing
Reverse the order of the list fruits.reverse()
(reverse())
new_fruits =
Copying (copy()) Get a shallow copy of the list
fruits.copy()
Create a new list from an existing
Comprehension [x*2 for x in list]
list
Zipping Combine multiple lists into tuples zip(list1, list2)
Lists inside lists (multidimensional
Nested Lists nested[1][0]
lists)
Tuples in Python
What is a Tuple?
Ex:
t1 = (1, 2, 3)
t2 = ("apple", "banana", "cherry")
t3 = (1, "hello", 3.5)
t4 = () # Empty tuple
t5 = (5,) # Single-element tuple (comma is necessary)
42 of 107
Accessing Tuple Elements:
Tuple Operations:
Operation Description Example
Accessing specific
Indexing t[1] → Returns second element
elements
Extracting a range of t[1:3] → Returns elements at index 1
Slicing
elements and 2
Concatena
Combining two tuples t1 + t2
tion
Repetition Repeating tuple elements t * 3
Membershi Checking if an element
'apple' in t
p exists
Iteration Looping through elements for i in t: print(i)
Function /
Description Example
Method
len(tuple) Returns number of items in the tuple len(t)
Returns the maximum value (numeric or max((4, 1, 9)) →
max(tuple)
alphabetic) 9
min((4, 1, 9)) →
min(tuple) Returns the minimum value
1
sum((1, 2, 3)) →
sum(tuple) Returns the sum of all numeric elements
6
tuple([1, 2]) →
tuple(seq) Converts a sequence (like list) into a tuple
(1, 2)
count(x) Returns the number of times x appears t.count(2)
index(x) Returns the index of the first occurrence of x t.index("apple")
43 of 107
Immutability in Practice:
t = (10, 20, 30)
# t[1] = 50 # Error: Tuples are immutable
Packing:
Unpacking:
a, b, c = t
print(a) # 1
print(b) # hello
Dictionaries in Python
What is a Dictionary?
44 of 107
Creating a Dictionary:
• get() method is preferred as it returns None if the key is not found instead of
raising an error.
Deleting Elements:
Dictionary Methods:
45 of 107
new_dict =
copy() Returns a shallow copy of the dictionary
student.copy()
setdefau Returns value if key exists, else inserts key with student.setdefault("grad
lt() default e", "B")
# OR using items()
for key, value in student.items():
print(key, "=>", value)
Dictionary Comprehension:
Nested Dictionaries:
students = {
"S1": {"name": "Alice", "age": 21},
"S2": {"name": "Bob", "age": 22}
}
Accessing nested data:
Conclusion
Dictionaries in Python are ideal for storing structured, key-based data efficiently. Their
fast access time, dynamic nature, and rich set of built-in methods make them
46 of 107
indispensable for data manipulation, configuration management, and backend logic in full
stack development.
Set
Creating Sets:
Accessing Elements:
Ex:
for item in my_set:
print(item)
Modifying Sets:
Removing Elements:
my_set.remove(3) # Removes element; raises KeyError if
not found
47 of 107
my_set.discard(10) # Removes element; does nothing if not
found
my_set.pop() # Removes and returns a random item
my_set.clear() # Removes all elements from the set
Set Operations:
Set Example:
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
Frozen Sets
A frozenset is an immutable version of a set. Once created, it cannot be modified (no add
or remove).
fs = frozenset([1, 2, 3])
48 of 107
Useful when you need a set to be used as a dictionary key or need it to remain unchanged.
Conclusion
Sets are a powerful data structure in Python for handling unique elements and
performing mathematical operations. Their high-performance membership testing and
flexible methods make them essential for data cleaning, analytics, and backend logic in
full stack development.
Functions in Python
What is a Function?
A function in Python is a block of reusable code that performs a specific task. Functions
help in organizing code into modular, readable, and maintainable components.
def function_name(parameters):
# function body
return value # optional
Example:
def greet(name):
return f"Hello, {name}!"
49 of 107
Function Arguments in Python:
Type Description Example
Positional Arguments Passed in correct position/order greet("John")
greet(name="John"
Keyword Arguments Passed with key=value format
)
def
Default Arguments Provide default values for parameters greet(name="Guest
")
Variable-length Allows passing multiple values as tuple
*args, **kwargs
Arguments or dict
Example of all:
50 of 107
square = lambda x: x ** 2
print(square(5)) # Output: 25
Return Statement:
Function Scope:
Conclusion
Functions are fundamental to writing clean, reusable, and efficient code in Python. By
mastering function definitions, arguments, and types, developers can build scalable and
maintainable applications in full stack development.
A lambda function is a small, anonymous (unnamed) function defined using the lambda
keyword in Python. It can take any number of arguments but can have only one
expression.
Syntax:
Example:
square = lambda x: x * x
print(square(5)) # Output: 25
51 of 107
Use Cases of Lambda Functions:
nums = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, nums))
print(squares) # Output: [1, 4, 9, 16]
Key Points:
Conclusion:
Lambda functions offer a concise way to create throwaway or inline functions. They are
especially useful for functional programming patterns and scenarios where a full function
definition would be unnecessary.
Recursion
52 of 107
Example: Factorial using Recursion
def factorial(n):
if n == 0:
return 1 # Base case
else:
return n * factorial(n - 1) # Recursive case
Key Points:
Conclusion:
53 of 107
1. Accept another function as an argument
2. Return a function as a result
Functi
Description Example
on
map(lambda x: x*2, [1, 2,
map() Applies a function to all items in an iterable
3])
filte filter(lambda x: x > 2,
Filters items based on a condition (function)
r() [1, 2, 3])
reduc Applies a rolling computation to items (from reduce(lambda x, y: x+y,
e() functools) [1, 2, 3])
nums = [1, 2, 3]
doubled = list(map(lambda x: x * 2, nums))
print(doubled) # Output: [2, 4, 6]
greet = outer_function("Hello")
greet() # Output: Message: Hello
Conclusion:
54 of 107
What is a Module in Python?
A module is a file containing Python code (functions, classes, variables) that can be
imported and reused in other Python programs. Modules help in organizing code into
manageable, reusable, and logical units.
Types of Modules:
Importing Modules:
import math
print(math.sqrt(16)) # Output: 4.0
# mymodule.py
def greet(name):
55 of 107
return f"Hello, {name}!"
import mymodule
print(mymodule.greet("Alice")) # Output: Hello, Alice!
import math
print(dir(math)) # Lists all functions and variables in the module
Module Purpose
math Mathematical functions
random Random number generation
datetim
Date and time manipulation
e
os Interacting with the operating system
System-specific parameters and
sys
functions
Third-party Modules:
Example usage:
import requests
response = requests.get("https://api.github.com")
print(response.status_code)
56 of 107
Conclusion:
Modules are essential for organizing, reusing, and scaling code in Python applications.
Whether using built-in libraries or third-party tools, modules enable efficient and
structured full stack development.
Exception
An exception is an error that occurs during the execution of a program, disrupting its
normal flow. Python provides a way to gracefully handle exceptions using built-in
exception handling mechanisms to prevent program crashes.
Common Exceptions:
ptry:
# Code that may raise an exception
result = 10 / 0
except ZeroDivisionError:
# Code that runs if an exception occurs
print("You cannot divide by zero!")
finally:
# Code that always runs
print("Execution completed.")
Keyword Purpose
57 of 107
Wraps the code block that might raise an
try
exception
except Handles the exception if it occurs
else Runs if no exceptions occur
finally Executes code regardless of exception
raise Manually raise a specific exception
try:
num = int(input("Enter a number: "))
print(10 / num)
except ValueError:
print("Please enter a valid number.")
except ZeroDivisionError:
print("Cannot divide by zero.")
else:
print("No errors occurred.")
finally:
print("Program ended.")
58 of 107
Object-Oriented Programming (OOP) in Python
• Class and Object: A class defines the structure and behavior, while an object is an
instance of a class.
• Encapsulation: Bundling data and methods within a class to restrict direct access
to internal variables.
• Inheritance: Allows one class to inherit attributes and methods from another,
promoting code reuse.
• Polymorphism: Enables methods to behave differently based on the object calling
them.
• Abstraction: Hides complex implementation details and exposes only the
necessary parts of an object.
Python's OOP features make it suitable for building scalable and maintainable
applications, especially in full-stack development.
Classes in Python
A class in Python is a user-defined blueprint or prototype for creating objects. Classes
encapsulate data (attributes) and functions (methods) that operate on that data. They allow code
to be organized in a clean, modular way, promoting reusability and scalability.
Syntax of a Class
class ClassName:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def method_name(self):
# perform some operation
59 of 107
pass
Key Components
1. class Keyword
Used to define a class.
class Person:
pass
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
3. Attributes
These are variables that belong to the object and hold data about the object.
p = Person("Nasir", 24)
print(p.name) # Output: Nasir
4. Methods
Functions defined inside a class that perform operations using the object’s data.
class Person:
def greet(self):
return f"Hello, my name is {self.name}"
5. self Keyword
Refers to the current instance of the class. It is used to access attributes and methods
within the class.
60 of 107
Example
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def full_name(self):
return f"{self.brand} {self.model}"
Objects in Python
An object is a concrete instance of a class. It holds actual data and can invoke methods defined
in the class. While the class is just a blueprint, an object is the real-world implementation of that
blueprint.
What is an Object?
In simple terms, if a class is a template, then an object is a real product created using that
template. Each object contains its own data and can perform actions using the methods defined in
its class.
Creating an Object
You create an object by calling the class as if it were a function. This triggers the class’s
__init__() constructor method.
61 of 107
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Creating an object
p1 = Person("Nasir", 24)
Once an object is created, you can access its attributes and methods using dot (.) notation.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, I’m {self.name} and I’m {self.age} years old."
p1 = Person("Nasir", 24)
print(p1.greet()) # Output: Hello, I’m Nasir and I’m 24 years
old.
You can create as many objects as you want from the same class. Each object will have its own
separate data.
python
CopyEdit
62 of 107
p2 = Person("Ayesha", 22)
print(p2.greet()) # Output: Hello, I’m Ayesha and I’m 22 years
old.
Characteristics of Objects
Summary
• Objects are the actual entities that interact with your code.
• They are created from classes and can store data and call methods.
• They bring the structure of a class to life by providing real data and behavior.
Methods in Python
A method is a function defined inside a class that operates on the data (attributes) of the class
and performs specific actions. Methods are used to define the behaviors of an object.
While functions are independent blocks of reusable code, methods are tied to objects—they
require an object to be called and usually work with that object's internal state.
Defining a Method
You define a method just like a normal function, but inside a class, and it must take self as its
first parameter.
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}"
Here, greet() is a method. It belongs to the Person class and uses the object’s attribute name.
63 of 107
Calling a Method
python
CopyEdit
p1 = Person("Nasir")
print(p1.greet()) # Output: Hello, my name is Nasir
Types of Methods
1. Instance Methods
These are the most common type. They use self to access instance-specific data.
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
2. Class Methods
These affect the class as a whole, not just a single instance. They use cls as the first
parameter and are marked with the @classmethod decorator.
class Student:
school_name = "Greenwood High"
@classmethod
def get_school(cls):
return cls.school_name
64 of 107
3. Static Methods
These don’t depend on self or cls. They behave like regular functions but are kept
inside the class for logical grouping. Marked with the @staticmethod decorator.
class MathUtils:
@staticmethod
def add(x, y):
return x + y
Summary
Inheritance in Python
Inheritance is a fundamental feature of object-oriented programming that allows one class
(called the child or derived class) to inherit the attributes and methods of another class (called
the parent or base class). It promotes code reuse, modularity, and extensibility.
Basic Syntax
class Parent:
def speak(self):
print("Speaking from Parent")
class Child(Parent):
def walk(self):
print("Walking from Child")
65 of 107
c = Child()
c.speak() # Inherited from Parent
c.walk() # Defined in Child
The Child class inherits the speak() method from Parent without having to define it again.
This is the power of inheritance.
The super() function is used inside a child class to call methods or constructors from the
parent class.
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, grade):
super().__init__(name)
self.grade = grade
Here, super().__init__(name) calls the parent constructor so we don’t have to repeat the
initialization logic.
Types of Inheritance
1. Single Inheritance
One child class inherits from one parent class.
class Animal:
pass
class Dog(Animal):
66 of 107
pass
2. Multiple Inheritance
A child class inherits from more than one parent class.
class Father:
pass
class Mother:
pass
3. Multilevel Inheritance
A class inherits from a child class which in turn inherits from another parent class.
class Grandparent:
pass
class Parent(Grandparent):
pass
class Child(Parent):
pass
4. Hierarchical Inheritance
Multiple child classes inherit from the same parent class.
class Vehicle:
pass
class Car(Vehicle):
pass
class Bike(Vehicle):
pass
67 of 107
Overriding Methods
A child class can override a method from its parent by defining it with the same name.
class Parent:
def greet(self):
return "Hello from Parent"
class Child(Parent):
def greet(self):
return "Hello from Child"
c = Child()
print(c.greet()) # Output: Hello from Child
Summary
• Inheritance enables a new class to use existing code from another class.
• It fosters reusability, clarity, and hierarchical structure.
• super() is a key tool for maintaining the parent-child relationship.
• Supports different types: single, multiple, multilevel, hierarchical.
What Is Abstraction?
Abstraction is one of the four core principles of Object-Oriented Programming (OOP) — the
others being Encapsulation, Inheritance, and Polymorphism.
In programming, abstraction hides the internal logic and only exposes a user-friendly
interface that helps simplify complex systems.
68 of 107
Purpose of Abstraction
Why should you care about abstraction as a full stack developer?
Step-by-Step Example
from abc import ABC, abstractmethod
@abstractmethod
def start_engine(self):
pass
@abstractmethod
def stop_engine(self):
pass
Here, Vehicle is an abstract class. It cannot be instantiated directly because it contains abstract
methods.
69 of 107
This will throw an error:
class Car(Vehicle):
def start_engine(self):
print("Car engine started.")
def stop_engine(self):
print("Car engine stopped.")
my_car = Car()
my_car.start_engine() # Output: Car engine started.
my_car.stop_engine() # Output: Car engine stopped.
class PaymentMethod(ABC):
@abstractmethod
def pay(self, amount):
pass
class CreditCard(PaymentMethod):
def pay(self, amount):
print(f"Paid ₹{amount} using Credit Card.")
70 of 107
class UPI(PaymentMethod):
def pay(self, amount):
print(f"Paid ₹{amount} using UPI.")
class PayPal(PaymentMethod):
def pay(self, amount):
print(f"Paid ₹{amount} using PayPal.")
This allows you to enforce a consistent interface, even though the implementation differs.
71 of 107
You use .append() on a list, but don’t know how it works You restrict access to a class’s
Example
internally attributes
Summary
• Abstraction is about hiding complex logic and exposing only essential parts.
• Use Python’s abc module with ABC and @abstractmethod to implement it.
• Abstract classes define a contract; child classes must fulfill it.
• Abstraction makes systems clean, maintainable, and scalable.
What is Encapsulation?
Encapsulation is the process of binding data (variables) and methods (functions) that operate
on the data into a single unit—typically a class—and restricting direct access to some
components.
In simpler terms:
“Encapsulation is about hiding the internal state of an object and requiring all interactions to
be performed through well-defined interfaces.”
Just like:
Purpose of Encapsulation
Why encapsulate? Because it gives you:
72 of 107
Encapsulation in Python
Python is a flexible language, and while it doesn't enforce strict access control like Java or C++,
it still supports encapsulation using naming conventions and special syntax.
Public Members
class Student:
def __init__(self):
self.name = "Nasir"
s = Student()
print(s.name) # Output: Nasir
Everything is accessible. This is fine for simple data, but not ideal for sensitive information.
Protected Members
class Student:
def __init__(self):
self._marks = 85 # Protected (by convention)
s = Student()
print(s._marks) # Technically accessible, but discouraged
73 of 107
Use _ to indicate that the attribute shouldn't be accessed directly.
Private Members
class Student:
def __init__(self):
self.__grade = "A" # Private
s = Student()
# print(s.__grade) # Error: Attribute not accessible
But Python internally uses name mangling, so the actual attribute is _Student__grade:
python
class BankAccount:
def __init__(self):
self.__balance = 0
def get_balance(self):
return self.__balance
You’re not allowed to touch __password directly. You must go through the
change_password() method.
75 of 107
Summary
• Encapsulation is about bundling data and methods together and restricting direct
access.
• Python uses naming conventions: _protected, __private.
• Use getter and setter methods to access private data safely.
• Encapsulation ensures data integrity, security, and cleaner code design.
What is Polymorphism
Polymorphism means "many shapes" in Greek, and in programming, it refers to the ability of
one interface to represent different underlying forms (data types). In simpler terms:
It’s like a chameleon, which changes color depending on its environment, but at its core, it’s still
a chameleon.
Purpose of Polymorphism
Why should you use polymorphism? Here’s why it’s a game-changer:
76 of 107
• Flexibility – Write code that works with any class object, as long as it adheres to the
required interface.
• Reusability – Use the same method for different classes, reducing redundancy.
• Maintainability – Add new classes and behaviors without changing existing code.
• Extensibility – Easily extend functionality by creating new classes that still fit into the
system.
• Method Overriding: A child class provides its own implementation of a method that is
already defined in its parent class.
• Duck Typing: Python’s philosophy: “If it looks like a duck and quacks like a duck, it is a
duck.” As long as an object implements the expected behavior, Python allows you to
interact with it, even if its class doesn’t explicitly match.
Let’s start with the more traditional approach to polymorphism: method overriding.
Parent Class:
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement abstract
method")
Child Classes:
class Dog(Animal):
def speak(self):
return "Bark"
class Cat(Animal):
def speak(self):
return "Meow"
class Cow(Animal):
def speak(self):
77 of 107
return "Moo"
Polymorphism in Action:
Here:
• The method speak() is overridden in each child class, allowing each animal to speak in
its own way.
• The same method name (speak()) works differently depending on which object it is
called on. This is polymorphism in action.
Python uses duck typing, which is a form of polymorphism that focuses on an object’s
behavior rather than its class.
class Bird:
def fly(self):
return "Flying high"
class Airplane:
def fly(self):
return "Flying at 30,000 feet"
Now, both Bird and Airplane have a fly() method. We can treat them interchangeably if
we care only about the method they implement, not their class type:
def lets_fly(flyable_thing):
print(flyable_thing.fly())
bird = Bird()
78 of 107
plane = Airplane()
This is duck typing: as long as an object implements the fly() method, we can use it,
regardless of its actual class.
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * (self.radius ** 2)
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
Now, you can write code that works for any shape:
79 of 107
print(shape.area()) # Output: 78.5, 16
Here, both Circle and Square classes have an area() method, but their implementations are
different. Thanks to polymorphism, we can use the same interface (area()) to compute areas
of different shapes without worrying about the class.
Summary
• Polymorphism allows objects to be treated as instances of their parent class, but they can
implement their own unique behavior.
• It is achieved in Python through method overriding and duck typing.
• Method overriding enables child classes to implement methods in their own way.
• Duck typing focuses on an object’s behavior, allowing for flexibility in working with
different types.
• Polymorphism promotes reusability, maintainability, and extensibility in your code.
80 of 107
Comparison: Polymorphism vs Inheritance
Aspect Polymorphism Inheritance
Allows different classes to
Purpos Allows one class to inherit attributes
implement the same method
e and methods from another class.
differently.
Focus Behavior (methods). Structure (attributes and methods).
Key
Class inheritance (parent-child
Mecha Method overriding, duck typing
relationship)
nism
Use When you want a common interface When you want to reuse code from a
Case for different classes. parent class.
What is NumPy?
NumPy stands for Numerical Python, and it’s an open-source library that enables you to
perform high-performance mathematical and numerical computations on large datasets. It adds
support for arrays, matrices, and a vast collection of mathematical functions to perform
operations on these arrays.
• Arrays: At the core of NumPy is the ndarray (n-dimensional array). It provides a way
to store and manipulate data in a more efficient and compact form compared to Python's
built-in lists.
• Vectorization: This is the process of performing operations on arrays element-wise
without using explicit loops, which results in significant speed gains.
81 of 107
1. ndarray (n-dimensional array)
The ndarray is the heart of NumPy. It’s a multidimensional container that holds a collection of
items, all of the same type, and is indexed by a tuple of non-negative integers. NumPy’s
ndarray is more efficient and faster than Python’s native list.
Example:
import numpy as np
# 1D array
arr = np.array([1, 2, 3, 4])
print(arr) # Output: [1 2 3 4]
# 2D array
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix)
2. Array Creation
Examples:
# Array of zeros
zero_arr = np.zeros((3, 3))
print(zero_arr)
# Array of ones
ones_arr = np.ones((2, 2))
82 of 107
print(ones_arr)
NumPy arrays can be indexed and sliced similar to Python lists, but with added flexibility and
powerful features like multi-dimensional indexing.
Examples:
# Indexing
arr = np.array([10, 20, 30, 40, 50])
print(arr[2]) # Output: 30
# Slicing
print(arr[1:4]) # Output: [20 30 40]
# 2D array slicing
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[0:2, 1:3]) # Output: [[2 3] [5 6]]
NumPy allows vectorized operations, which means you can apply mathematical operations to
entire arrays element-wise, without using loops.
Examples:
# Array addition
arr2 = np.array([5, 6, 7, 8])
83 of 107
print(arr + arr2) # Output: [6 8 10 12]
This is a major performance advantage over using Python lists, as NumPy operations are
executed in compiled code rather than Python’s slower interpreted code.
5. Mathematical Functions
NumPy provides a wide range of mathematical functions that can be applied to arrays. These
include:
Examples:
python
CopyEdit
# Element-wise trigonometric function
arr = np.array([0, np.pi/2, np.pi])
print(np.sin(arr)) # Output: [0. 1. 0.]
6. Broadcasting
Broadcasting refers to the ability to apply binary operations (like addition, multiplication)
between arrays of different shapes. NumPy automatically expands the smaller array to match
the shape of the larger array, making operations efficient.
84 of 107
Example:
# Broadcasting addition
result = matrix + arr
print(result)
The 1D array arr is automatically "broadcast" to match the shape of the 2D array matrix,
allowing element-wise addition.
7. Reshaping Arrays
NumPy provides methods to reshape arrays, which is useful when working with machine
learning algorithms or manipulating data. The shape of the array can be changed without
modifying its data.
Example:
8. Random Module
NumPy includes a random module to generate random numbers, which is crucial for
simulations, statistical modeling, and machine learning.
# Random integers
rand_int = np.random.randint(1, 10, (2, 2)) # Random integers between
1 and 10
85 of 107
print(rand_int)
Summary
• NumPy is a powerful library for numerical computing, built around the ndarray (n-
dimensional array) to handle large, multi-dimensional arrays and matrices.
• Key features include array creation, vectorized operations, mathematical functions,
broadcasting, and reshaping arrays.
• It significantly enhances performance by using compiled code for operations, making it
far more efficient than Python’s built-in lists.
• It integrates well with other scientific libraries, allowing Python to be used for complex
computations, machine learning, data analysis, and scientific research.
The most common and recommended method for installing NumPy is by using pip, the Python
package manager. pip is bundled with Python, so it should already be available if you have
Python installed.
bash
pip install numpy
86 of 107
This command will download and install the latest version of NumPy from the Python Package
Index (PyPI).
2. Verify Installation
Once the installation is complete, you can verify that NumPy is successfully installed by
checking its version in Python:
bash
python -c "import numpy; print(numpy.__version__)"
If NumPy is installed correctly, this command will output the version number of NumPy, like
1.23.1 (the version may vary based on the latest release).
If you are using the Anaconda or Miniconda distribution, you can install NumPy via the conda
package manager, which is optimized for scientific computing and automatically manages
dependencies for you.
bash
conda install numpy
Conda will automatically fetch the appropriate version of NumPy and its dependencies, ensuring
everything works smoothly in the environment.
It's a good practice to install packages in a virtual environment to avoid conflicts between
different projects. You can use venv (built-in for Python 3.3 and above) to create isolated
environments.
Steps:
bash
87 of 107
python -m venv myenv
bash
myenv\Scripts\activate
b. macOS/Linux:
bash
source myenv/bin/activate
bash
pip install numpy
bash
deactivate
If you want to install NumPy from source (which is less common for most users), you can
download the source code from GitHub or the official NumPy website and install it manually.
bash
git clone https://github.com/numpy/numpy.git
88 of 107
2. Navigate to the NumPy directory:
bash
cd numpy
bash
python setup.py install
This method is typically used by developers or users with specific needs, such as contributing to
NumPy or using a custom version.
Updating NumPy
To ensure you have the latest version of NumPy, you can update it using the following pip
command:
bash
pip install --upgrade numpy
bash
conda update numpy
Troubleshooting
• Issue 1: pip not found
If you get an error saying pip is not recognized, make sure Python and pip are added to
your system’s PATH variable.
o You can reinstall Python and check the box that says Add Python to PATH
during the installation.
• Issue 2: Version Conflict
Sometimes, other installed packages may conflict with NumPy. Consider using a virtual
89 of 107
environment to isolate dependencies for each project, or run pip check to identify and
resolve conflicts.
Conclusion
Installing NumPy is easy and can be done via pip or conda in most cases. By following these
steps, you should be able to set up NumPy in your Python environment and start using its
powerful array manipulation and mathematical capabilities. If you run into any issues, consider
using a virtual environment for better dependency management.
NumPy provides a variety of methods to create arrays of different dimensions. Arrays in NumPy
are the backbone for numerical operations, and you can create them for 1D (one-dimensional),
2D (two-dimensional), and 3D (three-dimensional) purposes.
Let’s break down the process of creating arrays for each dimension with examples.
1. Creating a 1D Array
A 1D array is simply a list of values in a single row, like a vector.
Syntax:
python
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
Example:
python
import numpy as np
# Creating a 1D array
arr_1d = np.array([10, 20, 30, 40, 50])
90 of 107
print("1D Array:")
print(arr_1d)
Output:
1D Array:
[10 20 30 40 50]
2. Creating a 2D Array
A 2D array is a matrix, which consists of rows and columns.
Syntax:
python
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
Example:
python
import numpy as np
# Creating a 2D array
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
Output:
2D Array:
[[1 2 3]
[4 5 6]]
91 of 107
3. Creating a 3D Array
A 3D array can be thought of as a stack of matrices (multiple 2D arrays). It has depth in addition
to rows and columns.
Syntax:
python
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
Example:
python
import numpy as np
# Creating a 3D array
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
Output:
lua
3D Array:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
92 of 107
Alternative Methods for Array Creation
Using np.zeros() (Creates an array filled with zeros)
• 1D:
python
arr_1d_zeros = np.zeros(5) # 1D array with 5 zeros
• 2D:
python
arr_2d_zeros = np.zeros((3, 3)) # 2D array (3x3) with zeros
• 3D:
python
arr_3d_zeros = np.zeros((2, 3, 2)) # 3D array (2x3x2) with zeros
• 1D:
python
arr_1d_ones = np.ones(4) # 1D array with 4 ones
• 2D:
python
arr_2d_ones = np.ones((2, 4)) # 2D array (2x4) with ones
• 3D:
python
arr_3d_ones = np.ones((3, 2, 2)) # 3D array (3x2x2) with ones
93 of 107
Using np.arange() (Creates an array with a sequence of numbers)
• 1D:
python
arr_1d_range = np.arange(1, 11, 2) # 1D array from 1 to 10, step 2
• 2D:
python
arr_2d_range = np.arange(1, 13).reshape(3, 4) # 2D array (3x4)
• 3D:
python
CopyEdit
arr_3d_range = np.arange(1, 25).reshape(2, 3, 4) # 3D array (2x3x4)
Conclusion
• 1D Arrays are essentially vectors, storing a sequence of values in one row.
• 2D Arrays are matrices, with rows and columns.
• 3D Arrays are a stack of 2D arrays, adding depth to the dimensions.
Indexing and slicing are fundamental operations when working with NumPy arrays. They allow
you to access and modify specific elements or subarrays in an array. Let's explore how indexing
and slicing work in NumPy with clear explanations and examples.
In a 1D array, you can access elements by specifying their index. Indexing starts from 0.
Syntax:
python
CopyEdit
array[index]
Example:
python
CopyEdit
import numpy as np
# 1D Array
arr = np.array([10, 20, 30, 40, 50])
Output:
perl
CopyEdit
Element at index 2: 30
Element at index -1: 50
Indexing in 2D Arrays
For 2D arrays, you need to specify two indices: one for the row and one for the column. You
use array[row, column] to access elements.
95 of 107
Syntax:
python
CopyEdit
array[row_index, column_index]
Example:
python
CopyEdit
import numpy as np
# 2D Array
arr_2d = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
# Accessing elements
print("Element at row 1, column 2:", arr_2d[1, 2]) # Output: 60
print("Element at row 0, column 0:", arr_2d[0, 0]) # Output: 10
Output:
sql
CopyEdit
Element at row 1, column 2: 60
Element at row 0, column 0: 10
Indexing in 3D Arrays
For 3D arrays, you need to specify three indices: one for the depth, one for the row, and one for
the column.
Syntax:
python
CopyEdit
96 of 107
array[depth_index, row_index, column_index]
Example:
python
CopyEdit
import numpy as np
# 3D Array
arr_3d = np.array([[[10, 20], [30, 40]], [[50, 60], [70, 80]]])
# Accessing elements
print("Element at depth 1, row 1, column 1:", arr_3d[1, 1, 1]) #
Output: 80
print("Element at depth 0, row 0, column 1:", arr_3d[0, 0, 1]) #
Output: 20
Output:
sql
CopyEdit
Element at depth 1, row 1, column 1: 80
Element at depth 0, row 0, column 1: 20
In 1D arrays, slicing allows you to extract a portion of the array using the start:stop:step
format.
97 of 107
Syntax:
array[start:stop:step]
Example:
import numpy as np
# 1D Array
arr = np.array([10, 20, 30, 40, 50, 60, 70])
Output:
Slicing in 2D Arrays
In 2D arrays, you can slice rows and columns using the array[start_row:end_row,
start_column:end_column] syntax.
98 of 107
Syntax:
array[start_row:end_row, start_column:end_column]
Example:
import numpy as np
# 2D Array
arr_2d = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
Output:
Slicing in 3D Arrays
For 3D arrays, you can slice in all three dimensions. The general syntax is
array[start_depth:end_depth, start_row:end_row,
start_column:end_column].
99 of 107
Syntax:
array[start_depth:end_depth, start_row:end_row,
start_column:end_column]
Example:
import numpy as np
# 3D Array
arr_3d = np.array([[[10, 20], [30, 40]], [[50, 60], [70, 80]]])
Output:
Example:
import numpy as np
# 1D Array
arr = np.array([10, 20, 30, 40, 50, 60, 70])
# Fancy indexing
indices = [1, 3, 5]
print("Fancy indexing result:", arr[indices]) # Output: [20 40 60]
100 of 107
Output:
less
Fancy indexing result: [20 40 60]
Conclusion
• Indexing is used to access specific elements in an array, whether it's a single element or a
multi-dimensional element.
• Slicing allows you to extract subarrays or specific ranges of elements from arrays. You
can slice arrays using the start:stop:step notation.
• Advanced Indexing (or fancy indexing) allows you to use arrays of indices or boolean
masks to select specific elements from an array.
Syntax:
array1 + array2
Example:
import numpy as np
# Two 1D Arrays
arr1 = np.array([10, 20, 30])
arr2 = np.array([5, 15, 25])
# Element-wise addition
result = arr1 + arr2
print("Addition of arrays:", result) # Output: [15 35 55]
101 of 107
Output:
Syntax:
array1 - array2
Example:
import numpy as np
# Two 1D Arrays
arr1 = np.array([10, 20, 30])
arr2 = np.array([5, 15, 25])
# Element-wise subtraction
result = arr1 - arr2
print("Subtraction of arrays:", result) # Output: [ 5 5 5]
Output:
Subtraction of arrays: [ 5 5 5]
array1 * array2
102 of 107
Example:
import numpy as np
# Two 1D Arrays
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# Element-wise multiplication
result = arr1 * arr2
print("Multiplication of arrays:", result) # Output: [ 4 10 18]
Output:
Syntax:
array1 / array2
Example:
import numpy as np
# Two 1D Arrays
arr1 = np.array([10, 20, 30])
arr2 = np.array([2, 4, 5])
# Element-wise division
result = arr1 / arr2
103 of 107
print("Division of arrays:", result) # Output: [ 5. 5. 6.]
Output:
Example:
import numpy as np
# 1D Array
arr = np.array([10, 20, 30])
# Scalar addition
result_add = arr + 5
print("Scalar addition:", result_add) # Output: [15 25 35]
# Scalar subtraction
result_sub = arr - 5
print("Scalar subtraction:", result_sub) # Output: [ 5 15 25]
# Scalar multiplication
result_mul = arr * 2
print("Scalar multiplication:", result_mul) # Output: [20 40 60]
# Scalar division
result_div = arr / 5
print("Scalar division:", result_div) # Output: [2. 4. 6.]
104 of 107
Output:
Example:
import numpy as np
Output:
In the above example, the 1D array arr1d is broadcast across each row of the 2D array arr2d
to perform the element-wise addition.
105 of 107
7. Universal Functions (ufuncs)
NumPy provides universal functions (ufuncs) to perform arithmetic operations on arrays. These
functions allow you to apply operations to entire arrays in a vectorized manner, ensuring fast
execution.
import numpy as np
# Two 1D Arrays
arr1 = np.array([10, 20, 30])
arr2 = np.array([5, 15, 25])
Output:
106 of 107
Conclusion
107 of 107