Python Essentials: A Speedy Introduction

mubbashir10

Mubbashir Mustafa

Posted on June 25, 2024

Python Essentials: A Speedy Introduction

Are you ready to dive into the exciting world of Artificial Intelligence and Machine Learning but need a quick introduction to Python first? This crash course is here to help! In this article, we'll cover the basics of Python programming to get you up to speed quickly. Whether you're new to programming or just need a refresher, this guide will provide the essential knowledge you need to start coding confidently. Let's get started!

Chapter 1: Python Syntax and Basics

In this chapter, we'll quickly cover Python's syntax and foundational concepts. This will serve as a concise refresher to familiarize you with Python's unique features.

Code Structure

Python uses indentation to define blocks of code, unlike languages like JavaScript which use braces. Consistent indentation is crucial as it directly impacts the program's flow. Here's a quick example:

def greet(name):
    if name:
        print(f"Hello, {name}!")
    else:
        print("Hello, world!")

Enter fullscreen mode Exit fullscreen mode

Variables and Data Types

Python is dynamically typed, meaning you don't need to declare the type of a variable when you create one. The basic data types in Python include:

  • Strings: Defined with single ('...') or double ("...") quotes.
  • Integers: No special syntax required, e.g., 5.
  • Floats: Use a point to denote decimal, e.g., 5.0.
  • Booleans: Written as True or False.

Example

name = "Alice"
age = 30
is_registered = True #capitalized boolean in python

Enter fullscreen mode Exit fullscreen mode

Collections

  • Lists: Ordered and mutable collection, e.g., numbers = [1, 2, 3].
  • Dictionaries: Key-value pairs, e.g., person = {"name": "Alice", "age": 30}.
  • Sets: Unordered collection of unique elements, e.g., unique_numbers = {1, 2, 3}.
  • Tuples: Ordered and immutable collection, e.g., point = (1, 2).

List Comprehensions

List comprehensions provide a concise way to create lists:

squares = [x**2 for x in range(10)]
print(squares)
Enter fullscreen mode Exit fullscreen mode
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Enter fullscreen mode Exit fullscreen mode

Functions

Defining functions in Python uses the def keyword. You can specify default values for parameters, which makes them optional during calls:

def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Alice")  # Uses the default greeting
greet("Bob", "Howdy")  # Uses a custom greeting

Enter fullscreen mode Exit fullscreen mode

This chapter sets the foundation for understanding how Python code is structured and executed. Up next, we will explore control structures to manage the flow of your Python programs.

Chapter 2: Control Structures

Python's control structures allow you to direct the flow of your program's execution through conditional statements and loops. This section will refresh your understanding of these constructs.

If, Elif, and Else

Conditional statements in Python are straightforward. The if statement evaluates a condition and executes a block of code if the condition is true. You can extend this logic with elif (else if) and else:

age = 25
if age < 18:
    print("You are a minor.")
elif age < 65:
    print("You are an adult.")
else:
    print("You are a senior.")

Enter fullscreen mode Exit fullscreen mode

Python evaluates conditions until one is true, then skips the rest, known as short-circuiting.

Loops

Python provides for and while loops for iterating over sequences or executing a block of code repeatedly under a condition.

For Loops: Used for iterating over a sequence (like a list, tuple, or string).

for number in range(5):  # range(5) generates numbers from 0 to 4
    print(number)
Enter fullscreen mode Exit fullscreen mode

While Loops: Execute as long as a condition is true.

count = 0
while count < 5:
    print(count)
    count += 1
Enter fullscreen mode Exit fullscreen mode

Control within loops can be managed with break (to exit the loop) and continue (to skip the current iteration and continue with the next one):

for number in range(10):
    if number == 3:
        continue  # Skip the print statement for number 3
    if number == 8:
        break  # Exit the loop when number is 8
    print(number)
Enter fullscreen mode Exit fullscreen mode

Iterators and Generators

Python uses iterators for looping. You can create your own iterator by implementing iter() and next() methods or using generator functions.

  • Generators: Use yield to generate a sequence of values. Generators are useful when you want to iterate over a sequence without storing the entire sequence in memory.
def countdown(num):
    while num > 0:
        yield num
        num -= 1

for i in countdown(5):
    print(i)

Enter fullscreen mode Exit fullscreen mode

