N NovaBrief.tech
CS50P-Aligned Interactive Course CPython 3.12 WebAssembly Sandbox

Learn & Practice Real Python in Your Browser

Move beyond passive video tutorials. Study all 10 structured engineering modules below, test your understanding with our instant interactive quiz, and launch our full CPython 3.12 sandbox to run code, pass automated unit tests, and earn XP.

10
Structured Modules

Variables to OOP, Regex & File I/O

57
Coding Exercises

Auto-graded with instant hints

30
Concept Quizzes

+ 20-Question Grand Exam

10
Debugging Labs

Fix real production-style bugs

Try Right Now · No Login Needed

5-Question Python Skill Check

Score: 0 / 5
Module 1 · Functions & variables

What does print(" python ".strip().title()) display?

Module 2 · Conditionals

What is the value of 7 % 2 == 1 and not False?

Module 3 · Loops

What does list(range(2, 7, 2)) contain?

Module 4 · Exceptions

int("three") raises which exception?

Module 5 · Libraries

How do you decode a JSON string?

Complete Open Syllabus

All 10 Python Engineering Modules & Code Examples

Open Full Interactive IDE →
Module 1 Beginner 2 Lessons · 5 Exercises · 3 Quiz Qs

Functions & variables

Turn an idea into a small, precise Python program.

Solve 5 Exercises in Sandbox

A warmer welcome

input() returns text. String methods return a new string; an f-string inserts values into text.

name = input().strip().title()
print(f"Welcome, {name}!")

Split the receipt

Convert numeric text before arithmetic. Formatting with :.2f keeps two decimal places.

bill = float(input())
people = int(input())
print(f"{bill / people:.2f}")
Hands-On Labs: A warmer welcome (Beginner) Split the receipt (Beginner) Reusable conversions (Developing) Default delivery (Developing) Debug: text is not a number (Developing)
Run in Browser Sandbox →
Module 2 Beginner 2 Lessons · 5 Exercises · 3 Quiz Qs

Conditionals

Teach your program to make careful decisions.

Solve 5 Exercises in Sandbox

Choose a ticket

An if/elif chain chooses the first matching branch. Check boundaries carefully.

age = int(input())
if age < 0: print("invalid")
elif age < 13: print("child")
elif age < 18: print("teen")
else: print("adult")

Calendar logic

Parentheses make combinations of and/or easier to review. Modulo tests divisibility.

y = int(input())
print("leap" if y % 400 == 0 or (y % 4 == 0 and y % 100 != 0) else "common")
Hands-On Labs: Choose a ticket (Beginner) Calendar logic (Developing) Command router (Developing) Two keys to entry (Beginner) Debug: boundary birthday (Developing)
Run in Browser Sandbox →
Module 3 Beginner 2 Lessons · 5 Exercises · 3 Quiz Qs

Loops

Work with collections and repeat with purpose.

Solve 5 Exercises in Sandbox

A running total

A sentinel marks the end of input. Test the sentinel before adding it to the total.

total = 0
while True:
    n = int(input())
    if n == 0: break
    total += n
print(total)

Count the words

A dictionary connects keys to values; get(key, default) handles a new word.

counts = {}
for word in input().lower().split():
    counts[word] = counts.get(word, 0) + 1
for word in sorted(counts):
    print(f"{word}:{counts[word]}")
Hands-On Labs: A running total (Beginner) Count the words (Developing) Build a number grid (Developing) Keep the useful values (Beginner) Fill: the missing endpoint (Developing)
Run in Browser Sandbox →
Module 4 Intermediate 2 Lessons · 5 Exercises · 3 Quiz Qs

Exceptions

Make programs that recover from unexpected input.

Solve 5 Exercises in Sandbox

Ask until it is an integer

Catch the specific error you expect. The else block runs only when the try block succeeds.

while True:
    try: n = int(input())
    except ValueError: continue
    else:
        print(n * 2)
        break

Divide safely

Different exceptions deserve different feedback. Avoid a bare except that hides unrelated failures.

a, b = input(), input()
try: print(f"{float(a)/float(b):.2f}")
except ValueError: print("invalid")
except ZeroDivisionError: print("undefined")
Hands-On Labs: Ask until it is an integer (Beginner) Divide safely (Developing) Validate a percentage (Developing) Read to the end (Developing) Debug: the wrong exception (Developing)
Run in Browser Sandbox →
Module 5 Intermediate 2 Lessons · 5 Exercises · 3 Quiz Qs

Libraries

Build on reusable tools and structured data.

Solve 5 Exercises in Sandbox

A small data summary

The standard library offers tested tools. Import modules before using their names.

import statistics
values = list(map(int, input().split()))
print(f"{statistics.mean(values):.1f}")
print(f"{statistics.median(values):.1f}")

Reproducible randomness

A dedicated seeded generator makes simulations reproducible without changing unrelated random state.

import random
rng = random.Random(int(input()))
print(*[rng.randint(1, 6) for _ in range(5)])
Hands-On Labs: A small data summary (Beginner) Reproducible randomness (Developing) Read an API response (Developing) Command-line greeter (Developing) Fill: decode the response (Developing)
Run in Browser Sandbox →
Module 6 Intermediate 2 Lessons · 6 Exercises · 3 Quiz Qs

