Skip to content
Open
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
45 changes: 45 additions & 0 deletions codegym/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/
*.egg-info/
dist/
build/

# Database
*.db
*.sqlite3

# Environment
.env
.env.local

# Node
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Build outputs
dist/
build/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Logs
logs/
*.log
262 changes: 262 additions & 0 deletions codegym/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# CodeGym

**Master Python, One Rep at a Time**

CodeGym is an interactive training platform that breaks down Python standard library functions into atomic, digestible exercises. Like a gym for your coding skills, you'll practice specific patterns through hands-on, incremental learning.

## Concept

Instead of jumping straight into LeetCode-style algorithmic problems, CodeGym helps you build a solid foundation by:

- **Breaking down stdlib functions** like `len()`, `sum()`, `map()`, `filter()` into step-by-step explanations
- **Interactive exercises** that let you practice each concept through multiple formats
- **Atomic learning** - master the building blocks before tackling complex algorithms
- **Spaced repetition** - track your progress and revisit concepts that need more practice

## Features

### Learning Modes

1. **Theory Section**
- What the function does
- Why it's useful
- Time/space complexity
- Important notes and gotchas

2. **Breakdown Section**
- Step-by-step internal implementation
- Visual code flow with explanations
- Understanding how it works under the hood

3. **Exercise Section**
- Fill in the blank
- Match output to code
- Multiple choice questions
- Order the steps correctly
- Code completion challenges

### Current Lessons

- `len()` - Count items in containers
- `sum()` - Add up numbers in iterables
- `max()` - Find the largest value
- `min()` - Find the smallest value
- `range()` - Generate number sequences

More coming soon!

## Tech Stack

### Backend
- **FastAPI** - Modern Python web framework
- **SQLAlchemy** - ORM for database operations
- **SQLite** - Lightweight database
- **Pydantic** - Data validation

### Frontend
- **React** - UI library
- **Vite** - Fast build tool
- **Tailwind CSS** - Utility-first styling
- **Monaco Editor** - VS Code's editor component
- **Axios** - HTTP client
- **Lucide React** - Icon library

## Getting Started

### Prerequisites

- Python 3.8+
- Node.js 18+
- npm or yarn

### Installation

1. **Clone the repository**
```bash
cd codegym
```

2. **Set up the backend**
```bash
cd backend

# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Copy environment file
cp .env.example .env
```

3. **Set up the frontend**
```bash
cd ../frontend

# Install dependencies
npm install

# Create .env file
echo "VITE_API_URL=http://localhost:8000/api" > .env
```

### Running the Application

1. **Start the backend server**
```bash
cd backend
source venv/bin/activate # If not already activated
python run.py
```

Backend will run on `http://localhost:8000`
API docs available at `http://localhost:8000/docs`

2. **Start the frontend development server** (in a new terminal)
```bash
cd frontend
npm run dev
```

Frontend will run on `http://localhost:5173`

3. **Open your browser** and navigate to `http://localhost:5173`

## Project Structure

```
codegym/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI application
│ │ ├── models/ # Pydantic models
│ │ │ └── exercise.py
│ │ ├── routes/ # API endpoints
│ │ │ ├── exercises.py
│ │ │ └── progress.py
│ │ └── database/ # Database setup
│ │ └── database.py
│ ├── data/
│ │ └── initial_lessons.py # Seed data for lessons
│ ├── requirements.txt
│ └── run.py # Development server
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── LessonList.jsx
│ │ │ ├── LessonView.jsx
│ │ │ ├── TheorySection.jsx
│ │ │ ├── BreakdownSection.jsx
│ │ │ ├── ExerciseSection.jsx
│ │ │ └── exercises/ # Exercise type components
│ │ │ ├── FillBlankExercise.jsx
│ │ │ ├── MatchOutputExercise.jsx
│ │ │ ├── MultipleChoiceExercise.jsx
│ │ │ ├── OrderStepsExercise.jsx
│ │ │ └── CodeCompletionExercise.jsx
│ │ ├── services/
│ │ │ └── api.js # API client
│ │ ├── App.jsx
│ │ └── main.jsx
│ ├── package.json
│ └── vite.config.js
└── README.md
```

