Modules

As Python programs become larger, putting all the code into one file quickly becomes difficult to manage. Modules allow us to organize code into separate files and reuse functions, variables, and classes in other programs.

This is especially useful in PyMedLab projects, where we might want separate code for DICOM handling, image analysis, statistics, visualization, and medical physics calculations.


What Is a Module?

A module is simply a Python file containing reusable Python code.

For example, suppose we create a file called:

medical_calculations.py

Inside it, we define some functions:

def calculate_mean(values):
    return sum(values) / len(values)


def calculate_range(values):
    return max(values) - min(values)


def calculate_snr(signal, noise):
    return signal / noise

medical_calculations.py is now a Python module.

Instead of copying these functions into every program, we can import the module whenever we need them.


Why Use Modules?

Imagine that you are developing several medical imaging programs.

One program analyzes CT images, another performs quality-control calculations, and another analyzes DICOM metadata.

Without modules, you might repeatedly write the same functions.

With modules, you can organize the project like this:

pymedlab_project/
│
├── main.py
├── medical_calculations.py
├── image_analysis.py
└── dicom_utils.py

Each file has a specific responsibility.

For example:

medical_calculations.py → calculations
image_analysis.py       → image-processing functions
dicom_utils.py          → DICOM functions
main.py                 → main program

This makes the project easier to read, test, maintain, and reuse.


Importing a Module

Python uses the import keyword to load a module.

For example, Python already includes a module called math.

import math

result = math.sqrt(25)

print(result)

Output:

5.0

Here:

import math

loads the module.

Then:

math.sqrt(25)

uses the sqrt() function contained in that module.

The general structure is:

module_name.function_name()

Importing Specific Functions

Sometimes we only need one function from a module.

Instead of:

import math

result = math.sqrt(25)

we can write:

from math import sqrt

result = sqrt(25)

print(result)

Now we can call sqrt() directly.


Importing Multiple Functions

Several functions can also be imported:

from math import sqrt, pi

radius = 5

area = pi * radius ** 2

print(area)

This imports both:

sqrt
pi

from the math module.


Using an Alias

Modules can also be imported using a shorter name called an alias.

For example:

import numpy as np

Now instead of writing:

numpy.mean(values)

we write:

np.mean(values)

This convention is extremely common in scientific Python.

You will frequently encounter:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

These aliases are standard conventions used throughout the Python scientific ecosystem.


Built-in, Third-Party, and Your Own Modules

It is useful to distinguish between three types of modules.

TypeExamplesDescription
Built-in / standard librarymath, statistics, os, pathlibIncluded with Python
Third-partynumpy, pandas, matplotlib, pydicomInstalled separately
Your own modulesimage_analysis.pyPython files you create

For example:

import math

uses Python’s standard library.

Whereas:

import numpy as np

requires NumPy to be installed in your Python environment.

And:

import image_analysis

could import a module that you created yourself.


Creating Your Own Module

Let’s create a small PyMedLab project.

Create two files:

pymedlab_project/
│
├── main.py
└── image_analysis.py

Step 1 — image_analysis.py

Add:

def calculate_mean(values):
    return sum(values) / len(values)


def calculate_range(values):
    return max(values) - min(values)


def calculate_snr(signal, noise):
    return signal / noise

This file is our module.


Step 2 — main.py

Now import it:

import image_analysis

hu_values = [-105, -98, -101, -95, -103]

mean_hu = image_analysis.calculate_mean(hu_values)
hu_range = image_analysis.calculate_range(hu_values)

print("Mean HU:", mean_hu)
print("HU range:", hu_range)

The functions are defined in one file but used in another.

This is one of the main advantages of modules.


Importing Your Own Function Directly

Instead of importing the complete module:

import image_analysis

we can import a specific function:

from image_analysis import calculate_mean

hu_values = [-105, -98, -101, -95, -103]

mean_hu = calculate_mean(hu_values)

print("Mean HU:", mean_hu)

Notice that we no longer need:

image_analysis.calculate_mean()

We can simply use:

calculate_mean()

Importing with an Alias

Your own modules can also use aliases:

import image_analysis as ia

hu_values = [-105, -98, -101, -95, -103]

