Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ A step-by-step guide for integrating the dataset into your own application:
exercises-dataset/
├── data/
│ └── exercises.json # Full dataset — 1,324 exercise records (JSON array)
├── examples/ # Small Node, Python, and SQLite integration examples
├── images/ # 1,324 × 180×180 thumbnails (© Gym visual)
├── videos/ # 1,324 × 180×180 animation GIFs (© Gym visual)
├── index.html # Interactive exercise browser (client-side, no server needed)
Expand All @@ -117,6 +118,7 @@ exercises-dataset/
### Key Files

- **`data/exercises.json`** — The primary data file. A JSON array of 1,324 exercise objects with all metadata. `image` / `gif_url` point to the local 180×180 assets, and each record carries an `attribution` field; `media_id` holds the original media reference id.
- **`examples/`** — Small integration examples for loading the dataset from Node.js, Python, and SQLite.
- **`images/`, `videos/`** — 180×180 thumbnails and animation GIFs (© [Gym visual](https://gymvisual.com/), used with permission).
- **`index.html`** — Standalone exercise browser. Open directly in any modern browser.
- **`setup.html`** — Developer guide for DB setup, API integration, and LLM-assisted backend generation.
Expand Down
27 changes: 27 additions & 0 deletions examples/node-load-dataset.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const dataPath = path.resolve(__dirname, '..', 'data', 'exercises.json');

const exercises = JSON.parse(fs.readFileSync(dataPath, 'utf8'));

const byBodyPart = exercises.reduce((counts, exercise) => {
counts[exercise.body_part] = (counts[exercise.body_part] ?? 0) + 1;
return counts;
}, {});

const bodyweight = exercises.filter((exercise) => exercise.equipment === 'body weight');

console.log(`Total exercises: ${exercises.length}`);
console.log(`Bodyweight exercises: ${bodyweight.length}`);
console.log('Exercises by body part:');

for (const [bodyPart, count] of Object.entries(byBodyPart).sort((a, b) => b[1] - a[1])) {
console.log(`- ${bodyPart}: ${count}`);
}

console.log('\nFirst exercise media attribution:');
console.log(exercises[0].attribution);
27 changes: 27 additions & 0 deletions examples/python-load-dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import json
from collections import Counter
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
DATA_PATH = ROOT / "data" / "exercises.json"


with DATA_PATH.open(encoding="utf-8") as file:
exercises = json.load(file)

by_body_part = Counter(exercise["body_part"] for exercise in exercises)
bodyweight = [
exercise for exercise in exercises
if exercise["equipment"] == "body weight"
]

print(f"Total exercises: {len(exercises)}")
print(f"Bodyweight exercises: {len(bodyweight)}")
print("Exercises by body part:")

for body_part, count in by_body_part.most_common():
print(f"- {body_part}: {count}")

print("\nFirst exercise media attribution:")
print(exercises[0]["attribution"])
51 changes: 51 additions & 0 deletions examples/sqlite-import.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SQLite import example

The dataset can be imported into SQLite by storing multilingual instructions and secondary muscles as JSON text columns.

## Minimal table

```sql
CREATE TABLE exercises (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
category TEXT,
body_part TEXT,
equipment TEXT,
instructions TEXT,
instruction_steps TEXT,
muscle_group TEXT,
secondary_muscles TEXT,
target TEXT,
image TEXT,
gif_url TEXT,
media_id TEXT,
created_at TEXT,
attribution TEXT
);
```

## Generate INSERT statements

Open `setup.html`, choose the SQLite tab, and click "Generate INSERT SQL". The generated file contains all 1,324 records and can be imported with:

```bash
sqlite3 exercises.db < exercises_insert_sqlite.sql
```

## Query examples

```sql
SELECT COUNT(*) FROM exercises;

SELECT name, target, equipment
FROM exercises
WHERE equipment = 'body weight'
ORDER BY name
LIMIT 20;

SELECT name, json_extract(instructions, '$.en') AS english_instructions
FROM exercises
WHERE id = '0001';
```

The media paths in `image` and `gif_url` point to files in this repository. Keep the `attribution` value with any exported records that include media references.