PRINCIPLES OF PROGRAMING II (PYTHON)
(CSC241 CUSTECH)
WEEK 1: Review of Programming I & Setup (with Examples)
Objectives Recap
By the end of this week, students should:
Recall Python basics
Set up Python, VS Code, and Git
Understand clean code practices
Build simple projects like a calculator and guessing game
Use GitHub to save and submit their work
Review of Key Python Concepts – with Examples
1. Variables & Data Types
Explanation:
A variable stores a piece of information. Variables are like labeled boxes storing data.
A data type describes what kind of data is stored.
Examples:
# Integer
age = 25
# Float
height = 5.9
# String
name = "Chinwe"
# Boolean
is_student = True
# Type conversion
print("My age is " + str(age)) # Converts int to string
print(int("123") + 1) # Converts string to int
2. Control Structures (if, for, while)
Used to control how your program runs:
if, elif, else — Make decisions.
for loops — Repeat a block a certain number of times.
while loops — Repeat as long as a condition is true.
if, elif, else – Example:
score = 75
if score >= 70:
print("You passed with Distinction")
elif score >= 50:
print("You passed")
else:
print("You failed")
for loop – Example:
for i in range(3):
print("Hello", i)
Output:
Hello 0
Hello 1
Hello 2
while loop – Example:
x = 0
while x < 3:
print("Counting", x)
x += 1
3. Functions
Explanation:
Functions help break down code into reusable chunks. Functions let us write reusable
code blocks.
Example:
def greet(name):
return f"Hello, {name}!"
print(greet("Ada"))
Output:
Hello, Ada!
4. Lists and Basic Operations
Explanation:
Store multiple values in one variable. A list stores multiple items.
Example:
fruits = ["apple", "banana"]
# Add item
[Link]("orange")
# Access second item
print(fruits[1]) # Output: banana
# Remove item
[Link]("banana")
# Loop through list
for fruit in fruits:
print(fruit)
Environment Setup (Step-by-step)
Tools You Need
Python 3.x – install from [Link]
VS Code – install from [Link]
Git – install from [Link]
GitHub Account – sign up at [Link]
Git Setup Commands (Run in Terminal):
git config --global [Link] "Your Name"
git config --global [Link] "you@[Link]"
Coding Style – Clean Code
Good Example:
def calculate_area(length, width):
"""Returns the area of a rectangle."""
return length * width
Bad Example:
def ca(a, b):
return a*b
Why?
Descriptive names (calculate_area instead of ca)
Clear documentation (docstring)
Easier to understand and maintain
Follow the PEP8 style guide.
Lab Exercises
Task 1: Calculator Function
Instruction:
Write a function that performs addition, subtraction, multiplication, or division.
Example Code:
def calculate(num1, num2, operator):
if operator == '+':
return num1 + num2
elif operator == '-':
return num1 - num2
elif operator == '*':
return num1 * num2
elif operator == '/':
if num2 == 0:
return "Error: Division by zero"
return num1 / num2
else:
return "Invalid operator"
# Example usage
print(calculate(10, 5, '+')) # Output: 15
Task 2: Number Guessing Game
Instruction:
Create a game where the computer chooses a number and the user keeps guessing
until they get it right.
Example Code:
import random
number = [Link](1, 10)
guess = 0
while guess != number:
guess = int(input("Guess a number between 1 and 10:
"))
if guess < number:
print("Too low!")
elif guess > number:
print("Too high!")
print("Correct! The number was", number)
Coding Challenge – FizzBuzz
Instruction:
Write a program to print numbers from 1 to 50, but:
If divisible by 3 → print "Fizz"
If divisible by 5 → print "Buzz"
If divisible by both → print "FizzBuzz"
Example Code:
def fizz_buzz():
for i in range(1, 51):
if i % 3 == 0 and i % 5 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
fizz_buzz()
GitHub Repo Structure – Explained
Structure your folder like this:
principles-of-programming-ii/
├── week1/
│ ├── lab/ ← For in-class activities
│ │ ├── [Link]
│ │ └── guessing_game.py
│ ├── challenge/ ← For homework/assignments
│ │ └── [Link]
│ └── [Link] ← Your summary notes
└── [Link] ← General course
description
Functions – Scope, Arguments, Return Values, and Recursion
Objectives
By the end of this week, students should be able to:
Define and use functions in Python
Understand local vs global scope
Pass different types of arguments to functions
Return single or multiple values from a function
Understand and write basic recursive functions
1. Function Definition and Calling
Explanation:
A function is a reusable block of code. It must be defined before it is called.
Example:
def say_hello():
print("Hello, welcome to class!")
say_hello() # Output: Hello, welcome to class!
2. Function Parameters and Arguments
Explanation:
Parameters are placeholders used in function definition.
Arguments are the real values you pass when calling the function.
Example:
def greet_user(name):
print(f"Hello, {name}!")
greet_user("Tunde") # Output: Hello, Tunde!
3. Return Values
Explanation:
Functions can send back values using the return keyword.
Example:
def add_numbers(a, b):
return a + b
result = add_numbers(3, 4)
print(result) # Output: 7
Multiple return values:
def get_name_and_age():
return "Blessing", 22
name, age = get_name_and_age()
print(name) # Output: Blessing
print(age) # Output: 22
4. Scope – Local vs Global Variables
Explanation:
Local variables are defined inside a function and only work there.
Global variables are defined outside functions and can be accessed anywhere.
Example:
name = "Global Name" # Global
def print_name():
name = "Local Name" # Local
print(name)
print_name() # Output: Local Name
print(name) # Output: Global Name
Using global:
count = 0
def increment():
global count
count += 1
increment()
print(count) # Output: 1
5. Recursive Functions
Explanation:
A function that calls itself is called recursive.
Example: Factorial
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print(factorial(5)) # Output: 120
Lab Exercises
Task 1: Celsius to Fahrenheit Converter
Write a function that takes temperature in Celsius and returns Fahrenheit.
def convert_to_fahrenheit(celsius):
return (celsius * 9/5) + 32
print(convert_to_fahrenheit(25)) # Output: 77.0
Task 2: Student Grade Calculator
Write a function that takes a score and returns the grade.
def grade(score):
if score >= 70:
return "A"
elif score >= 60:
return "B"
elif score >= 50:
return "C"
elif score >= 40:
return "D"
else:
return "F"
print(grade(73)) # Output: A
Coding Challenge: Fibonacci Sequence (Recursive)
Write a recursive function that returns the nth Fibonacci number.
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
for i in range(10):
print(fibonacci(i), end=' ')
Output:
0 1 1 2 3 5 8 13 21 34
GitHub Repo Structure (Week 2)
principles-of-programming-ii/
├── week2/
│ ├── lab/
│ │ ├── temperature_converter.py
│ │ └── student_grading.py
│ ├── challenge/
│ │ └── [Link]
│ └── [Link]
In [Link], you should summarize:
Definitions and examples of function basics
How recursion works with examples
What local/global scope means
WEEK 2: Classes, Objects, and Constructors in Python
Objectives
By the end of this week, students should be able to:
Understand what classes and objects are
Define and use classes
Create and use constructors (__init__)
Instantiate objects from classes
Access attributes and call methods from objects
1. What Is a Class?
Explanation:
A class is a blueprint or template for creating objects. It defines attributes (data) and
methods (functions) that an object can have.
2. Creating a Simple Class and Object
class Dog:
def bark(self):
print("Woof! Woof!")
# Creating an object of the class
my_dog = Dog()
# Calling a method using the object
my_dog.bark()
Output:
Woof! Woof!
3. Using the __init__ Constructor
Explanation:
The __init__ method is a constructor used to initialize the object's attributes
when it is created.
class Dog:
def __init__(self, name, age):
[Link] = name
[Link] = age
def describe(self):
print(f"My dog {[Link]} is {[Link]} years
old.")
my_dog = Dog("Bingo", 3)
my_dog.describe()
Output:
My dog Bingo is 3 years old.
4. Instance Attributes vs Class Attributes
Instance Attributes: Defined inside __init__ with self and are unique to each
object.
Class Attributes: Shared by all instances of the class.
class Student:
school = "Greenfield High" # Class attribute
def __init__(self, name):
[Link] = name # Instance attribute
s1 = Student("Ada")
s2 = Student("Tunde")
print([Link]) # Output: Ada
print([Link]) # Output: Greenfield High
5. Adding Behavior with Methods
class Circle:
def __init__(self, radius):
[Link] = radius
def area(self):
return 3.14 * [Link] ** 2
c = Circle(5)
print([Link]()) # Output: 78.5
Lab Exercises
Task 1: Class – Car
Instruction:
Create a Car class that has:
Attributes: make, model, year
Method: display_info() to print car details
class Car:
def __init__(self, make, model, year):
[Link] = make
[Link] = model
[Link] = year
def display_info(self):
print(f"{[Link]} {[Link]} {[Link]}")
car1 = Car("Toyota", "Camry", 2020)
car1.display_info() # Output: 2020 Toyota Camry
Task 2: Class – BankAccount
Instruction:
Create a BankAccount class with:
name, balance
deposit(amount), withdraw(amount)
class BankAccount:
def __init__(self, name, balance):
[Link] = name
[Link] = balance
def deposit(self, amount):
[Link] += amount
def withdraw(self, amount):
if amount > [Link]:
print("Insufficient funds")
else:
[Link] -= amount
def check_balance(self):
print(f"{[Link]}'s balance: {[Link]}")
account = BankAccount("Lekan", 5000)
[Link](1000)
[Link](2000)
account.check_balance() # Output: Lekan's balance: 4000
Coding Challenge: Student Record System
Challenge:
Create a Student class with:
Attributes: name, department, level
Method: promote() increases level
Method: display() prints all student info
class Student:
def __init__(self, name, department, level):
[Link] = name
[Link] = department
[Link] = level
def promote(self):
[Link] += 1
def display(self):
print(f"Name: {[Link]}, Dept:
{[Link]}, Level: {[Link]}")
s = Student("Favour", "Computer Science", 200)
[Link]()
[Link]() # Output: Name: Favour, Dept: Computer
Science, Level: 201
GitHub Repo Structure (Week 2)
principles-of-programming-ii/
├── week2/
│ ├── lab/
│ │ ├── car_class.py
│ │ ├── bank_account.py
│ ├── challenge/
│ │ └── student_record.py
│ └── [Link]
WEEK 3: Object-Oriented Programming II – Inheritance & Polymorphism
Objectives
By the end of this week, students should be able to:
Understand what inheritance is and why it's used
Create child classes that inherit from a parent class
Override methods in child classes
Understand and implement polymorphism in Python
Use the super() function to access parent class methods
Core Concepts with Clear Examples
1. What is Inheritance?
Explanation:
Inheritance allows one class (child) to inherit the attributes and methods of another
class (parent), promoting code reuse.
2. Basic Inheritance
class Animal:
def speak(self):
print("Animal speaks")
class Dog(Animal):
pass
dog = Dog()
[Link]() # Output: Animal speaks
Here, Dog inherited the speak() method from Animal.
3. Adding New Methods in Child Class
class Dog(Animal):
def bark(self):
print("Woof!")
dog = Dog()
[Link]() # Inherited
[Link]() # Own method
4. Overriding Parent Methods
Explanation:
You can change the behavior of a method in a child class by overriding it.
class Animal:
def speak(self):
print("Animal speaks")
class Cat(Animal):
def speak(self):
print("Meow!")
cat = Cat()
[Link]() # Output: Meow!
5. Using super() to Call Parent Method
class Bird:
def __init__(self, name):
[Link] = name
def info(self):
print(f"Bird name: {[Link]}")
class Parrot(Bird):
def __init__(self, name, color):
super().__init__(name) # Call Bird's __init__
[Link] = color
def info(self):
super().info() # Call Bird's info
print(f"Color: {[Link]}")
p = Parrot("Polly", "Green")
[Link]()
Output:
Bird name: Polly
Color: Green
6. Polymorphism
Polymorphism means many forms—when different classes implement the same
method but with different behavior.
class Bird:
def make_sound(self):
print("Some bird sound")
class Sparrow(Bird):
def make_sound(self):
print("Chirp!")
class Owl(Bird):
def make_sound(self):
print("Hoot!")
def bird_sound(bird):
bird.make_sound()
bird_sound(Sparrow()) # Output: Chirp!
bird_sound(Owl()) # Output: Hoot!
Lab Exercises
Task 1: Person and Employee
Create a base class Person and a derived class Employee.
class Person:
def __init__(self, name):
[Link] = name
def show(self):
print(f"Name: {[Link]}")
class Employee(Person):
def __init__(self, name, salary):
super().__init__(name)
[Link] = salary
def show(self):
super().show()
print(f"Salary: {[Link]}")
e = Employee("Tola", 50000)
[Link]()
Task 2: Shape and Subclasses
Create a class Shape and subclasses Rectangle and Circle. Override area()
method.
class Shape:
def area(self):
return 0
class Rectangle(Shape):
def __init__(self, width, height):
[Link] = width
[Link] = height
def area(self):
return [Link] * [Link]
class Circle(Shape):
def __init__(self, radius):
[Link] = radius
def area(self):
return 3.14 * [Link] ** 2
shapes = [Rectangle(4, 5), Circle(3)]
for s in shapes:
print([Link]())
Output:
20
28.26
Coding Challenge: University System
Create:
Base class UniversityMember with name, id
Subclass Student with level
Subclass Lecturer with department
Override a method describe() in each
class UniversityMember:
def __init__(self, name, id):
[Link] = name
[Link] = id
def describe(self):
print(f"{[Link]} with ID {[Link]}")
class Student(UniversityMember):
def __init__(self, name, id, level):
super().__init__(name, id)
[Link] = level
def describe(self):
print(f"Student: {[Link]}, Level: {[Link]}, ID:
{[Link]}")
class Lecturer(UniversityMember):
def __init__(self, name, id, department):
super().__init__(name, id)
[Link] = department
def describe(self):
print(f"Lecturer: {[Link]}, Dept: {[Link]},
ID: {[Link]}")
members = [
Student("Ola", "ST123", 200),
Lecturer("Dr. Musa", "LC456", "Computer Science")
for member in members:
[Link]()
WEEK 4: Data Structures I – Lists, Stacks, Queues
Objectives Recap
By the end of this week, students should be able to:
Understand how to use Python lists to store and manipulate collections of data.
Implement stacks (LIFO) and queues (FIFO) using Python list and deque.
Choose the right data structure depending on the operation's performance.
Core Concepts with Explanations and Examples
1. Python Lists
A list is a built-in data structure in Python that stores ordered and changeable
(mutable) sequences of items. You can:
Add (append) items
Remove (remove or pop)
Access elements by index (list[0])
Sort or reverse them
Think of a list like a row of seats in a classroom—each seat has a position and you
can rearrange students anytime.
Example:
fruits = ["apple", "banana", "cherry"]
[Link]("orange") # Add to the end
[Link]("banana") # Remove by value
print(fruits[0]) # Access by index: 'apple'
print(fruits) # Final list: ['apple',
'cherry', 'orange']
2. Stacks (Using list)
A stack follows LIFO (Last In, First Out) logic. The last item added is the first one
removed.
Real-world example: A stack of books. The last book placed on top is the first to be
taken.
Python Methods to Use:
append() → push
pop() → pop (remove last item)
Example:
stack = []
[Link]("a")
[Link]("b")
[Link]("c")
print([Link]()) # Removes 'c'
print(stack) # Now: ['a', 'b']
3. Queues (Using list)
A queue follows FIFO (First In, First Out) logic. The first item added is the first
removed.
Real-world example: People waiting in line at an ATM.
Python Methods to Use:
append() → enqueue
pop(0) → dequeue (slow for large lists because of shifting)
Example:
queue = []
[Link]("a")
[Link]("b")
[Link]("c")
print([Link](0)) # Removes 'a'
print(queue) # Now: ['b', 'c']
4. Queues (Using [Link])
Deque (double-ended queue) from Python’s collections module is faster for
queues than regular lists, especially for pop(0) operations.
Why? Lists are slow at the front because they shift elements; deque is optimized for
both ends.
Example:
from collections import deque
queue = deque()
[Link]("a")
[Link]("b")
[Link]("c")
print([Link]()) # Removes 'a'
print(queue) # deque(['b', 'c'])
5. Stacks (Using deque)
deque can also work like a stack, with fast append() and pop() from the right
side.
Example:
from collections import deque
stack = deque()
[Link]("x")
[Link]("y")
print([Link]()) # Removes 'y'
print(stack) # deque(['x'])
Lab Exercises
Task 1: Practice with Lists
Objective: Teach list creation, updating, sorting.
Clarification: Students create a list of names, then manipulate it by adding/removing
and finally sorting.
students = ["Tobi", "Ada", "Chuka"]
[Link]("Bola") # Add Bola
[Link]("Lami") # Add Lami
[Link]("Ada") # Remove Ada
[Link]() # Sort alphabetically
print(students) # ['Bola', 'Chuka',
'Lami', 'Tobi']
Task 3: Bank Queue with deque
Objective: Use deque for real-life queue simulation.
Clarification: Each new customer joins the end of the queue. First to arrive is served
first.
from collections import deque
queue = deque()
[Link]("Customer A")
[Link]("Customer B")
[Link]("Customer C")
print([Link]()) # Customer A
print(queue) # Remaining: deque(['Customer B',
'Customer C'])
Coding Challenge – Task Scheduler
Objective: Practice queues in a real-world setting.
Clarification: Each task is queued. Students simulate completing tasks one-by-one.
from collections import deque
tasks = deque()
[Link]("Send email")
[Link]("Backup database")
[Link]("Update software")
while tasks:
input("Press Enter to do next task...")
print(f"Doing: {[Link]()}")
WEEK 5: Data Structures II – Linked Lists and Custom Stack/Queue
Implementations
Learning Objectives
By the end of this week, students should be able to:
Understand how linked lists differ from Python lists
Implement a singly linked list in Python from scratch
Implement a custom stack and queue using a linked list
Explain the benefits of using linked lists for certain operations
Core Concepts with Examples
1. What Is a Linked List?
A linked list is a sequence of nodes where each node contains:
A value (data)
A reference (link) to the next node
Unlike Python's built-in list:
Memory is not allocated in blocks.
Insertions/deletions at the front are more efficient.
Index-based access (list[2]) is slower.
Real-world analogy: Think of a scavenger hunt—each clue (node) points you to the
next clue.
2. Singly Linked List Implementation
Step-by-step:
1. Define a Node class
2. Define a LinkedList class with insert, delete, and print
methods
1. The Node Class
class Node:
def __init__(self, data):
[Link] = data
[Link] = None
A Node is a basic unit in a linked list.
Each node stores:
data: the actual value (e.g. a number or string).
next: a pointer/reference to the next node in the list (initially None).
Analogy:
Think of a train. Each coach (node) has:
People inside it (data)
A link to the next coach (next)
If there's only one coach, its next is None.
2. The LinkedList Class – Creating the List
class LinkedList:
def __init__(self):
[Link] = None
[Link] is the starting point of the list. It's like saying:
“Where is the first coach in the train?”
When the list is empty, head is None.
3. Method: insert_at_end(self, data)
def insert_at_end(self, data):
new_node = Node(data)
if not [Link]:
[Link] = new_node
return
What’s happening here?
A new node is created with the provided data.
If the list is empty ([Link] is None), we make this new node the first
node.
The function stops here (return) if it was the first node.
current = [Link]
while [Link]:
current = [Link]
[Link] = new_node
What about if the list already has nodes?
We start from the head and walk through the list using current =
[Link].
This continues until we reach the last node (which has next = None).
Then we connect ([Link] = new_node) the new node at the end.
Example:
Inserting “Bola” into this list: Tobi -> Ada -> None
After insertion:
Tobi -> Ada -> Bola -> Non
4. Method: delete(self, key)
def delete(self, key):
current = [Link]
We start from the first node and look for the node containing the value key.
if current and [Link] == key:
[Link] = [Link]
return
Special Case: Deleting the first node
If the first node contains the key, we remove it by:
Moving the head to the next node ([Link] = [Link])
prev = None
while current and [Link] != key:
prev = current
current = [Link]
We walk through the list looking for the key.
We also keep track of the previous node (prev) because we’ll need it to
remove the current one.
if current:
[Link] = [Link]
If we found the node (current) to delete, we unlink it by pointing
[Link] to [Link].
Visual:
Before:
Tobi -> Ada -> Chuka -> None
If we delete "Ada":
Tobi’s next is changed from Ada to Chuka.
Result: Tobi -> Chuka -> None
5. Method: print_list(self)
def print_list(self):
current = [Link]
while current:
print([Link], end=" -> ")
current = [Link]
print("None")
What does this do?
It prints out all the nodes from head to the end.
Uses " -> " to show the link between nodes.
Ends with "None" to indicate the list's end.
Summary: What This Code Does
Component Purpose
Node class Represents one item in the list
LinkedList class Manages a collection of nodes
insert_at_end() Adds a new node to the end
delete(key) Removes the first node with the given value
print_list() Displays the entire list in order
Usage Example:
# Create a linked list instance
my_list = LinkedList()
# Insert some elements
my_list.insert_at_end(10)
my_list.insert_at_end(20)
my_list.insert_at_end(30)
print("After inserting 10, 20, 30:")
my_list.print_list()
# Output: 10 -> 20 -> 30 -> None
# Insert another element
my_list.insert_at_end(40)
print("After inserting 40:")
my_list.print_list()
# Output: 10 -> 20 -> 30 -> 40 -> None
# Delete an element
my_list.delete(20)
print("After deleting 20:")
my_list.print_list()
# Output: 10 -> 30 -> 40 -> None
# Delete head node (10)
my_list.delete(10)
print("After deleting head (10):")
my_list.print_list()
# Output: 30 -> 40 -> None
# Delete a non-existent value
my_list.delete(100)
print("After trying to delete 100 (not in list):")
my_list.print_list()
# Output: 30 -> 40 -> None
3. Custom Stack Using Linked List
What Is a Stack?
A stack is a Last In, First Out (LIFO) data structure.
Think of a stack of plates or books:
You place (push) items on top
You remove (pop) items from the top
class Stack:
def __init__(self):
[Link] = None
__init__() – Constructor
This sets up a new empty stack.
[Link] = None means: “There is no item in the stack yet.”
Push: Add to the Top
def push(self, data):
new_node = Node(data)
new_node.next = [Link]
[Link] = new_node
A new Node is created with the data.
The new node’s next points to the current top of the stack.
Then we make this new node the new top.
Example:
If the stack has:
Top → "Ada" → "Tobi" → None
Now you do: push("Chuka")
New structure:
Top → "Chuka" → "Ada" → "Tobi" → None
Pop: Remove the Top Item
def pop(self):
if [Link] is None:
return "Stack is empty"
popped = [Link]
[Link] = [Link]
return popped
Explanation:
If top is None, the stack is empty.
Otherwise:
Save the current top node’s data.
Move the top to the next node.
Return the saved data.
Example:
Before pop:
Top → "Chuka" → "Ada" → "Tobi"
After pop:
Top → "Ada" → "Tobi"
Returned value: "Chuka"
Peek: Look at the Top Without Removing It
def peek(self):
return [Link] if [Link] else None
Explanation:
This returns the data at the top of the stack.
But it does not remove it.
If the stack is empty, it returns None.
is_empty: Check if Stack Has Any Items
def is_empty(self):
return [Link] is None
Explanation:
Just checks whether there are any items.
If top is None, the stack is empty.
Useful for validation before pop() or peek().
Summary of Methods
Method Purpose
push(data) Add a new item to the top
pop() Remove and return the top item
peek() Look at the top item without removing
is_empty() Check if the stack is empty
Quick Usage Example
s = Stack()
[Link]("Monday")
[Link]("Tuesday")
print([Link]()) # Tuesday
print([Link]()) # Monday
print(s.is_empty()) # False
Real-Life Analogy
Undo feature in a text editor
Browser back button (recent pages are popped when you go back)
4. Custom Queue Using Linked List
What Is a Queue?
A queue is a First-In, First-Out (FIFO) data structure.
Think of it like:
A line at a bank or a bus stop.
The first person to get in line is the first to be served.
class Queue:
def __init__(self):
[Link] = [Link] = None
__init__() – Constructor
Initializes an empty queue.
front: the first item to be dequeued (served).
rear: the last item that was added (newest).
When the queue is empty, both are None.
enqueue(self, data) – Add to the End
def enqueue(self, data):
new_node = Node(data)
if not [Link]:
[Link] = [Link] = new_node
return
[Link] = new_node
[Link] = new_node
Explanation:
1. Create a new node with the given data.
2. If the queue is empty (rear is None):
Set both front and rear to the new node.
3. Otherwise:
Attach the new node to the end of the queue ([Link] =
new_node)
Move rear to point to the new node.
Example:
Before:
Queue is empty
Call:
[Link]("A")
[Link]("B")
[Link]("C")
Now:
front → "A" → "B" → "C" ← rear
dequeue(self) – Remove from the Front
def dequeue(self):
if not [Link]:
return "Queue is empty"
result = [Link]
[Link] = [Link]
if not [Link]:
[Link] = None
return result
Explanation:
1. If the queue is empty (front is None), return a message.
2. Save the data of the front node.
3. Move front to the next node.
4. If the queue becomes empty after removing, set rear to None as well.
Example:
Before:
front → "A" → "B" → "C"
After dequeue():
"A" is removed
Now: front → "B" → "C"
If we keep dequeuing:
"B" → "C" → then both front and rear become None.
is_empty(self) – Check If Queue Is Empty
def is_empty(self):
return [Link] is None
Returns True if no elements are in the queue.
Summary of Methods
Method Purpose
enqueue() Add a new item at the rear (end)
dequeue() Remove and return the item at the front
is_empty() Check if the queue has no items
Real-Life Analogy
Think of people waiting in line for a bus:
The first to arrive is the first to board.
New people join at the rear.
Boarding happens from the front.
Usage Example
q = Queue()
[Link]("Monday")
[Link]("Tuesday")
print([Link]()) # Output: "Monday"
print([Link]()) # Output: "Tuesday"
print([Link]()) # Output: "Queue is empty"