mean_hu = ia.calculate_mean(hu_values)

print(mean_hu)

This can be useful when module names are long.

However, aliases should remain clear and understandable.


A Medical Imaging Example

Suppose we create:

dicom_utils.py

with:

def display_scan_info(modality, rows, columns):
    print("Modality:", modality)
    print("Image matrix:", rows, "x", columns)

Then another program can use it:

import dicom_utils

dicom_utils.display_scan_info(
    modality="CT",
    rows=512,
    columns=512
)

Output:

Modality: CT
Image matrix: 512 x 512

Later in the PyMedLab course, this concept can be extended to actual DICOM datasets using pydicom.


Modules Can Contain More Than Functions

Modules are not limited to functions.

A module can contain:

Functions
Variables
Classes
Constants
Other imported modules

For example:

DEFAULT_MODALITY = "CT"


def calculate_mean(values):
    return sum(values) / len(values)


class MedicalImage:
    pass

All of these can exist inside the same module.


if __name__ == "__main__"

You will frequently encounter this:

if __name__ == "__main__":
    print("Running image analysis...")

It allows Python to distinguish between:

running a file directly

and

importing the file as a module.

Consider:

def calculate_mean(values):
    return sum(values) / len(values)


if __name__ == "__main__":
    hu_values = [-100, -98, -102]
    print(calculate_mean(hu_values))

If we run:

python image_analysis.py

the code inside the if block runs.

But if another file does:

import image_analysis

the code inside that block does not run automatically.

This becomes very useful as projects grow.


Avoid import *

Python allows:

from image_analysis import *

but this is generally best avoided.

It becomes difficult to determine where names came from and can create naming conflicts.

Prefer:

import image_analysis

or:

from image_analysis import calculate_mean

These are clearer.


From Modules to a PyMedLab Project

Students can now start building projects with meaningful structure:

ct_analysis/
│
├── main.py
│
├── dicom_utils.py
├── image_analysis.py
├── statistics_utils.py
│
└── data/

For example:

dicom_utils.py
    ↓
Read and handle DICOM information

image_analysis.py
    ↓
Analyze image values

statistics_utils.py
    ↓
Perform statistical calculations

main.py
    ↓
Bring everything together

This is an important transition from learning individual Python statements to building maintainable scientific programs.


Exercises

Exercise 1 — Standard Library

Import Python’s math module and calculate the square root of:

144

Expected result:

12.0

Exercise 2 — Import a Specific Function

Import only sqrt from math and calculate:

sqrt(81)

Exercise 3 — Create Your Own Module

Create:

dose_calculations.py

Add:

def calculate_total_dose(dose_per_fraction, fractions):
    return dose_per_fraction * fractions

Then create:

main.py

Import the module and calculate the total dose for:

2 Gy × 25 fractions

Exercise 4 — Medical Imaging

Create:

image_statistics.py

containing functions that calculate:

Mean
Minimum
Maximum
Range

Then import the module into main.py and analyze:

hu_values = [-105, -98, -101, -95, -103]

PyMedLab Challenge

Build this small project:

ct_qc/
│
├── main.py
├── ct_statistics.py
└── dose_calculations.py

ct_statistics.py should contain functions for:

Mean HU
Minimum HU
Maximum HU
HU range

dose_calculations.py should contain a simple dose calculation function.

Finally, use both modules from:

main.py

This exercise demonstrates why modules become valuable in real scientific software.


Key Takeaways

  • A module is a Python file containing reusable code.
  • Modules help organize larger programs.
  • import loads a module.
  • from module import function imports a specific component.
  • as creates an alias.
  • Python provides standard-library modules such as math.
  • Libraries such as NumPy, Pandas, Matplotlib, and pydicom provide third-party modules.
  • You can create your own modules simply by creating .py files.
  • Modules make scientific code easier to reuse, test, and maintain.
  • if __name__ == "__main__": separates code intended to run directly from code intended to be imported.

What’s Next?

The natural next lesson is Packages & Project Structure. That will explain how multiple modules are organized into packages and prepare students for the structure they will encounter later with NumPy, pydicom, image-processing projects, and PyMedLab’s GitHub repositories.


Leave a Reply

Your email address will not be published. Required fields are marked *