Ultimate Python Guide (2024)
Ultimate Python Guide (2024)
Tommy OG
CONTENTS
Title Page
Introduction
Why Learn Python?
Chapter 1: Getting Started with Python
1.1 Introduction to Python
1.2 Setting Up Your Environment
1.3 Python Syntax Basics
Chapter 2: Variables and Data Types
2.1 Understanding Variables
2.2 Basic Data Types
2.3 Working with Strings
Chapter 3: Control Structures
3.1 Conditional Statements
3.2 Loops
Chapter 4: Functions and Modules
4.1 Introduction to Functions
4.2 Scope and Lifetime of Variables
4.3 Modules and Packages
Chapter 5: Data Structures
5.1 Lists
5.2 Tuples
5.3 Dictionaries
5.4 Sets
Chapter 6: File Handling
6.1 Working with Files
6.2 Context Managers
Chapter 7: Error and Exception Handling
7.1 Understanding Errors
7.2 Handling Exceptions
Chapter 8: Object-Oriented Programming
8.1 Introduction to OOP
8.2 Creating Classes
8.3 Inheritance and Polymorphism
Chapter 9: Working with Libraries
9.1 Standard Library Overview
9.2 Third-Party Libraries
Chapter 10: Introduction to Web Development with Flask
10.1 What is Flask?
10.2 Routing and Templates
10.3 Handling Forms and Data
Chapter 11: Introduction to Data Analysis with Pandas
11.1 What is Pandas?
11.2 DataFrames and Series
11.3 Analyzing Data
Conclusion
Next Steps
Final Notes
Appendices
A. Cheat Sheets
B. Glossary
What to do next?
Even More Exercises For You
BONUS
THANK YOU!
INTRODUCTION
WELCOME
Welcome to "ULTIMATE Python Guide: From Zer0 to Hero"!
Whether you are stepping into the world of programming for the first time
or looking to enhance your existing skills, this book is designed with you in
mind. Python is known for its simplicity and versatility, making it an ideal
choice for beginners. By the end of this journey, you will have a solid
understanding of Python and the confidence to tackle real-world
programming challenges.
PURPOSE OF THE BOOK
The purpose of this book is to provide a comprehensive and
accessible introduction to Python programming. Our goals are:
Absolute Beginners:
If you have no prior programming experience, this book is for you.
We start with the basics, including setting up your programming
environment and writing your first lines of code. Each concept is explained
in a straightforward manner, with plenty of examples to help you
understand and apply what you learn.
Students:
Whether you are a high school student, a college undergraduate, or
pursuing any other form of education, this book will serve as a valuable
resource. It covers fundamental programming concepts that are essential for
academic success in computer science and related fields.
Self-Learners:
If you are learning to code on your own, this book is structured to
provide a clear, self-paced learning path. Each chapter builds on the
previous one, ensuring you develop a strong foundation before moving on
to more complex topics. The exercises and projects included will help you
practice and solidify your knowledge.
Career Changers:
For professionals looking to transition into a career in tech, learning
Python is a great way to start. This book will provide you with the skills
needed to pursue roles in web development, data analysis, automation, and
more. Python’s simplicity and readability make it an excellent choice for
those new to programming.
Professionals Enhancing Their Skills:
If you already have experience in other programming languages and
want to add Python to your toolkit, this book will help you quickly get up to
speed. It covers Python’s syntax and core libraries, as well as practical
applications that will be useful in your work.
Hobbyists and Enthusiasts:
If you enjoy tinkering with technology and want to learn a versatile
and powerful programming language, this book will guide you through fun
and engaging projects. From automating everyday tasks to creating small
games and tools, you will find Python to be a rewarding and enjoyable
language to learn.
Educators and Trainers:
If you teach programming or plan to introduce Python to your
students, this book can serve as a comprehensive curriculum. It includes
detailed explanations, examples, and exercises that you can use to structure
your lessons and engage your students.
No matter your background or goals, "ULTIMATE Python Guide:
From Zer0 to Hero" is designed to help you succeed in your learning
journey. We aim to make the process as smooth and enjoyable as possible,
providing you with the knowledge and confidence to harness the power of
Python.
HOW TO USE THIS BOOK
To maximize your learning experience with "Python for Beginners:
A Step-by-Step Guide," follow these guidelines:
Read Sequentially:
The book is structured to build your knowledge progressively. Start
from the beginning and move through each chapter in order. This ensures
you have a solid foundation before tackling more complex topics.
Practice Actively:
Each chapter includes practical examples and exercises. Don't just
read through them—actively type out the code, run it, and experiment with
modifications. This hands-on approach is crucial for reinforcing your
understanding.
Utilize Examples:
The book is filled with examples to illustrate key concepts. Study
these examples closely, as they demonstrate the practical application of the
material covered. Re-create these examples on your own to see how they
work in practice.
Complete Exercises:
At the end of each chapter, you'll find exercises designed to test
your understanding of the material. Make sure to complete these exercises,
as they provide valuable practice and help solidify your knowledge.
Work on Projects:
Some chapters include larger projects that integrate multiple
concepts. These projects are designed to simulate real-world scenarios and
provide a comprehensive learning experience. Take your time with these
projects and use them as an opportunity to apply what you've learned.
Why Python?
Python is more than just a programming language; it's a powerful
tool that opens doors to countless opportunities. Whether you're interested
in web development, data science, artificial intelligence, or automation,
Python's versatility makes it an excellent choice. Its straightforward syntax
and readability make it accessible for beginners, while its depth and wide
range of libraries cater to experienced programmers.
My Journey
I remember the challenges and excitement of learning to code. There
were moments of frustration, but also moments of triumph when things
finally clicked. This book is a product of those experiences. I’ve distilled
years of learning, teaching, and professional experience into this guide,
aiming to make your journey smoother and more enjoyable.
Teaching Philosophy
I believe that anyone can learn to code with the right guidance and
resources. This book is designed to be more than just a collection of
tutorials; it’s a mentor that walks you through the learning process step-by-
step. My goal is to break down complex concepts into manageable parts,
provide practical examples, and offer plenty of exercises to reinforce
learning.
Acknowledgments
I would like to extend my gratitude to the many individuals and
communities that have contributed to the creation of this book. From the
open-source contributors who maintain the Python libraries we use, to the
educators who inspired me, and the peers who supported me—thank you.
Your Journey
This book is just the beginning of your coding adventure. I hope it
sparks a passion for programming and opens up new opportunities for you.
Whether you aim to pursue a career in tech, automate tasks, or simply enjoy
the challenge of coding, I believe Python will serve you well.
Thank you for choosing this book. I am honored to be a part of your
learning journey and look forward to seeing what you create with Python.
Happy coding!
Best regards,
Tommy OG
WHY LEARN PYTHON?
Python has emerged as one of the most popular and versatile
programming languages in the world. Its widespread adoption is due to
several compelling reasons, making it an excellent choice for beginners and
experienced developers alike. Here, we explore the key factors behind
Python's popularity and demand.
POPULARITY AND DEMAND
Simplicity and Readability:
Python's syntax is clear and intuitive, making it easy to learn and
use. It emphasizes readability, which reduces the cost of program
maintenance and allows programmers to express concepts in fewer lines of
code compared to other languages like Java or C++.
The language's design philosophy, as outlined in the "Zen of
Python," prioritizes simplicity and readability, encouraging best practices
that enhance the quality of code.
Versatility and Applications:
Python is a general-purpose language, meaning it can be used for a
wide variety of applications. This includes web development (with
frameworks like Django and Flask), data analysis (with libraries like pandas
and NumPy), machine learning (with libraries like TensorFlow and scikit-
learn), automation, scripting, and more.
The ability to apply Python to different domains makes it a valuable skill
for various industries, including technology, finance, healthcare, and
academia.
Extensive Libraries and Frameworks:
Python boasts a rich ecosystem of libraries and frameworks that
extend its capabilities. For instance, matplotlib and seaborn for data
visualization, PyTorch for deep learning, and Beautiful Soup for web
scraping are just a few examples.
These libraries and frameworks save developers significant time and effort,
allowing them to focus on solving problems rather than reinventing the
wheel.
Community Support and Resources:
Python has a large and active community of developers who
contribute to its extensive documentation, tutorials, and forums. This
community support ensures that learners and developers can easily find
solutions to their problems and stay updated with the latest advancements in
the language.
Resources such as Stack Overflow, GitHub, and numerous online
courses (e.g., Coursera, Udemy) provide ample learning and
troubleshooting opportunities.
Industry Demand:
Python's popularity among major tech companies like Google,
Facebook, and Instagram, which use it for various applications, has spurred
a high demand for Python developers.
According to job market analysis platforms, Python consistently ranks as
one of the most in-demand programming languages. This demand translates
into abundant job opportunities and competitive salaries for Python
developers.
Educational Use:
Python is frequently chosen as the first programming language
taught in universities and coding bootcamps due to its simplicity and ease
of learning. This widespread adoption in education helps create a steady
stream of new developers proficient in Python.
The language's approachable syntax allows beginners to grasp fundamental
programming concepts without getting bogged down by complex syntax
rules, making the learning curve less steep.
Future-Proof and Evolving:
Python continues to evolve with regular updates that introduce new
features and improvements, ensuring it remains relevant and capable of
handling modern computing challenges.
Its adaptability and ongoing development make Python a future-
proof choice for those looking to invest in a long-term programming skill.
VERSATILITY AND APPLICATIONS
Python is celebrated for its versatility, making it a powerful tool for
a wide range of applications. This section explores some of the key areas
where Python is extensively used and why it stands out as a preferred
language in each domain.
Web Development
Frameworks: Python offers robust frameworks like Django, Flask,
and Pyramid that simplify the process of building web applications. Django,
in particular, is known for its "batteries-included" approach, providing a
comprehensive suite of tools for database management, authentication, and
more.
Applications: Many popular websites and web applications, such as
Instagram, Pinterest, and The Washington Post, leverage Python for its
efficiency and ease of use in developing scalable and maintainable web
solutions.
Data Science and Analytics
Libraries: Python's extensive libraries like pandas, NumPy, and
SciPy enable efficient data manipulation, analysis, and visualization. These
tools are integral for tasks such as data cleaning, statistical analysis, and
complex mathematical computations.
Tools and Platforms: Tools like Jupyter Notebooks and platforms
like Anaconda facilitate an interactive and collaborative environment for
data scientists, making Python an indispensable part of the data science
toolkit.
Applications: Python is used in various data-driven fields, from
finance and economics to healthcare and marketing, for predictive analytics,
data visualization, and statistical modeling.
Machine Learning and Artificial Intelligence
Libraries and Frameworks: Python is a leading language in
machine learning and AI, thanks to libraries such as TensorFlow, Keras,
PyTorch, and scikit-learn. These libraries provide powerful tools for
developing machine learning models, from simple classifiers to complex
neural networks.
Applications: Python is used in AI-driven applications like natural
language processing (NLP), computer vision, and robotics. Companies like
Google, IBM, and Amazon use Python to develop and deploy AI solutions
that enhance their products and services.
Automation and Scripting
Ease of Use: Python’s simplicity makes it ideal for scripting and
automation tasks. Its straightforward syntax allows developers to write
scripts that automate repetitive tasks, improving efficiency and productivity.
Applications: Python is widely used for automating tasks such as
file handling, web scraping, report generation, and even managing system
operations. Tools like Selenium and Beautiful Soup are popular for web
scraping and browser automation.
Scientific Computing
Libraries: Python is a staple in scientific computing, with libraries
such as SciPy, SymPy, and BioPython catering to different scientific
domains. These libraries offer functionalities for complex scientific
calculations, symbolic mathematics, and bioinformatics, respectively.
Applications: Python is used in fields like physics, chemistry,
biology, and astronomy to perform simulations, analyze experimental data,
and model scientific phenomena.
Game Development
Libraries and Frameworks: Pygame and Panda3D are notable
Python libraries used for game development. These tools provide the
necessary functions and modules to create 2D and 3D games.
Applications: While Python may not be the first choice for high-
end gaming, it is excellent for developing prototypes, indie games, and
educational games due to its ease of use and rapid development capabilities.
Finance and Fintech
Libraries: Libraries like QuantLib and PyAlgoTrade are used for
quantitative finance, algorithmic trading, and financial modeling. Python's
robust data analysis libraries also play a crucial role in financial analysis.
Applications: Python is employed in developing trading platforms,
risk management systems, and predictive financial models, providing
financial institutions with tools for better decision-making.
Education
Accessibility: Python's simple syntax and readability make it an
ideal first programming language for beginners. It is commonly used in
educational institutions to teach programming and computer science
concepts.
Applications: From introductory programming courses to
advanced topics like machine learning, Python serves as a versatile
educational tool, fostering a new generation of developers.
SUCCESS STORIES
Python's flexibility, readability, and extensive libraries have made it
the go-to language for many organizations. Below are 25 detailed success
stories demonstrating Python's impact across various industries.
Quora, the popular Q&A platform, uses Python for its backend
development. Python's readability and efficiency allow Quora to handle
user-generated content smoothly. The language's extensive libraries support
Quora's complex algorithms for content recommendation and moderation.
Lyft uses Python for backend services and data analytics, enhancing
its ride-matching algorithms and operational efficiency. Python's simplicity
and extensive libraries allow Lyft to develop and deploy features quickly,
maintaining a competitive edge in the ride-sharing market.
Major Milestones:
Python 1.0 (1994): The first official version, which included
features like exception handling, functions, and the core data types.
Python 2.0 (2000): Introduced new features like list
comprehensions, garbage collection, and Unicode support. Python 2.x
continued to be developed and maintained until 2020.
Python 3.0 (2008): A major overhaul designed to fix inherent
design flaws. Python 3 is not backward-compatible with Python 2.x, but it
introduced many improvements and modern features. Python 3.x is the
future of the language, and ongoing development continues to enhance its
capabilities.
Why Python?
Python’s popularity can be attributed to several factors that make it
an attractive choice for various applications:
Ease of Learning:
Beginner-Friendly: Python’s simple and readable syntax makes it
an ideal first programming language for beginners. Concepts like variables,
loops, and functions are straightforward to grasp.
Comprehensive Documentation: Python’s extensive
documentation and the availability of numerous learning resources,
tutorials, and courses make it accessible to new learners.
Versatility:
Multiple Domains: Python is used in various fields such as web
development, data science, artificial intelligence, scientific computing,
automation, and more. This versatility makes Python a valuable skill across
different industries.
Integration: Python can easily integrate with other languages and
technologies, making it suitable for a wide range of tasks from scripting to
building large-scale applications.
Productivity and Speed:
Rapid Development: Python’s concise syntax allows developers to
write less code to achieve the same functionality compared to other
languages. This boosts productivity and accelerates the development cycle.
Prototyping: Python’s ease of use and flexibility make it an
excellent choice for rapid prototyping and iterative development.
Community Support:
Active Development: The Python community actively contributes
to the language’s development, ensuring it evolves with the latest
technological trends. The support from the community also means that bugs
are quickly identified and fixed.
Collaborative Environment: The community provides a
collaborative environment where developers can share knowledge, tools,
and best practices.
Career Opportunities:
High Demand: The demand for Python developers continues to
grow as more industries adopt the language for various applications. This
translates into numerous job opportunities and competitive salaries for
Python programmers.
Industry Standard: Many leading tech companies, including
Google, Facebook, and Amazon, use Python, further establishing its
credibility and relevance in the tech industry.
In the following sections, we will guide you through setting up your
Python environment, understanding the basic syntax, and writing your first
Python programs. Welcome to the world of Python programming!
1.1.2 HISTORY OF PYTHON
Python, a high-level programming language known for its
readability and simplicity, has a rich history that spans over three decades.
Its development has been driven by a need for an easy-to-understand
language that can cater to a wide range of applications. Here, we delve into
the detailed history of Python, tracing its origins, evolution, and milestones.
Origins and Early Development
Conception and Initial Development (Late 1980s):
Python was conceived in the late 1980s by Guido van Rossum, a
Dutch programmer working at Centrum Wiskunde & Informatica (CWI) in
the Netherlands. Van Rossum was part of a team working on a language
called ABC, which was designed for teaching programming but had several
limitations. Inspired by ABC’s readability but seeking more functionality
and extensibility, van Rossum began developing Python during his
Christmas holidays in December 1989.
Release of Python 0.9.0 (1991):
The first version of Python, Python 0.9.0, was released in February
1991. This version already included many features that are still fundamental
to Python today, such as exception handling, functions, and the core data
types (str, list, dict). The design emphasized code readability and simplicity,
which have remained core tenets of the language.
Python 3:
Print Function: In Python 3, print is a function, which adds
flexibility such as specifying the end character and redirection of output.
For example:
print("Hello, World!")
2. Integer Division
Python 2:
Integer Division: Dividing two integers in Python 2 performs floor
division, discarding the decimal part:
result = 3 / 2 # Result is 1
True Division: To get a float result, you must explicitly convert one
of the operands to a float:
result = 3 / 2.0 # Result is 1.5
Python 3:
True Division: Python 3 performs true division by default, returning
a float result:
result = 3 / 2 # Result is 1.5
3. Unicode Support
Python 2:
Strings: ASCII is the default encoding for string literals, and
Unicode literals require a special prefix:
string = "Hello, World!" # ASCII string
unicode_string = u"Hello, World!" # Unicode string
Python 3:
Strings: Unicode is the default for all string literals, simplifying
internationalization and text processing:
string = "Hello, World!" # Unicode string by default
Python 3:
Exception Handling: Uses the new syntax, which is more
consistent and clear:
try:
# Code that may raise an exception
except Exception as e:
# Handle exception
print(e)
Python 3:
Range: range() returns an immutable sequence type (an iterator) by
default, combining the functionality of range() and xrange() from Python
2:
numbers = range(5) # Returns an iterator
7. Input Function
Python 2:
Raw Input: Uses raw_input() to read strings from the user, and
input() evaluates the input as a Python expression:
user_input = raw_input("Enter something: ") # Reads input as a string
user_input = input("Enter an expression: ") # Evaluates input as an expression
Python 3:
Input: The input() function reads input as a string, eliminating the
distinction and reducing confusion:
user_input = input("Enter something: ") # Always reads input as a string
3. Dynamically Typed
In Python, you do not need to declare the type of a variable when
you create one. The interpreter assigns the type dynamically at runtime.
This flexibility allows for faster prototyping and simplifies code
management.
Example:
x=5 # x is an integer
x = "Hello" # x is now a string
5. Portability
Python is highly portable, meaning that Python code can run on
various operating systems like Windows, macOS, Linux, and more without
modification. This cross-platform compatibility makes Python an excellent
choice for multi-platform development.
Example:
import platform
# Print the platform information
print(platform.system())
print(platform.release())
Data Science:
Libraries like pandas, NumPy, and Matplotlib make data
manipulation and visualization straightforward.
Example:
import pandas as pd
# Create a DataFrame
data = {'Name': ['John', 'Anna', 'Peter', 'Linda'],
'Age': [28, 24, 35, 32]}
df = pd.DataFrame(data)
# Display the DataFrame
print(df)
Machine Learning:
Frameworks like TensorFlow and scikit-learn provide tools for
building and training machine learning models.
Example:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
# Load dataset
iris = datasets.load_iris()
# Split dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3)
# Train a k-nearest neighbors classifier
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)
# Predict and evaluate
print(knn.score(X_test, y_test))
9. Integration Capabilities
Python can easily integrate with other languages and technologies. It
provides various tools and libraries for integrating with C, C++, Java, and
.NET, making it an ideal choice for projects that require interoperability
between different programming languages.
Example:
# Example using the ctypes library to call a C function
import ctypes
# Load the shared library
mylib = ctypes.CDLL('mylib.so')
# Call a function from the library
result = mylib.my_function(5)
print(result)
1.1.5 PYTHON IN THE REAL WORLD
Python's versatility and simplicity have led to its widespread
adoption across various industries and applications. This document explores
how Python is applied in different domains, highlighting its impact and
usefulness with detailed examples.
1. Web Development
Frameworks and Tools:
Python's powerful web frameworks, such as Django, Flask, and
Pyramid, facilitate rapid development of robust web applications. These
frameworks provide built-in tools and libraries that simplify tasks like
database integration, form handling, and user authentication.
Example: Django is used by large companies like Instagram and
Pinterest to handle massive amounts of user data and interactions. Django’s
"batteries-included" philosophy means it comes with most of the features
needed for a web application right out of the box, including an ORM,
authentication, and admin interface.
Case Study: Instagram:
Instagram, a leading social media platform, uses Django to handle
its backend operations. Django’s efficiency and scalability allow Instagram
to manage the high volume of user data and interactions seamlessly.
Instagram leverages Django to serve billions of users and handle extensive
data operations efficiently.
Example Code:
from django.shortcuts import render
from .models import Post
def home(request):
posts = Post.objects.all()
return render(request, 'home.html', {'posts': posts})
5. Scientific Computing
Scientific Libraries:
Python’s scientific libraries, such as SciPy, SymPy, and BioPython,
are extensively used in scientific research for performing complex
mathematical computations and simulations.
Example: SciPy is used for scientific and technical computing,
providing modules for optimization, integration, interpolation, eigenvalue
problems, algebraic equations, and more.
Case Study: CERN:
CERN, the European Organization for Nuclear Research, uses
Python for data analysis in its Large Hadron Collider experiments. Python
scripts analyze the vast amounts of data generated by particle collisions to
discover new particles and understand fundamental physics.
Example Code:
import numpy as np
from scipy.integrate import quad
# Define a function
def integrand(x):
return np.exp(-x**2)
# Perform integration
result, error = quad(integrand, 0, 1)
print(f'Result: {result}, Error: {error}')
Example Code:
import pygame
# Initialize the game engine
pygame.init()
# Set up display
screen = pygame.display.set_mode((800, 600))
# Main game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
pygame.display.flip()
pygame.quit()
9. Cybersecurity
Security Tools:
Python is extensively used in cybersecurity for writing scripts that
automate security tasks, conduct penetration testing, and analyze malware.
Example: Libraries like Scapy and Pyshark are used for network
analysis and packet manipulation.
Case Study: Dropbox:
Dropbox uses Python to secure its file hosting and sharing services.
Python scripts automate security checks, vulnerability scans, and intrusion
detection, ensuring the platform remains secure and reliable.
Example Code:
from scapy.all import *
# Packet sniffer
def packet_callback(packet):
print(packet.show())
# Start sniffing
sniff(prn=packet_callback, count=10)
12. Robotics
Robotics Libraries:
Python is extensively used in robotics for control systems,
automation, and sensor data processing. Libraries such as ROS (Robot
Operating System) and PyRobot facilitate robotics programming.
Example: Python scripts are used to control robotic movements,
process sensor data, and implement machine learning algorithms for
autonomous behavior.
Case Study: NASA Mars Rovers:
NASA uses Python for various aspects of its Mars Rover missions,
including data analysis and control systems. Python helps in processing the
data received from the rovers and controlling their movements and
operations remotely.
Example Code:
import rospy
from geometry_msgs.msg import Twist
# Initialize the ROS node
rospy.init_node('robot_mover', anonymous=True)
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
# Move the robot
move_cmd = Twist()
move_cmd.linear.x = 0.5 # Move forward at 0.5 m/s
pub.publish(move_cmd)
Jupyter Notebook
Jupyter Notebook is an open-source web application that allows you
to create and share documents containing live code, equations,
visualizations, and narrative text. It is widely used in data science, machine
learning, and scientific research.
Installing Jupyter Notebook:
Ensure you have Python installed.
Install Jupyter using pip:
pip install notebook
Sublime Text
Sublime Text is a sophisticated text editor for code, markup, and
prose. It is known for its speed and efficiency and is highly customizable.
Downloading and Installing Sublime Text:
Go to the Sublime Text website and download the installer for your
operating system.
Run the installer and follow the on-screen instructions to complete
the installation.
Basic Commands:
git add . # Add changes to the staging area
git commit -m "Commit message" # Commit changes
git push # Push changes to the remote repository
Managing Packages:
Install Packages:
pip install package_name # Install a package
pip install -r requirements.txt # Install packages from a requirements file
Freeze Environment:
pip freeze > requirements.txt # Save the current environment to a requirements file
5. Customizing Your IDE
Customize your IDE settings to enhance productivity:
PyCharm:
Code Style and Formatting: Configure code style settings under
Preferences > Editor > Code Style > Python.
Keymaps: Customize keybindings under Preferences > Keymap.
VSCode:
Settings and Extensions: Modify settings in settings.json. Install
extensions from the marketplace for additional functionalities.
Snippets: Create custom code snippets for commonly used code
blocks.
Jupyter Notebook:
Extensions: Use nbextensions to add functionalities like Table of
Contents, Variable Inspector, etc.
Themes: Customize the appearance with Jupyter themes.
Sublime Text:
Preferences: Modify user preferences in Preferences > Settings.
Key Bindings: Customize key bindings in Preferences > Key
Bindings.
6. Additional Tools and Extensions
Enhance your development environment with additional tools:
Linters and Formatters: Use flake8 for linting and black for code
formatting.
pip install flake8 black
flake8 your_script.py # Run linter
black your_script.py # Format code
Run the script: Right-click anywhere in the editor and select Run
'hello_world'. Alternatively, click the green Run button in the toolbar.
Output: The Run window at the bottom will display Hello, World!.
Visual Studio Code (VSCode):
Open VSCode.
Open the folder containing your script: Go to File > Open Folder,
and select the folder where hello_world.py is saved.
Write the script (if not already written): Create a new file and save it
as hello_world.py. Type the following code:
print("Hello, World!")
Save the file and run source ~/.bash_profile (or the respective file
for your shell).
pip Is Not Recognized as an Internal or External Command
Cause: This usually happens when pip is not installed or not added
to the PATH environment variable.
Solution:
Ensure that pip is installed by running:
python -m ensurepip --upgrade
Incomplete Installation
Cause: The installer might not have completed properly due to
network issues or interruptions.
Solution:
Re-download the installer from the official Python website.
Ensure a stable internet connection during the download and
installation process.
Restart your computer after installation to ensure all changes take
effect.
SSL/TLS Certificate Issues
Cause: This can occur if the SSL/TLS certificates required by
Python are not correctly set up.
Solution:
Update the certificates on your system.
On macOS, use the Install Certificates.command found in the
Python installation directory.
On Linux, ensure the ca-certificates package is installed and
updated:
sudo apt-get install --reinstall ca-certificates
Or:
python3 --version
Or:
pip3 --version
1.3 PYTHON SYNTAX BASICS
Python is known for its clear and readable syntax, which makes it an
excellent choice for beginners. This section covers the fundamental
elements of Python syntax, including how to write and run Python code.
We'll delve into variables, data types, operators, control structures,
functions, and more, providing a comprehensive foundation for your Python
programming journey.
1.3.1 WRITING AND RUNNING PYTHON
CODE
Writing Python Code
Creating a Python Script:
Open a text editor or IDE: Use any text editor (like Notepad,
Sublime Text) or an IDE (like PyCharm, VSCode).
Write Python code: Start with a simple example:
print("Hello, World!")
Save the file: Save your file with a .py extension, such as
hello_world.py.
Running Python Code:
Command Line: Open a terminal or command prompt, navigate to
the directory where your script is saved, and run:
python hello_world.py
Operators:
Arithmetic operators: +, -, *, /, // (floor division), % (modulus),
** (exponentiation).
Comparison operators: ==, !=, >, <, >=, <=.
Logical operators: and, or, not.
Example:
a = 10
b=3
print(a + b) # Output: 13
print(a / b) # Output: 3.333...
print(a // b) # Output: 3
print(a > b) # Output: True
print(a == 10 and b < 5) # Output: True
Strings:
Strings can be enclosed in single (') or double (") quotes.
Multi-line strings use triple quotes (''' or """).
Example:
greeting = "Hello"
multi_line_str = """This is
a multi-line
string."""
String concatenation:
full_greeting = greeting + " World!"
print(full_greeting) # Output: Hello World!
Lists:
Lists are ordered collections of items, which can be of different
types.
Example:
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # Output: apple
fruits.append("orange")
print(fruits) # Output: ['apple', 'banana', 'cherry', 'orange']
Tuples:
Tuples are similar to lists but are immutable (cannot be changed).
Example:
dimensions = (1920, 1080)
print(dimensions[0]) # Output: 1920
Dictionaries:
Dictionaries are collections of key-value pairs.
Example:
person = {"name": "Alice", "age": 25}
print(person["name"]) # Output: Alice
person["age"] = 26
print(person) # Output: {'name': 'Alice', 'age': 26}
Control Structures:
if statements: Conditional execution.
for loops: Iterating over a sequence.
while loops: Repeatedly executing a block as long as a condition is
true.
Examples:
# If statement
age = 18
if age >= 18:
print("You are an adult.")
else:
print("You are a minor.")
# For loop
for fruit in fruits:
print(fruit)
# While loop
count = 0
while count < 5:
print(count)
count += 1
Functions:
Functions are defined using the def keyword and are used to
encapsulate reusable code blocks.
Example:
def greet(name):
return f"Hello, {name}!"
print(greet("Alice")) # Output: Hello, Alice!
Importing Modules:
Python has a rich standard library and allows you to import modules
to extend functionality.
Example:
import math
print(math.sqrt(16)) # Output: 4.0
File Handling:
Reading from and writing to files.
Example:
# Writing to a file
with open("test.txt", "w") as file:
file.write("Hello, World!")
# Reading from a file
with open("test.txt", "r") as file:
content = file.read()
print(content) # Output: Hello, World!
Error Handling:
Using try, except, finally to handle exceptions.
Example:
try:
number = int(input("Enter a number: "))
print(f"You entered: {number}")
except ValueError:
print("That's not a valid number!")
finally:
print("This block always executes.")
Jupyter Notebook:
Write Code: Open Jupyter Notebook and create a new notebook.
Run Code: Write your code in a cell and press Shift + Enter.
Sublime Text:
Write Code: Open Sublime Text and write your code.
Run Code: Open the command palette (Ctrl + Shift + P), type
Anaconda: Run Python, and select it.
1.3.2 BASIC SYNTAX AND STRUCTURE
Python's syntax is designed to be readable and straightforward. This
section will cover the main aspects of Python's basic syntax and structure,
including comments, variables, data types, operators, control structures,
functions, and error handling.
1. Comments
Comments are used to annotate the code, making it easier to
understand. They are not executed by the interpreter.
Single-line comments: Start with a #.
# This is a single-line comment
print("Hello, World!") # This is an inline comment
3. Operators
Operators are used to perform operations on variables and values.
Arithmetic Operators: Perform mathematical operations.
+ (addition), - (subtraction), * (multiplication), / (division), // (floor
division), % (modulus), ** (exponentiation).
Example:
a = 12
b=5
print(a + b) # Output: 17
print(a / b) # Output: 2.4
print(a // b) # Output: 2
print(a % b) # Output: 2
print(a ** b) # Output: 248832
4. Control Structures
Control structures are used to control the flow of execution in a
program.
Conditional Statements (if, elif, else):
Used to execute code based on a condition.
Example:
score = 85
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B")
elif score >= 70:
print("Grade: C")
else:
print("Grade: D or F")
Loops:
for Loop: Iterates over a sequence.
Example:
languages = ["Python", "Java", "C++"]
for language in languages:
print(language)
5. Functions
Functions are reusable blocks of code that perform a specific task.
Defining a Function:
Functions are defined using the def keyword.
Example:
def multiply(x, y):
return x * y
print(multiply(4, 7)) # Output: 28
Default Arguments:
Provide default values for parameters.
Example:
def greet(name="Visitor"):
return f"Welcome, {name}!"
print(greet()) # Output: Welcome, Visitor!
print(greet("Michael")) # Output: Welcome, Michael!
Keyword Arguments:
Specify arguments by the parameter name.
Example:
def calculate_volume(length, width, height):
return length * width * height
print(calculate_volume(width=3, height=4, length=5)) # Output: 60
6. Importing Modules
Python's rich standard library allows you to import modules to
extend the functionality of your programs.
Importing a Module:
Use the import statement to include modules.
Example:
import math
print(math.sqrt(64)) # Output: 8.0
Renaming Imports:
Use as to rename imports.
Example:
import pandas as pd
data = {"name": ["John", "Anna"], "age": [28, 24]}
df = pd.DataFrame(data)
print(df)
7. File Handling
Python provides built-in functions to read from and write to files,
making it easy to handle file operations such as reading data from files and
writing data to files.
Writing to a File:
Use the open function with mode 'w' to write to a file.
The mode 'w' stands for write mode, which will create a new file if
it does not exist or overwrite the existing file.
Example:
with open("example.txt", "w") as file:
file.write("Learning Python!")
Appending to a File:
Use the open function with mode 'a' to append to a file.
The mode 'a' stands for append mode, which is used to add data to
the end of a file without overwriting the existing content.
Example:
with open("example.txt", "a") as file:
file.write("\nEnjoying the journey!")
8. Error Handling
Python uses try, except, else, and finally blocks to handle
exceptions and errors gracefully. This allows you to handle errors without
crashing your program and to take specific actions based on the type of
error that occurred.
Basic Error Handling:
Use try and except blocks to catch and handle exceptions.
Example:
try:
age = int(input("Enter your age: "))
print(f"You are {age} years old.")
except ValueError:
print("Invalid input! Please enter a number.")
Raising Exceptions:
Use the raise keyword to raise an exception manually.
Example:
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero.")
return a / b
try:
result = divide(10, 0)
except ValueError as e:
print(e) # Output: Cannot divide by zero.
1.3.3 COMMENTS IN PYTHON
Comments are an essential part of programming. They are used to
explain the code, making it easier to understand for anyone reading it,
including the original author. In Python, comments can be used to explain
the purpose of the code, describe how the code works, or to leave notes for
future reference. Comments are ignored by the Python interpreter, so they
do not affect the execution of the program.
Types of Comments in Python
Single-line Comments:
Single-line comments are created using the hash symbol (#).
Everything following the # on that line is treated as a comment and is
ignored by the interpreter.
They are useful for brief explanations or notes.
Example:
# This is a single-line comment
print("Hello, World!") # This is an inline comment
Multi-line Comments:
Multi-line comments are typically created using triple quotes (''' or
"""). Although technically these are multi-line strings, they can be used as
comments because they are not assigned to a variable or used in any
operation.
They are useful for providing detailed explanations or commenting
out blocks of code during debugging.
Example:
"""
This is a multi-line comment.
It can span multiple lines.
Useful for longer explanations.
"""
print("Hello, World!")
Best Practices for Writing Comments
Keep Comments Clear and Concise:
Comments should be easy to read and understand. Avoid
unnecessary information and focus on the purpose of the code.
Example:
# Calculate the area of a rectangle
length = 5
width = 3
area = length * width
print(area)
Consistency:
Consistent indentation is crucial. Mixing tabs and spaces can lead to
errors.
PEP 8, the Python style guide, recommends using 4 spaces per
indentation level.
Example:
for i in range(5):
print(i) # Correct indentation with 4 spaces
# Mixing tabs and spaces can cause an IndentationError
IndentationError:
An IndentationError occurs when the levels of indentation are not
consistent.
Python will not execute a program with incorrect indentation, which
helps to avoid logical errors.
Example:
def example():
print("Hello")
print("World") # This will raise an IndentationError because it is not correctly indented
Loops:
The body of loops (for and while) is indented.
Nested loops or conditionals within loops need further indentation.
Example:
for i in range(3):
print(f"Outer loop iteration {i}")
for j in range(2):
print(f" Inner loop iteration {j}")
count = 0
while count < 3:
print(f"Count is {count}")
count += 1
Conditional Statements:
The body of if, elif, and else statements must be indented.
Each block should be indented to the same level.
Example:
x = 10
if x > 5:
print("x is greater than 5")
elif x == 5:
print("x is 5")
else:
print("x is less than 5")
Nested Blocks:
When blocks are nested within other blocks, each subsequent level
of block must be further indented.
Example:
for i in range(3):
if i % 2 == 0:
print(f"{i} is even")
else:
print(f"{i} is odd")
Try/Except Blocks:
The try, except, else, and finally blocks each need to be indented.
Example:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
else:
print("Division successful")
finally:
print("Execution completed")
Best Practices for Indentation
Use Spaces Over Tabs:
According to PEP 8, use 4 spaces per indentation level. This is the
most common practice and ensures consistency across different editors and
environments.
Configure Your Text Editor:
Configure your text editor to automatically convert tabs to spaces.
Most modern text editors and IDEs have this feature.
Example for VS Code:
Go to File -> Preferences -> Settings, and search for insertSpaces.
Set it to true and tabSize to 4.
Consistent Style:
Stick to one style throughout your codebase. Consistency helps
maintain readability and reduces errors.
Code Formatting Tools:
Use code formatting tools like black or linters like flake8 to
automatically format your code and ensure consistent indentation.
Example:
pip install black
black your_script.py
1.3.5 PYTHON IDE SHORTCUTS AND
TIPS
Using an Integrated Development Environment (IDE) can
significantly enhance your productivity and efficiency when writing Python
code. IDEs like PyCharm, Visual Studio Code (VSCode), and Jupyter
Notebook offer numerous shortcuts and tips that can streamline your
workflow. This section provides detailed information on some of the most
useful shortcuts and tips for these popular Python IDEs.
PyCharm
Navigation Shortcuts:
Go to Class/File/Symbol: Ctrl + N / Cmd + N (Mac)
Quickly navigate to any class, file, or symbol in your project.
Navigate to Declaration: Ctrl + B / Cmd + B (Mac)
Jump to the declaration of a variable, function, or class.
Navigate Backward/Forward: Ctrl + Alt + Left/Right / Cmd +
Option + Left/Right (Mac)
Navigate through your recent locations in the code.
Editing Shortcuts:
Duplicate Line or Block: Ctrl + D / Cmd + D (Mac)
Duplicate the current line or selected block.
Delete Line: Ctrl + Y / Cmd + Backspace (Mac)
Delete the current line.
Comment/Uncomment Line: Ctrl + / / Cmd + / (Mac)
Toggle commenting on the current line or selected lines.
Reformat Code: Ctrl + Alt + L / Cmd + Option + L (Mac)
Reformat your code according to the style guide.
Code Assistance:
IntelliJ Auto-Completion: Ctrl + Space / Cmd + Space (Mac)
Trigger basic code completion.
Quick Documentation: Ctrl + Q / Ctrl + J / Cmd + J (Mac)
Show the documentation for the selected item.
Generate Code (Getters/Setters, etc.): Alt + Insert / Cmd + N
(Mac)
Automatically generate code for getters, setters, and other
boilerplate code.
Debugging Shortcuts:
Toggle Breakpoint: Ctrl + F8 / Cmd + F8 (Mac)
Toggle a breakpoint on the current line.
Step Over/Into/Out: F8/F7/Shift + F8 / F8/F7/Shift + F8 (Mac)
Control the flow of execution in the debugger.
Useful Tips:
Live Templates: Use live templates to insert common code snippets
quickly. Configure these under Settings > Editor > Live Templates.
Version Control Integration: PyCharm seamlessly integrates with
Git and other version control systems, allowing you to manage your code
versions effectively.
Visual Studio Code (VSCode)
Navigation Shortcuts:
Quick Open: Ctrl + P / Cmd + P (Mac)
Quickly open any file.
Go to Definition: F12
Navigate to the definition of a symbol.
Peek Definition: Alt + F12 / Option + F12 (Mac)
Peek at the definition of a symbol without navigating away.
Go to Symbol: Ctrl + Shift + O / Cmd + Shift + O (Mac)
Jump to a specific symbol in a file.
Editing Shortcuts:
Duplicate Line: Shift + Alt + Down/Up / Shift + Option +
Down/Up (Mac)
Duplicate the current line.
Move Line Up/Down: Alt + Up/Down / Option + Up/Down (Mac)
Move the current line up or down.
Comment/Uncomment Line: Ctrl + / / Cmd + / (Mac)
Toggle comments on the current line or selected lines.
Format Document: Shift + Alt + F / Shift + Option + F (Mac)
Format the entire document.
Code Assistance:
IntelliSense: Ctrl + Space / Cmd + Space (Mac)
Trigger IntelliSense for code completion.
Show References: Shift + F12
Show all references to a symbol.
Rename Symbol: F2
Rename all instances of a symbol.
Debugging Shortcuts:
Toggle Breakpoint: F9
Toggle a breakpoint on the current line.
Start/Continue Debugging: F5
Start or continue the debugging session.
Step Over/Into/Out: F10/F11/Shift + F11
Control the flow of execution in the debugger.
Useful Tips:
Extensions: Enhance your coding experience by installing
extensions such as Python, Pylance, and Jupyter.
Integrated Terminal: Use the integrated terminal (Ctrl + ) to run
commands without leaving VSCode.
Tasks: Automate common tasks using the tasks feature (Terminal >
Run Task).
Jupyter Notebook
Navigation and Cell Execution:
Run Cell: Shift + Enter
Execute the current cell and move to the next cell.
Run Cell and Insert Below: Alt + Enter
Execute the current cell and insert a new cell below.
Run All Cells: Cell > Run All
Execute all cells in the notebook.
Editing Shortcuts:
Change Cell to Code: Y
Change the current cell to a code cell.
Change Cell to Markdown: M
Change the current cell to a Markdown cell.
Insert Cell Above/Below: A/B
Insert a new cell above or below the current cell.
Cell Management:
Delete Cell: D, D (press D twice)
Delete the current cell.
Merge Cells: Shift + M
Merge the selected cells.
Navigation Shortcuts:
Move to Next Cell: Down Arrow
Move to the next cell.
Move to Previous Cell: Up Arrow
Move to the previous cell.
Useful Tips:
Magic Commands: Use magic commands like %timeit to measure
the execution time of a code snippet or %matplotlib inline to display
matplotlib plots inline.
Kernel Management: Restart the kernel to clear all variables and
states (Kernel > Restart).
Export Notebooks: Export your notebook to different formats (File
> Download as).
CHAPTER 2: VARIABLES AND
DATA TYPES
2.1 UNDERSTANDING VARIABLES
2.2.1 WHAT ARE VARIABLES?
Variables are fundamental concepts in programming, serving as
storage locations for data values. In Python, a variable is created when you
assign a value to it, and this value can be changed throughout the execution
of a program. Variables are essential because they allow programs to store,
retrieve, and manipulate data dynamically.
Key Characteristics of Variables in Python
Dynamic Typing:
Python is dynamically typed, which means you don't have to declare
the type of a variable when you create one. The type is inferred from the
value you assign to the variable.
For example:
x = 10 # x is an integer
y = 3.14 # y is a float
name = "Alice" # name is a string
Type Inference:
Python infers the type of a variable based on the value assigned to it.
This allows for more flexible and readable code.
For example:
a=5 # a is an integer
a = "Hello" # a is now a string
Reassignment:
Variables in Python can be reassigned to different values, and the
type can change with each reassignment.
For example:
b = 20 # b is an integer
b = 4.5 # b is now a float
b = "Python" # b is now a string
Creating Variables
To create a variable in Python, you simply assign a value to a name
using the equals (=) sign. The syntax is straightforward:
variable_name = value
Example:
age = 25
height = 5.9
first_name = "John"
is_student = True
Naming Variables
Naming variables appropriately is crucial for code readability and
maintenance. Here are some rules and best practices for naming variables in
Python:
Rules:
Variable names must start with a letter (a-z, A-Z) or an underscore
(_).
The rest of the variable name can contain letters, digits (0-9), and
underscores.
Variable names are case-sensitive (age, Age, and AGE are three
different variables).
Reserved words (keywords) cannot be used as variable names.
Examples:
valid_name = 10
_hidden_variable = 20
firstName = "Alice"
Best Practices:
Use meaningful names that describe the purpose of the variable.
Follow a consistent naming convention, such as snake_case for
variable names.
Avoid using single-letter names except for loop counters or in
contexts where the meaning is clear.
Examples:
total_price = 100.50
user_age = 30
is_valid = True
Variable Scope
The scope of a variable determines where in the code the variable
can be accessed or modified. In Python, variables can have different scopes:
Local Scope:
Variables declared inside a function are local to that function and
cannot be accessed outside of it.
Example:
def my_function():
local_var = 10
print(local_var)
my_function()
# print(local_var) # This will raise an error because local_var is not accessible outside the function
Global Scope:
Variables declared outside of all functions are global and can be
accessed from any function within the same module.
Example:
global_var = 5
def my_function():
print(global_var)
my_function() # Output: 5
Nonlocal Scope:
The nonlocal keyword is used to declare that a variable inside a
nested function is not local to that function but exists in the enclosing (non-
global) scope.
Example:
def outer_function():
outer_var = "I am outside!"
def inner_function():
nonlocal outer_var
outer_var = "I am inside!"
print(outer_var)
inner_function()
print(outer_var)
outer_function()
2.1.2 DECLARING AND INITIALIZING
VARIABLES
In Python, variables are essential components used to store and
manipulate data. Unlike some other programming languages, Python does
not require explicit declaration of variable types. This section explores how
to declare and initialize variables in Python, including best practices and
common mistakes to avoid.
Variable Declaration
Dynamic Typing:
Python uses dynamic typing, which means that the type of the
variable is determined at runtime. You do not need to declare the type of the
variable explicitly.
Example:
age = 25 # age is an integer
price = 19.99 # price is a float
name = "John" # name is a string
is_student = True # is_student is a boolean
Multiple Assignments:
Python allows you to assign values to multiple variables in a single
statement, which can be useful for initializing related variables together.
Example:
x, y, z = 10, 20.5, "Python"
Initializing Variables
Initialization:
Initializing a variable means assigning it an initial value. In Python,
this is done at the time of declaration.
Example:
count = 100 # Initialize count to 100
temperature = 36.6 # Initialize temperature to 36.6
username = "guest" # Initialize username to "guest"
logged_in = False # Initialize logged_in to False
Variable Scope
Local Scope:
Variables declared inside a function are local to that function and
cannot be accessed outside it.
Example:
def calculate_total():
subtotal = 100
tax = 10
total = subtotal + tax
print(total)
calculate_total()
# print(subtotal) # This will raise an error because subtotal is not accessible outside the function
Global Scope:
Variables declared outside of all functions are global and can be accessed
from any function within the same module.
Example:
discount = 5
def apply_discount(price):
return price - discount
print(apply_discount(100)) # Output: 95
Nonlocal Scope:
The nonlocal keyword allows you to modify a variable in an enclosing
(non-global) scope.
Example:
def outer_function():
message = "Hello"
def inner_function():
nonlocal message
message = "Hi"
print(message)
inner_function()
print(message)
outer_function()
Common Mistakes
Using Uninitialized Variables:
Attempting to use a variable before it has been assigned a value will
result in a NameError.
Example:
def process_data():
print(data) # This will raise a NameError
data = 50
process_data()
Case Sensitivity:
Variable names are case-sensitive. Variable, variable, and
VARIABLE are three different identifiers.
Example:
total = 100
Total = 200 # Different from total
Constants in Uppercase:
Constants should be written in all uppercase letters with underscores
separating words.
Example:
MAX_CONNECTIONS = 100
PI = 3.14159
Private Variables:
For private variables (intended for internal use in a class or module),
prefix the name with an underscore.
Example:
_internal_counter = 0
Class Variables:
Use the self keyword to refer to instance variables within a class.
For class-level variables, use all uppercase if they are constants.
Example:
class MyClass:
CLASS_CONSTANT = 42
def __init__(self, value):
self.instance_variable = value
Global Variables:
Global variables should be avoided when possible. If used, they
should be named with all uppercase letters if they are constants.
Example:
GLOBAL_CONFIG = "config.yaml"
Best Practices
Descriptive Names:
Use descriptive names that convey the purpose of the variable.
Avoid single-letter names except for simple counters in loops.
Example:
total_sales = 1500.75
average_temperature = 23.5
Avoid Ambiguity:
Ensure variable names are not ambiguous and clearly differentiate
between different types of data.
Example:
total = 100
total_amount = 100 # Better than using just 'total' for different purposes
Benefits:
Improves readability and makes the code self-documenting.
Reduces the need for additional comments to explain the variable's
purpose.
2. Follow Naming Conventions
Snake_case for Variables:
Use snake_case (lowercase letters with underscores) for variable
names as recommended by PEP 8.
Examples:
first_name = "Alice"
last_name = "Smith"
total_amount = 150.75
Constants in Uppercase:
Use all uppercase letters with underscores for constants.
Examples:
MAX_RETRIES = 5
PI = 3.14159
Benefits:
Consistency in naming conventions makes the code easier to read
and maintain.
Differentiates variable types at a glance (e.g., regular variables vs.
constants).
3. Avoid Reserved Words and Built-in Names
Purpose:
Reserved words (keywords) and built-in function names should not
be used as variable names to prevent conflicts and unexpected behavior.
Examples:
# Incorrect
def = 5
list = [1, 2, 3]
# Correct
definition = 5
my_list = [1, 2, 3]
Benefits:
Avoids syntax errors and overwriting built-in functions or keywords.
Ensures that the code behaves as expected.
4. Use Meaningful Names Even for Temporary Variables
Purpose:
Even for short-lived or temporary variables, meaningful names
should be used.
Examples:
# Good
for index in range(10):
print(index)
# Bad
for i in range(10):
print(i)
Benefits:
Enhances readability, especially in loops and comprehensions where
the variable is reused multiple times.
5. Avoid Ambiguous Names
Purpose:
Names that are too similar or ambiguous can cause confusion and
errors.
Examples:
# Ambiguous
user_data1 = "Alice"
user_data2 = "Bob"
# Clear
user_first_name = "Alice"
user_last_name = "Smith"
Benefits:
Reduces the likelihood of mistakes and makes the code easier to
understand.
6. Use Single-letter Names Sparingly
Purpose:
Single-letter names should be reserved for variables with a very
short scope, such as loop counters.
Examples:
# Good
for i in range(5):
print(i)
# Bad
total = 0
for t in range(10):
total += t
Benefits:
Prevents confusion over the purpose of the variable and maintains
clarity.
7. Maintain Consistency Across the Codebase
Purpose:
Consistency in naming conventions throughout the codebase
improves readability and makes it easier to collaborate with other
developers.
Examples:
# Consistent
user_count = 5
total_users = 10
# Inconsistent
user_count = 5
totalMembers = 10
Benefits:
Ensures that the code is uniform and predictable, reducing the
learning curve for new developers.
8. Prefix Private Variables with an Underscore
Purpose:
Prefix private variables with an underscore to indicate that they are
intended for internal use only.
Examples:
class MyClass:
def __init__(self):
self._private_variable = 42
Benefits:
Clarifies the intended scope and usage of the variable, helping to
prevent accidental access or modification from outside the intended context.
9. Use Plural Names for Collections
Purpose:
Use plural names for variables that store collections (lists, sets,
dictionaries, etc.).
Examples:
# Good
users = ["Alice", "Bob", "Charlie"]
settings = {"theme": "dark", "language": "en"}
# Bad
user = ["Alice", "Bob", "Charlie"]
setting = {"theme": "dark", "language": "en"}
Benefits:
Clearly indicates that the variable holds multiple items, improving
readability.
10. Use self for Instance Variables
Purpose:
Use the self keyword for instance variables within class methods.
Examples:
class MyClass:
def __init__(self, value):
self.value = value
def display_value(self):
print(self.value)
Benefits:
Follows standard conventions, making the code more
understandable and consistent with other Python code.
2.2 BASIC DATA TYPES
Python supports several basic data types that are integral to any
programming language. These include integers, floats, strings, and
booleans. This section will focus on integers and floats, providing a detailed
understanding of these numeric types, along with various examples to help
you grasp these concepts quickly and effectively.
2.2.1 INTEGERS AND FLOATS
Integers and floats are the primary numeric data types in Python.
They are used to represent whole numbers and numbers with decimal
points, respectively.
Integers
Definition:
An integer is a whole number without a fractional component. It can
be positive, negative, or zero.
Examples:
age = 25 # Positive integer
temperature = -5 # Negative integer
count = 0 # Zero
Operations on Integers:
Integers can be manipulated using various arithmetic operators like
addition (+), subtraction (-), multiplication (*), division (/), modulus (%),
exponentiation (**), and floor division (//).
Examples:
a = 10
b=3
# Addition
sum_result = a + b # 13
# Subtraction
difference = a - b # 7
# Multiplication
product = a * b # 30
# Division
quotient = a / b # 3.333...
# Modulus
remainder = a % b # 1
# Exponentiation
power = a ** b # 1000
# Floor Division
floor_div = a // b # 3
Type Conversion:
Integers can be converted to other data types and vice versa using
type conversion functions like int(), float(), and str().
Examples:
float_number = 12.34
integer_number = int(float_number) # 12
string_number = "56"
integer_from_string = int(string_number) # 56
Large Integers:
Python supports arbitrarily large integers, limited only by the
available memory.
Example:
large_number = 1234567890123456789012345678901234567890
print(large_number) # 1234567890123456789012345678901234567890
Floats
Definition:
A float, or floating-point number, is a number that has a decimal
point. Floats can represent both very large and very small numbers with
fractional parts.
Examples:
pi = 3.14159
gravity = 9.81
negative_float = -5.67
Operations on Floats:
Floats support the same arithmetic operations as integers, but they
handle fractional parts and provide more precision.
Examples:
x = 5.75
y = 2.5
# Addition
sum_result = x + y # 8.25
# Subtraction
difference = x - y # 3.25
# Multiplication
product = x * y # 14.375
# Division
quotient = x / y # 2.3
# Modulus
remainder = x % y # 0.75
# Exponentiation
power = x ** y # 91.491
# Floor Division
floor_div = x // y # 2.0
Precision Issues:
Floats can sometimes exhibit precision issues due to the way they
are stored in memory. This is a common issue in many programming
languages.
Example:
result = 0.1 + 0.2
print(result) # 0.30000000000000004
Scientific Notation:
Floats can be represented using scientific notation, which is useful
for very large or very small numbers.
Examples:
large_float = 1.23e5 # 123000.0
small_float = 1.23e-5 # 0.0000123
Type Conversion:
Floats can be converted to other data types using functions like
float(), int(), and str().
Examples:
integer_number = 42
float_number = float(integer_number) # 42.0
string_number = "3.14"
float_from_string = float(string_number) # 3.14
Mixed-Type Operations
Mixed Operations:
When performing operations between integers and floats, Python
will convert the integers to floats to ensure the precision of the operation.
Examples:
a=5
b = 2.5
# Addition
result = a + b # 7.5
# Multiplication
result = a * b # 12.5
# Division
result = a / b # 2.0
Double Quotes:
Strings can also be created using double quotes, which is useful if
the string itself contains single quotes.
quote = "Python's simplicity is beautiful."
Triple Quotes:
Triple quotes are used for multi-line strings or strings that contain
both single and double quotes.
multi_line_string = """This is a multi-line string.
It spans multiple lines."""
String Operations
Strings in Python support various operations, making it easy to
manipulate and work with text data.
Concatenation:
You can concatenate (join) two or more strings using the + operator.
first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name # "John Doe"
Repetition:
The * operator can be used to repeat a string multiple times.
repeated_string = "Hello! " * 3 # "Hello! Hello! Hello! "
Indexing:
Strings are indexed, meaning you can access individual characters
using square brackets []. Indexing starts at 0.
string = "Python"
first_char = string[0] # 'P'
last_char = string[-1] # 'n'
Slicing:
You can extract a substring from a string using slicing. The syntax is
string[start:end], where start is the starting index and end is the ending
index (exclusive).
string = "Hello, World!"
substring = string[0:5] # "Hello"
String Methods
Python provides numerous built-in methods for string manipulation.
len():
The len() function returns the length of a string.
string = "Python"
length = len(string) # 6
strip():
The strip() method removes any leading and trailing whitespace
from the string.
string = " Hello, World! "
stripped_string = string.strip() # "Hello, World!"
split():
The split() method splits the string into a list of substrings based on
a delimiter.
string = "apple,banana,cherry"
fruit_list = string.split(",") # ['apple', 'banana', 'cherry']
join():
The join() method joins a list of strings into a single string with a
specified delimiter.
fruits = ["apple", "banana", "cherry"]
joined_string = ", ".join(fruits) # "apple, banana, cherry"
replace():
The replace() method replaces occurrences of a substring with
another substring.
string = "I like cats"
new_string = string.replace("cats", "dogs") # "I like dogs"
find():
The find() method returns the lowest index of the substring if it is
found in the string. If not, it returns -1.
string = "Hello, World!"
index = string.find("World") # 7
String Formatting
String formatting is used to create formatted strings. Python
provides several ways to format strings:
% Operator:
This is an old-style string formatting method.
name = "John"
age = 30
formatted_string = "My name is %s and I am %d years old." % (name, age)
str.format():
This method uses curly braces {} as placeholders.
name = "John"
age = 30
formatted_string = "My name is {} and I am {} years old.".format(name, age)
Escape Characters
Escape characters are used to insert characters that are illegal in a
string. For example, you might want to include a double quote inside a
string that is enclosed in double quotes.
Common Escape Characters:
\\ - Backslash
\' - Single quote
\" - Double quote
\n - Newline
\t - Tab
Examples:
single_quote = 'It\'s a sunny day.'
double_quote = "He said, \"Hello!\""
new_line = "Hello\nWorld"
tabbed_string = "Name:\tJohn"
2.2.3 BOOLEANS
Booleans are a fundamental data type in Python, representing one of
two values: True or False. They are used in various operations, particularly
in conditional statements and logical operations, to control the flow of a
program.
Boolean Values
Definition:
Booleans in Python are a subclass of integers. They can take on one
of two values: True or False.
Example:
is_raining = True
has_passed = False
Type Conversion:
Boolean values can be converted to integers, where True becomes 1
and False becomes 0.
Example:
true_value = True
false_value = False
print(int(true_value)) # Output: 1
print(int(false_value)) # Output: 0
Boolean Operations
Logical Operations:
Boolean values are commonly used with logical operators to
perform logical operations.
Operators:
and: Returns True if both operands are True.
or: Returns True if at least one operand is True.
not: Returns the opposite boolean value.
Examples:
a = True
b = False
# and operator
print(a and b) # Output: False
# or operator
print(a or b) # Output: True
# not operator
print(not a) # Output: False
Comparison Operations:
Boolean values often result from comparison operations.
Operators:
==: Equal to
!=: Not equal to
>: Greater than
<: Less than
>=: Greater than or equal to
<=: Less than or equal to
Examples:
x = 10
y = 20
print(x == y) # Output: False
print(x != y) # Output: True
print(x > y) # Output: False
print(x < y) # Output: True
Boolean Contexts
Conditional Statements:
Booleans are often used in if, elif, and else statements to control the
flow of a program based on conditions.
Examples:
is_valid = True
if is_valid:
print("The data is valid.")
else:
print("The data is not valid.")
Loops:
Booleans are used in loops to determine when the loop should
continue or stop.
Example:
condition = True
while condition:
print("Loop is running")
condition = False # This will stop the loop after one iteration
2.2.4 TYPE CONVERSION
Type conversion, also known as type casting, is the process of
converting a value from one data type to another. In Python, type
conversion can be implicit (automatic) or explicit (manual). Understanding
type conversion is crucial for writing flexible and error-free code.
Implicit Type Conversion
Python automatically converts one data type to another without any
explicit instruction by the user. This type of conversion is called implicit
type conversion or coercion.
Examples:
Integer to Float:
x = 10 # Integer
y = 2.5 # Float
result = x + y # Implicitly converts x to float
print(result) # Output: 12.5
print(type(result)) # Output: <class 'float'>
Boolean to Integer:
a = True # Boolean
b = 5 # Integer
result = a + b # Implicitly converts a to integer (True becomes 1)
print(result) # Output: 6
print(type(result)) # Output: <class 'int'>
String to List:
Convert a string to a list of characters using the list() function.
Example:
s = "Python"
char_list = list(s)
print(char_list) # Output: ['P', 'y', 't', 'h', 'o', 'n']
Dictionary Keys and Values to List:
Convert the keys and values of a dictionary to separate lists.
Example:
d = {'name': 'Alice', 'age': 25}
keys_list = list(d.keys())
values_list = list(d.values())
print(keys_list) # Output: ['name', 'age']
print(values_list) # Output: ['Alice', 25]
2.2.5 DYNAMIC TYPING IN PYTHON
Python is a dynamically typed language, meaning that you don't
need to declare the data type of a variable when you create it. The type is
inferred at runtime, based on the value assigned to the variable. This feature
provides flexibility and ease of use but also requires careful handling to
avoid errors. Let's dive into the details of dynamic typing in Python with
numerous examples to illustrate its concepts.
Type Inference
Automatic Type Inference:
Python determines the type of a variable based on the value assigned
to it.
Example:
age = 25 # Inferred as int
name = "Alice" # Inferred as str
pi = 3.14159 # Inferred as float
is_valid = True # Inferred as bool
Python infers the type from the literal values: integers, strings,
floats, and booleans.
Type Checking
type() Function:
You can use the type() function to check the type of a variable at
runtime.
Examples:
a = 10
print(type(a)) # Output: <class 'int'>
b = "Python"
print(type(b)) # Output: <class 'str'>
c = 3.14
print(type(c)) # Output: <class 'float'>
Reassigning Variables
Changing Types:
You can reassign variables to values of different types, and Python
will automatically update the type.
Examples:
var = 42 # Initially an integer
print(type(var)) # Output: <class 'int'>
var = "text" # Now a string
print(type(var)) # Output: <class 'str'>
var = [1, 2, 3] # Now a list
print(type(var)) # Output: <class 'list'>
Type Hinting
To mitigate some challenges of dynamic typing, Python 3.5
introduced type hints, which provide a way to indicate the expected type of
variables and function return types. This does not enforce types but helps in
improving code readability and can be checked by tools like mypy.
Examples:
def greeting(name: str) -> str:
return "Hello, " + name
def add_numbers(a: int, b: int) -> int:
return a + b
name: str = "Alice"
age: int = 30
Practical Examples
Using Type Hints in Functions:
def calculate_area(radius: float) -> float:
return 3.14159 * (radius ** 2)
print(calculate_area(5.0)) # 78.53975
Concatenation:
Concatenation is the process of joining two or more strings together
using the + operator.
Examples:
str1 = "Hello"
str2 = "World"
result = str1 + " " + str2
print(result) # Output: "Hello World"
Repetition:
The * operator allows you to repeat a string a specified number of
times.
Examples:
str1 = "Hi! "
result = str1 * 3
print(result) # Output: "Hi! Hi! Hi! "
Slicing:
Slicing allows you to obtain a substring from a string. The syntax is
string[start:end], where start is the starting index and end is the ending
index (exclusive).
Examples:
str1 = "Hello, World!"
substring = str1[0:5]
print(substring) # Output: "Hello"
# Omitting start and end
print(str1[:5]) # Output: "Hello"
print(str1[7:]) # Output: "World!"
Case Conversion:
Strings can be converted to upper case, lower case, title case, and
more using built-in methods.
Examples:
str1 = "Python Programming"
# Convert to upper case
print(str1.upper()) # Output: "PYTHON PROGRAMMING"
# Convert to lower case
print(str1.lower()) # Output: "python programming"
# Convert to title case
print(str1.title()) # Output: "Python Programming"
# Convert to capitalize
print(str1.capitalize()) # Output: "Python programming"
Trimming Whitespace:
The strip() method removes leading and trailing whitespace. lstrip()
removes leading whitespace, and rstrip() removes trailing whitespace.
Examples:
str1 = " Hello, World! "
print(str1.strip()) # Output: "Hello, World!"
print(str1.lstrip()) # Output: "Hello, World! "
print(str1.rstrip()) # Output: " Hello, World!"
Joining:
The join() method joins a list of strings into a single string with a
specified delimiter.
Examples:
fruits = ["apple", "banana", "cherry"]
result = ", ".join(fruits)
print(result) # Output: "apple, banana, cherry"
Replacing Substrings:
The replace() method replaces occurrences of a substring with
another substring.
Examples:
str1 = "I like cats"
new_str = str1.replace("cats", "dogs")
print(new_str) # Output: "I like dogs"
Finding Substrings:
The find() method returns the lowest index of the substring if it is
found in the string. If not, it returns -1.
Examples:
str1 = "Hello, World!"
index = str1.find("World")
print(index) # Output: 7
index = str1.find("Python")
print(index) # Output: -1
String Formatting
Old-style Formatting:
Using the % operator.
Examples:
name = "Alice"
age = 30
formatted_str = "My name is %s and I am %d years old." % (name, age)
print(formatted_str) # Output: "My name is Alice and I am 30 years old."
str.format() Method:
Using curly braces {} as placeholders.
Examples:
name = "Alice"
age = 30
formatted_str = "My name is {} and I am {} years old.".format(name, age)
print(formatted_str) # Output: "My name is Alice and I am 30 years old."
Escape Characters:
Escape characters are used to insert characters that are illegal in a
string.
Examples:
single_quote = 'It\'s a sunny day.'
double_quote = "He said, \"Hello!\""
new_line = "Hello\nWorld"
tabbed_string = "Name:\tJohn"
print(single_quote) # Output: It's a sunny day.
print(double_quote) # Output: He said, "Hello!"
print(new_line) # Output:
# Hello
# World
print(tabbed_string) # Output: Name: John
2.3.2 STRING METHODS AND
FORMATTING
Strings in Python come with a variety of built-in methods and
formatting techniques that allow you to manipulate text efficiently. This
section covers these methods and formatting techniques in detail, along
with numerous examples to help you grasp these concepts thoroughly.
String Methods
Python provides many methods to work with strings. These methods
can be categorized into different types based on their functionality.
Case Conversion Methods
upper():
Converts all characters in the string to uppercase.
Example:
text = "hello world"
print(text.upper()) # Output: "HELLO WORLD"
lower():
Converts all characters in the string to lowercase.
Example:
text = "HELLO WORLD"
print(text.lower()) # Output: "hello world"
title():
Converts the first character of each word to uppercase.
Example:
text = "hello world"
print(text.title()) # Output: "Hello World"
capitalize():
Converts the first character of the string to uppercase and the rest to
lowercase.
Example:
text = "hello world"
print(text.capitalize()) # Output: "Hello world"
swapcase():
Swaps the case of all characters in the string.
Example:
text = "Hello World"
print(text.swapcase()) # Output: "hELLO wORLD"
Trimming Methods
strip():
Removes leading and trailing whitespace from the string.
Example:
text = " hello world "
print(text.strip()) # Output: "hello world"
lstrip():
Removes leading whitespace.
Example:
text = " hello world"
print(text.lstrip()) # Output: "hello world"
rstrip():
Removes trailing whitespace.
Example:
text = "hello world "
print(text.rstrip()) # Output: "hello world"
rfind():
Returns the highest index of the substring if it is found, otherwise
returns -1.
Example:
text = "hello world, welcome to the world"
print(text.rfind("world")) # Output: 23
replace():
Replaces occurrences of a substring with another substring.
Example:
text = "hello world"
print(text.replace("world", "Python")) # Output: "hello Python"
rsplit():
Splits the string into a list of substrings starting from the right.
Example:
text = "apple,banana,cherry"
print(text.rsplit(",", 1)) # Output: ['apple,banana', 'cherry']
join():
Joins a list of strings into a single string with a specified delimiter.
Example:
fruits = ["apple", "banana", "cherry"]
print(", ".join(fruits)) # Output: "apple, banana, cherry"
Formatting Methods
format():
Formats strings using curly braces {} as placeholders.
Example:
name = "Alice"
age = 30
print("My name is {} and I am {} years old.".format(name, age)) # Output: "My name is Alice and I
am 30 years old."
% Operator:
An older way of formatting strings using % placeholders.
Example:
name = "Alice"
age = 30
print("My name is %s and I am %d years old." % (name, age)) # Output: "My name is Alice and I
am 30 years old."
Validation Methods
isalnum():
Returns True if all characters in the string are alphanumeric.
Example:
text = "abc123"
print(text.isalnum()) # Output: True
text = "abc 123"
print(text.isalnum()) # Output: False
isalpha():
Returns True if all characters in the string are alphabetic.
Example:
text = "abc"
print(text.isalpha()) # Output: True
text = "abc123"
print(text.isalpha()) # Output: False
isdigit():
Returns True if all characters in the string are digits.
Example:
text = "123"
print(text.isdigit()) # Output: True
text = "abc123"
print(text.isdigit()) # Output: False
islower():
Returns True if all characters in the string are lowercase.
Example:
text = "hello"
print(text.islower()) # Output: True
text = "Hello"
print(text.islower()) # Output: False
isupper():
Returns True if all characters in the string are uppercase.
Example:
text = "HELLO"
print(text.isupper()) # Output: True
text = "Hello"
print(text.isupper()) # Output: False
isspace():
Returns True if all characters in the string are whitespace.
Example:
text = " "
print(text.isspace()) # Output: True
text = " a "
print(text.isspace()) # Output: False
endswith():
Returns True if the string ends with the specified substring.
Example:
text = "hello world"
print(text.endswith("world")) # Output: True
print(text.endswith("hello")) # Output: False
count():
Returns the number of occurrences of a substring in the string.
Example:
text = "hello world, hello"
print(text.count("hello")) # Output: 2
center():
Centers the string within a specified width, padding with a specified
character (default is space).
Example:
text = "hello"
print(text.center(10, '-')) # Output: "--hello---"
zfill():
Pads the string on the left with zeros to fill a specified width.
Example:
text = "42"
print(text.zfill(5)) # Output: "00042"
2.3.3 STRING SLICING AND INDEXING
String slicing and indexing are powerful features in Python that
allow you to access and manipulate substrings and individual characters.
These techniques are fundamental for text processing and are widely used
in various programming tasks.
String Indexing
Indexing:
Each character in a string has a specific position, starting from 0 for
the first character and increasing by 1 for each subsequent character.
Negative indices can be used to access characters from the end of the string.
Examples:
text = "Hello, World!"
# Positive indexing
print(text[0]) # Output: 'H'
print(text[7]) # Output: 'W'
# Negative indexing
print(text[-1]) # Output: '!'
print(text[-5]) # Output: 'o'
IndexError:
Trying to access an index that is out of the range of the string length
will result in an IndexError.
Example:
text = "Python"
# This will raise an IndexError
print(text[10]) # IndexError: string index out of range
String Slicing
Slicing:
Slicing allows you to extract a portion of a string by specifying a
start, end, and optional step value. The syntax is string[start:end:step].
Examples:
text = "Hello, World!"
# Basic slicing
print(text[0:5]) # Output: 'Hello'
print(text[7:12]) # Output: 'World'
# Omitting start and end
print(text[:5]) # Output: 'Hello'
print(text[7:]) # Output: 'World!'
# Using negative indices
print(text[-6:]) # Output: 'World!'
print(text[:-7]) # Output: 'Hello, '
# Using a step value
print(text[::2]) # Output: 'Hlo ol!'
print(text[1::2]) # Output: 'el,Wrd'
# Reversing a string
print(text[::-1]) # Output: '!dlroW ,olleH'
Step Value:
The step value specifies the increment between each index for the
slice. By default, the step value is 1.
Example:
text = "abcdefghij"
print(text[0:10:2]) # Output: 'acegi'
print(text[::3]) # Output: 'adgj'
Reversing a String:
A common use of the step value is to reverse a string by setting the
step to -1.
Example:
text = "Python"
print(text[::-1]) # Output: 'nohtyP'
Practical Applications
Extracting Substrings:
Slicing is commonly used to extract substrings based on specific
patterns or delimiters.
Examples:
url = "https://www.example.com"
protocol = url[:5] # Output: 'https'
domain = url[8:] # Output: 'www.example.com'
text = "2024-06-17"
year = text[:4] # Output: '2024'
month = text[5:7] # Output: '06'
day = text[8:] # Output: '17'
Manipulating Strings:
Indexing and slicing can be used to manipulate parts of a string,
such as changing specific characters or reversing sections.
Examples:
text = "Hello, World!"
# Replace 'World' with 'Python'
new_text = text[:7] + "Python!"
print(new_text) # Output: 'Hello, Python!'
# Reverse the first word
first_word_reversed = text[:5][::-1]
print(first_word_reversed) # Output: 'olleH'
Checking Palindromes:
Slicing can be used to check if a string is a palindrome (reads the
same forward and backward).
Example:
def is_palindrome(s):
return s == s[::-1]
print(is_palindrome("radar")) # Output: True
print(is_palindrome("python")) # Output: False
2.3.4 WORKING WITH MULTILINE
STRINGS
Multiline strings in Python are used to handle text that spans
multiple lines. These strings are particularly useful for preserving the
formatting of the text as it is written in the code, making it easier to read
and maintain. Python provides several ways to create and manipulate
multiline strings.
Creating Multiline Strings
Triple Quotes:
Multiline strings can be created using triple quotes, either ''' or """.
Examples:
# Using triple single quotes
multiline_string = '''This is a multiline string.
It spans multiple lines.
Each new line is preserved.'''
# Using triple double quotes
multiline_string = """This is another multiline string.
It also spans multiple lines.
Each new line is preserved."""
Newline Character:
The newline character (\n) can also be used within single or double
quotes to create multiline strings, though this approach is less readable.
Example:
multiline_string = "This is a multiline string.\nIt spans multiple lines.\nEach new line is preserved."
Preserving Indentation
When working with multiline strings inside functions or classes, it's
important to preserve the intended indentation. This can be done using the
textwrap module.
Example:
import textwrap
def example_function():
multiline_string = """This is a multiline string.
It spans multiple lines.
Each new line is preserved."""
print(textwrap.dedent(multiline_string))
example_function()
replace():
multiline_string = """Hello, World!
Welcome to Python programming."""
replaced_string = multiline_string.replace("World", "Everyone")
print(replaced_string) # Output: "Hello, Everyone!\nWelcome to Python programming."
join():
lines = ["Line one.", "Line two.", "Line three."]
multiline_string = "\n".join(lines)
print(multiline_string)
# Output:
# Line one.
# Line two.
# Line three.
Practical Applications
Multiline Comments:
Although Python uses # for single-line comments, multiline strings
can be used as comments for documentation purposes within functions or
classes.
Example:
def example_function():
"""
This is a multiline comment.
It is used to describe the function's behavior.
Each new line is part of the same comment.
"""
Pass
Docstrings:
Multiline strings are commonly used for docstrings, which describe
the purpose and usage of modules, classes, and functions.
Example:
def add(a, b):
"""
Add two numbers and return the result.
Parameters:
a (int): The first number.
b (int): The second number.
Returns:
int: The sum of the two numbers.
"""
return a + b
2.3.5 PRACTICAL EXAMPLES AND
EXERCISES
This section provides practical examples and exercises to reinforce
your understanding of string operations, methods, formatting, slicing,
indexing, and working with multiline strings. Each example covers specific
subtopics to help you apply the concepts effectively.
String Operations
Example 1: Basic String Operations
Task: Perform basic string operations on a given sentence.
Concatenate another sentence.
Repeat the sentence twice.
Access specific characters using indexing.
Extract a substring using slicing.
Example:
sentence = "Python is fun."
# Concatenation
extended_sentence = sentence + " Let's learn more about it."
print(extended_sentence) # Output: "Python is fun. Let's learn more about it."
# Repetition
repeated_sentence = sentence * 2
print(repeated_sentence) # Output: "Python is fun.Python is fun."
# Indexing
first_character = sentence[0]
print(first_character) # Output: 'P'
last_character = sentence[-1]
print(last_character) # Output: '.'
# Slicing
substring = sentence[7:9]
print(substring) # Output: 'is'
Additional Exercises
Exercise 5: Write a function that checks if a given string is a
palindrome, ignoring spaces, punctuation, and case.
Solution:
import re
def is_palindrome(s):
s = re.sub(r'[^A-Za-z0-9]', '', s).lower()
return s == s[::-1]
print(is_palindrome("A man, a plan, a canal, Panama")) # Output: True
print(is_palindrome("Hello, World")) # Output: False
Example:
age = 18
if age >= 18:
print("You are eligible to vote.")
# Output: You are eligible to vote.
elif Statement
The elif (short for "else if") statement allows you to test multiple
conditions sequentially. If the first if condition is False, the elif condition is
checked. If the elif condition is True, its block of code is executed. You can
include multiple elif statements to check various conditions.
Syntax:
if condition1:
# Code to execute if condition1 is True
elif condition2:
# Code to execute if condition2 is True
Example:
age = 16
if age >= 18:
print("You are an adult.")
elif age >= 13:
print("You are a teenager.")
# Output: You are a teenager.
else Statement
The else statement provides a fallback option when all previous if
and elif conditions are False. The block of code following the else statement
is executed if none of the previous conditions are met.
Syntax:
if condition1:
# Code to execute if condition1 is True
elif condition2:
# Code to execute if condition2 is True
else:
# Code to execute if all conditions are False
Example:
age = 10
if age >= 18:
print("You are an adult.")
elif age >= 13:
print("You are a teenager.")
else:
print("You are a child.")
# Output: You are a child.
Example:
age = 20
is_student = True
if age < 18 and is_student:
print("You are a student and a minor.")
elif age >= 18 and is_student:
print("You are a student and an adult.")
else:
print("You are not a student.")
# Output: You are a student and an adult.
Example:
age = 20
is_student = False
if age >= 18:
if is_student:
print("You are an adult student.")
else:
print("You are an adult non-student.")
else:
if is_student:
print("You are a minor student.")
else:
print("You are a minor non-student.")
# Output: You are an adult non-student.
Example:
user_logged_in = True
user_role = "admin"
if user_logged_in:
if user_role == "admin":
print("Access granted. Welcome, admin!")
else:
print("Access granted. Welcome, user!")
else:
print("Access denied. Please log in.")
Output:
Access granted. Welcome, admin!
Practical Examples of Nested Conditions
Example 1: Age and Membership Check
Scenario: A club requires that members be at least 18 years old.
Additionally, they check if the member is a premium member for special
privileges.
Code:
age = 20
is_premium_member = True
if age >= 18:
if is_premium_member:
print("Welcome, premium member!")
else:
print("Welcome, regular member!")
else:
print("Sorry, you must be at least 18 years old to join.")
Output:
Welcome, premium member!
Output:
Student passed.
Output:
You get a 10% discount.
Exercises
Exercise 1: Write a program that checks if a person is eligible to
vote, and if they are also a senior citizen.
age = int(input("Enter your age: "))
if age >= 18:
if age >= 65:
print("You are eligible to vote and you are a senior citizen.")
else:
print("You are eligible to vote.")
else:
print("You are not eligible to vote.")
Example:
a = True
b = False
print(a and b) # Output: False
print(a and True) # Output: True
or Operator:
The or operator returns True if at least one of the operands is True.
If both operands are False, the result is False.
Syntax: condition1 or condition2
Example:
a = True
b = False
print(a or b) # Output: True
print(b or False) # Output: False
not Operator:
The not operator inverts the boolean value of its operand. If the
operand is True, the result is False, and vice versa.
Syntax: not condition
Example:
a = True
b = False
print(not a) # Output: False
print(not b) # Output: True
Output:
You are allowed to drive.
Output:
You can relax today.
Output:
You can go outside without an umbrella.
Output:
You can go for a picnic.
Output:
You are eligible for a student discount.
Explanation: This program takes the user's age as input and checks if the
age is 18 or above. If true, it prints that the user is eligible to vote;
otherwise, it prints that they are not eligible.
Example 2: Grade Classification
Task: Write a program that classifies a student's grade based on
their score.
Code:
score = int(input("Enter your score: "))
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B")
elif score >= 70:
print("Grade: C")
elif score >= 60:
print("Grade: D")
else:
print("Grade: F")
Explanation: This program takes the student's score and classifies it into
grades A, B, C, D, or F based on predefined ranges.
Example 3: Nested Conditions for Discount Calculation
Task: Calculate discount based on membership status and purchase
amount.
Code:
membership_status = input("Enter membership status (gold/silver/none): ").lower()
purchase_amount = float(input("Enter purchase amount: "))
if membership_status == "gold":
if purchase_amount > 100:
discount = 0.20
else:
discount = 0.15
elif membership_status == "silver":
if purchase_amount > 100:
discount = 0.10
else:
discount = 0.05
else:
discount = 0.00
discount_amount = purchase_amount * discount
total_amount = purchase_amount - discount_amount
print(f"Discount: ${discount_amount:.2f}")
print(f"Total amount to be paid: ${total_amount:.2f}")
Explanation: This program uses the and operator to check if the user is
both an adult and a member. If both conditions are true, the user is eligible
for the special offer.
Exercises
Exercise 1: Check Even or Odd
Task: Write a program that checks if a number is even or odd.
Solution:
number = int(input("Enter a number: "))
if number % 2 == 0:
print("The number is even.")
else:
print("The number is odd.")
Example:
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
Output:
apple
banana
cherry
In this example, the for loop iterates over each item in the fruits list
and prints it.
Iterating Over Different Data Types
You can use for loops to iterate over various data types, including
lists, tuples, dictionaries, sets, and strings.
Lists:
numbers = [1, 2, 3, 4, 5]
for number in numbers:
print(number)
Output:
1
2
3
4
5
Explanation: This loop goes through each number in the numbers list and
prints it.
Tuples:
coordinates = (10, 20, 30)
for coordinate in coordinates:
print(coordinate)
Output:
10
20
30
Explanation: This loop goes through each item in the coordinates tuple and
prints it.
Dictionaries:
student = {"name": "John", "age": 20, "major": "Computer Science"}
for key, value in student.items():
print(f"{key}: {value}")
Output:
name: John
age: 20
major: Computer Science
Explanation: This loop iterates over each key-value pair in the student
dictionary and prints them.
Sets:
unique_numbers = {1, 2, 3, 4, 5}
for number in unique_numbers:
print(number)
Output:
1
2
3
4
5
Output:
H
e
l
l
O
Explanation: This loop iterates over each character in the string text and
prints it.
Using the range() Function
The range() function generates a sequence of numbers, which is
particularly useful for iterating a specific number of times in a for loop.
Syntax:
range(start, stop, step)
Examples:
Iterating from 0 to 4:
for i in range(5):
print(i)
Output:
0
1
2
3
4
Explanation: The range(5) function generates numbers from 0 to 4.
Iterating from 1 to 5:
for i in range(1, 6):
print(i)
Output:
1
2
3
4
5
Output:
0
2
4
6
8
10
Output:
123
456
789
Explanation: This example uses a nested for loop to iterate over a 2D list
(matrix). The outer loop iterates through each row, while the inner loop
iterates through each element in the current row, printing the elements in a
structured format.
Using else with for Loops
The else block in a for loop executes after the loop finishes iterating
over the sequence, unless the loop is terminated by a break statement.
Example:
for i in range(5):
print(i)
else:
print("Loop finished successfully.")
Output:
0
1
2
3
4
Loop finished successfully.
Explanation: The else block executes after the loop has completed all
iterations.
Example with break:
for i in range(5):
if i == 3:
break
print(i)
else:
print("Loop finished successfully.")
Output:
0
1
2
Explanation: The else block does not execute because the loop is
terminated by the break statement when i equals 3.
Practical Examples and Exercises
Example 1: Summing Numbers in a List
Task: Write a program to calculate the sum of all numbers in a list.
Code:
numbers = [1, 2, 3, 4, 5]
total = 0
for number in numbers:
total += number
print(f"Total sum: {total}")
Output:
Total sum: 15
Explanation: This loop iterates through each number in the numbers list,
adding each number to the total variable.
Exercise 1: Write a program to find the product of all numbers in a list.
Solution:
numbers = [1, 2, 3, 4, 5]
product = 1
for number in numbers:
product *= number
print(f"Product: {product}")
Output:
Product: 120
Explanation: This loop multiplies each number in the numbers list to the
product variable.
Example 2: Finding the Largest Number in a List
Task: Write a program to find the largest number in a list.
Code:
numbers = [3, 5, 7, 2, 8, 1]
largest = numbers[0]
for number in numbers:
if number > largest:
largest = number
print(f"Largest number: {largest}")
Output:
Largest number: 8
Explanation: This loop iterates through each number in the numbers list,
updating the largest variable if a larger number is found.
Exercise 2: Write a program to find the smallest number in a list.
Solution:
numbers = [3, 5, 7, 2, 8, 1]
smallest = numbers[0]
for number in numbers:
if number < smallest:
smallest = number
print(f"Smallest number: {smallest}")
Output:
Smallest number: 1
Explanation: This loop iterates through each number in the numbers list,
updating the smallest variable if a smaller number is found.
Example 3: Counting Vowels in a String
Task: Write a program to count the number of vowels in a given string.
Code:
text = "Hello, World!"
vowels = "aeiouAEIOU"
count = 0
for char in text:
if char in vowels:
count += 1
print(f"Number of vowels: {count}")
Output:
Number of vowels: 3
Explanation: This loop iterates through each character in the text string,
incrementing the count variable if the character is a vowel.
Exercise 3: Write a program to count the number of consonants in a given
string.
Solution:
text = "Hello, World!"
vowels = "aeiouAEIOU"
count = 0
for char in text:
if char.isalpha() and char not in vowels:
count += 1
print(f"Number of consonants: {count}")
Output:
Number of consonants: 7
Explanation: This loop iterates through each character in the text string,
incrementing the count variable if the character is a consonant (an alphabet
character that is not a vowel).
Example 4: Generating a Multiplication Table
Task: Write a program to generate a multiplication table for numbers 1 to 5.
Code:
for i in range(1, 6):
for j in range(1, 6):
print(f"{i} * {j} = {i * j}")
print()
Output:
1*1=1
1*2=2
1*3=3
1*4=4
1*5=5
2*1=2
2*2=4
2*3=6
2*4=8
2 * 5 = 10
3*1=3
3*2=6
3*3=9
3 * 4 = 12
3 * 5 = 15
4*1=4
4*2=8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
5*1=5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
Output:
*
**
***
****
*****
Output:
name: Alice
age: 22
major: Biology
Explanation: This loop iterates over each key-value pair in the student
dictionary and prints them in a formatted string.
Exercise 5: Write a program to calculate the average of all values in a
dictionary where the values are numbers.
Solution:
grades = {"math": 90, "science": 85, "history": 88, "english": 92}
total = 0
count = 0
for subject, grade in grades.items():
total += grade
count += 1
average = total / count
print(f"Average grade: {average}")
Output:
Average grade: 88.75
Explanation: This loop iterates over each key-value pair in the grades
dictionary, adding the grades to the total variable and incrementing the
count variable. The average is calculated by dividing the total by the count
of grades.
Example 6: Filtering Even Numbers from a List
Task: Write a program to filter out even numbers from a list.
Code:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = []
for number in numbers:
if number % 2 == 0:
even_numbers.append(number)
print(f"Even numbers: {even_numbers}")
Output:
Even numbers: [2, 4, 6, 8, 10]
Explanation: This loop iterates through each number in the numbers list
and appends it to the even_numbers list if it is even.
Exercise 6: Write a program to filter out odd numbers from a list.
Solution:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
odd_numbers = []
for number in numbers:
if number % 2 != 0:
odd_numbers.append(number)
print(f"Odd numbers: {odd_numbers}")
Output:
Odd numbers: [1, 3, 5, 7, 9]
Explanation: This loop iterates through each number in the numbers list
and appends it to the odd_numbers list if it is odd.
3.2.2 WHILE LOOPS
The while loop in Python is another fundamental control structure
that allows you to execute a block of code repeatedly as long as a specified
condition is True. This type of loop is particularly useful when the number
of iterations is not known beforehand and depends on some runtime
condition.
Basic Syntax
The basic syntax of a while loop in Python is:
while condition:
# Code to execute while condition is True
Example:
count = 0
while count < 5:
print(count)
count += 1
Output:
0
1
2
3
4
Output:
10
8
6
4
2
Explanation: The else block executes after the loop completes all iterations
because the condition count < 3 becomes False.
Practical Examples and Exercises
Example 1: Summing User-Input Numbers
Task: Write a program that keeps asking the user for a number and adds it
to a sum until the user enters 0.
Code:
total = 0
number = int(input("Enter a number (0 to stop): "))
while number != 0:
total += number
number = int(input("Enter a number (0 to stop): "))
print(f"Total sum: {total}")
Output (Example):
Enter a number (0 to stop): 5
Enter a number (0 to stop): 3
Enter a number (0 to stop): 8
Enter a number (0 to stop): 0
Total sum: 16
Explanation: This loop keeps asking the user for a number and adds it to
total until the user enters 0.
Exercise 1: Write a program to find the factorial of a number using a while
loop.
Solution:
number = int(input("Enter a number: "))
factorial = 1
count = 1
while count <= number:
factorial *= count
count += 1
print(f"Factorial of {number} is {factorial}")
Output (Example):
Enter a number: 5
Factorial of 5 is 120
Output (Example):
Enter your password: pass123
Incorrect password. Try again.
Enter your password: python123
Access granted.
Explanation: This loop continues to ask the user for a password until the
correct password is entered.
Exercise 2: Write a program that asks the user to guess a number between 1
and 10. The program should keep asking until the user guesses the correct
number.
Solution:
import random
secret_number = random.randint(1, 10)
guess = int(input("Guess the number between 1 and 10: "))
while guess != secret_number:
if guess < secret_number:
print("Too low!")
else:
print("Too high!")
guess = int(input("Guess the number between 1 and 10: "))
print("Congratulations! You guessed the number.")
Output (Example):
Guess the number between 1 and 10: 5
Too low!
Guess the number between 1 and 10: 8
Too high!
Guess the number between 1 and 10: 7
Congratulations! You guessed the number.
Explanation: This loop continues to ask the user for guesses until the
correct number is guessed, providing hints if the guess is too low or too
high.
Example 3: Calculating the Sum of Digits
Task: Write a program to calculate the sum of digits of a number using a
while loop.
Code:
number = int(input("Enter a number: "))
sum_of_digits = 0
while number > 0:
digit = number % 10
sum_of_digits += digit
number = number // 10
print(f"Sum of digits: {sum_of_digits}")
Output (Example):
Enter a number: 1234
Sum of digits: 10
Explanation: This loop extracts each digit from the number and adds it to
the sum_of_digits variable until the number is reduced to 0.
Exercise 3: Write a program that reverses the digits of a number using a
while loop.
Solution:
number = int(input("Enter a number: "))
reversed_number = 0
while number > 0:
digit = number % 10
reversed_number = reversed_number * 10 + digit
number = number // 10
print(f"Reversed number: {reversed_number}")
Output (Example):
Enter a number: 1234
Reversed number: 4321
Example:
for i in range(3):
for j in range(2):
print(f"i: {i}, j: {j}")
Output:
i: 0, j: 0
i: 0, j: 1
i: 1, j: 0
i: 1, j: 1
i: 2, j: 0
i: 2, j: 1
In this example, the outer loop iterates over the range 0 to 2, and for
each iteration of the outer loop, the inner loop iterates over the range 0 to 1.
Practical Applications of Nested Loops
Nested loops are useful in various scenarios, including working with
multidimensional arrays (matrices), creating patterns, and generating
combinations of items.
Example 1: Working with a 2D List (Matrix)
Task: Print all elements of a 2D list (matrix).
Code:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for row in matrix:
for element in row:
print(element, end=' ')
print()
Output:
123
456
789
Explanation: The outer loop iterates through each row of the matrix, and
the inner loop iterates through each element in the current row, printing the
elements in a structured format.
Example 2: Creating a Multiplication Table
Task: Create and print a multiplication table for numbers 1 to 5.
Code:
for i in range(1, 6):
for j in range(1, 6):
print(f"{i * j:2}", end=" ")
print()
Output:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
Explanation: The outer loop iterates through numbers 1 to 5, and the inner
loop multiplies the current number of the outer loop by each number in the
range 1 to 5, printing the results in a formatted table.
Nested while Loops
You can also use nested while loops, which follow a similar
structure to nested for loops but use while conditions for iterations.
Example:
i=0
while i < 3:
j=0
while j < 2:
print(f"i: {i}, j: {j}")
j += 1
i += 1
Output:
i: 0, j: 0
i: 0, j: 1
i: 1, j: 0
i: 1, j: 1
i: 2, j: 0
i: 2, j: 1
Explanation: The outer while loop iterates while i is less than 3, and for
each iteration of the outer loop, the inner while loop iterates while j is less
than 2.
Practical Examples and Exercises
Example 3: Pattern Generation
Task: Write a program to generate a pyramid pattern of stars.
Code:
rows = 5
for i in range(1, rows + 1):
for j in range(rows - i):
print(" ", end="")
for k in range(2 * i - 1):
print("*", end="")
print()
Output:
*
***
*****
*******
*********
Explanation: The outer loop controls the number of rows, the first inner
loop prints spaces for alignment, and the second inner loop prints stars to
form the pyramid pattern.
Exercise 1: Write a program to generate an inverted pyramid pattern of
stars.
Solution:
rows = 5
for i in range(rows, 0, -1):
for j in range(rows - i):
print(" ", end="")
for k in range(2 * i - 1):
print("*", end="")
print()
Output:
*********
*******
*****
***
*
Explanation: The outer loop starts from rows and decrements, the first
inner loop prints spaces for alignment, and the second inner loop prints stars
to form the inverted pyramid pattern.
Example 4: Generating All Possible Pairs
Task: Write a program to generate all possible pairs from two lists.
Code:
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for item1 in list1:
for item2 in list2:
print(f"({item1}, {item2})")
Output:
(1, a)
(1, b)
(1, c)
(2, a)
(2, b)
(2, c)
(3, a)
(3, b)
(3, c)
Explanation: The outer loop iterates through each item in list1, and for
each item in list1, the inner loop iterates through each item in list2, printing
all possible pairs.
Exercise 2: Write a program to generate all possible combinations of a list
of numbers and a list of letters.
Solution:
numbers = [4, 5, 6]
letters = ['x', 'y', 'z']
for number in numbers:
for letter in letters:
print(f"({number}, {letter})")
Output:
(4, x)
(4, y)
(4, z)
(5, x)
(5, y)
(5, z)
(6, x)
(6, y)
(6, z)
Explanation: The outer loop iterates through each number in numbers, and
for each number, the inner loop iterates through each letter in letters,
printing all possible combinations.
3.2.4 LOOP CONTROL STATEMENTS
(BREAK, CONTINUE, PASS)
Loop control statements in Python alter the normal flow of loops
(both for and while loops). They provide more control over the execution
of loops, allowing you to exit a loop, skip the current iteration, or do
nothing. The main loop control statements in Python are break, continue,
and pass.
The break Statement
The break statement is used to exit a loop prematurely. When break
is encountered, the loop terminates immediately, and control is passed to the
statement following the loop.
Syntax:
for item in sequence:
if condition:
break
# Code to execute if condition is False
Example:
for number in range(10):
if number == 5:
break
print(number)
Output:
0
1
2
3
4
Explanation: The loop iterates over numbers from 0 to 9, but when number
equals 5, the break statement exits the loop.
The continue Statement
The continue statement is used to skip the rest of the code inside the
loop for the current iteration and move to the next iteration.
Syntax:
for item in sequence:
if condition:
continue
# Code to execute if condition is False
Example:
for number in range(10):
if number % 2 == 0:
continue
print(number)
Output:
1
3
5
7
9
Example:
for number in range(10):
if number < 5:
pass
else:
print(number)
Output:
5
6
7
8
9
Explanation: The loop iterates over numbers from 0 to 9. For numbers less
than 5, the pass statement does nothing, and the loop continues to the next
iteration. For numbers 5 and above, the numbers are printed.
Practical Examples and Exercises
Example 1: Using break to Exit a Loop
Task: Write a program to search for a specific number in a list and exit the
loop once it is found.
Code:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
search_for = 7
for number in numbers:
if number == search_for:
print(f"Number {search_for} found!")
break
else:
print(f"Number {search_for} not found.")
Output:
Number 7 found!
Explanation: The loop iterates through the numbers list and exits as soon
as it finds the number 7, printing a message.
Exercise 1: Write a program to search for a specific string in a list of
strings. If found, print a message and exit the loop.
Solution:
words = ["apple", "banana", "cherry", "date", "elderberry"]
search_for = "cherry"
for word in words:
if word == search_for:
print(f"Word '{search_for}' found!")
break
else:
print(f"Word '{search_for}' not found.")
Output:
Word 'cherry' found!
Explanation: The loop iterates through the words list and exits as soon as it
finds the word "cherry", printing a message.
Example 2: Using continue to Skip Iterations
Task: Write a program to print all numbers from 1 to 10 except multiples of
3.
Code:
for number in range(1, 11):
if number % 3 == 0:
continue
print(number)
Output:
1
2
4
5
7
8
10
Output:
Hll, Wrld!
Explanation: The loop iterates through each character in the text string. If
the character is a vowel, the continue statement skips the rest of the loop
body for that iteration, printing only the consonants.
Example 3: Using pass as a Placeholder
Task: Write a program that includes a placeholder for future code inside a
loop.
Code:
for number in range(5):
if number % 2 == 0:
pass # Placeholder for future code
else:
print(f"Odd number: {number}")
Output:
Odd number: 1
Odd number: 3
Explanation: The pass statement does nothing for even numbers, allowing
the loop to continue. Odd numbers are printed.
Exercise 3: Write a program with a placeholder for handling errors inside a
loop.
Solution:
numbers = [1, 'two', 3, 'four', 5]
for number in numbers:
try:
print(number * 2)
except TypeError:
pass # Placeholder for future error handling code
Output:
2
6
10
Explanation: This program calculates the Body Mass Index (BMI) and
categorizes it based on standard BMI ranges.
Loops
Application: Sum of Natural Numbers
Task: Write a program to find the sum of the first n natural numbers.
Code:
n = int(input("Enter a positive integer: "))
sum = 0
for i in range(1, n + 1):
sum += i
print(f"Sum of the first {n} natural numbers is: {sum}")
Explanation: This program adds two 3x3 matrices using nested for loops
and prints the resulting matrix.
Exercise 3: Write a program that transposes a matrix.
Solution:
X = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
result = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
for i in range(len(X)):
for j in range(len(X[0])):
result[j][i] = X[i][j]
for r in result:
print(r)
Explanation: This program transposes a 3x3 matrix using nested for loops
and prints the resulting transposed matrix.
Loop Control Statements
Application: Prime Number Checker
Task: Write a program that checks if a number is prime.
Code:
num = int(input("Enter a number: "))
if num > 1:
for i in range(2, num):
if (num % i) == 0:
print(num, "is not a prime number")
break
else:
print(num, "is a prime number")
else:
print(num, "is not a prime number")
Explanation: This program prints all prime numbers between 1 and 100
using nested for loops and the break statement.
CHAPTER 4: FUNCTIONS AND
MODULES
4.1 INTRODUCTION TO FUNCTIONS
Functions are one of the fundamental building blocks in Python.
They allow you to encapsulate a block of code that performs a specific task
and reuse it whenever needed. Functions help make programs modular,
more readable, and easier to maintain.
4.1.1 DEFINING FUNCTIONS
Defining functions in Python is straightforward. You use the def
keyword, followed by the function name, parentheses, and a colon. Inside
the function, you write the code block that performs the specific task. Here
is a step-by-step guide to defining functions:
Basic Function Structure
The basic syntax for defining a function is as follows:
def function_name(parameters):
"""Docstring describing the function."""
# Code block
return [expression]
To call this function, you simply use its name followed by parentheses:
greet()
Output:
Hello, World!
Parameters and Arguments
Functions can accept parameters, allowing you to pass data into
them. Parameters are specified inside the parentheses of the function
definition.
Example: A function that takes two parameters and prints their sum.
def add_numbers(a, b):
"""Returns the sum of two numbers."""
return a + b
Output:
8
Default Parameters
You can define default values for parameters. If an argument is not
provided, the default value is used.
Example: A function with a default parameter.
def greet(name="World"):
"""Prints a personalized greeting."""
print(f"Hello, {name}!")
Output:
Hello, Alice!
Hello, World!
return Statement
The return statement is used to send a value back to the caller. If no
return statement is present, the function returns None by default.
Example: A function that calculates the square of a number.
def square(x):
"""Returns the square of a number."""
return x * x
Output:
16
Output:
Area of the circle with radius 5 is 78.54
Explanation: This function uses the math module to access the value of π
and calculate the area using the formula πr².
Exercise 1: Write a function to convert Celsius to Fahrenheit.
Solution:
def celsius_to_fahrenheit(celsius):
"""Converts Celsius to Fahrenheit."""
return (celsius * 9/5) + 32
To call this function:
celsius = 25
fahrenheit = celsius_to_fahrenheit(celsius)
print(f"{celsius}°C is {fahrenheit}°F")
Output:
25°C is 77.0°F
Output:
The maximum of the three numbers is 20
Explanation: This function uses Python's built-in max function to find and
return the largest of the three input numbers.
Exercise 2: Write a function to check if a number is even or odd.
Solution:
def is_even_or_odd(number):
"""Checks if a number is even or odd."""
if number % 2 == 0:
return "Even"
else:
return "Odd"
Output:
42 is Even
Output:
The number of vowels in 'Hello, World!' is 3
Output:
Hello, Alice! You are 30 years old.
Keyword Arguments:
These arguments are passed to a function by explicitly stating the
parameter name and assigning it a value.
Example:
def greet(name, age):
print(f"Hello, {name}! You are {age} years old.")
greet(name="Bob", age=25)
Output:
Hello, Bob! You are 25 years old.
Default Arguments:
You can provide default values for parameters. If the caller does not
provide a value for such a parameter, the default value is used.
Example:
def greet(name, age=20):
print(f"Hello, {name}! You are {age} years old.")
greet("Charlie")
greet("Diana", 35)
Output:
Hello, Charlie! You are 20 years old.
Hello, Diana! You are 35 years old.
Variable-Length Arguments:
Sometimes, you might not know how many arguments will be
passed to your function. Python allows you to handle such cases using
*args and **kwargs.
*args:
Used to pass a variable number of non-keyword arguments.
Example:
def greet(*names):
for name in names:
print(f"Hello, {name}!")
greet("Alice", "Bob", "Charlie")
Output:
Hello, Alice!
Hello, Bob!
Hello, Charlie!
**kwargs:
Used to pass a variable number of keyword arguments.
Example:
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="New York")
Output:
name: Alice
age: 30
city: New York
Return Values
The return statement is used in a function to send a value back to the
caller. This value can be a result of some computation or operation
performed within the function.
Single Return Value
A function can return a single value using the return statement.
Example:
def add(a, b):
return a + b
result = add(5, 3)
print(result)
Output:
8
Output:
Sum: 12, Difference: 8, Product: 20, Quotient: 5.00
Practical Examples and Exercises
Example 1: Temperature Conversion Functions
Task: Write functions to convert temperatures between Celsius and
Fahrenheit.
Code:
def celsius_to_fahrenheit(celsius):
return (celsius * 9/5) + 32
def fahrenheit_to_celsius(fahrenheit):
return (fahrenheit - 32) * 5/9
Output:
25°C is 77.0°F
77°F is 25.00°C
Output:
Vowels: 3, Consonants: 7, Total characters: 13
Output:
Minimum: 1, Maximum: 5, Average: 3.00
Example:
def greet(name="World"):
"""Prints a greeting message with a default name."""
print(f"Hello, {name}!")
Output:
Hello, Alice!
Hello, World!
Explanation: The function greet has a default parameter name with the
value "World". When called without an argument, it uses the default value.
Keyword Arguments
Keyword arguments allow you to pass arguments to a function by
explicitly naming each parameter and its corresponding value. This
enhances code readability and makes the function calls more explicit.
Using Keyword Arguments
When calling a function with keyword arguments, specify the
parameter names along with their values.
Syntax:
function_name(param1=value1, param2=value2)
Example:
def describe_person(name, age, city):
"""Prints a description of a person."""
print(f"{name} is {age} years old and lives in {city}.")
describe_person(name="Alice", age=30, city="New York")
describe_person(city="Paris", name="Bob", age=25)
Output:
Alice is 30 years old and lives in New York.
Bob is 25 years old and lives in Paris.
Output:
I have a dog named Buddy.
I have a cat named Whiskers.
I have a rabbit named Thumper.
Output:
Order ID: 101
Product: Laptop
Quantity: 2
Shipping Method: Standard
Order ID: 102
Product: Phone
Quantity: 1
Shipping Method: Express
Output:
Total price with default tip: $63.50
Total price with custom tip: $66.00
Output:
Hello, Mr. Smith! Have a great day!
Hello, Dr. Doe! Have a great day!
Hello, Mr. Jane! Welcome to our team!
Explanation: The function personalized_greeting has default parameters
title and message. It prints a personalized greeting message, using the
default values unless overridden by the caller.
Exercise 2: Write a function to generate a URL with optional query
parameters.
Solution:
def generate_url(base_url, path, **query_params):
"""Generates a URL with optional query parameters."""
url = f"{base_url}/{path}"
if query_params:
query_string = "&".join(f"{key}={value}" for key, value in query_params.items())
url = f"{url}?{query_string}"
return url
url = generate_url("https://example.com", "search", q="python", page=2)
print(url)
url_without_params = generate_url("https://example.com", "home")
print(url_without_params)
Output:
https://example.com/search?q=python&page=2
https://example.com/home
Output:
8
Output:
[1, 4, 9, 16, 25]
Output:
[11, 12, 13, 14, 15]
Output:
[1, 3, 5, 7, 9]
Output:
[6, 7, 8, 9, 10]
Output:
[(5, 0), (3, 1), (1, 2), (2, 4)]
Explanation: The lambda function lambda x: x[1] sorts the list of tuples
pairs by the second element in each tuple.
Exercise 3: Write a lambda function to sort a list of dictionaries by the
value of the "age" key.
Solution:
people = [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 20}, {"name": "Charlie", "age":
30}]
sorted_people = sorted(people, key=lambda x: x["age"])
print(sorted_people)
Output:
[{'name': 'Bob', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Charlie', 'age': 30}]
Output:
120
Output:
Hello World!
Exercise: Write a function to calculate the price of a meal with a default tip
percentage.
Solution:
def calculate_total_price(meal_price, tax_rate, tip_percentage=15):
"""Calculates the total price of a meal including tax and tip."""
tax_amount = meal_price * tax_rate / 100
tip_amount = meal_price * tip_percentage / 100
total_price = meal_price + tax_amount + tip_amount
return total_price
Lambda Functions
Example 6: Using Lambda with map()
Task: Write a lambda function to square each number in a list.
Code:
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(squared_numbers)
Exercise: Write a lambda function to filter out numbers greater than 5 from
a list using filter().
Solution:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filtered_numbers = list(filter(lambda x: x > 5, numbers))
print(filtered_numbers)
Explanation: In this example, the variable name is defined inside the greet
function and can only be accessed within that function. Attempting to
access name outside the function will result in an error.
Global Variables
Global variables are variables that are defined outside any function
and can be accessed throughout the entire program. They are created when
the script starts and destroyed when the script ends.
Example of Global Variables
Code:
name = "Alice" # Global variable
def greet():
print(f"Hello, {name}!")
greet()
print(name) # This works because 'name' is a global variable
Explanation: The global keyword tells Python that count refers to the
global variable, not a new local variable. This allows the function to modify
the global variable.
Shadowing
Shadowing occurs when a local variable has the same name as a
global variable. In such cases, the local variable shadows the global
variable within its scope.
Example of Shadowing
Code:
name = "Alice" # Global variable
def greet():
name = "Bob" # Local variable
print(f"Hello, {name}!")
greet()
print(name) # Output: Alice
Explanation: Inside the greet function, the local variable name shadows the
global variable name. The global variable remains unchanged outside the
function.
Practical Examples and Exercises
Example 1: Using Local and Global Variables
Task: Write a program that demonstrates the use of both local and global
variables.
Code:
message = "Global Variable"
def show_message():
local_message = "Local Variable"
print(local_message)
show_message()
print(message)
Explanation: This function uses the global keyword to modify the global
variable counter. Each call to update_counter increments the counter by 1.
Example 2: Shadowing a Global Variable
Task: Write a function that shadows a global variable.
Code:
total = 100
def calculate():
total = 50 # Local variable shadows the global variable
print(f"Inside function: {total}")
calculate()
print(f"Outside function: {total}")
Explanation: This function defines a local variable total that shadows the
global variable total. The global variable remains unchanged outside the
function.
Exercise 2: Create a Program that Differentiates Between Local and Global
Variables
Solution:
balance = 5000
def display_balance():
balance = 1000 # Local variable
print(f"Local balance: {balance}")
display_balance()
print(f"Global balance: {balance}")
Explanation: In this example, the global keyword tells Python that the
counter variable inside the increment function refers to the global variable
counter. This allows the function to modify the global counter.
Modifying a Global Variable Without global
Without the global keyword, any assignment to the variable inside
the function creates a local variable, leaving the global variable unchanged.
Code:
counter = 0 # Global variable
def increment():
counter = 1 # Local variable
print(counter)
increment()
print(counter) # Output: 0
Output:
1
1
Explanation: In this example, the nonlocal keyword tells Python that the
count variable inside the inner function refers to the count variable in the
nearest enclosing scope, which is the outer function. This allows the inner
function to modify the count variable defined in the outer function.
Practical Examples and Exercises
Example 1: Using global to Modify a Global Variable
Task: Write a program to demonstrate modifying a global variable using
the global keyword.
Code:
total = 0 # Global variable
def add_to_total(amount):
global total
total += amount
add_to_total(5)
add_to_total(10)
print(total) # Output: 15
Explanation: This function uses the global keyword to modify the global
list my_list by appending a new item.
Example 2: Using nonlocal to Modify an Enclosing Scope Variable
Task: Write a program to demonstrate modifying an enclosing scope
variable using the nonlocal keyword.
Code:
def outer_function():
value = 10 # Enclosing scope variable
def inner_function():
nonlocal value
value += 5
print(f"Inner function value: {value}")
inner_function()
print(f"Outer function value: {value}")
outer_function()
Output:
Inner function value: 15
Outer function value: 15
Example:
import math
print(math.sqrt(16)) # Output: 4.0
Explanation: This example imports the math module and uses its sqrt
function to calculate the square root of 16.
Importing Specific Attributes
You can import specific attributes (functions, classes, variables)
from a module using the from keyword:
from module_name import attribute_name
Example:
from math import pi, sqrt
print(pi) # Output: 3.141592653589793
print(sqrt(16)) # Output: 4.0
Explanation: This example imports the pi constant and the sqrt function
from the math module, allowing you to use them directly without the
math. prefix.
Importing All Attributes
To import all attributes from a module, you can use the * wildcard:
from module_name import *
Example:
from math import *
print(pi) # Output: 3.141592653589793
print(sqrt(16)) # Output: 4.0
Explanation: This imports all attributes from the math module. While this
can be convenient, it is generally not recommended because it can lead to
conflicts and make the code less readable.
Aliasing Modules
You can import a module and assign it a different name using the as
keyword. This is useful for shortening module names or avoiding name
conflicts.
import module_name as alias_name
Example:
import numpy as np
array = np.array([1, 2, 3])
print(array) # Output: [1 2 3]
Explanation: This example imports the numpy module and assigns it the
alias np, which is a common practice to make the code shorter and more
readable.
Aliasing Specific Attributes
You can also alias specific attributes when importing them:
from module_name import attribute_name as alias_name
Example:
from math import sqrt as square_root
print(square_root(16)) # Output: 4.0
Explanation: This imports the sqrt function from the math module and
assigns it the alias square_root.
Importing from a Module in a Package
A package is a collection of modules in directories that give a
package hierarchy. To import a module from a package, you use dot
notation:
import package_name.module_name
Example:
import mypackage.mymodule
mypackage.mymodule.my_function()
Example:
from mypackage.mymodule import my_function
my_function()
Explanation: This program imports the random module and uses its
randint function to generate a random integer between 1 and 100.
Exercise 1: Write a program to shuffle a list of numbers using the random
module.
Solution:
import random
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(f"Shuffled list: {numbers}")
Explanation: This program uses the shuffle function from the random
module to randomly shuffle the elements of the numbers list.
Example 2: Using the datetime Module
Task: Write a program that prints the current date and time.
Code:
import datetime
current_datetime = datetime.datetime.now()
print(f"Current date and time: {current_datetime}")
Explanation: This program imports the datetime module and uses its now
function to get the current date and time.
Exercise 2: Write a program to calculate the difference between two dates
using the datetime module.
Solution:
import datetime
date1 = datetime.datetime(2023, 1, 1)
date2 = datetime.datetime(2024, 1, 1)
difference = date2 - date1
print(f"Difference in days: {difference.days}")
Explanation: This example uses the pi constant from the math module to
calculate the area of a circle.
Exercise: Write a function that calculates the hypotenuse of a right-angled
triangle given the lengths of the other two sides.
import math
def hypotenuse(a, b):
return math.sqrt(a**2 + b**2)
a=3
b=4
print(f"The hypotenuse of the triangle is {hypotenuse(a, b):.2f}")
Explanation: This example uses the now function from the datetime
module to get the current date and time.
Exercise: Write a function that calculates the number of days between two
dates.
import datetime
def days_between(date1, date2):
delta = date2 - date1
return delta.days
date1 = datetime.datetime(2023, 1, 1)
date2 = datetime.datetime(2024, 1, 1)
print(f"Days between: {days_between(date1, date2)}")
4. The os Module
The os module provides a way of using operating system-dependent
functionality like reading or writing to the file system.
Example: Listing files in a directory.
import os
def list_files(directory):
return os.listdir(directory)
directory = "."
print(f"Files in '{directory}': {list_files(directory)}")
Explanation: This example uses the listdir function from the os module to
list files in the current directory.
Exercise: Write a function that creates a new directory.
import os
def create_directory(directory):
os.makedirs(directory, exist_ok=True)
print(f"Directory '{directory}' created")
create_directory("new_directory")
Explanation: This script imports the mymath module and uses its functions
to perform arithmetic operations.
3. Using Specific Functions
You can also import specific functions from a module.
Example: Importing specific functions from mymath.
from mymath import add, subtract
result_add = add(20, 10)
result_subtract = subtract(20, 10)
print(f"Add: {result_add}")
print(f"Subtract: {result_subtract}")
Explanation: This script imports only the add and subtract functions from
the mymath module, allowing you to use them directly without the mymath.
prefix.
4. Using Aliases
You can assign an alias to the module or its functions to simplify
their usage.
Example: Using aliases for the mymath module.
import mymath as mm
result_add = mm.add(30, 15)
result_subtract = mm.subtract(30, 15)
print(f"Add: {result_add}")
print(f"Subtract: {result_subtract}")
Explanation: This script imports the mymath module with the alias mm,
making it shorter to reference the module's functions.
Practical Examples and Exercises
Example 1: Creating a String Utilities Module
Task: Create a module named string_utils.py with functions to manipulate
strings.
Code:
# string_utils.py
def to_uppercase(s):
return s.upper()
def to_lowercase(s):
return s.lower()
def reverse_string(s):
return s[::-1]
# utilities/__init__.py
# This file can be empty or contain package initialization code.
string_utils.py:
# utilities/string_utils.py
def to_uppercase(s):
return s.upper()
def to_lowercase(s):
return s.lower()
def reverse_string(s):
return s[::-1]
file_utils.py:
# utilities/file_utils.py
def read_file(file_path):
with open(file_path, 'r') as file:
return file.read()
def write_file(file_path, content):
with open(file_path, 'w') as file:
file.write(content)
def append_to_file(file_path, content):
with open(file_path, 'a') as file:
file.write(content)
Code:
string_utils.py:
def to_uppercase(s):
return s.upper()
def to_lowercase(s):
return s.lower()
def reverse_string(s):
return s[::-1]
file_utils.py:
def read_file(file_path):
with open(file_path, 'r') as file:
return file.read()
def write_file(file_path, content):
with open(file_path, 'w') as file:
file.write(content)
def append_to_file(file_path, content):
with open(file_path, 'a') as file:
file.write(content)
__init__.py:
# Initialize the package
Solution:
basic_operations.py:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b != 0:
return a / b
else:
return "Division by zero is not allowed"
advanced_operations.py:
import math
def power(base, exponent):
return math.pow(base, exponent)
def sqrt(number):
return math.sqrt(number)
__init__.py:
# Initialize the package
Explanation: This function defines a local variable and prints both the
local and global namespaces using locals() and globals().
4.3.5 PRACTICAL APPLICATIONS AND
EXERCISES
In this section, we'll cover a range of practical applications and
exercises that demonstrate the creation and usage of modules and packages
in Python. These exercises will help you solidify your understanding of
these concepts and give you hands-on experience in organizing your code
more effectively.
Practical Application 1: Creating a Utility Package
Task 1: Create a package named utils with modules for string operations
and file operations.
Directory Structure:
utils/
__init__.py
string_utils.py
file_utils.py
string_utils.py:
# utils/string_utils.py
def to_uppercase(s):
return s.upper()
def to_lowercase(s):
return s.lower()
def reverse_string(s):
return s[::-1]
def is_palindrome(s):
return s == s[::-1]
file_utils.py:
# utils/file_utils.py
def read_file(file_path):
with open(file_path, 'r') as file:
return file.read()
def write_file(file_path, content):
with open(file_path, 'w') as file:
file.write(content)
def append_to_file(file_path, content):
with open(file_path, 'a') as file:
file.write(content)
def count_lines(file_path):
with open(file_path, 'r') as file:
return len(file.readlines())
basic.py:
# math_operations/basic.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b != 0:
return a / b
else:
return "Division by zero is not allowed"
advanced.py:
# math_operations/advanced.py
import math
def power(base, exponent):
return math.pow(base, exponent)
def sqrt(number):
return math.sqrt(number)
def factorial(number):
return math.factorial(number)
def logarithm(number, base=math.e):
return math.log(number, base)
cleaning.py:
# data_processing/cleaning.py
def remove_duplicates(data):
return list(set(data))
def fill_missing_values(data, fill_value):
return [x if x is not None else fill_value for x in data]
def normalize_data(data):
max_val = max(data)
min_val = min(data)
return [(x - min_val) / (max_val - min_val) for x in data]
analysis.py:
# data_processing/analysis.py
def mean(data):
return sum(data) / len(data)
def median(data):
sorted_data = sorted(data)
n = len(data)
mid = n // 2
if n % 2 == 0:
return (sorted_data[mid - 1] + sorted_data[mid]) / 2
else:
return sorted_data[mid]
def variance(data):
m = mean(data)
return sum((x - m) ** 2 for x in data) / len(data)
def standard_deviation(data):
return variance(data) ** 0.5
fetch.py:
# web_scraper/fetch.py
import requests
def fetch_html(url):
response = requests.get(url)
return response.text if response.status_code == 200 else None
parse.py:
# web_scraper/parse.py
from bs4 import BeautifulSoup
def parse_html(html):
soup = BeautifulSoup(html, 'html.parser')
return soup
def get_page_title(soup):
return soup.title.string
def get_all_links(soup):
return [a['href'] for a in soup.find_all('a', href=True)]
Examples:
# Creating a list of integers
numbers = [1, 2, 3, 4, 5]
# Creating a list of strings
fruits = ["apple", "banana", "cherry"]
# Creating a list with mixed data types
mixed_list = [1, "hello", 3.14, True]
# Creating an empty list
empty_list = []
Slicing Lists
Slicing allows you to access a subset of a list by specifying a range
of indices. The syntax for slicing is list_name[start:stop:step], where start
is the index to begin the slice, stop is the index to end the slice (not
inclusive), and step is the interval between indices.
Examples:
# Slicing the list 'numbers'
first_three_numbers = numbers[0:3] # Output: [1, 2, 3]
# Slicing with a step
every_second_number = numbers[::2] # Output: [1, 3, 5]
# Slicing from the end
last_two_numbers = numbers[-2:] # Output: [4, 5]
Modifying Lists
Lists are mutable, meaning you can change their content without
changing their identity. You can modify elements, add new elements, or
remove existing elements.
Modifying Elements
Syntax:
list_name[index] = new_value
Examples:
# Modifying the second element in the list 'numbers'
numbers[1] = 20
print(numbers) # Output: [1, 20, 3, 4, 5]
Adding Elements
You can add elements to a list using the append(), insert(), and
extend() methods.
Examples:
# Using append() to add a single element
numbers.append(6)
print(numbers) # Output: [1, 20, 3, 4, 5, 6]
# Using insert() to add an element at a specific position
numbers.insert(2, 15)
print(numbers) # Output: [1, 20, 15, 3, 4, 5, 6]
# Using extend() to add multiple elements
numbers.extend([7, 8])
print(numbers) # Output: [1, 20, 15, 3, 4, 5, 6, 7, 8]
Removing Elements
You can remove elements from a list using the remove(), pop(), and
clear() methods.
Examples:
# Using remove() to remove a specific element
numbers.remove(20)
print(numbers) # Output: [1, 15, 3, 4, 5, 6, 7, 8]
# Using pop() to remove an element by index
numbers.pop(2)
print(numbers) # Output: [1, 15, 4, 5, 6, 7, 8]
# Using clear() to remove all elements
numbers.clear()
print(numbers) # Output: []
Output:
First movie: Inception
Last movie: The Dark Knight
Some movies: ['The Matrix', 'Interstellar']
Exercise 1: Create a list of your top 5 favorite books and perform the
following operations:
Access the second book.
Access the last two books.
Modify the third book to a different title.
Add a new book to the end of the list.
Remove the first book from the list.
Solution:
favorite_books = ["1984", "To Kill a Mockingbird", "The Great Gatsby", "Moby Dick", "War and
Peace"]
# Accessing the second book
second_book = favorite_books[1]
print(f"Second book: {second_book}")
# Accessing the last two books
last_two_books = favorite_books[-2:]
print(f"Last two books: {last_two_books}")
# Modifying the third book
favorite_books[2] = "Pride and Prejudice"
print(f"Modified books: {favorite_books}")
# Adding a new book
favorite_books.append("The Catcher in the Rye")
print(f"Books after adding: {favorite_books}")
# Removing the first book
favorite_books.pop(0)
print(f"Books after removing the first one: {favorite_books}")
Output:
Second book: To Kill a Mockingbird
Last two books: ['Moby Dick', 'War and Peace']
Modified books: ['1984', 'To Kill a Mockingbird', 'Pride and Prejudice', 'Moby Dick', 'War and Peace']
Books after adding: ['1984', 'To Kill a Mockingbird', 'Pride and Prejudice', 'Moby Dick', 'War and
Peace', 'The Catcher in the Rye']
Books after removing the first one: ['To Kill a Mockingbird', 'Pride and Prejudice', 'Moby Dick', 'War
and Peace', 'The Catcher in the Rye']
5.1.2 LIST METHODS AND
OPERATIONS
Lists are a versatile data structure in Python, and they come with a
variety of built-in methods and operations that make manipulating and
working with lists efficient and straightforward. This section covers these
methods and operations in detail, providing practical examples and
exercises to reinforce your understanding.
List Methods
Python lists have several built-in methods that allow you to perform
various operations on them. Here are some of the most commonly used list
methods:
1. append()
The append() method adds a single element to the end of the list.
Syntax:
list_name.append(element)
Example:
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
print(fruits) # Output: ["apple", "banana", "cherry", "orange"]
Syntax:
list_name.extend(iterable)
Example:
fruits = ["apple", "banana", "cherry"]
more_fruits = ["orange", "grape"]
fruits.extend(more_fruits)
print(fruits) # Output: ["apple", "banana", "cherry", "orange", "grape"]
Example:
fruits = ["apple", "banana", "cherry"]
fruits.insert(1, "orange")
print(fruits) # Output: ["apple", "orange", "banana", "cherry"]
Example:
fruits = ["apple", "banana", "cherry", "banana"]
fruits.remove("banana")
print(fruits) # Output: ["apple", "cherry", "banana"]
Explanation: This removes the first occurrence of "banana" from the fruits
list.
5. pop()
The pop() method removes and returns the element at a specified
position. If no index is specified, it removes and returns the last element.
Syntax:
list_name.pop(index)
Example:
fruits = ["apple", "banana", "cherry"]
removed_fruit = fruits.pop(1)
print(fruits) # Output: ["apple", "cherry"]
print(removed_fruit) # Output: "banana"
Example:
fruits = ["apple", "banana", "cherry"]
fruits.clear()
print(fruits) # Output: []
Example:
fruits = ["apple", "banana", "cherry"]
index_of_banana = fruits.index("banana")
print(index_of_banana) # Output: 1
Syntax:
list_name.count(element)
Example:
fruits = ["apple", "banana", "cherry", "banana"]
banana_count = fruits.count("banana")
print(banana_count) # Output: 2
Example:
fruits = ["cherry", "banana", "apple"]
fruits.sort()
print(fruits) # Output: ["apple", "banana", "cherry"]
# Sorting in descending order
fruits.sort(reverse=True)
print(fruits) # Output: ["cherry", "banana", "apple"]
Explanation: This sorts the fruits list in ascending and then in descending
order.
10. reverse()
The reverse() method reverses the order of elements in the list.
Syntax:
list_name.reverse()
Example:
fruits = ["apple", "banana", "cherry"]
fruits.reverse()
print(fruits) # Output: ["cherry", "banana", "apple"]
Output:
apple
banana
cherry
Explanation: This iterates over each element in the fruits list and prints it.
Practical Examples and Exercises
Example 1: List Methods
Task: Create a list of favorite songs and perform various list operations.
Code:
favorite_songs = ["Bohemian Rhapsody", "Stairway to Heaven", "Hotel California"]
# Adding a song to the end
favorite_songs.append("Imagine")
print(favorite_songs)
# Inserting a song at the second position
favorite_songs.insert(1, "Comfortably Numb")
print(favorite_songs)
# Removing a song
favorite_songs.remove("Stairway to Heaven")
print(favorite_songs)
# Popping the last song
last_song = favorite_songs.pop()
print(favorite_songs)
print(f"Last song: {last_song}")
# Counting occurrences of a song
favorite_songs.append("Hotel California")
count_hotel_california = favorite_songs.count("Hotel California")
print(f"Hotel California count: {count_hotel_california}")
# Sorting the list
favorite_songs.sort()
print(f"Sorted songs: {favorite_songs}")
# Reversing the list
favorite_songs.reverse()
print(f"Reversed songs: {favorite_songs}")
Output:
['Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California', 'Imagine']
['Bohemian Rhapsody', 'Comfortably Numb', 'Stairway to Heaven', 'Hotel California', 'Imagine']
['Bohemian Rhapsody', 'Comfortably Numb', 'Hotel California', 'Imagine']
['Bohemian Rhapsody', 'Comfortably Numb', 'Hotel California']
Last song: Imagine
Hotel California count: 2
Sorted songs: ['Bohemian Rhapsody', 'Comfortably Numb'][...]
11. copy()
The copy() method returns a shallow copy of the list.
Syntax:
list_name.copy()
Example:
fruits = ["apple", "banana", "cherry"]
fruits_copy = fruits.copy()
print(fruits_copy) # Output: ["apple", "banana", "cherry"]
Example:
# Sorting a list of integers
numbers = [5, 2, 9, 1, 5, 6]
numbers.sort()
print(numbers) # Output: [1, 2, 5, 5, 6, 9]
# Sorting a list of strings
fruits = ["banana", "apple", "cherry"]
fruits.sort()
print(fruits) # Output: ["apple", "banana", "cherry"]
# Sorting in descending order
fruits.sort(reverse=True)
print(fruits) # Output: ["cherry", "banana", "apple"]
# Sorting with a key function (sorting by length of strings)
fruits.sort(key=len)
print(fruits) # Output: ["apple", "banana", "cherry"]
Explanation: This sorts the numbers list in ascending order, the fruits list
in ascending and then descending order, and then sorts the fruits list by the
length of the strings.
Practical Examples and Exercises
Example 1: Working with List Methods
Task: Create a list of favorite books and perform various list operations.
Code:
favorite_books = ["1984", "To Kill a Mockingbird", "The Great Gatsby", "Moby Dick"]
# Adding a book to the end
favorite_books.append("War and Peace")
print(favorite_books)
# Inserting a book at the second position
favorite_books.insert(1, "Pride and Prejudice")
print(favorite_books)
# Removing a book
favorite_books.remove("The Great Gatsby")
print(favorite_books)
# Popping the last book
last_book = favorite_books.pop()
print(favorite_books)
print(f"Last book: {last_book}")
# Counting occurrences of a book
favorite_books.append("1984")
count_1984 = favorite_books.count("1984")
print(f"'1984' count: {count_1984}")
# Sorting the list
favorite_books.sort()
print(f"Sorted books: {favorite_books}")
# Reversing the list
favorite_books.reverse()
print(f"Reversed books: {favorite_books}")
Output:
['1984', 'To Kill a Mockingbird', 'The Great Gatsby', 'Moby Dick', 'War and Peace']
['1984', 'Pride and Prejudice', 'To Kill a Mockingbird', 'The Great Gatsby', 'Moby Dick', 'War and
Peace']
['1984', 'Pride and Prejudice', 'To Kill a Mockingbird', 'Moby Dick', 'War and Peace']
['1984', 'Pride and Prejudice', 'To Kill a Mockingbird', 'Moby Dick']
Last book: War and Peace
'1984' count: 2
Sorted books: ['1984', '1984', 'Moby Dick', 'Pride and Prejudice', 'To Kill a Mockingbird']
Reversed books: ['To Kill a Mockingbird', 'Pride and Prejudice', 'Moby Dick', '1984', '1984']
5. Concatenation
You can concatenate two lists using the + operator.
Example:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined_list = list1 + list2
print(combined_list) # Output: [1, 2, 3, 4, 5, 6]
Output:
apple
banana
cherry
Explanation: This iterates over each element in the fruits list and prints it.
Practical Examples and Exercises
Example 2: List Operations
Task: Create two lists of numbers and perform various list operations.
Code:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# Concatenation
combined_list = list1 + list2
print(f"Combined list: {combined_list}")
# Repetition
repeated_list = list1 * 2
print(f"Repeated list: {repeated_list}")
# Membership
is_2_in_list = 2 in list1
print(f"Is 2 in list1? {is_2_in_list}")
# Iteration
for number in list1:
print(f"Number in list1: {number}")
Output:
Combined list: [1, 2, 3, 4, 5, 6]
Repeated list: [1, 2, 3, 1, 2, 3]
Is 2 in list1? True
Number in list1: 1
Number in list1: 2
Number in list1: 3
5.1.3 LIST COMPREHENSIONS
List comprehensions provide a concise way to create lists in Python.
They can replace for loops and the map(), filter(), and reduce() functions
for certain tasks, making code more readable and compact. This section
covers the syntax and use cases of list comprehensions in detail, with
practical examples and exercises.
Basic Syntax of List Comprehensions
The basic syntax for a list comprehension is:
[expression for item in iterable if condition]
Explanation: This list comprehension includes only the even numbers from
1 to 20.
Example 3: Applying Functions
Task: Create a list of uppercase versions of strings in a list.
Code:
words = ["hello", "world", "python", "list"]
uppercase_words = [word.upper() for word in words]
print(uppercase_words) # Output: ["HELLO", "WORLD", "PYTHON", "LIST"]
Explanation: This list comprehension converts each string in the words list
to uppercase.
Nested List Comprehensions
You can use nested list comprehensions to create lists of lists or to
flatten a nested list.
Example 4: Flattening a Nested List
Task: Flatten a 2D list into a 1D list.
Code:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Explanation: This list comprehension iterates over each row and then over
each number in the row to create a flattened list.
Example 5: Creating a 2D List
Task: Create a 2D list of size 3x3 initialized with zeroes.
Code:
zeros_2d = [[0 for _ in range(3)] for _ in range(3)]
print(zeros_2d) # Output: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Output:
[1, 2, 3, 4, 5]
[2, 4, 6, 8, 10]
[3, 6, 9, 12, 15]
[4, 8, 12, 16, 20]
[5, 10, 15, 20, 25]
Output:
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4)]
[(1, 0), (1, 1), (1, 2), (1, 3), (1, 4)]
[(2, 0), (2, 1), (2, 2), (2, 3), (2, 4)]
[(3, 0), (3, 1), (3, 2), (3, 3), (3, 4)]
[(4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]
Explanation: This nested list comprehension creates a 5x5 grid where each
element is a tuple containing its row and column indices.
5.1.4 PRACTICAL EXAMPLES AND
EXERCISES
In this section, we will cover a range of practical examples and
exercises using list comprehensions. These examples will help you
understand how to apply list comprehensions in different scenarios,
enhancing your skills in writing concise and efficient Python code. These
examples and exercises are unique compared to the ones we had earlier,
providing more variety and challenges.
Example 1: Generate a List of Prime Numbers
Task: Create a list of prime numbers between 2 and 50.
Code:
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
primes = [x for x in range(2, 51) if is_prime(x)]
print(primes) # Output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Examples:
# Creating a tuple of integers
numbers = (1, 2, 3, 4, 5)
# Creating a tuple of strings
fruits = ("apple", "banana", "cherry")
# Creating a tuple with mixed data types
mixed_tuple = (1, "hello", 3.14, True)
# Creating an empty tuple
empty_tuple = ()
# Creating a tuple without parentheses (tuple packing)
packed_tuple = 1, "hello", 3.14
Examples:
# Accessing elements from the tuple 'numbers'
first_number = numbers[0] # Output: 1
second_number = numbers[1] # Output: 2
# Accessing elements from the tuple 'fruits'
first_fruit = fruits[0] # Output: "apple"
second_fruit = fruits[1] # Output: "banana"
Examples:
# Slicing the tuple 'numbers'
first_three_numbers = numbers[0:3] # Output: (1, 2, 3)
# Slicing with a step
every_second_number = numbers[::2] # Output: (1, 3, 5)
# Slicing from the end
last_two_numbers = numbers[-2:] # Output: (4, 5)
Example:
numbers = (1, 2, 3, 2, 4, 2)
count_of_twos = numbers.count(2)
print(count_of_twos) # Output: 3
Explanation: This example shows how to use the count() method to count
occurrences of a value in a tuple.
index()
The index() method returns the first index of a specified value in the
tuple.
Syntax:
tuple_name.index(value)
Example:
numbers = (1, 2, 3, 2, 4, 2)
index_of_first_two = numbers.index(2)
print(index_of_first_two) # Output: 1
Output:
First color: red
Primary colors: ('red', 'green', 'blue')
All colors: ('red', 'green', 'blue', 'yellow', 'purple', 'orange')
Count of 'red': 1
Index of 'blue': 2
Output:
Second student: Bob
Last student: Eva
First three students: ('Alice', 'Bob', 'Charlie')
All students: ('Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Fiona', 'George')
Count of 'Alice': 1
Index of 'Charlie': 2
Output:
Element at row 2, column 3: 6
Second row: (4, 5, 6)
First column: (1, 4, 7)
Output:
Names: ('Alice', 'Bob', 'Charlie', 'David')
Ages: (20, 21, 19, 22)
Grades: ('A', 'B', 'A', 'C')
Example:
numbers = (1, 2, 3, 2, 4, 2)
count_of_twos = numbers.count(2)
print(count_of_twos) # Output: 3
Explanation: This example shows how to use the count() method to count
occurrences of the value 2 in the numbers tuple.
2. index()
The index() method returns the first index of a specified value in the
tuple. If the value is not found, it raises a ValueError.
Syntax:
tuple_name.index(value)
Example:
numbers = (1, 2, 3, 2, 4, 2)
index_of_first_two = numbers.index(2)
print(index_of_first_two) # Output: 1
Output:
apple
banana
cherry
Explanation: This example shows how to pack multiple values into a tuple
without using parentheses.
Unpacking
Tuple unpacking is the process of extracting values from a tuple into
individual variables.
Example:
numbers = (1, 2, 3)
a, b, c = numbers
print(a) # Output: 1
print(b) # Output: 2
print(c) # Output: 3
Output:
All foods: ('pizza', 'burger', 'pasta', 'sushi', 'tacos')
Repeated foods: ('pizza', 'burger', 'pasta', 'pizza', 'burger', 'pasta')
Is pizza in foods1? True
Performance
Tuples: Tuples are generally faster than lists for iteration and access
operations due to their immutability.
Lists: Lists are slightly slower than tuples because of their
mutability, which adds overhead for managing the list's dynamic nature.
Example:
import timeit
# Timing tuple access
tuple_time = timeit.timeit('x = my_tuple[0]', setup='my_tuple = (1, 2, 3)', number=1000000)
print(f'Tuple access time: {tuple_time}')
# Timing list access
list_time = timeit.timeit('x = my_list[0]', setup='my_list = [1, 2, 3]', number=1000000)
print(f'List access time: {list_time}')
Use Cases
Tuples: Use tuples for data that should not change throughout the
program. Common use cases include returning multiple values from a
function, using as keys in dictionaries (due to their immutability), and
representing fixed collections of related items.
Lists: Use lists for data that is expected to change or grow. Common
use cases include maintaining collections of items, storing sequences that
need to be modified, and using in loops for iteration and modification.
Practical Examples and Exercises
Example 1: Returning Multiple Values from a Function
Task: Use a tuple to return multiple values from a function.
Code:
def get_person_info():
name = "Alice"
age = 30
city = "New York"
return name, age, city
person_info = get_person_info()
print(person_info) # Output: ('Alice', 30, 'New York')
Explanation: This example shows how to use a list for a collection of items
that need to be modified dynamically.
Exercise 2: Iterating Over a List and Modifying It
Task: Use a list to store numbers and filter out even numbers.
Solution:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
odd_numbers = [number for number in numbers if number % 2 != 0]
print(odd_numbers) # Output: [1, 3, 5, 7, 9]
Explanation: This exercise shows how to use a list to store shopping cart
items, add new items using the append method, and remove an item using
the remove method.
Example 3: Using Tuples for Dictionary Keys
Task: Use tuples as keys in a dictionary to represent locations on a grid and
store their descriptions.
Code:
locations = {
(0, 0): "Home",
(1, 2): "School",
(3, 4): "Library"
}
print(locations[(1, 2)]) # Output: School
Explanation: This example demonstrates how to use tuples as immutable
keys in a dictionary to represent locations and store their descriptions.
Example 4: Using Lists for Sequence Operations
Task: Use a list to store a sequence of numbers and find the maximum and
minimum values.
Code:
numbers = [10, 20, 30, 40, 50]
max_value = max(numbers)
min_value = min(numbers)
print(f"Max: {max_value}, Min: {min_value}") # Output: Max: 50, Min: 10
Code:
user_inputs = []
for _ in range(5):
user_input = input("Enter a value: ")
user_inputs.append(user_input)
print("User Inputs:", user_inputs)
Example:
# Creating a dictionary of student grades
student_grades = {
"Alice": "A",
"Bob": "B",
"Charlie": "C"
}
print(student_grades) # Output: {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'}
Explanation: This example shows how to create a dictionary using curly
braces, where the keys are student names and the values are their grades.
Method 2: Using the dict() Function
Syntax:
dictionary_name = dict(key1=value1, key2=value2, ...)
Example:
# Creating a dictionary using the dict() function
student_ages = dict(Alice=20, Bob=21, Charlie=22)
print(student_ages) # Output: {'Alice': 20, 'Bob': 21, 'Charlie': 22}
Example:
# Creating a dictionary of squares using a dictionary comprehension
squares = {x: x**2 for x in range(1, 6)}
print(squares) # Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Example:
# Using the get() method to access values
bob_grade = student_grades.get("Bob", "No grade")
unknown_grade = student_grades.get("Unknown", "No grade")
print(bob_grade) # Output: 'B'
print(unknown_grade) # Output: 'No grade'
Explanation: This example shows how to use the get() method to access
values and handle cases where the key does not exist.
Adding and Modifying Dictionary Elements
Dictionaries are mutable, allowing you to add new key-value pairs
or modify existing ones.
Adding Elements
Syntax:
dictionary_name[key] = value
Example:
# Adding a new key-value pair to a dictionary
student_grades["David"] = "B"
print(student_grades) # Output: {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C', 'David': 'B'}
Explanation: This example demonstrates how to add a new key-value pair
to the student_grades dictionary.
Modifying Elements
Syntax:
dictionary_name[key] = new_value
Example:
# Modifying an existing value in a dictionary
student_grades["Alice"] = "A+"
print(student_grades) # Output: {'Alice': 'A+', 'Bob': 'B', 'Charlie': 'C', 'David': 'B'}
Explanation: This example shows how to modify the value associated with
the key "Alice" in the student_grades dictionary.
Removing Dictionary Elements
Dictionaries provide several methods for removing elements,
including pop(), popitem(), and del.
Using the pop() Method
The pop() method removes a key-value pair by key and returns the
value.
Syntax:
value = dictionary_name.pop(key, default_value)
Example:
# Removing an element using the pop() method
removed_grade = student_grades.pop("Bob", "No grade")
print(removed_grade) # Output: 'B'
print(student_grades) # Output: {'Alice': 'A+', 'Charlie': 'C', 'David': 'B'}
Example:
# Removing the last key-value pair using the popitem() method
last_item = student_grades.popitem()
print(last_item) # Output: ('David', 'B')
print(student_grades) # Output: {'Alice': 'A+', 'Charlie': 'C'}
Example:
# Removing a key-value pair using the del statement
del student_grades["Charlie"]
print(student_grades) # Output: {'Alice': 'A+'}
Syntax:
keys_view = dictionary_name.keys()
Example:
# Getting all keys in a dictionary
keys = student_grades.keys()
print(keys) # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
values()
The values() method returns a view object that displays a list of all
the values in the dictionary.
Syntax:
values_view = dictionary_name.values()
Example:
# Getting all values in a dictionary
values = student_grades.values()
print(values) # Output: dict_values(['A', 'B', 'C'])
items()
The items() method returns a view object that displays a list of all
the key-value pairs in the dictionary as tuples.
Syntax:
items_view = dictionary_name.items()
Example:
# Getting all key-value pairs in a dictionary
items = student_grades.items()
print(items) # Output: dict_items([('Alice', 'A'), ('Bob', 'B'), ('Charlie', 'C')])
Explanation: This exercise shows how to add a new item to the inventory,
update the quantity of an existing item, and remove an item from the
dictionary.
Example 2: Using Dictionaries for Data Aggregation
Task: Use a dictionary to count the occurrences of each word in a given
sentence.
Code:
sentence = "the quick brown fox jumps over the lazy dog the fox is quick"
words = sentence.split()
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(word_count)
# Output: {'the': 3, 'quick': 2, 'brown': 1, 'fox': 2, 'jumps': 1, 'over': 1, 'lazy': 1, 'dog': 1, 'is': 1}
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
student_grades.clear()
print(student_grades) # Output: {}
Example:
keys = ["Alice", "Bob", "Charlie"]
default_value = "Not Assigned"
student_grades = dict.fromkeys(keys, default_value)
print(student_grades) # Output: {'Alice': 'Not Assigned', 'Bob': 'Not Assigned', 'Charlie': 'Not
Assigned'}
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
bob_grade = student_grades.get("Bob", "No grade")
unknown_grade = student_grades.get("Unknown", "No grade")
print(bob_grade) # Output: 'B'
print(unknown_grade) # Output: 'No grade'
Explanation: This method is useful for safely accessing dictionary values
without raising a KeyError.
5. items()
The items() method returns a view object that displays a list of
dictionary's key-value tuple pairs.
Syntax:
items_view = dictionary_name.items()
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
items = student_grades.items()
print(items) # Output: dict_items([('Alice', 'A'), ('Bob', 'B'), ('Charlie', 'C')])
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
keys = student_grades.keys()
print(keys) # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
Explanation: This method is useful for iterating over or accessing all keys
in a dictionary.
7. pop()
The pop() method removes the specified key and returns the
corresponding value. If the key is not found, it returns the specified default
value.
Syntax:
value = dictionary_name.pop(key, default_value)
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
removed_grade = student_grades.pop("Bob", "No grade")
print(removed_grade) # Output: 'B'
print(student_grades) # Output: {'Alice': 'A', 'Charlie': 'C'}
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
last_item = student_grades.popitem()
print(last_item) # Output: ('Charlie', 'C')
print(student_grades) # Output: {'Alice': 'A', 'Bob': 'B'}
Explanation: This method is useful for removing and retrieving the last
key-value pair in a dictionary.
9. setdefault()
The setdefault() method returns the value of the specified key. If the
key does not exist, it inserts the key with the specified value.
Syntax:
value = dictionary_name.setdefault(key, default_value)
Example:
student_grades = {"Alice": "A", "Bob": "B"}
default_grade = student_grades.setdefault("Charlie", "C")
print(default_grade) # Output: 'C'
print(student_grades) # Output: {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'}
Explanation: This method is useful for ensuring that a key exists in a
dictionary with a default value.
10. update()
The update() method updates the dictionary with the elements from
another dictionary or an iterable of key-value pairs.
Syntax:
dictionary_name.update(other_dictionary)
Example:
student_grades = {"Alice": "A", "Bob": "B"}
new_grades = {"Charlie": "C", "David": "D"}
student_grades.update(new_grades)
print(student_grades) # Output: {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C', 'David': 'D'}
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
values = student_grades.values()
print(values) # Output: dict_values(['A', 'B', 'C'])
Output:
Alice's salary: 70000
Employee names: ['Alice', 'Bob', 'Charlie']
Salaries: [70000, 80000, 90000]
Employee salaries: [('Alice', 70000), ('Bob', 80000), ('Charlie', 90000)]
Explanation: This exercise shows how to use popitem() to remove the last
added key-value pair and clear() to remove all elements from the
dictionary.
Example 3: Using Multiple Dictionary Methods
Task: Create a dictionary of book titles and their authors. Perform
operations to add, update, retrieve, and remove books using various
dictionary methods.
Code:
# Creating the book dictionary
books = {
"1984": "George Orwell",
"To Kill a Mockingbird": "Harper Lee",
"The Great Gatsby": "F. Scott Fitzgerald"
}
# Adding a new book using update()
books.update({"Brave New World": "Aldous Huxley"})
print(books)
# Updating an existing book's author using update()
books.update({"1984": "Eric Arthur Blair"})
print(books)
# Retrieving an author's name using get()
author = books.get("The Great Gatsby", "Unknown")
print(f"The author of 'The Great Gatsby' is {author}")
# Removing a book using pop()
removed_book = books.pop("To Kill a Mockingbird", "Book not found")
print(f"Removed book: {removed_book}")
print(books)
Explanation: This example demonstrates how to use update(), get(), and
pop() to manage a dictionary of books and authors.
Example 4: Counting Character Frequencies
Task: Create a dictionary to count the frequency of each character in a
given string.
Code:
# Input string
input_string = "mississippi"
# Counting character frequencies
char_count = {}
for char in input_string:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
print(char_count) # Output: {'m': 1, 'i': 4, 's': 4, 'p': 2}
Solution:
# Student grades list
students = [
("Alice", "A"),
("Bob", "B"),
("Charlie", "A"),
("David", "C"),
("Eva", "B")
]
# Grouping students by grades
grade_groups = {}
for student, grade in students:
grade_groups.setdefault(grade, []).append(student)
print(grade_groups) # Output: {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Eva'], 'C': ['David']}
Explanation: This exercise demonstrates how to group students by their
grades using the setdefault() method to create and update lists in a
dictionary.
5.3.3 ITERATING OVER DICTIONARIES
Dictionaries are a fundamental data structure in Python, allowing
you to store key-value pairs. Efficiently iterating over these dictionaries is
essential for many tasks, such as data analysis, manipulation, and
aggregation. This section covers various methods to iterate over
dictionaries, providing detailed explanations, practical examples, and
exercises to reinforce your understanding.
Iterating Over Keys
The most straightforward way to iterate over a dictionary is by
looping through its keys. This method can be achieved using the for loop
directly on the dictionary.
Example:
student_grades = {"Alice": "A", "Bob": "B", "Charlie": "C"}
# Iterating over keys
for student in student_grades:
print(student)
Output:
Alice
Bob
Charlie
Explanation: This example shows how to iterate over the values of the
student_grades dictionary.
Iterating Over Key-Value Pairs
To iterate over both keys and values, you can use the items()
method, which returns key-value pairs as tuples.
Example:
# Iterating over key-value pairs
for student, grade in student_grades.items():
print(f"{student}: {grade}")
Output:
Alice: A
Bob: B
Charlie: C
Output:
{'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'}
Output:
{'Bob': 35, 'Charlie': 32}
Output:
Alice's grades:
Math: A
Science: B
Bob's grades:
Math: B
Science: C
Charlie's grades:
Math: C
Science: A
Output:
Total sales: $4600
Output:
{'hello': 2, 'world': 1, 'python': 1}
Output:
{90: ['Alice', 'Charlie'], 85: ['Bob', 'David'], 92: ['Eva']}
Output:
USA
France
Japan
Output:
Red
Yellow
Purple
Output:
Alice: 90
Bob: 85
Charlie: 92
Output:
{'Laptop': 900.0, 'Phone': 450.0, 'Tablet': 270.0}
Output:
Employee: Alice
Department: HR
Salary: 60000
Employee: Bob
Department: Engineering
Salary: 70000
Employee: Charlie
Department: Marketing
Salary: 50000
Output:
{'Blue': 2, 'Green': 2, 'Red': 1}
Output:
{'Fiction': ['To Kill a Mockingbird', 'The Great Gatsby'], 'Science': ['A Brief History of Time', 'The
Selfish Gene'], 'Dystopian': ['1984']}
Output:
{'North': 6000, 'South': 3300, 'East': 5100, 'West': 2850}
Output:
Average score: 87.00
Students who scored above average: ['Alice', 'Charlie', 'Eva']
Explanation: This exercise demonstrates how to calculate the average
value in a dictionary and use list comprehensions to find items that meet a
specific condition.
5.4 SETS
5.4.1 CREATING AND ACCESSING SETS
Sets are an essential data structure in Python that are used to store
unordered collections of unique elements. They are particularly useful when
you need to eliminate duplicate values and perform operations like unions,
intersections, and differences. This section provides a detailed guide on
creating and accessing sets, complete with practical examples and exercises
to help you understand and utilize sets effectively.
What is a Set?
A set is an unordered collection of unique elements. Unlike lists or
tuples, sets do not allow duplicate values, and they are mutable, meaning
you can add or remove elements. Sets are defined by placing elements
inside curly braces {} or by using the set() function.
Creating Sets
Method 1: Using Curly Braces {}
Syntax:
set_name = {element1, element2, element3, ...}
Example:
# Creating a set of fruits
fruits = {"apple", "banana", "cherry"}
print(fruits) # Output: {'banana', 'apple', 'cherry'}
Example:
# Creating a set from a list
numbers = set([1, 2, 3, 4, 5])
print(numbers) # Output: {1, 2, 3, 4, 5}
# Creating an empty set
empty_set = set()
print(empty_set) # Output: set()
Output:
banana
apple
cherry
Example:
# Adding an element to a set
fruits.add("orange")
print(fruits) # Output: {'banana', 'apple', 'cherry', 'orange'}
Explanation: This example shows how to add an element to a set using the
add() method.
Removing Elements from a Set
You can remove elements from a set using the remove() or
discard() method. The remove() method will raise a KeyError if the
element is not found, whereas the discard() method will not.
Syntax:
set_name.remove(element)
set_name.discard(element)
Example:
# Removing an element using remove()
fruits.remove("banana")
print(fruits) # Output: {'apple', 'cherry', 'orange'}
# Removing an element using discard()
fruits.discard("apple")
print(fruits) # Output: {'cherry', 'orange'}
Output:
banana
apple
cherry
Explanation: This example demonstrates how to create a set from a list to
eliminate duplicate values and iterate over the set to print each unique word.
Exercise 1: Adding and Removing Elements
Task: Create a set of numbers, add a new number to the set, and then
remove an existing number from the set.
Solution:
# Creating a set of numbers
numbers = {1, 2, 3, 4, 5}
# Adding a new number
numbers.add(6)
print(numbers) # Output: {1, 2, 3, 4, 5, 6}
# Removing an existing number
numbers.remove(3)
print(numbers) # Output: {1, 2, 4, 5, 6}
Explanation: This exercise shows how to add and remove elements from a
set using the add() and remove() methods.
Example 2: Set Operations (Union, Intersection, Difference)
Task: Perform union, intersection, and difference operations on two sets of
numbers.
Code:
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# Union
union_set = set1.union(set2)
print(f"Union: {union_set}") # Output: Union: {1, 2, 3, 4, 5, 6}
# Intersection
intersection_set = set1.intersection(set2)
print(f"Intersection: {intersection_set}") # Output: Intersection: {3, 4}
# Difference
difference_set = set1.difference(set2)
print(f"Difference: {difference_set}") # Output: Difference: {1, 2}
Example:
fruits = {"apple", "banana"}
fruits.add("cherry")
print(fruits) # Output: {'apple', 'banana', 'cherry'}
Explanation: This example shows how to add an element to a set using the
add() method.
2. remove()
The remove() method removes a specified element from the set. If
the element is not found, it raises a KeyError.
Syntax:
set_name.remove(element)
Example:
fruits.remove("banana")
print(fruits) # Output: {'apple', 'cherry'}
Explanation: This example demonstrates how to remove an element from a
set using the remove() method.
3. discard()
The discard() method removes a specified element from the set. If
the element is not found, it does nothing.
Syntax:
set_name.discard(element)
Example:
fruits.discard("apple")
print(fruits) # Output: {'cherry'}
Example:
fruit = fruits.pop()
print(fruit)
print(fruits)
Output:
cherry
set()
Example:
fruits.clear()
print(fruits) # Output: set()
Explanation: This example shows how to clear all elements from a set
using the clear() method.
6. copy()
The copy() method returns a shallow copy of the set.
Syntax:
new_set = set_name.copy()
Example:
new_fruits = fruits.copy()
print(new_fruits)
Example:
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1.union(set2)
print(union_set) # Output: {1, 2, 3, 4, 5}
Example:
intersection_set = set1.intersection(set2)
print(intersection_set) # Output: {3}
Example:
difference_set = set1.difference(set2)
print(difference_set) # Output: {1, 2}
Example:
sym_diff_set = set1.symmetric_difference(set2)
print(sym_diff_set) # Output: {1, 2, 4, 5}
Output:
Attendees after adding: {'David', 'Charlie', 'Alice', 'Eva', 'Bob'}
Attendees after removing: {'David', 'Alice', 'Bob'}
Explanation: This example demonstrates how to manage a set of attendees
by adding and removing elements.
Exercise 1: Set Operations with Student Groups
Task: Create two sets of students who play soccer and basketball. Find the
union, intersection, and difference between these sets.
Solution:
soccer_players = {"Alice", "Bob", "Charlie"}
basketball_players = {"Charlie", "David", "Eva"}
# Union of soccer and basketball players
all_players = soccer_players.union(basketball_players)
print(f"All players (union): {all_players}")
# Intersection of soccer and basketball players
both_sports_players = soccer_players.intersection(basketball_players)
print(f"Players who play both sports (intersection): {both_sports_players}")
# Difference between soccer and basketball players
soccer_only_players = soccer_players.difference(basketball_players)
print(f"Players who only play soccer (difference): {soccer_only_players}")
Output:
All players (union): {'Eva', 'David', 'Alice', 'Bob', 'Charlie'}
Players who play both sports (intersection): {'Charlie'}
Players who only play soccer (difference): {'Alice', 'Bob'}
Output:
Is set1 a subset of set2? True
Is set2 a superset of set1? True
Output:
Are the sets of courses disjoint? True
Output:
Registered users after adding new users: {'David', 'Alice', 'Eva', 'Charlie', 'Bob'}
Registered users after removing inactive users: {'David', 'Alice', 'Eva', 'Bob'}
Output:
All participants (union): {'David', 'Charlie', 'Alice', 'Eva', 'Bob'}
Participants who attended both sessions (intersection): {'Charlie'}
Explanation: This exercise shows how to use union() to combine sets and
intersection_update() to find common elements and update the set.
5.4.3 PRACTICAL APPLICATIONS AND
EXERCISES
To solidify your understanding of sets and their operations, we will
explore various practical applications and exercises that cover different
scenarios and use cases. These exercises are designed to be unique and
challenging, providing a comprehensive understanding of how to use sets
effectively in Python.
Practical Applications
Application 1: Detecting Duplicate Entries
Task: Create a set to detect and eliminate duplicate email addresses from a
list.
Code:
emails = [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
]
# Using a set to remove duplicates
unique_emails = set(emails)
print(f"Unique emails: {unique_emails}")
Explanation: This exercise shows how to find items that are unique to each
warehouse using the symmetric difference operation.
Exercise 4: Event Attendance Analysis
Task: Analyze attendance at multiple events to find attendees who attended
all events, some events, and only one event.
Solution:
event1_attendees = {"Alice", "Bob", "Charlie"}
event2_attendees = {"Bob", "David", "Alice"}
event3_attendees = {"Alice", "Charlie", "Eva"}
# Finding attendees who attended all events
all_events_attendees =
event1_attendees.intersection(event2_attendees).intersection(event3_attendees)
print(f"Attendees who attended all events: {all_events_attendees}")
# Finding attendees who attended at least one event
at_least_one_event_attendees = event1_attendees.union(event2_attendees).union(event3_attendees)
print(f"Attendees who attended at least one event: {at_least_one_event_attendees}")
# Finding attendees who attended only one event
only_one_event_attendees =
(event1_attendees.symmetric_difference(event2_attendees)).symmetric_difference(event3_attendees)
print(f"Attendees who attended only one event: {only_one_event_attendees}")
Example:
# Opening a file for reading
file = open("example.txt", "r")
Example:
# Reading the entire content of the file
file_content = file.read()
print(file_content)
Explanation: This example shows how to read and print the entire content
of a file.
Method 2: readline()
The readline() method reads a single line from the file.
Syntax:
line = file_object.readline()
Example:
# Reading the first line of the file
first_line = file.readline()
print(first_line)
Explanation: This example demonstrates how to read and print the first
line of a file.
Method 3: readlines()
The readlines() method reads all lines in the file and returns them as
a list of strings.
Syntax:
lines = file_object.readlines()
Example:
# Reading all lines of the file
lines = file.readlines()
print(lines)
Explanation: This example shows how to read and print all lines of a file
as a list.
Closing Files
It is important to close a file after you have finished working with it
to free up system resources. You can close a file using the close() method.
Syntax:
file_object.close()
Example:
# Closing the file
file.close()
Example:
# Using the with statement to open and read a file
with open("example.txt", "r") as file:
file_content = file.read()
print(file_content)
Explanation: This example shows how to use the with statement to open a
file, read its content, and automatically close the file.
Practical Examples and Exercises
Example 1: Reading a File Line by Line
Task: Read a file line by line and print each line.
Code:
with open("example.txt", "r") as file:
for line in file:
print(line.strip())
Explanation: This example demonstrates how to read a file line by line
using a for loop and the with statement. The strip() method is used to
remove any leading and trailing whitespace.
Exercise 1: Counting Lines in a File
Task: Write a program to count the number of lines in a file.
Solution:
line_count = 0
with open("example.txt", "r") as file:
for line in file:
line_count += 1
print(f"Number of lines: {line_count}")
Explanation: This example shows how to read all lines of a file into a list
and print the first and last lines.
Exercise 2: Searching for a Word in a File
Task: Write a program to search for a specific word in a file and print the
lines containing that word.
Solution:
search_word = "Python"
with open("example.txt", "r") as file:
for line in file:
if search_word in line:
print(line.strip())
Explanation: This exercise demonstrates how to search for a specific word
in a file and print the lines that contain the word.
6.1.2 WRITING TO FILES
Writing to files is a fundamental aspect of file handling in Python,
enabling you to create, modify, and save data to files. This section covers
the basics of writing to files, including various methods and practical
examples to help you understand and apply these techniques effectively.
Opening a File for Writing
To write to a file, you need to open it in write mode ("w"), append
mode ("a"), or exclusive creation mode ("x"). Each mode has its specific
use case:
"w": Write mode. Opens a file for writing. If the file does not exist,
it creates a new file. If the file exists, it truncates the file to zero length.
"a": Append mode. Opens a file for appending. If the file does not
exist, it creates a new file. If the file exists, it writes data at the end of the
file.
"x": Exclusive creation mode. Opens a file for exclusive creation. If
the file already exists, the operation fails.
Syntax:
file_object = open(filename, mode)
Example:
# Opening a file for writing
file = open("example.txt", "w")
Example:
# Writing a string to a file
file.write("Hello, World!")
Explanation: This example shows how to write the string "Hello, World!"
to a file.
Method 2: writelines()
The writelines() method writes a list of strings to the file. Each
string in the list is written to the file as a line.
Syntax:
file_object.writelines(list_of_strings)
Example:
# Writing multiple lines to a file
lines = ["First line\n", "Second line\n", "Third line\n"]
file.writelines(lines)
Example:
# Closing the file
file.close()
Explanation: This example shows how to close a file after writing data to
it.
Using the with Statement
To ensure that files are properly closed after their operations are
completed, you can use the with statement. This statement automatically
closes the file when the block of code within it is exited.
Syntax:
with open(filename, mode) as file_object:
# Perform file operations
Example:
# Using the with statement to open and write to a file
with open("example.txt", "w") as file:
file.write("Hello, World!\n")
lines = ["First line\n", "Second line\n", "Third line\n"]
file.writelines(lines)
Explanation: This example shows how to use the with statement to open a
file, write data to it, and automatically close the file.
Practical Examples and Exercises
Example 1: Writing User Input to a File
Task: Write a program that prompts the user for their name and writes it to
a file.
Code:
user_name = input("Enter your name: ")
with open("user_data.txt", "w") as file:
file.write(f"Name: {user_name}\n")
Example:
with open("example.txt", "r") as file:
content = file.read()
print(content)
Example:
with open("example.txt", "r") as file:
first_line = file.readline()
print(first_line)
Explanation: This example shows how to read a single line from a file
using the readline() method.
3. readlines()
The readlines() method reads all the lines in a file and returns them
as a list of strings.
Syntax:
lines = file_object.readlines()
Example:
with open("example.txt", "r") as file:
all_lines = file.readlines()
print(all_lines)
Explanation: This example demonstrates how to read all lines from a file
into a list using the readlines() method.
4. write()
The write() method writes a string to the file. If the file is opened in
write mode ("w"), it will overwrite the file. If the file is opened in append
mode ("a"), it will append to the file.
Syntax:
file_object.write(string)
Example:
with open("example.txt", "w") as file:
file.write("Hello, World!\n")
Explanation: This example shows how to write a string to a file using the
write() method.
5. writelines()
The writelines() method writes a list of strings to the file.
Syntax:
file_object.writelines(list_of_strings)
Example:
lines = ["First line\n", "Second line\n", "Third line\n"]
with open("example.txt", "w") as file:
file.writelines(lines)
Example:
file = open("example.txt", "r")
file.close()
Explanation: This example shows how to close a file using the close()
method.
7. seek()
The seek() method moves the file pointer to a specified position in
the file.
Syntax:
file_object.seek(offset, whence)
Example:
with open("example.txt", "r") as file:
file.seek(10)
content = file.read()
print(content)
Example:
with open("example.txt", "r") as file:
file.read(5)
position = file.tell()
print(position)
Explanation: This example shows how to get the current position of the
file pointer using the tell() method.
Practical Examples and Exercises
Example 1: Reading Specific Parts of a File
Task: Read the first 10 characters of a file and then read the next line.
Code:
with open("example.txt", "r") as file:
first_10_chars = file.read(10)
print(f"First 10 characters: {first_10_chars}")
next_line = file.readline()
print(f"Next line: {next_line}")
Explanation: This exercise shows how to write and append data to a file
using the writelines() method and different file modes.
Advanced File Methods
Example 2: Using seek() and tell()
Task: Move the file pointer to a specific position, read some data, and then
return to the beginning of the file.
Code:
with open("example.txt", "r") as file:
file.seek(10)
part_content = file.read(5)
print(f"Content from position 10: {part_content}")
file.seek(0)
beginning_content = file.read(10)
print(f"First 10 characters: {beginning_content}")
Explanation: This example demonstrates how to use the seek() and tell()
methods to move the file pointer and read data from specific positions in the
file.
Exercise 2: File Copying
Task: Write a program that copies the content of one file to another file.
Solution:
source_file = "source.txt"
destination_file = "destination.txt"
with open(source_file, "r") as src, open(destination_file, "w") as dest:
content = src.read()
dest.write(content)
with open(destination_file, "r") as file:
print(file.read())
Explanation: This example shows how to write text to a TXT file using the
write() method.
Working with CSV Files
CSV (Comma-Separated Values) files are used to store tabular data
in a plain text format. Each line in a CSV file represents a row, and each
value is separated by a comma.
Reading CSV Files
Python's csv module provides functionalities to read from and write
to CSV files.
Example:
import csv
# Reading a CSV file
with open("example.csv", "r") as file:
reader = csv.reader(file)
for row in reader:
print(row)
Explanation: This example demonstrates how to read a CSV file using the
csv.reader() function, which returns each row as a list.
Writing to CSV Files
Example:
import csv
# Data to write to the CSV file
data = [
["Name", "Age", "City"],
["Alice", 30, "New York"],
["Bob", 25, "Los Angeles"],
["Charlie", 35, "Chicago"]
]
# Writing to a CSV file
with open("example.csv", "w", newline='') as file:
writer = csv.writer(file)
writer.writerows(data)
Explanation: This example shows how to write data to a CSV file using
the csv.writer() function and the writerows() method.
Working with JSON Files
JSON (JavaScript Object Notation) files are used to store structured
data in a text format that is easy to read and write. JSON is often used for
data interchange between a server and a web application.
Reading JSON Files
Python's json module provides functionalities to read from and write
to JSON files.
Example:
import json
# Reading a JSON file
with open("example.json", "r") as file:
data = json.load(file)
print(data)
Explanation: This example demonstrates how to read a JSON file using the
json.load() function, which parses the JSON data into a Python dictionary.
Writing to JSON Files
Example:
import json
# Data to write to the JSON file
data = {
"Name": "Alice",
"Age": 30,
"City": "New York"
}
# Writing to a JSON file
with open("example.json", "w") as file:
json.dump(data, file, indent=4)
Explanation: This example shows how to write data to a JSON file using
the json.dump() function, which serializes the Python dictionary into a
JSON formatted string.
Practical Examples and Exercises
Example 1: Converting CSV to JSON
Task: Write a program to read data from a CSV file and write it to a JSON
file.
Code:
import csv
import json
# Reading CSV file
csv_file = "example.csv"
json_file = "example.json"
data = []
with open(csv_file, "r") as file:
reader = csv.DictReader(file)
for row in reader:
data.append(row)
# Writing to JSON file
with open(json_file, "w") as file:
json.dump(data, file, indent=4)
Explanation: This example demonstrates how to read data from a CSV file
using csv.DictReader() and write it to a JSON file using json.dump().
Exercise 1: Logging Data in JSON Format
Task: Write a program to log user activity (e.g., login, logout) in a JSON
file. Each log entry should include a timestamp and an activity description.
Solution:
import json
from datetime import datetime
# Log data
log_entry = {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"activity": "User logged in"
}
# Writing to JSON file
log_file = "activity_log.json"
try:
with open(log_file, "r") as file:
logs = json.load(file)
except FileNotFoundError:
logs = []
logs.append(log_entry)
with open(log_file, "w") as file:
json.dump(logs, file, indent=4)
# Reading and printing the log file
with open(log_file, "r") as file:
logs = json.load(file)
print(json.dumps(logs, indent=4))
Example:
with open("example.txt", "r") as file:
content = file.read()
print(content)
Explanation: In this example, the with statement opens the file example.txt
in read mode and assigns the file object to the variable file. The file is
automatically closed when the block inside the with statement is exited.
Advantages of Using the with Statement
Automatic Resource Management: The with statement ensures
that resources are automatically released when the block is exited, which is
particularly useful for file operations.
Cleaner Code: The with statement simplifies code by reducing the
need for explicit resource cleanup.
Exception Handling: Resources are properly released even if an
exception occurs within the with block.
Using the with Statement for File Handling
Reading a File
Example:
with open("example.txt", "r") as file:
content = file.read()
print(content)
Explanation: This example shows how to write to a file using the with
statement. The file is opened in write mode, and the string "Hello, World!"
is written to it. The file is automatically closed when the block is exited.
Appending to a File
Example:
with open("example.txt", "a") as file:
file.write("\nThis is an appended line.")
Explanation: This example demonstrates how to read each line from a file
and print it after stripping any leading or trailing whitespace.
Example 2: Writing User Input to a File
Task: Prompt the user for their name and write it to a file.
Code:
user_name = input("Enter your name: ")
with open("user_data.txt", "w") as file:
file.write(f"Name: {user_name}\n")
Explanation: This example shows how to prompt the user for their name
and write it to a file using the with statement.
Example 3: Copying Content from One File to Another
Task: Copy the content of one file to another file.
Code:
with open("source.txt", "r") as src, open("destination.txt", "w") as dest:
dest.write(src.read())
Error Message:
File "example.py", line 2
if x > 10
^
SyntaxError: invalid syntax
Explanation: The error message indicates a syntax error due to the missing
colon after the if statement.
Runtime Errors
Definition: Runtime errors, also known as exceptions, occur during
the execution of a program. These errors are detected by the Python
interpreter while the code is running, and they cause the program to
terminate abruptly unless they are handled.
Characteristics:
Detected at Runtime: Runtime errors are only detected when the
program is executed.
Error Messages: The interpreter provides an error message that
includes the type of error, the line number where the error occurred, and a
traceback that helps identify the source of the error.
Common Causes: Division by zero, accessing a non-existent
variable, type errors, and file not found errors.
Example:
# Division by zero error
result = 10 / 0
Error Message:
Traceback (most recent call last):
File "example.py", line 2, in <module>
result = 10 / 0
ZeroDivisionError: division by zero
Error Message:
File "example.py", line 1
def greet(name)
^
SyntaxError: invalid syntax
Corrected Code:
def greet(name):
print("Hello, " + name)
greet("Alice")
Error Message:
Traceback (most recent call last):
File "example.py", line 2, in <module>
print(numbers[5])
IndexError: list index out of range
Solution:
for i in range(5):
print(i)
Explanation: This exercise helps you practice identifying and fixing syntax
errors by adding the missing colon after the for loop.
Exercise 2: Handling Runtime Errors
Task: Write a program that handles a runtime error when attempting to
open a non-existent file.
Solution:
try:
with open("non_existent_file.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("The file was not found.")
Error Message:
File "example.py", line 1
if x > 10
^
SyntaxError: invalid syntax
Solution: Ensure all syntax rules are followed, such as adding colons and
matching parentheses.
Runtime Errors
2. NameError
Description: A NameError occurs when a variable or function
name is not found in the local or global scope.
Common Causes:
Using a variable before it is defined.
Misspelling a variable or function name.
Forgetting to import a module.
Example:
print(x)
Error Message:
NameError: name 'x' is not defined
Solution: Ensure that all variables and functions are defined before use and
that names are spelled correctly.
3. TypeError
Description: A TypeError occurs when an operation or function is
applied to an object of inappropriate type.
Common Causes:
Performing operations on incompatible types (e.g., adding a string
and an integer).
Passing the wrong type of arguments to a function.
Example:
result = "hello" + 5
Error Message:
TypeError: can only concatenate str (not "int") to str
Error Message:
IndexError: list index out of range
Solution: Ensure that the index is within the valid range for the sequence.
5. KeyError
Description: A KeyError occurs when attempting to access a
dictionary key that does not exist.
Common Causes:
Accessing a key that is not present in the dictionary.
Misspelling a key name.
Example:
ages = {"Alice": 25, "Bob": 30}
print(ages["Charlie"])
Error Message:
KeyError: 'Charlie'
Solution: Ensure that the key exists in the dictionary before accessing it.
6. AttributeError
Description: An AttributeError occurs when an attribute reference
or assignment fails.
Common Causes:
Trying to access or assign an attribute that does not exist for an
object.
Misspelling an attribute name.
Example:
class Person:
def __init__(self, name):
self.name = name
p = Person("Alice")
print(p.age)
Error Message:
AttributeError: 'Person' object has no attribute 'age'
Solution: Ensure that the attribute exists for the object and that attribute
names are spelled correctly.
7. ValueError
Description: A ValueError occurs when a function receives an
argument of the correct type but inappropriate value.
Common Causes:
Passing an argument that is not expected by the function.
Using a value that is out of the expected range.
Example:
number = int("hello")
Error Message:
ValueError: invalid literal for int() with base 10: 'hello'
Solution: Ensure that the values passed to functions are appropriate and
within the expected range.
8. ZeroDivisionError
Description: A ZeroDivisionError occurs when attempting to
divide a number by zero.
Common Causes:
Performing division or modulo operation with zero as the divisor.
Example:
result = 10 / 0
Error Message:
ZeroDivisionError: division by zero
Solution: Ensure that the divisor is not zero before performing division or
modulo operations.
Practical Examples and Exercises
Example 1: Handling Multiple Common Errors
Task: Write a program that handles various common errors using try-
except blocks.
Code:
try:
x = int(input("Enter a number: "))
print("10 divided by your number is:", 10 / x)
numbers = [1, 2, 3]
print("The fourth number is:", numbers[3])
ages = {"Alice": 25, "Bob": 30}
print("Charlie's age is:", ages["Charlie"])
except ValueError:
print("Please enter a valid number.")
except ZeroDivisionError:
print("Cannot divide by zero.")
except IndexError:
print("Index out of range.")
except KeyError:
print("Key not found in dictionary.")
Solution:
numbers = [1, 2, 3]
try:
print(numbers[3])
except IndexError:
print("Index out of range. Use a valid index.")
person = {"name": "Alice", "age": 25}
try:
print(person["height"])
except KeyError:
print("Key not found in dictionary. Use a valid key.")
try:
result = "10" + str(10)
print(result)
except TypeError:
print("Cannot concatenate string and integer. Convert integer to string.")
Example:
try:
result = 10 / 0
print(result)
except ZeroDivisionError:
print("Cannot divide by zero.")
Example:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
Example:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
except ValueError:
print("Invalid value.")
Example:
try:
file = open("example.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("The file was not found.")
finally:
file.close()
print("File closed.")
Explanation: This example shows how to use try, except, and finally
blocks to handle file operations and ensure proper cleanup.
Example 2: Handling Multiple Exceptions
Task: Write a program that performs division and handles both
ZeroDivisionError and ValueError.
Code:
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
print(f"The result is: {result}")
except ZeroDivisionError:
print("Cannot divide by zero.")
except ValueError:
print("Invalid input. Please enter numeric values.")
finally:
print("Operation complete.")
Explanation: This exercise shows how to use try, except, and finally
blocks to handle missing keys in a dictionary.
Exercise 2: Ensuring Resource Cleanup
Task: Write a program that opens a file for writing, writes some data, and
ensures the file is closed properly, even if an error occurs during writing.
Solution:
try:
file = open("output.txt", "w")
file.write("Hello, World!")
print("Data written successfully.")
except IOError as e:
print(f"An I/O error occurred: {e}")
finally:
file.close()
print("File closed.")
Example:
def check_positive(number):
if number < 0:
raise ValueError("The number must be positive.")
return number
try:
check_positive(-5)
except ValueError as e:
print(e)
Example:
class NegativeNumberError(Exception):
def __init__(self, message):
self.message = message
def check_positive(number):
if number < 0:
raise NegativeNumberError("The number must be positive.")
return number
try:
check_positive(-5)
except NegativeNumberError as e:
print(e)
Example:
class NegativeNumberError(Exception):
def __init__(self, message="Negative numbers are not allowed"):
self.message = message
super().__init__(self.message)
def check_positive(number):
if number < 0:
raise NegativeNumberError
return number
try:
check_positive(-5)
except NegativeNumberError as e:
print(e)
Explanation: In this example, Dog and Cat classes inherit from the Animal
class. They override the speak method to provide specific implementations
for dogs and cats.
4. Polymorphism
Polymorphism allows methods to do different things based on the
object it is acting upon, even though they share the same name. It is often
used to process objects differently based on their class.
Example:
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
# Function that demonstrates polymorphism
def make_animal_speak(animal):
print(animal.speak())
# Using polymorphism
animals = [Dog(), Cat()]
for animal in animals:
make_animal_speak(animal)
Explanation: In this example, Dog and Cat classes inherit from the Animal
class. They override the speak method to provide specific implementations.
4. Polymorphism
Definition: Polymorphism allows objects of different classes to be
treated as objects of a common superclass. It enables a single interface to be
used for different underlying forms (data types).
Key Concepts:
Method Overriding: Providing a specific implementation in a
subclass that already exists in the superclass.
Dynamic Method Binding: The method that is executed is
determined at runtime based on the object type.
Example:
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
# Function that demonstrates polymorphism
def make_animal_speak(animal):
print(animal.speak())
# Usage
animals = [Dog(), Cat()]
for animal in animals:
make_animal_speak(animal)
Example:
class Dog:
pass
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
# Creating an object of the Dog class
my_dog = Dog("Rex", "Golden Retriever")
print(my_dog.name) # Output: Rex
print(my_dog.breed) # Output: Golden Retriever
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(f"{self.name} says woof!")
# Creating an object of the Dog class
my_dog = Dog("Rex", "Golden Retriever")
my_dog.bark() # Output: Rex says woof!
Explanation: This example defines a bark method in the Dog class. The
method prints a message including the dog's name. The bark method is
called on the my_dog object, resulting in the output.
Class and Instance Attributes
Class Attributes: Attributes that are shared among all instances of a
class. They are defined outside the __init__ method.
Instance Attributes: Attributes that are unique to each instance of a
class. They are defined within the __init__ method.
Example:
class Dog:
species = "Canis familiaris" # Class attribute
def __init__(self, name, breed):
self.name = name # Instance attribute
self.breed = breed # Instance attribute
# Creating objects of the Dog class
dog1 = Dog("Rex", "Golden Retriever")
dog2 = Dog("Buddy", "Labrador Retriever")
print(dog1.species) # Output: Canis familiaris
print(dog2.species) # Output: Canis familiaris
print(dog1.name) # Output: Rex
print(dog2.name) # Output: Buddy
Explanation: This exercise helps you practice defining a Student class with
attributes and a method to display the student's information.
Exercise 2: Book Class
Task: Define a Book class with attributes title, author, and pages, and a
method to display the book's information.
Solution:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def display_info(self):
print(f"Book: {self.title} by {self.author}, Pages: {self.pages}")
# Creating an object of the Book class
book = Book("The Great Gatsby", "F. Scott Fitzgerald", 180)
book.display_info() # Output: Book: The Great Gatsby by F. Scott Fitzgerald, Pages: 180
Explanation: This exercise helps you practice defining a Book class with
attributes and a method to display the book's information.
8.2.2 THE __INIT__ METHOD
The __init__ method, commonly known as the constructor, is a
special method in Python classes. It is automatically called when an object
of the class is instantiated. The primary purpose of the __init__ method is
to initialize the attributes of the class.
Syntax and Usage
Syntax:
class ClassName:
def __init__(self, parameters):
# Initialize attributes
self.attribute = value
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
# Creating an object of the Dog class
my_dog = Dog("Rex", "Golden Retriever")
print(my_dog.name) # Output: Rex
print(my_dog.breed) # Output: Golden Retriever
Explanation: In this example, the Dog class has an __init__ method that
initializes the name and breed attributes. When a Dog object is created,
these attributes are set based on the provided arguments.
Detailed Breakdown
1. The self Parameter
The self parameter is a reference to the current instance of the class.
It is used to access variables that belong to the class. It must be the first
parameter of any function in the class.
Example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hello, my name is {self.name} and I am {self.age} years old.")
# Creating an object of the Person class
person = Person("Alice", 30)
person.greet() # Output: Hello, my name is Alice and I am 30 years old.
Explanation: The self parameter allows the __init__ method and other
methods to access and modify the attributes of the instance.
2. Initializing Attributes
The __init__ method is used to initialize an object's state by
assigning values to the attributes. This ensures that each instance of the
class starts with a specific set of data.
Example:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
# Creating an object of the Car class
my_car = Car("Toyota", "Corolla", 2020)
print(my_car.make) # Output: Toyota
print(my_car.model) # Output: Corolla
print(my_car.year) # Output: 2020
Explanation: In this example, the Car class initializes the make, model,
and year attributes using the values passed to the __init__ method during
object creation.
3. Default Values
The __init__ method can also provide default values for attributes,
making some parameters optional during object instantiation.
Example:
class BankAccount:
def __init__(self, account_number, balance=0):
self.account_number = account_number
self.balance = balance
# Creating an object of the BankAccount class
account1 = BankAccount("12345678")
account2 = BankAccount("87654321", 500)
print(account1.balance) # Output: 0
print(account2.balance) # Output: 500
Explanation: This example defines a Book class and uses the __init__
method to initialize its attributes. The display_info method prints the book's
details.
Example 2: Employee Class
Task: Define an Employee class with attributes name, position, and salary,
and ensure they are initialized using the __init__ method.
Code:
class Employee:
def __init__(self, name, position, salary):
self.name = name
self.position = position
self.salary = salary
def display_info(self):
print(f"Employee: {self.name}, Position: {self.position}, Salary: ${self.salary}")
# Creating an object of the Employee class
employee = Employee("John Doe", "Software Engineer", 75000)
employee.display_info() # Output: Employee: John Doe, Position: Software Engineer, Salary:
$75000
Explanation: This exercise helps you practice defining a Product class with
attributes and a method to display the product's information.
Exercise 2: Course Class
Task: Define a Course class with attributes course_name, instructor, and
credits, and ensure they are initialized using the __init__ method.
Solution:
class Course:
def __init__(self, course_name, instructor, credits):
self.course_name = course_name
self.instructor = instructor
self.credits = credits
def display_info(self):
print(f"Course: {self.course_name}, Instructor: {self.instructor}, Credits: {self.credits}")
# Creating an object of the Course class
course = Course("Data Structures", "Dr. Smith", 3)
course.display_info() # Output: Course: Data Structures, Instructor: Dr. Smith, Credits: 3
Explanation: This exercise helps you practice defining a Course class with
attributes and a method to display the course's information.
8.2.3 INSTANCE VARIABLES AND
METHODS
Instance variables and methods are fundamental concepts in Object-
Oriented Programming (OOP) that help define the properties and behaviors
of objects created from a class. This section explains what instance
variables and methods are, how to define them, and provides practical
examples to illustrate their usage.
Instance Variables
Definition: Instance variables are variables that are defined within a
class but outside any method. They are initialized through the __init__
method and are unique to each instance of the class. Instance variables hold
data that is specific to each object.
Syntax:
class ClassName:
def __init__(self, parameter1, parameter2):
self.instance_variable1 = parameter1
self.instance_variable2 = parameter2
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
# Creating objects of the Dog class
dog1 = Dog("Rex", "Golden Retriever")
dog2 = Dog("Buddy", "Labrador Retriever")
print(dog1.name) # Output: Rex
print(dog2.breed) # Output: Labrador Retriever
Explanation: In this example, name and breed are instance variables that
are initialized through the __init__ method. Each Dog object has its own
name and breed.
Instance Methods
Definition: Instance methods are functions defined within a class that
operate on instance variables. They are used to perform actions or
computations using the data stored in instance variables. Instance methods
must have self as their first parameter to access the instance variables and
other methods of the class.
Syntax:
class ClassName:
def __init__(self, parameter1, parameter2):
self.instance_variable1 = parameter1
self.instance_variable2 = parameter2
def instance_method(self):
# Perform actions using instance variables
pass
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(f"{self.name} says woof!")
# Creating an object of the Dog class
my_dog = Dog("Rex", "Golden Retriever")
my_dog.bark() # Output: Rex says woof!
Explanation: This exercise helps you practice defining a Product class with
instance variables and methods to display the product's information and
update the quantity.
Exercise 2: Course Class
Task: Define a Course class with instance variables course_name,
instructor, and credits, and methods to display the course's information and
update the credits.
Solution:
class Course:
def __init__(self, course_name, instructor, credits):
self.course_name = course_name
self.instructor = instructor
self.credits = credits
def display_info(self):
print(f"Course: {self.course_name}, Instructor: {self.instructor}, Credits: {self.credits}")
def update_credits(self, new_credits):
self.credits = new_credits
print(f"{self.course_name}'s new credits are {self.credits}.")
# Creating an object of the Course class
course = Course("Data Structures", "Dr. Smith", 3)
course.display_info() # Output: Course: Data Structures, Instructor: Dr. Smith, Credits: 3
course.update_credits(4)
course.display_info() # Output: Course: Data Structures, Instructor: Dr. Smith, Credits: 4
Explanation: This exercise helps you practice defining a Course class with
instance variables and methods to display the course's information and
update the credits.
8.2.4 PRACTICAL EXAMPLES AND
EXERCISES
In this section, we will provide practical examples and exercises to
help reinforce the concepts of creating classes, defining instance variables,
and methods in Object-Oriented Programming (OOP). These exercises will
help you apply what you've learned in real-world scenarios and build a solid
understanding of class structures in Python.
Practical Examples
Example 1: Library Book Management System
Task: Create a Book class to manage library books with attributes like title,
author, and status. Include methods to check out, return, and display book
information.
Code:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.status = "Available"
def check_out(self):
if self.status == "Available":
self.status = "Checked Out"
print(f"{self.title} has been checked out.")
else:
print(f"{self.title} is already checked out.")
def return_book(self):
if self.status == "Checked Out":
self.status = "Available"
print(f"{self.title} has been returned.")
else:
print(f"{self.title} is already available.")
def display_info(self):
print(f"Title: {self.title}, Author: {self.author}, Status: {self.status}")
# Creating and using the Book class
book1 = Book("1984", "George Orwell")
book1.display_info() # Output: Title: 1984, Author: George Orwell, Status: Available
book1.check_out() # Output: 1984 has been checked out.
book1.display_info() # Output: Title: 1984, Author: George Orwell, Status: Checked Out
book1.return_book() # Output: 1984 has been returned.
book1.display_info() # Output: Title: 1984, Author: George Orwell, Status: Available
Explanation: This exercise helps you practice defining a Song class with
methods to play, stop, and display song information.
Exercise 2: Contact Management
Task: Define a Contact class with attributes name, email, and
phone_number. Create methods to update contact information and display
contact details.
Solution:
class Contact:
def __init__(self, name, email, phone_number):
self.name = name
self.email = email
self.phone_number = phone_number
def update_email(self, new_email):
self.email = new_email
print(f"Updated email to {self.email}")
def update_phone_number(self, new_phone_number):
self.phone_number = new_phone_number
print(f"Updated phone number to {self.phone_number}")
def display_contact(self):
print(f"Name: {self.name}, Email: {self.email}, Phone Number: {self.phone_number}")
# Creating and using the Contact class
contact = Contact("Alice", "[email protected]", "123-456-7890")
contact.display_contact() # Output: Name: Alice, Email: [email protected], Phone Number: 123-
456-7890
contact.update_email("[email protected]") # Output: Updated email to
[email protected]
contact.update_phone_number("098-765-4321") # Output: Updated phone number to 098-765-4321
contact.display_contact() # Output: Name: Alice, Email: [email protected], Phone Number:
098-765-4321
Explanation: This exercise helps you practice defining a Contact class with
methods to update and display contact information.
8.3 INHERITANCE AND
POLYMORPHISM
8.3.1 INHERITANCE
Inheritance is a fundamental concept in Object-Oriented
Programming (OOP) that allows one class to inherit attributes and methods
from another class. This mechanism promotes code reuse and establishes a
hierarchical relationship between classes, making it easier to create and
maintain complex systems.
What is Inheritance?
Definition: Inheritance is the process by which a class (known as
the child or subclass) derives properties and behaviors (attributes and
methods) from another class (known as the parent or superclass). The
subclass inherits all the members of the superclass and can also have its
own additional attributes and methods.
Syntax:
class ParentClass:
# Parent class attributes and methods
pass
class ChildClass(ParentClass):
# Child class attributes and methods
pass
Example:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")
class Dog(Animal):
def speak(self):
return f"{self.name} says woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says meow!"
# Creating objects of the subclasses
dog = Dog("Rex")
cat = Cat("Whiskers")
print(dog.speak()) # Output: Rex says woof!
print(cat.speak()) # Output: Whiskers says meow!
Explanation: In this example, the Dog and Cat classes inherit from the
Animal class. They override the speak method to provide specific
implementations.
Types of Inheritance
Single Inheritance: A subclass inherits from a single superclass.
class Parent:
pass
class Child(Parent):
pass
Method Overriding
Method overriding occurs when a subclass provides a specific
implementation of a method that is already defined in its superclass. This
allows the subclass to modify or extend the behavior of the superclass
method.
Example:
class Vehicle:
def move(self):
print("The vehicle is moving")
class Car(Vehicle):
def move(self):
print("The car is driving")
# Creating objects of the classes
vehicle = Vehicle()
car = Car()
vehicle.move() # Output: The vehicle is moving
car.move() # Output: The car is driving
Explanation: In this example, the Car class overrides the move method of
the Vehicle class to provide a specific implementation for cars.
Practical Examples and Exercises
Example 1: Employee Management System
Task: Create a class hierarchy to manage different types of employees with
attributes like name and salary.
Code:
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def display_info(self):
print(f"Employee: {self.name}, Salary: ${self.salary}")
class Manager(Employee):
def __init__(self, name, salary, department):
super().__init__(name, salary)
self.department = department
def display_info(self):
super().display_info()
print(f"Department: {self.department}")
class Developer(Employee):
def __init__(self, name, salary, programming_language):
super().__init__(name, salary)
self.programming_language = programming_language
def display_info(self):
super().display_info()
print(f"Programming Language: {self.programming_language}")
# Creating objects of the subclasses
manager = Manager("Alice", 90000, "HR")
developer = Developer("Bob", 80000, "Python")
manager.display_info()
# Output:
# Employee: Alice, Salary: $90000
# Department: HR
developer.display_info()
# Output:
# Employee: Bob, Salary: $80000
# Programming Language: Python
Explanation: This exercise helps you practice defining a base class Person
and creating subclasses Teacher and Student with additional attributes and
methods.
Exercise 2: Animal Hierarchy
Task: Define an Animal class with attributes name and species. Create
subclasses Bird and Fish that inherit from Animal and add specific
attributes.
Solution:
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def display_info(self):
print(f"Name: {self.name}, Species: {self.species}")
class Bird(Animal):
def __init__(self, name, species, can_fly):
super().__init__(name, species)
self.can_fly = can_fly
def display_info(self):
super().display_info()
print(f"Can Fly: {self.can_fly}")
class Fish(Animal):
def __init__(self, name, species, water_type):
super().__init__(name, species)
self.water_type = water_type
def display_info(self):
super().display_info()
print(f"Water Type: {self.water_type}")
# Creating objects of the subclasses
bird = Bird("Parrot", "Aves", True)
fish = Fish("Goldfish", "Carassius", "Freshwater")
bird.display_info()
# Output:
# Name: Parrot, Species: Aves
# Can Fly: True
fish.display_info()
# Output:
# Name: Goldfish, Species: Carassius
# Water Type: Freshwater
Explanation: This exercise helps you practice defining a base class Animal
and creating subclasses Bird and Fish with additional attributes and
methods.
8.3.2 METHOD OVERRIDING
Method overriding is an essential concept in Object-Oriented
Programming (OOP) that allows a subclass to provide a specific
implementation of a method that is already defined in its superclass. This
mechanism enables the subclass to modify or extend the behavior of the
method inherited from the superclass, promoting flexibility and reuse in the
code.
What is Method Overriding?
Definition: Method overriding occurs when a subclass provides a
specific implementation for a method that is already defined in its
superclass. The method in the subclass should have the same name, return
type, and parameters as the method in the superclass.
Key Points:
The method in the subclass must have the same signature (name and
parameters) as in the superclass.
Method overriding allows a subclass to customize or completely
replace the behavior of the superclass method.
It is used to achieve runtime polymorphism.
Syntax and Usage
Syntax:
class Superclass:
def method(self):
# Superclass method implementation
pass
class Subclass(Superclass):
def method(self):
# Subclass method implementation (overrides the superclass method)
pass
Example:
class Animal:
def speak(self):
return "The animal makes a sound"
class Dog(Animal):
def speak(self):
return "The dog barks"
class Cat(Animal):
def speak(self):
return "The cat meows"
# Creating objects of the subclasses
dog = Dog()
cat = Cat()
print(dog.speak()) # Output: The dog barks
print(cat.speak()) # Output: The cat meows
Explanation: In this example, the Dog and Cat classes override the speak
method of the Animal class. Each subclass provides its specific
implementation of the speak method.
Practical Examples and Exercises
Example 1: Shape Hierarchy
Task: Create a class hierarchy for different shapes. Define a Shape class
with a method area and override this method in subclasses Circle and
Rectangle.
Code:
import math
class Shape:
def area(self):
raise NotImplementedError("Subclass must implement abstract method")
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# Creating objects of the subclasses
circle = Circle(5)
rectangle = Rectangle(4, 6)
print(f"Circle area: {circle.area()}") # Output: Circle area: 78.53981633974483
print(f"Rectangle area: {rectangle.area()}") # Output: Rectangle area: 24
Explanation: This exercise helps you practice defining a Vehicle class and
creating subclasses Car and Truck that override the fuel_efficiency method
to provide specific fuel efficiency values.
Exercise 2: Account Management
Task: Define an Account class with a method calculate_interest. Create
subclasses SavingsAccount and CheckingAccount that override the
calculate_interest method.
Solution:
class Account:
def __init__(self, balance):
self.balance = balance
def calculate_interest(self):
raise NotImplementedError("Subclass must implement abstract method")
class SavingsAccount(Account):
def calculate_interest(self):
return self.balance * 0.04 # 4% interest
class CheckingAccount(Account):
def calculate_interest(self):
return self.balance * 0.01 # 1% interest
# Creating objects of the subclasses
savings = SavingsAccount(1000)
checking = CheckingAccount(1000)
print(f"Savings account interest: ${savings.calculate_interest()}") # Output: Savings account
interest: $40.0
print(f"Checking account interest: ${checking.calculate_interest()}") # Output: Checking account
interest: $10.0
Explanation: This exercise helps you practice defining a Vehicle class and
creating subclasses Car and Bicycle that override the move method to
provide specific implementations.
Exercise 2: Account Management
Task: Define an Account class with a method calculate_interest. Create
subclasses SavingsAccount and CheckingAccount that override the
calculate_interest method.
Solution:
class Account:
def calculate_interest(self):
raise NotImplementedError("Subclass must implement abstract method")
class SavingsAccount(Account):
def calculate_interest(self):
return "Calculating interest for Savings Account"
class CheckingAccount(Account):
def calculate_interest(self):
return "Calculating interest for Checking Account"
# Function that demonstrates polymorphism
def account_interest(account):
print(account.calculate_interest())
# Creating a list of different accounts
accounts = [SavingsAccount(), CheckingAccount()]
for account in accounts:
account_interest(account)
Explanation: This exercise helps you practice defining a base class Animal
and creating subclasses Dog and Cat that override the make_sound method
to provide specific sounds.
Exercise 2: Employee Task Management
Task: Define an Employee class with a method perform_task. Create
subclasses Manager and Developer that override the perform_task method.
Write a function to demonstrate polymorphism by making different
employees perform tasks.
Solution:
class Employee:
def perform_task(self):
raise NotImplementedError("Subclass must implement abstract method")
class Manager(Employee):
def perform_task(self):
return "Managing the team"
class Developer(Employee):
def perform_task(self):
return "Writing code"
# Function demonstrating polymorphism
def employee_task(employee):
print(employee.perform_task())
# Creating instances of employees
manager = Manager()
developer = Developer()
# Performing tasks
employee_task(manager)
employee_task(developer)
2. datetime Library
The datetime library supplies classes for manipulating dates and
times.
Commonly Used Classes and Methods:
datetime.date(year, month, day): Creates a date object.
datetime.time(hour, minute, second): Creates a time object.
datetime.datetime(year, month, day, hour, minute, second):
Creates a datetime object.
datetime.timedelta(days, seconds): Represents the difference
between two dates or times.
Example:
import datetime
today = datetime.date.today()
print(today) # Output: 2024-06-17 (example)
now = datetime.datetime.now()
print(now) # Output: 2024-06-17 12:45:30.123456 (example)
delta = datetime.timedelta(days=5)
print(today + delta) # Output: 2024-06-22 (example)
3. os Library
The os library provides a way of using operating system-dependent
functionality like reading or writing to the file system.
Commonly Used Functions:
os.listdir(path): Returns a list of entries in the directory given by
path.
os.getcwd(): Returns the current working directory.
os.mkdir(path): Creates a new directory at path.
os.remove(path): Removes the file at path.
Example:
import os
current_directory = os.getcwd()
print(current_directory)
files = os.listdir(current_directory)
print(files)
os.mkdir('new_folder')
print(os.listdir(current_directory))
os.rmdir('new_folder')
4. sys Library
The sys library provides access to some variables used or
maintained by the interpreter and to functions that interact strongly with the
interpreter.
Commonly Used Attributes and Methods:
sys.argv: A list of command-line arguments passed to the script.
sys.exit([arg]): Exits from Python.
sys.path: A list of strings that specifies the search path for modules.
Example:
import sys
print("Script name:", sys.argv[0])
print("Arguments:", sys.argv[1:])
sys.exit("Exiting the program")
5. json Library
The json library is used for parsing JSON (JavaScript Object
Notation), a popular data interchange format.
Commonly Used Functions:
json.loads(json_string): Parses a JSON string and returns a Python
dictionary.
json.dumps(dictionary): Serializes a Python dictionary into a
JSON string.
Example:
import json
data = '{"name": "John", "age": 30}'
parsed_data = json.loads(data)
print(parsed_data)
json_data = json.dumps(parsed_data)
print(json_data)
6. random Library
The random library is used to generate pseudo-random numbers for
various distributions.
Commonly Used Functions:
random.random(): Returns a random float number between 0.0 and
1.0.
random.randint(a, b): Returns a random integer between a and b
inclusive.
random.choice(seq): Returns a random element from the non-
empty sequence seq.
Example:
import random
print(random.random()) # Output: A random float between 0.0 and 1.0
print(random.randint(1, 10)) # Output: A random integer between 1 and 10
print(random.choice(['apple', 'banana', 'cherry'])) # Output: A random fruit
7. re Library
The re library is used for working with regular expressions, a
powerful tool for matching patterns in text.
Commonly Used Functions:
re.match(pattern, string): Determines if the regex pattern matches
at the beginning of the string.
re.search(pattern, string): Scans through the string, looking for
any location where the regex pattern matches.
re.findall(pattern, string): Finds all occurrences of the pattern in
the string.
Example:
import re
pattern = r'\b[a-zA-Z]{4}\b'
text = "This is a test sentence with some four letter words."
matches = re.findall(pattern, text)
print(matches) # Output: ['This', 'test', 'with', 'some', 'four', 'word']
8. collections Library
The collections library implements specialized container datatypes
providing alternatives to Python’s general-purpose built-in containers like
dict, list, set, and tuple.
Commonly Used Classes:
collections.Counter: A counter tool to count the occurrences of
elements.
collections.defaultdict: A dictionary that calls a factory function to
supply missing values.
collections.namedtuple: Factory function for creating tuple
subclasses with named fields.
Example:
from collections import Counter, defaultdict, namedtuple
# Counter
counter = Counter('hello world')
print(counter)
# defaultdict
def_dict = defaultdict(int)
def_dict['key'] += 1
print(def_dict)
# namedtuple
Point = namedtuple('Point', 'x y')
point = Point(1, 2)
print(point.x, point.y)
Exercises
Math Library Exercise:
Write a program that calculates the hypotenuse of a right-angled
triangle given the lengths of the other two sides.
Solution:
import math
def calculate_hypotenuse(a, b):
return math.sqrt(a**2 + b**2)
print(calculate_hypotenuse(3, 4)) # Output: 5.0
OS Library Exercise:
Write a program that creates a new directory, lists all files in the
current directory, and then removes the newly created directory.
Solution:
import os
os.mkdir('temp_folder')
print("Files in current directory:", os.listdir('.'))
os.rmdir('temp_folder')
9.1.2 PRACTICAL EXAMPLES AND
EXERCISES
This section provides practical examples and exercises to help you
apply the knowledge you've gained about the Python Standard Library. By
working through these examples and exercises, you'll get hands-on
experience with some of the most useful standard libraries in Python,
enhancing your understanding and skill set.
Practical Examples
Example 1: Math Library - Calculating Compound Interest
Description: Write a program that calculates the compound interest for a
given principal amount, annual interest rate, and the number of years.
Code:
import math
def calculate_compound_interest(principal, rate, years):
amount = principal * math.pow((1 + rate / 100), years)
return amount
principal = 1000
rate = 5
years = 10
amount = calculate_compound_interest(principal, rate, years)
print(f"The compound interest for {years} years is: ${amount:.2f}")
Example:
pip install numpy
Explanation: This command installs the numpy library, which is used for
numerical computations in Python.
Installing Specific Versions
Sometimes, you may need to install a specific version of a library.
You can do this by specifying the version number:
pip install requests==2.25.1
Explanation: This script installs the requests library and makes a GET
request to the GitHub API, printing the status code and JSON response.
Example 2: Creating and Using a requirements.txt File
Task: Create a requirements.txt file for a project and install the listed
libraries.
Solution:
Open your terminal or command prompt and navigate to your
project directory.
Run the following command to generate a requirements.txt file:
pip freeze > requirements.txt
Share the requirements.txt file with others or use it to set up the
same environment on a different machine:
pip install -r requirements.txt
Explanation: This exercise helps you practice installing the pandas library
and using it to read and display data from a CSV file.
Exercise 2: Upgrading a Library
Task: Upgrade the numpy library to the latest version.
Solution:
Open your terminal or command prompt and run:
pip install --upgrade numpy
Basic Usage:
import numpy as np
# Creating an array
array = np.array([1, 2, 3, 4])
print("Array:", array)
# Performing arithmetic operations
array = array * 2
print("Array multiplied by 2:", array)
# Creating a 2D array (matrix)
matrix = np.array([[1, 2], [3, 4]])
print("Matrix:\n", matrix)
# Matrix multiplication
result = np.dot(matrix, matrix)
print("Matrix multiplied by itself:\n", result)
2. pandas
Description: pandas is an essential library for data manipulation
and analysis. It provides data structures like Series (one-dimensional) and
DataFrame (two-dimensional) that are easy to use and powerful for
handling real-world data.
Installation:
pip install pandas
Basic Usage:
import pandas as pd
# Creating a DataFrame from a dictionary
data = {'Name': ['John', 'Anna', 'Peter', 'Linda'],
'Age': [28, 24, 35, 32]}
df = pd.DataFrame(data)
print("DataFrame:\n", df)
# Reading data from a CSV file
df = pd.read_csv('sample.csv')
print("DataFrame from CSV:\n", df.head())
# Data manipulation
df['Age'] = df['Age'] + 1
print("DataFrame with Age incremented:\n", df)
3. matplotlib
Description: matplotlib is a comprehensive library for creating
static, animated, and interactive visualizations in Python. It is widely used
for plotting graphs and charts.
Installation:
pip install matplotlib
Basic Usage:
import matplotlib.pyplot as plt
# Creating a simple plot
x = [1, 2, 3, 4]
y = [10, 20, 25, 30]
plt.plot(x, y)
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.title('Simple Plot')
plt.show()
# Creating a bar chart
categories = ['A', 'B', 'C']
values = [3, 7, 5]
plt.bar(categories, values)
plt.xlabel('Category')
plt.ylabel('Values')
plt.title('Bar Chart')
plt.show()
Explanation: This script shows how to create a simple line plot and a bar
chart using matplotlib.
Exercises
Exercise 1: Numerical Computations with numpy
Task: Use numpy to create an array, perform element-wise operations, and
compute the mean and standard deviation.
Solution:
Install numpy if not already installed:
pip install numpy
Explanation: This exercise helps you practice using pandas for data
manipulation tasks, including sorting and grouping data.
Exercise 3: Plotting with matplotlib
Task: Use matplotlib to create a scatter plot and a histogram.
Solution:
Install matplotlib if not already installed:
pip install matplotlib
Explanation: This exercise helps you practice reading data from a CSV
file, filtering rows, grouping data, and calculating aggregate statistics using
pandas.
Exercise 3: Data Visualization with matplotlib
Task: Create a scatter plot of random data points and a histogram of
normally distributed data.
Solution:
Install matplotlib if not already installed:
pip install matplotlib
Explanation: This exercise helps you practice creating scatter plots and
histograms using matplotlib.
CHAPTER 10: INTRODUCTION TO
WEB DEVELOPMENT WITH FLASK
10.1 WHAT IS FLASK?
Flask is a lightweight and flexible web framework for Python,
designed to make it easy to start developing web applications quickly and
with a minimal amount of code. Flask is known for its simplicity, ease of
use, and fine-grained control over components, making it a popular choice
for both beginners and experienced developers.
Key Features of Flask:
Lightweight and Modular: Flask is designed to be simple and easy
to extend. It does not include many of the features that are common in full-
fledged frameworks, such as a built-in ORM (Object-Relational Mapping)
or form handling.
Built-in Development Server and Debugger: Flask comes with a
built-in server and debugger that makes it easy to test your applications
during development.
Flexible and Extensible: Flask can be easily extended with various
plugins and extensions, such as Flask-SQLAlchemy for database
integration, Flask-WTF for form handling, and more.
RESTful Request Dispatching: Flask supports the creation of
RESTful APIs with easy-to-use routing and request handling.
10.1.1 SETTING UP FLASK
Before you can start developing web applications with Flask, you
need to set up your development environment. This involves installing
Flask and creating a basic application to verify the installation.
Step-by-Step Guide to Setting Up Flask
Step 1: Install Flask
To install Flask, you need to have Python and pip installed on your
system. If you don't have them installed, download and install the latest
version of Python from python.org.
Once you have Python and pip installed, you can install Flask using
the following command:
pip install Flask
Step 2: Create a Basic Flask Application
Create a new directory for your Flask application. Navigate to the
directory in your terminal or command prompt and create a new Python file
(e.g., app.py).
Add the following code to app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Hello, Flask!"
if __name__ == '__main__':
app.run(debug=True)
Explanation:
Import Flask: The Flask class is imported from the flask module.
Create an Instance of Flask: An instance of the Flask class is
created. The __name__ argument is passed to the Flask constructor to
determine the root path of the application.
Define Routes: The @app.route('/') decorator is used to bind the
URL / to the home function. When the URL / is accessed, the home
function is executed, and the string "Hello, Flask!" is returned as the
response.
Run the Application: The app.run(debug=True) method runs the
Flask application. The debug=True argument enables debug mode, which
provides useful error messages and automatically restarts the server when
code changes are detected.
Step 3: Run the Flask Application
Navigate to the directory containing app.py in your terminal or
command prompt and run the following command:
python app.py
Explanation:
static/: This directory will contain static files such as CSS,
JavaScript, and images.
templates/: This directory will contain HTML templates.
index.html: This is the main HTML template.
app.py: This is the main Python file for your Flask application.
Step 2: Creating HTML Templates
Add the following HTML code to index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Flask App</title>
</head>
<body>
<h1>Welcome to My First Flask App!</h1>
<p>This is a simple Flask application.</p>
</body>
</html>
Explanation: This HTML file serves as the template for the homepage of
your Flask application.
Step 3: Updating app.py
Modify the app.py file to use the new template:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
Explanation:
Import render_template: The render_template function is
imported from Flask to render HTML templates.
Use Template in Route: The home function now returns
render_template('index.html'), which renders the index.html template.
Step 4: Adding More Routes
Add more routes to your Flask application in app.py:
@app.route('/about')
def about():
return "<h1>About Page</h1><p>This is the about page.</p>"
@app.route('/contact')
def contact():
return "<h1>Contact Page</h1><p>This is the contact page.</p>"
Explanation:
About Route: The /about route returns a simple HTML string for
the about page.
Contact Route: The /contact route returns a simple HTML string
for the contact page.
10.1.3 UNDERSTANDING THE FLASK
APPLICATION STRUCTURE
Flask applications are organized in a way that promotes clean and
maintainable code. Here is an overview of the typical structure of a Flask
application:
my_flask_app/
├── static/
│ └── css/
│ └── js/
│ └── images/
├── templates/
│ └── base.html
│ └── index.html
├── app.py
├── config.py
├── requirements.txt
├── instance/
│ └── config.py
├── .env
Explanation:
static/: This directory contains static files such as CSS, JavaScript,
and images. These files are served directly by the web server.
templates/: This directory contains HTML templates. Flask uses
Jinja2 templating engine to render HTML templates.
app.py: This is the main Python file for your Flask application. It
contains the application instance and route definitions.
config.py: This file contains configuration settings for the Flask
application.
requirements.txt: This file lists all the dependencies of the project.
It can be generated using pip freeze > requirements.txt and installed using
pip install -r requirements.txt.
instance/: This directory can contain configuration files that should
not be committed to version control, such as instance-specific settings.
.env: This file contains environment variables, which can be loaded
using a package like python-dotenv.
Detailed Breakdown of Each Component
1. static/ Directory
The static directory is where you store static assets like CSS,
JavaScript, and images. These files are not processed by Flask but are
served directly to the client.
Example:
my_flask_app/
├── static/
│ └── css/
│ └── styles.css
│ └── js/
│ └── scripts.js
│ └── images/
│ └── logo.png
You can link to these static files in your HTML templates using the
url_for function:
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
2. templates/ Directory
The templates directory is where you store your HTML templates.
Flask uses the Jinja2 template engine to render these templates dynamically.
Example:
my_flask_app/
├── templates/
│ └── base.html
│ └── index.html
base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My First Flask App{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<header>
<h1>Welcome to My Flask App</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2024 My Flask App</p>
</footer>
</body>
</html>
index.html:
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<p>This is the home page.</p>
{% endblock %}
3. app.py
The app.py file is the entry point of your Flask application. It
contains the Flask application instance and route definitions.
Example:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
4. config.py
The config.py file is used to store configuration settings for your
Flask application.
Example:
class Config:
DEBUG = True
SECRET_KEY = 'supersecretkey'
5. requirements.txt
The requirements.txt file lists all the dependencies of your project.
You can generate this file using pip freeze > requirements.txt and install
the dependencies using pip install -r requirements.txt.
Example:
Flask==2.0.1
6. instance/ Directory
The instance directory is used to store configuration files that should
not be committed to version control, such as instance-specific settings.
Example:
my_flask_app/
├── instance/
│ └── config.py
instance/config.py:
SECRET_KEY = 'supersecretkey'
DATABASE_URI = 'sqlite:///instance/db.sqlite'
7. .env
The .env file is used to store environment variables, which can be
loaded using a package like python-dotenv.
Example:
FLASK_ENV=development
SECRET_KEY=supersecretkey
Create app.py:
from flask import Flask, render_template
app = Flask(__name__)
posts = [
{'id': 1, 'title': 'First Post', 'content': 'This is the content of the first post.'},
{'id': 2, 'title': 'Second Post', 'content': 'This is the content of the second post.'},
]
@app.route('/')
def home():
return render_template('home.html', posts=posts)
@app.route('/post/<int:post_id>')
def post(post_id):
post = next((post for post in posts if post['id'] == post_id), None)
return render_template('post.html', post=post)
if __name__ == '__main__':
app.run(debug=True)
Create app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/contact')
def contact():
return render_template('contact.html')
@app.route('/submit', methods=['POST'])
def submit():
name = request.form['name']
message = request.form['message']
return render_template('result.html', name=name, message=message)
if __name__ == '__main__':
app.run(debug=True)
Create app.py:
from flask import Flask, render_template
app = Flask(__name__)
profiles = [
{'username': 'johndoe', 'name': 'John Doe', 'bio': 'Software Developer from San Francisco.'},
{'username': 'janedoe', 'name': 'Jane Doe', 'bio': 'Data Scientist from New York.'},
]
@app.route('/')
def home():
return render_template('profiles.html', profiles=profiles)
@app.route('/profile/<username>')
def profile(username):
profile = next((profile for profile in profiles if profile['username'] == username), None)
return render_template('profile.html', profile=profile)
if __name__ == '__main__':
app.run(debug=True)
Explanation: This exercise helps you practice creating routes with dynamic
URLs. The /profile/<username> route accepts a username and displays the
corresponding user profile using a template.
Exercise 2: Static Files
Task: Create a Flask application that includes static files (CSS and
JavaScript). Use these static files to style the application and add
interactivity.
Solution:
Create the project structure:
my_flask_static/
├── static/
│ └── css/
│ └── styles.css
│ └── js/
│ └── scripts.js
├── templates/
│ └── base.html
│ └── index.html
└── app.py
Explanation: This exercise helps you practice adding and using static files
in a Flask application. The CSS file (styles.css) is used to style the
application, and the JavaScript file (scripts.js) is used to add interactivity.
10.2 ROUTING AND TEMPLATES
10.2.1 URL ROUTING
In Flask, URL routing is the mechanism that maps URL patterns to
corresponding view functions. This is a fundamental concept in web
development, as it allows you to define how your application responds to
different URLs. Each URL pattern is associated with a specific view
function that is executed when the pattern is matched.
Defining Routes
In Flask, routes are defined using the @app.route decorator. The
decorator binds a URL to a function, which is called whenever a request to
that URL is received.
Example:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Welcome to the Home Page!"
@app.route('/about')
def about():
return "This is the About Page!"
Explanation:
@app.route('/'): This decorator binds the URL / to the home
function. When a user visits the root URL, the home function is called, and
it returns the string "Welcome to the Home Page!".
@app.route('/about'): This decorator binds the URL /about to the
about function. When a user visits the /about URL, the about function is
called, and it returns the string "This is the About Page!".
URL Variables
Flask allows you to capture parts of the URL and pass them as
arguments to your view functions. This is done using URL variables.
Example:
@app.route('/user/<username>')
def show_user_profile(username):
return f"User: {username}"
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f"Post ID: {post_id}"
Explanation:
<username>: This part of the URL captures a string and passes it as
the username argument to the show_user_profile function.
<int:post_id>: This part of the URL captures an integer and passes
it as the post_id argument to the show_post function.
HTTP Methods
By default, Flask routes respond to GET requests. You can specify
which HTTP methods a route should respond to by using the methods
parameter in the @app.route decorator.
Example:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return "Handle POST request"
else:
return "Show login form"
Explanation:
methods=['GET', 'POST']: This specifies that the login route can
handle both GET and POST requests.
request.method: This checks the HTTP method of the request and
responds accordingly.
URL Building
Flask provides the url_for function, which generates URLs for your
application based on the name of the view function and any arguments
provided.
Example:
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/')
def home():
return 'Home Page'
@app.route('/login')
def login():
return 'Login Page'
with app.test_request_context():
print(url_for('home')) # Output: /
print(url_for('login')) # Output: /login
print(url_for('login', next='/')) # Output: /login?next=/
Explanation:
url_for('home'): Generates the URL for the home view function.
url_for('login', next='/'): Generates the URL for the login view
function and adds a query string with next=/.
Dynamic URL Building
Dynamic URL building is useful when you need to generate URLs
with variable parts, such as user profiles or blog posts.
Example:
@app.route('/user/<username>')
def user_profile(username):
return f"User: {username}"
with app.test_request_context():
print(url_for('user_profile', username='john')) # Output: /user/john
Explanation:
url_for('user_profile', username='john'): Generates the URL for
the user_profile view function with the username variable set to 'john'.
10.2.2 USING HTML TEMPLATES
In Flask, HTML templates are used to separate the presentation
layer from the business logic of your application. Flask uses the Jinja2
templating engine to render HTML templates dynamically. This allows you
to create reusable and maintainable HTML templates that can be populated
with dynamic data.
Setting Up Templates
To get started with HTML templates in Flask, you need to set up a
directory named templates in your project. This is where all your HTML
templates will be stored.
Example Project Structure:
my_flask_app/
├── static/
├── templates/
│ └── base.html
│ └── index.html
└── app.py
Explanation:
Blocks: {% block title %} and {% block content %} are
placeholders for content that will be provided by other templates that extend
this base template.
Static Files: {{ url_for('static', filename='css/styles.css') }}
generates the URL for a static CSS file.
Extending a Base Template
You can create specific templates that extend the base template.
These templates will fill in the placeholders defined in the base template.
Example: index.html
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<h2>Welcome to the Home Page</h2>
<p>This is the home page of the Flask app.</p>
{% endblock %}
Example: about.html
{% extends "base.html" %}
{% block title %}About{% endblock %}
{% block content %}
<h2>About Us</h2>
<p>This is the about page of the Flask app.</p>
{% endblock %}
Explanation:
{% extends "base.html" %}: Indicates that this template extends
the base template.
Blocks: Content for {% block title %} and {% block content %}
is provided in these templates.
Rendering Templates in Flask
To render these templates from your Flask application, you use the
render_template function.
Example: app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/about')
def about():
return render_template('about.html')
if __name__ == '__main__':
app.run(debug=True)
Explanation:
render_template('index.html'): Renders the index.html template.
render_template('about.html'): Renders the about.html template.
Using Template Variables
You can pass data to templates using template variables. This allows
you to dynamically populate the template with data.
Example: Passing Variables
@app.route('/')
def home():
name = "John"
return render_template('index.html', name=name)
Explanation:
render_template('index.html', name=name): Passes the variable
name to the template.
{{ name }}: Inserts the value of the name variable into the HTML.
Template Control Structures
Jinja2 provides control structures for adding logic to your templates,
such as loops and conditionals.
Example: Using a Loop
@app.route('/')
def home():
items = ['Item 1', 'Item 2', 'Item 3']
return render_template('index.html', items=items)
Explanation:
Loop: {% for item in items %} iterates over the items list and
renders each item.
Conditional: {% if items %} checks if the items list is not empty.
10.2.3 PRACTICAL EXAMPLES AND
EXERCISES
This section provides practical examples and exercises to help you
solidify your understanding of Flask’s routing and templating features.
These exercises will guide you through creating dynamic and interactive
web applications.
Practical Examples
Example 1: Task Manager Application
Task: Create a task manager application where users can view a list of
tasks, add new tasks, and mark tasks as completed.
Solution:
Create the project structure:
task_manager/
├── static/
├── templates/
│ └── base.html
│ └── home.html
│ └── add_task.html
└── app.py
Create app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
tasks = []
@app.route('/')
def home():
return render_template('home.html', tasks=tasks)
@app.route('/add', methods=['GET', 'POST'])
def add_task():
if request.method == 'POST':
task_name = request.form['name']
tasks.append({'id': len(tasks) + 1, 'name': task_name, 'completed': False})
return redirect(url_for('home'))
return render_template('add_task.html')
@app.route('/complete/<int:task_id>')
def complete_task(task_id):
task = next((task for task in tasks if task['id'] == task_id), None)
if task:
task['completed'] = True
return redirect(url_for('home'))
if __name__ == '__main__':
app.run(debug=True)
Create app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
students = []
@app.route('/')
def home():
return render_template('home.html', students=students)
@app.route('/add', methods=['GET', 'POST'])
def add_student():
if request.method == 'POST':
student_name = request.form['name']
students.append({'id': len(students) + 1, 'name': student_name})
return redirect(url_for('home'))
return render_template('add_student.html')
@app.route('/student/<int:student_id>')
def student_details(student_id):
student = next((student for student in students if student['id'] == student_id), None)
return render_template('student_details.html', student=student)
if __name__ == '__main__':
app.run(debug=True)
Explanation: This exercise helps you practice creating a student enrollment
system with Flask. It includes routes for viewing students, adding students,
and viewing individual student details, and uses templates to render the
HTML.
Exercise 2: Simple Blogging Platform
Task: Create a simple blogging platform where users can view a list of blog
posts, add new blog posts, and view the details of individual posts.
Solution:
Create the project structure:
simple_blog/
├── static/
├── templates/
│ └── base.html
│ └── home.html
│ └── add_post.html
│ └── post_details.html
└── app.py
Create app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
posts = []
@app.route('/')
def home():
return render_template('home.html', posts=posts)
@app.route('/add', methods=['GET', 'POST'])
def add_post():
if request.method == 'POST':
post_title = request.form['title']
post_content = request.form['content']
posts.append({'id': len(posts) + 1, 'title': post_title, 'content': post_content})
return redirect(url_for('home'))
return render_template('add_post.html')
@app.route('/post/<int:post_id>')
def post_details(post_id):
post = next((post for post in posts if post['id'] == post_id), None)
return render_template('post_details.html', post=post)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Form</title>
</head>
<body>
<h2>Contact Us</h2>
<form method="post" action="/submit">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
Explanation:
Route /contact: Renders the contact form.
Route /submit: Handles the form submission. The methods=
['POST'] parameter specifies that this route should handle POST requests.
request.form: Accesses the form data submitted by the user.
Validating Form Data
Form validation ensures that the data submitted by the user is
correct and complete. Flask provides several ways to validate form data.
One common approach is to use Flask-WTF, which integrates Flask with
the WTForms library for form validation.
Example: Using Flask-WTF for Form Validation
Install Flask-WTF:
pip install Flask-WTF
Explanation:
Flask-WTF: Integrates Flask with WTForms for form validation.
ContactForm: Defines the form fields and their validators.
CSRF Protection: Flask-WTF provides CSRF protection out of the
box.
form.validate_on_submit(): Checks if the form is submitted and
valid.
10.3.2 SENDING AND RECEIVING DATA
Flask makes it straightforward to handle data sent to and received
from the server. This includes processing data from forms, handling JSON
data, and responding with JSON data. Understanding these concepts is
crucial for creating interactive web applications that can communicate
effectively with clients.
Sending Data
To send data from the client to the server, you typically use HTML
forms or JavaScript (via AJAX requests). Here’s how you can handle these
in Flask:
HTML Forms
HTML forms are a common way to send data to the server. When a
form is submitted, the data is sent to the server as part of the HTTP request.
Example: Contact Form
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Form</title>
</head>
<body>
<h2>Contact Us</h2>
<form method="post" action="/submit">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
Explanation:
request.form: Accesses the form data submitted by the user.
Receiving Data
You can also receive data from the server in various formats, such as
HTML, JSON, or XML. Here’s how you can respond with different types
of data in Flask:
Responding with HTML
When you use render_template, Flask responds with HTML
content.
Example:
@app.route('/')
def index():
return render_template('index.html')
Responding with JSON
Flask makes it easy to send JSON responses using the jsonify
function. This is especially useful for APIs or AJAX requests.
Example: JSON Response
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/data')
def data():
response_data = {'key': 'value', 'numbers': [1, 2, 3, 4]}
return jsonify(response_data)
if __name__ == '__main__':
app.run(debug=True)
Explanation:
jsonify: Converts the dictionary to a JSON response.
Handling JSON Data
Flask can also handle JSON data sent in a request. This is useful for
APIs and AJAX interactions.
Example: Handling JSON Request
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/json', methods=['POST'])
def json_example():
data = request.get_json()
name = data.get('name')
age = data.get('age')
return jsonify(message=f"Hello {name}, you are {age} years old.")
if __name__ == '__main__':
app.run(debug=True)
Explanation:
request.get_json(): Parses the incoming JSON request data.
Practical Example: AJAX Form Submission
Combining form handling with JSON, you can create a more
dynamic user experience using AJAX.
Example: AJAX Form Submission
Create the project structure:
ajax_form/
├── static/
│ └── js/
│ └── script.js
├── templates/
│ └── base.html
│ └── form.html
└── app.py
Create base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}AJAX Form{% endblock %}</title>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</head>
<body>
<header>
<h1>AJAX Form Example</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
Create form.html:
{% extends "base.html" %}
{% block title %}Form{% endblock %}
{% block content %}
<h2>Contact Us</h2>
<form id="contactForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea><br>
<button type="submit">Submit</button>
</form>
<div id="response"></div>
{% endblock %}
Create script.js:
document.getElementById('contactForm').addEventListener('submit', function(event) {
event.preventDefault();
var formData = new FormData(this);
fetch('/submit', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(formData)),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
document.getElementById('response').innerText = data.message;
});
});
Create app.py:
from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
@app.route('/')
def form():
return render_template('form.html')
@app.route('/submit', methods=['POST'])
def submit():
data = request.get_json()
name = data.get('name')
email = data.get('email')
message = data.get('message')
response_message = f"Received message from {name} ({email}): {message}"
return jsonify(message=response_message)
if __name__ == '__main__':
app.run(debug=True)
Explanation:
AJAX Form Submission: Uses JavaScript to submit the form data
as JSON and update the page with the server’s response without refreshing
the page.
10.3.3 PRACTICAL APPLICATIONS
AND EXERCISES
In this section, we will explore unique and practical exercises to
help you apply what you've learned about handling forms and data in Flask.
These exercises will cover various scenarios, from basic form handling to
more complex data processing and AJAX interactions.
Practical Application 1: Feedback Form with Star Rating
Task: Create a feedback form that allows users to submit their name, email,
message, and a star rating from 1 to 5. The form should display the
submitted feedback on a separate page.
Project Structure:
feedback_form/
├── static/
├── templates/
│ └── base.html
│ └── feedback.html
│ └── success.html
│ └── display_feedback.html
└── app.py
Create base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Feedback Form{% endblock %}</title>
</head>
<body>
<header>
<h1>Feedback Form</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2024 Feedback Form</p>
</footer>
</body>
</html>
Create feedback.html:
{% extends "base.html" %}
{% block title %}Submit Feedback{% endblock %}
{% block content %}
<h2>Submit Your Feedback</h2>
<form method="post" action="/submit">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea><br>
<label for="rating">Rating:</label>
<select id="rating" name="rating" required>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select><br>
<button type="submit">Submit</button>
</form>
{% endblock %}
Create success.html:
{% extends "base.html" %}
{% block title %}Thank You{% endblock %}
{% block content %}
<h2>Thank you, {{ name }}!</h2>
<p>Your feedback has been received.</p>
<p>Message: {{ message }}</p>
<p>Rating: {{ rating }} stars</p>
<a href="/feedbacks">See all feedbacks</a>
{% endblock %}
Create display_feedback.html:
{% extends "base.html" %}
{% block title %}All Feedbacks{% endblock %}
{% block content %}
<h2>All Feedbacks</h2>
<ul>
{% for feedback in feedbacks %}
<li>
<strong>{{ feedback.name }}</strong> ({{ feedback.email }}):
{{ feedback.message }} - <em>{{ feedback.rating }} stars</em>
</li>
{% endfor %}
</ul>
<a href="/submit">Submit more feedback</a>
{% endblock %}
Create app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
feedbacks = []
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
message = request.form['message']
rating = request.form['rating']
feedback = {
'name': name,
'email': email,
'message': message,
'rating': rating
}
feedbacks.append(feedback)
return render_template('success.html', name=name, message=message, rating=rating)
return render_template('feedback.html')
@app.route('/feedbacks')
def display_feedback():
return render_template('display_feedback.html', feedbacks=feedbacks)
if __name__ == '__main__':
app.run(debug=True)
Practical Application 2: Book Reservation System
Task: Create a book reservation system where users can reserve a book by
providing their name, email, book title, and reservation date. Display the list
of reserved books on a separate page.
Project Structure:
book_reservation/
├── static/
├── templates/
│ └── base.html
│ └── reserve.html
│ └── success.html
│ └── reservations.html
└── app.py
Create base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Book Reservation{% endblock %}</title>
</head>
<body>
<header>
<h1>Book Reservation</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2024 Book Reservation</p>
</footer>
</body>
</html>
Create reserve.html:
{% extends "base.html" %}
{% block title %}Reserve a Book{% endblock %}
{% block content %}
<h2>Reserve a Book</h2>
<form method="post" action="/reserve">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="book_title">Book Title:</label>
<input type="text" id="book_title" name="book_title" required><br>
<label for="reservation_date">Reservation Date:</label>
<input type="date" id="reservation_date" name="reservation_date" required><br>
<button type="submit">Reserve</button>
</form>
{% endblock %}
Create success.html:
{% extends "base.html" %}
{% block title %}Reservation Successful{% endblock %}
{% block content %}
<h2>Thank you, {{ name }}!</h2>
<p>Your reservation for "{{ book_title }}" on {{ reservation_date }} has been received.</p>
<a href="/reservations">See all reservations</a>
{% endblock %}
Create reservations.html:
{% extends "base.html" %}
{% block title %}All Reservations{% endblock %}
{% block content %}
<h2>All Reservations</h2>
<ul>
{% for reservation in reservations %}
<li>
<strong>{{ reservation.name }}</strong> ({{ reservation.email }}) reserved
"{{ reservation.book_title }}" on <em>{{ reservation.reservation_date }}</em>
</li>
{% endfor %}
</ul>
<a href="/reserve">Reserve another book</a>
{% endblock %}
Create app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
reservations = []
@app.route('/reserve', methods=['GET', 'POST'])
def reserve():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
book_title = request.form['book_title']
reservation_date = request.form['reservation_date']
reservation = {
'name': name,
'email': email,
'book_title': book_title,
'reservation_date': reservation_date
}
reservations.append(reservation)
return render_template('success.html', name=name, book_title=book_title,
reservation_date=reservation_date)
return render_template('reserve.html')
@app.route('/reservations')
def view_reservations():
return render_template('reservations.html', reservations=reservations)
if __name__ == '__main__':
app.run(debug=True)
Create base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}AJAX Autocomplete{% endblock %}</title>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</head>
<body>
<header>
<h1>AJAX Autocomplete Example</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
Create search.html:
{% extends "base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
<h2>Search</h2>
<input type="text" id="searchBox" placeholder="Search...">
<ul id="suggestions"></ul>
{% endblock %}
Create script.js:
document.addEventListener('DOMContentLoaded', function() {
const searchBox = document.getElementById('searchBox');
const suggestions = document.getElementById('suggestions');
searchBox.addEventListener('input', function() {
const query = searchBox.value;
if (query.length > 1) {
fetch(`/autocomplete?query=${query}`)
.then(response => response.json())
.then(data => {
suggestions.innerHTML = '';
data.suggestions.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
suggestions.appendChild(li);
});
});
} else {
suggestions.innerHTML = '';
}
});
});
Create app.py:
from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
# Example data for autocomplete suggestions
items = ['apple', 'banana', 'cherry', 'date', 'fig', 'grape', 'kiwi']
@app.route('/')
def search():
return render_template('search.html')
@app.route('/autocomplete')
def autocomplete():
query = request.args.get('query', '')
suggestions = [item for item in items if query.lower() in item.lower()]
return jsonify(suggestions=suggestions)
if __name__ == '__main__':
app.run(debug=True)
Explanation:
JavaScript (AJAX): The JavaScript code listens for input events on
the search box. When the user types, it sends a GET request to the
/autocomplete endpoint with the query parameter.
Flask Route /autocomplete: This route handles the AJAX request.
It filters the list of items based on the query and returns the suggestions as a
JSON response.
Template: The search.html template contains the search box and a
list to display the suggestions.
Practical Application 4: User Registration and Login
Task: Create a user registration and login system. Users can register with
their email and password, and then log in to access a protected page.
Project Structure:
user_auth/
├── templates/
│ └── base.html
│ └── register.html
│ └── login.html
│ └── profile.html
└── app.py
Create base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}User Authentication{% endblock %}</title>
</head>
<body>
<header>
<h1>User Authentication</h1>
<nav>
<a href="{{ url_for('register') }}">Register</a>
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('profile') }}">Profile</a>
</nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
Create register.html:
{% extends "base.html" %}
{% block title %}Register{% endblock %}
{% block content %}
<h2>Register</h2>
<form method="post" action="/register">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<button type="submit">Register</button>
</form>
{% endblock %}
Create login.html:
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block content %}
<h2>Login</h2>
<form method="post" action="/login">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<button type="submit">Login</button>
</form>
{% endblock %}
Create profile.html:
{% extends "base.html" %}
{% block title %}Profile{% endblock %}
{% block content %}
<h2>Welcome, {{ user.email }}!</h2>
<p>This is your profile page.</p>
{% endblock %}
Create app.py:
from flask import Flask, render_template, request, redirect, url_for, session
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
app.secret_key = 'supersecretkey'
users = {}
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
if email in users:
return 'Email already registered!'
users[email] = generate_password_hash(password)
return redirect(url_for('login'))
return render_template('register.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
user_password_hash = users.get(email)
if user_password_hash and check_password_hash(user_password_hash, password):
session['user'] = email
return redirect(url_for('profile'))
return 'Invalid credentials!'
return render_template('login.html')
@app.route('/profile')
def profile():
if 'user' in session:
user_email = session['user']
return render_template('profile.html', user={'email': user_email})
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)
Explanation:
User Registration: Users can register with an email and password.
Passwords are hashed before being stored.
User Login: Users can log in with their email and password. The
password is verified using the stored hash.
Protected Route: The profile page is protected and can only be
accessed by logged-in users. Sessions are used to track logged-in users.
CHAPTER 11: INTRODUCTION TO
DATA ANALYSIS WITH PANDAS
11.1 WHAT IS PANDAS?
Pandas is an open-source data manipulation and analysis library for
Python. It provides data structures and functions needed to work on
structured data seamlessly. The core functionality of Pandas revolves
around two primary data structures: Series and DataFrame.
Series: A one-dimensional labeled array capable of holding any data
type.
DataFrame: A two-dimensional labeled data structure with
columns of potentially different types.
Pandas is built on top of NumPy and is designed to make data
analysis in Python easier and more intuitive. It is widely used in data
science, statistics, finance, and many other fields where data manipulation
is essential.
Key Features of Pandas:
Data Alignment: Automatic data alignment and handling of
missing data.
Reshaping and Pivoting: Tools for reshaping and pivoting datasets.
Label-based Indexing: Access data using labels instead of integer
indices.
Merging and Joining: Combine data from multiple sources.
Time Series Functionality: Powerful time series manipulation
tools.
11.1.1 SETTING UP PANDAS
To start using Pandas, you need to have Python installed on your
machine. If you don't have Python installed, you can download and install it
from the official Python website.
Once Python is installed, you can set up Pandas by following these steps:
Step 1: Install Pandas
You can install Pandas using the Python package manager pip. Open
a terminal or command prompt and run the following command:
pip install pandas
This will download and install the latest version of Pandas along with its
dependencies.
Step 2: Verify the Installation
After installing Pandas, you can verify the installation by opening a
Python interpreter or an integrated development environment (IDE) like
Jupyter Notebook, and running the following code:
import pandas as pd
print(pd.__version__)
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Accessing Data
You can access data in a DataFrame using labels (column names)
and positions (index).
Accessing Columns:
# Access a single column
names = df['Name']
print(names)
# Access multiple columns
ages_and_cities = df[['Age', 'City']]
print(ages_and_cities)
Output:
0 Alice
1 Bob
2 Charlie
Name: Name, dtype: object
Age City
0 25 New York
1 30 Los Angeles
2 35 Chicago
Accessing Rows:
# Access a single row by index
first_row = df.loc[0]
print(first_row)
# Access multiple rows by index
first_two_rows = df.loc[0:1]
print(first_two_rows)
Output:
Name Alice
Age 25
City New York
Name: 0, dtype: object
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
Manipulating Data
Pandas provides a wide range of functions for data manipulation.
Adding a New Column:
# Add a new column
df['Salary'] = [70000, 80000, 90000]
print(df)
Output:
Name Age City Salary
0 Alice 25 New York 70000
1 Bob 30 Los Angeles 80000
2 Charlie 35 Chicago 90000
Updating Values:
# Update values in a column
df['Age'] = df['Age'] + 1
print(df)
Output:
Name Age City Salary
0 Alice 26 New York 70000
1 Bob 31 Los Angeles 80000
2 Charlie 36 Chicago 90000
Output:
Name Age City
0 Alice 26 New York
1 Bob 31 Los Angeles
2 Charlie 36 Chicago
Name Age City
0 Alice 26 New York
2 Charlie 36 Chicago
Basic Analysis
Pandas includes several methods for basic data analysis.
Descriptive Statistics:
# Summary statistics for numeric columns
summary = df.describe()
print(summary)
Output:
Age
count 2.000000
mean 31.000000
std 7.071068
min 26.000000
25% 28.500000
50% 31.000000
75% 33.500000
max 36.000000
Filtering Data:
# Filter rows based on a condition
filtered_df = df[df['Age'] > 30]
print(filtered_df)
Output:
Name Age City
2 Charlie 36 Chicago
Grouping Data:
# Group by a column and calculate the mean
grouped_df = df.groupby('City').mean()
print(grouped_df)
Output:
Age
City
Chicago 36.0
New York 26.0
11.1.3 PRACTICAL EXAMPLES AND
EXERCISES
To help you understand and practice the basic operations with
Pandas, here are some practical examples and exercises. These exercises
cover creating DataFrames, accessing and manipulating data, and
performing basic analysis.
Create a DataFrame:
import pandas as pd
data = {
'Product': ['A', 'B', 'A', 'C', 'B', 'A'],
'Region': ['North', 'South', 'East', 'West', 'North', 'South'],
'Sales': [1000, 1500, 2000, 1700, 1300, 1100],
'Quantity': [50, 60, 70, 40, 65, 55]
}
df = pd.DataFrame(data)
print(df)
Calculate Total Sales by Region:
total_sales_by_region = df.groupby('Region')['Sales'].sum()
print(total_sales_by_region)
Exercises:
Total Sales and Quantity by Product:
Calculate the total sales and total quantity sold for each product.
total_sales_and_quantity_by_product = df.groupby('Product')[['Sales', 'Quantity']].sum()
print(total_sales_and_quantity_by_product)
Create a DataFrame:
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Department': ['HR', 'Engineering', 'Marketing', 'Engineering', 'HR'],
'Salary': [70000, 80000, 75000, 85000, 72000],
'JoinDate': ['2018-01-15', '2016-03-22', '2017-07-11', '2019-10-01', '2020-05-19']
}
df = pd.DataFrame(data)
print(df)
Exercises:
Total Salary by Department:
Calculate the total salary paid for each department.
total_salary_by_department = df.groupby('Department')['Salary'].sum()
print(total_salary_by_department)
Create a DataFrame:
data = {
'Date': ['2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02', '2021-01-03', '2021-01-03'],
'Company': ['CompanyA', 'CompanyB', 'CompanyA', 'CompanyB', 'CompanyA', 'CompanyB'],
'ClosePrice': [150, 200, 155, 190, 160, 195],
'Volume': [10000, 15000, 12000, 14000, 13000, 16000]
}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'])
print(df)
Exercises:
Total Volume Traded by Company:
Calculate the total volume traded for each company.
total_volume_by_company = df.groupby('Company')['Volume'].sum()
print(total_volume_by_company)
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
Output:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
11.2.2 DATAFRAME METHODS
Pandas DataFrames come with a rich set of methods that allow you
to manipulate, analyze, and transform your data efficiently. Understanding
these methods is crucial for effective data analysis. Below are some of the
most commonly used DataFrame methods, along with examples to illustrate
their usage.
Viewing Data
head() and tail()
The head() method allows you to view the first few rows of a
DataFrame, while tail() shows the last few rows.
Example:
import pandas as pd
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Age': [25, 30, 35, 40, 45],
'City': ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix']
}
df = pd.DataFrame(data)
print(df.head(3)) # View the first 3 rows
print(df.tail(2)) # View the last 2 rows
filter()
The filter() method is used to select columns based on a list of
labels.
Example:
print(df.filter(['Name', 'City']))
Sorting Data
sort_values()
The sort_values() method sorts the DataFrame by the values of one
or more columns.
Example:
# Sort by Age
df_sorted = df.sort_values(by='Age')
print(df_sorted)
# Sort by multiple columns
df_sorted = df.sort_values(by=['City', 'Age'])
print(df_sorted)
Applying Functions
apply()
The apply() method applies a function along the axis of the
DataFrame.
Example:
# Apply a function to the Age column to calculate the square
df['Age_Squared'] = df['Age'].apply(lambda x: x ** 2)
print(df)
concat()
The concat() method concatenates DataFrames along a particular
axis.
Example:
df1 = pd.DataFrame({
'Name': ['Alice', 'Bob'],
'Age': [25, 30]
})
df2 = pd.DataFrame({
'Name': ['Charlie', 'David'],
'Age': [35, 40]
})
concatenated_df = pd.concat([df1, df2])
print(concatenated_df)
11.2.3 PRACTICAL EXAMPLES AND
EXERCISES
To help you understand and practice using DataFrame methods in
Pandas, here are some unique practical examples and exercises. These
examples will cover creating DataFrames, accessing and manipulating data,
and performing basic analysis.
Example 1: Student Grades Analysis
Task: Analyze a dataset of student grades to gain insights into their
performance.
Dataset:
Student,Subject,Grade
Alice,Math,85
Bob,Math,90
Charlie,Math,78
Alice,English,95
Bob,English,80
Charlie,English,85
Alice,Science,88
Bob,Science,82
Charlie,Science,91
Create a DataFrame:
import pandas as pd
data = {
'Student': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob', 'Charlie', 'Alice', 'Bob', 'Charlie'],
'Subject': ['Math', 'Math', 'Math', 'English', 'English', 'English', 'Science', 'Science', 'Science'],
'Grade': [85, 90, 78, 95, 80, 85, 88, 82, 91]
}
df = pd.DataFrame(data)
print(df)
Calculate Average Grade per Student:
avg_grade_per_student = df.groupby('Student')['Grade'].mean()
print(avg_grade_per_student)
Exercises:
Total Grades per Student:
Calculate the total grades for each student across all subjects.
total_grades_per_student = df.groupby('Student')['Grade'].sum()
print(total_grades_per_student)
Create a DataFrame:
data = {
'Employee': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Department': ['HR', 'Engineering', 'Marketing', 'Engineering', 'HR'],
'Salary': [70000, 80000, 75000, 85000, 72000],
'JoinDate': ['2018-01-15', '2016-03-22', '2017-07-11', '2019-10-01', '2020-05-19']
}
df = pd.DataFrame(data)
print(df)
Exercises:
Total Salary by Department:
Calculate the total salary paid for each department.
total_salary_by_department = df.groupby('Department')['Salary'].sum()
print(total_salary_by_department)
Create a DataFrame:
data = {
'Product': ['A', 'B', 'A', 'C', 'B', 'A'],
'Region': ['North', 'South', 'East', 'West', 'North', 'South'],
'Sales': [1000, 1500, 2000, 1700, 1300, 1100],
'Quantity': [50, 60, 70, 40, 65, 55]
}
df = pd.DataFrame(data)
print(df)
Exercises:
Total Quantity Sold by Region:
Calculate the total quantity sold for each region.
total_quantity_by_region = df.groupby('Region')['Quantity'].sum()
print(total_quantity_by_region)
Output:
Age Salary
count 10.000000 10.000000
mean 43.900000 80000.000000
std 24.928498 32998.484363
min 12.000000 30000.000000
25% 23.000000 65000.000000
50% 39.500000 75000.000000
75% 65.750000 90000.000000
max 89.000000 150000.000000
Data Aggregation
Aggregation functions allow you to compute summary statistics for
groups within your data. The groupby() method is commonly used for this
purpose.
Example:
import pandas as pd
data = {
'Department': ['HR', 'Engineering', 'HR', 'Marketing', 'Engineering', 'HR'],
'Salary': [70000, 80000, 75000, 90000, 85000, 60000]
}
df = pd.DataFrame(data)
# Group by department and calculate the mean salary
mean_salary_by_department = df.groupby('Department')['Salary'].mean()
print(mean_salary_by_department)
Output:
Department
Engineering 82500.0
HR 68333.3
Marketing 90000.0
Name: Salary, dtype: float64
Correlation Analysis
Correlation analysis is used to determine the relationship between
two variables. Pandas provides the corr() method to compute pairwise
correlation of columns.
Example:
import pandas as pd
data = {
'Age': [23, 45, 12, 67, 34, 89, 34, 23, 45, 67],
'Salary': [70000, 80000, 30000, 120000, 70000, 150000, 60000, 50000, 80000, 90000],
'Years_of_Experience': [2, 20, 1, 40, 10, 50, 15, 5, 20, 30]
}
df = pd.DataFrame(data)
# Compute correlation matrix
correlation_matrix = df.corr()
print(correlation_matrix)
Output:
Age Salary Years_of_Experience
Age 1.000000 0.944293 0.987745
Salary 0.944293 1.000000 0.915412
Years_of_Experience 0.987745 0.915412 1.000000
Value Counts
The value_counts() method is used to count the occurrences of
unique values in a Series.
Example:
import pandas as pd
data = {
'Product': ['A', 'B', 'A', 'C', 'B', 'A']
}
df = pd.DataFrame(data)
# Count the occurrences of each product
product_counts = df['Product'].value_counts()
print(product_counts)
Output:
A 3
B 2
C 1
Name: Product, dtype: int64
Pivot Tables
Pivot tables are used to summarize data, and Pandas provides the
pivot_table() method for creating pivot tables.
Example:
import pandas as pd
data = {
'Region': ['North', 'South', 'East', 'West', 'North', 'South'],
'Product': ['A', 'B', 'A', 'C', 'B', 'A'],
'Sales': [1000, 1500, 2000, 1700, 1300, 1100]
}
df = pd.DataFrame(data)
# Create a pivot table to summarize sales by region and product
pivot_table = pd.pivot_table(df, values='Sales', index='Region', columns='Product', aggfunc='sum')
print(pivot_table)
Output:
Product A B C
Region
East 2000.0 NaN NaN
North 1000.0 1300.0 NaN
South 1100.0 1500.0 NaN
West NaN NaN 1700.0
11.3.2 PRACTICAL EXAMPLES AND
EXERCISES
To help you practice and understand the basic data analysis
techniques using Pandas, here are some unique practical examples and
exercises. These examples cover descriptive statistics, data aggregation,
correlation analysis, and more.
Example 1: Customer Purchase Analysis
Task: Analyze customer purchase data to understand purchasing patterns.
Dataset:
CustomerID,Product,Price,Quantity,PurchaseDate
1,A,100,2,2022-01-01
2,B,150,1,2022-01-03
1,C,200,3,2022-01-05
3,A,100,1,2022-01-07
2,C,200,2,2022-01-09
3,B,150,2,2022-01-11
Create a DataFrame:
import pandas as pd
data = {
'CustomerID': [1, 2, 1, 3, 2, 3],
'Product': ['A', 'B', 'C', 'A', 'C', 'B'],
'Price': [100, 150, 200, 100, 200, 150],
'Quantity': [2, 1, 3, 1, 2, 2],
'PurchaseDate': ['2022-01-01', '2022-01-03', '2022-01-05', '2022-01-07', '2022-01-09', '2022-01-
11']
}
df = pd.DataFrame(data)
df['PurchaseDate'] = pd.to_datetime(df['PurchaseDate'])
print(df)
Exercises:
Calculate Total Quantity Purchased by Each Customer:
Calculate the total quantity of products purchased by each customer.
total_quantity_by_customer = df.groupby('CustomerID')['Quantity'].sum()
print(total_quantity_by_customer)
Create a DataFrame:
import pandas as pd
data = {
'EmployeeID': [101, 102, 103, 104, 101, 102, 103, 104],
'Department': ['Sales', 'Marketing', 'Sales', 'IT', 'Sales', 'Marketing', 'Sales', 'IT'],
'TasksCompleted': [15, 12, 10, 20, 18, 14, 12, 22],
'HoursWorked': [160, 150, 140, 180, 170, 160, 150, 190],
'ReviewScore': [4.5, 4.0, 3.8, 4.7, 4.6, 4.1, 4.0, 4.8],
'ReviewDate': ['2022-01-01', '2022-01-01', '2022-01-01', '2022-01-01', '2022-06-01', '2022-06-
01', '2022-06-01', '2022-06-01']
}
df = pd.DataFrame(data)
df['ReviewDate'] = pd.to_datetime(df['ReviewDate'])
print(df)
Exercises:
Identify the Department with the Most Tasks Completed:
Identify which department has the highest total tasks completed.
total_tasks_by_department = df.groupby('Department')['TasksCompleted'].sum()
department_with_most_tasks = total_tasks_by_department.idxmax()
print(department_with_most_tasks)
Create a DataFrame:
import pandas as pd
data = {
'Date': ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06', '2022-
01-07'],
'PageViews': [1000, 1100, 1050, 1200, 1150, 1300, 1250],
'UniqueVisitors': [800, 850, 820, 900, 870, 950, 930],
'BounceRate': [0.5, 0.4, 0.45, 0.35, 0.38, 0.32, 0.34]
}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'])
print(df)
Exercises:
Calculate the Total PageViews for the Week:
Calculate the total number of page views over the given week.
total_pageviews = df['PageViews'].sum()
print(f'Total PageViews for the week: {total_pageviews}')
Create a DataFrame:
import pandas as pd
data = {
'MovieID': [1, 2, 3, 4, 5, 6],
'Genre': ['Action', 'Comedy', 'Drama', 'Action', 'Comedy', 'Drama'],
'Rating': [4.5, 4.0, 3.5, 4.7, 3.8, 4.2],
'Views': [1000, 1500, 1200, 2000, 1300, 1100],
'ReleaseYear': [2019, 2018, 2017, 2016, 2019, 2018]
}
df = pd.DataFrame(data)
print(df)
Exercises:
Identify the Genre with the Highest Average Rating:
Find the genre that has the highest average rating.
genre_with_highest_avg_rating = df.groupby('Genre')['Rating'].mean().idxmax()
print(genre_with_highest_avg_rating)
Create a DataFrame:
import pandas as pd
data = {
'Date': ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06', '2022-
01-07'],
'ProductID': [101, 102, 101, 103, 104, 102, 103],
'QuantitySold': [20, 15, 25, 10, 30, 20, 15],
'Revenue': [2000, 1500, 2500, 1000, 3000, 2000, 1500]
}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'])
print(df)
Exercises:
Identify the Product with the Highest Total Sales Quantity:
Find the product that has the highest total quantity sold.
product_with_highest_quantity_sold = df.groupby('ProductID')['QuantitySold'].sum().idxmax()
print(product_with_highest_quantity_sold)
Basic Operations
# Arithmetic Operations
sum_result = 10 + 5 # Addition
difference = 10 - 5 # Subtraction
product = 10 * 5 # Multiplication
quotient = 10 / 5 # Division
power = 2 ** 3 # Exponentiation
# String Operations
greeting = "Hello" + " " + "World" # Concatenation
length = len("Hello") # Length of string
Control Structures
# Conditional Statements
if x > 5:
print("x is greater than 5")
elif x == 5:
print("x is equal to 5")
else:
print("x is less than 5")
# Loops
# for loop
for i in range(5):
print(i)
# while loop
count = 0
while count < 5:
print(count)
count += 1
Importing Modules
# Importing an Entire Module
import math
print(math.sqrt(16))
# Importing Specific Functions from a Module
from math import sqrt, pi
print(sqrt(25))
print(pi)
# Aliasing Modules
import numpy as np
array = np.array([1, 2, 3])
print(array)
Data Structures
Lists
# Creating Lists
fruits = ["apple", "banana", "cherry"]
print(fruits)
# Accessing Elements
first_fruit = fruits[0]
print(first_fruit)
# Adding Elements
fruits.append("date")
print(fruits)
# Removing Elements
fruits.remove("banana")
print(fruits)
Dictionaries
# Creating Dictionaries
person = {
"name": "Alice",
"age": 25,
"city": "New York"
}
print(person)
# Accessing Values
print(person["name"])
# Adding Key-Value Pairs
person["email"] = "[email protected]"
print(person)
# Removing Key-Value Pairs
del person["age"]
print(person)
Tuples
# Creating Tuples
coordinates = (10.0, 20.0)
print(coordinates)
# Accessing Elements
print(coordinates[0])
# Tuples are Immutable
# coordinates[0] = 15.0 # This will raise an error
Sets
# Creating Sets
unique_numbers = {1, 2, 3, 4, 4, 5}
print(unique_numbers) # Duplicates will be removed
# Adding Elements
unique_numbers.add(6)
print(unique_numbers)
# Removing Elements
unique_numbers.remove(3)
print(unique_numbers)
File Handling
Reading and Writing Files
# Writing to a File
with open('example.txt', 'w') as file:
file.write("Hello, World!")
# Reading from a File
with open('example.txt', 'r') as file:
content = file.read()
print(content)
Exception Handling
Try-Except Block
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
finally:
print("Execution completed.")
App01:
First install pygame:
pip install pygame
App02:
Make sure you have tkinter, sqlite3, datetime installed.
import tkinter as tk
from tkinter import messagebox
from datetime import datetime
import sqlite3
# Function to create the database and the notes table if it doesn't exist
def create_db():
conn = sqlite3.connect('notes.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS notes
(id INTEGER PRIMARY KEY, title TEXT, content TEXT, category TEXT, created_at
TIMESTAMP)''')
conn.commit()
conn.close()
# Main application class
class NotesApp:
def __init__(self, root):
self.root = root
self.root.title("Notes App")
self.title_label = tk.Label(root, text="Title")
self.title_label.pack()
self.title_entry = tk.Entry(root)
self.title_entry.pack()
self.category_label = tk.Label(root, text="Category")
self.category_label.pack()
self.category_entry = tk.Entry(root)
self.category_entry.pack()
self.content_label = tk.Label(root, text="Content")
self.content_label.pack()
self.content_text = tk.Text(root, height=10)
self.content_text.pack()
self.add_button = tk.Button(root, text="Add Note", command=self.add_note)
self.add_button.pack()
self.notes_listbox = tk.Listbox(root)
self.notes_listbox.pack(fill=tk.BOTH, expand=True)
self.notes_listbox.bind('<<ListboxSelect>>', self.display_note)
self.delete_button = tk.Button(root, text="Delete Note", command=self.delete_note)
self.delete_button.pack()
self.load_notes()
def run_query(self, query, params=()):
conn = sqlite3.connect('notes.db')
c = conn.cursor()
c.execute(query, params)
conn.commit()
results = c.fetchall()
conn.close()
return results
def add_note(self):
title = self.title_entry.get()
content = self.content_text.get("1.0", tk.END)
category = self.category_entry.get()
created_at = datetime.now()
if title and content.strip():
self.run_query("INSERT INTO notes (title, content, category, created_at) VALUES (?, ?, ?,
?)",
(title, content, category, created_at))
self.title_entry.delete(0, tk.END)
self.category_entry.delete(0, tk.END)
self.content_text.delete("1.0", tk.END)
self.load_notes()
else:
messagebox.showwarning("Warning", "Title and Content are required")
def load_notes(self):
self.notes_listbox.delete(0, tk.END)
notes = self.run_query("SELECT id, title, category FROM notes ORDER BY created_at
DESC")
for note in notes:
self.notes_listbox.insert(tk.END, f"{note[0]} - {note[1]} ({note[2]})")
def display_note(self, event):
selection = self.notes_listbox.curselection()
if selection:
note_id = self.notes_listbox.get(selection[0]).split(" - ")[0]
note = self
App03:
import pygame
import sys
# Initialize Pygame
pygame.init()
# Constants
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BALL_SIZE = 20
PADDLE_WIDTH = 10
PADDLE_HEIGHT = 100
PADDLE_SPEED = 6
BALL_SPEED_X = 5
BALL_SPEED_Y = 5
# Set up the display
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Ping-Pong")
# Game objects
ball = pygame.Rect(SCREEN_WIDTH // 2 - BALL_SIZE // 2, SCREEN_HEIGHT // 2 -
BALL_SIZE // 2, BALL_SIZE, BALL_SIZE)
player_paddle = pygame.Rect(SCREEN_WIDTH - 20, SCREEN_HEIGHT // 2 -
PADDLE_HEIGHT // 2, PADDLE_WIDTH, PADDLE_HEIGHT)
opponent_paddle = pygame.Rect(10, SCREEN_HEIGHT // 2 - PADDLE_HEIGHT // 2,
PADDLE_WIDTH, PADDLE_HEIGHT)
# Velocities
ball_speed_x = BALL_SPEED_X
ball_speed_y = BALL_SPEED_Y
player_speed = 0
opponent_speed = PADDLE_SPEED
# Game loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player_speed = -PADDLE_SPEED
if event.key == pygame.K_DOWN:
player_speed = PADDLE_SPEED
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player_speed = 0
# Ball movement
ball.x += ball_speed_x
ball.y += ball_speed_y
# Ball collision with walls
if ball.top <= 0 or ball.bottom >= SCREEN_HEIGHT:
ball_speed_y *= -1
if ball.left <= 0 or ball.right >= SCREEN_WIDTH:
ball_speed_x *= -1
# Ball collision with paddles
if ball.colliderect(player_paddle) or ball.colliderect(opponent_paddle):
ball_speed_x *= -1
# Player paddle movement
player_paddle.y += player_speed
if player_paddle.top <= 0:
player_paddle.top = 0
if player_paddle.bottom >= SCREEN_HEIGHT:
player_paddle.bottom = SCREEN_HEIGHT
# Opponent paddle movement
if opponent_paddle.top < ball.y:
opponent_paddle.y += opponent_speed
if opponent_paddle.bottom > ball.y:
opponent_paddle.y -= opponent_speed
if opponent_paddle.top <= 0:
opponent_paddle.top = 0
if opponent_paddle.bottom >= SCREEN_HEIGHT:
opponent_paddle.bottom = SCREEN_HEIGHT
# Draw everything
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, player_paddle)
pygame.draw.rect(screen, WHITE, opponent_paddle)
pygame.draw.ellipse(screen, WHITE, ball)
pygame.draw.aaline(screen, WHITE, (SCREEN_WIDTH // 2, 0), (SCREEN_WIDTH // 2,
SCREEN_HEIGHT))
pygame.display.flip()
pygame.time.Clock().tick(60)
App04:
Structure:
StarGazer/
│
├── app.py
├── templates/
│ ├── base.html
│ ├── index.html
│ ├── stars.html
│ ├── constellations.html
│ └── astronomers.html
└── static/
└── styles.css
app.py:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
# Data Structures
stars = [
{"name": "Sirius", "constellation": "Canis Major", "type": "Main Sequence"},
{"name": "Betelgeuse", "constellation": "Orion", "type": "Red Supergiant"}
]
constellations = set(["Orion", "Canis Major", "Ursa Major"])
astronomers = {
"Galileo Galilei": "Italian astronomer, physicist and engineer.",
"Carl Sagan": "American astronomer, planetary scientist, cosmologist, astrophysicist,
astrobiologist, author, and science communicator."
}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/stars')
def star_list():
return render_template('stars.html', stars=stars)
@app.route('/constellations')
def constellation_list():
return render_template('constellations.html', constellations=constellations)
@app.route('/astronomers')
def astronomer_list():
return render_template('astronomers.html', astronomers=astronomers)
@app.route('/add_star', methods=['GET', 'POST'])
def add_star():
if request.method == 'POST':
name = request.form['name']
constellation = request.form['constellation']
star_type = request.form['type']
stars.append({"name": name, "constellation": constellation, "type": star_type})
constellations.add(constellation)
return redirect(url_for('star_list'))
return render_template('add_star.html')
@app.route('/search_star', methods=['GET', 'POST'])
def search_star():
if request.method == 'POST':
name = request.form['name']
found_stars = [star for star in stars if star['name'].lower() == name.lower()]
return render_template('search_results.html', stars=found_stars)
return render_template('search_star.html')
if __name__ == '__main__':
app.run(debug=True)
templates/base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>StarGazer</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<header>
<h1>StarGazer</h1>
<nav>
<ul>
<li><a href="{{ url_for('index') }}">Home</a></li>
<li><a href="{{ url_for('star_list') }}">Stars</a></li>
<li><a href="{{ url_for('constellation_list') }}">Constellations</a></li>
<li><a href="{{ url_for('astronomer_list') }}">Astronomers</a></li>
<li><a href="{{ url_for('add_star') }}">Add Star</a></li>
<li><a href="{{ url_for('search_star') }}">Search Star</a></li>
</ul>
</nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
templates/index.html:
{% extends 'base.html' %}
{% block content %}
<h2>Welcome to StarGazer</h2>
<p>Explore the stars, constellations, and famous astronomers!</p>
{% endblock %}
templates/stars.html:
{% extends 'base.html' %}
{% block content %}
<h2>Stars</h2>
<ul>
{% for star in stars %}
<li>{{ star.name }} - {{ star.constellation }} - {{ star.type }}</li>
{% endfor %}
</ul>
{% endblock %}
templates/constellations.html:
{% extends 'base.html' %}
{% block content %}
<h2>Constellations</h2>
<ul>
{% for constellation in constellations %}
<li>{{ constellation }}</li>
{% endfor %}
</ul>
{% endblock %}
templates/astronomers.html:
{% extends 'base.html' %}
{% block content %}
<h2>Astronomers</h2>
<ul>
{% for name, bio in astronomers.items() %}
<li><strong>{{ name }}</strong>: {{ bio }}</li>
{% endfor %}
</ul>
{% endblock %}
templates/add_star.html:
{% extends 'base.html' %}
{% block content %}
<h2>Add a New Star</h2>
<form method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name"><br><br>
<label for="constellation">Constellation:</label>
<input type="text" id="constellation" name="constellation"><br><br>
<label for="type">Type:</label>
<input type="text" id="type" name="type"><br><br>
<input type="submit" value="Add Star">
</form>
{% endblock %}
templates/search_star.html:
{% extends 'base.html' %}
{% block content %}
<h2>Search for a Star</h2>
<form method="post">
<label for="name">Star Name:</label>
<input type="text" id="name" name="name"><br><br>
<input type="submit" value="Search">
</form>
{% endblock %}
templates/search_results.html:
{% extends 'base.html' %}
{% block content %}
<h2>Search Results</h2>
<ul>
{% if stars %}
{% for star in stars %}
<li>{{ star.name }} - {{ star.constellation }} - {{ star.type }}</li>
{% endfor %}
{% else %}
<li>No stars found</li>
{% endif %}
</ul>
{% endblock %}
static/styles.css:
body {
font-family: Arial, sans-serif;
background-color: #121212;
color: #ffffff;
}
header {
background-color: #1f1f1f;
padding: 1em;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul li {
display: inline;
margin-right: 1em;
}
nav ul li a {
color: #ffffff;
text-decoration: none;
}
h1 {
margin: 0;
}
h2 {
color: #f39c12;
}
App05:
import tkinter as tk
from tkinter import filedialog
from tkinter import scrolledtext
from PIL import Image
# ASCII characters used to build the output text
ASCII_CHARS = ["@", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]
def resize_image(image, new_width=100):
width, height = image.size
ratio = height / width / 1.65
new_height = int(new_width * ratio)
resized_image = image.resize((new_width, new_height))
return resized_image
def grayify(image):
grayscale_image = image.convert("L")
return grayscale_image
def pixels_to_ascii(image):
pixels = image.getdata()
ascii_str = ""
for pixel in pixels:
ascii_str += ASCII_CHARS[pixel // 25]
return ascii_str
def image_to_ascii(image_path):
try:
image = Image.open(image_path)
except Exception as e:
print(f"Unable to open image file {image_path}. {e}")
return
image = resize_image(image)
image = grayify(image)
ascii_str = pixels_to_ascii(image)
img_width = image.width
ascii_str_len = len(ascii_str)
ascii_img = ""
for i in range(0, ascii_str_len, img_width):
ascii_img += ascii_str[i:i + img_width] + "\n"
return ascii_img
def open_file():
file_path = filedialog.askopenfilename()
if file_path:
ascii_art = image_to_ascii(file_path)
if ascii_art:
txt_area.delete('1.0', tk.END)
txt_area.insert(tk.END, ascii_art)
# Setting up the GUI
root = tk.Tk()
root.title("Image to ASCII Art")
# Adding a button to open the file
btn_open = tk.Button(root, text="Open Image", command=open_file)
btn_open.pack(pady=10)
# Adding a scrolled text area to display the ASCII art
txt_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=100, height=40, font=("Courier",
10))
txt_area.pack(pady=10)
root.mainloop()
App06:
import tkinter as tk
from tkinter import messagebox, simpledialog, ttk
import pandas as pd
import csv
import os
class TaskManager:
def __init__(self, root):
self.root = root
self.root.title("Task Manager")
self.tasks = self.load_tasks()
self.create_widgets()
def create_widgets(self):
self.tree = ttk.Treeview(self.root, columns=('Task', 'Category', 'Completed'), show='headings')
self.tree.heading('Task', text='Task')
self.tree.heading('Category', text='Category')
self.tree.heading('Completed', text='Completed')
self.tree.pack(fill=tk.BOTH, expand=True)
self.load_tree()
self.add_btn = tk.Button(self.root, text="Add Task", command=self.add_task)
self.add_btn.pack(side=tk.LEFT, padx=10, pady=10)
self.edit_btn = tk.Button(self.root, text="Edit Task", command=self.edit_task)
self.edit_btn.pack(side=tk.LEFT, padx=10, pady=10)
self.del_btn = tk.Button(self.root, text="Delete Task", command=self.delete_task)
self.del_btn.pack(side=tk.LEFT, padx=10, pady=10)
self.search_btn = tk.Button(self.root, text="Search Task", command=self.search_task)
self.search_btn.pack(side=tk.LEFT, padx=10, pady=10)
self.stats_btn = tk.Button(self.root, text="View Stats", command=self.view_stats)
self.stats_btn.pack(side=tk.LEFT, padx=10, pady=10)
def load_tasks(self):
if os.path.exists('tasks.csv'):
return pd.read_csv('tasks.csv').to_dict(orient='records')
else:
return []
def save_tasks(self):
pd.DataFrame(self.tasks).to_csv('tasks.csv', index=False)
def load_tree(self):
for task in self.tasks:
self.tree.insert('', tk.END, values=(task['Task'], task['Category'], task['Completed']))
def add_task(self):
task_name = simpledialog.askstring("Task", "Enter task name:")
if not task_name:
return
task_category = simpledialog.askstring("Category", "Enter task category:")
if not task_category:
return
task = {"Task": task_name, "Category": task_category, "Completed": "No"}
self.tasks.append(task)
self.tree.insert('', tk.END, values=(task_name, task_category, "No"))
self.save_tasks()
def edit_task(self):
selected_item = self.tree.selection()
if not selected_item:
messagebox.showwarning("Warning", "Please select a task to edit")
return
task_name = simpledialog.askstring("Task", "Edit task name:",
initialvalue=self.tree.item(selected_item, 'values')[0])
if not task_name:
return
task_category = simpledialog.askstring("Category", "Edit task category:",
initialvalue=self.tree.item(selected_item, 'values')[1])
if not task_category:
return
self.tree.item(selected_item, values=(task_name, task_category, self.tree.item(selected_item,
'values')[2]))
task_index = self.tree.index(selected_item)
self.tasks[task_index] = {"Task": task_name, "Category": task_category, "Completed":
self.tree.item(selected_item, 'values')[2]}
self.save_tasks()
def delete_task(self):
selected_item = self.tree.selection()
if not selected_item:
messagebox.showwarning("Warning", "Please select a task to delete")
return
task_index = self.tree.index(selected_item)
self.tree.delete(selected_item)
del self.tasks[task_index]
self.save_tasks()
def search_task(self):
search_term = simpledialog.askstring("Search", "Enter task name or category to search:")
if not search_term:
return
search_results = [task for task in self.tasks if search_term.lower() in task['Task'].lower() or
search_term.lower() in task['Category'].lower()]
if search_results:
self.tree.delete(*self.tree.get_children())
for task in search_results:
self.tree.insert('', tk.END, values=(task['Task'], task['Category'], task['Completed']))
else:
messagebox.showinfo("No results", "No tasks found")
def view_stats(self):
total_tasks = len(self.tasks)
completed_tasks = len([task for task in self.tasks if task['Completed'] == "Yes"])
incomplete_tasks = total_tasks - completed_tasks
messagebox.showinfo("Task Stats", f"Total Tasks: {total_tasks}\nCompleted Tasks:
{completed_tasks}\nIncomplete Tasks: {incomplete_tasks}")
if __name__ == "__main__":
root = tk.Tk()
app = TaskManager(root)
root.mainloop()
App07:
import tkinter as tk
from tkinter import colorchooser, simpledialog
class DrawingApp:
def __init__(self, root):
self.root = root
self.root.title("Drawing App")
self.canvas = tk.Canvas(self.root, bg="white", cursor="cross")
self.canvas.pack(fill=tk.BOTH, expand=True)
self.setup_ui()
self.bind_events()
self.current_tool = "freehand"
self.current_color = "black"
self.start_x = None
self.start_y = None
def setup_ui(self):
toolbar = tk.Frame(self.root, bd=1, relief=tk.RAISED)
toolbar.pack(side=tk.TOP, fill=tk.X)
self.color_button = tk.Button(toolbar, text="Color", command=self.choose_color)
self.color_button.pack(side=tk.LEFT, padx=2, pady=2)
self.freehand_button = tk.Button(toolbar, text="Freehand", command=lambda:
self.select_tool("freehand"))
self.freehand_button.pack(side=tk.LEFT, padx=2, pady=2)
self.line_button = tk.Button(toolbar, text="Line", command=lambda: self.select_tool("line"))
self.line_button.pack(side=tk.LEFT, padx=2, pady=2)
self.rect_button = tk.Button(toolbar, text="Rectangle", command=lambda:
self.select_tool("rectangle"))
self.rect_button.pack(side=tk.LEFT, padx=2, pady=2)
self.circle_button = tk.Button(toolbar, text="Circle", command=lambda:
self.select_tool("circle"))
self.circle_button.pack(side=tk.LEFT, padx=2, pady=2)
self.clear_button = tk.Button(toolbar, text="Clear", command=self.clear_canvas)
self.clear_button.pack(side=tk.LEFT, padx=2, pady=2)
def bind_events(self):
self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<B1-Motion>", self.on_mouse_drag)
self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
def choose_color(self):
color = colorchooser.askcolor()[1]
if color:
self.current_color = color
def select_tool(self, tool):
self.current_tool = tool
def clear_canvas(self):
self.canvas.delete("all")
def on_button_press(self, event):
self.start_x = event.x
self.start_y = event.y
if self.current_tool == "freehand":
self.canvas.create_line(self.start_x, self.start_y, event.x, event.y, fill=self.current_color,
smooth=True)
def on_mouse_drag(self, event):
if self.current_tool == "freehand":
self.canvas.create_line(self.start_x, self.start_y, event.x, event.y, fill=self.current_color,
smooth=True)
self.start_x, self.start_y = event.x, event.y
def on_button_release(self, event):
if self.current_tool == "line":
self.canvas.create_line(self.start_x, self.start_y, event.x, event.y, fill=self.current_color)
elif self.current_tool == "rectangle":
self.canvas.create_rectangle(self.start_x, self.start_y, event.x, event.y,
outline=self.current_color)
elif self.current_tool == "circle":
x0, y0 = (self.start_x, self.start_y)
x1, y1 = (event.x, event.y)
r = ((x1 - x0)**2 + (y1 - y0)**2)**0.5
self.canvas.create_oval(x0 - r, y0 - r, x0 + r, y0 + r, outline=self.current_color)
self.start_x, self.start_y = None, None
if __name__ == "__main__":
root = tk.Tk()
app = DrawingApp(root)
root.mainloop()
THANK YOU!
TOMMY OG