Unit 3 · Big Idea 3
Build Your Library
Student Lab · Write Once, Use Everywhere
Student PIN:
Overview
You’ve built a lot of useful — move_arm, move_claw, back_until_pressed, Tick_Drive, line_follow — but every time you start a new program, you’ve had to type them all again. That ends today. You’ll gather all your best functions into one : a single file you write once and pull into any program with one line. Real programmers don’t rewrite their tools; they build a toolbox and carry it everywhere.
Core Insight
A library lets you write a function once and reuse it in every program forever. Your main stays short and readable, and all your tools live in one organized place.
By the end of this activity you will be able to:
- Create a Python file named after yourself and add it to your project.
- Move your reusable functions into that file, organized and documented.
- Import your library with
from yourname import *and call its functions frommain.
Phase 1 — Turn On Advanced Mode
The IDE normally hides its more powerful features to keep things simple. To work with libraries, you need Advanced mode. This is a setting on the user — so it must be turned on for any user you want to have advanced features.
- Click the menu button in the upper-left corner.
- Open User Preferences.
- Change the interface setting to Advanced.
- Go back to the project menu.
What changed?
Back in your project, look at the right side of the screen. You’ll see new areas that weren’t there before — including places for your project’s modules. That’s where your library will live.
After switching to Advanced and returning to your project, what new areas appeared on the right side of the screen that you didn’t see before?
Phase 2 — Concept: What a Library Is
Every program you’ve written already uses a library: the very first line, import _kipr as k, pulls in KIPR’s library — that’s where k.motor, k.analog, k.set_servo_position, and all the rest come from. You never wrote those; you imported them.
Today you build your own library the same way: a file holding your functions, that you pull into any program with one import line.
In Python, a library is just another file ending in .py — called a module. There’s no separate like KIPR’s library uses behind the scenes; your file is the whole thing, code and all. When you write:
from yourname import * # pulls your whole library into this program…the IDE reaches into yourname.py and makes everything in it available here, just like KIPR’s library. Because your library lives in the same project folder, Python knows where to find it.
You’ve been using import _kipr as k all along. Now that you know what it does, explain in your own words what an import line actually does.
Phase 3 — Create Your Library File
First, make sure your user is set to the advanced mode so that you can create new files. From the IDE homescreen, click on User Preferences, select your user from the menu at the top, then set the interface mode to Advanced.
Then, go to the project you created and in the file area on the right, create a new Python file. Name it after yourself, using your first name and the file extension .py — for example, maria.py or devon.py. This is your library.
Watch out for name collisions
A few names are already taken — by Python itself. If your first name happens to match a built-in module like math, random, os, or time, naming your library that exact word will break your own import, because Python will find its own module first. If that’s you, add your last initial (math_r.py) or use your last name instead.
| Your library file name | Write it here |
|---|---|
| your first name + .py |
It's portable
Once your library exists, you can take it anywhere. Select it and use the File menu to download it, then drop it into any other project. Write your tools once, carry them forever.
Phase 4 — Move Your Functions Into the Library
Now fill your library with every reusable function you’ve built. Organize it in two clear sections, in this order: at the top, then function definitions. This is the same structure you’ve used all along — now it lives in your library. Python doesn’t use separate like you may have used before; a function just needs to be defined above the point where it’s called.
# ============================================================
# yourname.py: My Botball function library
# Every reusable tool I've built, in one place.
# ============================================================
import os, sys
sys.path.append("/usr/lib")
import _kipr as k
# ---- VARIABLES (my robot's tuned values) ----
# These live here so the whole library can use them. You can also
# move them into main() if you'd rather set them per program.
ARM_MIN = ____
ARM_MAX = ____
CLAW_OPEN = ____
CLAW_SHUT = ____
MIDPOINT = ____
FAST = ____
SLOW = ____
# ---- FUNCTION DEFINITIONS (the recipes) ----
# Servo movement notes:
# - A one-tick command does not actually move the servo, so step by two.
# - Repeated get_servo_position calls can overload the controller. Store
# each reading in current_position and refresh it once per loop.
# move_arm: Smoothly moves the arm servo (port 0) to a position.
# - Clamps the value into the safe range so the servo can't be
# forced past a hard stop and burned out.
# - Steps two ticks at a time for smooth motion.
# Pass in the arm position you want (e.g. ARM_MIN to raise).
def move_arm(target_position):
if target_position > ARM_MAX: target_position = ARM_MAX
if target_position < ARM_MIN: target_position = ARM_MIN
current_position = k.get_servo_position(0)
while current_position != target_position:
# A 2-tick step could skip a target that is only 1 tick away.
if abs(current_position - target_position) == 1:
k.set_servo_position(0, target_position)
elif current_position < target_position:
k.set_servo_position(0, current_position + 2)
else:
k.set_servo_position(0, current_position - 2)
k.msleep(1)
current_position = k.get_servo_position(0)
# move_claw: Smoothly moves the claw servo (port 3) to a position.
# Works just like move_arm, but for the claw. Clamps between
# CLAW_SHUT and CLAW_OPEN so the claw never strains.
# Pass in CLAW_OPEN to open, CLAW_SHUT to close on a cube.
def move_claw(target_position):
if target_position < CLAW_OPEN: target_position = CLAW_OPEN
if target_position > CLAW_SHUT: target_position = CLAW_SHUT
current_position = k.get_servo_position(1)
while current_position != target_position:
# A 2-tick step could skip a target that is only 1 tick away.
if abs(current_position - target_position) == 1:
k.set_servo_position(3, target_position)
elif current_position < target_position:
k.set_servo_position(3, current_position + 2)
else:
k.set_servo_position(3, current_position - 2)
k.msleep(1)
current_position = k.get_servo_position(1)
# back_until_pressed: Drives the robot straight backward until the
# touch sensor on k.digital(0) is pressed against a wall, then stops.
# Use it to return to a wall and reset to a known position.
def back_until_pressed():
while k.digital(0) == 0:
k.motor(0, -50)
k.motor(3, -50)
k.msleep(10)
k.motor(0, 0); k.motor(3, 0); k.msleep(50)
# Tick_Drive: Drives the robot straight forward a measured distance.
# Pass in the number of encoder ticks to travel. Clears the
# counter, drives until it reaches 'ticks', then brakes.
def Tick_Drive(ticks):
k.cmpc(0)
while k.gmpc(0) < ticks:
k.motor(0, 50)
k.motor(3, 50)
k.motor(0, 0); k.motor(3, 0); k.msleep(50)
# line_follow: Follows a line for a measured distance using the
# Tophat sensor on k.analog(0). Steers with k.mav based on whether
# the reading is above MIDPOINT (black) or below (white).
# Pass in the number of ticks to follow before stopping.
def line_follow(ticks):
k.cmpc(0)
while k.gmpc(0) < ticks:
if k.analog(0) > MIDPOINT:
k.mav(0, FAST); k.mav(1, SLOW)
else:
k.mav(0, SLOW); k.mav(1, FAST)
k.motor(0, 0); k.motor(3, 0); k.msleep(50)like a teacher
Notice every function has a comment explaining what it does, written for someone who has never seen it before. That’s your job here: above each function, write a clear note saying what it does, what you pass in, and what happens. One day that “someone” will be you, six months from now — and you’ll be glad you wrote it.
Pick one of your functions. Write the comment you’d put above it to explain it to a brand-new user who has never seen your code.
Phase 5 — Import It and Call Every Function
Now the payoff. In your main program, add your library with a from yourname import * line at the top — right under the KIPR one. Then your main can call any function in your library. Test every function once to prove the library works.
#!/usr/bin/python3
import os, sys
sys.path.append("/usr/lib")
import _kipr as k # KIPR's library
from yourname import * # Import YOUR library to get all your tools in one line.
def main():
k.enable_servo(0)
k.enable_servo(1)
# Call each library function once to test it:
Tick_Drive(2000) # drive forward a measured distance
back_until_pressed() # back into the wall
line_follow(1500) # follow the line a while
move_claw(CLAW_OPEN) # open the claw
move_arm(ARM_MAX) # lower the arm
move_claw(CLAW_SHUT) # close on a cube
move_arm(ARM_MIN) # raise it up
main()See how short and readable main is now? Every line says what happens, and the how lives in your library. That’s the power of organizing your code.
Test Each Function
Run your program and check off each function as you confirm it works from the library.
Did every function work when called from your library? If one didn’t, what was the problem and how did you fix it?
Phase 6 — Connect: The AI Literacy Bridge
AI Literacy Thread
Complex intelligent systems are built from organized, reusable building blocks.
No one builds a giant intelligent system as one enormous program. They build small, tested, reusable pieces and organize them into libraries — then combine those pieces into something big. The code that runs a self-driving car, a phone, or an AI model is built on layers of libraries, most written by other people, each one a tool someone built once and shared. Today you took your own scattered tools and organized them into a library. That’s exactly how real software is built: not by rewriting everything, but by standing on well-organized, reusable parts.
Read each scenario. Think it through, then write your answer.
Why is it better to keep your functions in one library than to copy-paste them into every new program? Think about what happens when you find a bug.
You wrote comments for a user who’s never seen your code. Why is clear documentation so important when code is meant to be reused by others — or by your future self?
Phase 7 — Individual Reflection
Complete this section on your own.
1. What is a library, and what does the import line do?
2. What two sections did you organize your library into, and in what order?
3. How does moving your functions into a library make your main program easier to read?
4. Complete in 2–3 sentences: “Complex intelligent systems are built from organized, reusable building blocks. This means that a good programmer spends time…”
Extension Challenges
Finished early? Try one or more of these.
Extension A — Add a Helper
- Write one brand-new function (like
stop_and_hold()oropen_then_lower()) and add it to your library, fully commented. Call it frommain.
Extension B — Share It
- Download your library through the File menu and trade with a partner. Can you read and use their functions from their comments alone? What made it easy or hard?
Extension C — A Combined Behavior
- Write a function in your library that calls other library functions — for example,
grab_cube()that opens, lowers, closes, and raises. Why is building big functions from small ones powerful?
Extension D — Looking Ahead: Turns
- Soon you’ll need the robot to turn exactly 90° left and right. What would you name those functions, and where will they go once you’ve perfected them?
Extension E — Whose Code Is It?
- You just shared your library with a partner (Extension B). If you posted it online for any team to download, what could they do with it — use it as-is? Modify it and call it theirs? Sell it?
- Write one sentence saying what you would and wouldn’t allow, and give your library a one-line “license” note at the top of the file.
Extension F — Ready for Strangers?
- Extension B had one partner try your library. Now imagine every Botball team in your region wanted to use it. What would you need to add or change (documentation, defaults, error-checking) before a total stranger could use it without you there to explain anything?
- Would your library work unmodified on a different KIPR model, or would some functions need adjusting? Sketch what “version 2” would need before a public release.
When you are finished, press the button to turn in your work and save a copy.
KIPR · Botball Explorer · Unit 3 Big Idea 3 — Student Lab