Edited By Siddhartha Reddy Jonnalagadda, PhD
Written By Hundreds of Parents
Introduction
Welcome. This book is for anyone who learns in their own way. Whether you think in pictures, love patterns, or find comfort in clear, sequential steps, this guide is designed for you. It’s a journey into the world of coding that values clarity, patience, and a deep understanding of core concepts over speed. We’ll build a strong foundation, piece by piece, and discover how coding can be a powerful tool for creativity, problem-solving, and building the things you want to see in the world.
There’s no single "right" way to learn. This book is a resource you can use at your own pace. You can read it from start to finish, jump to a topic that interests you, or go back and review a concept as many times as you need. The most important thing is that you feel comfortable and confident throughout the process.
Let’s begin.
Learning to code is like learning any new language. At first, the symbols and rules might feel strange, but with a little practice, they’ll start to make sense. What makes coding so exciting is that it’s a language not just for communicating, but for building. You can use code to create websites, analyze data, design games, or automate repetitive tasks. It’s a tool that gives you the power to bring your ideas to life.
Setting Up Your Toolkit
Before we write our first line of code, we need a place to do it. You don’t need to download or install anything complicated. We’ll use a browser-based tool called Google Colab. It’s a notebook, which is a special kind of document where you can write code and notes together. It’s a perfect place to start because it’s free, easy to use, and requires no setup.
To get started with Google Colab:
Go to colab.research.google.com.
Sign in with your Google account. If you don’t have one, you can create one.
Click "File" > "New notebook." A new, blank notebook will open.
The notebook is made of cells. You can write code in a code cell or regular text in a text cell. To run the code in a cell, just click the play button on the left or press Shift + Enter.
Your First Program
Let’s write a simple program. Don’t worry about understanding it all right now. Just focus on typing it exactly as you see it and watching what happens.
In a code cell, type the following:
print("Hello, world!")
Now, run the cell. You should see the phrase "Hello, world!" appear just below the cell.
You just wrote and ran your first program! The word print is a function, which is a built-in command in the Python language. In this case, it tells the computer to display the text that’s inside the parentheses. The text itself, "Hello, world!", is called a string.
Now, try changing the text inside the parentheses to say something else, like your name or a favorite phrase. Run the cell again to see the new output.
You’ve taken the first step on your coding journey. Feel free to experiment with this simple program before we move on to the next concepts. The best way to learn is to play and explore.
Programming is all about giving instructions to a computer. To do that, we need to be able to talk about the things we’re instructing the computer to work with. These "things" are pieces of information, and in coding, we call them data.
Think of data as different types of materials you might use to build something, like wood, metal, or cloth. Each material has its own properties and is used in a specific way. In the same way, different types of data have their own rules and uses.
Variables: A Label for a Box
Imagine you have a box, and inside that box is a piece of information. A variable is just a label you put on the outside of the box so you can find and use what’s inside later.
Let’s create a variable in Python. In a new code cell, type this:
favorite_color = "blue"
What happened here?
favorite_color is the variable name—the label on our box.
= is the assignment operator. It tells the computer, "Put the thing on my right into the box on my left."
"blue" is the value—the piece of information we’re putting in the box.
Now that we have this box with the label favorite_color, we can use it whenever we want. Try this in another code cell:
print(favorite_color)
The output will be:
blue
The computer looks at the label favorite_color, finds the value "blue" inside the box, and prints it out.
You can also change the value inside the box. Type this and run the cell:
favorite_color = "green"
print(favorite_color)
The output is now:
green
The computer simply put a new value into the favorite_color box, replacing the old one.
Data Types: The Kinds of Information
Every value has a data type. This tells the computer what kind of information it is. We’ll focus on three main types to start:
Strings (str): These are for text. They are always enclosed in quotation marks (either single ' or double ").
Examples: "Hello", 'Python is fun', "2025"
Even if a value looks like a number, if it’s in quotes, the computer sees it as text. "2025" is not a number; it’s a string of characters.
Numbers (int and float):
Integers (int) are for whole numbers without a decimal point.
Examples: 10, 42, -5
Floating-point numbers (float) are for numbers with a decimal point.
Examples: 3.14, 99.9, -0.5
Booleans (bool): These are for values that can only be either True or False. They are always capitalized.
Examples: True, False
Booleans are incredibly useful for making decisions in your code.
You can ask Python what type of data a value is using the type() function.
print(type("hello"))
print(type(10))
print(type(3.14))
print(type(True))
Run this cell to see the output. It will tell you the type of each value.
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
Understanding data types is crucial because they determine what you can do with a value. You can add two numbers together, but you can’t add a number and a string. For example, 5 + "hello" would be a mistake that the computer wouldn’t understand.
In the next chapter, we’ll learn about the symbols and keywords that let us perform actions on these different types of data.
Now that you understand variables and data types, let’s talk about operators. Think of operators as the action words in your code. They tell the computer to do something with your data, like add two numbers together or compare two values.
There are different types of operators, and each one performs a specific kind of action. We’ll start with the most common ones.
The Math Operators (Arithmetic Operators)
These are the operators you learned in school. They perform mathematical calculations on numbers.
Operator
Action
Example
Result
+
Addition
10 + 5
15
-
Subtraction
10 - 5
5
*
Multiplication
10 * 5
50
/
Division
10 / 5
2.0
**
Exponentiation
2 ** 3
8
%
Modulus
10 % 3
1
//
Floor Division
10 // 3
3
Let’s try a few. In a new code cell, type and run this:
cost_of_apples = 2
cost_of_oranges = 3
total_cost = cost_of_apples + cost_of_oranges
print(total_cost)
The output is 5. The + operator added the values of the two variables and stored the result in a new variable called total_cost.
Notice that the division operator (/) always gives you a float (a number with a decimal). If you want the result as a whole number, use floor division (//). The modulus operator (%) is also very useful; it gives you the remainder after a division. For example, 10 % 3 is 1 because 3 goes into 10 three times with a remainder of 1.
You can also use these operators on strings. The + operator will join strings together, an action called concatenation. The * operator will repeat a string.
greeting = "Hello" + " world"
print(greeting)
loud_word = "Wow!" * 3
print(loud_word)
The output will be:
Hello world
Wow!Wow!Wow!
The Comparison Operators
These operators compare two values and give you a Boolean result (True or False). They are the most important tools for making decisions in your code.
Operator
Action
Example
Result
==
Equal to
5 == 5
True
!=
Not equal to
5 != 3
True
>
Greater than
5 > 3
True
<
Less than
5 < 3
False
>=
Greater than or equal to
5 >= 5
True
<=
Less than or equal to
3 <= 5
True
Let’s see them in action:
is_raining = True
is_cold = False
is_it_perfect = is_raining == is_cold
print(is_it_perfect)
The output is False because the two variables are not equal.
The Logic Operators
These operators are used to combine and manipulate Boolean values.
Operator
Action
Example
Result
and
Returns True if both sides are True
True and False
False
or
Returns True if at least one side is True
True or False
True
not
Reverses the Boolean value
not True
False
Using the variables from the previous example:
should_bring_coat = is_raining or is_cold
print(should_bring_coat)
The output will be True because is_raining is True.
With these operators, you now have the tools to perform calculations and make comparisons in your code. This is the foundation of all problem-solving in programming. In the next chapter, we’ll use these tools to create programs that can make decisions on their own.
The ability for a program to make decisions is what makes it truly powerful. This is called control flow, and it allows your code to run different blocks of instructions depending on whether a certain condition is true or false.
The most common way to make decisions in Python is with if, elif, and else statements.
The if Statement
The if statement is the simplest form of a conditional. It says, "If this condition is true, then do this."
Here’s a simple example:
is_it_raining = True
if is_it_raining:
print("Don't forget your umbrella.")
Since the variable is_it_raining is True, the code inside the if block is run, and the message is printed.
A crucial part of this is indentation. The line print("Don't forget your umbrella.") is indented, which tells Python that it belongs to the if statement. If you don’t indent, Python won’t know which lines of code are part of the conditional.
The else Statement
What if the condition is false? That’s where the else statement comes in. It says, "If the first condition is not true, then do this instead."
Let’s modify our example:
is_it_raining = False
if is_it_raining:
print("Don't forget your umbrella.")
else:
print("You can leave your umbrella at home.")
Now, because is_it_raining is False, the code in the if block is skipped, and the code in the else block is run. The output is "You can leave your umbrella at home."
The elif Statement
Sometimes you have more than two options. The elif (short for "else if") statement lets you check for multiple conditions. It’s always placed between an if and an else statement.
The program checks the conditions in order, from top to bottom. As soon as it finds a condition that is true, it runs the code in that block and then skips the rest.
Here is a more complex example using elif to determine what to wear based on the temperature:
temperature = 22 # in Celsius
if temperature > 25:
print("Wear shorts and a t-shirt.")
elif temperature > 20:
print("A light jacket might be a good idea.")
elif temperature > 15:
print("Bring a sweater.")
else:
print("Time for a winter coat!")
The output will be "A light jacket might be a good idea." The program first checks if temperature is greater than 25. It’s not, so it moves to the elif statement. Since 22 is greater than 20, that condition is true, and the corresponding message is printed. The other conditions are not checked.
You can have as many elif statements as you need. The else at the end is like a catch-all for any case that doesn’t fit the previous conditions.
Combining Conditions
You can use the logic operators (and, or, not) we learned in the previous chapter to create more complex conditions.
is_sunny = True
is_warm = True
if is_sunny and is_warm:
print("It's a perfect day for a walk!")
else:
print("Might be better to stay inside.")
Both is_sunny and is_warm must be true for the condition to be met.
You can think of control flow as a flowchart that guides your program from one step to the next, just as decisions guide our actions in everyday life. Mastering these statements gives you the power to write flexible programs that can respond to different situations.
In the next chapter, we’ll learn about loops, which allow your programs to repeat actions without needing to write the same code over and over again.
In programming, you often need to perform the same task multiple times. Imagine you had a list of 100 names and you wanted to print each one. You wouldn’t want to write print() 100 times. This is where loops come in. Loops allow you to automate repetitive tasks, making your code shorter, more efficient, and easier to read.
Python has two main types of loops: the for loop and the while loop.
The for Loop
A for loop is used to repeat an action for each item in a sequence. A sequence can be a list of items, a string of text, or a range of numbers. The loop will run a specific number of times, once for each item.
Let’s look at a simple example using a list of fruits:
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
The output will be:
apple
banana
cherry
Here’s how this works:
The code creates a list called fruits.
The for loop says, "For each item in the fruits list, do the following."
In the first run, the variable fruit is assigned the value "apple".
The code inside the loop (print(fruit)) is executed.
The loop then moves to the next item, "banana", and runs the code again.
This continues until every item in the list has been processed.
You can also use a for loop with the range() function, which generates a sequence of numbers.
for number in range(3):
print(number)
The output will be:
0
1
2
By default, range(3) creates a sequence of numbers from 0 up to (but not including) 3.
The while Loop
A while loop is used to repeat an action as long as a certain condition remains true. It’s useful when you don’t know ahead of time how many times the loop needs to run.
Here’s an example:
count = 0
while count < 3:
print(count)
count = count + 1
The output is:
0
1
2
Here’s how this loop works:
The variable count is set to 0.
The while loop checks if the condition count < 3 is true. Since 0 is less than 3, the condition is true, and the code inside the loop is executed.
The code prints count and then adds 1 to it (count = count + 1 can also be written as count += 1).
The loop goes back to the top and checks the condition again. This repeats until count is no longer less than 3.
It’s important to make sure the condition for a while loop will eventually become false. If it doesn’t, you’ll create an infinite loop, which will run forever and can cause your program to freeze.
Controlling the Loop
Sometimes, you need to change the flow of a loop while it’s running. Python provides two helpful statements for this: break and continue.
break: Stops the loop completely and immediately exits. It’s useful for when you’ve found what you’re looking for and don’t need to continue.
continue: Skips the rest of the current pass through the loop and moves on to the next item.
Here’s an example that uses both:
numbers = [1, 2, 3, 4, 5, 6]
for number in numbers:
if number % 2 != 0: # If the number is odd
continue # Skip to the next number
print(f"The number {number} is even.")
if number == 6:
break # Exit the loop
The output will be:
The number 2 is even.
The number 4 is even.
The number 6 is even.
The loop checks each number. When it finds an odd number, continue sends it to the next item. When it finds 6, break stops the loop entirely.
Loops are fundamental to programming. They allow you to turn complex, repetitive tasks into just a few lines of code. In the next chapter, we’ll learn about functions, which allow you to package these reusable blocks of code into a single, named tool.
As your programs become more complex, you’ll find yourself performing the same actions in different parts of your code. For example, you might need to calculate the area of a rectangle, convert a temperature from Fahrenheit to Celsius, or format a message to a user. Instead of writing the same lines of code over and over again, you can create a function.
A function is a reusable block of code that performs a specific task. Think of a function like a kitchen gadget or a recipe. You can use the gadget whenever you need to, without having to build it from scratch each time.
Defining a Function
You define a function using the def keyword, followed by a name for your function, and then a set of parentheses.
Here is a simple function that prints a greeting:
def say_hello():
print("Hello there!")
def tells Python you’re defining a function.
say_hello is the name of the function. It should be descriptive, just like a variable name.
() holds any parameters the function needs to do its job. We’ll get to those in a moment.
The colon : marks the start of the function’s code block.
The indented lines that follow are the body of the function.
To use the function, you must call it by writing its name followed by parentheses.
say_hello()
say_hello()
The output is:
Hello there!
Hello there!
You can call this function as many times as you like, which saves you from having to type print("Hello there!") repeatedly.
Parameters and Return Values
Functions become much more powerful when you can send them information and get a result back.
Parameters are variables that are used as a way for a function to receive information. You place them inside the parentheses in the function definition.
Let’s make our say_hello function more personal by giving it a name parameter:
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Arjun")
say_hello("Sita")
The output is:
Hello, Arjun!
Hello, Sita!
When we defined the function, we specified that it expects one piece of information, which it will label name.
When we called the function, we provided a specific piece of information ("Arjun" or "Sita"). This is called an argument. The argument is sent into the function, where it’s used as the value for the name variable.
Return values are what a function gives back after it’s done its job. You use the return keyword to send a value out of the function.
Let’s create a function that calculates the area of a rectangle and gives us the result back.
def calculate_area(length, width):
area = length * width
return area
# Call the function and store the result in a variable
room_area = calculate_area(5, 8)
print(room_area)
The output is 40.
The function calculate_area takes two parameters, length and width.
It calculates the area and then uses return to send the value of area out of the function.
We then store this value in the room_area variable, so we can use it later.
A function can only return one value, but you can return multiple things at once by putting them into a list or a tuple.
Functions are a core concept in all of programming. They let you organize your code into small, understandable, and reusable chunks. In the next chapter, we’ll dive into different ways to organize large amounts of information using data structures.
In the real world, you rarely work with just one piece of information at a time. You have lists of things to do, collections of items, or directories of contacts. In programming, data structures are tools that allow you to organize and store collections of data efficiently. They are containers that hold multiple values, and each one has a specific way of arranging those values.
Lists: An Ordered Collection
A list is a data structure that holds an ordered collection of items. Think of it like a shopping list or a checklist. The items are kept in the order you put them in, and you can change the list later by adding, removing, or changing items. This makes lists mutable.
You create a list by placing items inside square brackets [], separated by commas.
shopping_list = ["bread", "milk", "eggs"]
You can access an item in a list using its index, which is its position number. In Python, counting starts at 0.
first_item = shopping_list[0]
print(first_item)
The output will be bread. You can also change an item’s value by referencing its index.
shopping_list[1] = "almond milk"
print(shopping_list)
The output will be ['bread', 'almond milk', 'eggs'].
Tuples: An Immutable Collection
A tuple is very similar to a list, but it’s immutable, which means once you create it, you cannot change its contents. Think of a tuple like a record or a fixed list of ingredients in a recipe. They are often used for data that shouldn’t be altered, like coordinates on a map.
You create a tuple by placing items inside parentheses (), separated by commas.
coordinates = (10.0, 20.0)
You can access items in a tuple using an index, just like with a list. However, if you try to change an item, Python will give you an error.
# This will cause an error!
coordinates[0] = 15.0
This behavior can be useful because it helps prevent accidental changes to important data.
Dictionaries: A Key-Value Collection
A dictionary is a data structure that stores information as key-value pairs. Instead of using a number to find an item, you use a unique key. Think of a physical dictionary, where you look up a word (the key) to find its definition (the value). This makes dictionaries very efficient for looking up information.
You create a dictionary by placing key-value pairs inside curly braces {}. The key and value are separated by a colon :, and each pair is separated by a comma.
person = {
"name": "Arjun",
"age": 30,
"city": "Mumbai"
}
You can access a value by using its key in square brackets.
print(person["name"])
The output is Arjun. You can also add a new key-value pair or change an existing one.
person["job"] = "developer"
print(person)
The output will show the new job key-value pair.
Sets: A Collection of Unique Items
A set is an unordered collection of items where every item must be unique. If you try to add an item that’s already in the set, the set will simply ignore it. Sets are often used to find unique items in a list or to perform mathematical set operations like finding a union or intersection.
You create a set by placing items inside curly braces {}.
unique_numbers = {1, 2, 3, 3, 4, 5}
print(unique_numbers)
The output will be {1, 2, 3, 4, 5}. The duplicate 3 is automatically removed.
You can also use a set to find the unique items in a list:
all_fruits = ["apple", "banana", "apple", "cherry"]
unique_fruits = set(all_fruits)
print(unique_fruits)
The output is {'apple', 'banana', 'cherry'}.
Understanding these data structures is a key step in becoming a proficient programmer. By choosing the right one for your task, you can write more efficient and organized code.
In the next chapter, we’ll learn how to work with files, which allows you to save and load information outside of your programs.
So far, all the programs we’ve written have been temporary. When a program finishes running, any variables and data structures we created disappear. This is fine for small practice exercises, but for real-world applications, you need a way to store data permanently.
Files allow your programs to save and load information. Think of a file as a physical document that exists outside of your program’s memory. When your program runs, it can open a file, read its contents, and write new information to it.
Reading from a File
To read a file, your program needs to open it in read mode. We’ll use a special with open() statement that’s a best practice because it automatically closes the file for you when you’re done, even if an error happens.
Let’s assume you have a text file named journal.txt with the following content:
First day of learning.
Feeling excited about coding!
To read and print its contents, you’d use this code:
with open('journal.txt', 'r') as file:
content = file.read()
print(content)
with open() opens the file.
'journal.txt' is the file path or name. Since it’s in the same folder as our code, we just need the name.
'r' is the mode, indicating we want to read from the file.
as file gives us a variable named file that we can use to access the file’s contents.
file.read() reads the entire file as a single string.
The output will be the content of the file. You can also read a file line by line using a for loop, which is useful for large files:
with open('journal.txt', 'r') as file:
for line in file:
print(line.strip())
The .strip() part is a string method that removes any extra spaces or newlines at the beginning or end of a line.
Writing to a File
To write to a file, you need to open it in write mode ('w') or append mode ('a').
'w' mode: writes to the file. If the file already exists, it will be completely erased and overwritten. If it doesn’t exist, a new file will be created.
'a' mode: appends to the end of the file. This is useful for adding new information without deleting the old.
Here’s an example of writing a new journal entry:
new_entry = "Today I learned about file operations."
with open('journal.txt', 'a') as file:
file.write("\n" + new_entry)
The \n is a special character that creates a new line, so our new entry doesn’t get stuck to the end of the last line. If you run this code, your journal.txt file will now have a new line at the end.
Working with Files in Google Colab
Since Google Colab is a cloud-based environment, the files you work with are stored on Google’s servers, not your computer. To access your own files or save your work, you need to connect your Colab notebook to your Google Drive.
In a code cell, run the following command:
from google.colab import drive
drive.mount('/content/drive')
A link will appear. Click it, sign in to your Google account, and copy the authorization code.
Paste the code into the box in Colab and press Enter.
Now your Google Drive is mounted. You can access files in your Drive using a path like '/content/drive/My Drive/my_folder/my_file.txt'.
Why is this so important? File operations are the key to building real applications. They allow you to create programs that can remember information, like a personal journal, a to-do list, or a program that saves your high scores in a game.
In the next chapter, we’ll dive into Object-Oriented Programming (OOP), a powerful way to organize your code that lets you model real-world things as digital objects.
As you build more complex programs, you’ll find that organizing your code around data and the actions that can be performed on that data becomes essential. Object-Oriented Programming (OOP) is a powerful way to do this. It lets you model real-world things as digital objects, each with its own information and abilities.
Think of an object as a single, self-contained unit. For example, your phone is an object. It has attributes (data) like its color, brand, and battery level. It also has methods (abilities or functions) like making calls, taking pictures, and sending texts. In OOP, you create a blueprint for an object, and then you can create as many objects as you need from that blueprint.
Classes: The Blueprints
A class is the blueprint for creating objects. It defines the attributes and methods that all objects of that class will have. You define a class using the class keyword.
Let’s create a class called Phone.
class Phone:
def __init__(self, brand, color):
self.brand = brand
self.color = color
self.battery_level = 100
def make_call(self, number):
print(f"Calling {number} from my {self.color} {self.brand} phone.")
class Phone:: This line tells Python you’re creating a blueprint for a Phone.
def __init__(self, brand, color):: This is a special method called the constructor. It’s automatically run whenever you create a new object from the class. Its job is to set up the object’s initial attributes.
self: This refers to the specific object you are creating. It’s always the first parameter in a method.
brand and color: These are the initial pieces of information needed to create a phone object.
self.brand = brand: This line creates an attribute named brand on the object and sets its value.
def make_call(self, number):: This is a regular method. It’s a function that belongs to the object. It can access the object’s attributes using self.
Objects: The Instances
An object is a specific instance created from a class. Once you have a Phone blueprint, you can create as many Phone objects as you like, each with its own unique attributes.
To create an object, you call the class name as if it were a function:
my_phone = Phone("Apple", "silver")
your_phone = Phone("Samsung", "black")
# Accessing attributes
print(my_phone.color)
print(your_phone.brand)
# Calling a method
my_phone.make_call("555-1234")
The output will be:
silver
Samsung
Calling 555-1234 from my silver Apple phone.
Each object (my_phone and your_phone) has its own separate values for brand, color, and battery_level. When you call my_phone.make_call(), the method knows to use the attributes of my_phone.
Key Concepts of OOP
The world of OOP is vast, but these three core concepts are what make it so powerful.
Encapsulation: The idea of bundling data (attributes) and methods (abilities) into a single, cohesive unit. This keeps related information together and helps prevent accidental changes.
Inheritance: The ability for one class to inherit attributes and methods from another. This is a way to reuse code and create a hierarchy of objects. For example, a Smartphone class could inherit from a Phone class, and then add its own unique attributes and methods like a screen_size and a run_app() method.
Polymorphism: The ability for objects of different classes to respond to the same method call in their own unique ways. For example, if both a Dog object and a Cat object have a make_sound() method, they would each produce a different sound when called.
OOP allows you to create more organized, flexible, and reusable code. By thinking in terms of objects, you can model complex problems in a way that feels natural and intuitive.
In the next chapter, we’ll learn about errors and debugging, which are crucial skills for any programmer.
No matter how carefully you write your code, you will encounter errors. This isn’t a sign of failure; it’s a normal part of the process. In fact, a good programmer isn’t someone who never makes a mistake, but someone who knows how to deal with them effectively. This chapter will teach you how to understand errors and find bugs in your code.
Understanding Errors and Exceptions
In Python, errors often come with a detailed message called a traceback. A traceback can look intimidating, but it’s a valuable map that tells you exactly where and why your code broke.
Let’s look at a common error.
x = 10
y = "hello"
z = x + y
When you run this, you’ll get an error message that looks something like this:
Traceback (most recent call last):
File "<ipython-input-1-c12e8b2f9a94>", line 3, in <module>
z = x + y
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Let’s break it down:
The last line, TypeError: unsupported operand..., is the error message itself. It tells you the type of error (TypeError) and a short description of what went wrong. In this case, you can’t add a number (int) and a string (str).
The lines above that are the traceback. They show the sequence of calls that led to the error. The last line in the traceback points to the line in your code where the error occurred.
Most errors are exceptions, which are problems that arise during the execution of your code. Common exceptions include:
NameError: You’ve tried to use a variable that hasn’t been created yet.
IndexError: You’ve tried to access an item in a list or tuple using an index that doesn’t exist.
KeyError: You’ve tried to get a value from a dictionary using a key that isn’t there.
Handling Exceptions
Sometimes, you can anticipate that an error might happen. For example, what if a user is asked to enter a number but types a word instead? Your program would crash. You can use try and except blocks to handle these situations gracefully.
try:
user_input = int(input("Enter a number: "))
result = 10 / user_input
print(f"The result is: {result}")
except ValueError:
print("That's not a valid number. Please try again.")
except ZeroDivisionError:
print("You can't divide by zero. Please try again.")
The code inside the try block is what you want to run.
If a ValueError occurs (e.g., the user types a word), the code inside the except ValueError block runs. The program doesn’t crash; it simply prints the helpful message.
Similarly, if a ZeroDivisionError occurs, the program handles it and continues.
You can also use a generic except to catch any type of error, but it’s often better to be specific so you know what went wrong.
Debugging Techniques
Debugging is the process of finding and fixing bugs. It’s a key skill for any programmer.
Read the Traceback Carefully: The traceback is your best friend. Pay close attention to the last line, as it often contains the most important information.
Use print() statements: The simplest way to debug is to print the values of your variables at different points in your code. This helps you see how data is changing and where things might be going wrong.
Break It Down: If a large piece of code isn’t working, break it into smaller parts. Test each part individually to find the exact location of the bug.
Google the Error: Copy and paste the error message into a search engine. Chances are, someone else has had the same problem, and the solution is online.
Debugging requires patience and a systematic approach. With practice, you’ll become more adept at identifying and solving problems, which will make you a more confident programmer.
In the next chapter, we’ll build a small project to put all of these concepts together.
It’s time to bring all the concepts we’ve learned together. In this chapter, we’ll build a small but complete application: a simple to-do list manager. This project will require us to use variables, data structures, loops, conditionals, functions, and file operations.
Our to-do list program will have three main features:
Add a new task.
View all existing tasks.
Save the tasks to a file so they aren’t lost when the program closes.
Step 1: Planning and Setup
Before we write any code, let’s create a plan.
We need a way to store our tasks. A list is perfect for this because it keeps the tasks in order and we can easily add new ones.
The main part of our program will be a loop that presents a menu to the user.
We’ll use if/elif/else statements to check the user’s choice and run the correct code.
We’ll use functions to keep our code organized and easy to read.
We’ll use a file named tasks.txt to save our tasks.
Step 2: Building the Functions
First, let’s write the functions that handle the core logic.
# Function to load tasks from the file
def load_tasks():
try:
with open('tasks.txt', 'r') as file:
return [line.strip() for line in file]
except FileNotFoundError:
return []
# Function to save tasks to the file
def save_tasks(tasks):
with open('tasks.txt', 'w') as file:
for task in tasks:
file.write(task + '\n')
print("Tasks saved successfully!")
# Function to add a new task
def add_task(tasks):
task = input("Enter a new task: ")
tasks.append(task)
print(f"'{task}' has been added.")
# Function to view all tasks
def view_tasks(tasks):
if not tasks:
print("Your to-do list is empty.")
else:
print("Your To-Do List:")
for i, task in enumerate(tasks):
print(f"{i+1}. {task}")
load_tasks() uses a try/except block to handle the case where the file doesn’t exist yet. It reads each line and puts it into a list.
save_tasks() takes the list of tasks and writes each one to a new line in the file.
add_task() gets input from the user and appends it to our list of tasks.
view_tasks() checks if the list is empty. If not, it uses a for loop to print each task with a number next to it. enumerate() is a handy built-in function that gives you both the index and the item.
Step 3: Creating the Main Program Loop
Now, let’s tie everything together with a main loop that runs our program.
# The main loop of our program
def main():
tasks = load_tasks()
print("Welcome to your to-do list manager!")
while True:
print("\nMenu:")
print("1. Add a task")
print("2. View all tasks")
print("3. Save and Exit")
choice = input("Enter your choice (1-3): ")
if choice == '1':
add_task(tasks)
elif choice == '2':
view_tasks(tasks)
elif choice == '3':
save_tasks(tasks)
print("Goodbye!")
break
else:
print("Invalid choice. Please try again.")
# Run the main function when the script starts
if __name__ == '__main__':
main()
When you run this code, it will present a menu and wait for your input. Based on your choice, it will call the correct function. The while loop will keep the program running until you choose to exit.
You can run this program in Google Colab. Just put all the code from this chapter into a single code cell. When you run it, you can interact with it in the output section below.
Troubleshooting and Enhancements
Practice Debugging: Try running the program and purposely entering text instead of a number for a choice. See what happens!
Add a remove_task() function: As a challenge, try writing a new function that lets a user remove a task from the list.
Handle more errors: What happens if the tasks.txt file gets corrupted? How could you handle that?
This project demonstrates how just a few core concepts can be combined to create a useful and functional program. It’s a stepping stone to building more complex applications.
In the final chapter, we’ll reflect on your journey and provide guidance on how to continue your growth as a programmer.
Congratulations! You’ve successfully completed your first comprehensive project, and in doing so, you’ve touched upon nearly every foundational concept in programming. This is a significant milestone. It’s a testament to your hard work and a powerful demonstration of what you can accomplish.
Programming isn’t a destination; it’s a journey of continuous learning. The skills you’ve acquired in this book are the bedrock upon which you can build anything. Here’s how you can continue to grow and expand your abilities.
Take a moment to look back at where you started. You’ve moved from understanding what a variable is to writing a program that can manage and save data. This progress is a result of several key habits you’ve developed:
Patience: You’ve learned to approach problems step-by-step, patiently working through challenges.
Systematic Thinking: You’ve broken down complex tasks into smaller, manageable pieces, a skill that is valuable in all aspects of life.
Resilience: You’ve learned that errors are not failures but opportunities to learn and improve.
These skills are just as important as the code you write.
The world of programming is vast and exciting. Here are some pathways you can explore next:
Learn More Python Libraries: The Python Standard Library is full of powerful tools, and there are thousands of external libraries available. Consider learning one of these to solve a specific problem:
Pandas: For working with data in a structured way.
Matplotlib: To create beautiful graphs and charts from your data.
Requests: To interact with websites and get information from the internet.
Explore a New Field: Use your Python skills to dive into a new area that interests you.
Web Development: Learn frameworks like Flask or Django to build your own websites.
Data Science: Use Python to analyze large datasets and find patterns.
Automation: Write scripts to automate repetitive tasks on your computer.
Build Your Portfolio: Start new projects that solve problems you care about. A portfolio of projects is the best way to demonstrate your skills to others. Consider creating a personal blog, a simple game, or a tool that helps with a hobby you enjoy.
This book was designed to be a gentle and supportive introduction. Remember that learning is a personal process, and it’s perfectly fine to go at your own pace. The most important thing is to stay curious and keep building.
Thank you for allowing me to be a part of your journey. Happy coding!