Instashire

Introduction to Python

Overview of Python

  • Python is a high-level, interpreted, and general-purpose programming language.
  • Created by Guido van Rossum and first released in 1991.
  • Emphasizes code readability with its clean and simple syntax.
  • Widely used in web development, data analysis, artificial intelligence, machine learning, scientific computing, and more.

Features and Benefits of Python

  • Easy to Learn and Use: Python’s syntax resembles English, making it beginner-friendly.
  • Interpreted Language: No need for compilation; the interpreter runs the code directly.
  • Cross-platform: Runs on Windows, macOS, Linux, etc., without modification.
  • Extensive Libraries: Comes with built-in modules and frameworks for diverse use cases like data analysis (pandas), web development (Django), and more.
  • Community Support: A massive community that provides tutorials, documentation, and solutions.
  • Open Source: Free to use, modify, and distribute.
  • Dynamic Typing: No need to declare variable types explicitly.
  • Versatility: Suitable for small scripts to complex enterprise-level applications.

Setting up Python Environment

  • Installing Python:

    • Download Python from the official website https://www.python.org/.
    • Ensure to check the “Add Python to PATH” option during installation.
  • Installing an IDE (Integrated Development Environment):

    • Popular IDEs:
      • PyCharm (beginner-friendly and feature-rich)
      • Visual Studio Code (lightweight and versatile)
      • Jupyter Notebook (great for data analysis and experimentation)
    • Alternative: Use the built-in IDLE (comes with Python installation).
  • Verifying Installation:

    • Open a terminal/command prompt and type
python --version
python3 --version

Python Syntax and Structure

Indentation:

  • Python uses indentation to define blocks of code (no braces {}).

Case Sensitivity:

  • Python is case-sensitive: MyVariable and myvariable are different.

Comments:

  • Single-line comment: Use #

Variables:

  • No need to declare types explicitly

Print Statement:

  • Use print() to display output
if 10 > 5:
    print("10 is greater than 5")  # Indented code block
# This is a single-line comment
x = 10  # Integer
y = "Hello"  # String
print("Hello, World!")

Basic Concepts

Variables and Data Types

Variables are containers used to store data values. Python allows dynamic typing, so you don’t need to declare the type explicitly.
x = 10  # Integer
y = 3.14  # Float
z = "Hello, Python!"  # String
is_valid = True  # Boolean

Types of Data:

Numbers:
  • int: Whole numbers.
  • float: Numbers with decimal points.
  • complex: Numbers with real and imaginary parts.
age = 25
pi = 3.14
z = 3 + 4j
print(z.real, z.imag)  # Outputs: 3.0 4.0
Strings:
  • Text data enclosed in single, double, or triple quotes.
  • String concatenation:
  • Accessing characters:
name = "Alice"
message = '''Welcome to Python programming!'''
greeting = "Hello" + ", " + "World!"
print(greeting)
word = "Python"
print(word[0])  # Output: P
print(word[-1])  # Output: n
Booleans:
  • Represents True or False.
is_python_fun = True
print(is_python_fun)  # Output: True

Input and Output

  • Input: Capturing user input using input(). Note: The input() function always returns a string.
  • Output: Printing to the console using print().
name = input("Enter your name: ")
print("Hello, " + name + "!")
print("Welcome to Python!")
print("Age:", 25)

Comments in Python

  • Single-line comments:
  • Multi-line comments:
# This is a comment
x = 5  # Assigning value 5 to x

'''
This is a multi-line
comment in Python.
'''

Basic Operators

