feat: added Exercise and Exercise Submission doctypes
Also: - added methods to submit an exercise and get the submission for a user - added test cases Issue #90
This commit is contained in:
0
community/lms/doctype/exercise/__init__.py
Normal file
0
community/lms/doctype/exercise/__init__.py
Normal file
8
community/lms/doctype/exercise/exercise.js
Normal file
8
community/lms/doctype/exercise/exercise.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2021, FOSS United and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Exercise', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
||||||
99
community/lms/doctype/exercise/exercise.json
Normal file
99
community/lms/doctype/exercise/exercise.json
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2021-05-19 17:43:39.923430",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"title",
|
||||||
|
"description",
|
||||||
|
"code",
|
||||||
|
"answer",
|
||||||
|
"column_break_4",
|
||||||
|
"course",
|
||||||
|
"hints",
|
||||||
|
"tests",
|
||||||
|
"image"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Title"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "course",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Course",
|
||||||
|
"options": "LMS Course"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 4,
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 4,
|
||||||
|
"fieldname": "answer",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Answer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "tests",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Tests"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_4",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 4,
|
||||||
|
"fieldname": "hints",
|
||||||
|
"fieldtype": "Markdown Editor",
|
||||||
|
"label": "Hints"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": 4,
|
||||||
|
"fieldname": "code",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "image",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Image",
|
||||||
|
"read_only": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-19 18:27:40.475515",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Exercise",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"search_fields": "title",
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"title_field": "title",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
44
community/lms/doctype/exercise/exercise.py
Normal file
44
community/lms/doctype/exercise/exercise.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class Exercise(Document):
|
||||||
|
def get_user_submission(self):
|
||||||
|
"""Returns the latest submission for this user.
|
||||||
|
"""
|
||||||
|
user = frappe.session.user
|
||||||
|
if not user or user == "Guest":
|
||||||
|
return
|
||||||
|
|
||||||
|
result = frappe.get_all('Exercise Submission',
|
||||||
|
fields="*",
|
||||||
|
filters={
|
||||||
|
"owner": user,
|
||||||
|
"exercise": self.name
|
||||||
|
},
|
||||||
|
order_by="creation desc",
|
||||||
|
page_length=1)
|
||||||
|
if result:
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
def submit(self, code):
|
||||||
|
"""Submits the given code as solution to exercise.
|
||||||
|
"""
|
||||||
|
user = frappe.session.user
|
||||||
|
if not user or user == "Guest":
|
||||||
|
return
|
||||||
|
|
||||||
|
old_submission = self.get_user_submission()
|
||||||
|
if old_submission and old_submission.solution == code:
|
||||||
|
return old_submission
|
||||||
|
|
||||||
|
doc = frappe.get_doc(
|
||||||
|
doctype="Exercise Submission",
|
||||||
|
exercise=self.name,
|
||||||
|
exercise_title=self.title,
|
||||||
|
solution=code)
|
||||||
|
doc.insert()
|
||||||
|
return doc
|
||||||
|
|
||||||
37
community/lms/doctype/exercise/test_exercise.py
Normal file
37
community/lms/doctype/exercise/test_exercise.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestExercise(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
frappe.db.sql('delete from `tabExercise Submission`')
|
||||||
|
frappe.db.sql('delete from `tabExercise`')
|
||||||
|
|
||||||
|
def new_exercise(self):
|
||||||
|
e = frappe.get_doc({
|
||||||
|
"doctype": "Exercise",
|
||||||
|
"name": "test-problem",
|
||||||
|
"title": "Test Problem",
|
||||||
|
"description": "draw a circle",
|
||||||
|
"code": "# draw a single cicle",
|
||||||
|
"answer": (
|
||||||
|
"# draw a single circle\n" +
|
||||||
|
"circle(100, 100, 50)")
|
||||||
|
})
|
||||||
|
e.insert()
|
||||||
|
return e
|
||||||
|
|
||||||
|
def test_exercise(self):
|
||||||
|
e = self.new_exercise()
|
||||||
|
assert e.get_user_submission() is None
|
||||||
|
|
||||||
|
def test_exercise_submission(self):
|
||||||
|
e = self.new_exercise()
|
||||||
|
submission = e.submit("circle(100, 100, 50)")
|
||||||
|
assert submission is not None
|
||||||
|
|
||||||
|
user_submission = e.get_user_submission()
|
||||||
|
assert user_submission is not None
|
||||||
|
assert user_submission.name == submission.name
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2021, FOSS United and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Exercise Submission', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2021-05-19 11:41:18.108316",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"exercise",
|
||||||
|
"solution",
|
||||||
|
"exercise_title"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "exercise",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Exercise",
|
||||||
|
"options": "Exercise"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "solution",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Solution"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "exercise.title",
|
||||||
|
"fieldname": "exercise_title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Exercise Title",
|
||||||
|
"read_only": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-05-19 19:41:55.852069",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Exercise Submission",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class ExerciseSubmission(Document):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestExerciseSubmission(unittest.TestCase):
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user