-
Notifications
You must be signed in to change notification settings - Fork 7
How to add a new subproblem for a task
First, it is necessary to understand the INGInious packages which form the application itself, and then proceed to modify the required ones.
“INGInious is made from three different packages:
- The common which contains basic blocks like tasks and courses. Derivates from this blocks are created by the frontend and other modules. The common does not need the backend nor the frontend;
- The agent: that runs jobs. It interacts directly with Docker to start new containers, and send the grades back to the backend. A specific part of the backend is in charge of starting the agents automatically; you most of time won’t need to it manually. The agent needs to be run on the Docker host, as it interacts with other containers with Unix sockets, and must also interact with CGroups to allow a very fine management of timeouts and memory limits.
- The backend: which is in charge of handling grading requests, giving the work to distant agents; the backend is made to be simple and frontend-agnostic; you can ‘easily’ replace the frontend by something else. The backend only store information about running tasks. This point is important when considering replication and horizontal scalability (see later)
- The frontend which is a web interface for the backend. It provides a simple yet powerful interface for students and teachers. It is made to be “stateless”: all its state is stored in DB, allowing to replicate the frontend horizontally.”
Additionally, to add some new subproblem it is required to modify two packages, the common and the frontend packages. Also, depending on what you need it is necessary to modify both parts, task editing (related to admin users) and task submission (related to students).
In the common package (inginious.common) is located all the classes for control the tasks and courses (inginious.common.tasks_problems.py):
- courses.py: Which contains the Course class to handle the course objects.
- course_factory.py: Which is used to create all the courses that are stored in the disk.
- tasks.py: Which contains the Task class to handle the tasks of every course.
- task_factory: Which creates tasks from the disk and associate them to a course.
- tasks_problems: Which contains the classes for every kind of subproblem that is possible to add in a specific task.
The last file, tasks_problems, is the main file here and in order to add a new subproblem it is necessary to extend the functionality of one of the classes allocated there.
- BasicProblem
- MatchProblem
- BasicCodeProblem
- CodeSingleLineProblem
- CodeFileProblem
- CodeProblem
- CodeMultipleLanguagesProblem
- MultipleChoiceProblem
In this case, as we want to add a new functionality for the CodeProblem subproblems (the possibility to choose any language for a submission) we extend from the CodeProblem and create a new Class that will handle the objects of our desired new subproblem.
And define a new type of subproblem overriding the method get_type
Now, to referring to this type of subproblem we’ll always ask about the type, and it has to be “code-multiple-languages”.
So, we have to add this type of problem and the class associated with it in the next file:
inginious/common/tasks.py
In the task_problem_types object. Which contains all the available subproblems that a Task can hold.
Firstly, to add a new subproblem task is necessary to create a new template that will handle it.
The subproblem templates are allocated in the file inginious/frontend/webapp/course_admin/edit_tabs/subproblem_templates.html
In the above file is recommended to add the new subproblem view. And in each HTML tag associate an id made of the PID that corresponds to the task that contains the subproblem.
While modifying a task for a course, all the actions made by an administrator are controlled by
inginious/frontend/webapp/static/js/studio.js
Thus, in this file we have to add the methods to manage the created template.
For the new subproblem that we are creating, the following functions were created or edited:
- studio_init_template_code_multiple_languages: (Created) Which takes the template associated to the code-multiple-languages subproblem and places the associated information
- studio_get_template_for_problem: (Edited) get the template for every kind of subproblem. Here is added the id of the new subproblem template.
- studio_init_template: (Edited) Calls the studio_init_template_code_multiple_languages, and all the rest methods to init templates.
As the settings for a task are allocated in a .yaml file in the course folder. To manage the object that contains the information of a subproblem is necessary to add the required statements in the process of parsing the file.
This has to be done in the next file:
inginious/frontend/webapp/pages/course_admin/task_edit.py
And specifically in the method parse_problem.
Finally, to be able to add the subproblem in the creation process you have to add the new subproblem in:
inginious/frontend/webapp/templates/course_admin/edit_tabs/subproblems.html
The value of the option has to be the same to the one added in:
inginious/frontend/webapp/static/js/studio.js
Now, if you want to just create a new subproblem which only contains an extended set of settings of any existing subproblem there’s no need to continue here, just the steps mentioned above are required. But, if you need to add some feature in the front end that a student should see, it’s necessary to continue and add some more things to the code.
As well as there are a set of Classes to control the type of subproblems objects, there are some classes that control the functioning of the interface of those type of subproblems. Those classes are allocated in the file:
inginious/frontend/common/task_problems.py
Actually, this classes render the html file that will be showed to the user. In the example of the multiple languages subproblem will be something like this:
It must extend from the class created in inginious.common.tasks_problems.py and from some of the Displayable classes defined in this file.
Then, the show_input method has to be overridden.
If you see, this method is rendering something called tasks.multiplelanguages. This is the other template we have to create, this is the template that will be shown to the user.
This has to be added into the next folder:
inginious/frontend/common/templates/tasks
The above folder contains all types of subproblems that a user can find.
UNCode - Distributed and maintained by the Universidad Nacional de Colombia, Campus Bogotá.
Visit the UNCode web page.
Visit UNCode.
- Home
- User's Documentation
- Developer's Documentation
- Deploy UNCode
- Others