This repostory will contain all code for our semester long project created during our CMPT 470 - Web Development class at Simon Fraser University.
A lot of beginner programmers seem to face two consistent problems:
- Setting up a programming environment:
- Installing interpreters/compilers
- Making sure that their environment matches that of the instructor(students use Windows/Mac while instructor might be using Linux)
- Making sure that their assignments are portable(Ex: Code written on Windows but has to run on Linux)
- Feeling overwhelmed by large blocks of code
- Large blocks of code might make beginners nervous and apprehensive about diving into the code. While it is necessary to learn to handle large blocks of code in the long run, beginner programmers can be eased into it by being presented small chunks of code that have been annotated(like a Jupyter Notebook).
For our project, we chose to create a full-stack web application which can be used to aid the learning of programming through interactive tutorials. The application provides literate programming features and has a user interface similar to Jupyter Notebooks.
Each interactive tutorial can be made up of:
- Explanatory text written using markdown(with support for LaTex formulas and emojis).
- Chunks of code which are written by the tutorial author. These chunks of code can then be ran remotely(on the applications server) and the result returned and shown to the reader. Tutorial readers can additionally modify these cells and re-run them in order to understand the code better through experimentation.
NOTE: This is a project made for a web-development class in our university. It is not meant to be used in any serious applications.
- Class Support: Support for one or more classes made up of instructor and students. Each class is separate from all others and tutorials are accessible to users only if they have the appropriate permissions to do so.
- Tutorials:
- Tutorials are written using markdown and each tutorail can contain mathematical formulas and emojis. Tutorails can be previewed in real-time before being published for students to see.
- Tutorials contain code cells which can be ran by readeers. The result of evaluating each code cell is then shown as soon as the code is evaluated.
- Code cells can be edited by students to experiement and better understand the code.
- Code cells can be ran in different "environments" which lets one tutorial contain code which is ran in two or more different interpreters. This prevents interference and pollution of the interpreter environments.
- Tutorials can be made up of several languages. As an example, a tutorial might contain code cells in both
python
andjulia
.
- Forums: Each class has an associated forum for all questions and other class discussions.
- Language Support: Currently, the application supports four languages:
- Python 3
- Julia
- Bash
- Zshell/Zsh
- Sandboxed environments: All interpreter environments are sandboxed from one another using
Docker
containers. Each interpreter started by each user has its own container based off ofUbuntu
. This means that each user gets a fully functional sandboxed file system which can be used to accomplish a variety of tasks. - Automated Test Runner: Course instructors can create scripts to test a project submission made by a student. Students can then submit their assignments and the tests provided by the course instructor are automatically ran within a sandboxed environment. Any output generated by the test(i.e. "Works/Does not work", "True/False"...) are sent back to the student as feedback.
- Jupyter Notebooks have support for more languages than our tutorial application.
- Jupyter Notebooks are more popular and have more support/plugins available.
- Jupyter notebooks are extremely popular in various scientific/industrial fields(Data Science, Machine Learning, Physics...) but they require the user to install all necessary interpreters and configure the Jupyter kernel to detect them. Our tutorial application requires no setup for students besides creating an account.
- Jupyter Notebook files require all Jupyter files to be distributed to each user(Dropbox, Github/Gitlab...). Our application provides automatic hosting for every file created. The only barrier to accessing a file is simply having the permission to do so. There is no need to download anything.
- Jupyter Notebook files are difficult to read without using a Jupyter Notebook as the front-end interface. All tutorials for our application are written in plain markdown and can be distributed as raw files if necessary.
- Jupyter Notebook files are constrained to only one language per file. Each tutorial in our application can be made up of executable code cells for several languages(currently support Python, Julia, Zshell/Zsh and Bash).
repl.it
has support for more languages than our tutorial application.repl.it
allows users to run full environments where they can install additional libraries.repl.it
has a more attractive/powerful UI/UX.
repl.it
can only run interpreted code(Ruby, Python, Javascript...) in "one shot". Each time a project is executed, it is executed from the start to the end. The interpreter used to run the project is closed after the last line of code. Users do not have the ability to run only certain parts of a program over and over again.repl.it
does not provide any way of annotating code outside of comments within the source code or additional files explaining the code. This makes it difficult to annotate and break up a source file into smaller chunks which are easier to understand and digest by students.
Detailed information on how code cells/instructor tests are executed in the backend can be found within the docs/executing-code.md file.
client
: Contains all code for the frontend of the application. The frontend is built usingReact
andBootstrap
.server
: Contains all code for the backend of our application. The backend is built usingexpress.js
,MongoDB
andnode.js
.containers
: Contains all docker files use to create interpreter environments and isolate each user from all others.language-servers
Contains all code for each of the language servers which are used to maintain each supported language and its associated interpreter.models
: Contains all database models.routes
: Contains all API routes.
The project is a bit difficult to setup locally. Unfortunately, we ran out of free Google Cloud Platform credits so we cannot host the project there anymore
NOTE: All commands from step 3 and onwards are executed from the project root.
git clone https://github.com/CMPT-470-Fall-2020/Code-Tutorial-App.git
cd Code-Tutorial-App
cd client && npm install
cd server && npm install
- Make sure that the docker daemon is started. After this is done,
- Download the Ubuntu 20.04 image from dockerhub
cd server/docker_container_setup
. If you are running on Linux/MacOS, execute thegenerate-containers.sh
file. If you are running on Windows, execute thegenerate-containers.ps1
file. This will create all the docker images necessary to run the project. Note: This might take some time.- Create a MongoDB Atlas instance and grab its URL.
cd server && touch .env
- Within the
/server/.env
file, add three items:
ATLAS_URI = MONGODB_ATLAS_URI_HERE
SESSION_SECRET= SOME_RANDOM_SECRET_CODE_HERE
COOKIE_PARSER_SECRET= SOME_RANDOM_SECRET_CODE_HERE
cd server && npm start
to start the back-end application server on port 4000.- Open another terminal, navigate to the root of the project and run the following:
cd client && npm start
to start the application front-end on port 3000.
- To remove all running docker instances if they are not stopped through the applications front-end, you can run the command
docker rm $(docker ps -aq)
from a terminal. - To remove all docker images created, you can executed the
/server/docker_container_setup/delete-images.sh
(Linux/MacOS) file or/server/docker_container_setup/delete-images.ps1
file if you are on windows.