Unit testing

Prove that your code works at the boundaries.

Solve 6 Exercises in Sandbox

Turn cases into assertions

Assertions fail loudly when a condition is false. Include zero, negative inputs, and contrasting cases.

def is_even(n): return n % 2 == 0
assert is_even(0)
assert is_even(-2)
assert not is_even(3)
print(is_even(int(input())))

Separate logic from display

Returning results makes logic easy to call from tests. Keep input and printing at the program boundary.

import json
def total(price, quantity): return price * quantity
print(json.dumps([total(*pair) for pair in json.loads(input())]))
Hands-On Labs: Turn cases into assertions (Beginner) Separate logic from display (Developing) An exception test harness (Challenging) Write a regression suite (Challenging) Practice pytest.raises (Developing) Debug: truthiness is not equality (Developing)
Run in Browser Sandbox →
Module 7 Intermediate 2 Lessons · 5 Exercises · 3 Quiz Qs

File I/O

Read, transform, and save useful information.

Solve 5 Exercises in Sandbox

A tidy reading list

with closes a file even when an error occurs. strip removes the newline and surrounding whitespace.

with open("books.txt") as file:
    books = [line.strip() for line in file if line.strip()]
print("\n".join(sorted(books)))

Save a journal entry

Mode a appends; w replaces existing contents. Exercise files are private, temporary text files inside the sandbox.

entry = input()
with open("journal.txt", "a") as file: file.write(entry + "\n")
with open("journal.txt") as file: print(file.read(), end="")
Hands-On Labs: A tidy reading list (Beginner) Save a journal entry (Developing) A class gradebook (Challenging) Export the roster (Developing) Debug: preserve a journal (Developing)
Run in Browser Sandbox →
Module 8 Advanced 2 Lessons · 5 Exercises · 3 Quiz Qs

Regular expressions

Find structure in messy text.

Solve 5 Exercises in Sandbox

Validate an identifier

fullmatch validates the entire string; * permits zero or more of the preceding pattern.

import re
print("valid" if re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", input()) else "invalid")

Extract a date

Capturing groups retain matched parts. The walrus operator assigns a match while checking whether it exists.

import re
if m := re.search(r"(?<![0-9])([0-9]{4})-([0-9]{2})-([0-9]{2})(?![0-9])", input()):
    print(f"{m[3]}/{m[2]}/{m[1]}")
else: print("none")
Hands-On Labs: Validate an identifier (Beginner) Extract a date (Developing) Normalize a messy note (Developing) Find a campus address (Challenging) Debug: a dot too far (Developing)
Run in Browser Sandbox →
Module 9 Advanced 2 Lessons · 6 Exercises · 3 Quiz Qs

Object-oriented programming

Model a system with well-defined objects.

Solve 6 Exercises in Sandbox

Model a wallet

Objects keep state and behavior together. A property can expose a value without allowing direct assignment.

import json
class Wallet:
    def __init__(self): self._balance = 0
    @property
    def balance(self): return self._balance
    def change(self, amount):
        if self._balance + amount >= 0: self._balance += amount
w = Wallet()
for n in json.loads(input()): w.change(n)
print(w.balance)

Construct from a record

classmethod receives the class; staticmethod receives neither class nor instance. __str__ controls readable object output.

class Student:
    def __init__(self, name, score): self.name, self.score = name, score
    @staticmethod
    def valid(score): return 0 <= score <= 100
    @classmethod
    def from_record(cls, record):
        name, score = record.rsplit(",", 1)
        score = int(score)
        if not cls.valid(score): raise ValueError()
        return cls(name.strip(), score)
    def __str__(self): return f"{self.name} ({self.score})"
try: print(Student.from_record(input()))
except ValueError: print("invalid")
Hands-On Labs: Model a wallet (Developing) Construct from a record (Developing) Extend a delivery service (Challenging) Add two vectors (Challenging) Protect an object’s state (Challenging) Debug: shared backpacks (Developing)
Run in Browser Sandbox →
Module 10 Advanced 2 Lessons · 10 Exercises · 3 Quiz Qs

Et cetera

Write expressive, reusable Python.

Solve 10 Exercises in Sandbox

A unique guest list

A set removes duplicates. Sort it when output order matters.

print(" ".join(sorted({name.lower() for name in input().split()})))

Transform a dataset

Comprehensions combine transformation and filtering. enumerate pairs each value with an index.

values = map(int, input().split())
squares = [n*n for n in values if n % 2 == 0]
for index, value in enumerate(squares, start=1): print(f"{index}:{value}")
Hands-On Labs: A unique guest list (Beginner) Transform a dataset (Developing) Flexible invoice (Challenging) Generate a countdown (Developing) A configurable repeater (Challenging) Understand shared state (Developing) Project: study session report (Challenging) Build a lazy pipeline (Developing) Split a record with unpacking (Developing) Fill: lazy squares (Developing)
Run in Browser Sandbox →