Python Language Tutorial

What is Python?
Python is a high-level, interpreted, and versatile programming language known for its simplicity and readability. Guido van Rossum created Python in the late 1980s, and it was first released in 1991. Since then, Python has gained tremendous popularity and has become one of the most widely used programming languages in the world.
1. Features of Python
a. Easy to Learn and Read
Python's syntax is designed to be simple and straightforward, making it easy for beginners to learn and read the code. The use of indentation for code blocks also enhances readability, making it easier to understand the program's structure.
b. Interpreted Language
Python is an interpreted language, meaning that it does not require a separate compilation step. Instead, the Python interpreter reads and executes the code line-by-line, making the development process faster and more interactive.
c. Dynamically typed
Python is dynamically typed, which means that variable types are determined at runtime. Unlike statically typed languages, you don't need to declare the data type of a variable explicitly.
d. Object-Oriented
Python is a fully object-oriented language, allowing developers to create and work with classes and objects, promoting code reusability and modularity.
e. Extensive Standard Library
Python comes with a comprehensive standard library that provides a wide range of modules and functions for various tasks, such as file handling, networking, and web development.
f. Cross-Platform
Python is a cross-platform language, meaning that Python code written on one operating system can be executed on another without any modifications.
2. Installing Python
Python is available for various platforms, including Windows, macOS, and Linux. Setting up a Python environment is the first step to start programming in Python. A Python environment consists of the Python interpreter, libraries, and tools that allow you to write, execute, and manage Python code efficiently.
Python has two major versions in use: Python 2 and Python 3. Python 2 reached its end of life on January 1, 2020, and Python 3 is the current and recommended version. In this guide, we'll focus on Python 3 as it is the version actively developed and supported. To install Python on your computer, follow these steps:
a. Windows
Visit the official Python website (https://www.python.org) and go to the Downloads section.
- Click on the latest stable release of Python 3 (e.g., Python 3.8.x).
- Scroll down and download the Windows installer (e.g., python-3.8.x-amd64.exe) suitable for your system architecture (32-bit or 64-bit).
- Run the installer and check the option to add Python to the system's PATH during installation.
- Click "Install Now" to begin the installation process.
- After installation, open the Command Prompt or PowerShell and type python to verify that Python is installed correctly.
b. MacOS
macOS usually comes with a pre-installed version of Python, but it's recommended to install the latest version from the official website.
Visit the official Python website (https://www.python.org) and go to the Downloads section.
- Click on the latest stable release of Python 3 (e.g., Python 3.9.x).
- Download the macOS installer (e.g., python-3.9.x-macosx10.9.pkg).
- Double-click the downloaded .pkg file to run the installer.
- Follow the installation instructions to complete the installation.
c. Linux
Most Linux distributions come with Python pre-installed. However, to ensure that you have the latest version, you can use your package manager to install Python.
For Debian/Ubuntu-based systems:
sudo apt update(code-box)
sudo apt install python3(code-box)
For Red Hat/Fedora-based systems:
sudo dnf install python3(code-box)
For Arch Linux:
sudo pacman -S python(code-box)
After installation, you can check the Python version by typing python3 --version in the terminal.
3. Python Integrated Development Environments (IDEs)
While you can write Python code in any text editor, using an Integrated Development Environment (IDE) can significantly enhance your productivity. IDEs provide features like code completion, syntax highlighting, debugging tools, and integration with version control systems. Here are some popular Python IDEs:
a. PyCharm
PyCharm is a powerful and feature-rich IDE developed by JetBrains. It is available in both free (Community Edition) and paid (Professional Edition) versions. PyCharm offers advanced code analysis, debugging, and integration with popular web frameworks.
We will download Pycharm Community Edition which is free to use. There are some steps you have to follow to install community edition.
Step -1
To download required package or executable file click on this link : https://www.jetbrains.com/pycharm/download/?section=windows#section=windows
There are two versions: Pycharm Professional and Pycharm Community Edition. I am using the Community version that is free. Scroll and come to Pycharm Community Edition and click the download button.
Step-2
You will see the welcome screen and click on next button.
Step-3
Select destination folder or keep default folder path. Click on next button
.
Step-4
Select destination folder or keep default folder path. Click on next button
Step-5
Keep default. And. click on next button
Step-6
Wait to complete installation
Step-7
Now, click on Run Pycharm Community Edition check box. And Click on Finish button.
Step-8
Create a new project.
Step-9
Check out the “Create a main.py welcome script”
Step-10
Setting python interpreter, click Python Interpreter.
Step-11
You can install package as per your requirement.
Step-12
Create a new file right click on python project, then click on New, after that click on Python file.
Your First Python Program
Let's write a simple "Hello, World!" program in Python to get started in Pycharm.
# Hello, World! program
print("Hello, World!")(code-box)
4. Python syntax and comments
In Python, syntax refers to the set of rules that govern how you write code in the language. It's essential to follow these rules to ensure that your code is valid and can be executed without errors. Here are some key points about Python syntax:
Indentation: Python uses indentation to define blocks of code instead of using curly braces as in many other programming languages. Indentation is crucial for structuring your code and identifying loops, conditionals, and function definitions.
Example:
# Correct indentation
if x > 5:
print("x is greater than 5")
else:
print("x is not greater than 5")
# Incorrect indentation (will raise an IndentationError)
if x > 5:
print("x is greater than 5")(code-box)
Comments: Comments in Python are used to explain code or add notes that are not executed when the program runs. They are essential for making your code more readable and understandable to yourself and others.
Example:
# This is a single-line comment
"""
This is a
multi-line
comment
"""
# Code with comments
x = 10
# The following line adds 5 to the value of x
x += 5 # Now x is 15(code-box)
Line Continuation: If a statement is too long and doesn't fit on a single line, you can use a backslash () to continue the statement on the next line.
Example:
result = 10 + 20 + \
30 + 40 + \
50(code-box)
Semicolons: Unlike some other languages, Python does not require semicolons to separate statements. However, you can use them to put multiple statements on one line.
Example:
print("Hello"); print("World")(code-box)
Whitespace: While indentation is crucial, Python is generally lenient with whitespace (spaces, tabs) within lines, but consistent indentation is essential for maintaining code readability.
Example:
# Both are valid
x=5
y = 10(code-box)
5. Basic Input/Output Functions
print() function and input() function
In Python, the print() and input() functions are essential for input/output operations.
The print() function is used to display output to the console. It takes one or more arguments (separated by commas) and prints them to the screen. Here's how you use it:
print("Hello, world!")(code-box)
The above code will print "Hello, world!" to the console. You can also provide multiple arguments to print():
name = "John"
age = 30
print("My name is", name, "and I am", age, "years old.")(code-box)
This will output: "My name is John and I am 30 years old."
The input() function is used to get input from the user. When called, it displays a prompt to the user and waits for them to enter some text. The user's input is treated as a string and can be stored in a variable. Here's an example:
name = input("Enter your name: ")
print("Hello, " + name + "!")(code-box)
When you run this code, it will ask the user to enter their name. After the user enters their name, it will display a greeting like "Hello, John!" if the user entered "John."
You can also convert the input to other data types. For example, if you expect the user to enter an integer, you can do this:
age = int(input("Enter your age: "))(code-box)
PYTHON BASICS: VARIABLES AND DATA TYPES
Introduction to Variables and Data Types
In Python, variables are used to store data values. They act as containers for holding various types of data, such as numbers, text, or collections of values. Understanding variables and data types is fundamental to programming in Python, as it allows us to work with different types of data efficiently. In this chapter, we'll explore Python's built-in data types and learn how to work with variables effectively.
1. Declaring Variables
In Python, declaring a variable is as simple as assigning a value to it using the equal sign (=) operator. Unlike some other programming languages, Python is dynamically typed, meaning the type of a variable is determined at runtime based on the value assigned to it.
# Declaring variables
age = 25
name = "John Doe"
is_student = True(code-box)
In the above example, we declared three variables: age, name, and is_student. The first variable, age, holds an integer value (25), the second variable, name, holds a string value ("John Doe"), and the third variable, is_student, holds a Boolean value (True).
2. Python Data Types
Python supports several built-in data types, which are the fundamental building blocks for constructing more complex data structures. The most common data types include:
a. Numeric Types
Python has several numeric data types:
Integers: Whole numbers without a fractional part, such as 1, 10, or -5.
Floating-Point Numbers: Numbers with a fractional part, such as 3.14 or -2.71.
Complex Numbers: Numbers in the form of a + bj, where a and b are real numbers and j represents the square root of -1.
# Numeric data types
age = 25
height = 5.11
complex_num = 3 + 2j(code-box)
b. Strings
Strings are sequences of characters and are used to represent text data. They can be enclosed in single quotes (') or double quotes (").
# String data type
name = "John Doe"
message = 'Hello, World!'(code-box)
c. Boolean
Boolean data type represents the truth values True or False. Booleans are often used in conditional statements.
# Boolean data type
is_student = True
is_registered = False(code-box)
d. Lists
Lists are ordered collections of elements. They can contain elements of different data types and can be modified after creation.
# List data type
numbers = [1, 2, 3, 4, 5]
names = ["John", "Jane", "Bob"]
mixed_list = [1, "Hello", True](code-box)
e. Tuples
Tuples are similar to lists but are immutable, meaning their elements cannot be changed after creation.
# Tuple data type
coordinates = (10, 20)
colors = ("red", "green", "blue")(code-box)
f. Dictionaries
Dictionaries are unordered collections of key-value pairs. Each value is associated with a unique key, allowing for efficient data retrieval.
# Dictionary data type
person = {"name": "John", "age": 25, "is_student": True}(code-box)
g. Sets
Sets are unordered collections of unique elements. They are useful for performing mathematical set operations like union, intersection, etc.
# Set data type
unique_numbers = {1, 2, 3, 4, 5}(code-box)
3. Type Conversion (Typecasting)
In Python, we can convert data from one type to another using type conversion or type casting. This allows us to perform operations that might not be possible with certain data types.
# Type conversion
num_str = "10"
num_int = int(num_str) # Convert the string to an integer
num_float = float(num_str) # Convert the string to a floating-point number(code-box)
4. Operations on Variables
We can perform various operations on variables, depending on their data types.
a. Arithmetic Operations
Arithmetic operations, such as addition, subtraction, multiplication, and division, can be performed on numeric variables.
# Arithmetic operations
x = 10
y = 5
addition = x + y
subtraction = x - y
multiplication = x * y
division = x / y
remainder=x % y
exponentiation= x ** y(code-box)
b. String Operations
String variables support various string operations, such as concatenation and slicing.
# String operations
name = "John"
greeting = "Hello, " + name # Concatenation
substring = name[1:3] # Slicing(code-box)
c. String Concatenation
You can concatenate strings using the + operator
first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name(code-box)
c. List Operations
Lists support several operations, such as element access, appending, and removing elements.
# List operations
numbers = [1, 2, 3, 4, 5]
first_element = numbers[0] # Accessing elements
numbers.append(6) # Appending elements
numbers.remove(3) # Removing elements(code-box)
d. Dictionary Operations
Dictionaries support operations for accessing, adding, and removing key-value pairs.
# Dictionary operations
person = {"name": "John", "age": 25}
person["gender"] = "Male" # Adding a key-value pair
del person["age"] # Removing a key-value pair(code-box)
e. Comparison Operations
Comparison operators are used to compare variables and return Boolean values (True or False):
x = 10
y = 5
is_equal = x == y
is_not_equal = x != y
is_greater_than = x > y
is_less_than = x < y
is_greater_or_equal = x >= y
is_less_or_equal = x <= y(code-box)
f. Logical Operations
Logical operators are used to combine conditions and evaluate complex expressions:
p = True
q = False
logical_and = p and q
logical_or = p or q
logical_not = not p(code-box)
5. Variable Naming Rules
There are certain rules and conventions for naming variables in Python:
- Variable names must start with a letter (a-z, A-Z) or an underscore (_).
- The rest of the variable name can consist of letters, digits (0-9), and underscores.
- Variable names are case-sensitive (age, Age, and AGE are three different variables).
- It is recommended to use descriptive and meaningful names for variables to enhance code readability.
6. Global Scope
In Python, the term "global scope" refers to the visibility or accessibility of variables and objects defined at the top level of a Python script or module. Variables declared at this level are considered to have a global scope, which means they can be accessed from any part of the code, including within functions and classes.
When a variable is defined outside of any function or class, it becomes a global variable. Here's an example:
# Global scope variable
global_var = 10
def my_function():
# Accessing the global variable within a function
print(global_var)
my_function() # Output: 10(code-box)
In the example above, the variable global_var is defined outside the function my_function, making it accessible from within the function.
However, if you want to modify the value of a global variable from within a function, you need to use the global keyword. Without using this keyword, Python would assume that you are creating a new local variable inside the function instead of modifying the global one:
global_var = 10
def modify_global():
global global_var
global_var = 20
print(global_var) # Output: 10
modify_global()
print(global_var) # Output: 20(code-box)
It's important to use global variables judiciously, as excessive reliance on them can make code harder to read, understand, and maintain. In many cases, it is recommended to pass variables explicitly as function arguments and return values instead of using global variables whenever possible. This promotes better code organization and reduces potential side effects.
CONTROL FLOW: CONDITIONALS AND LOOPS
Introduction to Control Flow
Control flow structures allow us to control the flow of our program's execution based on certain conditions or to repeat certain actions multiple times. In Python, control flow is achieved through conditionals (if-else statements) and loops (while and for loops). Understanding control flow is essential for creating dynamic and interactive programs. In this chapter, we'll explore conditionals and loops in Python and learn how to make decisions and repeat actions based on specific conditions.
1. If-Else Statements
a. The if Statement
The if statement is used to execute a block of code only if a certain condition is true. It allows us to make decisions in our program.
# Example of if statement
age = 25
if age >= 18:
print("You are an adult.")(code-box)
In this example, we check if the age variable is greater than or equal to 18. If the condition is true, the indented block of code under the if statement will be executed, and "You are an adult." will be printed.
b. The if-else statement
The if-else statement allows us to specify two blocks of code: one to be executed if the condition is true, and another to be executed if the condition is false.
# Example of if-else statement
age = 15
if age >= 18:
print("You are an adult.")
else:
print("You are a minor.")(code-box)
In this example, if the age variable is greater than or equal to 18, "You are an adult." will be printed. Otherwise, "You are a minor." will be printed.
c. The if-elif-else Statement
The if-elif-else statement allows us to check multiple conditions and execute different blocks of code based on those conditions.
# Example of if-elif-else statement
score = 85
if score >= 90:
print("You got an A.")
elif score >= 80:
print("You got a B.")
elif score >= 70:
print("You got a C.")
else:
print("You got a D.")(code-box)
In this example, the program checks the score variable and prints different messages based on the score range.
# Assume we have a variable called 'score' representing a student's test score
score =int(input("Enter the Grade score :"))
# Using if-elif-else to determine the grade based on the score
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
# Printing the grade
print("The student's grade is:", grade)(code-box)
2. While Loop
The while loop allows us to repeat a block of code as long as a certain condition is true. It is useful when we want to perform an action repeatedly until a specific condition is met.
# Example of while loop
count = 0
while count < 5:
print("Count:", count)
count += 1(code-box)
In this example, the while loop will continue to print the value of count as long as it is less than 5.
This loop counts down from 10 to 1 and then prints "Blastoff!".
count = 10
while count > 0:
print(count)
count -= 1
print("Blastoff!")(code-box)
This loop keeps asking the user for input until they type "exit".
user_input = ""
while user_input != "exit":
user_input = input("Enter 'exit' to quit: ")
print("You entered:", user_input)(code-box)
This loop calculates the sum of numbers from 1 to 10.
total = 0
number = 1
while number <= 10:
total += number
number += 1
print("Sum of numbers:", total)(code-box)
This loop prompts the user for a password until they enter the correct password ("secret" in this case).
password = "secret"
input_password = ""
while input_password != password:
input_password = input("Enter the password: ")
print("Access granted!")(code-box)
This loop generates and prints the Fibonacci sequence up to the first number greater than 100.
a, b = 0, 1
while a < 100:
print(a, end=" ")
a, b = b, a + b(code-box)
3. For Loop
The for loop allows us to iterate over a sequence (such as a list, tuple, string, or dictionary) and perform a certain action for each element in the sequence.
# Example of for loop with list
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)(code-box)
In this example, the for loop iterates over each element in the fruits list and prints its value.
This loop iterates through the numbers from 1 to 5 (inclusive) and prints each
for num in range(1, 6):
print(num)(code-box)
This loop iterates through the letters in the string "Python" and prints each letter.
word = "Python"
for letter in word:
print(letter)(code-box)
This loop demonstrates nested loops, where the inner loop runs completely for each iteration of the outer loop.
for i in range(3):
for j in range(2):
print(i, j)(code-box)
This loop uses the enumerate() function to iterate through a list while also keeping track of the index of each element.
colors = ["red", "green", "blue"]
for index, color in enumerate(colors):
print(f"Color {index + 1}: {color}")(code-box)
a. The range() Function
The range() function is often used with for loops to generate a sequence of numbers.
# Example of for loop with range function
for num in range(5):
print(num)(code-box)
In this example, the for loop will iterate five times, printing the numbers 0 to 4.
b. The enumerate() Function
The enumerate() function is used to loop over both the index and the value of elements in a sequence.
# Example of for loop with enumerate function
fruits = ["apple", "banana", "orange"]
for index, fruit in enumerate(fruits):
print("Index:", index, "Fruit:", fruit)(code-box)
In this example, the for loop will iterate over the fruits list and print both the index and the value of each element.
4. Control Flow Statements
Python provides control flow statements that allow us to modify the flow of loops and conditionals.
a. break Statement
The break statement is used to exit a loop prematurely, even if the loop's condition is still true.
# Example of break statement
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num == 3:
break
print(num)(code-box)
In this example, the for loop will exit when it encounters the number 3, and the loop will not continue to iterate through the rest of the numbers.
b. continue Statement
The continue statement is used to skip the current iteration of a loop and proceed to the next iteration.
# Example of continue statement
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num == 3:
continue
print(num)(code-box)
In this example, when the loop encounters the number 3, it will skip that iteration and continue with the next iteration, printing all other numbers except 3.
c. else Statement with Loops
The else statement in loops is executed when the loop completes all its iterations without encountering a break statement.
# Example of else statement with for loop
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print(num)
else:
print("Loop completed successfully.")(code-box)
In this example, after the for loop has completed all iterations, "Loop completed successfully." will be printed.
FUNCTIONS AND MODULES
Introduction to Functions
Functions are blocks of code that perform a specific task and can be reused throughout a program. They are a fundamental concept in programming, allowing us to break down complex tasks into smaller, manageable parts. Functions help improve code readability, reusability, and organization. In this chapter, we'll explore how to define and call functions in Python, as well as how to work with modules, which are collections of functions and variables.
1. Defining Functions
In Python, functions are defined using the def keyword, followed by the function name and a set of parentheses. Function parameters can be specified inside the parentheses.
# Example of a simple function
def greet():
print("Hello, world!")(code-box)
In the above example, we defined a function called greet() that prints "Hello, world!" when called.
a. Function Parameters
Functions can take input parameters, which allow us to pass data to the function for processing. Parameters are specified inside the parentheses when defining the function.
# Example of a function with parameters
def greet(name):
print("Hello, " + name + "!")(code-box)
In this example, we defined a function greet() that takes a parameter name. When called, the function will greet the person whose name is passed as an argument.
b. Return Statement
Functions can also return values using the return statement. The return statement allows a function to send a value back to the code that called it.
# Example of a function with a return statement
def add_numbers(a, b):
return a + b(code-box)
In this example, the function add_numbers() takes two parameters a and b and returns their sum.
2. Calling Functions
To call a function, simply write the function name followed by parentheses. If the function has parameters, pass the appropriate values inside the parentheses.
# Calling functions
greet() # Output: Hello, world!
greet("John") # Output: Hello, John!
result = add_numbers(5, 3)
print(result) # Output: 8(code-box)
3. Default Parameters
In Python, you can assign default values to function parameters. If a value is not passed for that parameter during the function call, the default value will be used.
# Function with default parameter
def greet(name="Guest"):
print("Hello, " + name + "!")(code-box)
In this example, if no name is provided during the function call, the default value "Guest" will be used.
4. Variable Scope
Variables defined inside a function have a local scope and are only accessible within that function. Variables defined outside any function have a global scope and can be accessed throughout the program.
# Variable scope example
def my_function():
x = 10 # Local variable
print(x)
x = 5 # Global variable
my_function() # Output: 10
print(x) # Output: 5(code-box)
Example of Functions
Addition Function:
def add_numbers(a, b):
result = a + b
return result(code-box)
This function takes two arguments, a and b, and returns their sum.
Factorial Function:
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)(code-box)
This function calculates the factorial of a given positive integer n.
String Reversal Function:
def reverse_string(input_string):
reversed_str = input_string[::-1]
return reversed_str(code-box)
This function reverses a given input string.
Prime Check Function:
def is_prime(number):
if number <= 1:
return False
for i in range(2, int(number**0.5) + 1):
if number % i == 0:
return False
return True(code-box)
List Sum Function:
def list_sum(numbers):
total = 0
for num in numbers:
total += num
return total(code-box)
This function calculates the sum of all elements in a given list of numbers.
5. Modules
Modules are files containing Python definitions and statements. They allow us to organize our code into separate files and reuse functions and variables across multiple programs. Python provides many built-in modules, and we can also create our own custom modules. For example : math, random, datetime, etc.
a. Importing Modules
To use a module, we need to import it into our Python script using the import keyword.
# Importing a module
import math
result = math.sqrt(16)
print(result) # Output: 4.0(code-box)
In this example, we imported the math module and used its sqrt() function to calculate the square root of 16.
b. Aliasing Modules
You can give a module a different name when importing it using the as keyword. This is known as aliasing.
# Aliasing a module
import math as m
result = m.sqrt(25)
print(result) # Output: 5.0(code-box)
In this example, we imported the math module as m and used m.sqrt() to calculate the square root of 25.
c. Importing Specific Functions
If you only need specific functions from a module, you can import them individually using the from keyword.
# Importing specific functions from a module
from math import sqrt, sin
result1 = sqrt(36)
result2 = sin(0.5)
print(result1) # Output: 6.0
print(result2) # Output: 0.479425538604203(code-box)
In this example, we imported the sqrt() and sin() functions directly from the math module.
d. Creating Custom Modules
Creating custom modules in Python is a way to organize your code into reusable components that can be imported and used in other Python programs. To create a custom module, you simply need to create a Python file with the functions, classes, or variables you want to include in the module. Here's a step-by-step guide on how to do it:
Create a new Python file: Start by creating a new file with a .py extension. Choose a descriptive name for your module, for example, mymodule.py.
Define functions or classes: Inside the new Python file, define the functions or classes that you want to include in the module. For example:To use the custom module in another script, simply import it like any other module.
# mymodule.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b(code-box)
Save the file: Make sure to save the file after defining your functions or classes.
Using the custom module: To use the custom module in another Python program, place the mymodule.py file in the same directory as your new program. Then, you can import and use the functions or classes as follows:
# main_program.py
import mymodule
result1 = mymodule.add(5, 3)
result2 = mymodule.subtract(10, 4)
print(result1) # Output: 8
print(result2) # Output: 6(code-box)
Import specific functions or classes: If you don't want to import the entire module, you can import specific functions or classes using the from keyword:
# main_program.py
from mymodule import add, subtract
result1 = add(5, 3)
result2 = subtract(10, 4)
print(result1) # Output: 8
print(result2) # Output: 6(code-box)
Including a __name__ check: If you have code in the module that should only run when the module is executed directly (not when it's imported by another module), you can use the if __name__ == "__main__": check. This is commonly used for testing or example code within the module.
# mymodule.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
if __name__ == "__main__":
print("This is a test code for mymodule.")
print(add(5, 3)) # Output: 8
print(subtract(10, 4)) # Output: 6(code-box)
When you execute the mymodule.py directly, it will run the code inside the if __name__ == "__main__": block. But when you import the module into another program, this block will not be executed.
e. The __name__ Variable
The __name__ variable is a built-in variable that contains the name of the current module. It is useful for distinguishing between a script that is being run directly and a module that is being imported.
# Example of __name__ variable
if __name__ == "__main__":
# Code here will only run when this script is executed directly
print("This script is being run directly.")
else:
# Code here will run when this script is imported as a module
print("This script is being imported.")(code-box)
f. Lambda is a keyword
In Python, lambda is a keyword that is used to create anonymous functions, also known as lambda functions. Unlike regular functions defined using the def keyword, lambda functions don't require a name. Instead, they are typically used for short, simple operations where defining a full function using def would be unnecessary or cumbersome.
The general syntax of a lambda function is as follows:
lambda arguments: expression(code-box)
Here's a breakdown of each part:
lambda: This is the keyword that tells Python we are creating a lambda function.
arguments: These are the input parameters to the function, similar to the arguments in a regular function defined with def.
expression: This is the single expression or operation that the lambda function will evaluate and return.
Lambda functions are particularly useful when you need a small, temporary function to be used as an argument for higher-order functions like map(), filter(), and reduce(), or when you want to define simple functions in a concise manner.
Here's an example of a lambda function that adds two numbers:
add = lambda x, y: x + y
result = add(3, 5)
print(result) # Output: 8(code-box)
Keep in mind that lambda functions are limited in what they can do compared to regular functions defined with def. They can only consist of a single expression, so they are best suited for simple tasks. For more complex operations, it's generally better to use regular named functions.
WORKING WITH LISTS AND DICTIONARIES
Introduction to Lists and Dictionaries
Lists and dictionaries are powerful data structures in Python that allow us to store and manipulate collections of data. Lists are ordered, mutable, and can contain elements of different data types. Dictionaries, on the other hand, are unordered collections of key-value pairs, providing efficient data retrieval based on keys. In this chapter, we'll explore lists and dictionaries in detail, learning how to create, access, modify, and perform various operations on them.
1. Lists
a. Creating Lists
In Python, lists are created using square brackets ([]) and can hold any number of elements, separated by commas.
# Example of creating a list
numbers = [1, 2, 3, 4, 5]
names = ["John", "Jane", "Bob"]
mixed_list = [1, "Hello", True](code-box)
In this example, we created three lists: numbers, names, and mixed_list.
b. Accessing Elements
You can access individual elements in a list using their index, starting from 0.
# Accessing elements in a list
numbers = [1, 2, 3, 4, 5]
first_element = numbers[0] # Output: 1
third_element = numbers[2] # Output: 3(code-box)
In this example, first_element will be assigned the value 1, and third_element will be assigned the value 3.
c. Slicing Lists
You can also use slicing to extract a portion of a list.
# Slicing a list
numbers = [1, 2, 3, 4, 5]
subset = numbers[1:4] # Output: [2, 3, 4](code-box)
In this example, subset will be assigned the list [2, 3, 4], which includes elements at indices 1, 2, and 3 (up to, but not including, index 4).
d. Modifying Lists
Lists are mutable, which means you can change their elements after creation.
# Modifying a list
numbers = [1, 2, 3, 4, 5]
numbers[0] = 10
numbers[3] = 40(code-box)
In this example, we modified the first element of numbers to 10 and the fourth element to 40.
e. List Operations
Lists support various operations, such as appending, extending, and removing elements.
# List operations
numbers = [1, 2, 3]
numbers.append(4) # Append an element to the end of the list
numbers.extend([5, 6]) # Extend the list with another list
numbers.remove(3) # Remove the first occurrence of an element(code-box)
After performing these operations, the number list will be [1, 2, 4, 5, 6].
f. List Comprehensions
List comprehensions provide a concise way to create lists using a single line of code.
# List comprehension
squares = [x**2 for x in range(1, 6)] # Output: [1, 4, 9, 16, 25](code-box)
In this example, squares is a list containing the squares of numbers from 1 to 5.
2. Dictionaries
a. Creating Dictionaries
In Python, dictionaries are created using curly braces ({}) and consist of key-value pairs separated by colons (:)
# Example of creating a dictionary
person = {"name": "John", "age": 25, "is_student": True}(code-box)
In this example, we created a dictionary person with keys "name", "age", and "is_student" and their respective values.
b. Accessing Values
To access values in a dictionary, use the keys as the index.
# Accessing values in a dictionary
person = {"name": "John", "age": 25}
name = person["name"] # Output: "John"
age = person["age"] # Output: 25(code-box)
In this example, name will be assigned the value "John", and age will be assigned the value 25.
c. Modifying Dictionaries
Dictionaries are mutable, so you can modify their values or add new key-value pairs.
# Modifying a dictionary
person = {"name": "John", "age": 25}
person["age"] = 26 # Modify the value for the key "age"
person["gender"] = "Male" # Add a new key-value pair(code-box)
After these modifications, the person dictionary will be {"name": "John", "age": 26, "gender": "Male"}.
d. Dictionary Operations
Dictionaries support several useful operations, such as checking if a key exists and deleting key-value pairs.
# Dictionary operations
person = {"name": "John", "age": 25}
is_student_present = "is_student" in person # Check if a key exists
del person["age"] # Delete a key-value pair(code-box)
After these operations, the person dictionary will be {"name": "John"}.
e. Looping through Dictionaries
You can loop through the keys or values in a dictionary using a for loop.
# Looping through dictionary keys
person = {"name": "John", "age": 25}
for key in person:
print(key) # Output: "name", "age"
# Looping through dictionary values
for value in person.values():
print(value) # Output: "John", 25
# Looping through key-value pairs
for key, value in person.items():
print(key, value) # Output: "name" "John", "age" 25(code-box)
FILE HANDLING IN PYTHON
Introduction to File Handling
File handling is an essential aspect of programming that allows us to interact with external files for reading and writing data. Python provides built-in functions and methods to work with files efficiently. In this chapter, we'll explore how to open, read, write, and close files in Python, as well as how to handle different file modes and exceptions.
The key function for working with files in Python is the open() function.
The open() function takes two parameters; filename, and mode.
There are four different methods (modes) for opening a file:
"r" - Read - Default value. Opens a file for reading, error if the file does not exist
"a" - Append - Opens a file for appending, creates the file if it does not exist
"w" - Write - Opens a file for writing, creates the file if it does not exist
"x" - Create - Creates the specified file, returns an error if the file exists
In addition you can specify if the file should be handled as binary or text mode
"t" - Text - Default value. Text mode
"b" - Binary - Binary mode (e.g. images)
1. Opening a File
To open a file in Python, we use the open() function, which takes two arguments: the file path and the mode in which the file should be opened.
# Example of opening a file
file_path = "data.txt"
file = open(file_path, "r")(code-box)
In this example, we opened a file named "data.txt" in read mode ("r"). The "r" mode indicates that the file is opened for reading. Other common file modes include "w" for writing, "a" for appending, and "x" for exclusive creation (fails if the file already exists).
2. Reading from a File
Once a file is open, we can read its contents using various methods. The two primary methods for reading data from a file are read() and readline().
a. The read() Method
The read() method reads the entire contents of the file as a single string.
# Reading from a file using read()
file_path = "data.txt"
with open(file_path, "r") as file:
contents = file.read()
print(contents)(code-box)
The with statement is used to automatically close the file after its suite (indented block of code) has been executed.
b. The readline() Method
The readline() method reads a single line from the file and moves the file pointer to the next line.
# Reading from a file using readline()
file_path = "data.txt"
with open(file_path, "r") as file:
line1 = file.readline()
line2 = file.readline()
print("Line 1:", line1)
print("Line 2:", line2)(code-box)
In this example, line1 will contain the first line of the file, and line2 will contain the second line.
c. Iterating through the File
We can also iterate through the lines of the file using a for loop.
# Iterating through the file
file_path = "data.txt"
with open(file_path, "r") as file:
for line in file:
print(line)(code-box)
In this example, each iteration of the loop will read a line from the file and print it.
3. Writing to a File
To write data to a file, we use the write() method. It is important to note that opening a file in write mode ("w") will overwrite its contents. If the file does not exist, a new file will be created.
# Writing to a file
file_path = "output.txt"
with open(file_path, "w") as file:
file.write("Hello, World!\n")
file.write("This is a new line.")(code-box)
In this example, we opened a file named "output.txt" in write mode and wrote two lines of text to it.
4. Appending to a File
To add new content to an existing file without overwriting it, we use the append mode ("a").
# Appending to a file
file_path = "data.txt"
with open(file_path, "a") as file:
file.write("This is a new line.\n")(code-box)
In this example, we opened the file "data.txt" in append mode and added a new line to the end of the file.
5. Handling Exceptions
When working with files, it is essential to handle exceptions that may occur, such as file not found errors or permission errors. We use a try-except block to handle exceptions gracefully.
# Handling file exceptions
file_path = "non_existent_file.txt"
try:
with open(file_path, "r") as file:
contents = file.read()
print(contents)
except FileNotFoundError:
print("File not found.")
except PermissionError:
print("Permission denied.")(code-box)
In this example, if the file "non_existent_file.txt" does not exist or cannot be opened for reading, the appropriate exception will be caught and an error message will be displayed.
6. Closing a File
It is crucial to close a file after performing read or write operations to release system resources. While using the with statement automatically closes the file when the block is exited, you can also close the file manually using the close() method.
# Manually closing a file
file_path = "data.txt"
file = open(file_path, "r")
contents = file.read()
file.close()(code-box)
7. Working with Binary Files
In addition to text files, Python can also handle binary files, such as images, audio files, and videos. To work with binary files, you need to open the file in binary mode ("rb" for reading and "wb" for writing).
# Working with binary files
image_path = "image.jpg"
output_image_path = "output_image.jpg"
with open(image_path, "rb") as file:
image_data = file.read()
with open(output_image_path, "wb") as output_file:
output_file.write(image_data)(code-box)
In this example, we read the binary data from an image file and write it to a new file.
8. What is JSON File ?
In the English language, a JSON file (JSON stands for JavaScript Object Notation) is a popular data interchange format used to store and exchange data between different programs and systems. It is easy for both humans to read and write, as well as for machines to parse and generate.
JSON files are primarily composed of key-value pairs, where each key is a string and its corresponding value can be a string, number, boolean, array, or another JSON object. The structure of JSON resembles the syntax of JavaScript object literals, which is why it's easy to work with in JavaScript-based environments.
9. Convert a JSON file to a Python file
To convert a JSON file to a Python file, you need to read the JSON data from the file and then parse it into a Python data structure. The Python data structure typically consists of dictionaries, lists, strings, numbers, booleans, and None. You can use the built-in json module in Python to accomplish this.
import json
# some JSON data :
x = '{ "name":"Pradip",
"age": 30,
"city":"New York",
"hobbies": ["reading", "gardening", "cooking"] }'
# parse x:
y = json.loads(x)
# the result is a Python dictionary:
print("Name : ", y["name"])
print("Age : ", y["age"])
print("City : ", y["city"])
print("Hobbies : ", y["hobbies"])(code-box)
10. Convert from Python to JSON
If you want to convert from a Python object to JSON, you can convert it into a JSON string by using the json.dumps() method.
import json
# This is Python object data :
x = { "name":"Pradip", "age":30, "city":"New York","hobbies": ["reading", "gardening", "cooking"]}
# convert into JSON data
y = json.dumps(x)
# the result is a Python dictionary:
print(y) (code-box)
OBJECT-ORIENTED PROGRAMMING (OOP)
Object-Oriented Programming (OOP) is a powerful programming paradigm that allows you to model real-world entities as objects. It provides a structured and modular approach to programming, making it easier to manage complex systems and promote code reusability. In this chapter, we'll delve into the core concepts of OOP, including classes, objects, inheritance, polymorphism, and encapsulation.
1. Introduction to OOP:
OOP is based on the concept of "objects," which are instances of user-defined data types called "classes." Each class defines a blueprint for creating objects with specific attributes (data members) and behaviors (methods). OOP provides several key principles that enhance software development:
a. Abstraction:
Abstraction allows you to represent complex real-world entities as simplified models. It focuses on essential features while hiding unnecessary details. Classes act as abstractions of objects, encapsulating their state and behavior.
b. Encapsulation:
Encapsulation is the concept that bundling data and methods which operate on that data within a single unit (class). It prevents direct access to internal data from outside the class, promoting data integrity and security.
c. Inheritance:
Inheritance enables the creation of a new class (derived class) from an existing class (base class). The derived class inherits the attributes and methods of the base class, allowing code reuse and extending functionality.
d. Polymorphism:
Polymorphism allows objects of different types classes to be treated as instances of a common base class. It enables you to use a single interface to represent various types of objects, promoting flexibility and extensibility.
2. Defining Classes and Creating Objects:
To define a class in Python, you have to use the class keyword followed by the class name and a colon. Within the class, you have to define data members (attributes) and methods (functions). Here's an example of a simple class representing a Point in 2D space:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, dx, dy):
self.x += dx
self.y += dy
def distance_from_origin(self):
return (self.x ** 2 + self.y ** 2) ** 0.5(code-box)
To create an object from this class, you use the class name followed by parentheses:
point1 = Point(3, 4)
point2 = Point(-2, 1)(code-box)
3. Constructor and Destructor:
The __init__() method in a class is called the constructor. It is automatically executed when an object is created and is used to initialize its attributes. You can also define a __del__() method, called the destructor, to perform cleanup operations when an object is about to be destroyed.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
print(f"Student {self.name} is created.")
def __del__(self):
print(f"Student {self.name} is being destroyed.")(code-box)
4. Inheritance:
Inheritance allows you to create a new class that inherits attributes and methods from an existing class. The new class is called a subclass, and the existing class is the superclass or base class. The subclass can extend or modify the behavior of the base class.
class Animal:
def __init__(self, species):
self.species = species
def make_sound(self):
pass # Placeholder method, to be defined in subclasses
class Dog(Animal):
def __init__(self, name):
super().__init__("Dog")
self.name = name
def make_sound(self):
return "Woof!"
class Cat(Animal):
def __init__(self, name):
super().__init__("Cat")
self.name = name
def make_sound(self):
return "Meow!"(code-box)
5. Polymorphism:
Polymorphism allows objects of different classes to be treated as instances of a common base class. This principle enables you to write generic code that can operate on different types of objects.
def animal_sound(animal):
return animal.make_sound()
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(animal_sound(dog)) # Output: Woof!
print(animal_sound(cat)) # Output: Meow!(code-box)
6. Access Modifiers:
In Python, access modifiers are used to control the visibility of class members (attributes and methods). The three main access modifiers are:
Public (default): Members accessible from anywhere outside the class.
Protected (single underscore _): Members accessible within the class and its subclasses.
Private (double underscore __): Members accessible only within the class.
class Car:
def __init__(self, make, model):
self.make = make
self._model = model
self.__mileage = 0
def drive(self, distance):
self.__mileage += distance
def get_mileage(self):
return self.__mileage(code-box)
7. Method Overriding:
Inheritance allows you to override methods in the derived class to provide a specific implementation. This feature enables the derived class to replace or extend the behavior of the base class.
class Vehicle:
def make_sound(self):
return "Vroom!"
class Bicycle(Vehicle):
def make_sound(self):
return "Ring ring!"(code-box)
8. Multiple Inheritance:
Python supports multiple inheritance, where a class can inherit from multiple base classes. This feature enables a class to combine attributes and methods from different sources.
class A:
def method_a(self):
return "Method A"
class B:
def method_b(self):
return "Method B"
class C(A, B):
pass
c = C()
print(c.method_a()) # Output: Method A
print(c.method_b()) # Output: Method B(code-box)
9. Class and Static Methods:
In addition to regular instance methods, Python allows you to define class methods and static methods.
a. Class Methods:
Class methods are bound to the class rather than the instance. They take the class as their first parameter (usually named cls) and are defined using the @classmethod decorator.
class MyClass:
count = 0
def __init__(self):
MyClass.count += 1
@classmethod
def get_count(cls):
return cls.count(code-box)
b. Static Methods:
Static methods do not depend on class or instance state and do not receive any implicit first parameter. They are defined using the @staticmethod decorator.
class MathUtility:
@staticmethod
def add(x, y):
return x + y(code-box)
10. Getter and Setter Methods:
Getter and setter methods provide control over the access and modification of class attributes. They allow you to perform additional actions when getting or setting attribute values.
class Circle:
def __init__(self, radius):
self._radius = radius
def get_radius(self):
return self._radius
def set_radius(self, radius):
if radius >= 0:
self._radius = radius
else:
raise ValueError("Radius cannot be negative.")(code-box)
11. Class Variables vs. Instance Variables:
Class variables are shared among all instances of a class and are accessed using the class name. Instance variables are unique to each instance and are accessed using self.
class Employee:
company = "ABC Corp" # Class variable
def __init__(self, name):
self.name = name # Instance variable(code-box)
12. Special Methods (Magic Methods):
Python provides special methods (also known as magic methods or dunder methods) that enable you to customize the behavior of classes and objects. These methods are called automatically in response to certain events.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"{self.title} by {self.author}"
def __eq__(self, other):
return self.title == other.title and self.author == other.author(code-box)
13. Composition:
Composition is a design principle that allows you to create complex objects by combining simpler objects as their components. It promotes code reuse and modular design.
class Engine:
def start(self):
return "Engine started."
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
return self.engine.start()(code-box)
14. Namespaces and Scope:
Namespaces are containers that hold identifiers (e.g., variable names, function names, class names). Python follows a specific order for resolving names based on their scope. The scope defines the region where a name is accessible.
# Global scope
x = 10
def my_function():
# Local scope
y = 5
print(x) # Accessing global variable within the function
print(y)
my_function()
print(x) # Global variable accessible outside the function
# print(y) # Will raise NameError, y is not accessible outside the function(code-box)
15. Inheritance vs. Composition:
Both inheritance and composition enable code reuse, but they serve different purposes. Inheritance models an "is-a" relationship, while composition models a "has-a" relationship.
Inheritance:
class Animal:
def make_sound(self):
pass
class Dog(Animal):
def make_sound(self):
return "Woof!"
Composition:
class Engine:
def start(self):
return "Engine started."
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
return self.engine.start()(code-box)
16. Class Hierarchy and Multiple Levels of Inheritance:
In complex systems, you can create a hierarchy of classes using multiple levels of inheritance. Subclasses can inherit from other subclasses, creating a chain of inheritance.
class Shape:
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
square = Square(5)
print(square.area()) # Output: 25(code-box)
17. Abstract Base Classes (ABCs):
In Python, Abstract Base Classes (ABCs) allow you to define abstract classes and abstract methods. Abstract classes cannot be instantiated directly, and their subclasses must implement all abstract methods.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2(code-box)
18. Overloading Operators:
Python allows you to overload operators using special methods. For example, you can define how two objects of your custom class should interact when using the +, -, *, and other operators.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
v1 = Vector(2, 3)
v2 = Vector(4, 1)
result_add = v1 + v2
result_sub = v1 - v2
result_mul = v1 * 3
print(result_add.x, result_add.y) # Output: 6, 4
print(result_sub.x, result_sub.y) # Output: -2, 2
print(result_mul.x, result_mul.y) # Output: 6, 9(code-box)
19. Real-World OOP Application:
Let's consider a real-world application of OOP: a simple banking system. We'll model customers, accounts, and transactions using classes and demonstrate how OOP facilitates modular design and code organization.
class Customer:
def __init__(self, name, email):
self.name = name
self.email = email
self.accounts = []
def add_account(self, account):
self.accounts.append(account)
def get_balance(self):
total_balance = 0
for account in self.accounts:
total_balance += account.get_balance()
return total_balance
class Account:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient funds.")
def get_balance(self):
return self.balance
# Creating objects
customer1 = Customer("Alice", "alice@email.com")
account1 = Account("A12345", 1000)
account2 = Account("B67890", 500)
# Linking customer to accounts
customer1.add_account(account1)
customer1.add_account(account2)
# Performing transactions
account1.deposit(500)
account2.withdraw(200)
# Checking balance
print(customer1.get_balance()) # Output: 1800(code-box)
20. Advantages of OOP:
OOP offers several advantages that make it a widely used programming paradigm:
Modularity: OOP encourages the development of modular and reusable code, making maintenance and updates more manageable.
Code Reusability: With inheritance and composition, you can reuse existing code to build new classes and objects, reducing redundant code.
Abstraction and Encapsulation: OOP allows you to represent complex entities as simplified models and hides internal details, enhancing data security and reducing complexity.
Flexibility: Polymorphism enables you to use the same interface to interact with different types of objects, promoting flexibility and adaptability.
Real-World Modeling: OOP's object-oriented approach maps well to real-world entities, making it intuitive and easy to understand.
21. Disadvantages of OOP:
While OOP offers many benefits, it also has some drawbacks:
Learning Curve: OOP concepts can be complex, especially for beginners, requiring a deeper understanding of abstraction, inheritance, and polymorphism.
Performance Overhead: OOP can introduce performance overhead due to the additional layers of abstraction and method calls.
Code Complexity: Poorly designed inheritance hierarchies can lead to complex and hard-to-maintain code.
Overuse of Inheritance: Overuse of inheritance can lead to tightly coupled classes, making it difficult to modify and extend code.
22. When to Use OOP:
OOP is best suited for projects that require modeling real-world entities, creating modular and reusable code, and managing complexity. It is commonly used in applications with graphical user interfaces, simulations, games, and large software systems.
ERROR HANDLING AND DEBUGGING
Error handling and debugging are crucial skills for any programmer. Errors are a natural part of the development process, and effective error handling helps identify and resolve issues, ensuring that programs run smoothly and as expected. In this chapter, we'll explore common types of errors, methods of handling errors in Python, and various debugging techniques to diagnose and fix problems in your code.
1. Types of Errors:
In Python, errors can be categorized into three main types:
a. Syntax Errors
Syntax errors occur when the code violates the rules of the Python language. These errors are raised during the parsing of the code and prevent the program from running. Common syntax errors include missing colons, mismatched parentheses, or incorrect indentation.
# Syntax error examples
if x > 5 # Missing colon at the end of the 'if' statement
print("Hello, world!") # Missing parentheses for the 'print' function(code-box)
b. Runtime Errors (Exceptions):
Runtime errors, also known as exceptions, occur during the execution of a program. They are caused by invalid input, unexpected conditions, or issues with external resources. Common runtime errors include ZeroDivisionError, TypeError, IndexError, and FileNotFoundError.
# Runtime error examples
result = 10 / 0 # ZeroDivisionError: division by zero
text = "Hello"
number = int(text) # ValueError: invalid literal for int() with base 10: 'Hello'(code-box)
Logical errors occur when the code runs without raising any errors, but it produces incorrect results. These errors are often more challenging to identify and fix because the program runs without any apparent issues.
# Logical error example
def calculate_area(width, height):
return width * length # Typo: should be 'height' instead of 'length'(code-box)
2. Handling Exceptions with try-except:
Python provides a powerful mechanism to handle exceptions using the try-except block. This construct allows you to catch exceptions and handle them gracefully, preventing the program from terminating abruptly.
try:
x = int(input("Enter a number: "))
result = 10 / x
print("Result:", result)
except ZeroDivisionError:
print("Cannot divide by zero.")
except ValueError:
print("Invalid input. Please enter a valid number.")(code-box)
You can have multiple except blocks to handle different types of exceptions, and a single try block can be associated with multiple except blocks.
3. Handling Multiple Exceptions:
Python also allows you to handle multiple exceptions in a single except block using parentheses.
try:
# Some code that may raise exceptions
except (ZeroDivisionError, ValueError, FileNotFoundError) as e:
# Handle the exceptions here(code-box)
4. Handling All Exceptions with except:
If you want to handle all types of exceptions in one block, you can use the generic except clause. However, it is generally recommended to handle specific exceptions whenever possible to provide targeted error messages and avoid hiding unexpected issues.
try:
# Some code that may raise exceptions
except Exception as e:
# Handle all exceptions here(code-box)
5. else and finally Blocks:
The else block is executed when the try block runs successfully without raising any exceptions. It is often used to perform actions that should occur if no exceptions occur.
The finally block is executed regardless of whether an exception was raised or not. It is commonly used for cleanup tasks, such as closing files or releasing resources.
try:
# Some code that may raise exceptions
except SomeException as e:
# Handle the specific exception
else:
# Code to be executed if no exception occurs
finally:
# Cleanup code that runs regardless of exceptions(code-box)
6. Raising Exceptions with raise:
You can manually raise exceptions using the raise keyword. This is useful when youencounter situations that require specific error handling based on your program's logic.
def divide(x, y):
if y == 0:
raise ValueError("Cannot divide by zero.")
return x / y
try:
result = divide(10, 0)
except ValueError as e:
print(e) # Output: "Cannot divide by zero."(code-box)
7. Assertion:
Assertions are statements that check whether certain conditions are true during the execution of the program. If the condition is false, an AssertionError is raised, indicating a bug or an unexpected situation.
def divide(x, y):
assert y != 0, "Cannot divide by zero."
return x / y
try:
result = divide(10, 0)
except AssertionError as e:
print(e) # Output: "Cannot divide by zero."(code-box)
8. Logging:
Logging is a technique used to record events and messages during the execution of a program. Python's logging module allows you to create logs of different levels (e.g., info, warning, error) to help diagnose and troubleshoot issues in your code.
import logging
logging.basicConfig(filename="app.log", level=logging.ERROR,
format="%(asctime)s - %(levelname)s - %(message)s")
try:
# Some code that may raise exceptions
except Exception as e:
logging.error(f"An error occurred: {e}")(code-box)
9. Debugging Techniques:
Debugging is the process of finding and fixing errors in your code. Python provides several tools and techniques to help you debug your programs effectively.
a. Print Statements:
Adding print statements to your code can help you understand the flow of execution and the values of variables at different points in the program
def divide(x, y):
print(f"Dividing {x} by {y}")
return x / y
result = divide(10, 0)(code-box)
b. Debugging with pdb:
Python's built-in debugger, pdb (Python Debugger), allows you to interactively step through your code, inspect variables, and trace the execution flow.
import pdb
def divide(x, y):
pdb.set_trace()
return x / y
result = divide(10, 0)(code-box)
c. Using IDE Debugger:
Integrated Development Environments (IDEs) like PyCharm, Visual Studio Code, and others come with built-in debuggers that provide advanced debugging features like breakpoints, variable inspection, and step-by-step execution.
d. Exception Stack Trace:
When an exception occurs, Python provides a traceback or stack trace that shows the sequence of function calls leading to the error. It can help you pinpoint the exact location of the error.
def func1():
func2()
def func2():
raise ValueError("Error in func2")
try:
func1()
except ValueError as e:
print("Exception stack trace:")
print(e)(code-box)
10. Debugging Tips:
a. Start Small:
If you encounter an error, try to reproduce it in the simplest possible scenario. This helps isolate the issue and narrows down the potential causes.
b. Divide and Conquer:
Split your code into smaller sections and test each section separately. This makes it easier to identify which part of the code is causing the problem.
c. Read Error Messages Carefully:
Error messages provide valuable information about what went wrong. Pay attention to the error type, line number, and the accompanying message.
d. Use Version Control:
Using version control systems like Git allows you to revert to previous working versions of your code if things go wrong during debugging.
e. Peer Review:
Sometimes, a fresh pair of eyes can catch mistakes you might have overlooked. Consider asking a colleague to review your code.
11. Unit Testing:
Unit testing is the practice of testing individual units (functions, methods, classes) of your code to ensure they work as expected. Python's unittest module provides a framework for writing and executing unit tests.
import unittest
def add(x, y):
return x + y
class TestAddition(unittest.TestCase):
def test_addition(self):
result = add(3, 5)
self.assertEqual(result, 8)
if __name__ == "__main__":
unittest.main()(code-box)
12. Exception Handling Best Practices:
a. Be Specific with Exception Handling:
Avoid using generic except blocks without specifying the type of exceptions you're handling. This can lead to hiding unexpected errors and make debugging more difficult.
b. Keep Error Messages Informative:
Provide clear and meaningful error messages that help users understand the issue and guide them on how to resolve it.
c. Use Logging Wisely:
Use the logging module to log relevant information at appropriate log levels. This helps you analyze errors and track the program's behavior.
d. Handle Exceptions at the Right Level:
Handle exceptions at the level where you can take appropriate corrective actions. Avoid handling exceptions too early, as it may lead to incomplete or incorrect error recovery.
e. Follow the Principle of EAFP:
EAFP stands for "Easier to Ask for Forgiveness than Permission." It means it's often better to try an operation and handle the exception if it fails, rather than checking for preconditions before performing the operation.
Python Standard Library
The Python Standard Library is a rich collection of modules and packages that come bundled with Python. It provides a wide range of functionalities to facilitate various programming tasks, making Python a versatile and powerful programming language. In this chapter, we'll explore some of the most commonly used modules and packages from the Python Standard Library, including those for file handling, data manipulation, networking, and more.
1. OS Module:
The os module provides a way to interact with the operating system, allowing you to perform various tasks such as file and directory operations, environment management, and more.
a. File and Directory Operations:
import os
# Get the current working directory
current_directory = os.getcwd()
# List files and directories in a directory
files = os.listdir(current_directory)
# Create a new directory
new_directory = "new_dir"
os.mkdir(new_directory)
# Rename a file or directory
os.rename("old_file.txt", "new_file.txt")
# Remove a file or directory
os.remove("file_to_delete.txt")
os.rmdir("directory_to_delete")(code-box)
b. Environment Variables:
import os
# Get the value of an environment variable
python_path = os.environ.get("PYTHONPATH")
# Set an environment variable
os.environ["MY_VARIABLE"] = "my_value"(code-box)
2. sys Module:
The sys module provides access to various system-specific parameters and functions related to Python's runtime environment
import sys
# Get the Python version
python_version = sys.version
# Get the command-line arguments passed to the script
arguments = sys.argv
# Exit the program with a status code
sys.exit(1)(code-box)
3. datetime Module:
The datetime module offers classes for manipulating dates and times.
from datetime import datetime, timedelta
# Get the current date and time
now = datetime.now()
# Create a specific date and time
specific_date = datetime(2023, 7, 1, 12, 30, 0)
# Time difference calculation
time_difference = specific_date - now
# Add or subtract time intervals
future_date = now + timedelta(days=7)(code-box)
4. math Module:
The math module provides various mathematical functions and constants.
import math
# Calculate the square root
square_root = math.sqrt(25)
# Calculate the value of pi
pi_value = math.pi
# Calculate the sine of an angle
angle = math.radians(45)
sine_value = math.sin(angle)(code-box)
5. random Module:
The random module is used to generate random numbers and perform random selections.
import random
# Generate a random integer between two values
random_integer = random.randint(1, 10)
# Generate a random float between 0 and 1
random_float = random.random()
# Randomly shuffle a list
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)(code-box)
6. json Module:
The json module provides functions for working with JSON data.
import json
# Convert a Python object to a JSON string
data = {"name": "John", "age": 30}
json_string = json.dumps(data)
# Convert a JSON string to a Python object
json_data = '{"name": "John", "age": 30}'
python_object = json.loads(json_data)(code-box)
7. csv Module:
The csv module is used for reading and writing CSV (Comma Separated Values) files.
import csv
# Reading from a CSV file
with open("data.csv", newline="") as csvfile:
reader = csv.reader(csvfile)
for row in reader:
print(row)
# Writing to a CSV file
data = [["Name", "Age"], ["John", 30], ["Alice", 25]]
with open("data.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerows(data)(code-box)
8. requests Module:
The requests module allows you to send HTTP requests and interact with web APIs.
import requests
# Sending a GET request
response = requests.get("https://api.example.com/data")
# Accessing response data
data = response.json()
# Sending a POST request with data
data_to_send = {"name": "John", "age": 30}
response = requests.post("https://api.example.com/submit", data=data_to_send)(code-box)
9. socket Module:
The socket module provides access to low-level networking functionality, allowing you to create and interact with network sockets.
import socket
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to a remote server
host = "www.example.com"
port = 80
s.connect((host, port))
# Send data to the server
message = "GET / HTTP/1.1\r\n\r\n"
s.sendall(message.encode())
# Receive data from the server
response = s.recv(1024)
# Close the socket
s.close()(code-box)
10. subprocess Module:
The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
import subprocess
# Execute a command and capture its output
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)(code-box)
11. pathlib Module:
The pathlib module provides a more object-oriented approach to working with file paths and directories.
from pathlib import Path
# Create a Path object
file_path = Path("my_folder/my_file.txt")
# Check if a path exists
if file_path.exists():
print("File exists!")
# Get the file extension
file_extension = file_path.suffix(code-box)
12. timeit Module:
The timeit module is used to measure the execution time of small bits of Python code.
import timeit
# Measure the execution time of a function
execution_time = timeit.timeit("my_function()", globals=globals(), number=1000)(code-box)
13. collections Module:
The collections module provides alternative data structures to the built-in Python data types, including namedtuple, deque, Counter, and more.
from collections import namedtuple, defaultdict
# Creating a namedtuple
Person = namedtuple("Person", ["name", "age", "city"])
person = Person("John", 30, "New York")
# Creating a defaultdict
word_freq = defaultdict(int)
for word in text.split():
word_freq[word] += 1(code-box)
14. itertools Module:
The itertools module offers various functions for working with iterators and combinatorial iterators.
import itertools
# Creating permutations
letters = ["A", "B", "C"]
permutations = itertools.permutations(letters, 2)
# Creating combinations
combinations = itertools.combinations(letters, 2)
# Creating infinite iterators
counter = itertools.count(start=1, step=2)
cycle = itertools.cycle([1, 2, 3])(code-box)
15. unittest Module:
The unittest module provides a testing framework for writing and running unit tests.
import unittest
# Creating a test case
class MyTestCase(unittest.TestCase):
def test_addition(self):
result = add(3, 5)
self.assertEqual(result, 8)
if __name__ == "__main__":
unittest.main()(code-box)