This chapter covers the basic control structures in Python. You'll find these essential for creating conditional logic and managing looping in your Python programs. Next, we'll dive into more Pythonic techniques and features to help you write cleaner and more efficient code.

Chapter 3: Pythonic Techniques

This chapter delves into more sophisticated Pythonic techniques, enabling you to write cleaner, more efficient, and more Python-specific code. These techniques leverage Python's unique capabilities and idiomatic practices.

Unpacking

Unpacking allows you to assign values from a list or tuple to variables in a single statement, improving readability and conciseness.

a, b, c = [1, 2, 3]
print(a, b, c)  # Outputs: 1 2 3

# Star expressions for capturing excess items
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)  # Outputs: 1 [2, 3, 4] 5

Enter fullscreen mode Exit fullscreen mode

Lambda Functions

Lambda functions are small anonymous functions defined with the lambda keyword. They are best used for short, simple functions.

# A simple lambda to add two numbers
add = lambda x, y: x + y
print(add(5, 3))  # Outputs: 8

# Often used in functions like map() and filter()
squares = list(map(lambda x: x**2, range(10)))
print(squares)  # Outputs: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Enter fullscreen mode Exit fullscreen mode

Map and Filter

The map and filter functions are functional programming tools that apply a function to each item in an iterable (like a list) and return an iterable.

map(): Applies a function to each item in an iterable.
filter(): Extracts elements from an iterable for which a function returns True.

# Using map to square numbers
nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, nums))

# Using filter to find even numbers
evens = list(filter(lambda x: x % 2 == 0, nums))

Enter fullscreen mode Exit fullscreen mode

When compared to list comprehensions, map() and filter() can be preferable for their readability and expressive power with small lambda functions. However, list comprehensions are often clearer and more Pythonic when the operation is straightforward.

This chapter introduces you to writing Python in a way that is not just correct but also stylistically Pythonic, embracing the language's philosophy of readability and simplicity. By using these advanced features, you can make your code more modular, reusable, and expressive. Up next, we'll cover file handling and exception management to ensure your programs are robust and professional.

Chapter 4: File Handling and Exception Management

In Python, managing files and handling exceptions are critical for creating robust applications. This chapter covers the essentials of these areas, focusing on best practices and Pythonic approaches.

File Handling

Python simplifies file operations with built-in functions and methods. The with statement ensures that files are properly closed after their suite finishes, even if an exception is raised.

# Reading from a file
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)

# Writing to a file
with open('output.txt', 'w') as file:
    file.write("Hello, Python!\n")

Enter fullscreen mode Exit fullscreen mode

For reading and writing files, Python offers methods like read(), readline(), readlines(), write(), and writelines(), allowing you to handle different file sizes and content types efficiently.

Exception Handling

Proper error and exception handling is essential for writing reliable and user-friendly programs. Python uses try, except, else, and finally blocks to handle exceptions.

try:
    # Try to do something that might raise an exception
    result = 10 / 0
except ZeroDivisionError:
    # Handle specific exceptions
    print("Divided by zero!")
else:
    # Execute if no exceptions
    print("Division successful!", result)
finally:
    # Always executed
    print("Cleaning up, if needed.")

Enter fullscreen mode Exit fullscreen mode

Use specific exception types in except blocks to catch and handle different error conditions appropriately. This not only helps in debugging but also allows the program to continue or fail gracefully.

Context Managers

For more complex resource management, Python provides context managers that allow you to allocate and release resources precisely when you want. The with statement is commonly used with file handling, as shown above, but can also be used with other resources like network connections or locking mechanisms.

from contextlib import contextmanager

@contextmanager
def managed_file(name):
    try:
        f = open(name, 'w')
        yield f
    finally:
        f.close()

# Usage
with managed_file('hello.txt') as f:
    f.write('hello, world!')

Enter fullscreen mode Exit fullscreen mode

This chapter ensures that you are equipped to handle file I/O operations and exceptions in your Python applications effectively, contributing to their reliability and maintainability. Next, we will explore modules, packages, and Python's environment management tools.

Chapter 5: Modules and Packages

This chapter focuses on the organization and reusability of code in Python through modules and packages. Understanding how to create, import, and manage modules and packages is key for developing maintainable and scalable Python applications.

Importing Modules

Python's modules are simply Python files with .py extensions containing Python code that can be reused in other Python scripts.

# Importing a whole module
import math
print(math.sqrt(16))  # Outputs: 4.0

