0% found this document useful (0 votes)
8 views

Python Programming -Basics to Advanced (1)

The document provides an overview of Python programming, covering various types of Python, data types, and basic programming concepts such as functions, lists, and dictionaries. It includes examples of numeric, sequence, mapping, set, boolean, binary, and none types, along with operations on these data types. Additionally, it discusses the use of functions, loops, and methods for manipulating data structures in Python.

Uploaded by

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

Python Programming -Basics to Advanced (1)

The document provides an overview of Python programming, covering various types of Python, data types, and basic programming concepts such as functions, lists, and dictionaries. It includes examples of numeric, sequence, mapping, set, boolean, binary, and none types, along with operations on these data types. Additionally, it discusses the use of functions, loops, and methods for manipulating data structures in Python.

Uploaded by

emilyroswell4947
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 107

Python

Programming

Copyright @ Dr. Faisal Azam COMSATS Islamabad 1


Types
Iron Python (.Net framework)

CPython

Jython

PyPy (interpreter)

Stackless Python (Light


weight)
MicroPython (for
Microcontrollers)
Data Types
• Python has various data types that define the type of
value a variable holds.
• Here’s a list of the main data types with examples:
• 1. Numeric Types
• int: Represents integers (whole numbers).
Example: a = 10
• float: Represents floating-point numbers (decimal numbers).
Example: b = 10.5
• complex: Represents complex numbers.
Example: c = 2 + 3j
Data Types
• Sequence Types
• str: Represents a string of characters (text).
Example: s = "Hello"
• list: Ordered, mutable collection of items.Example:
my_list = [1, 2, 3, "four"]
• tuple: Ordered, immutable collection of items.
Example: my_tuple = (1, 2, 3)
Data Types
• Mapping Type
dict: Key-value pairs, unordered and mutable.
Example: my_dict = {"name": "John", "age": 30}
Data Types
• Set Types
• set: Unordered collection of unique items.
• Example: my_set = {1, 2, 3, 4}
• frozenset: Immutable version of a set.
• Example: frozen_set = frozenset([1, 2, 3])
• print(list(frozen_set))
• print(*(frozen_set))
Data Types

Boolean Type

bool: Represents True or


False.
• Example: is_active = True
Data Types
• Binary Types
• bytes: Immutable sequence of bytes.
• Example: b = b'hello'
• bytearray: Mutable sequence of bytes.
• Example: ba = bytearray(5)
• memoryview: Memory view object of another binary
object.
• Example: mv = memoryview(b'hello')
Data Types
• None Type
• None: Represents the absence of a value.
• Example: x = None
# Step 1: Get user input for two numbers and the operation
num1 = float(input("Enter the first number: "))
num2 = float(input("Enter the second number: "))
operation = input("Choose operation (+, -, *, /): ")

# Step 2: Perform the operation based on user input


if operation == '+':
result = num1 + num2
elif operation == '-':
result = num1 - num2
elif operation == '*':
result = num1 * num2
elif operation == '/':
result = num1 / num2
else:
result = "Invalid operation"

# Step 3: Output the result