Arithmetic Operators:
x = 10
y = 3
print(x + y)  # Addition: 13
print(x - y)  # Subtraction: 7
print(x * y)  # Multiplication: 30
print(x / y)  # Division: 3.333...
print(x // y)  # Floor division: 3
print(x % y)  # Modulus: 1
print(x ** y)  # Exponentiation: 1000
Comparison Operators (returns True or False):
print(x > y)  # Greater than: True
print(x < y)  # Less than: False
print(x == y)  # Equal to: False
print(x != y)  # Not equal to: True
print(x >= y)  # Greater than or equal to: True
print(x <= y)  # Less than or equal to: False
Logical Operators:
a = True
b = False
print(a and b)  # Logical AND: False
print(a or b)  # Logical OR: True
print(not a)  # Logical NOT: False
Assignment Operators:
x = 5  # Assignment
x += 2  # Equivalent to x = x + 2
x -= 1  # Equivalent to x = x - 1
x *= 3  # Equivalent to x = x * 3
x /= 2  # Equivalent to x = x / 2
print(x)

Type Conversion

Python supports typecasting to change the type of variables.
Implicit Type Conversion (automatic):
Explicit Type Conversion (manual):

x = 5  # int
y = 2.5  # float
result = x + y  # Result will be float (7.5)
print(type(result))  # Output: <class 'float'>
x = "10"
y = int(x)  # Convert string to integer
print(y + 5)  # Output: 15

num = 3.14
print(int(num))  # Converts float to int: Output: 3

z = 10
print(str(z))  # Converts int to string: Output: "10"

Control Flow

Conditional Statements

Conditional statements control the flow of execution based on conditions.

  1. if Statement: Executes a block of code if a condition is True.

  2. if-else Statement: Adds an alternative block of code if the condition is False.
  3. if-elif-else Statement: Allows checking multiple conditions.
if condition:
    # Code to execute if condition is True
if condition:
    # Code to execute if condition is True
else:
    # Code to execute if condition is False
if condition1:
    # Code to execute if condition1 is True
elif condition2:
    # Code to execute if condition2 is True
else:
    # Code to execute if none of the conditions are True

Loops

Loops are used to repeat a block of code as long as a condition is met.
for Loop:

The for loop iterates over a sequence (like a list, tuple, or range).

while Loop:

The while loop executes a block of code as long as its condition is True.

for variable in sequence:
    # Code to execute for each item in sequence
while condition:
    # Code to execute as long as condition is True


counter = 1
while counter <= 5:
    print(counter)
    counter += 1

Loop Control Statements

These statements alter the flow of a loop.

  1. break: Terminates the loop prematurely.

  2. continue: Skips the current iteration and moves to the next.
  3. pass: Does nothing and is used as a placeholder.
for num in range(1, 11):
    if num == 5:
        break  # Exit the loop when num is 5
    print(num)
for num in range(1, 11):
    if num % 2 == 0:  # Skip even numbers
        continue
    print(num)
for letter in "Python":
    if letter == "h":
        pass  # Placeholder for future code
    print(letter)

Data Structures

Strings

Strings are sequences of characters, enclosed in single, double, or triple quotes.

String Operations
  1. Concatenation:

  2. Repetition:
  3. Indexing and Slicing:
str1 = "Hello"
str2 = "World"
result = str1 + " " + str2
print(result)  # Output: Hello World
print("Python " * 3)  # Output: Python Python Python
text = "Python"
print(text[0])  # Output: P (first character)
print(text[-1])  # Output: n (last character)
print(text[1:4])  # Output: yth (characters from index 1 to 3)

String Methods

Common methods for string manipulation:

  1. len(): Returns the length of the string.

  2. lower() and upper():
  3. strip(): Removes leading and trailing spaces.
  4. replace():
  5. split() and join():
print(len("Hello"))  # Output: 5
text = "Python"
print(text.lower())  # Output: python
print(text.upper())  # Output: PYTHON

text = "  Hello  "
print(text.strip())  # Output: Hello

print("Hello World".replace("World", "Python"))  # Output: Hello Python

text = "Python is fun"
words = text.split()  # Splits into a list of words
print(words)  # Output: ['Python', 'is', 'fun']

sentence = " ".join(words)  # Joins the list back into a string
print(sentence)  # Output: Python is fun

Lists

Lists are ordered collections that are mutable and can hold items of any type.

Indexing and Slicing:
Adding and Removing Items:

my_list = [1, 2, 3, 4, 5]
print(my_list[0])  # Output: 1
print(my_list[1:4])  # Output: [2, 3, 4]
my_list.append(6)  # Adds 6 to the end
my_list.insert(2, 10)  # Inserts 10 at index 2
my_list.remove(3)  # Removes the first occurrence of 3
print(my_list)  # Output: [1, 2, 10, 4, 5, 6]

List Methods

  • append(): Adds an item to the end.
  • extend(): Adds multiple items.
  • sort() and reverse()
my_list = [3, 1, 4, 2]
my_list.sort()
print(my_list)  # Output: [1, 2, 3, 4]
my_list.reverse()
print(my_list)  # Output: [4, 3, 2, 1]

Tuples

Tuples are immutable sequences, often used for fixed collections of items.

  1. Defining a Tuple:

  2. Operations:

    • Accessing elements: Similar to lists.
    • Tuples cannot be modified (immutable).
my_tuple = (1, 2, 3)
print(my_tuple[0])  # Output: 1

Dictionaries

Dictionaries store data as key-value pairs.

Key-Value Pair Operations
  1. Accessing and Modifying:

  2. Adding and Removing:
  3. Methods:

    • keys(): Returns all keys.
    • values(): Returns all values.
    • items(): Returns key-value pairs.
my_dict = {"name": "Alice", "age": 25}
print(my_dict["name"])  # Output: Alice
my_dict["age"] = 26  # Modifying a value
print(my_dict)  # Output: {'name': 'Alice', 'age': 26}
my_dict["city"] = "New York"  # Adding a new key-value pair
del my_dict["age"]  # Removing a key-value pair
print(my_dict)  # Output: {'name': 'Alice', 'city': 'New York'}

Sets

Sets are unordered collections of unique elements.

Set Operations
  1. Creating a Set:

  2. Common Operations:

    • Union
    • Intersection
    • Difference
  3. Adding and Removing Items:
my_set = {1, 2, 3, 4}
print(my_set)  # Output: {1, 2, 3, 4}
set1 = {1, 2, 3}
set2 = {3, 4, 5}
print(set1 | set2)  # Output: {1, 2, 3, 4, 5}
print(set1 & set2)  # Output: {3}
print(set1 - set2)  # Output: {1, 2}
my_set.add(5)  # Adds 5 to the set
my_set.remove(2)  # Removes 2 from the set
print(my_set)

Functions

Functions are blocks of reusable code designed to perform a specific task. They improve code modularity and reusability.

Defining Functions

A function is defined using the def keyword.
def function_name(parameters):
    # Code block
    return value
def greet():
    print("Hello, world!")
greet()  # Output: Hello, world!

Parameters and Arguments

  • Parameters: Variables listed in the function definition.
  • Arguments: Values passed to the function when calling it.
  • Default Arguments:
  • Keyword Arguments:
def greet(name):
    print(f"Hello, {name}!")
greet("Alice")  # Output: Hello, Alice!
def greet(name="Guest"):
    print(f"Hello, {name}!")
greet()  # Output: Hello, Guest!
greet("Bob")  # Output: Hello, Bob!
def display_info(name, age):
    print(f"Name: {name}, Age: {age}")
display_info(age=30, name="Alice")  # Output: Name: Alice, Age: 30

Return Statement

The return statement allows a function to send a result back to the caller.

Multiple Returns:

def add(a, b):
    return a + b
result = add(5, 3)
print(result)  # Output: 8
def calculate(a, b):
    return a + b, a - b, a * b
add, subtract, multiply = calculate(6, 3)
print(add, subtract, multiply)  # Output: 9 3 18

Scope of Variables

  • Local Scope: Variables defined inside a function.
  • Global Scope: Variables defined outside any function.
x = 10  # Global variable

def example():
    x = 5  # Local variable
    print("Inside function:", x)

example()  # Output: Inside function: 5
print("Outside function:", x)  # Output: Outside function: 10

Modifying Global Variables:

x = 10

def modify_global():
    global x
    x = 20

modify_global()
print(x)  # Output: 20

Lambda Functions

Lambda functions are anonymous functions defined with the lambda keyword. They are typically used for simple, short tasks.
lambda arguments: expression
# Lambda for addition
add = lambda a, b: a + b
print(add(5, 3))  # Output: 8

# Using lambda with filter
nums = [1, 2, 3, 4, 5]
even_nums = list(filter(lambda x: x % 2 == 0, nums))
print(even_nums)  # Output: [2, 4]

Built-in Functions

Python provides a wide range of built-in functions.

len(): Returns the length of an object.

max() and min():

sum():

map():

print(len("Python"))  # Output: 6
nums = [3, 5, 7, 2]
print(max(nums))  # Output: 7
print(min(nums))  # Output: 2
nums = [1, 2, 3]
print(sum(nums))  # Output: 6
nums = [1, 2, 3]
squared = list(map(lambda x: x**2, nums))
print(squared)  # Output: [1, 4, 9]

Recursive Functions

A recursive function calls itself to solve a problem.
Example: Factorial Using Recursion:
Example: Fibonacci Sequence:

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

print(factorial(5))  # Output: 120
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

for i in range(6):
    print(fibonacci(i), end=" ")  # Output: 0 1 1 2 3 5

Modules and Packages

Importing Modules

Modules are files containing Python code that can include functions, classes, or variables. They allow you to organize your code into reusable pieces.
import module_name
import math
print(math.sqrt(16))  # Output: 4.0

Specific Import:
Renaming with as

from math import sqrt
print(sqrt(16))  # Output: 4.0

import math as m
print(m.sqrt(16))  # Output: 4.0

Built-in Modules

Python comes with a rich library of built-in modules. Here are a few commonly used ones:

  1. math:

  2. os (for interacting with the operating system):
  3. random (for generating random numbers):
  4. datetime (for date and time operations):
import math
print(math.pi)  # Output: 3.141592653589793
print(math.factorial(5))  # Output: 120
import os
print(os.getcwd())  # Get the current working directory
os.mkdir("new_folder")  # Create a new folder
import random
print(random.randint(1, 10))  # Random integer between 1 and 10
print(random.choice(["apple", "banana", "cherry"]))  # Random choice
from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))  # Output: Current date and time

