Lab Manual
Lab Manual
Lab Manual
1
Table of Content
Lab # 01 ________________________________________________________ 3
Lab # 02 ________________________________________________________ 9
Lab # 03 _______________________________________________________ 15
Lab # 04 _______________________________________________________ 20
Lab # 05 _______________________________________________________ 23
Lab # 06 _______________________________________________________ 27
Lab # 07 _______________________________________________________ 29
Lab # 08 _______________________________________________________ 31
Lab # 10 _______________________________________________________ 33
Lab # 11 _______________________________________________________ 35
Lab # 13 _______________________________________________________ 39
Lab # 14 _______________________________________________________ 41
Lab # 15 _______________________________________________________ 43
2
Lab # 01
1.1. Objective: The objective of this lab was to introduce fundamental concepts in basic Python
programming, such as the printing of output, comments, declaring variables, type casting and type
switching. The lab aimed at helping students become familiar with the basic syntax and variable behaviors
in Python.
1.2. Introduction: Python is a versatile and powerful high-level programming language widely used for
various types of programming tasks. It is very simple and easy to use, and for this reason, great for
beginners while extensive libraries make it popular among professionals in web development, data
analysis, and artificial intelligence.
In this lab, we explored several foundational concepts:
Each of these elements plays an essential role in Python programming, and understanding them is crucial for
writing effective code.
1.3. Software: For performing these lab tasks we are using Google Colab.
1.4. Code Explanation: This lab was all about the basics of Python operations. The major parts are broken
down below:
1.4.1. Printing Outputs: Python’s print() function allows us to display text or other types of output in the
console. The basic syntax involves passing a string or variable to the print() function, which then outputs it
to the console.
Code:
print(“Hello, World!”)
Output:
1.4.2. Comments: Comments in Python help in documenting the code, making it easier to understand.
Python supports two types of comments:
Single-line comments
Multi-line comments
Code:
#This is a single line comment
print("Hello, World!")
"""
This is a comment
written in
more than just one line
"""
print("Hello, World!")
3
1.4.3. Variables: Variables are containers for storing data values.
Code:
#variables
x=5
y = "John"
print(x)
print(y)
Output:
1.4.4. Type Casting: To explicitly set the type of a variable, Python provides casting functions such as int(),
float(), and str().
Code:
#If you want to specify the data type of a variable, this can be done with casting.
x = str(3) # x will be '3'
y = int(3) # y will be 3
z = float(3) # z will be 3.0
print(A)
print(a)
Output:
1.4.6. Slicing: You can return a range of characters by using the slice syntax.
Code:
4
#slicing string
b = "Hello, World!"
print(b[2:5])
Output:
print("Hello, World!")
"""
This is a comment
written in
more than just one line
"""
print("Hello, World!")
#variables
x=5
y = "John"
print(x)
print(y)
#Variables do not need to be declared with any particular type, and can even change type
after they have been set.
x=4 # x is of type int
x = "Sally" # x is now of type str
print(x)
#If you want to specify the data type of a variable, this can be done with casting.
x = str(3) # x will be '3'
y = int(3) # y will be 3
z = float(3) # z will be 3.0
#You can get the data type of a variable with the type() function.
x=5
y = "John"
print(type(x))
print(type(y))
5
#Variable names are case-sensitive.
a=4
A = "Sally"
#A will not overwrite a
print(A)
print(a)
x = y = z = "Orange"
print(x)
print(y)
print(z)
#Unpack a Collection
fruits = ["apple", "banana", "cherry"]
x, y, z = fruits
print(x)
print(y)
print(z)
#global variable
x = "awesome"
def myfunc():
print("Python is " + x)
myfunc()
x = "awesome"
def myfunc():
x = "fantastic"
print("Python is " + x)
6
myfunc()
print("Python is " + x)
#If you use the global keyword, the variable belongs to the global scope
def myfunc():
global x
x = "fantastic"
myfunc()
print("Python is " + x)
#Import the random module, and display a random number between 1 and 9
import random
print(random.randrange(1, 10))
#casting integers
x = int(1) # x will be 1
y = int(2.8) # y will be 2
z = int("3") # z will be 3
print(x)
print(y)
print(z)
#casting floats
x = float(1)
y = float(2.8)
z = float("3")
w = float("4.2")
print(x)
print(y)
print(z)
print(w)
#casting strings
x = str("s1")
y = str(2)
z = str(3.0)
print(x)
print(y)
print(z)
#Multiline Strings
a = """Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua."""
print(a)
7
#slicing string
b = "Hello, World!"
print(b[2:5])
print(10 + 5)
#boolean
a = 200
b = 33
if b > a:
print("b is greater than a")
else:
print("b is not greater than a")
1.6. Conclusion: In this lab, we covered the basics of Python programming, including printing output, using
comments, and working with variables. We learned that Python allows dynamic typing, meaning that
variables can change types during execution. Moreover, we explored type casting and how to explicitly set a
variable’s type when necessary.By understanding these basic principles, we are now able to build more
complex Python programs in the coming labs.
8
Lab # 02
2.1. Objective: The main objective of this lab is to learn string manipulation techniques in Python, such as
string capitalization, length calculation, centering, justification, finding characters, counting occurrences,
and how to do Unicode encoding.
2.2. Introduction: In this lab, we explored several string manipulation techniques, which are fundamental
concepts for handling text data in Python. These techniques include:
Each of these elements is essential for string manipulation in Python, and mastering them is crucial for
working with text data effectively in programming tasks.
2.3. Code Explanation: This lab was all about the string manipulation in python. The major parts are
broken down below:
2.3.1. String Capitalizing: This converts the first letter of the string to uppercase.
Code:
str ="mehroze"
str.capitalize()
Output:
2.3.2. String Length Calculation: The len() function is used to determine the length of a string, counting
the characters including spaces.
Code:
str="mehroze is a good girl"
print(len(str))
Output:
2.3.3. String Centering: This centers the string and pads it with the character to fit a total width of desired
characters.
Code:
str="mehroze is a good girl"
print(len(str))
9
str.center(24,'h')
Output:
2.3.4. String Justification: This right-justifies the string by padding it with character on the left to fit all to
desired characters.
Code:
str="mehroze"
len(str)
str.rjust(8,'a')
Output:
2.3.5. Counting Occurrences of Characters: This Counts how many times 'e' occurs in the string.
Code:
str="mehroze is my name"
str.count('e',0,22)
Output:
2.3.6. Check String Properties: Check if strings start or end with specific characters.
Code:
str1="i like darkness"
print(str1.startswith("i",0,100))
print(str1.endswith("like",0,100))
Output:
2.3.7. String Swap Case: This converts the strings to title case and swap case between upper and lower.
Code:
str="i am MEHROZE"
str1="i am mehroze"
print(str.islower())
print(str1.islower())
Output:
# print string
print('The string is:', string)
# print result
print('The encoded version is:', string_utf)
Output:
str="mehroze"
len(str)
str.rjust(8,'a')
str="mehroze is my name"
str.count('e',0,22)
str="Mehroze"
str.count('h',0,7)
str="mehroze\tjaved"
str.expandtabs(100)
11
str="mehroze11 is a student"
print(str.isalnum())
str1="haven"
print(str1.isalnum())
str="mehrozeismyid"
print(str.isalpha())
str="mehroze"
print(str.isalpha())
str="mehroze57"
print(str.isdigit())
str="2345"
print(str.isdigit())
str="i am MEHROZE"
str1="i am mehroze"
print(str.islower())
print(str1.islower())
str=" "
str1="byeeeee"
print(str.isspace())
print(str1.isspace())
str="This Is Excellent"
str1="This is excellent"
print(str.istitle())
print(str1.istitle())
s = "_";
seq = ("I", "AM", "Mehroze");
print( s.join( seq ))
str="mehroze is calm"
len(str)
str="mehroze"
len(str)
str.ljust(8,'h')
str="I Am MeHrOze"
12
print(str.lower())
print(str.upper())
str="i am amina"
print(max(str))
str="i am amina"
print(min(str))
str="i am amina"
print(str.split('-',3))
print(str.split('a',2))
str="i am amina"
str.title()
str="i am amina"
str1="I AM AMINA"
print(str.swapcase())
print(str1.swapcase())
str="amina"
str.zfill(10)
# unicode string
string = 'amina!'
# print string
print('The string is:', string)
# print result
print('The encoded version is:', string_utf)
# unicode string
13
string = 'pythön!'
# print string
print('The string is:', string)
# print result
print('The encoded version is:', string_utf)
# unicode string
string = 'anaconda!'
# print string
print('The string is:', string)
# print result
print('The encoded version is:', string_utf)
2.5. Conclusion: This lab explored a wide range of string manipulation techniques in Python. By using
methods such as capitalization, length calculation, justification, encoding, and case conversion. These skills
are crucial for text processing tasks in various applications of AI and software development.
14
Lab # 03
elif Marks>=850:
print(name+" Congratulations Your admission is done in Electrical engineering")
elif Marks>=800:
print(name+" Congratulations Your admission is done in Civil engineering")
elif Marks>=750:
print(name+" Congratulations Your admission is done in Computer Science and engineering")
elif Marks>=700:
print(name+" Congratulations Your admission is done in Biomediacal engineering")
elif Marks<700:
15
print(name+" Sorry your Marks are too low to get admission in any department")
for x in "Engineering":
print(x)
for x in "cs":
print(x)
16
depart = ["CS", "Electrical", "Mechanical","Civil"]
for x in depart:
print(x)
if x=="CS":
break
if x=="Mechanical":
continue
print(x)
if x=="CS":
continue
print(x)
for x in adj:
for y in fruits:
print(x, y)
for x in name:
for y in fruits:
print(x, y)
i=1
while i <= 5:
print(i)
i +=1
i=1
while i < 6:
print(i)
if i == 4:
break
i += 1
i=0
while i < 6:
i += 1
if i == 3:
continue
print(i)
i=1
17
while i < 6:
print(i)
i += 1
else:
print("i is no longer less than 6")
def my_function():
print("Function is called")
my_function()
def my_class():
print("class is called")
my_class()
def reply(str):
if (name=='Mehroze'):
print('welcome Sir')
elif (name=="Javed"):
print("Boss is waiting for you.")
else:
print("You may come tomorrow.")
name = str(input("please tell your name :"))
reply(name)
def my_function(fname):
print(fname + " is a good girl")
my_function("ABC")
my_function("EFG")
my_function("HIJ")
my_function("Mehroze", "scholar")
def find_near(*country):
print("The nearest country is " + country[2])
def find_near(*Mehroze):
print("Mehroze is " + Mehroze[1])
my_function("Pakistan")
my_function("India")
my_function()
my_function("Turkey")
"""
Conclusion:This lab enhanced the understanding of key programming concepts, including conditionals,
loops, and functions, which are critical for solving more complex problems in AI and software development.
Through practical exercises, students gained experience in making decisions programmatically, handling
lists, and creating reusable functions. These skills are fundamental for progressing into more advanced
topics in AI and automation, ensuring students are well-prepared for future projects.
19
Lab # 04
4.2. Code:
print("******UET FSD*******")
print("\n Welcome to Aggregate System")
print("\nYou can have idea about your admission in diffetrent departments of University")
name= str(input("\nPlease Enter Your Name "))
Marks= int(input("Plaease Enter Your Marks "))
Marks=int(Marks)
if Marks>=900:
print(name+" Congratulations Your admission is done in Computer Science.")
elif Marks>=850:
print(name+" Congratulations Your admission is done in Electrical Engineering")
elif Marks>=800:
print(name+" Congratulations Your admission is done in Chemical Engineering.")
elif Marks>=750:
print(name+" Congratulations Your admission is done in Textile Engineering.")
elif Marks>=700:
print(name+" Congratulations Your admission is done in Chemistry")
elif Marks<700:
print(name+" Sorry your Marks are too low to get admission in any department")
mylist[:2]
mylist[1:5]
mylist[2:]
20
mylist[3] = 'Mehroze' #change value in list
mylist
mylist2 = [1,2,3,44,4]
mylist.append(mylist2)
mylist
#for loops
#nested loop
for x in range(3):
for y in range(3):
print(x,y)
#while loop
x =1
while x < 6:
print(x)
x += 1
# functions
def my_function():
print("Hello from a function")
def my_function(fname):
print(fname + "Javed")
21
my_function("Mehroze")
my_function("Alina")
my_function("Amna") #func with arguments
4.3. Conclusion: This lab provided hands-on experience with Python's foundational elements such as
conditionals, loops, lists, and functions.
22
Lab # 05
5.1. Objective: The lab aims to predict student performance using decision tree classifiers, focusing on data
pre-processing, model training with Gini Index and Entropy, and evaluating performance. Students will also
learn to visualize and interpret decision trees, emphasizing key machine learning processes like data
preparation and model evaluation.
5.2. Introduction: This lab applies decision tree classifiers to predict student performance using features
like study hours, attendance, previous grades, and socioeconomic background. It covers key machine
learning concepts such as data-set preparation, feature encoding, and model evaluation through metrics like
accuracy and confusion matrices. The performance of two decision tree models, based on Gini Index and
Entropy, is trained and compared.
5.3. Code:
return balance_data
23
return balance_data
# Splitting the dataset into training and testing sets (70% training, 30% testing)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=100)
# Performing training
clf_gini.fit(X_train, y_train)
return clf_gini
# Performing training
clf_entropy.fit(X_train, y_train)
return clf_entropy
# Main function
24
if __name__ == "__main__":
# Import the dataset
data = importdata()
5.4. Conclusion: Through this lab, students gained practical knowledge of building and evaluating decision
tree classifiers using Python. They learned how to preprocess data, split it into training and testing sets, and
train models using different criteria. Visualizing the decision trees allowed students to understand how the
model makes decisions. This exercise emphasized the importance of feature selection and model evaluation
in machine learning tasks, equipping students with essential skills for future projects.
26
Lab # 06
6.1. Objective: The objective of this lab is to implement and compare two fundamental graph traversal
algorithms: Depth-First Search (DFS) and Breadth-First Search (BFS). By utilizing these algorithms, we aim
to explore the structure of a graph and demonstrate how each algorithm traverses nodes using different
strategies. Additionally, the lab seeks to reinforce the understanding of stacks and queues as data structures
used in these algorithms.
6.2. Introduction:Graph traversal algorithms are essential for exploring the nodes and edges of a graph data
structure. Two primary methods for graph traversal are Depth-First Search (DFS) and Breadth-First Search
(BFS). DFS explores as far as possible along a branch before backtracking, utilizing a stack data structure,
which can be implemented either explicitly or through recursion. Conversely, BFS explores all neighbors at
the present depth before moving on to nodes at the next depth level, relying on a queue data structure. This
lab involves implementing both algorithms to traverse a simple undirected graph defined by an adjacency
list. By comparing the outputs of DFS and BFS, we gain insights into their respective behaviors and use
cases.
graph = {
0: [1, 2],
1: [2, 0],
2: [1, 0, 3, 4],
3: [2],
4: [2]
}
start_node = 1
stack = [start_node]
visited = set()
# DFS
while stack:
node = stack.pop()
6.4. Output:
27
6.5. Code of BFS:
start_node = 1
queue = deque([start_node])
visited = set()
# BFS
while queue:
node = queue.popleft()
6.6. Output:
6.7. Conclusion: In this lab, we successfully implemented Depth-First Search (DFS) and Breadth-First
Search (BFS) to traverse a graph. The results demonstrated the distinct approaches of both algorithms: DFS
delves deep into the graph structure before exploring other branches, while BFS systematically explores all
neighboring nodes at the current level before proceeding. Understanding these traversal techniques is
fundamental for tackling more complex graph-related problems, as they form the basis for various
applications, including pathfinding, web crawling, and social network analysis. The choice between DFS
and BFS depends on the specific requirements of the problem, including memory efficiency and the
structure of the graph being traversed.
28
Lab # 07
7.1. Objective: The objective of this lab is to implement the Uniform Cost Search (UCS) algorithm to find
the least-cost path between a start node and a goal node in a weighted graph. By employing a priority queue
to explore nodes based on cumulative cost, this algorithm aims to provide an efficient method for
pathfinding in scenarios where the cost of traversing edges varies.
7.2. Introduction: Uniform Cost Search (UCS) is a variant of Dijkstra’s algorithm designed to find the
least-cost path in a weighted graph. It explores nodes by prioritizing those with the lowest cumulative cost,
using a priority queue for efficient retrieval. This lab implements UCS on a sample graph represented by an
adjacency list with edge costs, illustrating how the algorithm identifies the optimal path from a start node to
a goal node.
7.3. Code:
import heapq
while priority_queue:
current_cost, current_node = heapq.heappop(priority_queue)
if current_node == goal:
path = []
while current_node is not None:
path.append(current_node)
current_node = parents[current_node]
return path[::-1], current_cost
if __name__ == "__main__":
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'D': 2, 'E': 5},
'C': {'A': 4, 'F': 3},
'D': {'B': 2, 'F': 1},
'E': {'B': 5, 'F': 2},
'F': {'C': 3, 'D': 1, 'E': 2},
}
29
start_node = 'A'
goal_node = 'F'
7.4. Output:
7.5. Conclusion: In this lab, we successfully implemented the Uniform Cost Search algorithm to identify the
least-cost path in a weighted graph. The results illustrated UCS's capability to efficiently explore the graph
by expanding nodes based on the cumulative cost of reaching them. We found that the path from the start
node 'A' to the goal node 'F' is optimal, with a total cost determined by the weights of the edges traversed.
This algorithm is particularly useful in real-world applications where costs vary, such as in transportation
and network routing.
30
Lab # 08
8.1. Objective:The objective of this lab is to understand and implement the Iterative Deepening Search
(IDS) algorithm in Python. IDS is a graph traversal and search technique that combines the benefits of
Depth-First search (DFS) and Breadth-First Search (BFS) to explore a graph efficiently while avoiding the
memory overhead of BFS. The goal of this lab is to enable students to apply IDS to find a path from a
starting node to a goal node within a depth-limited framework.
8.2. Introduction:Iterative Deepening Search (IDS) is a search algorithm that incrementally increases the
search depth until the goal node is found. It is particularly useful in scenarios where the depth of the goal
node is unknown and there is a need to avoid the high memory usage of BFS. IDS performs a series of
Depth-Limited Searches (DLS) with increasing depth limits, exploring the graph progressively deeper until
it reaches the goal. This approach is memory-efficient like DFS and guarantees finding the shortest path in
terms of depth like BFS. In this lab, we implement IDS by building two functions:
iterative_deepening_search, which manages depth limits, and depth_limited_search, which performs the
depth-limited exploration of nodes.
8.3. Code:
8.4. Output:
8.5. Conclusion: In this lab, we successfully implemented the Iterative Deepening Search (IDS) algorithm,
demonstrating how to find a path from a start node to a goal node in a graph with minimal memory usage.
IDS combines the advantages of DFS and BFS, exploring each depth level thoroughly before moving deeper,
which ensures finding the shortest path in terms of depth. This approach is ideal for large search spaces with
unknown goal depths. Through this lab, we gained practical insight into recursive depth-limited search and
iterative deepening strategies, both of which are foundational for developing efficient search algorithms in
AI.
32
Lab # 10
10.1. Objective:The objective of this lab is to understand and implement the Best First Search (BFS)
algorithm in Python, a heuristic-based graph traversal technique that combines the advantages of Breadth-
First Search and Greedy algorithms.
10.2. Introduction:The Best First Search algorithm is a graph traversal technique that explores nodes
based on a specific heuristic function, such as the shortest distance to the goal node or the lowest cost.
10.3. Code:
from queue import PriorityQueue
v = 14
graph = [[] for i in range(v)]
for v, c in graph[u]:
if visited[v] == False:
visited[v] = True
pq.put((c, v))
print()
addedge(0, 1, 3)
addedge(0, 2, 6)
addedge(0, 3, 5)
addedge(1, 4, 9)
addedge(1, 5, 8)
addedge(2, 6, 12)
addedge(2, 7, 14)
addedge(3, 8, 7)
addedge(8, 9, 5)
addedge(8, 10, 6)
addedge(9, 11, 1)
33
addedge(9, 12, 10)
addedge(9, 13, 2)
source = 0
target = 9
best_first_search(source, target, v)
10.4. Output:
10.5. Conclusion: In this lab, students will learn the working mechanism of the Best First Search algorithm.
Implement the algorithm in Python to solve a graph traversal problem. Also understand the importance of
heuristics in optimizing graph search algorithms an gain insight into real-world applications of BFS in AI
and pathfinding problems.
34
Lab # 11
Lab Topic: A*
11.1. Objective: The objective of this lab is to understand and implement the A (A Star)* algorithm in
Python, a powerful and widely used pathfinding and graph traversal algorithm
Introduction:The A algorithm* is a graph traversal and search algorithm that finds the shortest path from a
start node to a goal node. It uses a cost function to guide its search, defined as:
f(n)=g(n)+h(n)f(n) = g(n) + h(n)f(n)=g(n)+h(n)
11.2. Code:
import math
import heapq
class Cell:
def __init__(self):
self.parent_i = 0
self.parent_j = 0
self.f = float('inf')
self.g = float('inf')
self.h = 0
ROW = 9
COL = 10
for i in path:
print("->", i, end=" ")
print()
def a_star_search(grid, src, dest):
i = src[0]
j = src[1]
cell_details[i][j].f = 0
cell_details[i][j].g = 0
cell_details[i][j].h = 0
cell_details[i][j].parent_i = i
cell_details[i][j].parent_j = j
open_list = []
heapq.heappush(open_list, (0.0, i, j))
found_dest = False
while len(open_list) > 0:
p = heapq.heappop(open_list)
i = p[1]
j = p[2]
closed_list[i][j] = True
directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]
for dir in directions:
new_i = i + dir[0]
new_j = j + dir[1]
cell_details[new_i][new_j].parent_i = i
cell_details[new_i][new_j].parent_j = j
print("The destination cell is found")
trace_path(cell_details, dest)
found_dest = True
return
else:
cell_details[new_i][new_j].f = f_new
cell_details[new_i][new_j].g = g_new
cell_details[new_i][new_j].h = h_new
cell_details[new_i][new_j].parent_i = i
cell_details[new_i][new_j].parent_j = j
if not found_dest:
print("Failed to find the destination cell")
def main():
grid = [
[1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 0, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[0, 0, 1, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 0, 1, 1, 1, 0, 1, 0],
[1, 0, 1, 1, 1, 1, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 0, 0, 1]
]
src = [8, 0]
dest = [0, 0]
if __name__ == "__main__":
37
main()
11.3. Output:
11.4. Conclusion: In this lab, students will gain a comprehensive understanding of the theory and working
mechanism of the A* algorithm, a widely used pathfinding and graph traversal technique. They will
implement the algorithm in Python to solve pathfinding problems on graphs or grids, enhancing their
practical programming skills. Additionally, students will learn the importance of designing effective
heuristic functions to optimize the algorithm's performance. Through this lab, they will also recognize the
versatility of A* in addressing real-world optimization challenges across various domains.
38
Lab # 13
13.1. Objective:The objective of this lab is to understand the Naive Bayes classification algorithm and its
applications in solving problems such as spam detection, sentiment analysis, and other classification tasks.
13.2. Introduction:Naive Bayes is a probabilistic machine learning algorithm based on Bayes' Theorem,
assuming independence among features. Despite its simplicity, it is efficient and effective for text
classification and other domains where independence assumptions are reasonable.
13.3. Code:
# Import necessary libraries
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
39
13.4. Output:
13.5. Conclusion:This lab provided practical insights into the working of the Naive Bayes algorithm. It
highlighted its strengths in handling high-dimensional data and its limitations in scenarios with highly
correlated features.
40
Lab # 14
14.3. Code:
# Import necessary libraries
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
41
14.4.Output:
14.5. Conclusion: This lab provided hands-on experience with Multilayer Perceptrons, showcasing their
ability to model complex relationships in data. By implementing and training an MLP, we explored its
structure, activation functions, and backpropagation, reinforcing its importance in solving real-world AI
problems.
42
Lab # 15
15.2. Introduction:Adversarial search is a fundamental concept in Artificial Intelligence used for decision-
making in competitive environments, such as two-player games. It involves strategies to maximize a player's
advantage while minimizing the opponent's chances of success. Minimax and Alpha-Beta Pruning are key
algorithms that explore game trees to determine optimal moves, making them essential for solving problems
in game theory and AI.
15.3. Code:
def is_moves_left(board):
for row in board:
for cell in row:
if cell == '':
return True
return False
def evaluate(b):
for row in range(6):
for col in range(4):
if b[row][col] == b[row][col+1] == b[row][col+2] == b[row][col+3] == 'o':
return 10
for col in range(7):
for row in range(3):
if b[row][col] == b[row+1][col] == b[row+2][col] == b[row+3][col] == 'o':
return 10
for row in range(3):
for col in range(4):
if b[row][col] == b[row+1][col+1] == b[row+2][col+2] == b[row+3][col+3] == 'o':
return 10
for row in range(3, 6):
for col in range(3):
if b[row][col] == b[row - 1][col+1] == b[row-2][col+2] == b[row - 3][col+3] == 'o':
return 10
return 0
if score == 10:
return score - depth
if not is_moves_left(board):
43
return 0
if is_max:
best_value = -float('inf')
for col in range(7):
for row in range(5, -1, -1):
if board[row][col] == '':
board[row][col] = 'x'
best_val = max(best_val, minimax(
board, depth+1, not is_max))
board[row][col] = ''
break
return best_val
else:
best_value = float('inf')
for col in range(7):
for row in range(5, -1, -1):
if board[row][col] == '':
board[row][col] = 'o'
best_val = max(best_val, minimax(
board, depth+1, not is_max))
board[row][col] = ''
break
return best_val
def find_optimal_move(board):
best_move = None
best_val = -float('inf')
board = [
['x', 'x', 'o', '', '', '', 'x'],
['o', 'o', 'o', 'x', '', '', 'x'],
['x', 'o', '', '', '', '', ''],
['x', 'o', 'o', '', '', '', ''],
['x', 'x', 'x', 'o', '', '', ''],
['o', 'o', 'x', 'o', 'x', '', '']
]
optimal_move = find_optimal_move(board)
if optimal_move:
print("The optimal move for player O to win is:", optimal_move)
44
else:
print("Player O cannot win with the current board confguration")
15.4.Output:
15.5. Conclusion: This lab demonstrated the application of adversarial search in strategic decision-making.
By implementing and analyzing Minimax and Alpha-Beta Pruning, we gained insights into optimizing game
strategies while managing computational resources efficiently.
45