Run Python Code in Your Browser - No Setup Needed
A comprehensive guide to browser-based Python execution covering use cases for students, data analysts, educators, developers, and anyone who needs quick Python without installation
There is a wall between “I want to learn Python” and “I am running Python code.” On the far side of that wall is a thriving language used for data science, automation, web development, scientific research, and more creative applications than any single guide could enumerate. On the near side is a setup process that has stopped more aspiring Python programmers than any concept the language itself contains.
Download Python. Choose a version. Navigate the installer options. Understand why PATH matters. Figure out pip. Create a virtual environment. Understand why virtual environments exist. Install a package. Get an error because the package requires a specific Python version. Look up that error. Discover a forum thread from years ago that may or may not apply to your situation. Repeat.
None of this has anything to do with Python. None of it teaches programming. And yet for millions of people who could genuinely benefit from Python, this setup friction is the reason they never get started.
Browser-based Python execution eliminates the entire wall. Open a URL. Write code. Run code. The environment is ready before you finish typing your first line. For learners, this means getting to the actual subject immediately. For experienced developers, it means having Python available on any device without setup. For educators, it means every student has a working environment without any IT coordination. For data analysts, it means running quick calculations on a new machine without installing anything.
ReportMedic’s Python Code Runner is a browser-based Python execution environment that runs Python locally on your device. Your code and your data stay on your machine. There is no server processing your scripts, no account required, and no installation to manage.
This guide covers everything: how browser-based Python works technically, how to use the tool effectively, practical code recipes for common tasks, use cases by persona, comparisons with alternatives, and the specific situations where browser-based Python is the right tool and where you should use something else.
The Problem with Python Setup
To appreciate what browser-based execution solves, it helps to understand specifically what makes Python setup difficult.
Installation Complexity
Python installation is more complex than installing most consumer software because Python is not a single thing. It is a language with multiple major versions (Python 2, Python 3), multiple minor versions within Python 3 (3.8, 3.9, 3.10, 3.11, 3.12, and so on), and a complex ecosystem of packages that may have version-specific compatibility requirements.
On Windows, Python installation requires navigating installer options including the crucial “Add Python to PATH” checkbox that new users frequently miss, leading to a situation where Python appears installed but the python command does not work from the command line.
On macOS, the situation is further complicated by the fact that macOS ships with a system Python installation that should not be modified, requiring users to install a separate Python version and understand which one they are using.
On Linux, Python is usually available through the package manager, but may be an older version or require specific version selection.
After installation, users must understand:
What a virtual environment is and why it matters
How to create one with
python -m venv venvHow to activate it (different commands on Windows vs macOS/Linux)
That they need to activate it every time they start a new terminal session
How to install packages with pip within the virtual environment
Why packages installed in one environment may not be available in another
For an experienced developer, all of this is second nature. For a student trying to complete a programming assignment or a data analyst trying to run a script they received from a colleague, it is a significant and often discouraging obstacle.
The Version Compatibility Problem
Python packages do not always work with all Python versions. A tutorial written for Python 3.8 may use a package that does not support Python 3.12. A script shared by a colleague may fail because it uses a feature added in Python 3.10 that the recipient’s Python 3.8 installation does not support.
Managing Python versions requires additional tools (pyenv on macOS/Linux, pyenv-win on Windows) that add another layer of complexity. Many users end up with multiple Python installations in various states of configuration and confusion.
The Environment State Problem
Even after a working Python environment is set up, it can be disrupted. A macOS update that changes system Python. A new project that requires conflicting package versions. A corporate IT policy that restricts what can be installed. A new computer that requires the entire setup process again. A shared computer where the Python environment was set up by someone else and may not be in the expected state.
Browser-based Python eliminates all of this. Every session starts from a clean, consistent state. No leftover package versions from previous projects. No configuration that someone else modified. No PATH issues. No activation forgotten.
How Browser-Based Python Works
The technical mechanism that makes Python run in a browser is genuinely interesting and worth understanding.
WebAssembly: The Foundation
WebAssembly (Wasm) is a binary instruction format designed for execution in web browsers. Modern browsers include a WebAssembly runtime that can execute compiled Wasm code at near-native performance. WebAssembly was designed to enable running code originally written for non-web platforms (C, C++, Rust) in browsers without rewriting it in JavaScript.
This capability is the foundation for browser-based Python. The CPython interpreter, the reference implementation of Python written in C, can be compiled to WebAssembly. The resulting Wasm module runs inside the browser’s WebAssembly runtime, executing Python code exactly as it would on a native machine.
Pyodide: Python in WebAssembly
Pyodide is the most widely used implementation of Python in WebAssembly. It is a port of CPython to WebAssembly with several additions:
Python standard library: Pyodide includes the complete Python standard library, so all standard modules (math, json, csv, datetime, re, collections, itertools, and hundreds more) are available without any installation.
Scientific Python stack: Pyodide includes pre-compiled versions of key scientific Python packages: NumPy for numerical computing, Pandas for data manipulation, Matplotlib for visualization, SciPy for scientific computing, and others. These packages are compiled to WebAssembly along with their C extensions, providing the full performance and functionality of these libraries.
JavaScript interoperability: Pyodide provides a bridge between Python and JavaScript, allowing Python code to interact with browser APIs and JavaScript libraries. This enables Python code to manipulate the browser DOM, make HTTP requests, and interact with web functionality directly.
Package installation: Pyodide can install additional packages from PyPI using micropip, Pyodide’s package manager for the Wasm environment. Not all PyPI packages are available (packages with compiled C extensions that have not been compiled for WebAssembly are not available), but a growing subset of the package ecosystem works in Pyodide.
Brython: Python in JavaScript
An alternative approach to browser Python is Brython (Browser Python), which translates Python source code to JavaScript at runtime. Brython achieves Python syntax support without the WebAssembly overhead but is limited to pure Python code: packages with C extensions do not work in Brython because there is no C runtime available.
Brython is appropriate for educational tools teaching basic Python syntax and for web development use cases where Python is used for browser interaction. For scientific computing and data analysis use cases requiring NumPy and Pandas, WebAssembly-based implementations are more appropriate.
PyScript
PyScript is a framework built on Pyodide that enables embedding Python code in HTML pages with a <py-script> tag. PyScript is designed for building web applications with Python rather than for running Python in a REPL-style interface. It is relevant for developers building Python-powered web applications, less so for the interactive code execution use cases covered in this guide.
What This Means in Practice
For the user of a browser-based Python runner:
Complete isolation: Each session is isolated. Variables, imports, and state from one session do not persist to the next. Every session starts fresh.
No server involvement: Python execution happens in the browser’s WebAssembly runtime on the user’s device. Code, data, and output stay on the device. Nothing is transmitted to a server for processing.
Standard Python behavior: The Python that runs in the browser behaves like the Python that runs natively. The same syntax, the same standard library behavior, the same package semantics. Code written in the browser runs identically on a local Python installation (for packages available in the Wasm environment).
Performance: WebAssembly execution is slower than native compiled code, typically by a factor of 1.5-5x for compute-intensive tasks. For most Python use cases (data manipulation, string processing, algorithmic implementations, basic data science), this performance difference is not practically meaningful. For very compute-intensive tasks (training large machine learning models, processing massive datasets), a local installation or cloud compute environment is more appropriate.
ReportMedic’s Python Code Runner: Full Walkthrough
Navigate to reportmedic.org/tools/python-code-runner.html. The tool loads a Python execution environment directly in the browser.
The Interface
The Python Code Runner presents a code editor pane where you write Python code, and an output console pane where execution results appear. The interface is clean and minimal: write code, run it, see the output.
Code editor: Supports Python syntax with appropriate formatting. Handles multi-line code, function definitions, class definitions, and all Python constructs. Tab indentation works as expected in Python code.
Output console: Displays standard output from print() statements, return values displayed in interactive mode, error messages and tracebacks, and any output generated by code execution.
Run control: Execute the code in the editor and see results in the console. Clear the console to start a fresh output view without losing your code.
Running Your First Python Code
Type a simple expression:
print("Hello from Python in the browser")
Click run. The output console shows:
Hello from Python in the browser
This simplest possible example confirms the environment is working. The code ran on your device, in your browser, using a Python interpreter compiled to WebAssembly. No server was involved.
Working with Variables and Data
# Basic arithmetic
x = 10
y = 3
print(f"Sum: {x + y}")
print(f"Product: {x * y}")
print(f"Division: {x / y:.2f}")
print(f"Integer division: {x // y}")
print(f"Remainder: {x % y}")
print(f"Power: {x ** y}")
Output:
Sum: 13
Product: 30
Division: 3.33
Integer division: 3
Remainder: 1
Power: 1000
Working with Lists and Collections
# List operations
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
# Slicing
print(fruits[1:3]) # ['banana', 'cherry']
print(fruits[-2:]) # ['date', 'elderberry']
# List comprehension
uppercase = [f.upper() for f in fruits]
print(uppercase)
# Filtering with comprehension
long_fruits = [f for f in fruits if len(f) > 5]
print(long_fruits)
# Sorting
sorted_fruits = sorted(fruits, key=len)
print(sorted_fruits)
String Processing
text = "The quick brown fox jumps over the lazy dog"
# Word count
words = text.split()
print(f"Word count: {len(words)}")
# Word frequency
from collections import Counter
freq = Counter(words)
most_common = freq.most_common(5)
print("Most common words:")
for word, count in most_common:
print(f" {word}: {count}")
# String operations
print(f"Uppercase: {text.upper()}")
print(f"Replace: {text.replace('fox', 'cat')}")
print(f"Starts with 'The': {text.startswith('The')}")
Error Handling in the Browser Environment
When Python code contains an error, the output console displays the full traceback, including the line number and error description:
# This will produce an error
result = 10 / 0
Output:
ZeroDivisionError: division by zero
File "<stdin>", line 2, in <module>
The error display is the same as native Python: full traceback with file and line information. Learning to read Python error messages is an essential Python skill, and the browser environment provides the same error messages as native Python.
Available Libraries
The Python Code Runner includes the standard library and commonly used packages. Available libraries include:
Standard library (always available): math, statistics, random, datetime, json, csv, re, collections, itertools, functools, string, os.path, pathlib, io, sys, copy, time, calendar, decimal, fractions, hashlib, base64, urllib.parse, and the complete standard library.
Pre-included scientific packages: NumPy for numerical arrays and operations, Pandas for DataFrames and data manipulation, Matplotlib for plotting and visualization (output displayed inline), SciPy for scientific computing.
Additional packages: Available via import in the Pyodide environment. If a package is not immediately available, micropip can install additional packages that have WebAssembly-compatible versions.
Practical Python Recipes for Browser Execution
The following recipes demonstrate practical Python tasks that work well in the browser-based environment.
String Manipulation and Text Processing
import re
from collections import Counter
# Clean and normalize text
raw_text = """
Hello, World! This is some MESSY text.
It has extra spaces and MIXED case.
"""
# Normalize whitespace and case
clean = " ".join(raw_text.split()).lower()
print("Cleaned:", clean)
# Extract all words
words = re.findall(r'\b[a-z]+\b', clean)
print(f"Words found: {len(words)}")
# Count word frequency
freq = Counter(words)
print("Top 5 words:", freq.most_common(5))
# Find all email-like patterns in text
text_with_emails = "Contact us at info@example.com or support@company.org"
emails = re.findall(r'\b[\w.-]+@[\w.-]+\.[a-z]{2,}\b', text_with_emails)
print("Emails found:", emails)
# Check if a string is a valid URL pattern
url_pattern = re.compile(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-]+')
urls = url_pattern.findall("Visit https://reportmedic.org or http://example.com for more info")
print("URLs found:", urls)
CSV and Data Parsing
import csv
from io import StringIO
from collections import defaultdict
# Parse CSV data directly in the browser
csv_data = """name,department,salary,years
Alice,Engineering,95000,5
Bob,Marketing,72000,3
Carol,Engineering,105000,8
David,HR,65000,2
Eve,Engineering,88000,4
Frank,Marketing,78000,6
"""
reader = csv.DictReader(StringIO(csv_data))
employees = list(reader)
# Convert salary to int for calculations
for emp in employees:
emp['salary'] = int(emp['salary'])
emp['years'] = int(emp['years'])
# Calculate department averages
dept_salaries = defaultdict(list)
for emp in employees:
dept_salaries[emp['department']].append(emp['salary'])
print("Department average salaries:")
for dept, salaries in sorted(dept_salaries.items()):
avg = sum(salaries) / len(salaries)
print(f" {dept}: ${avg:,.0f}")
# Find highest earner
top = max(employees, key=lambda e: e['salary'])
print(f"\nHighest earner: {top['name']} ({top['department']}) at ${top['salary']:,}")
# Filter by years of experience
senior = [e for e in employees if e['years'] >= 5]
print(f"\nSenior employees (5+ years): {[e['name'] for e in senior]}")
JSON Data Processing
import json
from datetime import datetime
# Parse and process JSON data
json_str = '''
{
"orders": [
{"id": 1001, "customer": "Alice", "amount": 125.50, "status": "completed"},
{"id": 1002, "customer": "Bob", "amount": 89.99, "status": "pending"},
{"id": 1003, "customer": "Carol", "amount": 245.00, "status": "completed"},
{"id": 1004, "customer": "Alice", "amount": 55.25, "status": "cancelled"},
{"id": 1005, "customer": "David", "amount": 178.75, "status": "completed"}
]
}
'''
data = json.loads(json_str)
orders = data['orders']
# Group by status
from collections import defaultdict
by_status = defaultdict(list)
for order in orders:
by_status[order['status']].append(order)
print("Orders by status:")
for status, items in by_status.items():
total = sum(o['amount'] for o in items)
print(f" {status}: {len(items)} orders, ${total:.2f} total")
# Customer totals (completed orders only)
completed = [o for o in orders if o['status'] == 'completed']
customer_totals = defaultdict(float)
for order in completed:
customer_totals[order['customer']] += order['amount']
print("\nCustomer totals (completed orders):")
for customer, total in sorted(customer_totals.items()):
print(f" {customer}: ${total:.2f}")
# Serialize to formatted JSON
result = {
"summary": {
"total_orders": len(orders),
"completed": len(by_status['completed']),
"revenue": sum(o['amount'] for o in by_status['completed'])
}
}
print("\nSummary JSON:")
print(json.dumps(result, indent=2))
Mathematical Calculations
import math
import statistics
# Statistical analysis
data = [23, 45, 12, 67, 34, 89, 56, 45, 23, 78, 34, 56, 89, 12, 45]
print("Statistical Summary:")
print(f" Count: {len(data)}")
print(f" Sum: {sum(data)}")
print(f" Min: {min(data)}")
print(f" Max: {max(data)}")
print(f" Mean: {statistics.mean(data):.2f}")
print(f" Median: {statistics.median(data)}")
print(f" Mode: {statistics.mode(data)}")
print(f" Std Dev: {statistics.stdev(data):.2f}")
print(f" Variance: {statistics.variance(data):.2f}")
# Geometric and financial calculations
principal = 10000
rate = 0.07 # 7% annual return
years = 20
# Compound interest
future_value = principal * (1 + rate) ** years
print(f"\nCompound interest calculation:")
print(f" Principal: ${principal:,}")
print(f" Rate: {rate*100:.1f}%")
print(f" Years: {years}")
print(f" Future value: ${future_value:,.2f}")
# Rule of 72
doubling_years = 72 / (rate * 100)
print(f" Approximate doubling time: {doubling_years:.1f} years")
# Prime number check and generation
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
primes = [n for n in range(2, 100) if is_prime(n)]
print(f"\nPrimes under 100: {primes}")
print(f"Count: {len(primes)}")
Regular Expression Development and Testing
import re
# The browser Python runner is ideal for developing and testing regex patterns
# because you get immediate feedback on your patterns
test_cases = [
"2024-01-15",
"01/15/2024",
"January 15, 2024",
"15 Jan 2024",
"not a date",
"2024-13-45", # invalid date values
]
# Date pattern: YYYY-MM-DD
iso_date = re.compile(r'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$')
print("ISO date pattern testing:")
for tc in test_cases:
match = iso_date.match(tc)
print(f" '{tc}': {'MATCH' if match else 'no match'}")
# Phone number patterns
phones = [
"+1-555-123-4567",
"(555) 123-4567",
"555.123.4567",
"5551234567",
"not-a-phone",
"+44 20 7946 0958",
]
phone_pattern = re.compile(r'(\+\d{1,3}[\s-]?)?\(?\d{3}\)?[\s.\-]?\d{3}[\s.\-]?\d{4}')
print("\nPhone pattern testing:")
for phone in phones:
match = phone_pattern.search(phone)
print(f" '{phone}': {'MATCH' if match else 'no match'}")
Date and Time Calculations
from datetime import datetime, timedelta, date
import calendar
# Date arithmetic
today = date.today()
print(f"Today: {today}")
print(f"Day of week: {today.strftime('%A')}")
print(f"Week number: {today.isocalendar()[1]}")
# Date calculations
thirty_days = today + timedelta(days=30)
print(f"\n30 days from today: {thirty_days}")
# Business days calculation (simple version)
def business_days_between(start, end):
"""Count business days between two dates."""
business_days = 0
current = start
while current <= end:
if current.weekday() < 5: # Monday = 0, Friday = 4
business_days += 1
current += timedelta(days=1)
return business_days
start = date(2024, 1, 1)
end = date(2024, 3, 31)
bd = business_days_between(start, end)
print(f"\nBusiness days in Q1 2024: {bd}")
# Days until a future date
target = date(today.year + 1, 1, 1) # Next new year
days_until = (target - today).days
print(f"\nDays until {target}: {days_until}")
# Month calendar
cal = calendar.monthcalendar(today.year, today.month)
print(f"\nCalendar for {today.strftime('%B %Y')}:")
print("Mo Tu We Th Fr Sa Su")
for week in cal:
print(" ".join(f"{d:2d}" if d > 0 else " " for d in week))
Algorithm Implementation and Testing
# Implementing and testing algorithms in the browser
# is excellent for coding interview preparation
def binary_search(arr, target):
"""Binary search implementation."""
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Test binary search
sorted_arr = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
print("Binary Search Tests:")
for target in [7, 1, 19, 4, 13]:
idx = binary_search(sorted_arr, target)
if idx >= 0:
print(f" Found {target} at index {idx}")
else:
print(f" {target} not found")
def merge_sort(arr):
"""Merge sort implementation."""
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
# Test merge sort
unsorted = [64, 34, 25, 12, 22, 11, 90, 45, 67, 3]
print(f"\nMerge Sort:")
print(f" Before: {unsorted}")
print(f" After: {merge_sort(unsorted)}")
# Fibonacci with memoization
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(f"\nFibonacci sequence (first 15):")
print([fibonacci(i) for i in range(15)])
Use Cases by Persona
Students Learning Python for the First Time
For students in introductory programming courses, the browser environment removes the barrier between the first day of class and writing actual code. The instructor can share a URL, and every student has a working Python environment in ten seconds regardless of their operating system, their existing software configuration, or their technical experience.
CS101 homework: Standard introductory assignments (FizzBuzz, factorial, Fibonacci, sorting algorithms, string manipulation) all work perfectly in the browser environment. Students can work on assignments during class, in the library, on any computer, without needing their personal laptop.
Immediate feedback: The browser runner provides immediate error messages and output, exactly like a local Python installation. Students learn to read error tracebacks and debug their code the same way they would with any Python environment.
No homework environment issues: The classic “it worked on my computer” problem for student submissions is reduced when the course reference environment is a browser URL that behaves consistently across all students’ machines.
Progressive learning: Starting in the browser and later transitioning to a local installation is a natural progression. Students who are comfortable with Python concepts are better positioned to manage the local installation process when it becomes relevant.
For introductory exercises specifically suited to the browser environment: all standard Python concepts (variables, control flow, functions, classes, modules from the standard library), basic data structure practice, algorithm implementation, and string processing work exactly as they would in any Python environment.
Data Analysts Doing Quick Calculations
Data analysts frequently need to run Python calculations that do not require a full analytical environment: a quick statistical check, a unit conversion calculation, a formula verification, a data format validation.
For these tasks, spinning up a Jupyter notebook or a local Python shell involves more overhead than the task itself. The browser runner provides Python immediately.
Quick statistical checks:
import statistics
# Quick check: what's the 95th percentile of this dataset?
data = [12, 45, 23, 67, 89, 34, 56, 78, 91, 23, 45, 67, 89, 34, 56]
data.sort()
n = len(data)
p95_idx = int(0.95 * n)
print(f"95th percentile: {data[p95_idx]}")
print(f"Mean: {statistics.mean(data):.1f}")
print(f"Std dev: {statistics.stdev(data):.1f}")
Data format verification:
import re
# Verify that a column of data matches the expected format
sample_dates = ["2024-01-15", "2024-02-30", "not-a-date", "2024-12-01"]
pattern = re.compile(r'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$')
for d in sample_dates:
valid = bool(pattern.match(d))
print(f" {d}: {'valid' if valid else 'INVALID'}")
URL and text parsing:
from urllib.parse import urlparse, parse_qs
url = "https://example.com/path?category=tech&page=3&sort=date&filter=active"
parsed = urlparse(url)
params = parse_qs(parsed.query)
print(f"Scheme: {parsed.scheme}")
print(f"Host: {parsed.netloc}")
print(f"Path: {parsed.path}")
print(f"Parameters: {dict(params)}")
Educators Teaching Python in Class
Classroom Python instruction has traditionally required either: every student having a working local installation (requiring IT support and setup troubleshooting), a shared cloud environment (requiring account creation and management), or working entirely in slides (limiting interactivity).
Browser-based Python changes this. Demonstrations run live in the browser with no setup. Students can follow along on their own machines without any coordination.
Live demonstration advantages: An instructor demonstrating Python concepts can show the code in the browser runner and share the URL for students to open the same environment. The demonstration is live, interactive, and immediately verifiable by students running the same code on their own machines simultaneously.
Error demonstration: One of the most valuable teaching tools is deliberately introducing errors and reading the traceback together. The browser runner displays Python error messages identically to a local installation, teaching students to read real Python errors from day one.
Interactive exercises: Instructors can prepare code templates with blanks for students to fill in, share them as text, and have students run completed versions immediately. The feedback loop is seconds, not minutes.
No IT coordination: A Python lesson can be added to any curriculum without IT department involvement. If the students have a browser, they can run Python.
Developers Testing Snippets and Prototyping Logic
For developers with established Python installations, the browser runner serves a different purpose: quick testing of logic without context switching.
Testing a regex pattern: Rather than opening a terminal, activating a virtual environment, launching Python, and testing a pattern, a developer can open the browser runner in a new tab and test the pattern immediately.
Verifying an algorithm: A developer implementing a complex algorithm in a larger codebase can implement and verify the core logic in the browser runner before integrating it into the project.
Checking API response format: When working with API responses, a developer can paste JSON data into the browser runner and write quick parsing logic to explore the structure.
Code review assistance: When reviewing a colleague’s code, pasting small functions into the browser runner and running them with test inputs provides immediate verification of whether the logic is correct.
Interview preparation: Developers preparing for technical interviews can practice algorithm and data structure implementations in the browser runner, using the same immediate feedback loop they will have during interview sessions in online coding platforms.
Marketers Running Data Transformations
Marketing professionals increasingly work with data: campaign performance data, customer lists, URL analytics, conversion funnel data. Python provides powerful tools for manipulating this data, even without a data science background.
URL processing:
from urllib.parse import urlparse, urlencode
# Clean up and standardize a list of landing page URLs
raw_urls = [
"https://example.com/landing?utm_source=google&utm_medium=cpc&extra=remove",
"https://example.com/other?utm_source=email&utm_campaign=spring",
"https://example.com/page?irrelevant=param"
]
def keep_utm_params(url):
parsed = urlparse(url)
from urllib.parse import parse_qs
params = parse_qs(parsed.query)
utm_params = {k: v[0] for k, v in params.items() if k.startswith('utm_')}
clean_query = urlencode(utm_params)
return f"{parsed.scheme}://{parsed.netloc}{parsed.path}{'?' + clean_query if clean_query else ''}"
for url in raw_urls:
print(keep_utm_params(url))
List deduplication and cleaning:
# Clean and deduplicate an email list
import re
raw_emails = [
"alice@EXAMPLE.COM",
"Bob@example.com ",
"carol@example.com",
"Alice@example.com", # duplicate
"invalid-email",
" david@example.com",
"carol@example.com", # duplicate
]
email_pattern = re.compile(r'^[\w.-]+@[\w.-]+\.[a-z]{2,}$')
def clean_email(email):
return email.strip().lower()
cleaned = set()
invalid = []
for email in raw_emails:
clean = clean_email(email)
if email_pattern.match(clean):
cleaned.add(clean)
else:
invalid.append(email.strip())
print(f"Valid unique emails ({len(cleaned)}):")
for email in sorted(cleaned):
print(f" {email}")
print(f"\nInvalid emails ({len(invalid)}):")
for email in invalid:
print(f" {email}")
Scientists Running Calculations and Formula Verification
Scientists and engineers who use Python for calculations benefit from the browser runner for quick formula verification, unit conversion, and exploratory calculations before implementing in a more complete analysis environment.
import math
# Physics calculations: projectile motion
def projectile_range(v0, angle_deg, g=9.81):
"""Calculate range of a projectile."""
angle_rad = math.radians(angle_deg)
return (v0**2 * math.sin(2 * angle_rad)) / g
def max_height(v0, angle_deg, g=9.81):
"""Calculate maximum height of a projectile."""
angle_rad = math.radians(angle_deg)
return (v0**2 * math.sin(angle_rad)**2) / (2 * g)
# Compare angles for a given initial velocity
v0 = 50 # m/s
print(f"Projectile analysis at v0 = {v0} m/s:")
print(f"{'Angle':>8} {'Range (m)':>12} {'Max Height (m)':>15}")
print("-" * 38)
for angle in range(15, 90, 15):
r = projectile_range(v0, angle)
h = max_height(v0, angle)
print(f"{angle:>7}° {r:>12.1f} {h:>15.1f}")
Job Seekers Practicing Coding Interview Questions
Browser-based Python provides an immediately accessible environment for practicing LeetCode-style problems and algorithm implementations without any environment setup.
# Two Sum - classic interview problem
def two_sum(nums, target):
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
# Test cases
test_cases = [
([2, 7, 11, 15], 9), # Expected: [0, 1]
([3, 2, 4], 6), # Expected: [1, 2]
([3, 3], 6), # Expected: [0, 1]
([1, 5, 3, 7], 8), # Expected: [1, 2] (5+3)
]
print("Two Sum Test Results:")
for nums, target in test_cases:
result = two_sum(nums, target)
print(f" nums={nums}, target={target}: {result}")
# Validate a palindrome
def is_palindrome(s):
cleaned = ''.join(c.lower() for c in s if c.isalnum())
return cleaned == cleaned[::-1]
palindrome_tests = [
"A man, a plan, a canal: Panama",
"race a car",
"Was it a car or a cat I saw?",
"hello",
]
print("\nPalindrome Test Results:")
for s in palindrome_tests:
print(f" '{s}': {is_palindrome(s)}")
Python for Data Science Concepts in the Browser
Browser Python with Pyodide’s included scientific libraries enables meaningful data science work. While large-scale ML training and big data processing belong in dedicated environments, understanding and prototyping data science concepts works perfectly in the browser.
NumPy Fundamentals
NumPy is the foundation of scientific Python. Its ndarray provides efficient numerical computation that outperforms native Python lists for mathematical operations.
import numpy as np
# Creating arrays
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("1D Array:", arr)
print("Shape:", arr.shape)
print("Matrix:\n", matrix)
# Array operations (vectorized, no loops needed)
print("\nArray operations:")
print(" Squared:", arr ** 2)
print(" Square root:", np.sqrt(arr).round(2))
print(" Mean:", arr.mean())
print(" Std:", arr.std().round(3))
# Boolean indexing
above_five = arr[arr > 5]
print(" Values above 5:", above_five)
# Linspace and mathematical operations
x = np.linspace(0, 2 * np.pi, 8)
print("\nSine values at 8 points across 2π:")
for xi, yi in zip(x, np.sin(x)):
print(f" x={xi:.3f}: sin(x)={yi:.3f}")
# Matrix operations
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print("\nMatrix multiplication:")
print(np.dot(a, b))
print("\nMatrix inverse:")
print(np.linalg.inv(a).round(3))
Pandas Data Manipulation
Pandas provides the DataFrame structure that is central to data analysis in Python. The browser runner allows exploring Pandas functionality on sample data.
import pandas as pd
# Create a sample DataFrame
data = {
'name': ['Alice', 'Bob', 'Carol', 'David', 'Eve', 'Frank'],
'department': ['Eng', 'Marketing', 'Eng', 'HR', 'Eng', 'Marketing'],
'salary': [95000, 72000, 105000, 65000, 88000, 78000],
'years': [5, 3, 8, 2, 4, 6],
'performance': [4.2, 3.8, 4.7, 3.5, 4.0, 4.1]
}
df = pd.DataFrame(data)
print("DataFrame overview:")
print(df.head())
print("\nData types:")
print(df.dtypes)
print("\nBasic statistics:")
print(df[['salary', 'years', 'performance']].describe().round(2))
# Filtering
engineers = df[df['department'] == 'Eng']
print(f"\nEngineers ({len(engineers)} rows):")
print(engineers[['name', 'salary', 'performance']])
# GroupBy aggregation
dept_stats = df.groupby('department').agg(
count=('name', 'count'),
avg_salary=('salary', 'mean'),
avg_performance=('performance', 'mean')
).round(2)
print("\nDepartment statistics:")
print(dept_stats)
# Sorting and ranking
df['rank'] = df['salary'].rank(ascending=False).astype(int)
print("\nSalary ranking:")
print(df[['name', 'salary', 'rank']].sort_values('rank'))
# Adding computed columns
df['salary_per_year'] = (df['salary'] / df['years']).round(0).astype(int)
print("\nSalary efficiency (salary per year of experience):")
print(df[['name', 'salary', 'years', 'salary_per_year']].sort_values('salary_per_year', ascending=False))
Statistics and Probability
import statistics
import math
import random
# Demonstrate core statistical concepts
# Sampling and distributions
random.seed(42)
sample = [random.gauss(100, 15) for _ in range(1000)]
print("Simulated IQ score distribution (n=1000, mean=100, std=15):")
print(f" Sample mean: {statistics.mean(sample):.2f}")
print(f" Sample std dev: {statistics.stdev(sample):.2f}")
print(f" Sample median: {statistics.median(sample):.2f}")
# Distribution of scores in ranges
ranges = [(70, 85), (85, 100), (100, 115), (115, 130)]
print("\nScore distribution:")
for low, high in ranges:
count = sum(1 for x in sample if low <= x < high)
bar = '█' * (count // 20)
print(f" {low:3d}-{high:3d}: {count:4d} {bar}")
# Confidence interval approximation (95%)
n = len(sample)
mean = statistics.mean(sample)
std = statistics.stdev(sample)
margin = 1.96 * (std / math.sqrt(n))
print(f"\n95% confidence interval for mean:")
print(f" {mean - margin:.2f} to {mean + margin:.2f}")
# Correlation coefficient (manual implementation)
def pearson_correlation(x, y):
n = len(x)
mean_x = sum(x) / n
mean_y = sum(y) / n
numerator = sum((xi - mean_x) * (yi - mean_y) for xi, yi in zip(x, y))
denom_x = math.sqrt(sum((xi - mean_x)**2 for xi in x))
denom_y = math.sqrt(sum((yi - mean_y)**2 for yi in y))
return numerator / (denom_x * denom_y)
# Generate correlated data
x_data = [random.gauss(50, 10) for _ in range(100)]
y_data = [x + random.gauss(0, 5) for x in x_data] # correlated
z_data = [random.gauss(50, 10) for _ in range(100)] # uncorrelated
print(f"\nCorrelation tests:")
print(f" x vs y (should be high): {pearson_correlation(x_data, y_data):.3f}")
print(f" x vs z (should be low): {pearson_correlation(x_data, z_data):.3f}")
Advanced Python Patterns for Browser Use
These more advanced patterns demonstrate Python capabilities that are particularly useful in the browser context.
Functional Programming Patterns
from functools import reduce, partial
from itertools import groupby, chain, islice
# Map, filter, reduce
numbers = range(1, 21)
# Filter even numbers, square them, sum the result
result = reduce(
lambda acc, x: acc + x,
map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers))
)
print(f"Sum of squares of even numbers 1-20: {result}")
# Same with comprehension (more Pythonic)
result2 = sum(x**2 for x in range(1, 21) if x % 2 == 0)
print(f"Same result with comprehension: {result2}")
# Partial application
def multiply(x, y):
return x * y
double = partial(multiply, 2)
triple = partial(multiply, 3)
numbers_list = [1, 2, 3, 4, 5]
print(f"\nDoubled: {list(map(double, numbers_list))}")
print(f"Tripled: {list(map(triple, numbers_list))}")
# groupby - group sorted data
words = ['apple', 'ant', 'banana', 'bear', 'cat', 'cherry', 'dog']
words.sort()
print("\nWords grouped by first letter:")
for letter, group in groupby(words, key=lambda w: w[0]):
print(f" {letter}: {list(group)}")
# islice for working with large or infinite sequences
def fibonacci_generator():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
first_15_fibs = list(islice(fibonacci_generator(), 15))
print(f"\nFirst 15 Fibonacci numbers: {first_15_fibs}")
Object-Oriented Programming
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class Product:
name: str
price: float
category: str
in_stock: bool = True
tags: List[str] = field(default_factory=list)
def discounted_price(self, discount_pct: float) -> float:
return self.price * (1 - discount_pct / 100)
def __str__(self):
status = "In Stock" if self.in_stock else "Out of Stock"
return f"{self.name} (${self.price:.2f}) - {status}"
@dataclass
class ShoppingCart:
items: List[tuple] = field(default_factory=list) # (product, quantity)
def add(self, product: Product, quantity: int = 1):
self.items.append((product, quantity))
@property
def total(self) -> float:
return sum(p.price * q for p, q in self.items)
@property
def item_count(self) -> int:
return sum(q for _, q in self.items)
def summary(self) -> str:
lines = ["Shopping Cart:"]
for product, qty in self.items:
lines.append(f" {product.name} x{qty}: ${product.price * qty:.2f}")
lines.append(f"Total: ${self.total:.2f} ({self.item_count} items)")
return "\n".join(lines)
# Create products
products = [
Product("Laptop", 999.99, "Electronics", tags=["computer", "portable"]),
Product("Mouse", 49.99, "Electronics"),
Product("Keyboard", 79.99, "Electronics", tags=["input", "mechanical"]),
Product("Desk Lamp", 34.99, "Office"),
]
# Build a cart
cart = ShoppingCart()
cart.add(products[0], 1)
cart.add(products[1], 2)
cart.add(products[3], 1)
print(cart.summary())
print(f"\n10% discount on laptop: ${products[0].discounted_price(10):.2f}")
# Filter products by category
electronics = [p for p in products if p.category == "Electronics"]
print(f"\nElectronics ({len(electronics)}):")
for p in electronics:
print(f" {p}")
Context Managers and Resource Handling
from contextlib import contextmanager
import time
# Custom context manager using generator
@contextmanager
def timer(operation_name):
start = time.time()
try:
yield
finally:
elapsed = time.time() - start
print(f"{operation_name} took {elapsed*1000:.2f}ms")
# Demonstrate timing
with timer("List comprehension"):
result = [x**2 for x in range(10000)]
with timer("Generator (lazy)"):
gen = (x**2 for x in range(10000))
# Generator hasn't been fully evaluated yet
with timer("Generator (fully evaluated)"):
gen = (x**2 for x in range(10000))
total = sum(gen)
print(f"\nSum: {total:,}")
# Context manager for safe data processing
@contextmanager
def error_reporting(stage_name):
try:
print(f"Starting: {stage_name}")
yield
print(f"Completed: {stage_name}")
except Exception as e:
print(f"ERROR in {stage_name}: {type(e).__name__}: {e}")
raise
# Process data with error reporting at each stage
raw_data = ["10", "20", "abc", "30", "40"]
with error_reporting("Data parsing"):
numbers = []
for item in raw_data:
try:
numbers.append(int(item))
except ValueError:
print(f" Skipping invalid value: '{item}'")
print(f"Parsed values: {numbers}")
print(f"Sum: {sum(numbers)}")
Generators and Memory-Efficient Processing
# Generators are excellent for processing large data streams
# because they only compute values when needed
def read_csv_rows(csv_text):
"""Generator that yields rows from CSV text."""
import csv
from io import StringIO
reader = csv.DictReader(StringIO(csv_text))
for row in reader:
yield row
def filter_rows(rows, **conditions):
"""Generator that filters rows by conditions."""
for row in rows:
if all(row.get(k) == str(v) for k, v in conditions.items()):
yield row
def transform_row(rows, **transforms):
"""Generator that applies transforms to row values."""
for row in rows:
new_row = dict(row)
for key, func in transforms.items():
if key in new_row:
new_row[key] = func(new_row[key])
yield new_row
# Pipeline of generators
csv_data = """id,name,department,salary
1,Alice,Engineering,95000
2,Bob,Marketing,72000
3,Carol,Engineering,105000
4,David,HR,65000
5,Eve,Engineering,88000
6,Frank,Marketing,78000"""
# Build a processing pipeline
pipeline = read_csv_rows(csv_data)
pipeline = filter_rows(pipeline, department="Engineering")
pipeline = transform_row(pipeline,
salary=lambda s: int(s),
name=lambda n: n.upper()
)
print("Engineering team (transformed):")
total_salary = 0
for emp in pipeline:
print(f" {emp['name']}: ${emp['salary']:,}")
total_salary += emp['salary']
print(f"\nTotal engineering payroll: ${total_salary:,}")
print(f"Average: ${total_salary/3:,.0f}")
Teaching Python with Browser-Based Tools
For educators designing Python curriculum, browser-based execution enables several teaching approaches that are not possible or practical with local installations.
The Instant Feedback Classroom
The most immediate advantage of browser Python in a classroom is that every student gets to the “it works” moment in the same session where they first encounter the language. No setup delays, no platform-specific problems, no waiting for individual troubleshooting.
Day one structure that works:
Opening a URL. Loading the Python runner. Typing print("Hello, World!") and running it. Seeing the output. This sequence creates an immediate, visceral connection between writing code and seeing results.
In ten minutes, every student in the room has:
Written Python code
Run it successfully
Seen both successful output and error messages
Understood that Python is a tool that responds to their input
This foundation is far more motivating than spending the first session on setup documentation.
Structured Exercises with Templates
Educators can prepare code templates that students complete in the browser runner. A template approach:
# Exercise: Complete this function to return the sum of all even numbers
# in a list up to n
def sum_of_evens(n):
# Your code here
pass
# Test your implementation
print(sum_of_evens(10)) # Expected: 2+4+6+8+10 = 30
print(sum_of_evens(20)) # Expected: 110
print(sum_of_evens(5)) # Expected: 2+4 = 6
Students paste this template into the runner, complete the function body, and verify their solution against the expected outputs. The expected outputs serve as immediate, self-checking unit tests.
Error Exploration as Curriculum
Deliberately introducing errors and reading the tracebacks together is valuable curriculum content. The browser runner shows the same error messages as any Python environment:
# This code has several errors to find and fix
def calculate_average(numbers):
total = sum(numbers)
return total / len(numbers
averages = [10, 20, 30, 40, 50]
result = calculate_average(averages)
print(f"Average: {result}")
# Additional: what happens when numbers is empty?
empty = []
print(calculate_average(empty))
This code has a syntax error (missing closing parenthesis) and a runtime error (ZeroDivisionError when the list is empty). Working through these errors in class teaches both error-reading skills and defensive programming concepts.
Progression from Browser to Local
A well-designed curriculum uses browser Python for introductory concepts and transitions students to local Python when:
Projects grow beyond single-script scope
File system access becomes necessary
Package requirements exceed what Pyodide provides
Performance requirements exceed browser execution capability
The transition is natural because the Python learned in the browser runs identically on a local installation. Students who understand Python concepts from browser-based practice can install a local environment and continue without re-learning anything.
Python Recipes for Specific Domains
Different professional contexts have characteristic Python use cases. These domain-specific recipes demonstrate applicable patterns.
Finance and Business Calculations
from decimal import Decimal, ROUND_HALF_UP
# Use Decimal for precise financial calculations
def calculate_loan_payment(principal, annual_rate, years):
"""Calculate monthly mortgage payment using the standard formula."""
monthly_rate = annual_rate / 12
n_payments = years * 12
if monthly_rate == 0:
return principal / n_payments
payment = principal * (monthly_rate * (1 + monthly_rate)**n_payments) / \
((1 + monthly_rate)**n_payments - 1)
return round(payment, 2)
def amortization_summary(principal, annual_rate, years):
"""Show amortization summary for a loan."""
monthly_payment = calculate_loan_payment(principal, annual_rate, years)
total_paid = monthly_payment * years * 12
total_interest = total_paid - principal
return {
'monthly_payment': monthly_payment,
'total_paid': total_paid,
'total_interest': total_interest,
'interest_ratio': total_interest / principal
}
# Compare loan scenarios
scenarios = [
(300000, 0.07, 30, "30-year at 7%"),
(300000, 0.065, 30, "30-year at 6.5%"),
(300000, 0.07, 15, "15-year at 7%"),
]
print("Mortgage Comparison ($300,000 loan):")
print(f"{'Scenario':<22} {'Monthly':>10} {'Total Paid':>12} {'Interest':>12}")
print("-" * 60)
for principal, rate, years, label in scenarios:
summary = amortization_summary(principal, rate, years)
print(f"{label:<22} ${summary['monthly_payment']:>9,.2f} "
f"${summary['total_paid']:>11,.2f} ${summary['total_interest']:>11,.2f}")
Text Analysis and NLP Basics
import re
from collections import Counter
def basic_text_analysis(text):
"""Perform basic text analysis on a string."""
# Tokenize
words = re.findall(r'\b[a-z]+\b', text.lower())
# Common stopwords
stopwords = {'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at',
'to', 'for', 'of', 'with', 'by', 'from', 'is', 'was',
'are', 'were', 'be', 'been', 'being', 'have', 'has', 'had',
'do', 'does', 'did', 'will', 'would', 'could', 'should',
'may', 'might', 'must', 'can', 'it', 'this', 'that', 'these',
'those', 'i', 'you', 'he', 'she', 'we', 'they', 'what',
'which', 'who', 'how', 'when', 'where', 'not', 'no'}
# Content words (non-stopwords)
content_words = [w for w in words if w not in stopwords and len(w) > 2]
# Sentences (simple split)
sentences = re.split(r'[.!?]+', text)
sentences = [s.strip() for s in sentences if len(s.strip()) > 10]
freq = Counter(content_words)
return {
'total_words': len(words),
'unique_words': len(set(words)),
'content_words': len(content_words),
'sentence_count': len(sentences),
'avg_sentence_length': len(words) / max(len(sentences), 1),
'top_10_words': freq.most_common(10),
'vocabulary_richness': len(set(words)) / max(len(words), 1)
}
# Analyze a sample text
sample_text = """
Python is a high-level, general-purpose programming language. Its design
philosophy emphasizes code readability with the use of significant indentation.
Python is dynamically typed and garbage-collected. It supports multiple
programming paradigms, including structured, object-oriented and functional
programming. Python is often described as a batteries included language due
to its comprehensive standard library.
"""
analysis = basic_text_analysis(sample_text)
print("Text Analysis Results:")
print(f" Total words: {analysis['total_words']}")
print(f" Unique words: {analysis['unique_words']}")
print(f" Sentences: {analysis['sentence_count']}")
print(f" Avg sentence length: {analysis['avg_sentence_length']:.1f} words")
print(f" Vocabulary richness: {analysis['vocabulary_richness']:.2%}")
print(f"\nTop 10 content words:")
for word, count in analysis['top_10_words']:
bar = '|' * count
print(f" {word:<15} {count:2d} {bar}")
Data Validation and Quality Checking
import re
from datetime import datetime
def validate_record(record, rules):
"""
Validate a record against a set of rules.
Rules are dicts: {'field': field_name, 'type': str/int/float,
'required': True/False, 'pattern': regex,
'min': min_value, 'max': max_value}
"""
errors = []
for rule in rules:
field = rule['field']
value = record.get(field)
# Required check
if rule.get('required', False) and (value is None or value == ''):
errors.append(f"{field}: required but missing")
continue
if value is None or value == '':
continue
# Type check
if 'type' in rule:
try:
converted = rule['type'](value)
except (ValueError, TypeError):
errors.append(f"{field}: cannot convert '{value}' to {rule['type'].__name__}")
continue
# Range checks for numeric types
if rule['type'] in (int, float):
if 'min' in rule and converted < rule['min']:
errors.append(f"{field}: {converted} is below minimum {rule['min']}")
if 'max' in rule and converted > rule['max']:
errors.append(f"{field}: {converted} exceeds maximum {rule['max']}")
# Pattern check
if 'pattern' in rule and not re.match(rule['pattern'], str(value)):
errors.append(f"{field}: '{value}' does not match expected format")
return errors
# Define validation rules for a customer record
customer_rules = [
{'field': 'email', 'required': True, 'pattern': r'^[\w.-]+@[\w.-]+\.[a-z]{2,}$'},
{'field': 'age', 'required': True, 'type': int, 'min': 0, 'max': 150},
{'field': 'name', 'required': True},
{'field': 'phone', 'pattern': r'^\+?1?\d{10,14}$'},
{'field': 'zip_code', 'pattern': r'^\d{5}(-\d{4})?$'},
]
# Test records
test_records = [
{'email': 'alice@example.com', 'age': '28', 'name': 'Alice', 'phone': '5551234567', 'zip_code': '10001'},
{'email': 'not-an-email', 'age': '200', 'name': 'Bob', 'phone': 'abc', 'zip_code': '1234'},
{'email': 'carol@example.com', 'age': '35', 'name': '', 'zip_code': '90210'},
]
print("Record Validation Results:")
for i, record in enumerate(test_records, 1):
errors = validate_record(record, customer_rules)
status = "VALID" if not errors else f"INVALID ({len(errors)} errors)"
print(f"\nRecord {i}: {status}")
if errors:
for error in errors:
print(f" - {error}")
Python and the Broader Data Analysis Ecosystem
Python in the browser is most powerful as part of a connected workflow that spans multiple tools. Understanding how browser Python connects to other tools clarifies when to reach for Python versus when another tool is better suited.
Python vs SQL for Data Analysis
Python and SQL are complementary rather than competing tools for data analysis.
Use SQL when:
Data lives in a relational database and you want to query it there
You need joins across multiple tables
Aggregation and filtering are the primary operations
The dataset is large and benefits from database-optimized execution
The query needs to be maintained by non-Python users
Use Python when:
Data needs complex transformation beyond what SQL easily expresses
You need string processing with regular expressions
The analysis involves statistical modeling or machine learning
You need to process multiple files or data formats
The transformation logic is complex enough that procedural code is clearer than SQL
The SQL Query tool handles SQL-appropriate analysis on CSV files. The Python Code Runner handles Python-appropriate transformation. Used in sequence, they cover the full range of data manipulation workflows.
When to Use Jupyter Notebooks vs the Code Runner
The code runner and Jupyter notebooks (viewable via ReportMedic’s Jupyter Notebook Viewer) serve different purposes:
Code runner is better for: Quick scripts that produce output, algorithm testing, function development, data validation, calculations, and any task that fits naturally in a REPL workflow.
Jupyter notebooks are better for: Analysis that combines code and narrative explanation, data science workflows that should be reproducible and documented, sharing an analysis with both code and output intact, exploratory analysis with many intermediate steps.
The code runner is where you build and test Python logic. The Jupyter notebook is where you document an analysis that combines that logic with explanation and visualization.
Limitations and the Sweet Spot for Browser Python
Honest assessment of what browser Python does well and where it falls short helps you choose the right tool for each situation.
What Browser Python Excels At
Immediate execution without setup: Any situation where setup friction would otherwise prevent using Python benefits from browser execution. The zero-setup time is a genuine advantage for casual use, learning, and quick calculations.
Privacy-sensitive code execution: Code that processes personal data, confidential business data, or sensitive files benefits from running locally. No server sees the code or data.
Teaching and demonstration: Any educational context where consistent environments across students or attendees matter benefits from browser-based execution.
Algorithm and logic development: Pure Python logic development, data structure implementation, and algorithmic prototyping all work perfectly in the browser environment.
Standard library exploration: Learning what the Python standard library provides, testing standard library module behavior, and exploring built-in functions all work exactly the same as in a local installation.
Cross-platform consistency: Code that needs to behave consistently across Windows, macOS, Linux, and Chromebooks benefits from a browser-based environment that is identical across all platforms.
Where Local Python or Cloud Notebooks Are Better
Large dataset processing: Processing datasets larger than what fits comfortably in browser memory (typically above a few hundred megabytes) is better handled by a local installation or a cloud compute environment.
Machine learning model training: Training neural networks, large scikit-learn models, and other computationally intensive ML tasks benefit from dedicated hardware (GPU, large RAM) and optimized local libraries. Browser Python is appropriate for understanding ML concepts and small-scale examples but not for production training.
Packages not available in Wasm: Some packages with compiled C extensions that have not been compiled for WebAssembly are not available in the browser environment. If your workflow requires a specific package that is not available, a local installation is necessary.
Long-running scripts: Scripts that need to run for hours (batch processing, complex simulations) should run on dedicated compute rather than in a browser tab.
File system access for large files: While the File System Access API allows browser access to local files, processing very large files through the browser environment has practical memory limitations.
Production pipelines: Automated, scheduled, or production Python workflows need a server-side execution environment, not a browser tool.
The Right Mental Model
Browser Python is to local Python what a pocket calculator is to a full spreadsheet application: excellent for the quick, immediate computation it is designed for, and the right tool for many everyday situations, while the more capable tool exists for complex tasks that exceed its appropriate scope.
Comparison with Alternatives
Google Colab
Google Colab is the most widely used browser-based Python environment, providing a Jupyter notebook interface with Google’s cloud compute backing. Colab is excellent for: machine learning with GPU/TPU access, sharing notebooks with collaboration features, access to large memory and compute for big data tasks, integration with Google Drive and Google Cloud services.
Colab requires a Google account, uploads data and code to Google’s servers, has session time limits that disconnect inactive sessions, and requires internet connectivity for execution (since computation happens on Google’s servers, not locally).
ReportMedic’s Python Code Runner is better for: privacy-sensitive code that should not leave the device, quick tasks without account requirements, situations where internet connectivity is limited, and simple code execution without the overhead of a notebook interface.
Replit
Replit is a browser-based development environment with a Python runner, a full file system, multi-file project support, and collaboration features. Replit is a development platform rather than a quick execution tool.
Replit requires an account, runs code on remote servers (code and data are transmitted to Replit’s infrastructure), and has usage limits on free plans. It is appropriate for building and hosting small applications, collaborative coding education, and multi-file project development.
For quick single-file Python execution without data leaving the device, the browser-based local runner is simpler and more private.
Jupyter Notebook (Local)
Running Jupyter notebooks locally provides the full Jupyter experience with complete package support, persistent files, and integration with local data. Jupyter locally is the gold standard for data science workflows.
The requirement is a working local Python installation with Jupyter installed. For users who already have this, local Jupyter is excellent for data science work. For situations where this setup is unavailable or undesirable, browser-based execution provides Python access without it.
ReportMedic’s Jupyter Notebook Viewer complements the Python Code Runner by allowing .ipynb notebook files to be viewed in the browser without a Jupyter installation, making notebooks accessible to non-technical recipients.
PythonAnywhere
PythonAnywhere is a hosted Python environment that provides persistent Python consoles, file storage, and web app hosting. It requires an account and runs code on PythonAnywhere’s servers.
Good for: persistent Python environments that survive sessions, hosting Python web applications, educational environments that need persistent student work. Not appropriate for privacy-sensitive code execution where data should not leave the local device.
Online Python Compilers (tutorialspoint, w3schools, etc.)
Many educational websites provide simple online Python runners as supplements to their tutorials. These typically transmit code to servers for execution. They are useful for basic syntax demonstration but are not appropriate for sensitive code and often have limitations on execution time and available libraries.
Integrating Browser Python with Other ReportMedic Tools
The Python Code Runner fits naturally into workflows that connect to other ReportMedic tools.
Python for Data Preparation Before SQL Querying
Write Python to clean and reshape a dataset, then use ReportMedic’s SQL Query tool to query the cleaned data with SQL. Python handles complex string manipulation, regular expression cleaning, and programmatic transformations. SQL handles filtering, aggregation, and reporting on the cleaned data.
Example workflow:
Use Python Code Runner to clean a messy CSV: strip whitespace, normalize formats, validate email patterns, fix date formats
Export the cleaned data as a CSV string
Import the cleaned CSV into the SQL Query tool for analysis
import csv
from io import StringIO
# Example: Clean data to prepare for SQL querying
raw_data = [
{"email": " ALICE@EXAMPLE.COM ", "amount": "1,250.00", "date": "01/15/2024"},
{"email": "bob@example.com", "amount": "890", "date": "2024-02-20"},
{"email": " Carol@Example.com", "amount": "$345.67", "date": "March 3, 2024"},
]
def clean_amount(amount_str):
cleaned = amount_str.replace(",", "").replace("$", "").strip()
return float(cleaned)
cleaned = []
for row in raw_data:
cleaned.append({
"email": row["email"].strip().lower(),
"amount": clean_amount(row["amount"]),
"raw_date": row["date"] # date normalization would need more logic
})
output = StringIO()
writer = csv.DictWriter(output, fieldnames=["email", "amount", "raw_date"])
writer.writeheader()
writer.writerows(cleaned)
print("Cleaned CSV output:")
print(output.getvalue())
Python for Pre-Processing Before Visualization
Prepare data in the Python runner, then explore it visually through other ReportMedic analysis tools. Python handles the complex transformations; the visualization and analysis tools provide the interactive exploration layer.
Python as a Learning Companion
The Python Code Runner and the Jupyter Notebook Viewer are complementary learning tools. The Viewer lets learners open and read through Jupyter notebooks that contain explanations and examples. The Code Runner lets them run, modify, and experiment with code from those notebooks. Together they provide a complete read-modify-run learning loop without any local setup.
Tips for Effective Browser Python Use
Write Self-Contained Scripts
Browser Python sessions reset between runs. Variables, imports, and state from previous executions do not persist. Write each script to be self-contained: include all necessary imports, define all needed functions, and include the data or data generation code inline.
This self-contained approach is actually good Python practice for reproducible code: scripts that declare all their dependencies and include all necessary data setup can be understood and run without needing to know the prior state of the environment.
Use Print Statements Generously
The output console shows only what you explicitly print (or error messages). Unlike a Jupyter notebook, which displays the value of the last expression in each cell, the browser runner requires explicit print() calls to see intermediate values.
When debugging, add print statements at each stage:
data = load_data()
print(f"Loaded {len(data)} rows") # confirm loading worked
filtered = filter_data(data)
print(f"After filter: {len(filtered)} rows") # confirm filter worked
result = process(filtered)
print(f"Result: {result}") # see final output
Structure Complex Scripts as Functions
For longer scripts, defining the logic as functions (even when called only once) makes the code easier to read, debug, and modify:
def load_and_parse(csv_text):
"""Parse CSV text and return a list of dicts."""
import csv
from io import StringIO
reader = csv.DictReader(StringIO(csv_text))
return list(reader)
def calculate_summary(records):
"""Calculate summary statistics from records."""
values = [float(r['amount']) for r in records]
return {
'count': len(values),
'total': sum(values),
'mean': sum(values) / len(values),
'min': min(values),
'max': max(values)
}
def format_report(summary):
"""Format summary as a readable report."""
return "\n".join([
f"Records: {summary['count']}",
f"Total: ${summary['total']:,.2f}",
f"Average: ${summary['mean']:,.2f}",
f"Min: ${summary['min']:,.2f}",
f"Max: ${summary['max']:,.2f}"
])
# Run the pipeline
csv_data = """name,amount
Alice,1250.00
Bob,890.50
Carol,345.75
David,2100.00"""
records = load_and_parse(csv_data)
summary = calculate_summary(records)
report = format_report(summary)
print(report)
Handle Errors Explicitly
The browser runner displays Python exceptions with full tracebacks. When developing code that might fail on specific inputs, use try/except blocks to provide informative error messages:
def safe_parse_number(s):
try:
return float(s.replace(',', '').replace('$', '').strip())
except (ValueError, AttributeError) as e:
print(f"Warning: Could not parse '{s}' as number: {e}")
return None
test_values = ["1,250.00", "$89.99", "invalid", "", None]
for val in test_values:
result = safe_parse_number(val)
if result is not None:
print(f" '{val}' -> {result}")
Frequently Asked Questions
Does the Python Code Runner have internet access from within Python?
Browser-based Python execution using WebAssembly runs in the browser’s security sandbox. Standard HTTP requests using Python’s urllib or requests may be limited by browser security policies (CORS restrictions). For data fetching within Python scripts, this can be a limitation compared to native Python. For processing data that you provide directly in the script (inline data, constants, user input), internet access is not required and the tool works fully offline after the initial page load.
What Python version does the browser runner use?
The browser runner uses a recent stable version of Python 3 via Pyodide. The exact version follows Pyodide’s release cycle, which tracks reasonably closely to Python’s stable releases. All Python 3 syntax and the complete standard library are available. The tool does not support Python 2 syntax.
Can I use NumPy and Pandas in the browser runner?
Yes. Pyodide includes pre-compiled versions of NumPy, Pandas, Matplotlib, SciPy, and other commonly used scientific Python packages. These libraries are available without any installation step. For packages not included by default, Pyodide’s micropip can install additional packages that have WebAssembly-compatible versions available.
Is my code and data private when using the browser runner?
Yes. The Python Code Runner processes all code and data locally in your browser using the WebAssembly runtime. No code, no data, and no output is transmitted to any server. Your scripts and the data they process stay on your device. This makes the browser runner appropriate for processing sensitive business data, personal information, and confidential calculations that should not leave your machine.
Can I save my scripts between sessions?
Browser Python sessions are stateless: code and state from one session do not persist to the next by default. To save your code, copy it to a text file (any text editor, saved as .py) and paste it back into the runner in future sessions. This is also good practice for building a personal library of useful scripts. Alternatively, use the browser’s built-in notes feature or a cloud text document to save frequently used code snippets accessible from any device.
How does browser Python performance compare to native Python?
WebAssembly execution is generally 1.5 to 5 times slower than native Python for compute-intensive operations. For most everyday Python tasks (string processing, data manipulation with Pandas, algorithm implementation, CSV parsing, JSON processing), the performance difference is not practically meaningful: operations that take a few milliseconds natively take a few milliseconds to perhaps tens of milliseconds in the browser. For very compute-intensive tasks (training machine learning models, processing very large datasets, running complex simulations), native Python or cloud compute is more appropriate.
What is the difference between the browser runner and Jupyter notebooks?
Jupyter notebooks provide a document-based interface where code is organized in cells, output is preserved inline below each cell, and the document can be saved and shared with both code and output included. The notebook format is excellent for data analysis workflows where the analysis and its results are part of a cohesive document. The browser runner provides a simpler REPL-style interface where you write code, run it, see the output, and revise. The runner is better for quick scripts, algorithm testing, and situations where the notebook’s document overhead is unnecessary. For viewing existing .ipynb notebooks, ReportMedic’s Jupyter Notebook Viewer renders notebooks directly in the browser.
Can I process files from my computer with browser Python?
Browser Python can process file content that you paste or type directly into the script as string data. For processing actual files from your filesystem, browser Python (through Pyodide’s file handling) can access files selected through browser file input elements, enabling reading CSV files, JSON files, and text files from your local system for processing in Python code. The SQL Query tool provides a more direct interface for querying CSV files with SQL if that matches your use case.
Can I use the browser runner to learn Python from scratch?
Yes, and it is an excellent starting point. The browser runner provides the same feedback loop (write code, run it, see the result or error) as any Python environment, without the setup barrier. The complete Python standard library is available, covering all introductory Python topics. When you are comfortable with Python fundamentals and ready for a local installation (for larger projects, package management, and file system access), the transition is straightforward because the Python you learned in the browser runs identically on a local installation.
What should I do if my code runs but produces no output?
No output usually means the code executed successfully but produced no printed output. Python only outputs what you explicitly print. Check that your code includes print() calls for any values you want to see. The last expression in a script does not display automatically (unlike Jupyter notebooks). Add print(result) for any variable you want to inspect. If you expected output and got none, trace through your code and add print statements at each stage to understand what is executing and what values are produced.
Key Takeaways
Browser-based Python removes the most significant barrier to Python use: the setup process. By running Python entirely in the browser using WebAssembly, it provides an immediately available Python environment on any device with a modern browser.
ReportMedic’s Python Code Runner processes code and data locally on your device. Nothing is transmitted to any server, making it appropriate for privacy-sensitive calculations and data processing.
The tool is excellent for: learning Python from scratch, quick calculations and script testing, teaching Python without IT coordination, algorithm development and interview preparation, data transformation tasks, and any situation where setup friction would otherwise prevent using Python.
For large-scale data analysis, machine learning model training, and production workflows, local Python installations and cloud compute environments are the appropriate tools.
The Python Code Runner connects naturally with ReportMedic’s SQL Query tool for data that needs both programmatic transformation and SQL analysis, and with ReportMedic’s Jupyter Notebook Viewer for making Python notebooks accessible without a Jupyter installation.
The wall between wanting to use Python and running Python code is gone. Open the browser, open the tool, write code.
Explore all of ReportMedic’s browser-based tools at reportmedic.org.
Python Standard Library Deep Dive
The standard library is one of Python’s most powerful features and a key reason “batteries included” describes the language well. Everything in the standard library is available in browser Python without any installation.
The collections Module
The collections module provides specialized container types that solve common data structuring problems more elegantly than built-in types.
from collections import Counter, defaultdict, deque, namedtuple, OrderedDict
# Counter: count occurrences efficiently
words = "to be or not to be that is the question to be".split()
word_count = Counter(words)
print("Word frequency:")
print(word_count.most_common(5))
# Counter arithmetic
text1 = Counter("hello world")
text2 = Counter("world peace")
print(f"\nCharacters in text1 but not text2: {text1 - text2}")
print(f"Characters in either: {text1 | text2}")
print(f"Characters in both: {text1 & text2}")
# defaultdict: dictionary with default values for missing keys
# Avoids KeyError and setdefault() boilerplate
inventory = defaultdict(int)
purchases = [('apple', 3), ('banana', 2), ('apple', 5), ('cherry', 1), ('banana', 4)]
for item, quantity in purchases:
inventory[item] += quantity # No need to check if key exists
print("\nInventory:", dict(inventory))
# deque: double-ended queue, efficient O(1) append/pop from both ends
# Perfect for sliding window problems, BFS queues, recent-items tracking
recent = deque(maxlen=3) # Keep only the 3 most recent
for item in ['a', 'b', 'c', 'd', 'e']:
recent.append(item)
print(f"\nRecent 3 items: {list(recent)}")
# namedtuple: lightweight, immutable record with named fields
Point = namedtuple('Point', ['x', 'y', 'label'])
points = [Point(0, 0, 'origin'), Point(3, 4, 'p1'), Point(-1, 2, 'p2')]
for p in points:
distance = (p.x**2 + p.y**2)**0.5
print(f"Point '{p.label}' at ({p.x}, {p.y}): distance from origin = {distance:.2f}")
The itertools Module
itertools provides efficient tools for iterator-based operations that are memory-efficient and composable.
from itertools import product, permutations, combinations, chain, cycle, accumulate
# product: Cartesian product
suits = ['♠', '♥', '♦', '♣']
values = ['A', 'K', 'Q', 'J', '10']
face_cards = list(product(values, suits))
print(f"Face cards: {len(face_cards)} combinations")
print(f"Sample: {face_cards[:4]}")
# combinations: choose k from n (order doesn't matter)
team = ['Alice', 'Bob', 'Carol', 'David', 'Eve']
pairs = list(combinations(team, 2))
print(f"\nPossible pairs from team of 5: {len(pairs)}")
print(f"First 3: {pairs[:3]}")
# permutations: arrangements (order matters)
slots = list(permutations(['Gold', 'Silver', 'Bronze']))
print(f"\nWays to assign medals to 3 people: {len(slots)}")
# chain: flatten/combine iterables
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]
combined = list(chain(list1, list2, list3))
print(f"\nChained: {combined}")
# accumulate: running calculations
values = [1, 2, 3, 4, 5]
running_total = list(accumulate(values))
print(f"Values: {values}")
print(f"Running total: {running_total}")
import operator
running_product = list(accumulate(values, operator.mul))
print(f"Running product: {running_product}")
The pathlib and io Modules
from pathlib import PurePath
from io import StringIO, BytesIO
import csv
# PurePath: work with file paths without actual filesystem access
# Useful for path manipulation logic testing
path = PurePath('/home/user/documents/project/data/results.csv')
print(f"Name: {path.name}")
print(f"Stem: {path.stem}")
print(f"Suffix: {path.suffix}")
print(f"Parent: {path.parent}")
print(f"Parts: {path.parts}")
# Constructing paths
new_path = PurePath('/home/user') / 'documents' / 'output.txt'
print(f"\nConstructed path: {new_path}")
# io.StringIO: in-memory text stream
# Treat a string as a file-like object
csv_content = "name,value\nalice,100\nbob,200\n"
buffer = StringIO(csv_content)
reader = csv.DictReader(buffer)
for row in reader:
print(f" {row['name']}: {row['value']}")
# Writing CSV to a StringIO buffer
output_buffer = StringIO()
writer = csv.writer(output_buffer)
writer.writerow(['product', 'quantity', 'price'])
writer.writerows([
['Widget A', 100, 9.99],
['Widget B', 50, 14.99],
['Widget C', 200, 4.99],
])
csv_output = output_buffer.getvalue()
print(f"\nGenerated CSV:\n{csv_output}")
The hashlib and base64 Modules
import hashlib
import base64
import secrets
# Hashing strings
messages = ["Hello, World!", "Hello, World!", "Hello, world!"]
print("SHA-256 hashes:")
for msg in messages:
hash_val = hashlib.sha256(msg.encode()).hexdigest()
print(f" '{msg}': {hash_val[:16]}...")
# Note: identical strings produce identical hashes
# One character difference produces a completely different hash
print("\nNote: 'World' vs 'world' produces completely different hashes")
# MD5 for checksums (not security-critical use)
file_content = "This is the content of a file"
checksum = hashlib.md5(file_content.encode()).hexdigest()
print(f"\nMD5 checksum: {checksum}")
# Base64 encoding and decoding
original = "Binary data: \x00\x01\x02\x03"
encoded = base64.b64encode(original.encode('latin-1')).decode()
decoded = base64.b64decode(encoded).decode('latin-1')
print(f"\nBase64 encoded: {encoded}")
print(f"Decoded matches original: {decoded == original}")
# URL-safe base64 (for tokens, IDs, etc.)
token_bytes = secrets.token_bytes(16)
token = base64.urlsafe_b64encode(token_bytes).decode().rstrip('=')
print(f"\nURL-safe random token: {token}")
# Generate secure random values
print(f"Random integer (1-100): {secrets.randbelow(100) + 1}")
print(f"Random hex: {secrets.token_hex(8)}")
Building Useful Python Utilities in the Browser
These complete utility scripts demonstrate building practical tools with browser Python.
CSV Data Transformer
import csv
from io import StringIO
def transform_csv(input_csv, column_transforms=None, filter_func=None,
new_columns=None, drop_columns=None):
"""
Generic CSV transformation pipeline.
Args:
input_csv: CSV string to transform
column_transforms: dict of {column: transform_function}
filter_func: function that takes a row dict and returns True/False
new_columns: dict of {new_column: function(row) -> value}
drop_columns: list of columns to remove
"""
reader = csv.DictReader(StringIO(input_csv))
rows = list(reader)
# Apply filter
if filter_func:
rows = [r for r in rows if filter_func(r)]
# Apply column transforms
if column_transforms:
for row in rows:
for col, transform in column_transforms.items():
if col in row:
try:
row[col] = transform(row[col])
except Exception as e:
row[col] = f"ERROR: {e}"
# Add new columns
if new_columns:
for row in rows:
for col, func in new_columns.items():
row[col] = func(row)
# Drop columns
if drop_columns:
for row in rows:
for col in drop_columns:
row.pop(col, None)
if not rows:
return ""
output = StringIO()
writer = csv.DictWriter(output, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
return output.getvalue()
# Sample data
sales_csv = """id,customer,product,amount,region,active
1,Alice Corp,Widget A,1250.50,North,Y
2,Bob LLC,Widget B,890.00,South,N
3,Carol Inc,Widget A,2100.75,North,Y
4,David Co,Widget C,450.25,East,Y
5,Eve Ltd,Widget B,1875.00,West,N
"""
result = transform_csv(
sales_csv,
column_transforms={
'amount': float,
'active': lambda x: x == 'Y'
},
filter_func=lambda row: row.get('active') == 'Y',
new_columns={
'amount_with_tax': lambda r: round(float(r['amount']) * 1.1, 2)
},
drop_columns=['active']
)
print("Transformed CSV (active customers only, with tax):")
print(result)
Simple Template Engine
import re
def render_template(template, context):
"""
Simple template engine that replaces {{variable}} with values.
Supports: {{variable}}, {{#if condition}}...{{/if}}, {{#each list}}...{{/each}}
"""
# Replace simple variables
def replace_var(match):
key = match.group(1).strip()
value = context.get(key, '')
return str(value)
result = re.sub(r'\{\{([^#/][^}]*)\}\}', replace_var, template)
# Handle simple conditionals (very basic)
def replace_if(match):
condition_key = match.group(1).strip()
content = match.group(2)
if context.get(condition_key):
return content
return ''
result = re.sub(r'\{\{#if (\w+)\}\}(.*?)\{\{/if\}\}', replace_if, result, flags=re.DOTALL)
return result
# Email template
email_template = """
Dear {{customer_name}},
Thank you for your order #{{order_id}}.
Order Summary:
Product: {{product_name}}
Quantity: {{quantity}}
Unit Price: ${{unit_price}}
Total: ${{total}}
{{#if expedited}}
Your order has been flagged for expedited shipping and will arrive in 1-2 business days.
{{/if}}
Best regards,
{{company_name}}
"""
# Render for a specific order
context = {
'customer_name': 'Alice Johnson',
'order_id': 'ORD-2024-001',
'product_name': 'Professional Keyboard',
'quantity': 2,
'unit_price': '79.99',
'total': '159.98',
'expedited': True,
'company_name': 'ReportMedic Tech'
}
print(render_template(email_template, context).strip())
Frequently Asked Questions (Continued)
How do I work with dates in browser Python?
The datetime module is fully available and works identically to native Python. Use datetime.datetime.now() for the current timestamp, datetime.date.today() for the current date, datetime.timedelta for date arithmetic, and strftime/strptime for formatting and parsing. One consideration: the browser Python environment’s time zone handling uses the browser’s local time zone, which may differ from expectations if you are building timezone-sensitive applications.
Can I import external Python libraries not included in Pyodide?
Yes, through micropip. Micropip is Pyodide’s package installer that can install Python packages that have been compiled for WebAssembly or are pure Python. In the code runner, import micropip followed by await micropip.install('package-name') (in an async context) installs the package. Not all packages are available in the Wasm environment: packages with C extensions that have not been compiled for WebAssembly (which is most C-extension packages) are not available. Pure Python packages from PyPI generally work. The set of available packages grows as the Pyodide project compiles more packages for WebAssembly.
Key Takeaways
Browser-based Python execution, powered by WebAssembly and Pyodide, provides a complete, private, installation-free Python environment in any modern browser. ReportMedic’s Python Code Runner makes this accessible without any account or installation.
The standard library and key scientific packages (NumPy, Pandas, Matplotlib, SciPy) are available without any setup. Algorithms, data structures, string processing, CSV parsing, JSON handling, statistical calculations, and data transformation all work exactly as they do in native Python.
The sweet spot: learning Python without setup friction, quick calculations and script testing on any device, privacy-sensitive processing that should not leave the machine, teaching Python without IT coordination, and algorithm development and interview preparation.
The tool connects naturally with ReportMedic’s SQL Query tool for workflows that combine programmatic data transformation with SQL analysis, and with ReportMedic’s Jupyter Notebook Viewer for making Python notebooks accessible to all audiences.
Open a browser. Open the tool. Write Python. The environment is ready.
Explore all of ReportMedic’s browser-based tools at reportmedic.org.
A Note on Python as a Long-Term Skill
Python is consistently one of the most widely used programming languages across data science, web development, automation, scientific computing, and education. Learning it is an investment that pays dividends across many contexts.
The browser runner lowers the barrier to starting that investment dramatically. Someone who would have given up during setup can spend that time actually learning Python instead. Someone who already knows Python but is on an unfamiliar machine can write and run code in thirty seconds instead of thirty minutes.
The long-term trajectory from browser Python to full Python development is clear: start in the browser with the fundamentals, build real comfort with the language, then install a local environment when projects grow beyond what a single browser-based script can handle. The Python you learned in the browser transfers completely. No relearning required.
That is the promise of the browser Python runner: not a toy version of Python, but the same language, the same standard library, the same behavior, with the wall knocked down.
Quick-Start Python Recipes Reference
For immediate use without reading the full guide, here are the most useful one-liners and short snippets for common tasks:
# Word count in a string
text = "your text here"
print(len(text.split()))
# Unique values in a list (preserving order)
items = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
unique = list(dict.fromkeys(items))
# Flatten a nested list
nested = [[1, 2], [3, 4], [5, 6]]
flat = [x for sublist in nested for x in sublist]
# Count occurrences
from collections import Counter
data = ['a', 'b', 'a', 'c', 'b', 'a']
print(Counter(data))
# Check if a string is numeric
"123.45".replace('.', '', 1).isdigit() # True
"12abc".replace('.', '', 1).isdigit() # False
# Parse JSON
import json
data = json.loads('{"name": "Alice", "age": 30}')
# Format a number with commas
print(f"{1234567.89:,.2f}") # 1,234,567.89
# All permutations
from itertools import permutations
list(permutations([1, 2, 3], 2))
# Group a list into chunks
lst = list(range(10))
chunks = [lst[i:i+3] for i in range(0, len(lst), 3)]
# Zip two lists into a dict
keys = ['a', 'b', 'c']
values = [1, 2, 3]
d = dict(zip(keys, values))
# Find duplicates in a list
from collections import Counter
data = [1, 2, 3, 2, 4, 3, 5]
duplicates = [k for k, v in Counter(data).items() if v > 1]
# Transpose a matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = list(zip(*matrix))
These recipes are all available in the browser runner immediately. Copy, modify, and run.
