"The future belongs not to the ones who write AI prompts, but to the ones who can read the code and understand the logic."/// The Beaverbit Philosophy
From code to hardware in seconds.
A coding platform and a physical board, built to work together.
Write code in a browser-based editor with an AI tutor that guides you through challenges by asking the right questions, not giving answers.
An ESP32-based board packed with everything you need to see your Python come alive. You write the code — the board proves it works.
Four steps. Zero to code running on real hardware.
Guided challenges matched to your level.
Python or C++ with AI guidance when you get stuck.
One click. The platform handles compilation.
LED blinks. Sensor reacts. Proof your logic works.
23 levels. From your first function call to design patterns, algorithms, and inventions nobody has thought of yet. You're learning Python — the board just proves your code works.
Already know Python? Skip to Level 23 — The Invention Lab. The board is waiting for your ideas.
How to import a module, call a function, and understand what happens when you run a line of code. Your very first program.
# Your first program
from beaverbit import Board
board = Board()
board.led.on()Loops that repeat forever, controlling timing with sleep(), and understanding how programs flow from top to bottom — and back again.
# Make it blink
import time
while True:
board.led.on()
time.sleep(0.5)
board.led.off()
time.sleep(0.5)Storing data in variables, understanding types (int, float, string), and using print() to see what your program knows.
# Read and remember
temp = board.sensor.temperature()
light = board.sensor.light()
board.screen.show(f"Temp: {temp}C")
board.screen.show(f"Light: {light}")Branching logic with conditionals. Your program reacts differently based on what's happening — just like real software does.
# React to input
if board.button.a_pressed():
board.led.color("green")
board.speaker.tone(440)
elif board.button.b_pressed():
board.led.color("red")
board.speaker.tone(880)
else:
board.led.off()Creating your own functions with def, passing parameters, returning values. You stop repeating code and start organizing it.
# Create reusable commands
def alarm(frequency, duration):
board.led.color("red")
board.speaker.tone(frequency)
time.sleep(duration)
board.speaker.off()
board.led.off()
alarm(1000, 0.5)
alarm(2000, 0.3)Storing multiple values in lists, iterating with for loops, and using indexing. You go from single actions to orchestrated sequences.
# Play a melody
melody = [262, 294, 330, 349, 392]
times = [0.4, 0.4, 0.4, 0.4, 0.8]
for note, dur in zip(melody, times):
board.speaker.tone(note)
time.sleep(dur)
board.speaker.off()String manipulation, formatting with f-strings, slicing, and building dynamic messages from data. Text becomes a tool.
# Dynamic display
name = "Lab 3"
temp = board.sensor.temperature()
status = "OK" if temp < 30 else "HOT"
message = f"{name} | {temp}C | {status}"
board.screen.scroll(message)Key-value pairs with dictionaries, looking up data, and mapping ranges of input to meaningful output. Structure meets logic.
# Map data to meaning
icons = {
"cold": "***",
"nice": "+++",
"hot": "!!!"
}
temp = board.sensor.temperature()
if temp < 15: mood = "cold"
elif temp < 28: mood = "nice"
else: mood = "hot"
board.screen.show(icons[mood])Object-oriented programming: classes, __init__, methods, and self. You stop writing scripts and start designing systems.
# Build your own instrument
class Instrument:
def __init__(self, board):
self.board = board
self.octave = 4
def play(self, note):
freq = self.note_to_freq(note)
self.board.speaker.tone(freq)
def note_to_freq(self, note):
notes = {"C": 262, "D": 294,
"E": 330, "G": 392}
return notes[note] * self.octave
piano = Instrument(board)
piano.play("C")Exception handling with try/except/finally, raising your own errors, and reading tracebacks. Bugs aren't failures — they're data.
# Catch and handle errors
try:
temp = board.sensor.temperature()
if temp > 100:
raise ValueError("Sensor overload")
board.screen.show(f"{temp}C")
except ValueError as e:
board.led.color("red")
board.screen.show(f"ERR: {e}")
except Exception:
board.screen.show("Unknown error")
finally:
board.speaker.beep()Tuples for immutable data, sets for unique values, slicing for subsets, and choosing the right collection for the job.
# Track unique events
COLORS = ("red", "green", "blue")
seen_temps = set()
while True:
temp = round(board.sensor.temperature())
seen_temps.add(temp)
unique = len(seen_temps)
last_5 = sorted(seen_temps)[-5:]
board.screen.show(
f"{unique} unique | {last_5}"
)
time.sleep(1)List comprehensions, dict comprehensions, lambda functions, map/filter. Writing elegant Python that does more in fewer lines.
# Elegant data processing
readings = [board.sensor.temperature()
for _ in range(20)]
hot = [t for t in readings if t > 28]
avg = sum(readings) / len(readings)
label = sorted(readings,
key=lambda t: abs(t - avg)
)[0]
board.screen.show(
f"Avg:{avg:.1f} Hot:{len(hot)}"
)Reading and writing files, logging data over time, and understanding persistence. Your program remembers things between runs.
# Log temperature over time
import json
readings = []
for i in range(10):
temp = board.sensor.temperature()
readings.append({
"sample": i,
"temp": temp
})
time.sleep(2)
with open("log.json", "w") as f:
json.dump(readings, f)Connecting to WiFi, making HTTP requests, and parsing API responses. Your board talks to the internet.
# Fetch live weather
import urequests
board.wifi.connect("SchoolNet", "pass")
r = urequests.get(
"http://api.weather.com/montreal"
)
data = r.json()
board.screen.show(
f"Montreal: {data['temp']}C"
)Running multiple tasks simultaneously with threading. Your program does two things at once — like real software.
# Monitor while displaying
import _thread
def watch_gyro():
while True:
tilt = board.gyro.angle()
if abs(tilt) > 45:
board.led.color("red")
else:
board.led.color("green")
time.sleep(0.1)
_thread.start_new_thread(watch_gyro, ())
while True:
board.screen.show(
f"Tilt: {board.gyro.angle()}"
)
time.sleep(0.2)Parsing JSON, working with REST APIs, sending and receiving structured data. You build real integrations with the outside world.
# Live dashboard
def get_data():
r = urequests.get(API_URL)
return r.json()
while True:
data = get_data()
board.screen.clear()
board.screen.line(0,
f"Users: {data['active']}")
board.screen.line(1,
f"Temp: {data['temp']}C")
board.screen.line(2,
f"Status: {data['status']}")
time.sleep(5)Functions that modify functions, the @decorator syntax, and generators with yield for memory-efficient data streams. Advanced Python patterns used in real frameworks.
# Decorator: log every action
def log_action(func):
def wrapper(*args, **kwargs):
board.screen.show(
f"Running: {func.__name__}"
)
result = func(*args, **kwargs)
board.screen.show("Done")
return result
return wrapper
@log_action
def read_all_sensors():
return {
"temp": board.sensor.temperature(),
"light": board.sensor.light(),
"tilt": board.gyro.angle()
}
# Generator: stream readings
def sensor_stream():
while True:
yield board.sensor.temperature()
time.sleep(0.5)Organizing code into modules and packages, understanding __init__.py, importing your own libraries, and using third-party packages. Your code becomes a project.
# my_project/sensors/climate.py
class ClimateStation:
def __init__(self, board):
self.board = board
self.history = []
def sample(self):
reading = {
"temp": self.board.sensor.temp(),
"light": self.board.sensor.light()
}
self.history.append(reading)
return reading
# main.py
from sensors.climate import ClimateStation
station = ClimateStation(board)
data = station.sample()Writing tests with assert, unittest, and test-driven development. Proving your code works before you even run it on hardware. The professional way.
# Test before you deploy
import unittest
class TestAlarm(unittest.TestCase):
def test_high_temp_triggers(self):
monitor = SmartMonitor(board)
monitor.alerts["hot"] = 30
# Simulate hot reading
result = monitor.evaluate(35)
self.assertTrue(result.triggered)
self.assertEqual(
result.message, "Temperature!"
)
def test_normal_temp_safe(self):
monitor = SmartMonitor(board)
result = monitor.evaluate(22)
self.assertFalse(result.triggered)
unittest.main()Sorting algorithms, binary search, stacks, queues, and Big O thinking. The computer science that separates coders from engineers.
# Binary search sensor logs
def binary_search(data, target):
low, high = 0, len(data) - 1
while low <= high:
mid = (low + high) // 2
if data[mid]["temp"] == target:
return mid
elif data[mid]["temp"] < target:
low = mid + 1
else:
high = mid - 1
return -1
# Find when it hit 30C
logs = sorted(history,
key=lambda x: x["temp"])
idx = binary_search(logs, 30)
board.screen.show(f"Found at #{idx}")The Observer pattern for event-driven code, State pattern for mode switching, Factory pattern for creating objects. How real software is architected.
# Observer: react to events
class EventBus:
def __init__(self):
self._listeners = {}
def on(self, event, callback):
self._listeners.setdefault(
event, []).append(callback)
def emit(self, event, data=None):
for cb in self._listeners.get(
event, []):
cb(data)
bus = EventBus()
bus.on("hot", lambda t:
board.led.color("red"))
bus.on("hot", lambda t:
board.speaker.tone(1000))
temp = board.sensor.temperature()
if temp > 35:
bus.emit("hot", temp)Combining every concept into one guided project. Architecture, planning, debugging, iteration. You build a complete system from scratch.
# A complete smart device
class SmartMonitor:
def __init__(self, board):
self.board = board
self.log = []
self.alerts = {
"hot": 35, "tilt": 30
}
def check_alerts(self):
temp = self.board.sensor.temp()
angle = self.board.gyro.angle()
if temp > self.alerts["hot"]:
self.alarm("Temperature!")
if abs(angle) > self.alerts["tilt"]:
self.alarm("Movement!")
def alarm(self, msg):
self.board.speaker.tone(1000)
self.board.screen.show(msg)
self.log.append(msg)No instructions. No guide. No limits. Whether you just finished level 22 or you've been coding for years and want a playground with real hardware — this is where you build what doesn't exist yet. Experienced developers: skip straight here. The board is waiting.
# What will you invent?
#
# A gesture-controlled
# musical instrument?
# A motion-activated
# security system?
# A portable weather
# station with alerts?
# A multiplayer game
# over WiFi?
# A machine learning
# classifier on sensor data?
# A Morse code translator?
# A theremin?
#
# The board is yours.
# The code is yours.
# Invent.Every feature exists to build understanding, not shortcuts.
Guided hints, not answers. The AI understands your code and leads you to the solution.
Screen, speaker, LEDs, sensors, gyroscope, buttons, WiFi — everything to test your code.
Python and C/C++. Industry languages, not toy blocks.
23 levels from your first function call to building inventions nobody has thought of.
Code runs on real hardware in seconds. Immediate proof.
No installs. Open your browser, write code, upload to your board.
Whether you teach coding or want to learn it yourself.
Bring hands-on coding to your classroom with hardware students can hold.
Learn at your own pace with your own board, from anywhere.
Beaverbit is designed to slot into your existing CS, science, and math courses. Grades 9-12, CEGEP, and college intro — ready to go.
Each of the 23 levels comes with lesson plans, learning objectives, and assessments. Aligned with CS education standards and Quebec's QEP competencies.
See every student's progress in real time. Review their code, track challenge completion, and identify who needs help — all in one place.
30-unit kits built to last. Boards are reusable across semesters — no consumables, no replacements. One investment, years of use.
Browser-based platform. No software installs, no admin permissions needed. Works on school Chromebooks, laptops, and desktops.
Challenge completion tracking, code quality metrics, and progress reports you can export. Grading support without extra work.
Teachers choose which modules to assign, in what order, and at what pace. Fit Beaverbit into a semester, a year, or a single unit.
Your data stays in Canada. Your learning stays yours.
Founded in Montreal, Quebec. Data on Canadian servers.
We never sell your data or use student work to train AI.
Quebec Law 25 & PIPEDA compliant. Ages 16+.
You can't be a real programmer until you get these.
Why do Python programmers prefer snakes?
Because they don't have class... until they define one.
Why was the function sad after returning?
It lost all its local variables.
A QA engineer walks into a bar. Orders 1 beer. Orders 0 beers. Orders 99999999 beers. Orders -1 beers. Orders a lizard.
First real customer walks in and asks where the bathroom is. The bar bursts into flames.
There are only 10 types of people in the world.
Those who understand binary, and those who don't.
What's a programmer's favorite hangout place?
Foo Bar.
["hip", "hip"]
(hip hip, array!)
A programmer's wife tells him: "Go to the store and get a loaf of bread. If they have eggs, get a dozen."
He came home with 12 loaves of bread. "They had eggs."
Why do programmers always mix up Halloween and Christmas?
Because Oct 31 == Dec 25.