# Importing specific functions
from math import sqrt
print(sqrt(16))  # Outputs: 4.0

# Using alias for modules
import numpy as np
array = np.array([1, 2, 3])

Enter fullscreen mode Exit fullscreen mode

When you import a module, Python executes all of the code in the module file.

Creating Modules

Any Python file can be a module. To create a module, simply save your Python code in a .py file. Other Python scripts can then import this file as a module.

# Example of a simple module, saved as calculator.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

Enter fullscreen mode Exit fullscreen mode

You can then use this module in other Python scripts:

from calculator import add, subtract
print(add(5, 3))  # Outputs: 8

Enter fullscreen mode Exit fullscreen mode

Packages

A package is a collection of Python modules under a common directory. For Python to recognize a directory as a package, it must contain a file named init.py. The file can be empty but it signifies that the directory contains Python modules.

# Assume the following directory structure:
# mypackage/
#   __init__.py
#   subpackage1/
#       __init__.py
#       module1.py
#   subpackage2/
#       __init__.py
#       module2.py

# Importing from a package
from mypackage.subpackage1 import module1
module1.some_function()

Enter fullscreen mode Exit fullscreen mode

Virtual Environments

Using virtual environments in Python helps manage dependencies for different projects. By creating a virtual environment, you can keep dependencies required by different projects separate from each other.

# Creating a virtual environment
python -m venv myprojectenv

# Activating the virtual environment
# On Windows
myprojectenv\Scripts\activate

# On MacOS/Linux
source myprojectenv/bin/activate

Enter fullscreen mode Exit fullscreen mode

This setup ensures that any Python packages installed while the virtual environment is active will only affect this particular environment, helping avoid conflicts between project dependencies.

This chapter provides the tools you need to effectively manage and modularize your Python code, essential for professional, clean, and efficient Python programming. Coming up next, we'll discuss best practices in logging and debugging to enhance the observability and maintainability of your Python applications.

Chapter 6: Logging and Debugging

Effective logging and debugging are crucial for developing, maintaining, and troubleshooting Python applications. This chapter covers how to utilize Python's built-in logging module and debugging tools to keep your applications running smoothly and efficiently.

Logging

Python's logging module provides a flexible framework for emitting log messages from Python programs. It is preferable to using print statements because it offers different severity levels and allows you to direct the logs to different outputs.

import logging

# Basic configuration to log to file
logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Different levels of logs
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

Enter fullscreen mode Exit fullscreen mode

Using Log Levels

Log levels provide a way to categorize the importance of the messages logged by the application:

  • DEBUG: Detailed information, typically of interest only when diagnosing problems.
  • **INFO: Confirmation that things are working as expected.
  • WARNING: An indication that something unexpected happened, or indicative of some problem in the near future.
  • ERROR: Due to a more serious problem, the software has not been able to perform some function.
  • CRITICAL: A serious error, indicating that the program itself may be unable to continue running.

Debugging Tools
When it comes to debugging, Python provides several tools to help identify issues in the code. The most commonly used tool is the Python Debugger (pdb), which allows interactive debugging.

import pdb

# Example usage
def div(a, b):
    pdb.set_trace()
    return a / b

print(div(4, 2))

Enter fullscreen mode Exit fullscreen mode

Using pdb, you can step through your code, inspect variables, and evaluate expressions to diagnose and fix issues more effectively.

  • Commands: list (shows current position in the code), next (executes the next line), continue (continues execution until the next breakpoint), break (adds breakpoints), print (prints a variable), and quit (exits the debugger).

Tips for Effective Debugging

  • Start Small: Test small parts of your code as you write them.
  • Use Logs: Insert logging statements to report the occurrence of particular events.
  • Isolate Problems: When you encounter a bug, narrow down where it could be by using unit tests or dividing the code.

This chapter equips you with essential tools for logging and debugging, helping ensure your Python applications perform as intended and making it easier to maintain and troubleshoot them. In the next chapter, we will explore the broader Python ecosystem, including toolchains and additional libraries that can help streamline your Python development process.

Chapter 7: Toolchain and Additional Libraries

In this final chapter, we'll explore the broader Python ecosystem, focusing on toolchains for code style enforcement, testing, and some additional libraries that extend Python's capabilities. These tools and libraries can significantly enhance productivity and ensure high-quality software development.

PEP 8 and Linters

