16 KiB
C Programming Learning Management System
A web-based learning management system for C programming with interactive exercises and code compilation capabilities.
Features
- View lessons written in Markdown format
- Interactive C code editor with compilation and execution
- Real-time feedback on code compilation and execution
- No database required - content stored as Markdown files
- Student token-based progress tracking system
- No authentication required - ready to use out of the box
- Containerized with Podman for easy deployment
Prerequisites
- Podman installed on your system
- Basic knowledge of Docker/Podman commands
Getting Started
Option 1: Using Podman Compose (Recommended)
-
Navigate to the project directory:
cd lms-c -
Build and start the container:
podman-compose -f podman-compose.yml up --build -
Access the application at
http://localhost:5000
Option 2: Using the Access Script
-
Make the access script executable:
chmod +x access_container.sh -
Run the access script:
./access_container.shThis will start the container and open a shell inside it. From there, you can run:
python app.py
Option 3: Direct Podman Commands
-
Build the image:
podman build -t lms-c . -
Run the container:
podman run -p 5000:5000 -v ../content:/app/content -v ./static:/app/static -v ./templates:/app/templates -v ./tokens.csv:/app/tokens.csv lms-c
Content Structure
The system uses Markdown files for content management. There are two main types of content files:
Content Directory Location
The content directory is located at the parent directory level, outside of the elemes/ directory. This allows for easy linking and sharing of content between different instances of the LMS.
Home Page (home.md)
The home page serves as the main landing page and lesson directory. Here's the template structure:
# Welcome to C Programming Learning System
This is a comprehensive learning platform designed to help you master the C programming language through interactive lessons and exercises.
## Learning Objectives
| Module | Objective | Skills Acquired |
|--------|-----------|-----------------|
| Introduction to C | Understand basic syntax and structure | Writing first C program |
| Variables & Data Types | Learn about different data types | Proper variable declaration |
| Control Structures | Master conditional statements and loops | Logic implementation |
| Functions | Create and use functions | Code organization |
| Arrays & Pointers | Work with complex data structures | Memory management |
## How to Use This System
1. **Browse Lessons**: Select from the available lessons on the left
2. **Read Content**: Study the lesson materials and examples
3. **Practice Coding**: Use the integrated code editor to write and test C code
4. **Complete Exercises**: Apply your knowledge to solve programming challenges
5. **Get Feedback**: See immediate results of your code execution
## Getting Started
Start with the "Introduction to C" lesson to begin your journey in C programming. Each lesson builds upon the previous one, so it's recommended to follow them in order.
Happy coding!
---Available_Lessons---
1. [Introduction to C Programming](lesson/introduction_to_c.md)
2. [Variables and Data Types in C](lesson/variables_and_data_types.md)
Key Components of home.md:
- Main title and welcome message
- Learning objectives table
- Usage instructions
- Getting started section
---Available_Lessons---separator followed by a list of lessons in the format[Lesson Title](lesson/filename.md)
Lesson Template
Each lesson file follows a specific structure to enable all system features. Here's the complete template:
---LESSON_INFO---
**Learning Objectives:**
- Understand basic syntax and structure of C programs
- Learn how to write your first C program
- Familiarize with the compilation process
**Prerequisites:**
- Basic understanding of programming concepts
- Familiarity with command line interface (optional)
---END_LESSON_INFO---
# Lesson Title
Lesson content goes here...
## Section
More content...
---
## Common Data Types in C
| Type | Description | Example |
|------|-------------|---------|
| int | Integer values | `int age = 25;` |
| float | Floating-point numbers | `float price = 19.99;` |
| char | Single character | `char grade = 'A';` |
| double | Double precision float | `double pi = 3.14159;` |
---EXERCISE---
# Exercise Title
Exercise instructions go here...
**Requirements:**
- Requirement 1
- Requirement 2
**Expected Output:**
Expected output example
Try writing your solution in the code editor below!
---EXPECTED_OUTPUT---
Expected output text
---END_EXPECTED_OUTPUT---
---INITIAL_CODE---
#include <stdio.h>
int main() {
// Write your code here
printf("Hello, World!\\n");
return 0;
}
---END_INITIAL_CODE---
---SOLUTION_CODE---
#include <stdio.h>
int main() {
// Write your solution here
printf("Solution output\\n");
return 0;
}
---END_SOLUTION_CODE---
Key Components of Lesson Files:
-
Lesson Information Block (Optional):
---LESSON_INFO---and---END_LESSON_INFO---separators- Contains learning objectives and prerequisites
- Appears in a special information card on the lesson page
-
Main Content:
- Standard Markdown content with headers, text, tables, etc.
- Supports all standard Markdown features including code blocks
-
Exercise Block (Optional):
---EXERCISE---separator- Exercise instructions and requirements
- Appears above the code editor
-
Expected Output Block (Optional):
---EXPECTED_OUTPUT---and---END_EXPECTED_OUTPUT---separators- Defines the expected output for the exercise
- When student code produces this output, they get a success message
-
Initial Code Block (Optional):
---INITIAL_CODE---and---END_INITIAL_CODE---separators- Provides starter code for the student
- If not provided, defaults to a basic "Hello, World!" program
-
Solution Code Block (Optional):
---SOLUTION_CODE---and---END_SOLUTION_CODE---separators- Contains the correct solution
- A "Show Solution" button appears when this is provided and the exercise is completed successfully
Adding New Lessons
To add new lessons:
- Create a new Markdown file in the
contentdirectory with a.mdextension - Follow the lesson template structure above
- Use standard Markdown syntax for content formatting
- Add exercises with the
---EXERCISE---separator if needed - Include expected output, initial code, and solution code as appropriate
Complete Lesson Template
Here's a complete template with all optional sections for a new lesson:
---LESSON_INFO---
**Learning Objectives:**
- Understand the purpose of this lesson
- Learn specific concepts or skills
- Apply knowledge to practical examples
**Prerequisites:**
- Knowledge from previous lessons
- Basic understanding of related concepts
---END_LESSON_INFO---
# Lesson Title
Lesson content goes here...
## Section
More content...
---
## Tables and Other Content
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Data 1 | Data 2 | Data 3 |
| Data 4 | Data 5 | Data 6 |
---EXERCISE---
# Exercise Title
Exercise instructions go here...
**Requirements:**
- Requirement 1
- Requirement 2
**Expected Output:**
Expected output example
Try writing your solution in the code editor below!
---EXPECTED_OUTPUT---
Expected output text
---END_EXPECTED_OUTPUT---
---INITIAL_CODE---
#include <stdio.h>
int main() {
// Write your code here
printf("Hello, World!\\n");
return 0;
}
---END_INITIAL_CODE---
---SOLUTION_CODE---
#include <stdio.h>
int main() {
// Write your solution here
printf("Solution output\\n");
return 0;
}
---END_SOLUTION_CODE---
Markdown Features Supported
- Headers:
#,##,### - Code blocks: Use triple backticks (```c for C code highlighting)
- Lists:
-for unordered,1.for ordered - Bold/italic:
**bold**,*italic* - Links:
[text](url) - Tables: Using standard Markdown table syntax
- Images:
 - Blockquotes:
