Blog Post #3: Code Type Snippets 👨💻
DebadityaPal
Published: 07/15/2021
So we have just passed the halfway mark on our GSoC journey and a considerable amount of my project is over. However, now is not the time to rest. Now comes the most important part of my project, i.e: Code Type Snippets.
It is this feature that is going to encourage and entertain users the most so that they keep on using my package.
The idea is to let the users write Python code during runtime while a course is being served, and check that code for correctness. So in a manner my program will have another program running inside of it. Sort of like a shell inside a shell. Shellception! but how would we do this?
Turns out Python already has an inbuilt module for it called code. So this code module has a few classes like the InteractiveConsole class that closesly emulates the actual interactive Python Shell experience and takes in user code. This code is stored as a string, we have the
InteractiveInterpreter.runcode()
function for running this code and generating the variables dynamically at runtime.
So for now I have planned to use these for the CodeType snippets as I can use a simple string matching to check for code correctness, and later run the code to keep the variables ready for the next Code Snippet within the same chapter.
View Blog Post
Weekly Check-In #3: MCQ Snippet ✔️
DebadityaPal
Published: 07/07/2021
What did I do this week?
This week was spent implementing a specific type of Snippet viz, the MCQ Snippet. This is a very important subtype as it is currently the only way to check retention of information from the user's part. The YAML structure for this snippet had to be made simple so that anyone can use it irrespective of their technical know-how. The current YAML structure looks like this:
The keys are self explanatory. To properly check for retention I decided to randomly shuffle the options every time the snippet is parsed. The Hint will be used after every wrong answer given by the user.
What is coming next?
Since 2 out of the 3 proposed Snippets have been added. I will be working on the 3rd one next, i.e.: The Code Snippet. This one is by far going to be the most complicated snippet as it involves evaluating python code written during runtime. I'll take a look at swirl to see how they have achieved this with R, and maybe look into the "code" module in Python.
Did I get stuck anywhere?
The MCQ snippet was pretty easy to implement, since it's a non console snippet and the abstract classes defined during the previous weeks already had the implementations of the basic functions. So I did not get stuck anywhere during this week.
View Blog Post
Blog Post #2: Documentation 📕
DebadityaPal
Published: 06/30/2021
This week was mainly spent on writing docstrings to improve the overall documentation of the project. My goal was to get the API reference up to date with the work I've done and get it hosted via ReadTheDocs. However, there were a couple of hiccups on the way, hence I am devoting this blog post to ReadTheDocs.
ReadTheDocs makes parsing docstrings and hosting documentation a lot easier than having to do it manually, however their documentation is a bit unfriendly towards first time users. Like if you want to use an Automatic Docstring parser to parse docstrings, a user will have to install
recommonmark but a simple pip install wont work. After some docs hunting I found out that one needed to add this function to the configuration file.
from recommonmark.transform import AutoStructify
...
github_doc_root = "https://github.com/rtfd/recommonmark/tree/master/doc/"
def setup(app):
app.add_config_value(
"recommonmark_config",
{
"url_resolver": lambda url: github_doc_root + url,
"auto_toc_tree_section": "Contents",
},
True,
)
app.add_transform(AutoStructify)
I hope this code snippet helps others in automating their documentation pipeline. I am also sure that the authors of these packages will fix these issues within the near future. Long live Open Source Software.
View Blog Post
Weekly Check-In #2: MetaClasses and OOP 🤖
DebadityaPal
Published: 06/23/2021
What did I do this week?
This week was spent creating the various classes and subclasses for the Course Engine. I finished writing all the different functions and utility functions that perform the following tasks:
- Recursively Load Data from Yaml files
- Verify the Chapters for missing fields before serving it
- Serve the chapters on the CLI
I used python's metaclass concept to make "Snippet" a meta class for the different types of snippets that will be implemented in the following weeks. The purpose of this is to ensure implementation of certain functions in the inherited child classes.
What is coming next?
Over the course of the next week, I will be trying to improve the documentation of my codebase and introduce unit tests to ensure a robust system. Once that is done, I will be implementing specific types of Snippets using the base class as the parent. The first in the list is the TextSnippet followed by MCQSnippet and CodeSnippet.
Did I get stuck anywhere?
This week was spent with the basics of Object Oriented Programming (OOP) hence I didn't get stuck anywhere, however the concept of a metaclass was new to me, so I had to read some documentation and tinker around with it before implementing it in my project.
View Blog Post
Blog Post #1: The Skeletal Framework ⚙️
DebadityaPal
Published: 06/16/2021
During this week, I analyzed the flow of data in my project and modelled the classes accordingly. The course data is expected to be stored in a YAML file, hence the first thing that I needed to implement was a YAML parser. Thankfully, Python has a package aptly named
yaml
for that specific purpose. The course file would have the following structure:
Now once we have the raw data from the YAML file, we need to give it some structure for ease of computation. I decided to have the following heirarchical structure.
- Course
- Chapter 1
- Snippet 1
- Snippet 2
- Snippet 3
- Chapter 2
Once this was decided, I went on to create the basic classes for a Course, Chapter and Snippet. My plan is to keep these classes as base classes so that in future if more features are to be added, the newer classes can simply inherit the base functionalities from these classes. However these classes will also need to have a few restrictions like, some mandatory fields of data, some mandatory functions being implemented for all subclasses that inherit this class and so on. For the latter I aim to explore metaclasses in Python. The metaclass can be used to control how a certain class behaves.
View Blog Post