Creating Custom Modules

You can create your own module by writing functions or variables in a .py file.

Example:

  1. Create a file my_module.py:

  2. Import and use it in another script:
def greet(name):
    return f"Hello, {name}!"
import my_module
print(my_module.greet("Alice"))  # Output: Hello, Alice!

Using pip to Install Packages

pip is Python’s package manager used to install external libraries or packages from the Python Package Index (PyPI).

  1. Check if pip is installed:

  2. Install a package:
  3. Upgrade a package:
  4. Uninstall a package:
  5. List installed packages:
pip --version
pip install package_name
pip install numpy
pip install --upgrade package_name
pip uninstall package_name
pip list

File Handling

Python provides built-in functionality for handling files, including reading, writing, and working with structured data such as CSV files.

File Modes:
File modes define how files are opened and accessed. The most common modes are:

ModeDescription
rRead mode (default). File must exist.
wWrite mode. Creates or overwrites a file.
aAppend mode. Adds data to the end of a file.
rbRead in binary mode.
wbWrite in binary mode.
# Open file in read mode
file = open("example.txt", "r")

# Open file in write mode
file = open("example.txt", "w")

# Open file in append mode
file = open("example.txt", "a")

Reading from and Writing to Files

Reading from a File

  1. Reading the entire content:
  2. Reading line by line:
  3. Reading specific lines:
