Every student learns at a different pace. Some students may grasp concepts more easily, while others may require extra coaching and practice before they could grasp the concepts. The traditional teaching style typically provides a "one-size-fits-all" learning experience. It is usually targeted at the average student, which might bore the faster students, while leaving the slower students struggling to catch up. "Adaptive learning", on the other hand, addresses the needs of each student through real-time feedback, and adapts the teaching pace and content sequences accordingly. This approach usually provides better learning experiences and results.
Electrical circuit principles, which are taught in the freshmen year for both electrical and computer engineering programmes, are important foundational knowledge for several other modules. It is observed that students who do not have a good grasp of these principles tend to struggle in the subsequent modules. The objective of this capstone project is to develop an adaptive learning software that teaches electrical circuit principles, so as to help as many students as possible to grasp these important fundamental concepts.
The four students in this capstone project will jointly develop the software tool, consisting of the following key parts:
The adaptive learning software tool has great potential for the following:
First, git clone
this project onto your machine. Then, when you are working on the app itself, it is recommended to open the project in the /LeetNode/leetnode
subfolder instead of the /LeetNode
root folder as the relative paths might break. Just remember to cd ..
back to the root folder when running docker compose
.
git clone https://github.com/zhermin/LeetNode
cd LeetNode # root folder of this repo
cd leetnode # subfolder for the NextJS app only
code . # opens the /leetnode subfolder in VSCode
! IMPORTANT: Always ensure you have the most updated .env
file from your team and place it in the /LeetNode/leetnode
subfolder. You will also need a serviceAccountKey.json
file in the /LeetNode/recommender
subfolder for Firebase to work, which you can get from your team, or from your Firebase console under Project Overview > Project settings > Service accounts
after you are added into the Firebase project.
You may also start from scratch by copying the .env.example
file in the /LeetNode/leetnode
subfolder and creating a new .env
local file with the environment variables filled in.
If you are deploying on Vercel or other managed hosting services, remember to replicate them in Vercel's or the provider's environment variables section as well.
Using Docker to run the app while still developing on your own host machine is recommended because everyone on the team will be in the same environment with the same tools, although installing the dependencies and starting the app on your own machine works as well.
Note that using Docker to develop means you cannot use the PlanetScale CLI and Prisma Studio to manage your database and interactively view and edit your database's data. So it is up to personal and team preferences.
Start by installing Docker on your machine. The commands below are for Ubuntu / WSL machines from this link. You can find the steps for other OS online.
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo groupadd -f docker && sudo usermod -aG docker $USER && newgrp docker
# Verify Installation
docker run hello-world
There are many ways to provision a server to self-host the Docker containers. Easiest way to get started is to setup a small instance on cloud providers like GCP/AWS/Azure (on free credits preferably), SSH into it, git clone/pull
this repo, build and start the server using docker compose
. Then, just get a free subdomain from freedns and point it to the public static IP address of the instance, allowing the app to be accessible with the URL.
However, running on local servers is also viable. With a Raspberry Pi or Synology NAS, it follows the same concept as above where the main tool needed is Docker. Once Docker is setup, and you have the source code and env files in the hardware's disk, Docker should be able to handle everything else from there to deploy the app. At best some networking configs have to be setup for users to access the IP address of the server either through an internal address on VPN or the local wifi, or an external URL like one from freedns.
Provision server from online cloud providers or local hardware like Synology NAS / Raspberry Pi.
Find the public static IP address of the server and make sure the hardware allows SSH and has the SSH port 22 opened (no firewall blocking).
Setup an SSH key on your local machine.
ssh-keygen
SSH into the server with your private SSH key (non-.pub
).
ssh -i ~/.ssh/id_rsa <username>@<server public IP>
Update packages in the server.
sudo apt-get update && sudo apt-get upgrade
Install Docker for the server's OS and setup permissions to allow Docker to work for non-sudo users (refer above) and enable swap mode if the server has not enough RAM.
Git clone this repo.
git clone https://github.com/zhermin/LeetNode
Navigate to the /LeetNode
root folder and pull the latest changes, if any.
cd LeetNode
git pull
Build and start the app in the background using docker compose
.
docker compose --profile prod --env-file ./leetnode/.env up -d --build --force-recreate
docker compose
: Runs the multi-container setup specified by the docker-compose.yml
file (preferred over the docker-compose
command)--profile prod
: Runs the Docker Compose services with the "prod" profileup
: Spins up all the containers at once (use docker compose down
to shut them down)-d
: Runs containers in the background--build
: Rebuilds containers without having to first run docker compose down
if there are new changes after git pull
--force-recreate
: Recreates containers forcefully in case changes were not detectedGet a DNS address and point it to the public IP address, example from freedns; might be different for intranet / VPN access.
If everything ran without errors, the app should be accessible on the URL or the IP address directly, if on the same network as the server.
You can also run the 3 containers in development mode using the dev
profile, which enables hot reloading for changes to be reflected instantly, speeding up development on your own machine.
docker compose --profile dev --env-file ./leetnode/.env up --build --force-recreate
The app will then be accessible on http://localhost
(no port needed). The recommender service will also be accessible on http://localhost/recommender/
and the auto-generated docs on http://localhost/recommender/docs
.
The team has managed to accomplish the core functionalities expected from this web application, and beyond. However, the application did not manage to reach the general user testing phase, and hence, unforeseen problems might crop up. Regardless, here are some possible high-level extensions to LeetNode apart from deploying on local servers and managing the public release.
math.js
supports it but integration is neededdocker compose
will only instantiate 1 set of containers. However, if user traffic ever scales immensely, orchestration tools such as Kubernetes and Docker Swarm can help automated scaling and management.All the technologies used can be overwhelming. However, start by trying to setup Docker and running the app locally on your machine first if possible so that you can see changes live. For example, by changing the source code of the Homepage's title.
The most important tool would be NextJS, which will also require some ReactJS understanding to at least change the frontend. JavaScript (TypeScript is just a stricter version) is then critical for the backend work.
All of the backend authentication, databases, hosting and infrastructure should work as is but will need further reading up on their docs or watching online tutorials if you wish to modify anything.
The code and detailed documentation for the main app, the LeetNode website, can be found in this repo in the subfolder /leetnode
.
Likewise, the code and docs for the recommender microservice can be found in the other subfolder /recommender
. Originally, this was hosted on Heroku; but since Heroku only offers a 1 year free trial, moving forward, this will be self-hosted alongside the main app using Docker and Nginx.
The technologies listed below follow the order of the diagram above from top to bottom, left to right, except for the ones used for the recommender service.