# Step 1: Start an infinite while loop # Step 4: Perform the operation based on
while True: user input
# Step 2: Get user input for two if operation == '+':
numbers and the operation result = num1 + num2
num1 = float(input("Enter the first elif operation == '-':
number: ")) result = num1 - num2
num2 = float(input("Enter the second elif operation == '*':
number: "))
result = num1 * num2
operation = input("Choose operation
(+, -, *, /) or type 'exit' to quit: ") elif operation == '/':
# Step 3: Check if the user wants to result = num1 / num2
exit else:
if operation.lower() == 'exit': result = "Invalid operation"
print("Exiting calculator. Goodbye!")
break # Exit the loop # Step 5: Output the result
print("The result is:", result)
Programming
Strategies

• Swap
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
return;
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y);
printf(“%d %d\n”, x, y);
return 0;
}

13
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
return;
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x: 1
printf(“%d %d\n”, x, y);
return 0; y:
} 2

14
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{ tmp:
int tmp;
tmp = *a; a: addr of x
*a = *b;
*b = tmp; b:
return; addr of y
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x: 1
printf(“%d %d\n”, x, y);
return 0; y:
} 2

15
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{ tmp: 1
int tmp;
tmp = *a; a: addr of x
*a = *b;
*b = tmp; b:
return; addr of y
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x: 1
printf(“%d %d\n”, x, y);
return 0; y:
} 2

16
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{ tmp: 1
int tmp;
tmp = *a; a: addr of x
*a = *b;
*b = tmp; b:
return; addr of y
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x: 2
printf(“%d %d\n”, x, y);
return 0; y:
} 2

17
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{ 1
int tmp; tmp:

tmp = *a; a: addr of x


*a = *b;
*b = tmp;
return; b: addr of y
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x: 2
printf(“%d %d\n”, x, y);
return 0;
} y: 1

18
#include <stdio.h> Good swap

void swap2(int* a, int* b)


{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
return;
}
int main()
{
int x = 1, y = 2;
swap2(&x, &y); x:
2
printf(“%d %d\n”, x, y);
return 0; y:
} 1

19
Python Swap
# Function to swap two numbers in Python
def swap(a, b):
return b, a
x=1
y=2
# Swapping the values of x and y
x, y = swap(x, y)
print(x, y) # Output: 2 1
For Loop in Python
for item in sequence:
# code block to be executed

fruits = ['apple', 'banana', 'cherry’]

for fruit in fruits:


print(fruit)

for i in range(5):
print(i)
List in Python
•# Creating a list •#Adding item at specific position
•my_list = [1, 2, 3, 4, 5] •my_list.insert(1, "inserted")
•# Accessing elements •print(my_list) # Output: [1,
•print(my_list[0]) # Output: 1 'inserted', 2, 3, 4]
•#Popping an element from a
•# Adding an element
specific index (removes and
•my_list.append(6) returns):
•# Removing an element •my_list.pop(2)
•my_list.remove(3) •print(my_list) # Output: [1,
•# Checking the list 'inserted', 4]
•print(my_list) # Output: [1, 2, 4, 5,
6]
List

• In Python, a list is a collection of items that can


store multiple values in a single variable. Lists
are ordered, changeable, and allow duplicate
elements.
Key properties

• Ordered: Items are stored in a specific order.


• Changeable: You can modify the list (add,
remove, or change items).
• Allows duplicates: Lists can have the same
value repeated multiple times.
1. Length of a List

my_list = [1, 2, 3, 4, 5]
print(len(my_list)) # Output: 5
2. List with Multiple Data Types

mixed_list = [1, "hello", 3.14, True]


print(mixed_list) # Output: [1, "hello", 3.14, True]
3. Multidimensional Lists (Lists within Lists)

matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Accessing elements
print(matrix[0][1]) # Output: 2 (first row, second element)
3D List

cube = [
[[1, 2], [3, 4]],
[[5, 6], [7, 8]]
]

# Accessing elements
print(cube[1][0][1]) # Output: 6
5. List Slicing
my_list = [1, 2, 3, 4, 5]
sliced_list = my_list[1:4] # Slices from index 1 to 3 (excludes index 4)
print(sliced_list) # Output: [2, 3, 4]
6. Iterating through a List
my_list = [10, 20, 30]
for item in my_list:
print(item) or print (*[item])

• my_list = [10, 20, 30]


print(*range(len(my_list)))
Output: 0 1 2
7. Checking for Elements
my_list = [1, 2, 3, 4]
print(3 in my_list) # Output: True
8. List Comprehension
squares = [x ** 2 for x in range(5)]
print(squares) # Output: [0, 1, 4, 9, 16]
9. Copying a List
original = [1, 2, 3]
copy = original.copy()
print(copy) # Output: [1, 2, 3]
10. Sorting a List
my_list = [3, 1, 4, 2]
my_list.sort() # Ascending
print(my_list) # Output: [1, 2, 3, 4]

my_list.sort(reverse=True) # Descending
print(my_list) # Output: [4, 3, 2, 1]
11. Reversing a List
my_list = [1, 2, 3]
my_list.reverse()
print(my_list) # Output: [3, 2, 1]
Python
Dictionary
• A dictionary in Python is a collection of key-value pairs, where each key maps to a
value.
#Creating a dictionary
student = {
"name": "Jamal",
"age": 12,
"grade": "6th",
"subjects": ["Math", "Science", "English"]
}
# Accessing elements
print(student["name"]) # Output: Jamal
print(student["subjects"]) # Output: ['Math', 'Science', 'English’]
print(student) # Output: {'name': ‘Jamal', 'age': 12, 'grade': '6th', 'subjects': ['Math', 'Science', 'English']}
List of Dictionaries
•# Creating a list of dictionaries •# Looping through all student
•students = [ records
• {"name": “Jamal", "age": 12, "grade": •for student in students:
"6th"},
• print(f"{student['name']} is in
• {"name": "Ali", "age": 13, "grade":
grade {student['grade']}.")
"7th"},
• {"name": "Bilal", "age": 11, "grade":
"5th"}
•]

•# Accessing the first student's information


•print(students[0]["name"]) # Output: Jamal
•print(students[0]["age"]) # Output: 12
Dynamic Addition of Records

# Adding a new student to the list


students.append({"name": "Ehsan", "age": 14, "grade":
"8th"})

# Now the list contains 4 students


print(len(students)) # Output: 4
Creating another dictionary

student = {
"name": "John",
"age": 12,
"grade": "6th"
}
Dictionary Methods
Method Description Example
keys() Returns a list of dictionary student.keys() → ['name',
keys 'age', 'grade']
values() Returns a list of dictionary student.values() → ['John',
values 12, '6th']
items() Returns a list of key-value student.items() →
pairs as tuples [('name', 'John'), ('age',
12)]
get(key) Returns the value for a student.get("name") →
given key, or None if key 'John'
doesn’t exist
update() Merges another dictionary student.update({"age":
into the current one 13}) → Updates 'age' to
13
Checking for a Key
if "name" in student:
print("Name is present in the dictionary.")
Looping Through a Dictionary
for key in student:
print(key)

# Looping through values


for value in student.values():
print(value)

# Looping through key-value pairs


for key, value in student.items():
print(f"{key}: {value}")
Nested Dictionaries
students = {
"student1": {"name": "John", "age": 12, "grade":
"6th"},
"student2": {"name": "Alice", "age": 13, "grade":
"7th"}
}

print(students["student1"]["name"]) # Output: John


Dictionary Comprehensions
squares = {x: x**2 for x in range(5)}
print(squares) # Output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Copying a Dictionary
student_copy = student.copy()
Default Values with get()
print(student.get("age", "Not Found")) # Output: 12
print(student.get("school", "Not Found")) # Output: Not
Found
Sorting a Dictionary by Keys or
Values
# Sorting by keys
sorted_by_keys = {key: student[key] for key in sorted(student)}
print(sorted_by_keys)

# Sorting by values
sorted_by_values = {key: value for key, value in
sorted(student.items(), key=lambda item: item[1])}

sorted_by_age = {key: value for key, value in


sorted(students.items(), key=lambda item: item[1]['age'])}
print(sorted_by_age)
Dictionaries
• Dictionaries in Python are powerful tools for storing and
manipulating key-value pairs.
• They offer flexibility with dynamic additions and
modifications, unlike static data structures like C
structs.
• By utilizing dictionary methods, nested dictionaries, and
comprehensions, you can build complex data
representations efficiently.
Functions in Python – A starting intro

def add(a, b):


return a + b

result = add(3, 5) # result will be 8


print(result) # This will print 8
Functions
• A function is a block of reusable code that performs a
specific task.
• It helps break the code into smaller, modular chunks,
making it easier to manage and reuse.
• Functions are defined using the def keyword followed
by the function name and parentheses () which may
contain parameters. The function body is indented.

•def function_name(parameters):

• # Function body

• # Return statement (optional)

Defining a
Function •def greet(name):
• print(f"Hello, {name}!")
Calling a Function
greet(“Ali") # Output: Hello, Ali!
Parameters and Arguments
• Parameters: Variables listed in the function definition.
• Arguments: Values you pass to the function when
calling it.

def add_numbers(a, b): # a and b are parameters


return a + b

result = add_numbers(5, 10) # 5 and 10 are arguments


Return Statement
• The return statement is used to exit a function and
optionally send back a value.
• If a function doesn't have a return statement, it returns
None by default.
def square(num):
return num ** 2

result = square(4) # result will be 16


Default Arguments
• You can define default values for function parameters.
• If no argument is passed for a parameter, the default
value is used.
def greet(name="Guest"):
print(f"Hello, {name}!")

greet() # Output: Hello, Guest!


greet("Ali") # Output: Hello, Ali
Keyword Arguments
• You can pass arguments to a function using the
parameter names. This allows you to pass them in any
order.

def introduce(name, age):


print(f"{name} is {age} years old.")

introduce(age=30, name="Ali") # Order does not matter


Variable-Length Arguments
• Python allows you to pass a variable number of
arguments to a function using *args (non-keyword
arguments) and **kwargs (keyword arguments).
• *args: Allows the function to accept any number of positional
arguments as a tuple.
def add_all(*numbers):
return sum(numbers)

print(add_all(1, 2, 3, 4)) # Output: 10


**kwargs
def display_info(**info):
for key, value in info.items():
print(f"{key}: {value}")

display_info(name="Ali", age=30, city=“Lahore")


Lambda Functions
• A lambda function is an anonymous function (without a
name) defined using the lambda keyword.
• They are typically used for short, simple operations.
lambda arguments: expression

square = lambda x: x ** 2
print(square(5)) # Output: 25
Scope of Variables
• Local Scope: Variables defined within a function are only
accessible inside that function.
• Global Scope: Variables defined outside any function are
accessible throughout the program.
Scope Variables
x = 10 # Global variable

def change_x():
x = 5 # Local variable
print("Inside function:", x)

change_x() # Output: Inside function: 5


print("Outside function:", x) # Output: Outside function:
10
global Keyword
• To modify a global variable inside a function, use the global keyword.

x = 10

def change_global_x():
global x
x=5

change_global_x()
print(x) # Output: 5
nonlocal Keyword
• The nonlocal keyword is used to modify a variable in the
enclosing (non-global) scope.

def outer_function():
x = 10
def inner_function():
nonlocal x
x = 20
inner_function()
print(x) # Output: 20
Function Documentation
• You can add a docstring to a function to describe its
purpose.
• Use triple quotes """ to define a docstring.
def add(a, b):
"""This function adds two numbers."""
return a + b

print(add.__doc__) # Output: This function adds two


numbers.
Function Annotations
• Function annotations are optional metadata for
parameters and return types.
• They don't affect the function's behavior but are useful
for type hinting.
def greet(name: str, age: int) -> str:
return f"Hello {name}, you are {age} years old."
Recursive Functions
• A recursive function is a function that calls itself in
order to solve a problem.
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)

print(factorial(5)) # Output: 120


Functions as First-Class Citizens
• In Python, functions are first-class citizens, meaning
they can be assigned to variables, passed as
arguments, or returned from other functions.
def greet():
return "Hello!"

say_hello = greet # Assigning function to variable


print(say_hello()) # Output: Hello!
Class in Python
• class is a blueprint for creating objects (instances).
• A class encapsulates data (attributes) and functions
(methods) that operate on the data.
• It provides a way to organize code and model real-world
entities.
Defining a Class
• A class is defined using the class keyword, followed by a
name that is usually written in PascalCase.
class MyClass:
pass # This is an empty class
Attributes
• Attributes are variables that belong to a class or an
instance of a class.
• Instance attributes: Unique to each instance of the class.
• Class attributes: Shared among all instances of the class.

class Car:
wheels = 4 # Class attribute (shared by all instances)

def __init__(self, color, model):


self.color = color # Instance attribute
self.model = model # Instance attribute
What Happens If We
Remove self?
? class Car:
def __init__(color,
model):
color = color
model = model
Reason
• color = color and model = model are just local variables
inside __init__, not stored in the object.
• The color and model values will be lost after __init__
finishes execution.

• car1 = Car("Red", "Toyota")


• print(car1.color) # ❌ ERROR: AttributeError: 'Car' object
has no attribute 'color'
Methods
• Methods are functions that are defined inside a class
and operate on the class’s attributes.
• Instance methods: These take self as the first parameter and
operate on instance attributes.
• Class methods: Take cls (the class itself) as the first
parameter.
• Static methods: Do not take self or cls as a parameter.
Methods
class Car: @classmethod
wheels = 4 # Class attribute
def get_wheels(cls):
def __init__(self, color, model): # Class method
self.color = color return cls.wheels
self.model = model

def description(self): @staticmethod


# Instance method
def honk(): # Static
return f"Car model: {self.model},
color: {self.color}" method
return "Beep beep!"
Constructors (__init__ Method)
• The __init__ method is a special method (also called the
constructor) that gets called when you create a new
instance of the class.
• It is used to initialize instance attributes.
Constructor
class Car:
def __init__(self, color, model):
self.color = color
self.model = model
Instance Creation
• Once a class is defined, you can create instances
(objects) of that class.

my_car = Car("Red", "Toyota")


print(my_car.color) # Accessing an instance attribute
Encapsulation
Encapsulation is the concept of bundling data (attributes) and
methods that operate on that data within a class.
It allows controlling access to data using access modifiers

Public attributes: Accessible from outside the class (no leading


underscores).
Protected attributes: Denoted by a single underscore (_), signaling
that they are for internal use.
Private attributes: Denoted by a double underscore (__), which
triggers name to prevent external access.
Encapsulation
class Car:
def __init__(self, model):
self.model = model # Public
self._fuel = 50 # Protected
self.__engine = "V8" # Private

my_car = Car("Toyota")
print(my_car.model) # Public: Accessible
print(my_car._fuel) # Protected: Accessible, but not recommended
# print(my_car.__engine) # Private: Raises an AttributeError
Inheritance
• Inheritance allows one class to inherit attributes and methods from
another class.
• The parent class is called the superclass, and the class that inherits is
called the subclass.
class Vehicle:
def __init__(self, brand):
self.brand = brand

class Car(Vehicle): # Car inherits from Vehicle


def __init__(self, brand, model):
super().__init__(brand) # Calling the parent class constructor
self.model = model
Polymorphism
• Polymorphism allows different classes to be treated as
instances of the same class through inheritance.
• It means that a subclass can override methods of the
parent class.
Polymorphism
class Animal: class Cat(Animal):
def speak(self): def speak(self):
return "Animal sound" return "Meow"

class Dog(Animal): animals = [Dog(), Cat()]


def speak(self): for animal in animals:
# Overriding the parent print(animal.speak())
method # "Bark", "Meow"
return "Bark"
Abstraction
• Abstraction hides the complexity of the system and
exposes only the necessary components.
• It can be achieved through abstract classes.

• To create an abstract class, you use the abc (Abstract


Base Class) module in Python.
Abstraction
from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def sound(self):
pass

class Dog(Animal):
def sound(self):
return "Bark"
Without Abstraction
class CreditCard:
def pay_with_card(self, amount):
print(f"Paid ${amount} using Credit Card")

class PayPal:
def paypal_payment(self, amount):
print(f"Paid ${amount} using PayPal")
Without Abstration
def process_payment(payment_method, amount):
if isinstance(payment_method, CreditCard):
payment_method.pay_with_card(amount)
elif isinstance(payment_method, PayPal):
payment_method.paypal_payment(amount)
else:
raise ValueError("Unsupported payment method")
Without Abstraction
cc = CreditCard()
pp = PayPal()

process_payment(cc, 100)
process_payment(pp, 200)
With Abstraction
from abc import ABC, abstractmethod

# Abstract Base Class


class Payment(ABC):
@abstractmethod
def pay(self, amount):
pass # No implementation, forces subclasses to
define it
With Abstraction
class CreditCard(Payment):
def pay(self, amount):
print(f"Paid ${amount} using Credit Card")

class PayPal(Payment):
def pay(self, amount):
print(f"Paid ${amount} using PayPal")

# Function now works with any Payment subclass


def process_payment(payment_method: Payment, amount):
payment_method.pay(amount) # No need for isinstance() checks
With Abstraction
cc = CreditCard()
pp = PayPal()

process_payment(cc, 100)
process_payment(pp, 200)
Dunder (Magic) Methods
• These are special methods with double underscores
(like __init__, __str__, etc.).
• They allow customization of certain operations (like
string representation, object comparisons, etc.)
Dunder methods
Class Car:
def __init__(self, model):
self.model = model

def __str__(self):
return f"Car model: {self.model}"

my_car = Car("Toyota")
print(my_car) # Output: Car model: Toyota
Dunder Methods
Common dunder methods:

__init__(self): Constructor
__str__(self): String representation
__len__(self): Defines the behavior for the len()
function
__eq__(self, other): Used for comparison (e.g., ==)
Consider a graph
Nodes: A, B, C, D, E, F, G, H
A Edges:
/ \
B C A↔B
/\ \ A↔C
D E F B↔D
\ / B↔E
C↔F
G H
F↔H
D↔G
The DFS Data Structure

1. State of the node


2. Parent of the node
3. Actions applicable to that node
4. The total path cost of that node starting
from the initial state until that particular node
is reached
Class Node
class Node:
def __init__(self, state, parent=None, path_cost=0):
self.state = state # Current state of the node (e.g.,
'A', 'B', etc.)
self.parent = parent # Parent node
self.path_cost = path_cost # Cost to reach this node
self.children = [] # List to store children nodes
self.actions = [] # Actions applicable to this node
Explanation
Node Class:
__init__ method initializes a node with its state, parent,
path cost, children, and applicable actions. ()

add_child method adds a child node to the current


node and records the action taken to reach it.()

__str__ method provides a readable representation of


the node. ()
Functions
def add_child(self, child_node):
"""Add a child node and define the action to reach it."""
self.children.append(child_node)
self.actions.append(f"Go to {child_node.state}")

def __str__(self):
"""String representation of the node."""
return (f"Node(state={self.state}, "
f"parent={self.parent.state if self.parent else None}, "
f"path_cost={self.path_cost})")
Graph Generation
# Sample graph creation
def create_graph():
# Create nodes
A = Node('A')
B = Node('B', parent=A, path_cost=1)
C = Node('C', parent=A, path_cost=1)
D = Node('D', parent=B, path_cost=2)
E = Node('E', parent=B, path_cost=2)
F = Node('F', parent=C, path_cost=2)
G = Node('G', parent=D, path_cost=3)
H = Node('H', parent=F, path_cost=3)
Explanation
Creating the Graph:

In the create_graph function, we create nodes


representing the graph.
We then define relationships (edges) between the
nodes using the add_child method.
Define Edges
# Define the relationships (edges)
A.add_child(B)
A.add_child(C)
B.add_child(D)
B.add_child(E)
C.add_child(F)
D.add_child(G)
F.add_child(H)
return A # Return the root node
Depth First Search
# Depth First Search (DFS) function
def dfs(node):
"""Perform Depth First Search (DFS) on the graph."""
print(node) # Print the current node's details

for child in node.children:


dfs(child) # Recursive call for each child
main function
# Main function to run the program
if __name__ == "__main__":
root = create_graph() # Create the graph
dfs(root) # Start DFS from the root node
DFS
DFS Function:

The dfs function prints details of the current node and


recursively calls itself for each child node to explore the
graph.
main
• Main Block:
• The main block creates the graph and starts the DFS
from the root node (A).
Activity
• For the graph in previous activity, imagine node A as
starting node and your goal is to reach F.
• Keeping breadth first search in mind, describe a
sequence of actions that you must take to reach that
goal state

You might also like