123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- """
- Dummy backend
- Use as reference
- This file is part of polyglot, etc.
- """
- import datetime
- from backends.support import Backend, Course, AssignmentGrade, CategoryGrade, AuthTypes, ResourceCategory, ResourceRawHTML, Task, FileUpload, Quiz, MultipleChoiceQuestion, FreeResponseQuestion, Forum, Post
- class DummyQuiz(Quiz):
- def __init__(self, course, id, name):
- super().__init__(id, name)
- self.course = course
- # Fetch quiz questions
- # This should be call carefully, as it has nasty side effects in some courses!
- # Hence why it is a method, breaking with the usual @property technique.
- def questions(self):
- question1 = MultipleChoiceQuestion("Is mathematics fun?", ["Absolutely!", "Definitely!"])
- question2 = FreeResponseQuestion("What's your favourite part?")
- return [question1, question2]
- # Submit quiz where responses is the output of questions filled out
- # True on success
- def submit(self, responses):
- return True
- class DummyForum(Forum):
- def __init__(self, course, id, name):
- super().__init__(id, name)
- self.course = course
- # Existing discussion posts.
- # Returns a root Post object (with many nested replies, perhaps).
- @property
- def thread(self):
- reply2 = Post("Babs Seed", "That gives me a good idea to annoy the CMCs!", [])
- reply1 = Post("Jane Doe", "DNA nanotechnology involves forming artificial, designed nanostructures", [reply2])
- question = Post("Carl Smith", "In the homework problem set, you looked at a formula to estimate the number of basepairs in a DNA strand given the length. What are your thoughts?", [reply1])
- return question
- # Parent is the post to be replied to, body is the text
- # Usual return code
- def reply(self, parent, body):
- return True
- class DummyCourse(Course):
- def __init__(self, data):
- # Course ID unique within this backend but not necessarily in general
- self.id = data["id"]
- # Course name and teacher name, no localisation?
- self.title = data["title"]
- self.teacher = data["teacher"]
- # Single course grade, if that's available (otherwise, it's computed)
- self.grade_summary = data["grade"]
- # Detailed gradebook, including weighted categories
- @property
- def grades(self):
- # Uh-oh, let's make a request to the server
- # Request the grade break down for course id self.id
- # Then fill out like this
- grade1 = AssignmentGrade("Chapter 1 Test", 0.95)
- grade2 = AssignmentGrade("Homework 1", 0.95)
- category1 = CategoryGrade("Tests", 0.80, [grade1])
- category2 = CategoryGrade("Homeworks", 0.20, [grade2])
- return [category1, category2]
- # Arbitrary hierarchy of resources
- # Lectures, external links, the syllabus, etc should go here.
- # This is necessary as many (most? all?) LMSes support course-specific WYSIWYG editing
- # That said, use sparingly as it is not semantic (compare tasks, etc)
- @property
- def resources(self):
- rsrc1 = ResourceRawHTML("Notes", "<p>To-do: Should this be refactored more?</p>")
- rsrc2 = FileUpload("foobarbaz", "Essay")
- rsrc3 = DummyQuiz(self, "foobazbar", "Post-essay quiz")
- rsrc4 = DummyForum(self, "bazbar", "Post-quiz discussion")
- rsrc5 = ResourceRawHTML("Syllabus", "1. Be good")
- cat = ResourceCategory("Week 1", [], [rsrc1, rsrc2, rsrc3, rsrc4])
- cat2 = ResourceCategory("Modules", [cat], [])
- return ResourceCategory("Root", [], [cat2, rsrc5])
- # Tasks are assignments with a definite (near) due-date.
- # Naturally suited to traditional courses (where tonight's homework is here)
- # Probably not of much use to self-paced classes
- @property
- def tasks(self):
- return [Task("Homework 2", datetime.datetime.now() + datetime.timedelta(days=1))]
- # Upload a file where ID was passed in a FileUpload model
- # Returns true if the upload was successful and false otherwise
- def upload_file(self, id, file):
- return True
- class DummyBackend(Backend):
- # Parameters needed for authentication
- Config = ["Username", "Password"]
- # Attempts login based on config from Config
- # Return True on success and False on failure.
- # Caller is responsible for tracking authentication statement based on this response.
- def login(self, config):
- if not (config["Username"] == "AzureDiamond" and config["Password"] == "hunter2"):
- return False
- self.session_id = "cookies_are_tasty"
- return True
- # List of courses available (available post-auth)
- # Array of Course objects, although in practice this will be inherited
- @property
- def courses(self):
- # Fetch something with self.session_id
- course = DummyCourse({
- "id": "ABC123",
- "title": "Algebra II",
- "teacher": "Carl Smith",
- "grade": 0.95
- })
- return [course]
|