Interactive Python learning desktop app with PDF book reader and code editor
Project description
PyLearn
An interactive desktop app for learning programming from PDF books. Split-pane interface with a book reader on the left and a code editor + console on the right — read the book, write code, and run it all in one place.
Screenshots
Light mode — reading with Book menu open:
Dark mode — reading with code execution:
Sepia mode — reading view:
Sepia mode — running code (Zen of Python):
Features
- PDF Book Reader — Parses PDF books into structured, styled HTML with headings, body text, and syntax-highlighted code blocks
- Code Editor — QScintilla-powered editor with syntax highlighting, line numbers, auto-indent, and configurable font/tab settings
- Code Execution — Run Python code directly from the editor with output displayed in an integrated console (30s timeout, sandboxed subprocess)
- Table of Contents — Auto-generated chapter navigation from PDF structure
- Progress Tracking — SQLite database tracks chapter completion status, bookmarks, and notes per book
- Bookmarks & Notes — Save bookmarks and attach notes to any page
- Multiple Book Profiles — Supports Python, C++, and HTML/CSS books with per-book font classification profiles
- Themes — Light, dark, and sepia themes for the reader panel
- External Editor — Launch code in Notepad++ or your preferred external editor
- Parsed Content Caching — PDF parsing results cached as JSON for fast subsequent loads
Requirements
- Python 3.12 or newer
- Windows, macOS, or Linux
Platform Notes
| Platform | Notes |
|---|---|
| Windows | Works out of the box with Python 3.12+ |
| Linux | Install system deps first: sudo apt-get install libegl1 libxkbcommon0 |
| macOS | May need Xcode command line tools: xcode-select --install |
Installation
Pick one of the methods below.
Option A: Install from PyPI (simplest)
pip install pylearn-reader
Option B: Install from GitHub (latest code)
pip install git+https://github.com/fritz99-lang/pylearn.git
Option C: Clone the repo (for development)
git clone https://github.com/fritz99-lang/pylearn.git
cd pylearn
# Create a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows
pip install -e . # editable install
pip install -e ".[dev]" # or include pytest + mypy
Registering a Book
PyLearn reads PDF books, but it needs to know where your PDFs are. You do this by editing a single config file called books.json.
Step 1 — Find your config directory
Where books.json lives depends on how you installed:
| Install method | Config location |
|---|---|
| Git clone (Option C) | config/ folder inside the repo — configs are created automatically from the .json.example files on first launch |
| pip install (Option A or B) | A config/ folder inside your system's app-data directory (see table below) |
App-data directory by platform (pip installs only):
| Platform | Path |
|---|---|
| Windows | %LOCALAPPDATA%\pylearn\config\ (typically C:\Users\<you>\AppData\Local\pylearn\config\) |
| macOS | ~/Library/Application Support/pylearn/config/ |
| Linux | ~/.local/share/pylearn/config/ |
Tip: Launch the app once (
python -m pylearn) and it will create the config directory for you. Then you just need to add yourbooks.jsonfile inside it.
Step 2 — Create (or edit) books.json
If the file doesn't exist yet, create it. Add one entry per book:
{
"books": [
{
"book_id": "learning_python",
"title": "Learning Python, 5th Edition",
"pdf_path": "C:/Users/you/Documents/Learning_Python.pdf",
"language": "python",
"profile_name": "learning_python"
}
]
}
Field reference:
| Field | Required | Description |
|---|---|---|
book_id |
Yes | A short unique ID you make up — no spaces, lowercase with underscores (e.g. "my_python_book") |
title |
Yes | Display name shown in the app |
pdf_path |
Yes | Absolute path to the PDF file on your computer. Use forward slashes even on Windows (C:/Users/...) |
language |
No | "python" (default), "cpp", or "html" — controls syntax highlighting in the editor |
profile_name |
No | A named parsing profile that fine-tunes how PDF fonts are classified. Leave it as "" (empty string) for auto-detection, which works well for most books |
Available named profiles (only needed if auto-detection doesn't work well for your book):
profile_name |
Best for |
|---|---|
learning_python |
Learning Python by Mark Lutz |
python_cookbook |
Python Cookbook by Beazley & Jones |
programming_python |
Programming Python by Mark Lutz |
cpp_generic |
General C++ textbooks |
cpp_primer |
C++ Primer by Lippman et al. |
effective_cpp |
Effective C++ by Scott Meyers |
| (empty string) | Auto-detect from the PDF — try this first |
Step 3 — Launch and parse
python -m pylearn
On first launch for each book, the app will ask if you want to parse the PDF. Click Yes — this takes a minute or two depending on the book size. After parsing, the book content is cached so subsequent launches are instant.
Usage
| Area | What it does |
|---|---|
| Left panel | Book reader — navigate chapters via the table of contents sidebar |
| Right panel (top) | Code editor — write or paste code from the book |
| Right panel (bottom) | Console — see output from running your code |
| Toolbar | Theme switching, bookmarks, notes, progress tracking |
Keyboard Shortcuts
| Category | Shortcut | Action |
|---|---|---|
| Navigation | Alt+Left / Alt+Right |
Previous / next chapter |
Ctrl+M |
Mark chapter complete | |
Ctrl+T |
Toggle TOC panel | |
| Search | Ctrl+F |
Find in current chapter |
Ctrl+Shift+F |
Search all books | |
| Code | F5 |
Run code |
Shift+F5 |
Stop execution | |
Ctrl+S |
Save code to file | |
Ctrl+O |
Load code from file | |
Ctrl+E |
Open in external editor | |
| View | Ctrl+= / Ctrl+- |
Increase / decrease font size |
Ctrl+1 / 2 / 3 |
Focus TOC / reader / editor | |
| Notes | Ctrl+B |
Add bookmark |
Ctrl+N |
Add note | |
| Help | Ctrl+/ |
Show shortcuts dialog |
Configuration
Config files are JSON. For git-clone installs they live in config/ inside the repo. For pip installs they live in your app-data directory (see Registering a Book for the exact path).
app_config.json— Window size, theme, splitter positions, last opened bookbooks.json— Registered books with PDF paths and profile nameseditor_config.json— Editor font size, tab width, line numbers, execution timeout
Development
# Run all tests (702 tests)
pytest tests/ -v
# Skip slow tests
pytest tests/ -v -m "not slow"
# Type checking
mypy src/pylearn/
# Pre-parse books to cache
python scripts/parse_books.py
# Analyze PDF font metadata (useful for creating new book profiles)
python scripts/analyze_pdf_fonts.py path/to/book.pdf
Project Structure
src/pylearn/
parser/ PDF parsing, font analysis, content classification, caching
renderer/ HTML rendering, syntax highlighting, themes
executor/ Subprocess-based code execution with sandboxing
ui/ PyQt6 widgets (main window, reader, editor, console, dialogs)
core/ Config, database, models, constants
utils/ Text utilities, error handling
config/ User-specific JSON config (not committed; see *.json.example)
data/ SQLite database + parsed PDF cache (not committed)
tests/ 702 tests (500+ unit + 150+ integration)
scripts/ Utility scripts for PDF analysis and book parsing
Troubleshooting
App won't start
- Make sure PyQt6 is installed:
pip install PyQt6 PyQt6-QScintilla - Verify Python 3.12+:
python --version - On Linux, install system deps:
sudo apt-get install libegl1 libxkbcommon0
"No books registered" or no books appear
- Make sure
books.jsonexists in the correct config directory (see Registering a Book above) - Open the file and check for JSON syntax errors (missing commas, unclosed braces)
- Make sure each entry has at least
book_id,title, andpdf_path
"PDF not found" error during parsing
- The
pdf_pathinbooks.jsonmust be an absolute path — relative paths won't work - Use forward slashes, even on Windows:
"C:/Users/you/Documents/book.pdf" - Double-check the file actually exists at that path
Book not parsing correctly
- Try auto-detection first: set
"profile_name": ""in your book entry - Use Book > Re-parse (clear cache) from the menu bar to force a fresh parse
- If auto-detection gives poor results, try a named profile (see the profile table above)
- For dev installs: run
python scripts/analyze_pdf_fonts.py path/to/book.pdfto inspect font metadata
Code execution timeout
- Default timeout is 30 seconds
- Increase it in
editor_config.jsonby setting"execution_timeout"to a higher value (in seconds)
Acknowledgments
Built in partnership with Claude Code (Anthropic) — architecture, implementation, testing, and code review.
License
MIT - Copyright (c) 2026 Nathan Tritle
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pylearn_reader-1.0.1.tar.gz.
File metadata
- Download URL: pylearn_reader-1.0.1.tar.gz
- Upload date:
- Size: 77.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bafce2fdc6f82782e17e2c1b7a4a35f776aa6f4964f4538ef2207fc90b98812
|
|
| MD5 |
315943307ffc56522df2d1a341ca63c3
|
|
| BLAKE2b-256 |
f993c433bbca5061a9ff7c635003a7ce29ee465357209651e4dc22a6a9bfab0b
|
File details
Details for the file pylearn_reader-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pylearn_reader-1.0.1-py3-none-any.whl
- Upload date:
- Size: 91.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f802c6631bbcc4ab84e77af10077302036b4379fbea1676a945399fec9bf399
|
|
| MD5 |
d784986d001fa06d064d05235f59766f
|
|
| BLAKE2b-256 |
5c8018202c7d28fb9e7f7884ebc811464311dd938c5605c1b28bdf71a30fd8f0
|