Python by Example Book 1 (Fundamentals and Basics)
Python by Example Book 1 (Fundamentals and Basics)
Python by Example Book 1 (Fundamentals and Basics)
Book 1
July 2023
Disclaimer
This book has been created using various tools, including AI tools,
development tools, and other services. While the book's development
has involved the utilization of these tools, it is important to note that
the content has been planned and organized by the author.
Python's wide adoption and popularity can be attributed to several key factors:
Python 2 vs. Python 3: It's essential to note that there are two major versions of
Python: Python 2 and Python 3. Python 2 was widely used in the past, but its
development and support officially ended on January 1, 2020. Python 3, with its
numerous improvements, is the current and recommended version for all new
projects. In this book, we will focus on Python 3 as it is the modern and more
actively maintained version of the language.
Getting Started: To begin your Python journey, you'll need to install Python on
your computer. Python can be downloaded for free from the official Python website
(www.python.org) and is available for all major operating systems. The installation
process is straightforward, and once Python is installed, you can start writing and
executing Python code.
Before we embark on our Python journey, it's crucial to set up the Python
environment on your computer. In this section, we'll guide you through the
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 2|P a g e
Python by Example (Book 1: Fundamentals and Basics)
installation process, ensuring you have everything you need to start writing and
executing Python code.
Downloading Python: To get started, head over to the official Python website
(www.python.org) and navigate to the "Downloads" section. Here, you'll find the
latest version of Python available for various operating systems, including Windows,
macOS, and Linux.
Choosing the Right Version: Python has two major versions: Python 2 and
Python 3. While Python 2 was widely used in the past, it is no longer supported, and
its development has ceased. Therefore, it's essential to choose Python 3 for all new
projects. The website will likely highlight the latest Python 3 version, making it easier
for you to make the right choice.
Installing Python: Once you've downloaded the Python installer for your
operating system, run the installation program. The installation process is
straightforward and typically involves accepting the license agreement, choosing the
installation location, and selecting the optional features you want to include.
Verifying the Installation: Once the installation is complete, you can verify
whether Python is successfully installed on your system. Open the Command Prompt
or Terminal and type "python --version" (without quotes) and press Enter. If Python
is installed correctly, the version number will be displayed in the output.
interpreter, open the Command Prompt or Terminal and type "python" (without
quotes). Press Enter, and you should see the Python prompt (">>>"), indicating that
you are now in the Python interactive mode.
Writing Your First Python Program: Congratulations! You have set up the Python
environment, and you're ready to write your first Python program. You can use any
text editor or an Integrated Development Environment (IDE) to write Python code.
Popular text editors like Visual Studio Code, Sublime Text, or Atom have Python
support, while dedicated Python IDEs like PyCharm offer a full suite of development
tools.
Anaconda
In the interactive mode, you can enter Python expressions and statements
directly, and Python will execute them immediately, displaying the output right
away. This allows you to experiment with Python syntax and test code snippets
quickly.
To exit the interactive mode, type "exit()" (without quotes) and press Enter.
Executing Python Scripts: While the interactive interpreter is useful for testing
small code snippets, most Python projects involve writing larger scripts or programs.
Python scripts are files with a ".py" extension that contain a sequence of Python
statements. These scripts can be executed from the command line or within an
Integrated Development Environment (IDE).
To run a Python script from the command line, navigate to the directory where
the script is saved using the "cd" command (Change Directory), and then type
"python script_name.py" (without quotes). Press Enter, and Python will execute the
script, displaying the output in the command line.
For example, if you have a script named "hello.py", you can run it by typing:
python hello.py
Popular Python IDEs include PyCharm, Visual Studio Code (with Python
extension), and IDLE (Python's built-in IDE). These IDEs allow you to write Python
code, run scripts, and manage projects seamlessly, all within a single interface.
In Python, numbers play a crucial role as they allow us to perform a wide range
of mathematical operations and computations. Whether it's basic arithmetic,
complex mathematical algorithms, or data analysis, Python's versatility with
numbers makes it an exceptional choice for various applications.
Integers (int): Integers are whole numbers, positive or negative, without any
fractional parts. For example, 5, -20, and 0 are all integers in Python.
# Addition
result_add = 5 + 3
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 8|P a g e
Python by Example (Book 1: Fundamentals and Basics)
print(result_add) # Output: 8
# Subtraction
result_sub = 10 - 4
print(result_sub) # Output: 6
# Multiplication
result_mul = 2 * 6
print(result_mul) # Output: 12
# Division
# Note - Division always returns a float
result_div = 10 / 2
print(result_div) # Output: 5.0
# Floor Division
result_floor_div = 10 // 3
print(result_floor_div) # Output: 3
# Modulo (remainder)
result_mod = 10 % 3
print(result_mod) # Output: 1
# Exponentiation
result_exp = 2 ** 3
print(result_exp) # Output: 8
Type Conversion:
import math
In Python, strings are a fundamental data type used to represent text. From
simple sentences to complex data parsing, strings play a vital role in handling textual
information in your programs.
Creating Strings:
You can create strings in Python by enclosing text in either single quotes (' '),
double quotes (" "), or triple quotes (''' ''') for multi-line strings.
Very convenient!'''
str1 = "Hello"
str2 = "Python"
result_str = str1 + " " + str2
print(result_str) # Output: "Hello Python"
original_str = "Python"
repeated_str = original_str * 3
print(repeated_str) # Output: "PythonPythonPython"
Python allows you to access individual characters in a string using indexing. The
index starts from 0 for the first character, -1 for the last character, -2 for the second
last character, and so on.
String Methods:
String Formatting:
name = "Nadeem"
age = 55
Boolean Values:
Boolean values represent the truth of a statement. The values `True` and `False`
are the two Boolean literals in Python. They are essential in control flow, such as if-
statements and loops, where actions depend on whether certain conditions are true
or false.
is_raining = True
is_sunny = False
Comparison Operators:
Comparison operators are used to compare values and evaluate conditions. The
result of a comparison is a Boolean value (`True` or `False`). Here are the comparison
operators:
`==`: Equal to
`!=`: Not equal to
`>`: Greater than
`<`: Less than
`>=`: Greater than or equal to
`<=`: Less than or equal to
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 13 | P a g e
Python by Example (Book 1: Fundamentals and Basics)
Example:
x = 10
y = 5
Logical Operators:
Example:
x = 10
y = 5
print(x > 0 and y < 10) # Output: True (both conditions are True)
print(x > 10 or y < 5) # Output: False (both conditions are False)
print(not x > y) # Output: True (opposite of the expression)
Short-Circuit Evaluation:
Example:
a = 5
b = 0
if condition:
# Code to be executed if the condition is True
if num > 0:
print("The number is positive.")
In this example, the condition `num > 0` is evaluated. If the value of `num` is
greater than 0, the code inside the "if" block will be executed, and the message "The
number is positive." will be printed.
You can include multiple statements inside the "if" block by indenting them
appropriately. For example:
if num > 0:
print("The number is positive.")
print("This is a positive number.")
num_squared = num ** 2
print("The square of the number is:", num_squared)
In this example, all the statements inside the "if" block are executed if the
condition `num > 0` evaluates to True.
if condition:
# Code to be executed if the condition is True
else:
# Code to be executed if the condition is False
Let's use the previous example and add an "else" statement to handle the case
when the number is not positive:
if num > 0:
print("The number is positive.")
else:
print("The number is not positive.")
In this case, since `num` is -5, the condition `num > 0` evaluates to False, and the
code inside the "else" block will be executed, printing "The number is not positive."
You can include multiple statements inside the "else" block by indenting them
correctly. For example:
if num > 0:
print("The number is positive.")
else:
print("The number is not positive.")
num_abs = abs(num)
print("The absolute value of the number is:", num_abs)
In this example, all the statements inside the "else" block will be executed if the
condition `num > 0` evaluates to False.
if condition1:
# Code to be executed if condition1 is True
elif condition2:
# Code to be executed if condition2 is True
elif condition3:
# Code to be executed if condition3 is True
...
else:
# Code to be executed if none of the conditions are True
In this case, since `score` is 85, the first condition `score >= 90` is False, the
second condition `score >= 80` is True, and the code inside the "elif" block for B
grade will be executed, printing "Grade: B."
Loops are essential tools in programming that enable us to repeat a block of code
multiple times. Python provides two primary loop constructs: the "while" loop and
the "for" loop. Here we will explore both loop types and learn how to leverage them
effectively to streamline repetitive tasks and solve complex problems.
false. This looping structure is ideal when the exact number of iterations is
uncertain, and the loop depends on a dynamically changing condition.
Let's take a simple example to understand the "while" loop. Suppose we want to
print the first five even numbers. We can achieve this using a "while" loop:
In this example, we initialize the variable `count` to 1. The loop will continue as
long as `count` is less than or equal to 10. Within the loop, we use the "if" statement
to check if the current value of `count` is even. If it is, we print the number. Finally,
we increment `count` by 1 in each iteration to move to the next number.
The "for" loop, on the other hand, is designed to iterate over a sequence (such as
a list, tuple, or string) and execute the block of code for each element in the
sequence. Unlike the "while" loop, the "for" loop has a predetermined number of
iterations based on the length of the sequence. Let's use a "for" loop to print the
elements of a list:
In this example, we have a list called `fruits`, containing several fruits. The "for"
loop iterates over each element in the list, and in each iteration, the variable `fruit`
holds the current element. The loop then prints each fruit's name, giving us the
complete list of fruits.
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 20 | P a g e
Python by Example (Book 1: Fundamentals and Basics)
Nested Loops:
Loops can also be nested inside each other, allowing us to perform complex
tasks. Let's consider a scenario where we want to create a multiplication table:
print("Multiplication Table:")
for i in range(1, 11):
for j in range(1, 11):
print(i, "*", j, "=", i * j)
In this example, we have two "for" loops nested inside each other. The outer
loop iterates from 1 to 10, representing the multiplicand. The inner loop iterates
from 1 to 10, representing the multiplier. In each iteration, the code prints the
product of `i` and `j`, creating the multiplication table.
In this section, we will explore two essential control flow statements: `break` and
`continue`. These statements allow us to have more control over loops, enabling us
to fine-tune the flow of our programs based on specific conditions. Understanding
how to use `break` and `continue` will enhance your ability to create efficient and
flexible Python code.
The `break` statement provides a way to prematurely exit a loop when a certain
condition is met. It is commonly used when you want to stop a loop's execution
early, even before the loop's normal termination conditions are satisfied.
Let's illustrate the usage of `break` with an example. Consider a scenario where
we want to find the first occurrence of a target number in a list and stop the loop as
soon as we find it:
target = 10
In this example, the loop iterates through the `numbers` list, and when it
encounters the value `10`, it executes the `if` block, printing the message "Target 10
found!" and then breaks out of the loop. Since the `break` statement is triggered,
the `else` block will not execute.
The `continue` statement is used to skip the rest of the current iteration of a loop
and proceed to the next iteration. It is particularly useful when you want to skip
certain elements in a loop and continue processing the remaining elements.
In this example, the loop iterates through the `numbers` list. When an odd
number is encountered, the `if` block executes the `continue` statement, skipping
the odd number, and proceeding to the next iteration. The even numbers are
printed as a result.
Chapter 4: Functions
Functions are the building blocks of efficient and organized programming. They
allow us to break down complex tasks into smaller, manageable pieces, making our
programs easier to understand and maintain. As we delve into the world of
functions, you'll discover how they enhance code readability, promote code reuse,
and enable you to create elegant solutions to a wide range of problems.
def greet():
print("Hello! Welcome to our Python program.")
In this example, the function is called with `greet()`. It executes the `print()`
statement, displaying the message "Hello! Welcome to our Python program." on the
screen.
Functions like these can be useful for displaying messages, performing setup
tasks, or executing specific operations that don't rely on external input. They
contribute to organizing code and making it more modular, even if they don't
explicitly require parameters or return values.
Function Parameters:
Let's dive into an example to understand this concept better. Suppose we want
to create a function that calculates the area of a rectangle. The function will take
two parameters: length and width.
which we store in the variable `result`. The print statement displays the calculated
area of the rectangle.
Default Parameters:
Python allows us to set default values for function parameters. If a default value
is provided, the parameter becomes optional when calling the function. If the caller
does not provide a value for that parameter, the default value is used. Let's modify
our previous example to include default parameters for `length` and `width`:
result1 = calculate_rectangle_area()
result2 = calculate_rectangle_area(5, 10)
print("The area of the default rectangle is:", result1)
# Output: The area of the default rectangle is: 1
print("The area of the rectangle is:", result2)
# Output: The area of the rectangle is: 50
In this example, we see that `result1` holds the area of a default rectangle with
sides of length `1` and width `1`, while `result2` holds the area of a rectangle with
sides of length `5` and width `10`.
Return Values:
Return values allow functions to provide outputs that can be used in the calling
code. When a function encounters a `return` statement, it immediately exits the
function and passes the specified value back to the caller. Let's consider a function
that calculates the sum of two numbers:
In this function, `calculate_sum`, we take two parameters, `a` and `b`, and
calculate their sum, which we store in the variable `result`. We then use the `return`
statement to provide this sum as the output of the function. Now, let's call the
function and store the result in a variable:
In this example, we call the function `calculate_sum` with arguments `10` and
`20`. The function calculates their sum, which is `30`, and returns it. The returned
value, `30`, is then stored in the variable `sum_result`, which we print to display the
final result.
Functions also introduce a concept known as "scope," which refers to the region
of a program where a particular variable can be accessed. Understanding scope is
crucial for writing bug-free and efficient code, as it determines the visibility and
lifetime of variables within different parts of the program.
Local Scope:
When you define a variable inside a function, it is said to have "local scope." This
means the variable is only accessible within that specific function and cannot be
accessed from outside. Once the function completes its execution, the local variables
are destroyed, and their values are no longer available. Let's look at an example to
illustrate local scope:
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 26 | P a g e
Python by Example (Book 1: Fundamentals and Basics)
def my_function():
x = 10
print("Inside the function: x =", x)
my_function()
# Output: Inside the function: x = 10
In this example, the variable `x` is defined inside the `my_function()`. It has local
scope, and hence, it is accessible only within the function. Attempting to access `x`
outside the function will result in a `NameError`.
Global Scope:
Variables declared outside of any function, i.e., in the main body of the program,
have "global scope." These variables are accessible throughout the entire program,
including inside functions. Let's see an example of using a global variable:
global_var = 100
def my_function():
print("Inside the function: global_var =", global_var)
my_function()
# Output: Inside the function: global_var = 100
In this example, `global_var` is declared outside the function and has global
scope. Therefore, it can be accessed both inside and outside the function.
While you can access global variables inside functions, modifying them requires a
special declaration. By default, when you assign a value to a variable inside a
function, Python assumes it's a local variable. To modify a global variable inside a
function, you need to explicitly declare it as `global` using the `global` keyword:
global_var = 100
def modify_global():
global global_var
global_var += 50
modify_global()
print("Modified global_var =", global_var)
# Output: Modified global_var = 150
One of the essential tasks in any interactive program is to receive input from the
user. In Python, this can be achieved using the built-in function `input()`.
The `input()` function is a powerful tool for gathering user input during program
execution. It prompts the user to enter a value or string and waits for the user's
response. Once the user enters the input and presses the "Enter" key, the `input()`
function returns the input as a string.
In this example, we prompt the user to enter their name using `input()`. The
entered name is then stored in the variable `name`, and we use string interpolation
(using an f-string) to display a personalized greeting.
# Get the user's age as input and calculate the year of birth
age = int(input("Enter your age: "))
current_year = 2023
In this example, we receive the user's age as input. However, since `input()`
returns a string, we need to convert it to an integer using the `int()` function to
perform numerical operations. We then calculate user's birth year and display it.
When using `input()`, it's essential to consider user input validation to ensure
that the program can handle various input scenarios without encountering errors.
For example, if the program expects a numeric input but the user enters a non-
numeric value, it may cause a `ValueError`. We can use techniques like `try-except`
blocks to handle such situations gracefully.
handling process, where we manipulate and persistently store data for various
purposes. The process of file handling encompasses multiple steps, such as opening
files to access their content, reading from them, writing new data, or appending to
existing files, and finally, closing the files after the required operations are
performed. Mastering these file handling techniques empowers us to create robust
and efficient applications that can seamlessly interact with external files, facilitating
data storage and retrieval with ease.
Python provides a simple and intuitive way to write data to files. To begin, we
need to open a file in write mode using the `open()` function. The syntax for opening
a file for writing is as follows:
In the above code, `"filename.txt"` represents the name of the file we want to
create or open, and `"w"` denotes that we are opening the file in write mode. If the
specified file does not exist, Python will create a new file with the given name.
Writing Data:
Once the file is open in write mode, we can use the `write()` method to write
data to the file. The `write()` method takes a string as an argument and writes it to
the file. Here's an example of writing data to a file:
file.close()
In this example, we first open a file named "output.txt" in write mode. We then
use the `write()` method to write two lines of text to the file. Note that each call to
`write()` appends the text to the file, so multiple calls can be used to write different
pieces of information.
If we want to add data to an existing file without overwriting its contents, we can
open the file in append mode (`"a"`) instead of write mode (`"w"`). Here's an
example:
In this case, the new text will be added to the end of the existing content in the
"output.txt" file.
When working with files, it's good practice to use the `with` statement, which
automatically handles the file closing for us. The `with` statement creates a context
manager that opens the file, allows us to perform operations on it, and automatically
closes it when we're done. Here's an example:
The above code achieves the same result as the earlier example but with the
added benefit of automatic file closure.
In this example, we first open the file "output.txt" in write mode and write two
lines of text to it. Then, we open the file again in append mode and add another line
of text to the end of the existing content.
Next, we open the file in read mode (`"r"`) using the `with` statement, which
automatically closes the file after reading its contents. We use the `read()` method
to read the entire contents of the file and store it in the variable `contents`.
Finally, we print the contents of the file to the console, displaying the text we
previously wrote and appended.
As you can see, we successfully wrote data to the file, appended new data, and
then read and displayed the entire content of the file using Python's file handling
capabilities. This powerful combination of reading and writing to files allows us to
create applications that can efficiently interact with external data sources and
manipulate data for various purposes.
String Concatenation:
name = "Nadeem"
age = 55
print("Name is " + name + ", I am " + str(age) + " years old.")
Using `str.format()`:
inserted into the string. This method is especially useful when dealing with multiple
variables.
name = "Nadeem"
age = 55
print("Name is {} and I am {} years old.".format(name, age))
Introduced in Python 3.6, f-strings offer a concise and efficient way to format
output. F-strings allow us to embed expressions and variables directly within curly
braces `{}` preceded by the letter 'f'. The expressions inside the braces are evaluated
at runtime, making f-strings a powerful tool for dynamic output formatting.
name = "Nadeem"
age = 55
print(f"Hello, my name is {name} and I am {age} years old.")
We can also use format specifiers to control the appearance of the output
further. Format specifiers define how data should be displayed, such as setting a
fixed width for numbers or specifying the number of decimal places.
pi = 3.14159265359
print("The value of pi is {:.2f}".format(pi))
# Output: "The value of pi is 3.14"
Format specifiers also allow us to align the output and fill spaces with specific
characters.
name = "Nadeem"
age = 55
print(f"{name:<10} is {age} years old.")
Compiled & Edited by Muhammad Nadeem Khokhar ([email protected]) 35 | P a g e
Python by Example (Book 1: Fundamentals and Basics)
In this example, `name` is left-aligned within a field of width 10, and the extra
spaces are filled with a default space character. By changing `<` to `>`, we can right-
align the text, and by using `^`, we can center it.
Python offers various format specifiers for numbers and dates to control their
appearance. For example:
number = 12345.6789
date = datetime.now()
print(f"Formatted number: {number:,.2f}")
# Output: "Formatted number: 12,345.68"
print(f"Formatted date: {date:%Y-%m-%d}")
# Output: "Formatted date: 2023-07-20"
In this example, `,` is used to add commas for thousands separators in numbers,
and `%Y-%m-%d` represents the date format as year-month-day.
The try-except block is a structured way to handle exceptions. The "try" block
contains the code that may raise an exception. If an exception occurs within the try
block, Python immediately jumps to the corresponding "except" block, allowing us to
manage the exception. The program then continues executing from the point after
the except block, avoiding a complete program crash. Syntax:
try:
# Code that may raise an exception
# ...
except ExceptionType:
# Code to handle the exception
# ...
we want to catch any type of exception, we can use a general `except:` block without
specifying the type.
Let's consider a simple example where we want to perform division and handle
the case of division by zero. Without exception handling, the program would raise a
"ZeroDivisionError" and terminate.
# Test cases
divide(10, 2) # Output: The result of 10 divided by 2 is 5.0.
divide(8, 0) # Output: Error: Division by zero is not allowed.
In the above example, the try block attempts to perform the division. If the
divisor is zero, a ZeroDivisionError is raised, and the except block handles the error
gracefully.
In this example, we want to convert user input to an integer. If the input is not a
valid integer, a ValueError will be raised. We will use the try-except block to handle
this situation.
def get_integer_input():
try:
# Test cases
get_integer_input()
# Input: 42
# Output: Your input as an integer: 42.
get_integer_input()
# Input: abc
# Output: Error: Invalid input. Please enter a valid integer.
In this case, the try block attempts to convert the user input to an integer. If the
input is not a valid integer, a ValueError is raised, and the except block handles the
error message appropriately.
While Python provides a wide range of built-in exceptions to cover most common
error scenarios, there are instances where we may encounter specific situations that
require a more specialized approach. This is where custom exceptions come into
play.
To create a custom exception, we define a new class that inherits from the built-
in `Exception` class or any of its subclasses. This custom class will represent our
custom exception. Let's see an example:
class CustomError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return f'Custom Error: {self.message}'
Now that we have our custom exception, we can raise it in our code when a
specific error condition occurs. Let's illustrate this with a simple function that
calculates the area of a rectangle, but we want to handle the scenario where the
width or height is negative:
In this example, if the `width` or `height` is less than or equal to zero, we raise
our custom `CustomError` exception with a meaningful error message.
try:
width = -5
height = 10
area = calculate_rectangle_area(width, height)
print("Area:", area)
except CustomError as e:
print(e)
Creating custom exceptions allows us to add clarity and precision to our error
handling. It enhances code readability and makes troubleshooting and debugging
easier, as the exception messages are more descriptive and relevant to the specific
error scenarios we encounter in our applications.
We present two engaging projects that will put your newfound Python
knowledge into action. These projects serve as practical exercises, allowing you to
implement the concepts learned throughout the book in real-world scenarios. Each
project provides a unique opportunity to explore Python's features, including
variables, control flow, functions, and more. By completing these projects, you'll
reinforce your understanding and gain confidence in your ability to tackle coding
challenges.
import random
def guess_the_number():
secret_number = random.randint(1, 100)
attempts = 0
while True:
try:
user_guess = int(input("Enter your guess: "))
attempts += 1
if user_guess == secret_number:
print(f"Congratulations! Guessed: {secret_number}")
print(f"in {attempts} attempts.")
break
elif user_guess < secret_number:
print("Too low! Try a higher number.")
else:
print("Too high! Try a lower number.")
except ValueError:
print("Invalid input. Please enter a valid integer.")
if __name__ == "__main__":
guess_the_number()
Build a to-do list manager where users can add, view, and remove tasks.
Implement options to mark tasks as completed and display completed tasks
separately. This project will allow you to apply your knowledge of lists, functions,
and basic input/output operations.
def show_menu():
print("Todo List Manager")
print("1. Add task")
print("2. View tasks")
print("3. Remove task")
print("4. Mark task as completed")
print("5. View completed tasks")
print("6. Exit")
def add_task(todo_list):
task = input("Enter the task: ")
todo_list.append({"task": task, "completed": False})
print("Task added successfully.")
def view_tasks(todo_list):
print("Tasks:")
for index, task in enumerate(todo_list, start=1):
status = "✓" if task["completed"] else " "
print(f"{index}. [{status}] {task['task']}")
def remove_task(todo_list):
view_tasks(todo_list)
try:
choice = int(input("Enter the task number to remove: "))
if 1 <= choice <= len(todo_list):
todo_list.pop(choice - 1)
print("Task removed successfully.")
else:
print("Invalid task number.")
except ValueError:
print("Invalid input. Please enter a valid task number.")
def mark_completed(todo_list):
view_tasks(todo_list)
try:
choice = int(input("Task number to mark as completed: "))
if 1 <= choice <= len(todo_list):
def view_completed_tasks(todo_list):
completed_tasks = [task for task in todo_list if
task["completed"]]
if not completed_tasks:
print("No completed tasks.")
else:
print("Completed tasks:")
for index, task in enumerate(completed_tasks, start=1):
print(f"{index}. {task['task']}")
def main():
todo_list = []
while True:
show_menu()
try:
choice = int(input("Enter your choice: "))
if choice == 1:
add_task(todo_list)
elif choice == 2:
view_tasks(todo_list)
elif choice == 3:
remove_task(todo_list)
elif choice == 4:
mark_completed(todo_list)
elif choice == 5:
view_completed_tasks(todo_list)
elif choice == 6:
print("Goodbye!")
break
else:
print("Invalid choice. Please select again.")
except ValueError:
print("Invalid input. Please enter a valid choice.")
if __name__ == "__main__":
main()
The exercises in this section are designed to provide hands-on practice and
deepen your understanding of the concepts covered in the book. By engaging with
these exercises, you'll sharpen your coding abilities and gain confidence in your
Python proficiency.
Write a Python function that takes two strings as input, `text` and `pattern`, and
determines if the pattern exists in the text. The pattern can contain both letters and
wildcards represented by asterisks (*), which can match zero or more characters in
the text. Your function should return `True` if the pattern is found in the text,
considering the wildcard matching, and `False` otherwise.
if pattern[pattern_idx] == '*':
for i in range(text_idx, len(text) + 1):
if match(i, pattern_idx + 1):
return True
elif (text_idx < len(text) and
(text[text_idx] == pattern[pattern_idx] or
pattern[pattern_idx] == '?')):
return match(text_idx + 1, pattern_idx + 1)
return False
return match(0, 0)
# Test cases
print(pattern_matcher("hello_world", "h*o_w*d")) # Output: True
print(pattern_matcher("programming", "pr*g")) # Output: False
Create a Python program that takes two text files as input and measures their
similarity using the Jaccard similarity coefficient. The Jaccard similarity coefficient
compares the similarity between two sets by calculating the size of their intersection
divided by the size of their union. In this case, each set represents the unique words
in each text file. Your program should read the files, tokenize the words, and
calculate and display the Jaccard similarity coefficient between the two files.