Python notes and useful links

Python 

What is python? 

Python is a type of computer language that lets people talk to computers and tell them what to do. Imagine it as a set of easy-to-learn instructions that help you build things like websites, games, or apps. It’s popular because it’s simple to use, even for beginners, but still powerful enough for experts to create amazing things. 

Basic Data Structures in Python 

Python has several built-in data structures that allow you to organize and manipulate data effectively. These include Lists, Tuples, Sets, and Dictionaries. 

 

1. Lists 

A list is an ordered, mutable (changeable) collection of elements. Lists can store different data types. 

Key Features: 

  • Elements are ordered. 

  • Duplicates are allowed. 

  • Elements can be added, removed, or updated. 

Syntax: 

my_list = [1, 2, 3, "apple", 5.5] 
 

# Accessing elements 
print(my_list[0])   

Output: 1 
 
# Adding elements 
my_list.append("banana") 
print(my_list)   

Output: [1, 2, 3, "apple", 5.5, "banana"] 
 
# Removing elements 
my_list.remove(3) 
print(my_list 

Output: [1, 2, "apple", 5.5, "banana"] 
 
# Slicing 
print(my_list[1:4])   

Output: [2, "apple", 5.5] 
 
# Length of list 
print(len(my_list))   

Output: 5 
 

2. Tuples 

A tuple is an ordered, immutable (unchangeable) collection of elements. It is like a list but cannot be modified after creation. 

Key Features: 

  • Elements are ordered. 

  • Duplicates are allowed. 

  • Faster than lists due to immutability. 

Syntax: 

my_tuple = (1, 2, 3, "apple", 5.5) 
 

Common Operations: 

# Accessing elements 
print(my_tuple[0])   

 

Output: 1 
 
# Slicing 
print(my_tuple[1:3])   

 

Output: (2, 3) 
 
# Length of tuple 
print(len(my_tuple))   

 

Output: 5 
 
# Converting to a list 
mutable_list = list(my_tuple) 
mutable_list.append("banana") 
print(mutable_list)   

 

Output: [1, 2, 3, "apple", 5.5, "banana"] 
 

 

3. Sets 

A set is an unordered, mutable collection of unique elements. 

Key Features: 

  • Elements are unordered. 

  • No duplicates are allowed. 

  • Commonly used for operations like union, intersection, and difference. 

Syntax: 

my_set = {1, 2, 3, "apple"} 
 

Common Operations: 

# Adding elements 
my_set.add("banana") 
print(my_set)   

 

Output: {1, 2, 3, "apple", "banana"} 
 
# Removing elements 
my_set.remove(3) 
print(my_set)   

 

 Output: {1, 2, "apple", "banana"} 
 
# Union 
set2 = {3, 4, 5} 
print(my_set | set2)   

 

Output: {1, 2, 3, 4, 5, "apple", "banana"} 
 
# Intersection 
print(my_set & set2 

  

Output: {3} 
 
# Difference 
print(my_set - set2)   

 

Output: {1, 2, "apple", "banana"} 
 

 

4. Dictionaries 

A dictionary is a collection of key-value pairs where each key is unique. 

Key Features: 

  • Elements are unordered. 

  • Keys must be unique and immutable (e.g., strings, numbers, tuples). 

  • Values can be any data type. 

Syntax: 

my_dict = {"name": "Alice", "age": 25, "city": "New York"} 
 

Common Operations: 

# Accessing values 
print(my_dict["name"])  

 

Output: Alice 
 
# Adding a new key-value pair 
my_dict["job"] = "Engineer" 
print(my_dict)   

 

Output: {"name": "Alice", "age": 25, "city": "New York", "job": "Engineer"} 
 
# Updating a value 
my_dict["age"] = 26 
print(my_dict) 

 

Output: {"name": "Alice", "age": 26, "city": "New York", "job": "Engineer"} 
 
# Removing a key-value pair 
del my_dict["city"] 
print(my_dict 

  

 Output: {"name": "Alice", "age": 26, "job": "Engineer"} 
 
# Iterating over keys and values 
for key, value in my_dict.items(): 
    print(key, ":", value) 
 

Output: 
name : Alice 
age : 26 
job : Engineer 
 

 

Comparison of Data Structures 

Feature 

List 

Tuple 

Set 

Dictionary 

Ordered 

Yes 

Yes 

No 

No 

Mutable 

Yes 

No 

Yes 

Yes 

Allows Duplicates 

Yes 

Yes 

No 

Keys: No, Values: Yes 

Use Case 

General-purpose 

Fixed collections 

Unique elements 

Key-value pairs 

Each structure has its own strengths, making it suitable for specific tasks in Python programming. 

 

Data Types in Python 

  1. Numeric Types: 

  1. int: Whole numbers (e.g., 10, -5). 

  1. float: Numbers with decimals (e.g., 3.14, -0.1). 

  1. complex: Numbers with real and imaginary parts (e.g., 3 + 4j). 

  1. Text Type: 

  1. str: Strings, or sequences of characters (e.g., "Hello, World!", 'Python'). 

  1. Boolean Type: 

  1. bool: True or False values (e.g., True, False). 

  1. Sequence Types: 

  1. list: Ordered and mutable collections (e.g., [1, 2, 3], ["apple", "banana"]). 

  1. tuple: Ordered and immutable collections (e.g., (1, 2, 3), ("a", "b")). 

  1. range: A sequence of numbers (e.g., range(0, 5)). 

  1. Mapping Type: 

  1. dict: Key-value pairs (e.g., {"name": "Alice", "age": 25}). 

 

  1. Set Types: 

  1. set: Unordered collections of unique items (e.g., {1, 2, 3}). 

  1. frozenset: Immutable version of a set. 

  1. Binary Types: 

  1. bytes, bytearray, memoryview: For binary data (e.g., images, files). 

  1. None Type: 

  1. NoneType: Represents no value or a null value (None). 

 

Variables in Python 

  • A variable is a name used to store data. You can assign a value to a variable using the = operator. 

  • Variable names should start with a letter or an underscore (_) and can’t start with a number. 

  • Example: 

                       # Assigning values to variables 
 

name = "John"      # String 
age = 25           # Integer 
height = 5.9       # Float 
is_student = True  # Boolean 
# Using variables 
print("Name:", name) 
print("Age:", age) 
print("Height:", height) 
print("Is Student?", is_student) 

                      Output:  

Name: John 

Age: 25 

Height: 5.9 

Is Student? True 

  

Basic Operators in Python 

        Operators in Python are symbols or keywords that perform operations on values or variables. These are divided into several categories: 

1. Arithmetic Operators 

Used to perform mathematical operations. 

 

Operator 

Description 

Example 

Output 

+ 

Addition 

5 + 3 

8 

- 

Subtraction 

5 - 3 

2 

* 

Multiplication 

5 * 3 

15 

/ 

Division (float result) 

5 / 2 

2.5 

// 

Floor Division (integer result) 

5 // 2 

2 

% 

Modulus (remainder) 

5 % 2 

1 

** 

Exponentiation (power) 

5 ** 2 

25 

2. Comparison (Relational) Operators 

Used to compare two values. 

 

Operator 

Description 

Example 

Output 

== 

Equal to 

5 == 3 

FALSE 

!= 

Not equal to 

5 != 3 

TRUE 

> 

Greater than 

5 > 3 

TRUE 

< 

Less than 

5 < 3 

FALSE 

>= 

Greater than or equal to 

5 >= 3 

TRUE 

<= 

Less than or equal to 

5 <= 3 

FALSE 

 3. Logical Operators 

Used to combine conditional statements. 

Operator 

Description 

Example 

Output 

and 

True if both are True 

True and False 

FALSE 

or 

True if at least one is True 

True or False 

TRUE 

not 

Negates the condition 

not True 

FALSE 

 

4. Assignment Operators 

Used to assign values to variables. 

Operator 

Description 

Example 

Equivalent 

= 

Assign 

x = 5 

x = 5 

+= 

Add and assign 

x += 3 

x = x + 3 

-= 

Subtract and assign 

x -= 3 

x = x - 3 

*= 

Multiply and assign 

x *= 3 

x = x * 3 

/= 

Divide and assign 

x /= 3 

x = x / 3 

%= 

Modulus and assign 

x %= 3 

x = x % 3 

**= 

Exponent and assign 

x **= 2 

x = x ** 2 

//= 

Floor divide and assign 

x //= 3 

x = x // 3 

 

5. Bitwise Operators 

Used for operations on binary numbers. 

Operator 

Description 

Example 

Output (Binary) 

& 

AND 

5 & 3 

1 (0101 & 0011) 

` 

` 

OR 

`5 

^ 

XOR 

5 ^ 3 

6 (0101 ^ 0011) 

~ 

NOT 

~5 

-6 (Inverts bits) 

<< 

Left shift 

5 << 1 

10 (1010) 

>> 

Right shift 

5 >> 1 

2 (0010) 

 

6. Membership Operators 

Used to check for membership in sequences like lists, strings, etc. 

Operator 

Description 

Example 

Output 

in 

True if value is in sequence 

'a' in 'apple' 

True 

not in 

True if value is not in seq. 

'x' not in 'apple' 

True 

 

7. Identity Operators 

Used to compare memory locations of two objects. 

Operator 

Description 

Example 

Output 

is 

True if objects are same 

x is y 

False 

is not 

True if objects are not same 

x is not y 

True 

 

Example Code: 

# Arithmetic Operators 
a = 10 
b = 3 
print("Addition:", a + b)   

 

Output: 13 

 
print("Exponent:", a ** b) 

 

Output: 1000 
 
# Comparison 
print("Is a > b?", a > b)   

Output: True 
 
# Logical Operators 
print("a > 5 and b < 5:", a > 5 and b < 5)   

 

Output: True 
 
# Membership 
my_list = [1, 2, 3] 
print("2 in my_list:", 2 in my_list)   

 

Output: True 

 

Functions in Python 

Functions are reusable blocks of code that perform specific tasks. They make programs easier to manage, understand, and debug. 

1. Defining and Calling Functions 

Defining a Function 

  • Use the def keyword followed by the function name and parentheses (). 

  • Write the function's code inside an indented block. 

 

Example: 

 

def greet(): 
    print("Hello, World!") 
 

Calling a Function 

  • To run the function, use its name followed by (). 

 

greet()   

 

Output: Hello, World! 
 

 

2. Arguments and Return Values 

Arguments 

  • Functions can accept inputs, called arguments, which are passed inside the parentheses. 

  • You can have required arguments, default arguments, and variable-length arguments. 

 

Example 

def greet_person(name): 
    print(f"Hello, {name}!") 
greet_person("Alice")   

 

Output: Hello, Alice! 
 

Default Arguments 

  • Provide default values if no arguments are given. 

 

 

Example: 

def greet_person(name="Guest"): 
    print(f"Hello, {name}!") 

 
greet_person()   

Output: Hello, Guest! 
 

Return Values 

  • Functions can return a result using the return keyword. 

 

def add(a, b): 
    return a + b 
 
result = add(5, 3) 
print(result)   

 

Output: 8 
 

Variable-Length Arguments 

  • Use *args for positional arguments and **kwargs for keyword arguments. 

 

def print_numbers(*args): 
    for number in args: 
        print(number) 
 
print_numbers(1, 2, 3, 4) 
Output: 
1 
2 
3 
4 
 

 

3. Local and Global Variables 

Local Variables 

  • Variables declared inside a function are local to that function and cannot be accessed outside it. 

 

def example(): 
    x = 10  # Local variable 
    print(x) 
 
example() 
# print(x)  # Error: NameError: name 'x' is not defined 
 

Global Variables 

  • Variables declared outside any function are global and can be accessed anywhere in the program. 

 

y = 20  # Global variable 
 
def example(): 
    print(y) 
 
example()   

Output: 20 
 

Modifying Global Variables 

  • To modify a global variable inside a function, use the global keyword. 

 

z = 30  # Global variable 
 
def modify_global(): 
    global z 
    z += 10 
    print(z) 
 
modify_global( 

  

Output: 40 
 

print(z)         

Output: 40 
 

 

Example: Combining Concepts 

# Function with arguments and return value 
def calculate_area(length, width): 
    return length * width 
 
# Function using global and local variables 
pi = 3.14  # Global variable 
 
def calculate_circle_area(radius): 
    area = pi * radius ** 2  # Local variable 
    return area 
 
# Calling the functions 
rect_area = calculate_area(5, 3) 
circle_area = calculate_circle_area(4) 
 
print(f"Rectangle Area: {rect_area}")   

Output: Rectangle Area: 15 

 
print(f"Circle Area: {circle_area}")   

Output: Circle Area: 50.24 
 

 

Best Practices for Functions 

  1. Use Descriptive Names: Function names should describe their purpose (e.g., calculate_sum). 

  1. Keep Functions Short: Functions should do one thing and do it well. 

  1. Avoid Too Many Global Variables: Prefer local variables for better code isolation and debugging. 

  1. Use Default and Keyword Arguments: Make functions flexible and user-friendly. 

  1. Document Functions: Use comments or docstrings to describe what the function does. 

Functions are a cornerstone of Python programming, allowing you to write modular, reusable, and efficient code! 

 

Modules and Packages in Python 

Modules and packages allow you to organize and reuse code efficiently. They are essential for creating structured and maintainable Python programs. 

1. Importing Modules 

A module is a Python file containing definitions (functions, variables, and classes) that can be reused in other programs. 

Importing a Module 

  • Use the import keyword to include a module. 

import math  # Import the math module 
print(math.sqrt(16))   

Output: 4.0 
 

Import Specific Functions or Variables 

  • Import only what you need using from. 

from math import sqrt 
print(sqrt(25))   

Output: 5.0 
 

Import with Alias 

  • Use as to give a module or function a shorter name. 

 

import math as m 
print(m.pi)   

Output: 3.141592653589793 
 

Import Everything 

  • Import all contents of a module (not recommended due to potential conflicts). 

from math import * 
print(sin(0))   

Output: 0.0 
 

 

2. Exploring the Standard Library 

The Python Standard Library is a collection of modules that comes pre-installed with Python. It provides a wide range of functionalities. 

Commonly Used Modules 

  1. math: For mathematical operations. 

import math 
print(math.factorial(5))   

Output: 120 
 

  1. random: For generating random numbers. 

import random 
print(random.randint(1, 10))   

Output: Random number between 1 and 10 
 

  1. datetime: For date and time manipulation. 

from datetime import datetime 
print(datetime.now())  

Output: Current date and time 
 

  1. os: For interacting with the operating system. 

import os 
print(os.getcwd())   

 

Output: Current working directory 
 

  1. sys: For interacting with the Python interpreter. 

import sys 
print(sys.version) 

 

Output: Python version 
 

  1. json: For working with JSON data. 

import json 
data = '{"name": "Alice", "age": 25}' 
parsed = json.loads(data) 
print(parsed["name"])   

Output: Alice 
 

  1. re: For working with regular expressions. 

import re 
match = re.search(r'\d+', "The answer is 42") 
print(match.group())   

Output: 42 
 

 

3. Writing Your Own Modules 

You can create your own module by saving a Python script (.py) file and importing it into another script. 

Example: 

my_module.py: 

def greet(name): 
    return f"Hello, {name}!" 
 

main.py: 

import my_module 
print(my_module.greet("Alice"))  

Output: Hello, Alice! 
 

 

4. Packages 

A package is a collection of modules organized in directories. Packages are identified by the presence of an __init__.py file. 

Example of a Package Structure: 

my_package/ 
    __init__.py 
    module1.py 
    module2.py 
 

Importing a Package: 

from my_package import module1 
module1.function_name() 
 

 

5. Installing Third-Party Packages 

Use the pip tool to install third-party libraries from the Python Package Index (PyPI). 

Example: 

pip install requests 
 

Using the Installed Package: 

import requests 
response = requests.get("https://api.github.com") 
print(response.status_code)  # Output: 200 
 

 

6. Best Practices for Modules and Packages 

  1. Use Clear and Descriptive Names: Module and package names should be meaningful and easy to understand. 

  1. Avoid Circular Imports: Structure your modules to avoid interdependencies. 

  1. Organize Code: Use packages to group related modules. 

  1. Keep Functions Small and Modular: Each module should focus on a specific functionality. 

Modules and packages are powerful tools in Python that allow you to write modular and maintainable code while leveraging the vast ecosystem of pre-existing tools! 

Lambda Functions in Python 

A lambda function is a small, anonymous function defined using the lambda keyword. It is often used for short, throwaway functions where a full function definition would be unnecessary. 

 

1. Syntax of Lambda Functions 

 

lambda arguments: expression 
 

  • lambda: Declares the lambda function. 

  • arguments: Inputs to the function (can be zero or more arguments). 

  • expression: A single expression that is evaluated and returned. 

Example: 

square = lambda x: x ** 2 
print(square(5))   

 

Output: 25 
 

 

File Handling in Python 

File handling allows you to work with files for reading, writing, and manipulating data. Python provides simple and efficient tools for managing files and directories. 

 

1. Reading and Writing Files 

Opening a File 

Use the open() function to open a file. 

python 

CopyEdit 

file = open("filename.txt", mode) 
 

  • filename: Name of the file (with its path if not in the current directory). 

  • mode: 

  • 'r': Read (default). 

  • 'w': Write (overwrites the file). 

  • 'a': Append (adds to the file without overwriting). 

  • 'rb'/'wb': Binary mode for reading/writing binary files. 

Reading a File 

  • read(): Reads the entire content. 

  • readline(): Reads one line at a time. 

  • readlines(): Reads all lines into a list. 

 

# Reading a file 
with open("example.txt", "r") as file: 
    content = file.read() 
    print(content) 
 
# Reading line by line 
with open("example.txt", "r") as file: 
    for line in file: 
        print(line.strip()) 
 

Writing to a File 

  • write(): Writes a string to the file. 

  • writelines(): Writes a list of strings to the file. 

 

# Writing to a file 
with open("example.txt", "w") as file: 
    file.write("Hello, World!\n") 
    file.write("This is Python file handling.") 
 
# Appending to a file 
with open("example.txt", "a") as file: 
    file.write("\nAppending another line.") 
 

 

2. Working with Directories 

The os module provides tools to interact with the file system. 

Listing Files 

import os 
files = os.listdir(".")  # Lists all files in the current directory 
print(files) 
 

Creating a Directory 

os.mkdir("new_directory")  # Creates a new directory 
 

Checking if a File/Directory Exists 

print(os.path.exists("example.txt"))  # Output: True/False 
 

Removing a File or Directory 

 

os.remove("example.txt")  # Deletes a file 
os.rmdir("new_directory")  # Deletes an empty directory 
 

Renaming a File or Directory 

 

os.rename("old_name.txt", "new_name.txt") 
 

Navigating Directories 

 

os.chdir("new_directory")  # Changes the current working directory 
print(os.getcwd())         # Prints the current working directory 
 

 

3. Exception Handling during I/O 

File operations can raise exceptions (e.g., if the file doesn’t exist). Use try...except to handle these cases gracefully. 

Example: Handling File Not Found 

try: 
    with open("non_existent_file.txt", "r") as file: 
        content = file.read() 
        print(content) 
except FileNotFoundError: 
    print("File not found. Please check the file name or path.") 
 

Example: Handling Permission Errors 

try: 
    with open("/restricted_file.txt", "w") as file: 
        file.write("Trying to write.") 
except PermissionError: 
    print("You do not have permission to write to this file.") 
 

Handling Multiple Exceptions 

try: 
    with open("example.txt", "r") as file: 
        content = file.read() 
        print(content) 
except FileNotFoundError: 
    print("File does not exist.") 
except PermissionError: 
    print("You do not have permission to access the file.") 
finally: 
    print("File operation completed.") 
 

 

Best Practices 

  1. Use with Statement: Automatically closes the file after operations. 

 

with open("example.txt", "r") as file: 
    content = file.read() 
 

  1. Check File/Directory Existence: Use os.path.exists() to avoid unnecessary errors. 

  1. Handle Exceptions Gracefully: Always anticipate and handle common I/O errors. 

  1. Avoid Hardcoding Paths: Use libraries like os or pathlib for cross-platform compatibility. 

File handling is an essential skill for working with data in Python, allowing efficient interaction with text, CSV, JSON, and more! 

Error and Exception Handling in Python 

Exception handling allows you to manage runtime errors gracefully, ensuring that your program doesn't crash unexpectedly and provides meaningful feedback to users. 

 

1. Using try, except, and finally 

Basic Syntax 

try: 
   # Code that might raise an exception 
   risky_operation() 
except ExceptionType: 
   # Code to handle the exception 
   handle_exception() 
finally: 
   # Code that always executes, regardless of whether an exception occurred 
   cleanup() 
 

 

Example: Handling Specific Exceptions 

try: 
   result = 10 / 0 
except ZeroDivisionError: 
   print("Error: Division by zero is not allowed.") 
finally: 
   print("Execution complete.") 
 

Output: 

Error: Division by zero is not allowed. 
Execution complete. 
 

Catching Multiple Exceptions 

You can catch multiple exceptions and handle them differently. 

try: 
   num = int("abc") 
   result = 10 / num 
except ValueError: 
   print("Error: Invalid input. Please enter a number.") 
except ZeroDivisionError: 
   print("Error: Division by zero is not allowed.") 
 

Catching All Exceptions 

Use a generic except block for unknown exceptions. This is typically used as a fallback. 

try: 
   result = risky_function() 
except Exception as e: 
   print(f"An error occurred: {e}") 
 

 

2. The finally Block 

The finally block is executed no matter what, whether an exception is raised or not. It's useful for cleanup operations like closing files or releasing resources. 

try: 
   file = open("example.txt", "r") 
   content = file.read() 
except FileNotFoundError: 
   print("File not found.") 
finally: 
   if 'file' in locals(): 
       file.close() 
       print("File closed.") 
 

 

3. Custom Exceptions 

Python allows you to define your own exception classes for specific use cases. This is useful for handling domain-specific errors. 

Creating a Custom Exception 

  • Inherit from the Exception base class. 

class MyCustomError(Exception): 
   """Custom exception for specific errors.""" 
   pass 
 

Raising a Custom Exception 

Use the raise keyword to throw an exception explicitly. 

def check_age(age): 
   if age < 18: 
       raise MyCustomError("Age must be 18 or older.") 
   print("Age is valid.") 
 
try: 
   check_age(16) 
except MyCustomError as e: 
   print(f"Custom Error: {e}") 
 

Output: 

Custom Error: Age must be 18 or older. 
 

Custom Exception with Additional Attributes 

Custom exceptions can include additional data for more detailed error handling. 

class InsufficientFundsError(Exception): 
   def __init__(self, balance, amount): 
       self.balance = balance 
       self.amount = amount 
       super().__init__(f"Attempted to withdraw {amount}, but only {balance} is available.") 
 
def withdraw(balance, amount): 
   if amount > balance: 
       raise InsufficientFundsError(balance, amount) 
   return balance - amount 
 
try: 
   withdraw(100, 150) 
except InsufficientFundsError as e: 
   print(e) 
 

Output: 

vbnet 

CopyEdit 

Attempted to withdraw 150, but only 100 is available. 
 

 

Best Practices for Exception Handling 

  1. Catch Specific Exceptions: Avoid generic except blocks unless absolutely necessary. 

  1. Use finally for Cleanup: Ensure resources like files or connections are properly closed. 

  1. Raise Meaningful Exceptions: Include informative messages or additional attributes in custom exceptions. 

  1. Don't Overuse Exceptions: Use them for exceptional conditions, not regular control flow. 

  1. Log Errors: Use logging to record exceptions for debugging and monitoring purposes. 

 

Example: Combining Concepts 

python 

CopyEdit 

class NegativeNumberError(Exception): 
   """Raised when the number is negative.""" 
   pass 
 
def calculate_square_root(number): 
   if number < 0: 
       raise NegativeNumberError("Cannot calculate the square root of a negative number.") 
   return number ** 0.5 
 
try: 
   num = -4 
   print(calculate_square_root(num)) 
except NegativeNumberError as e: 
   print(f"Error: {e}") 
finally: 
   print("Calculation attempt complete.") 
 

Output: 

Error: Cannot calculate the square root of a negative number. 
Calculation attempt complete. 
 

Exception handling ensures your Python programs are robust, user-friendly, and maintainable!