🚀 Welcome back to our AI Engineer Roadmap! ❤️
In the previous post, we learned about Lambda Functions and how they can be used with
Now let's move to another important programming concept: Recursion.
📖 Phase 1: Programming Fundamentals
📌 Topic 13: Recursion
Recursion is a programming technique in which a function calls itself to solve a problem. Instead of solving the entire problem at once, recursion breaks the problem into smaller versions of the same problem.
🧠 Simple Example
Imagine you are standing in front of a staircase and want to reach the top.
Instead of thinking about the entire staircase, you can think:
👉 Reach the next step → repeat → repeat → reach the top.
That's similar to how recursion works.
1. Basic Recursive Function
Here's a simple example:
Output:
Notice what happens:
When
2. Base Case
Every properly designed recursive function needs a base case. The base case tells the function when to stop calling itself.
Example:
Without a base case, the function may continue calling itself indefinitely.
❌ Example Without a Proper Base Case
This function never reaches a stopping condition, eventually causing a
3. Recursive Case
The recursive case is where the function calls itself with a smaller or simpler version of the problem.
Example:
Here:
So a recursive function generally has:
Base Case → Stop
Recursive Case → Continue with a smaller problem
4. Factorial Using Recursion
Factorial is one of the most common examples of recursion.
Mathematically: 5! = 5 × 4 × 3 × 2 × 1
So: 5! = 120
We can define factorial recursively:
Output: 120
Let's see how it works:
5. Fibonacci Using Recursion
Another famous example is the Fibonacci sequence.
0, 1, 1, 2, 3, 5, 8, 13...
Each number is the sum of the previous two numbers.
A simple recursive implementation is:
Output: 8
Because: Fibonacci: 0, 1, 1, 2, 3, 5, 8
6. Recursion and the Call Stack
When a function calls itself, Python keeps track of each function call using the call stack.
For example:
Once the base case is reached, the calls start returning in reverse order. This is why recursion can consume significant memory when there are many recursive calls.
7. Recursion vs Loops
Many problems can be solved using either recursion or loops.
Using a loop:
Using recursion:
Both produce: 120
Which Should You Use?
Use a loop when:
✅ A simple repetition is enough.
Use recursion when:
✅ The problem naturally breaks into smaller versions of itself.
Recursion is particularly useful for problems involving:
Trees, Graph traversal, Divide-and-conquer algorithms, Backtracking, Searching hierarchical structures
Double Tap ❤️ For More
In the previous post, we learned about Lambda Functions and how they can be used with
map(), filter(), and sorted().Now let's move to another important programming concept: Recursion.
📖 Phase 1: Programming Fundamentals
📌 Topic 13: Recursion
Recursion is a programming technique in which a function calls itself to solve a problem. Instead of solving the entire problem at once, recursion breaks the problem into smaller versions of the same problem.
🧠 Simple Example
Imagine you are standing in front of a staircase and want to reach the top.
Instead of thinking about the entire staircase, you can think:
👉 Reach the next step → repeat → repeat → reach the top.
That's similar to how recursion works.
1. Basic Recursive Function
Here's a simple example:
def countdown(n):
if n == 0:
return
print(n)
countdown(n - 1)
countdown(5)
Output:
5
4
3
2
1
Notice what happens:
countdown(5)
↓
countdown(4)
↓
countdown(3)
↓
countdown(2)
↓
countdown(1)
↓
countdown(0)
When
n becomes 0, the function stops.2. Base Case
Every properly designed recursive function needs a base case. The base case tells the function when to stop calling itself.
Example:
if n == 0:
return
Without a base case, the function may continue calling itself indefinitely.
❌ Example Without a Proper Base Case
def count(n):
print(n)
count(n - 1)
This function never reaches a stopping condition, eventually causing a
RecursionError.3. Recursive Case
The recursive case is where the function calls itself with a smaller or simpler version of the problem.
Example:
def countdown(n):
if n == 0:
return
print(n)
countdown(n - 1)
Here:
countdown(n - 1) is the recursive case.So a recursive function generally has:
Base Case → Stop
Recursive Case → Continue with a smaller problem
4. Factorial Using Recursion
Factorial is one of the most common examples of recursion.
Mathematically: 5! = 5 × 4 × 3 × 2 × 1
So: 5! = 120
We can define factorial recursively:
def factorial(n):
if n == 0 or n == 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
Output: 120
Let's see how it works:
factorial(5)
= 5 × factorial(4)
= 5 × 4 × factorial(3)
= 5 × 4 × 3 × factorial(2)
= 5 × 4 × 3 × 2 × factorial(1)
= 5 × 4 × 3 × 2 × 1
= 120
5. Fibonacci Using Recursion
Another famous example is the Fibonacci sequence.
0, 1, 1, 2, 3, 5, 8, 13...
Each number is the sum of the previous two numbers.
A simple recursive implementation is:
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(6))
Output: 8
Because: Fibonacci: 0, 1, 1, 2, 3, 5, 8
6. Recursion and the Call Stack
When a function calls itself, Python keeps track of each function call using the call stack.
For example:
factorial(3) creates calls like:factorial(3)
↓
factorial(2)
↓
factorial(1)
Once the base case is reached, the calls start returning in reverse order. This is why recursion can consume significant memory when there are many recursive calls.
7. Recursion vs Loops
Many problems can be solved using either recursion or loops.
Using a loop:
factorial = 1
for i in range(1, 6):
factorial *= i
print(factorial)
Using recursion:
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
Both produce: 120
Which Should You Use?
Use a loop when:
✅ A simple repetition is enough.
Use recursion when:
✅ The problem naturally breaks into smaller versions of itself.
Recursion is particularly useful for problems involving:
Trees, Graph traversal, Divide-and-conquer algorithms, Backtracking, Searching hierarchical structures
Double Tap ❤️ For More
❤9
🚀 Welcome back to our AI Engineer Roadmap! ❤️
In the previous post, we learned about Recursion and how a function can call itself to solve smaller versions of a problem. Now let's move to one of the most commonly used data types in Python.
📖 Phase 1: Programming Fundamentals
📌 Topic 14: Strings
A String is a sequence of characters used to represent text. Names, sentences, email addresses, file paths, messages, and many other types of textual information are represented using strings.
Example:
Here, both "Alice" and "Welcome to Python!" are strings.
Why Do We Need Strings?
Strings are essential for:
• Storing text
• Processing user input
• Working with names and messages
• Reading and processing files
• Handling data from APIs
• Processing text for AI and NLP applications
1. Creating Strings
Strings can be created using single or double quotes.
Both are valid.
You can also use triple quotes for multi-line strings:
2. Accessing Characters
Every character in a string has an index. Python uses zero-based indexing, meaning the first character is at index 0.
The indexes look like this:
3. Negative Indexing
Python also supports negative indexes. The last character has index -1.
Indexing from the end looks like:
4. String Slicing
Slicing allows you to extract part of a string.
Syntax:
Example:
Because indexes 0, 1, and 2 are included, but index 3 is excluded.
Slicing with a Step
5. String Length
Use the
Spaces are also counted as characters.
6. Important String Methods
upper() — Converts text to uppercase.
lower() — Converts text to lowercase.
strip() — Removes leading and trailing whitespace.
replace() — Replaces part of a string.
split() — Splits a string into a list.
join() — Combines elements into a string.
7. Checking Content
You can check whether a substring exists using
8. Strings Are Immutable
One of the most important things to understand about Python strings is that they are immutable. This means you cannot directly change an individual character.
❌ This is not allowed:
In the previous post, we learned about Recursion and how a function can call itself to solve smaller versions of a problem. Now let's move to one of the most commonly used data types in Python.
📖 Phase 1: Programming Fundamentals
📌 Topic 14: Strings
A String is a sequence of characters used to represent text. Names, sentences, email addresses, file paths, messages, and many other types of textual information are represented using strings.
Example:
name = "Alice"
message = "Welcome to Python!"
Here, both "Alice" and "Welcome to Python!" are strings.
Why Do We Need Strings?
Strings are essential for:
• Storing text
• Processing user input
• Working with names and messages
• Reading and processing files
• Handling data from APIs
• Processing text for AI and NLP applications
1. Creating Strings
Strings can be created using single or double quotes.
name = "Alice"
city = 'Mumbai'
Both are valid.
You can also use triple quotes for multi-line strings:
message = """This is
a multi-line
string."""
2. Accessing Characters
Every character in a string has an index. Python uses zero-based indexing, meaning the first character is at index 0.
word = "Python"
print(word[0]) # P
print(word[1]) # y
print(word[5]) # n
The indexes look like this:
P y t h o n
0 1 2 3 4 5
3. Negative Indexing
Python also supports negative indexes. The last character has index -1.
word = "Python"
print(word[-1]) # n
print(word[-2]) # o
Indexing from the end looks like:
P y t h o n
-6 -5 -4 -3 -2 -1
4. String Slicing
Slicing allows you to extract part of a string.
Syntax:
string[start:end] — The end index is not included.Example:
word = "Python"
print(word[0:3]) # Pyt
Because indexes 0, 1, and 2 are included, but index 3 is excluded.
Slicing with a Step
word = "Python"
print(word[0:6:2]) # Pto
5. String Length
Use the
len() function to find the number of characters.text = "Python"
print(len(text)) # 6
Spaces are also counted as characters.
6. Important String Methods
upper() — Converts text to uppercase.
text = "hello"
print(text.upper()) # HELLO
lower() — Converts text to lowercase.
text = "HELLO"
print(text.lower()) # hello
strip() — Removes leading and trailing whitespace.
text = " Python "
print(text.strip()) # Python
replace() — Replaces part of a string.
text = "I like Java"
print(text.replace("Java", "Python")) # I like Python
split() — Splits a string into a list.
text = "Python is powerful"
words = text.split()
print(words) # ['Python', 'is', 'powerful']
join() — Combines elements into a string.
words = ["Python", "is", "powerful"]
text = " ".join(words)
print(text) # Python is powerful
7. Checking Content
You can check whether a substring exists using
in.text = "Python is easy"
print("Python" in text) # True
print("Java" not in text) # True
8. Strings Are Immutable
One of the most important things to understand about Python strings is that they are immutable. This means you cannot directly change an individual character.
❌ This is not allowed:
❤3
word = "Python"
word[0] = "J"
Instead, you create a new string:
word = "Python"
word = "J" + word[1:]
print(word) # Jython
9. String Concatenation
You can combine strings using
+.first_name = "Alice"
last_name = "Smith"
full_name = first_name + " " + last_name
print(full_name) # Alice Smith
10. f-Strings
f-strings provide a convenient way to insert variables into strings.
name = "Alice"
age = 25
message = f"My name is {name} and I am {age} years old."
print(message) # My name is Alice and I am 25 years old.
f-strings are widely used because they make formatted text easier to read.
11. Strings in AI and NLP
Strings become especially important when you move into Artificial Intelligence. AI systems frequently work with text such as: User questions, Chat messages, Documents, Reviews, Emails, Search queries, AI prompts.
Before text can be processed by many NLP and LLM systems, it often needs to be cleaned, transformed, tokenized, or converted into numerical representations.
For example:
text = " AI is AMAZING! "
cleaned_text = text.strip().lower()
print(cleaned_text) # ai is amazing!
This is a very simple example of text preprocessing.
Common Beginner Mistakes
❌ Forgetting that indexing starts at 0.
❌ Assuming the end index in slicing is included.
❌ Trying to modify an individual character.
❌ Confusing
split() with join().❌ Forgetting that spaces count toward string length.
Best Practices
✅ Use meaningful variable names.
✅ Use appropriate string methods instead of manually processing characters when possible.
✅ Use f-strings for readable string formatting.
✅ Remember that strings are immutable.
Key Takeaways
• A string is a sequence of characters.
• Python uses zero-based indexing.
• Negative indexing starts from -1.
• Slicing extracts portions of a string.
•
len() returns the number of characters. • Strings are immutable.
• Methods such as
upper(), lower(), strip(), split(), and replace() are extremely useful. • Strings are fundamental to NLP, LLMs, and AI applications.
➡️ Double Tap ❤️ For More
❤13👏2