2.11. Packages and Libraries in Python#

2.11.1. What are packages?#

Packages (or libraries) are collections of modules with ready-to-use functions, classes, and tools—without needing to reinvent the wheel.

Famous examples:

  • math: mathematical operations

  • random: random number generation and selections

  • pandas: data analysis

  • matplotlib: graph visualization

2.11.2. Installing Packages with pip#

pip is Python’s official package manager. It installs libraries available from PyPI (Python Package Index).

2.11.2.1. How to install a package:#

pip install package_name

2.11.2.2. How to upgrade a package version:#

pip install --upgrade package_name

2.11.2.3. How to uninstall a package version:#

pip uninstall package_name

conda is a package and environment manager that is part of Anaconda/Miniconda. It is widely used in Data Science because it facilitates the installation of packages with native dependencies (like NumPy, TensorFlow, etc.).

2.11.2.4. How to install a package using conda:#

conda install numpy
conda install -c conda-forge package_name

Criterion

pip

conda

Source

PyPI

Conda repositories

Installation

Lighter and more direct

More robust and complex

Environments

Uses venv

Uses conda env (more comprehensive)

Speed

Fast

Slower (but manages dependencies)

Popularity

Universal (works with everything)

More used in data science

2.12. Importing Libraries in Python#

In Python, a library (or, more formally, a module or package) is a file or a collection of files containing Python code (functions, classes, variables) that can be reused in other programs. Think of them as toolboxes: you don’t need to build a screwdriver every time you need one; you simply pick it from your toolbox.

2.12.1. Why Import?#

  1. Code Reusability: Prevents you from reinventing the wheel. Many common tasks (mathematics, string manipulation, web access, machine learning) have already been implemented efficiently.

  2. Organization: Helps organize large projects into smaller, manageable files.

  3. Collaboration: Facilitates the use of code written by other developers.

  4. Specialized Functionality: Provides access to functionalities that are not part of Python’s “core” but are essential for specific tasks (like numpy for numerical arrays, matplotlib for plotting).

2.12.2. How to Import Libraries#

There are several ways to import modules in Python, depending on what you need and how you want to reference the imported items.

2.12.2.1. Standard Import: import module_name#

This is the most common way. It imports the entire module, and you need to use the module name as a prefix to access its functions and variables.

  • Advantage: Avoids name conflicts if different modules have functions or variables with the same name.

  • Disadvantage: Can make the code slightly longer.

Example:

import math # 'math' module for mathematical functions

radius = 5
area = math.pi * (radius ** 2) # Accessing 'pi' from the 'math' module
print(f"The area of the circle is: {area}")
# Output: The area of the circle is: 78.53981633974483

2.12.2.2. Import with Alias: import module_name as alias#

Allows you to give a nickname (alias) to the module. This is useful for modules with long names or when there are widely accepted alias conventions.

  • Advantage: Makes the code more concise without losing clarity of the function’s origin.

  • Disadvantage: If the alias is not intuitive, it can make the code harder to read.

Example:

import numpy as np # 'np' is the conventional alias for NumPy

arr = np.array([1, 2, 3, 4, 5]) # Using the alias 'np' to access the 'array' function
print(f"NumPy Array: {arr}")
print(f"Sum of the array: {np.sum(arr)}")
# Output:
# NumPy Array: [1 2 3 4 5]
# Sum of the array: 15

2.12.2.3. Selective Import: from module_name import item1, item2#

Allows you to import only specific functions, classes, or variables from a module. You can then use these items directly, without the module prefix.

  • Advantage: Cleaner and more concise code, as it eliminates the prefix.

  • Disadvantage: Increases the risk of name conflicts if you import items with the same name from different modules.

Example:

from datetime import date # Importing only the 'date' class from the 'datetime' module

today = date(2025, 6, 22) # Using 'date' directly
print(f"Today's date: {today}")
# Output: Today's date: 2025-06-22

2.12.2.4. Import All: from module_name import *#

This form imports all public items from a module directly into the current namespace.

  • Advantage: Extremely concise.

  • Disadvantage: Strongly discouraged in most cases! It pollutes the current namespace with many names, dramatically increasing the risk of name conflicts and making it difficult to tell where a function or variable came from. Use only in very small scripts or for debugging.

Example (for demonstration, but not recommended):

from math import * # NOT RECOMMENDED IN PRODUCTION CODE

radius = 5
area = pi * (radius ** 2) # 'pi' is accessed directly
print(f"The area of the circle is: {area}")
# Output: The area of the circle is: 78.53981633974483

2.12.3. Where to Place Imports#

By convention (and good practice), all import statements should be placed at the top of the Python file, after any file comments (docstrings) and before any other code. This makes the code more readable and helps to quickly identify the file’s dependencies.