uLearn is an adaptive learning tool designed to personalize the learning experience for students.
- Dynamic Question Difficulty based on global student performance.
- Track individual student mastery for each Topic.
- Use IRT to identify relationships between individual students and the questions to accurately recommend questions.
Before you can install our app, you must have the following pre-requisites:
Services | Version |
---|---|
Node.js | > 21.6.2 |
NPM | > 10.5.0 |
Docker Desktop | > 4.28.0 |
Python | > 3.7 |
R | > 4.3.2 |
Git | > 2.39.3 |
Our app also requires come R & Python packages of a certain version. These requirements are highlighted below:
Packages | Version |
---|---|
rpy2 | > 3.5.15 |
pandas | > 2.2.1 |
These are just the recommend versions for each of the above services and packages. Other verisons (older/newer) may also work. However, compatability for these has not been tested.
The recommend way to install our app is to use the following steps:
- Clone the repository using
https://github.com/SatanshuMishra/honours-2023-adaptive-learning-tool.git
. - Navigate into
honours-2023-adaptive-learning-tool
. Install system dependencies:
npm install
- Initialize .env and .env.local files.
.env:
DATABASE_URL = # Enter the URL to the database here.
.env.local
JWT_SECRET= # A secure key that will be used to encrypt your JWT
PASSWORD_ENCRYPTION_KEY= # A secure key that will be used to encrypt your passwords.
- Open Docker. Start the docker containers using a terminal of your choosing:
docker-compose up [-d]
- The system will be live @
localhost:3030
. - Built into the docker-compose is a MySQL server and phpmyadmin live @
localhost:8080
.
This learning tool uses a specific way to log users into the system:
- By default, the username
SystemAdmin
is available to you. First go tolocalhost:3030
and Sign-Up using the aforementioned username. - Once you successfully sign-up, use the same credentials to sign-in.
You are now logged in!
The learning tool offers a simplifed way to load questions. Lets go through the steps:
- Ensure you are logged in as the
SystemAdmin
user. You should see Developer Tools at the bottom of your dashboard.
![image](https://private-user-images.githubusercontent.com/63601536/326533361-b7481c4a-e6d9-4be0-ab62-be8bc6b4beef.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjYwMjQ1MzEsIm5iZiI6MTcyNjAyNDIzMSwicGF0aCI6Ii82MzYwMTUzNi8zMjY1MzMzNjEtYjc0ODFjNGEtZTZkOS00YmUwLWFiNjItYmU4YmM2YjRiZWVmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA5MTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwOTExVDAzMTAzMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQxMGVjYjU2NzZjY2U1MmUyOTdjNTVhMmUzM2IwM2MxNWU1YmIyYWQxMWJlNjM0ZjRmNmZhM2MwMTJkMDRiMmYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.3aSGuTMP53Kz6CcFIakB99WuO1DXn7LW1mtd2gUJQzM)
- Open your file explorer. Navigate into
honours-2023-adaptive-learning-tool/app/data
. Here you will notice one file calleddummyData.ts
. This is the file that will be queried when we add the questions. Here you have two options, you can create your own questions in this file. Or you can use the pre-made questions in the four other files provided. - If you want to use the pre-given questions, then rename the appropriate file to
dummyData.ts
. - Return to the app and select the first button the Developer Tools. This will add all the questions in the file. Once the process is compelete, refresh the page to see the topic on the dashboard.
Important Considerations when Creating your own Questions:
To generate your own questions, you will need to take some important factors into consideration. It is IMPORTANT that the questions follow the following structure (Also given in dummyData.ts
):
difficulty: number; // A number between 0 - 1.
question: string;
code?: string; // Code is optional for each question.
answers: string[]; // Array of 4 strings.
correct: number;
explanations: string[]; // Array of 4 strings, Each refering to the same index value in answers.
bloomTaxonomy: string; // One of Remembering, Understanding, Applying, Analyzing, Evaluating or Creating.
timeTakenSeconds: number;
topic: string; // All questions with the same topic will be grouped together.
If you want to change the bloomTaxonomy (i.e., Category) of the question, you will need to either add these manually to the Database (See Database Section) or add logic to automatically add new categories to the database on question insert.
Deeper changes to the question structure will require revaluation of the question selection code.
The following is the database structure used in this learning tool and their uses:
/* STORES SIGN-UP ABLE USERNAMES: YOU CAN ONLY SIGN-UP IF YOUR USERNAME IS IN THIS TABLE. VALUES MANUALLY INSERTED.*/
studentCode (
code VARCHAR(255) PRIMARY KEY NOT NULL,
isRegistered BOOLEAN NOT NULL DEFAULT FALSE
)
/* STORES SIGNED-UP STUDENT INFORMATION.*/
student (
studentID BINARY(16) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
completedBonusContent BOOLEAN NOT NULL DEFAULT FALSE,
FOREIGN KEY (username) REFERENCES studentCode(code)
)
/* STORES QUESTION TOPICS. ADDED AUTOMATICALLY AS QUESTIONS ARE ADDED.*/
questionTopic (
topicID BINARY(16) NOT NULL PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL,
image BLOB
)
/* STORES QUESTION CATEGORIES. MANUALLY INSERTED.*/
taxonomyCategory (
categoryID BINARY(16) NOT NULL PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL
)
/* STORES QUESTIONS ADDED TO THE SYSTEM */
question (
questionID BINARY(16) NOT NULL PRIMARY KEY,
topicID BINARY(16) NOT NULL,
assignedDifficulty DECIMAL(4, 1) NOT NULL,
modifiedDifficulty DECIMAL(4, 1) NOT NULL,
categoryID BINARY(16) NOT NULL,
assignedCompletionTime DECIMAL(5, 2) NOT NULL,
modifiedCompletionTime DECIMAL(5, 2) NOT NULL,
question TEXT NOT NULL,
code TEXT,
FOREIGN KEY (topicID) REFERENCES questionTopic(topicID),
FOREIGN KEY (categoryID) REFERENCES taxonomyCategory(categoryID)
)
/* STORES ANSWERS ADDED FOR QUESTIONS ADDED TO THE SYSTEM*/
answer (
answerID BINARY(16) NOT NULL PRIMARY KEY,
questionID BINARY(16) NOT NULL,
answerDescription TEXT NOT NULL,
answerExplanation TEXT NOT NULL,
isCorrect BOOLEAN NOT NULL,
FOREIGN KEY (questionID) REFERENCES question(questionID)
)
/* STORE STATISTIC DATA FOR ALL STUDENTS ON THE SYSTEM */
statistic (
statID BINARY(16) NOT NULL PRIMARY KEY,
studentID BINARY(16) NOT NULL,
questionID BINARY(16) NOT NULL,
chosenAnswerID BINARY(16) NOT NULL,
isCorrect BOOLEAN NOT NULL,
timeToAnswer DECIMAL(10, 3) NOT NULL,
createdAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (questionID) REFERENCES question(questionID),
FOREIGN KEY (chosenAnswerID) REFERENCES answer(answerID)
)
/* [IMPORTANT FOR ML] STORES THE IRT DIFFICULTY OFFSET AND MASTERY FOR EACH STUDENT FOR EACH TOPIC - CATEGORY PAIR. */
studentKnowledge (
knowledgeID BINARY(16) NOT NULL PRIMARY KEY,
studentID BINARY(16) NOT NULL,
topicID BINARY(16) NOT NULL,
categoryID BINARY(16) NOT NULL,
mastery DECIMAL(5, 2) DEFAULT 0.5 NOT NULL,
difficultyOffset DECIMAL(5, 2) DEFAULT 0 NOT NULL,
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (topicID) REFERENCES questionTopic(topicID),
FOREIGN KEY (categoryID) REFERENCES taxonomyCategory(categoryID)
)
/* STORES STUDENT MASTERY CHANGES OVER TIME. DOESN'T STORE ACTUAL VALUES BUT THE CHANGE. */
studentLogMastery (
studentLogID BINARY(16) NOT NULL PRIMARY KEY,
studentID BINARY(16) NOT NULL,
topicID BINARY(16) NOT NULL,
categoryID BINARY(16) NOT NULL,
mastery DECIMAL(5, 2) NOT NULL,
createdAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (topicID) REFERENCES questionTopic(topicID),
FOREIGN KEY (categoryID) REFERENCES taxonomyCategory(categoryID)
)
/* STORES STUDENT DIFFICULTY OFFSET CHANGES OVER TIME. */
studentLogOffset (
studentLogID BINARY(16) NOT NULL PRIMARY KEY,
studentID BINARY(16) NOT NULL,
topicID BINARY(16) NOT NULL,
categoryID BINARY(16) NOT NULL,
difficultyOffset DECIMAL(5, 2) NOT NULL,
createdAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (topicID) REFERENCES questionTopic(topicID),
FOREIGN KEY (categoryID) REFERENCES taxonomyCategory(categoryID)
)
/* STORES CHANGES IN QUESTION DIFFICULTY OVER TIME. */
questionLogsDifficulty (
questionLogID BINARY(16) NOT NULL PRIMARY KEY,
questionID BINARY(16) NOT NULL,
difficulty DECIMAL(3, 2) NOT NULL,
createdAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (questionID) REFERENCES question(questionID)
)