with open("example.txt", "r") as file:
    content = file.read()
    print(content)
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())
with open("example.txt", "r") as file:
    lines = file.readlines()  # Returns a list of lines
    print(lines[0])  # Print the first line

Writing to a File

  1. Overwriting a file:
  2. Appending to a file:
with open("example.txt", "w") as file:
    file.write("This will overwrite the file.\n")
with open("example.txt", "a") as file:
    file.write("Adding new content.\n")

Closing Files

Using with open() automatically closes the file after the operation, so you don’t need to call file.close() manually.

Working with CSV Files

The csv module makes it easy to work with CSV files.

  1. Reading CSV Files:

  2. Writing CSV Files:
  3. Reading CSV Files as Dictionaries:
  4. Writing CSV Files as Dictionaries:
import csv

with open("data.csv", "r") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)
import csv

with open("data.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["Name", "Age", "City"])
    writer.writerow(["Alice", 25, "New York"])
import csv

with open("data.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row["Name"], row["City"])
import csv

with open("data.csv", "w", newline="") as file:
    fieldnames = ["Name", "Age", "City"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)

    writer.writeheader()  # Write column headers
    writer.writerow({"Name": "Alice", "Age": 25, "City": "New York"})

Exception Handling in File Operations

File operations may encounter errors (e.g., file not found, permission denied). Exception handling ensures graceful handling of such errors.
try:
    with open("example.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("Error: The file does not exist.")
except IOError:
    print("Error: Unable to read the file.")
else:
    print("File read successfully.")
finally:
    print("File operation completed.")

Object-Oriented Programming (OOP)

Object-Oriented Programming (OOP) is a paradigm in programming that organizes code into objects, making it modular, reusable, and easier to maintain. Here’s an overview of the key concepts:

1. Classes and Objects

Class: A blueprint for creating objects. It defines a set of attributes (variables) and methods (functions) that the objects created from the class will have.

Object: An instance of a class with specific values assigned to its attributes.

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

# Object
my_car = Car("Toyota", "Corolla")
print(my_car.brand)  # Output: Toyota

2. Constructors (__init__)

  • A special method in Python, used for initializing the attributes of a class.
  • Automatically called when an object is created
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person1 = Person("Alice", 25)
print(person1.name)  # Output: Alice

3. Attributes and Methods

  • Attributes: Variables that belong to an object or class.
  • Methods: Functions defined within a class to define the behavior of an object
class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        return f"{self.name} says Woof!"

dog1 = Dog("Buddy")
print(dog1.bark())  # Output: Buddy says Woof!

4. Inheritance

  • Mechanism for creating a new class (child) based on an existing class (parent).
  • The child class inherits attributes and methods from the parent class and can also have its own
class Animal:
    def __init__(self, species):
        self.species = species

    def sound(self):
        return "Some generic sound"

class Cat(Animal):
    def sound(self):
        return "Meow"

cat1 = Cat("Feline")
print(cat1.sound())  # Output: Meow

5. Polymorphism

The ability of different classes to be treated as instances of the same parent class, usually through method overriding or interfaces.
class Bird:
    def sound(self):
        return "Chirp"

class Dog:
    def sound(self):
        return "Bark"

def make_sound(animal):
    print(animal.sound())

make_sound(Bird())  # Output: Chirp
make_sound(Dog())   # Output: Bark

6. Encapsulation and Abstraction

Encapsulation: Restricts direct access to some of an object’s components and prevents accidental modification.
class Account:
    def __init__(self):
        self.__balance = 0  # Private attribute

    def deposit(self, amount):
        self.__balance += amount

    def get_balance(self):
        return self.__balance

acc = Account()
acc.deposit(100)
print(acc.get_balance())  # Output: 100
Abstraction: Hides complex implementation details and shows only the essential features.
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    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

rect = Rectangle(5, 10)
print(rect.area())  # Output: 50

7. Special Methods (__str__, __repr__, etc.)

Special (magic/dunder) methods provide built-in behavior and functionality to user-defined classes.

  • __str__: Used for a user-friendly string representation of an object.
  • __repr__: Used for a developer-friendly string representation (usually for debugging).
class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return f"{self.title} by {self.author}"

    def __repr__(self):
        return f"Book(title={self.title}, author={self.author})"

book1 = Book("1984", "George Orwell")
print(book1)        # Output: 1984 by George Orwell
print(repr(book1))  # Output: Book(title=1984, author=George Orwell)

Error and Exception Handling

Error and exception handling is a critical concept in programming, allowing developers to manage and respond to unexpected situations gracefully rather than crashing a program. Here’s an overview of the key components:

1. Understanding Errors

Errors are issues that arise during the execution of a program, causing it to stop if not handled. Common Python errors include:

  • SyntaxError: Occurs when the code has invalid syntax.

  • TypeError: Occurs when an operation is applied to an inappropriate type.
  • NameError: Occurs when a variable or function is not defined.
  • ValueError: Occurs when a function receives an argument of the right type but inappropriate value.
print("Hello world  # SyntaxError: Missing closing quote
print(5 + "hello")  # TypeError: unsupported operand type(s)
print(x)  # NameError: name 'x' is not defined
int("abc")  # ValueError: invalid literal for int()