Skip to Content
BonicBot A2DevelopmentPython ProgrammingLesson 12 - Modules & Code Reusability

Lesson 12 - Modules & Code Reusability

Learning Objective

Split code across multiple files using modules, import functions between them, and understand what an import statement actually does.


Introduction

Every lesson so far has lived inside a single Python file.

That works well for small programs, but as software grows, putting everything into one file becomes difficult to manage.

Python solves this with modules.

A module is simply a Python file (.py) that contains code you want to reuse elsewhere.

Instead of copying and pasting functions between files, you can place them in one module and import them wherever they’re needed.

You’ve actually been using modules since Lesson 1.

For example:

from bonicbot_bridge import BonicBot

Here, bonicbot_bridge is a module (technically a package made up of multiple modules), and you’re importing the BonicBot class from it.

Modules help make programs:

  • Easier to organize
  • Easier to maintain
  • Easier to test
  • Easier to reuse

What Is a Module?

Any Python file can be a module.

Example:

# helpers.py def greet(name): print(f"Hello, {name}!")

Another file can use it:

from helpers import greet greet("Aditi")

Output:

Hello, Aditi!

The function only needs to be written once.


Why Use Modules?


Creating Your First Module

File:

# helpers.py def is_prime(n): if n < 2: return False for divisor in range(2, n): if n % divisor == 0: return False return True

Another file:

# main.py from helpers import is_prime print(is_prime(17))

Output:

True

Code

helpers.py

# helpers.py — a module: just function definitions, nothing runs on its own def is_prime(n): if n < 2: return False for divisor in range(2, n): if n % divisor == 0: return False return True def is_palindrome(word): cleaned = word.lower() return cleaned == cleaned[::-1]

main.py

# main.py — imports and uses the module above from helpers import is_prime, is_palindrome print(is_prime(17)) print(is_palindrome("radar")) import helpers print(helpers.is_prime(18))

Expected Output

Click to see expected output

True True False

Two Ways to Import

Import Specific Names

from helpers import is_prime

Usage:

print(is_prime(17))

This places is_prime directly into your current file’s namespace.


Import the Entire Module

import helpers

Usage:

print(helpers.is_prime(17))

The function remains grouped under the module name.


Comparing Import Styles

StyleExampleCall Style
Import specific functionfrom helpers import is_primeis_prime(17)
Import moduleimport helpershelpers.is_prime(17)

Both approaches are valid.

Choose whichever improves readability for your project.


Where Does Python Look for Modules?

When Python sees:

import helpers

it searches for:

  1. The current folder
  2. Installed packages
  3. Python’s standard library locations

That’s why:

import math

works immediately.

And why:

from bonicbot_bridge import BonicBot

works after the SDK has been installed.


Reusing Code Across Projects

One of the biggest advantages of modules is that they encourage reusable code.

Instead of:

# project_a.py # copy function here # project_b.py # copy function again

you can write:

# helpers.py

once and import it everywhere.

This eliminates duplication and reduces maintenance work.


🔧 Under the Hood

What’s the difference between “from helpers import is_prime” and “import helpers”?

Both statements load the same module.

The difference is how names become available afterward.

Option 1

from helpers import is_prime

Python:

  1. Loads helpers.py
  2. Finds is_prime
  3. Places it directly into the current namespace

You can call:

is_prime(17)

without mentioning helpers.


Option 2

import helpers

Python:

  1. Loads helpers.py
  2. Keeps everything grouped under helpers

You call:

helpers.is_prime(17)

instead.


Important Detail

Python only executes a module once.

If multiple files import:

import helpers

Python loads it the first time and then reuses the already-loaded version.

This helps imports stay efficient.


Module Discovery

When Python imports:

import helpers

it first looks for:

helpers.py

in the same folder.

If it isn’t found there, Python searches installed packages and standard library locations.

This is exactly how packages such as:

math random pathlib bonicbot_bridge

are discovered.


Student Challenge

Challenge 1

Build a reusable statistics module named stats.py with helper functions, and import them into a main reporting script report.py.

  • In stats.py, define two functions:
    • mean(numbers): Calculates and returns the average of a list of numbers.
    • max_value(numbers): Finds and returns the highest value in a list.
  • In report.py, import mean and max_value from stats, pass in a list of test scores (such as [82, 91, 76, 88, 95]), and print the average (86.4) and highest score (95).

Hint

Notice that neither function in stats.py references scores directly.

They operate on whatever list is passed in as an argument, making them completely reusable for any collection of numbers across different projects.

Click to see solution

stats.py

# stats.py def mean(numbers): return sum(numbers) / len(numbers) def max_value(numbers): highest = numbers[0] for n in numbers[1:]: if n > highest: highest = n return highest

report.py

# report.py from stats import mean, max_value scores = [82, 91, 76, 88, 95] print(f"Average: {mean(scores):.1f}") print(f"Highest: {max_value(scores)}")

Expected Output:

Average: 86.4 Highest: 95

Challenge 2

Create a custom robot movement module named robot_moves.py and import its functions into a main control script challenge_use_robot_moves.py.

  • In robot_moves.py, define functions for robot actions:
    • patrol_square(bot, side_m=0.4, speed=0.2): Drives in a square using loops.
    • scan_surroundings(bot): Scans left/right with obstacle distance checks and returns a dictionary of readings.
    • wave_hello(bot): Moves arm or head servos to greet.
  • In challenge_use_robot_moves.py, import patrol_square, scan_surroundings, and wave_hello from robot_moves, and run them inside a BonicBot context block.

Full SDK method details are available in the Python SDK reference.

Hint

Any function defined in:

robot_moves.py

can immediately be imported in another script using:

from robot_moves import wave_hello

as long as both files are in the same folder. No extra configuration is required.

Click to see solution

robot_moves.py

# robot_moves.py def patrol_square(bot, side_m=0.4, speed=0.2): for _ in range(4): bot.drive_distance(side_m, speed=speed) bot.rotate_angle(90, speed=45.0) bot.stop() def scan_surroundings(bot): bot.look_left() left_distance = bot.get_min_obstacle_distance() bot.look_right() right_distance = bot.get_min_obstacle_distance() bot.look_center() return { "left": left_distance, "right": right_distance } def wave_hello(bot): print("Waving hello!") bot.move_left_arm(shoulder=90, elbow=30) bot.move_left_arm(shoulder=90, elbow=0) bot.move_left_arm(shoulder=0, elbow=0)

challenge_use_robot_moves.py

# challenge_use_robot_moves.py from bonicbot_bridge import BonicBot from robot_moves import patrol_square, scan_surroundings, wave_hello with BonicBot(host='192.168.0.188') as bot: wave_hello(bot) readings = scan_surroundings(bot) print(f"Obstacle readings: {readings}") patrol_square(bot, side_m=0.3)

Common Module Structure

A small project might look like:

project/ ├── main.py ├── helpers.py ├── stats.py └── robot_moves.py

Each file has a clear responsibility.

This organization becomes increasingly important as projects grow.


Reflection Question

robot_moves.py is a module you wrote yourself, and bonicbot_bridge is a module BonicBot Robotics wrote — but both get imported with the exact same from ... import ... syntax. What does that tell you about what an SDK or library actually is, underneath the name?


By the end of this lesson, you should be comfortable creating modules, importing functions between files, choosing between different import styles, and organizing reusable code into separate, maintainable components.

Last updated on