PEP 8 is the style guide for Python code. Adhering to PEP 8 helps ensure that your Python code is readable and consistent. Python's linters like flake8 or pylint help enforce coding standards and catch potential errors.

# Installing flake8
pip install flake8

# Using flake8
flake8 my_script.py

Enter fullscreen mode Exit fullscreen mode

These tools provide feedback on style issues, complexity, and programmatic errors, making them indispensable for maintaining code quality.

Testing
Testing is critical in the development process to ensure your code behaves as expected.

  • unittest: Python’s built-in library that allows you to test small units of code independently.
import unittest

class TestMathOperations(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1 + 1, 2)

    def test_subtract(self):
        self.assertEqual(2 - 1, 1)

if __name__ == '__main__':
    unittest.main()

Enter fullscreen mode Exit fullscreen mode
  • pytest: A more powerful, third-party testing framework with a simpler syntax and more features than unittest.
# Installing pytest
pip install pytest

# Using pytest
pytest

Enter fullscreen mode Exit fullscreen mode

Popular Python Libraries

Several Python libraries can help simplify complex tasks across different domains:

  • Requests: Simplifies making HTTP requests for web clients.
import requests
response = requests.get('https://api.example.com/data')

Enter fullscreen mode Exit fullscreen mode
  • Pandas: Essential for data analysis and manipulation.
import pandas as pd
data = pd.read_csv('data.csv')

Enter fullscreen mode Exit fullscreen mode
  • NumPy: Provides support for large, multi-dimensional arrays and matrices.
import numpy as np
array = np.array([1, 2, 3])

Enter fullscreen mode Exit fullscreen mode
  • Scikit-Learn: Ideal for implementing machine learning algorithms.
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(train_data, train_labels)

Enter fullscreen mode Exit fullscreen mode
  • Matplotlib: A plotting library for creating static, interactive, and animated visualizations in Python
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.show()

Enter fullscreen mode Exit fullscreen mode

Extra Chapter: Python and Object-Oriented Programming

Introduction to Classes and Objects

In Python, classes are created using the class keyword, and objects are instances of these classes. Here’s a simple example:

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self, sound):
        return f"{self.name} says {sound}"

# Creating an instance of Dog
my_dog = Dog("Rex", 4)
print(my_dog.speak("Woof"))

Enter fullscreen mode Exit fullscreen mode

Attributes and Methods

Attributes are variables associated with a class, and methods are functions defined within a class that operate on its attributes. The init method is a special method called a constructor, used for initializing an instance of the class.

Inheritance

Python supports inheritance, allowing multiple base classes and thus facilitating complex relationships between objects.

class Cat(Dog):  # Inherits from Dog
    def purr(self):
        return f"{self.name} purrs."

# Usage
my_cat = Cat("Whiskers", 3)
print(my_cat.speak("Meow"))  # Inherited method
print(my_cat.purr())         # New method

Enter fullscreen mode Exit fullscreen mode

Encapsulation

Encapsulation is the bundling of data with the methods that operate on these data. It restricts direct access to some of the object’s components, which can prevent the accidental modification of data:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age  # Leading underscore suggests protected (by convention)

    def get_age(self):
        return self._age

# Direct access to _age is discouraged
john = Person("John", 28)
print(john.get_age())

Enter fullscreen mode Exit fullscreen mode

Polymorphism

Polymorphism allows for the interchangeability of components through a common interface. In Python, it’s more loosely applied, allowing different classes to be used interchangeably if they implement the same methods.

def animal_sound(animal):
    print(animal.speak("Hi there"))

animal_sound(my_dog)
animal_sound(my_cat)

Enter fullscreen mode Exit fullscreen mode

Congratulations on completing this quick crash course on Python basics! I hope this speedy overview has given you a solid foundation in Python programming, equipping you with the essential skills needed to embark on your AI and ML journey. While this guide covered the fundamentals, there's so much more to learn and explore when implementing practical solutions in the world of Artificial Intelligence and Machine Learning. As you continue to build on these basics, you'll discover the power and versatility of Python in solving complex problems and creating innovative solutions. Stay curious, keep coding, and get ready to transform your ideas into reality with Python!

Notebook version: https://github.com/mubbashir10/applied_ai/blob/main/Chapter%200%20-%20Python%20basics.ipynb

💖 💪 🙅 🚩
mubbashir10
Mubbashir Mustafa

Posted on June 25, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related