> quoted text
Exercise Guidelines
- Exercises are optional - lessons can exist without them
- When an exercise is provided, it will appear above the code editor
- If no exercise is provided, a message will indicate that users can still practice with the code editor
- The code editor is always available for practice regardless of whether an exercise is defined
- Use
---EXPECTED_OUTPUT---to provide automatic feedback when students complete exercises correctly - Use
---INITIAL_CODE---to provide starter code - Use
---SOLUTION_CODE---to provide a reference solution - Use
---LESSON_INFO---to provide learning objectives and prerequisites in a special information card
Updating the Home Page
After creating new lessons, update the ../content/home.md file to include links to your new lessons in the ---Available_Lessons--- section:
---Available_Lessons---
1. [Lesson Title](lesson/filename.md)
Content Organization
- Store all lesson files in the
../content/directory (at the parent directory level) - Use descriptive filenames with underscores instead of spaces (e.g.,
variables_and_data_types.md) - Keep lesson files focused on a single topic or concept
- Use consistent formatting and structure across all lessons
- Include practical examples and exercises where appropriate
Student Progress Tracking
The system includes a token-based progress tracking system:
- A
tokens.csvfile is automatically generated based on the lessons in the content directory - Teachers manually add student tokens and names to this file
- Students log in using their assigned token
- Progress is automatically tracked when students complete exercises successfully
- The system updates the CSV file with completion status for each lesson
To generate the tokens CSV file:
python generate_tokens.py
The CSV file format is: token;nama_siswa;lesson1;lesson2;...
How to Use
- Access the application at
http://localhost:5000 - Browse available lessons
- Click on a lesson to view content and exercises
- Use the code editor to write C code
- Click "Run Code" to compile and execute your code
- View the output in the output panel
- For student tracking, use the token login field in the top navigation bar
Using as a Submodule
This LMS can be used as a submodule in another repository. To set it up:
-
Add this repository as a submodule to your main project:
git submodule add <repository-url> elemes -
Create a content directory at the root level of your main project:
mkdir content -
Add your lesson files to the content directory
-
Run the LMS from the elemes directory:
cd elemes podman-compose -f podman-compose.yml up --build
The content directory at the root level will be automatically mounted to the application container.
Security Considerations
- The application runs C code in a containerized environment
- Timeouts are implemented to prevent infinite loops
- File system access is limited to the application directory
- Copy-paste functionality is disabled in the code editor to encourage manual coding
Project Structure
app.py: Main Flask application../content/: Directory for lesson Markdown files (at parent directory level)templates/: HTML templatesstatic/: CSS, JavaScript, and other static assetstokens.csv: Student progress tracking filegenerate_tokens.py: Script to generate tokens CSV fileDockerfile: Container configurationpodman-compose.yml: Podman Compose configurationrequirements.txt: Python dependencies
Development
To access the running container for development:
podman exec -it <container_name> /bin/bash
Troubleshooting
- If you get permission errors, make sure your user has access to Podman
- If the application doesn't start, check that port 5000 is available
- If code compilation fails, verify that the gcc compiler is available in the container
- If progress tracking isn't working, ensure the tokens.csv file is properly formatted
Stopping the Application
To stop the application:
If running with Podman Compose:
# Stop the containers
podman-compose -f podman-compose.yml down
# Or if you want to stop and remove containers, networks, and volumes:
podman-compose -f podman-compose.yml down -v
If running with direct Podman command:
# Find the container name or ID
podman ps
# Stop the container (replace <container_name> with actual name)
podman stop lms-c-container
# Remove the container after stopping (optional but recommended)
podman rm lms-c-container
# Or do both in one command:
podman stop lms-c-container && podman rm lms-c-container
Using the access script:
If you're currently in the container shell opened via access_container.sh, you can:
- Exit the container shell (type
exit) - Then stop the container from outside:
podman stop lms-c-container
Troubleshooting: Port Already in Use
If you get an error about the port already being in use, it means the container wasn't properly stopped. First, check what's using the port:
podman ps
If you see the lms-c-container still running, stop it:
podman stop lms-c-container && podman rm lms-c-container
Or stop all running containers:
podman stop $(podman ps -q)
Then you can run the application again on the desired port.
API Endpoints
GET /- Main page with all lessonsGET /lesson/<filename>- View a specific lessonPOST /compile- Compile and run C code (expects JSON with "code" field)POST /login- Validate student tokenPOST /validate-token- Check if token is validPOST /track-progress- Update student progressGET /static/<path>- Serve static files
Example API Usage
To compile and run C code via the API:
curl -X POST http://localhost:5000/compile \
-H "Content-Type: application/json" \
-d '{"code": "#include <stdio.h>\\n\\nint main() {\\n printf(\\"Hello, World!\\\\n\\");\\n return 0;\\n}"}'
Response:
{
"success": true,
"output": "Hello, World!\n",
"error": null
}
In case of compilation errors:
{
"success": false,
"output": "error message...",
"error": "Compilation failed"
}
Load Testing with Locust
The system includes support for load testing using Locust to simulate multiple concurrent users accessing the LMS.
Prerequisites for Load Testing
- Docker/Podman installed on the load testing machine
- Network access to the LMS server
Running Load Tests
-
Prepare the LMS Server
- Deploy the LMS container on the target server
- Note the server IP address and port (default: http://<LMS_SERVER_IP>:5000)
-
Configure Locust
- Update the
podman-compose.locust.ymlfile with the correct LMS server IP address:command: ["locust", "-f", "locustfile.py", "--host", "http://<LMS_SERVER_IP>:5000"]
- Update the
-
Run Locust Load Test
- On the load testing machine, navigate to the project directory
- Build and start the Locust container:
podman-compose -f test/podman-compose.locust.yml up --build - Access the Locust web interface at
http://localhost:8089 - Configure the number of users, spawn rate, and other parameters
- Start the load test
-
Alternative: Run Locust Directly
- Install Locust on the load testing machine:
pip install -r locust/requirements.txt - Run Locust directly:
cd locust locust -f locustfile.py --host http://<LMS_SERVER_IP>:5000
- Install Locust on the load testing machine:
Locust Test Scenarios
The included locustfile.py simulates the following user behaviors:
- Browsing the home page
- Viewing lessons
- Compiling C code
- Validating student tokens
- Logging in with tokens
- Tracking student progress
Monitoring Performance
Monitor the LMS server's resource usage (CPU, memory, disk I/O) during load testing to identify potential bottlenecks. Pay attention to:
- Response times for API requests
- Compilation performance under load
- Database performance (if one is added in the future)
- Container resource limits