## API Endpoints

### Exercises
- `GET /api/exercises/` - Get all lessons
- `GET /api/exercises/{lesson_id}` - Get specific lesson
- `GET /api/exercises/category/{category}` - Get lessons by category

### Progress (Coming Soon)
- `GET /api/progress/{user_id}` - Get user progress
- `POST /api/progress/{user_id}/{lesson_id}` - Update progress
- `GET /api/progress/{user_id}/stats` - Get user statistics

## Adding New Lessons

To add a new Python stdlib function lesson:

1. Open `backend/data/initial_lessons.py`
2. Add a new lesson object following this structure:

```python
{
"id": "builtin_function_name",
"function_name": "function()",
"category": "Built-in Functions - Category",
"difficulty": 1, # 1=Beginner, 2=Intermediate, 3=Advanced
"theory": {
"what": "What it does",
"why": "Why it's useful",
"time_complexity": "O(?)",
"space_complexity": "O(?)",
"notes": "Additional notes"
},
"breakdown": [
{
"step": 1,
"code": "code_snippet",
"explanation": "Explanation"
}
],
"exercises": [
{
"type": "fill_blank",
"question": "Question text",
"template": "code with ___",
"answer": "correct_answer",
"explanation": "Why this is the answer"
}
],
"examples": [
"example1",
"example2"
]
}
```

3. Restart the backend server - database will auto-seed with new lesson

## Roadmap

- [ ] User authentication and accounts
- [ ] Spaced repetition algorithm
- [ ] Achievement badges and gamification
- [ ] More stdlib functions (itertools, functools, collections)
- [ ] Advanced topics (decorators, generators, context managers)
- [ ] Code execution sandbox for testing
- [ ] Community-contributed lessons
- [ ] Mobile app

## Contributing

Contributions are welcome! Whether it's:
- Adding new lessons
- Improving exercises
- Fixing bugs
- Enhancing UI/UX
- Writing documentation

Feel free to open issues or submit pull requests.

## License

MIT License - Feel free to use this for learning and teaching!

## Acknowledgments

Built with inspiration from:
- Duolingo's bite-sized learning approach
- LeetCode's problem-solving platform
- The Python community's excellent documentation

---

**Start your training today and master Python fundamentals the right way!**
3 changes: 3 additions & 0 deletions codegym/backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DATABASE_URL=sqlite:///./codegym.db
API_HOST=0.0.0.0
API_PORT=8000
Empty file added codegym/backend/app/__init__.py
Empty file.
Empty file.
58 changes: 58 additions & 0 deletions codegym/backend/app/database/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from sqlalchemy import create_engine, Column, String, Integer, Float, JSON, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import os

# Database URL
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./codegym.db")

# Create engine
engine = create_engine(
DATABASE_URL,
connect_args={"check_same_thread": False} if "sqlite" in DATABASE_URL else {}
)

# Session factory
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Base class for models
Base = declarative_base()

# Database models
class LessonDB(Base):
__tablename__ = "lessons"

id = Column(String, primary_key=True, index=True)
function_name = Column(String, index=True)
category = Column(String, index=True)
difficulty = Column(Integer)
theory = Column(JSON)
breakdown = Column(JSON)
exercises = Column(JSON)
examples = Column(JSON)
created_at = Column(DateTime, default=datetime.utcnow)

class UserProgressDB(Base):
__tablename__ = "user_progress"

id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String, index=True, default="anonymous")
lesson_id = Column(String, index=True)
completed_exercises = Column(JSON)
score = Column(Float, default=0.0)
last_attempt = Column(DateTime, default=datetime.utcnow)

# Database initialization
def init_db():
"""Initialize database and create tables"""
Base.metadata.create_all(bind=engine)
print("Database initialized successfully")

# Dependency to get DB session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Loading