Structured, schema-validated representation of the undergraduate curriculum of the
Department of Informatics and Telecommunications, National and Kapodistrian
University of Athens (EKPA). The source is the official study guide
(ODIGOS_SPOYDWN_DIT_EKPA_2025-26.pdf); this repo turns it into machine-readable
data so it can be consumed by tools, drive UIs, and be reviewed change-by-change
through Git.
schema/ JSON Schema (Draft 2020-12), one per entity type
course.schema.json
program.schema.json
specialization.schema.json
data/ Source of truth — hand-editable JSON
program.json Academic year, institution, directions, graduation rules
specializations/S1..S6.json
courses/<CODE>.json One file per course → clean, line-level diffs
scripts/
validate.py Schema validation + cross-file referential integrity
build.py Bundle data/ → dist/curriculum.json
dist/
curriculum.json Generated single-file bundle for consumers
site/ Static dashboard (Curriculum Atlas) — reads the bundle
index.html styles.css app.js
.github/workflows/
validate.yml CI: validate on every push / PR
deploy-site.yml Build + deploy the dashboard to GitHub Pages
site/ is a dependency-free static dashboard that visualises the whole
curriculum from dist/curriculum.json: headline figures (courses, ECTS on offer,
offered-this-year, prerequisite links, instructors), charts (category mix, course
load per semester, specialization depth, teaching-hours mix), an interactive
prerequisite-flow graph (courses laid out by semester; solid links = required,
dashed = recommended; hover to trace a chain), and a searchable/filterable course
explorer with a detail drawer. Bilingual (EL/EN) toggle.
Deploy: the deploy-site.yml workflow validates the data, rebuilds the bundle,
and publishes to GitHub Pages on every push to main. One-time setup: repo
Settings → Pages → Build and deployment → Source: GitHub Actions.
Preview locally: serve the repo root and open the site —
python -m http.server 8000 # then visit http://localhost:8000/site/(The page loads ./curriculum.json when deployed, falling back to
../dist/curriculum.json for local preview, so no copy step is needed.)
# one-time
python -m venv venv && ./venv/bin/pip install jsonschema
./venv/bin/python scripts/validate.py # check schemas + integrity (exits non-zero on errors)
./venv/bin/python scripts/build.py # regenerate dist/curriculum.json- program — academic year, institution, department, degree title, the two
directions (
CS,CET), and graduation rules. - specializations —
S1–S6, each belonging to one direction (S1–S3 → CS, S4–S6 → CET). - course —
code, bilingualtitle,category, weeklyhours(theory/tutorial/lab),ects,semester,direction,prerequisites(required vs recommended),specialization_roles(mandatoryΥ/ basicΒper specialization),offered_this_year,instructors.
Course code is the natural key; prerequisites and specialization roles reference
it. validate.py enforces uniqueness and referential integrity beyond what JSON
Schema alone can express.
All courses were extracted from the PDF with scripts/extract.py (uses
pdfplumber for positional table parsing). Re-run it any time the guide changes:
./venv/bin/pip install pdfplumber # one-time, in addition to jsonschema
./venv/bin/python scripts/extract.py --dry-run # parse & print a summary, write nothing
./venv/bin/python scripts/extract.py # (re)write data/courses/*.jsonIt parses the course tables (pp. 76–83), the per-semester instructor schedule
(winter pp. 88–89, spring pp. 91–93), and the free-elective lists (pp. 90 & 94),
and adds thesis/internship from the prose. Specialization S1–S6 markers are read
by x-position; codes are canonicalised to Greek; (ΔΠ) titles are flagged
offered_this_year: false. Prerequisite type is read from character font/colour
— bold-black → required (focused cycle), italic-blue → recommended (basic cycle),
per the guide's own legend (p. 76).
All 138 courses are extracted and validated (0 errors): 18 compulsory, 3 standalone labs, 11 direction electives, 4 projects, 3 general-education, 62 optional, 33 free electives, 2 thesis, 2 internship.
Prerequisite type is auto-detected from the PDF's bold-black / italic-blue formatting (48 required, 33 recommended).
- Instructors are filled where the schedule could be parsed (~86 courses); a few first-year/wrapped entries may be missing or partial.
- Codes for thesis/internship (
ΠΕ1,ΠΕ2,ΠΑ1,ΠΑ2) are assigned by this dataset — the guide describes them in prose without codes. - Full per-course descriptions (content, learning outcomes, assessment,
bibliography) are not in this PDF; the guide hyperlinks them externally.
Capture later via
description_urlif needed.