Programming Exam Creation
Relevant source files
The following files were used as context for generating this wiki page:The Programming Exam Creation feature allows educators to design and build comprehensive, project-based coding assessments. The system supports both manual creation, where instructors define every component of the exam, and an automated, AI-driven approach that generates entire exam structures from a simple topic prompt. This includes defining tasks, providing starter code, and setting up automated test cases for evaluation.
This feature is central to the platform's ability to offer practical coding challenges. It integrates with the ProgrammingExamService for data management and the OpenAIService for intelligent content generation, storing the final structure in the database as defined by the ProgrammingExamModels.
Data Models and Schema
The foundation of a programming exam is a set of related data models that define its structure, content, and associated student attempts. These entities are defined in the database context and are linked through foreign key relationships.
Sources: Models/ProgrammingExamModels.cs, Data/ApplicationDbContext.cs:222-353
Entity Relationship Diagram
This diagram shows the core entities involved in a programming exam and their relationships.
Core Entities
ProgrammingExam
This is the top-level entity representing the entire exam. It contains metadata like the title, duration, programming language, and links to its constituent parts.
| Property | Type | Description |
|---|---|---|
Id | int | Primary key. |
Title | string | The title of the exam. |
Description | string? | A detailed description of the exam project. |
CourseId | int | Foreign key to the Course entity. |
Language | ProgrammingLanguage | Enum for the language (e.g., Java, Python, C#). |
ProjectName | string | The name of the project, used in the IDE. |
TotalPoints | decimal | The total possible points for the exam. |
DurationMinutes | int | The time limit for the exam in minutes. |
Tasks | ICollection<ProgrammingTask> | A collection of tasks within the exam. |
StarterFiles | ICollection<ProjectFile> | A collection of starter files for the project. |
ExamCodes | ICollection<ProgrammingExamCode> | Access codes generated for this exam. |
Sources: Models/ProgrammingExamModels.cs:7-80
ProgrammingTask
A task represents a specific problem or feature for the student to implement.
| Property | Type | Description |
|---|---|---|
Id | int | Primary key. |
ProgrammingExamId | int | Foreign key to the ProgrammingExam. |
Title | string | The title of the task. |
Instructions | string | Detailed instructions for completing the task. |
Points | decimal | Points awarded for this task. |
TargetFiles | string? | Comma-separated list of files relevant to this task. |
TestCases | ICollection<TestCase> | Automated test cases to validate the task's solution. |
Sources: Models/ProgrammingExamModels.cs:100-128
TestCase
A test case is used for automated evaluation of a ProgrammingTask.
| Property | Type | Description |
|---|---|---|
Id | int | Primary key. |
ProgrammingTaskId | int | Foreign key to the ProgrammingTask. |
Name | string | A descriptive name for the test. |
Input | string? | Input to be provided to the student's code (e.g., via stdin). |
ExpectedOutput | string? | The expected output from the student's code. |
IsHidden | bool | If true, the test case is not visible to the student. |
Points | decimal | Points awarded if this test case passes. |
TimeoutSeconds | int | Maximum execution time before the test fails. |
Sources: Models/ProgrammingExamModels.cs:133-162
ProjectFile
Represents a starter file (source code, data file, etc.) provided to the student at the beginning of the exam.
| Property | Type | Description |
|---|---|---|
Id | int | Primary key. |
ProgrammingExamId | int | Foreign key to the ProgrammingExam. |
FilePath | string | Full path of the file within the project structure (e.g., src/Main.java). |
Content | string | The initial content of the file. |
IsReadOnly | bool | If true, the student cannot edit this file in the IDE. |
IsEntryPoint | bool | If true, this is the main file to be run/compiled. |
Sources: Models/ProgrammingExamModels.cs:167-198
Manual Exam Creation
Instructors can create programming exams manually through the web interface. The backend logic for this is handled by the ProgrammingExamService, which provides a set of CRUD (Create, Read,Update, Delete) operations for each of the core entities.
Sources: Services/ProgrammingExamService.cs
Creation Flow
The process involves creating the main exam object first, followed by adding its associated tasks, files, and test cases.
Key Service Methods
The IProgrammingExamService interface defines the contract for managing exam components.
| Method | Description |
|---|---|
CreateProgrammingExamAsync(ProgrammingExam exam) | Creates a new ProgrammingExam record in the database. |
CreateTaskAsync(ProgrammingTask task) | Adds a new ProgrammingTask to an existing exam. |
CreateTestCaseAsync(TestCase testCase) | Adds a new TestCase to an existing task. |
CreateProjectFileAsync(ProjectFile file) | Adds a new ProjectFile (starter file) to an exam. |
UpdateProgrammingExamAsync(ProgrammingExam exam) | Updates an existing exam's properties. |
DeleteProgrammingExamAsync(int examId) | Marks an exam as inactive (soft delete). |
Sources: Services/ProgrammingExamService.cs:11-30
AI-Powered Exam Generation
The system leverages the OpenAIService to automatically generate a complete programming exam from a high-level topic, language, task count, and difficulty. This significantly speeds up the creation process.
Sources: Services/OpenAIService.cs:282-436
Generation Process
The GenerateProgrammingTasksAsync method orchestrates the interaction with the OpenAI API. It constructs a detailed system prompt that instructs the AI to return a response in a specific JSON format.
Sources: Services/OpenAIService.cs:282-369
AI Prompt and Schema
The service uses a carefully crafted system prompt to guide the AI. The prompt specifies the expected output schema to ensure a predictable and parsable response.
The AI is expected to return JSON matching the GeneratedProgrammingExam class structure.
// DTO for AI-generated exam data
public class GeneratedProgrammingExam
{
public string ProjectName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public List<GeneratedProjectFile> StarterFiles { get; set; } = new();
public List<GeneratedTask> Tasks { get; set; } = new();
}
// Example of the system prompt structure
/*
You are an expert programming exam designer.
Language: {languageName}
Topic: {topic}
...
CRITICAL: Return ONLY valid JSON. No markdown...
Schema:
{{
"projectName": "PascalCaseNoSpaces",
"description": "exam overview",
"starterFiles": [ ... ],
"tasks": [ ... ]
}}
*/
Sources: Services/OpenAIService.cs:61-71, 298-347
After the AI returns the data, the ProgrammingExamService can be used to persist these generated entities (ProgrammingExam, ProgrammingTask, etc.) into the database.
Exam Authorization and Start Flow
Once an exam is created, students can access it using a generated ProgrammingExamCode. The ExamAppController and ExamAppService handle the authorization flow for the secure desktop client.
This diagram illustrates the sequence for a student starting a programming exam.