Python Tutor
Generate a Jupyter notebook filled with practice challenges and questions. Challenges cover pandas (data manipulation, cleaning, exploration, time series) and algorithms (vanilla Python data structures, sorting, searching, recursion).
Follow the rules in RULES.md.
Workflow
Gather parameters using AskUserQuestion. Ask the user:
- Category: Which category to focus on, or generate a random mix from all categories. Present the subcategories listed below.
- Difficulty: easy, medium, or hard.
- Number of questions: How many challenges to include (default 10).
- Output directory: Where to save the notebook. Default is
notebooks/practice.
- Previous exercises folder (optional): Path to a folder containing previous practice notebooks. If provided, scan these notebooks to avoid repeating exact questions. You may generate the same type of question but must vary the data, parameters, or scenario to ensure uniqueness.
Check for previous exercises (if folder provided):
- Scan notebooks in the previous exercises folder for question prompts.
- Extract the core challenge type from each (e.g., "filter DataFrame by condition", "implement binary search").
- When generating new questions, avoid repeating the exact same prompt. You may reuse the same question type but must change the data, column names, values, or scenario to make it fresh.
Generate varied question data using the helper scripts (see Scripts below). For every notebook:
- Run
random_tickers.py to pick a fresh set of tickers for the session.
- Run
fetch_price_data.py to get real market data for those tickers. Use the --format code or --format returns flag to get a Python snippet you can embed in the notebook setup cell.
- Run
random_data.py to generate random numbers, date ranges, or messy DataFrames as needed by the questions.
- Vary the data in each question so notebooks are never identical.
Build the notebook using generate_notebook.py:
- Option A — from the question bank: Use
--bank to pull pre-written questions and randomize:python scripts/generate_notebook.py \
--bank questions/bank.json \
--category pandas --difficulty easy --count 5 \
--output notebooks/practice
- Option B — custom questions: Generate a JSON array of question objects and pipe to the script:
python scripts/generate_notebook.py \
--category pandas --difficulty medium \
--output notebooks/practice < /tmp/questions.json
- Each question object must have
prompt (str) and solution (str). Optional fields:
hint (str, will be rendered in a collapsed <details> tag). Hints must be hidden by default.
setup (str, per-question code cell), subcategory (str).
Customize the setup cell — replace the template's sample data with the real market data fetched in step 3. Use the output of fetch_price_data.py --format code or --format returns as the setup cell content.
Confirm the notebook path to the user when finished.
Notebook Structure
Each generated notebook must follow this structure:
- Title cell (markdown): includes category, difficulty, date, and number of questions.
- Setup cell (code): import statements and sample datasets. For pandas notebooks, embed real market data fetched with
fetch_price_data.py.
- For each question:
- A markdown cell with the challenge prompt, numbered (e.g. "### Challenge 1"). Include:
- A clear problem statement
- Any sample data or expected output
- When appropriate include a hidden hint wrapped in a
<details><summary>💡 Hint</summary>...</details> tag (initially collapsed).
- An empty code cell for the user to write their solution.
- A hidden solution cell wrapped in a markdown
<details><summary>✅ Solution</summary>...</details> tag so the user can reveal it.
Scripts
All scripts live in scripts/ and are run from that directory.
generate_notebook.py
Builds a .ipynb file from a category template + question data. Uses nbformat.
# From question bank:
python scripts/generate_notebook.py --bank questions/bank.json \
--category pandas --subcategory series --difficulty easy --count 5 --output notebooks/practice
# From a JSON file of custom questions:
python scripts/generate_notebook.py --questions /tmp/my_questions.json \
--category algorithms --difficulty hard --output notebooks/practice
# From stdin:
cat questions.json | python scripts/generate_notebook.py --category pandas --output notebooks/practice
random_tickers.py
Pick random ticker symbols to use in questions. Avoids repeating the same tickers.
python scripts/random_tickers.py --count 4 # 4 random tickers
python scripts/random_tickers.py --count 3 --sector tech # from tech sector
python scripts/random_tickers.py --count 5 --diverse # one per sector
python scripts/random_tickers.py --list-sectors # show all sectors
Use this every time you generate a notebook to ensure fresh ticker sets.
fetch_price_data.py
Fetch real stock price data from Yahoo Finance via yfinance. Embed the output in notebook setup cells so students work with real market data.
# Get a code snippet to embed in the notebook
python scripts/fetch_price_data.py --tickers AAPL MSFT TSLA --period 6mo --format code
# Get daily returns as a code snippet
python scripts/fetch_price_data.py --tickers AAPL MSFT --period 3mo --format returns
# Random tickers + real data
python scripts/fetch_price_data.py --random 4 --period 1y --format code
# Save as CSV
python scripts/fetch_price_data.py --tickers SPY QQQ --start 2023-01-01 --end 2024-01-01 --output prices.csv
random_data.py
Generate random numbers, date ranges, names, and messy DataFrames for question variety.
python scripts/random_data.py --type integers --count 10 --min 1 --max 100
python scripts/random_data.py --type floats --count 5 --min -0.05 --max 0.05
python scripts/random_data.py --type date_range --start 2020-01-01 --periods 30 --freq B
python scripts/random_data.py --type names --count 8
python scripts/random_data.py --type messy_dataframe --rows 20
Use --type messy_dataframe to generate data-cleaning exercises with realistic problems (missing values, inconsistent casing, whitespace, bad types, duplicates).
Templates
Category-specific notebook templates live in templates/. Each template provides:
- A title cell with
{{difficulty}}, {{date}}, {{count}}, {{subcategories}} placeholders
- A setup cell with appropriate imports and sample datasets
| Template |
File |
Description |
| Pandas |
templates/pandas_template.ipynb |
Imports pandas, numpy, matplotlib, seaborn. Pre-built sample datasets (stock_returns, messy_data, sectors). |
| Algorithms |
templates/algorithms_template.ipynb |
Imports collections, heapq, math, typing. Includes a check() helper for testing solutions. |
Question Bank
Pre-written questions are stored in questions/bank.json. The bank is organized as:
{ category: { subcategory: { difficulty: [question, ...] } } }
Each question has: prompt, solution, and optionally hint and setup.
Categories and Subcategories
Pandas
Refer to references/PANDAS_NOTE.md for the topic tree and references/PANDAS_FOR_DATA_SCIENCE.md for functions and techniques. Use examples/PANDAS_EXAMPLES.md for sample data patterns.
Subcategories:
- Series: creation, retrieval, modification, alignment, built-in methods
- DataFrames: retrieval (loc/iloc, slicing, boolean masks), modification, column operations
- Data exploration: apply/applymap, correlations, covariance, DataFrame-Series arithmetic
- Missing data: detection, dropping, filling, interpolation
- Reindexing and sorting: reindex, drop, sort_index, sort_values
- Categorical data: unique values, value_counts, isin, dummy variables
- File I/O: reading/writing CSV, Excel, pickle
- Multi-indexing: multi-index DataFrames and Series, stack/unstack, swaplevel
- Time series: timestamps, offsets, date ranges, resampling, shifting
- GroupBy, pivot, merge: groupby, pivot_table, merge/join, concat
- Rolling and quantiles: rolling windows, qcut, shift for returns
- Plotting: line, bar, scatter, histograms, heatmaps with seaborn
Algorithms
Focused on vanilla Python (no external libraries).
Subcategories:
- Data structures: lists, dicts, sets, tuples, deques, heaps
- Sorting: bubble, merge, quick, insertion sort implementations
- Searching: linear search, binary search
- Recursion: factorial, fibonacci, tree traversal, divide and conquer
- String manipulation: reversal, palindromes, anagrams, pattern matching
- Math and logic: primes, GCD, modular arithmetic, bit manipulation
Difficulty Levels
- Easy: Single-concept problems. Provide hints and sample data. Expect 1-5 lines of code per solution.
- Medium: Combine 2-3 concepts. Provide sample data but no hints. Expect 5-15 lines of code.
- Hard: Multi-step problems requiring chaining operations or designing algorithms. No hints. Expect 10-30+ lines of code.
Additional Resources
- For pandas topic details, see references/PANDAS_NOTE.md
- For pandas functions reference, see references/PANDAS_FOR_DATA_SCIENCE.md
- For numpy context, see references/NUMPY.md
- For code examples and sample data, see examples/PANDAS_EXAMPLES.md
1---2name: python-practice3description: Generate Jupyter notebook practice challenges for Python. Use when the user wants practice problems, coding exercises, study notebooks, or drill questions for pandas or algorithms.4---5
6# Python Tutor
7
8Generate a Jupyter notebook filled with practice challenges and questions. Challenges cover **pandas** (data manipulation, cleaning, exploration, time series) and **algorithms** (vanilla Python data structures, sorting, searching, recursion).
9
10Follow the rules in [RULES.md](RULES.md).
11
12## Workflow
13
141. **Gather parameters** using AskUserQuestion. Ask the user:
15 - **Category**: Which category to focus on, or generate a random mix from all categories. Present the subcategories listed below.
16 - **Difficulty**: easy, medium, or hard.
17 - **Number of questions**: How many challenges to include (default 10).
18 - **Output directory**: Where to save the notebook. Default is `notebooks/practice`.
19 - **Previous exercises folder** (optional): Path to a folder containing previous practice notebooks. If provided, scan these notebooks to avoid repeating exact questions. You may generate the same *type* of question but must vary the data, parameters, or scenario to ensure uniqueness.
20
212. **Check for previous exercises** (if folder provided):
22 - Scan notebooks in the previous exercises folder for question prompts.
23 - Extract the core challenge type from each (e.g., "filter DataFrame by condition", "implement binary search").
24 - When generating new questions, avoid repeating the exact same prompt. You may reuse the same question *type* but must change the data, column names, values, or scenario to make it fresh.
25
263. **Generate varied question data** using the helper scripts (see [Scripts](#scripts) below). For every notebook:
27 - Run `random_tickers.py` to pick a fresh set of tickers for the session.
28 - Run `fetch_price_data.py` to get real market data for those tickers. Use the `--format code` or `--format returns` flag to get a Python snippet you can embed in the notebook setup cell.
29 - Run `random_data.py` to generate random numbers, date ranges, or messy DataFrames as needed by the questions.
30 - Vary the data in each question so notebooks are never identical.
31
324. **Build the notebook** using `generate_notebook.py`:
33 - **Option A — from the question bank**: Use `--bank` to pull pre-written questions and randomize:
34 ```bash
35 python scripts/generate_notebook.py \
36 --bank questions/bank.json \
37 --category pandas --difficulty easy --count 5 \
38 --output notebooks/practice
39 ```
40 - **Option B — custom questions**: Generate a JSON array of question objects and pipe to the script:
41 ```bash
42 python scripts/generate_notebook.py \
43 --category pandas --difficulty medium \
44 --output notebooks/practice < /tmp/questions.json
45 ```
46 - Each question object must have `prompt` (str) and `solution` (str). Optional fields:
47 - `hint` (str, will be rendered in a collapsed `<details>` tag). Hints must be hidden by default.
48 - `setup` (str, per-question code cell), `subcategory` (str).
49
505. **Customize the setup cell** — replace the template's sample data with the real market data fetched in step 3. Use the output of `fetch_price_data.py --format code` or `--format returns` as the setup cell content.
51
526. **Confirm** the notebook path to the user when finished.
53
54## Notebook Structure
55
56Each generated notebook must follow this structure:
57
581. **Title cell** (markdown): includes category, difficulty, date, and number of questions.
592. **Setup cell** (code): import statements and sample datasets. For pandas notebooks, embed real market data fetched with `fetch_price_data.py`.
603. **For each question**:
61 - A **markdown cell** with the challenge prompt, numbered (e.g. "### Challenge 1"). Include:
62 - A clear problem statement
63 - Any sample data or expected output
64 - When appropriate include a **hidden hint** wrapped in a `<details><summary>💡 Hint</summary>...</details>` tag (initially collapsed).
65 - An **empty code cell** for the user to write their solution.
66 - A **hidden solution cell** wrapped in a markdown `<details><summary>✅ Solution</summary>...</details>` tag so the user can reveal it.
67
68## Scripts
69
70All scripts live in [scripts/](scripts/) and are run from that directory.
71
72### `generate_notebook.py`
73Builds a `.ipynb` file from a category template + question data. Uses `nbformat`.
74
75```bash
76# From question bank:
77python scripts/generate_notebook.py --bank questions/bank.json \
78 --category pandas --subcategory series --difficulty easy --count 5 --output notebooks/practice
79
80# From a JSON file of custom questions:
81python scripts/generate_notebook.py --questions /tmp/my_questions.json \
82 --category algorithms --difficulty hard --output notebooks/practice
83
84# From stdin:
85cat questions.json | python scripts/generate_notebook.py --category pandas --output notebooks/practice
86```
87
88### `random_tickers.py`
89Pick random ticker symbols to use in questions. Avoids repeating the same tickers.
90
91```bash
92python scripts/random_tickers.py --count 4 # 4 random tickers
93python scripts/random_tickers.py --count 3 --sector tech # from tech sector
94python scripts/random_tickers.py --count 5 --diverse # one per sector
95python scripts/random_tickers.py --list-sectors # show all sectors
96```
97
98**Use this every time** you generate a notebook to ensure fresh ticker sets.
99
100### `fetch_price_data.py`
101Fetch real stock price data from Yahoo Finance via `yfinance`. Embed the output in notebook setup cells so students work with real market data.
102
103```bash
104# Get a code snippet to embed in the notebook
105python scripts/fetch_price_data.py --tickers AAPL MSFT TSLA --period 6mo --format code
106
107# Get daily returns as a code snippet
108python scripts/fetch_price_data.py --tickers AAPL MSFT --period 3mo --format returns
109
110# Random tickers + real data
111python scripts/fetch_price_data.py --random 4 --period 1y --format code
112
113# Save as CSV
114python scripts/fetch_price_data.py --tickers SPY QQQ --start 2023-01-01 --end 2024-01-01 --output prices.csv
115```
116
117### `random_data.py`
118Generate random numbers, date ranges, names, and messy DataFrames for question variety.
119
120```bash
121python scripts/random_data.py --type integers --count 10 --min 1 --max 100
122python scripts/random_data.py --type floats --count 5 --min -0.05 --max 0.05
123python scripts/random_data.py --type date_range --start 2020-01-01 --periods 30 --freq B
124python scripts/random_data.py --type names --count 8
125python scripts/random_data.py --type messy_dataframe --rows 20
126```
127
128Use `--type messy_dataframe` to generate data-cleaning exercises with realistic problems (missing values, inconsistent casing, whitespace, bad types, duplicates).
129
130## Templates
131
132Category-specific notebook templates live in [templates/](templates/). Each template provides:
133- A title cell with `{{difficulty}}`, `{{date}}`, `{{count}}`, `{{subcategories}}` placeholders
134- A setup cell with appropriate imports and sample datasets
135
136| Template | File | Description |
137|----------|------|-------------|
138| Pandas | `templates/pandas_template.ipynb` | Imports pandas, numpy, matplotlib, seaborn. Pre-built sample datasets (stock_returns, messy_data, sectors). |
139| Algorithms | `templates/algorithms_template.ipynb` | Imports collections, heapq, math, typing. Includes a `check()` helper for testing solutions. |
140
141## Question Bank
142
143Pre-written questions are stored in [questions/bank.json](questions/bank.json). The bank is organized as:
144
145```
146{ category: { subcategory: { difficulty: [question, ...] } } }
147```
148
149Each question has: `prompt`, `solution`, and optionally `hint` and `setup`.
150
151## Categories and Subcategories
152
153### Pandas
154
155Refer to [references/PANDAS_NOTE.md](references/PANDAS_NOTE.md) for the topic tree and [references/PANDAS_FOR_DATA_SCIENCE.md](references/PANDAS_FOR_DATA_SCIENCE.md) for functions and techniques. Use [examples/PANDAS_EXAMPLES.md](examples/PANDAS_EXAMPLES.md) for sample data patterns.
156
157Subcategories:
158- **Series**: creation, retrieval, modification, alignment, built-in methods
159- **DataFrames**: retrieval (loc/iloc, slicing, boolean masks), modification, column operations
160- **Data exploration**: apply/applymap, correlations, covariance, DataFrame-Series arithmetic
161- **Missing data**: detection, dropping, filling, interpolation
162- **Reindexing and sorting**: reindex, drop, sort_index, sort_values
163- **Categorical data**: unique values, value_counts, isin, dummy variables
164- **File I/O**: reading/writing CSV, Excel, pickle
165- **Multi-indexing**: multi-index DataFrames and Series, stack/unstack, swaplevel
166- **Time series**: timestamps, offsets, date ranges, resampling, shifting
167- **GroupBy, pivot, merge**: groupby, pivot_table, merge/join, concat
168- **Rolling and quantiles**: rolling windows, qcut, shift for returns
169- **Plotting**: line, bar, scatter, histograms, heatmaps with seaborn
170
171### Algorithms
172
173Focused on vanilla Python (no external libraries).
174
175Subcategories:
176- **Data structures**: lists, dicts, sets, tuples, deques, heaps
177- **Sorting**: bubble, merge, quick, insertion sort implementations
178- **Searching**: linear search, binary search
179- **Recursion**: factorial, fibonacci, tree traversal, divide and conquer
180- **String manipulation**: reversal, palindromes, anagrams, pattern matching
181- **Math and logic**: primes, GCD, modular arithmetic, bit manipulation
182
183## Difficulty Levels
184
185- **Easy**: Single-concept problems. Provide hints and sample data. Expect 1-5 lines of code per solution.
186- **Medium**: Combine 2-3 concepts. Provide sample data but no hints. Expect 5-15 lines of code.
187- **Hard**: Multi-step problems requiring chaining operations or designing algorithms. No hints. Expect 10-30+ lines of code.
188
189## Additional Resources
190
191- For pandas topic details, see [references/PANDAS_NOTE.md](references/PANDAS_NOTE.md)
192- For pandas functions reference, see [references/PANDAS_FOR_DATA_SCIENCE.md](references/PANDAS_FOR_DATA_SCIENCE.md)
193- For numpy context, see [references/NUMPY.md](references/NUMPY.md)
194- For code examples and sample data, see [examples/PANDAS_EXAMPLES.md](examples/PANDAS_EXAMPLES.md)