Python Fundamentals
Transition to Python to prototype faster with readable, expressive code.
Content
REPL and Script Execution
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Python REPL and Script Execution — Play, Prototype, Then Productionize
"When in doubt: prototype in the REPL, finalize in a script, benchmark carefully — and blame your virtualenv if anything breaks."
You're coming off learning how to install Python and use venv, and you've been neck-deep in C data structures comparing vectors, lists, and hash tables for speed. Good. Now think of the REPL as your laboratory bench for quick experiments, and scripts as the reproducible lab notebook. This lesson shows how to use both effectively so your prototypes turn into reliable, repeatable programs — and so you don't accidentally benchmark a broken experiment.
What are we even talking about?
- REPL = Read–Eval–Print Loop. Type Python expressions, get immediate feedback. Great for exploration and debugging.
- Script execution = running a .py file start-to-finish. Great for repeatability, testing, and production runs.
Why it matters for CS50 projects and for comparing data structures:
- REPL lets you iterate on algorithms fast (fast feedback loop). You'll prototype a graph traversal in seconds instead of recompiling C.
- Scripts make experiments reproducible for fair benchmarking and for handing in assignments.
- Use your venv (from the previous lesson) to freeze the interpreter and packages so your experiments are consistent.
The REPL: Your quick-thinking friend (and sometimes your enabler)
Start it with:
python3 # or `python` if your system points to Python 3
ipython # richer REPL: tab-complete, %magic, %timeit
Handy REPL tricks:
_(underscore) returns the value of the last expression.help(obj)anddir(obj)for introspection.- In IPython:
?and??for docs and source,%timeitfor timing snippets. - Paste multi-line code in IPython with
%pasteor use a heredoc in the standard REPL.
Use cases:
- Testing a function on a handful of inputs.
- Inspecting objects returned by libraries (like networkx graphs — remember adjacency lists from C? Neurotic curiosity > theoretical correctness).
- Quick debugging and trial-and-error.
Warning (the punchline): REPL state persists. If you redefined a function earlier and forgot, your later tests may be lying to you.
Scripts: reproducible, repeatable, serious
Create a file myscript.py:
#!/usr/bin/env python3
import sys
def main(argv):
print('Args:', argv)
if __name__ == '__main__':
main(sys.argv[1:])
Run it with:
python3 myscript.py arg1 arg2
# or
chmod +x myscript.py && ./myscript.py arg1
# or run a module: python -m package.module
Important bits:
__name__ == '__main__'ensures code only runs when the file is executed as a script, not when imported as a module. This is crucial when you import helper modules during testing or when reusing code across projects.- Use
argparsefor robust command-line parsing.
Quick example for argparse:
import argparse
p = argparse.ArgumentParser()
p.add_argument('--size', type=int, default=10)
args = p.parse_args()
print(args.size)
Bridging REPL and scripts: best of both worlds
- Prototype functions in the REPL, copy them into modules for scripts.
- Run a script and drop into REPL afterwards with
python -i script.py— great for inspecting variables created by the run. - IPython:
%run script.pyruns the script and brings its variables into the interactive namespace.
"This is the moment where the concept finally clicks." — when you realize the REPL is for discovery and scripts are for discipline.
Execution details that bite students (and how to avoid them)
- Import-time execution: importing a module executes top-level code. Use the
if __name__ == '__main__'pattern to prevent side-effects when importing. - Relative imports: keep module layout tidy or use
python -m package.moduleto run packages correctly. - Shebang and executable permission only affect running
./script.py;python script.pyignores the shebang. - Python caches bytecode in
__pycache__— fine, but remember that stale caches rarely cause trouble unless you change interp settings.
Performance & benchmarking — important after your C data structures work
- Python is slower than optimized C. That's fine for prototyping. But when comparing algorithmic ideas you should:
- Use
timeit(or IPython's%timeit) for micro-benchmarks. - Run benchmarks in scripts (not just REPL) to avoid warmed-up state or cached objects that bias results.
- Use
python -m timeit -s 'from module import func' 'func(x)'for clean runs.
- Use
- For full-program profiling, use
python -m cProfile -o out.prof script.pyand visualize with snakeviz or pstats. - If you moved from Python prototype to C implementation for speed, ensure both are run with the same input sizes and that you isolate startup costs (Python startup can dominate tiny benchmarks).
Quick troubleshooting checklist
- Script not running? Check
python3 script.pyvspython script.pyand which interpreter your venv points to. - ImportError on a module you just wrote? Make sure you ran from the right directory or use
python -m package.module. - Unexpected behavior only in REPL? Restart REPL to clear state.
Key takeaways (bulleted for the long night ahead)
- REPL = fast iteration, experiment, inspect. Great for prototypes.
- Script = reproducibility, automation, production. Use
if __name__ == '__main__'. - Use your venv to lock Python versions and dependencies for consistent benchmarking.
- For performance comparisons (Python vs C), prototype in Python but benchmark in controlled script runs.
- Tools to remember:
python -m timeit,%timeit,python -m cProfile,ipython,python -i.
Parting wisdom: prototype until your idea works in the REPL, then write the script that proves you weren't hallucinating. And when your C implementation outruns Python, don’t gloat too long — your grader will care more about clarity and reproducibility than bragging rights.
Small next-step challenge
- In the REPL, write a tiny function to count neighbors in an adjacency list (remember graphs from C).
- Move it into a module and write a script that reads a simple graph file, times the function using
timeit, and prints results. - Run it inside and outside a venv and note any differences.
If you do these three, you’ll walk away able to prototype like a mad scientist and document like a professional.
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!