-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #71 from CS3219-AY2425S1/dev
push final changes dev to main
- Loading branch information
Showing
49 changed files
with
3,165 additions
and
2,197 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.env | ||
|
||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
peerprep/backend/collab-service/src/controller/gptController.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
const axios = require('axios'); | ||
|
||
const assessCode = async (req, res) => { | ||
console.log('assessCode controller activated'); | ||
try { | ||
const { codeDetails } = req.body; | ||
if (!codeDetails) { | ||
res.status(400).json({ error: 'Code content is required' }); | ||
return; | ||
} | ||
|
||
const instructionalPrompt = | ||
"Analyze the following: 1: Question, and its 2: Description, and 3: The code attempt. " + | ||
"\n" + | ||
"Assess the code, focusing on its efficiency and style. Determine the correctness of the code, given the language and question specified. " + | ||
"Always ensure to not divulge the solution to the question, or any hints that will spoil the solution. " + | ||
"\n" + | ||
"Your response should include:" + | ||
"\n" + | ||
"\n" + | ||
"\t1. Time Complexity – Provide the Big-O notation." + | ||
"\n" + | ||
"\t2. Space Complexity – Provide the Big-O notation." + | ||
"\n" + | ||
"\t3. Code Style – Briefly assess readability, naming conventions, and formatting." + | ||
"\n" + | ||
"\t4. Optimization Hints – Suggest improvements if the time or space complexity could be reduced, while ensuring to not expose the solution details." + | ||
"\n" + | ||
"\t5. Correctness – Summarize any other relevant observations and assess correctness to question requirements " + | ||
"(e.g., potential edge cases, overall structure)." + | ||
"\n" + | ||
"\n" + | ||
"Keep each response concise but comprehensive." + | ||
"\n" + | ||
"\n" + | ||
"Here are some few shot exmples of inputs and the expected repsonses you hsould produce:" + | ||
"\n" + | ||
"Example 1:\n" + | ||
"1: Question - Two Sum\n" + | ||
"2: DescriptionGiven an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.\n" + | ||
"3: Code attempt in - javascript\n" + | ||
"const nums = [2, 7, 11, 15];\n" + | ||
"const target = 9;\n" + | ||
"let result = [];\n" + | ||
"for (let i = 0; i < nums.length; i++) {\n" + | ||
" for (let j = i + 1; j < nums.length; j++) {\n" + | ||
" if (nums[i] + nums[j] === target) {\n" + | ||
" result = [i, j];\n" + | ||
" }\n" + | ||
" }\n" + | ||
"}\n" + | ||
"console.log(result);\n\n" + | ||
"Expected response 1: \n" + | ||
"1. Time Complexity: The time complexity of the code is O(n^2), where n is the length of the array. This is because of the nested loops that iterate over the array.\n\n" + | ||
"2. Space Complexity: The space complexity of the code is O(1), as no additional space is used apart from a single array to store the result.\n\n" + | ||
"3. Code Style: The code style is basic but functional. Variable names like `nums`, `target`, and `result` are descriptive enough. However, the use of nested loops reduces readability and efficiency. Adding comments to describe the algorithm would improve clarity.\n\n" + | ||
"4. Optimization Hints: Try using a data structure to track the numbers you’ve seen so far. It’ll help you quickly check if the matching number for the target is already there, saving a lot of extra work!\n\n" + | ||
"5. Correctness: The code works for small inputs but is inefficient for large arrays. It also does not handle cases where no two numbers add up to the target. Adding an edge case check would make the solution more robust.\n" + | ||
"\n" + | ||
"\n" + | ||
"Example 2:\n" + | ||
"1: Question - Roman to Integer\n" + | ||
"2: DescriptionGiven a roman numeral, convert it to an integer.\n" + | ||
"3: Code attempt in - python\n" + | ||
"I = 1\n" + | ||
"V = 5\n" + | ||
"X = 10\n" + | ||
"L = 50\n" + | ||
"C = 100\n" + | ||
"D = 500\n" + | ||
"M = 1000\n" + | ||
's = "LVIII"\n' + | ||
"length = len(s)\n" + | ||
"numbers = list(map(list, s))\n" + | ||
"x = 0\n" + | ||
"while x < length:\n" + | ||
" print(numbers[x])\n" + | ||
" x = x + 1\n\n" + | ||
"Expected response 2:\n" + | ||
"1. Time Complexity: The time complexity of the code is O(n), where n is the length of the string. This is because the code iterates over the string once.\n\n" + | ||
"2. Space Complexity: The space complexity of the code is also O(n), where n is the length of the string. This is because the code creates a list of characters from the string.\n\n" + | ||
"3. Code Style: The code style is not very good. The variable names are not descriptive, which makes the code hard to understand. The code also lacks comments, which would help explain what each part of the code is doing. The use of a while loop instead of a for loop also makes the code less readable.\n\n" + | ||
"4. Optimization Hints: Try using a data structure to answer this question, maybe something to store your mappings?\n\n" + | ||
"5. Correctness: The code does not actually convert the roman numeral to an integer, it just prints out the characters in the string. The code does not handle many example cases as well, try to think about more basic testcases and handle them.\n" + | ||
"\n" + | ||
"Example 3:\n" + | ||
"1: Question - Roman to Integer\n" + | ||
"2: DescriptionGiven a roman numeral, convert it to an integer.\n" + | ||
"3: Code attempt in - python\n" + | ||
"test\n" + | ||
"Expected response 3: \n" + | ||
"Without the code attempt, it's impossible to provide a detailed analysis. Please provide the code you want to be analyzed."; | ||
|
||
console.log('Submitting code to OpenAI API:', instructionalPrompt, codeDetails); | ||
|
||
// API request to OpenAI for code assessment | ||
const response = await axios.post( | ||
'https://api.openai.com/v1/chat/completions', | ||
{ | ||
model: 'gpt-4', | ||
messages: [ | ||
{ role: 'system', content: "You are a coding assistant." }, | ||
{ role: 'user', content: `${instructionalPrompt}\n\n${codeDetails}` } | ||
], | ||
temperature: 0 | ||
}, | ||
{ | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` | ||
} | ||
} | ||
); | ||
|
||
const feedback = response.data.choices[0].message.content; | ||
res.json({ feedback }); | ||
} catch (error) { | ||
console.error('Error in assessCode controller:', error); | ||
res.status(500).json({ error: 'Failed to process code assessment' }); | ||
} | ||
}; | ||
|
||
module.exports = { | ||
assessCode | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const { Router } = require('express'); | ||
const { assessCode } = require('../controller/gptController'); | ||
|
||
const router = Router(); | ||
|
||
// Route for handling code assessment with GPT | ||
router.post('/gpt/assess', assessCode); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 48 additions & 62 deletions
110
peerprep/backend/matching-service/src/controllers/requestController.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,61 @@ | ||
import { Request, Response } from 'express'; | ||
import { addToQueue, findMatchInQueue } from '../services/queueManager'; | ||
//import { redisDelete } from '../utils/redisUtils'; | ||
import { addToQueue, removeFromQueue, cancelSession} from '../services/queueManager'; | ||
import ReqObj from '../models/ReqObj'; | ||
|
||
// new request | ||
export const createRequest = async (req: Request, res: Response): Promise<void> => { | ||
const { userId, topic, difficulty } = req.body; | ||
|
||
const newRequest: ReqObj = { | ||
userId, | ||
topic, | ||
difficulty, | ||
status: 'pending', | ||
createdAt: new Date(), | ||
userId, | ||
topic, | ||
difficulty, | ||
status: 'pending', | ||
createdAt: new Date(), | ||
}; | ||
|
||
|
||
await addToQueue(userId, topic, difficulty); | ||
|
||
// find within 30 seconds | ||
let matchedUser = null; | ||
const timeout = 30000; | ||
const startTime = Date.now(); | ||
|
||
while (!matchedUser && Date.now() - startTime < timeout) { | ||
matchedUser = await findMatchInQueue(userId); | ||
|
||
if (matchedUser) { | ||
break; | ||
} | ||
// Wait one second before checking againe | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
} | ||
|
||
if (matchedUser) { | ||
res.status(200).json({ message: 'Match found', data: matchedUser }); | ||
} else { | ||
//await redisDelete(newRequest.userId); // Remove request if no match | ||
res.status(408).json({ message: 'No match found, request timed out' }); | ||
|
||
try { | ||
// Try to add the user to the queue | ||
await addToQueue(userId, topic, difficulty); | ||
res.status(200).json({ message: 'Request successfully added to the queue' }); | ||
// Match user | ||
|
||
} catch (error) { | ||
const err = error as Error; | ||
if (err.name === "UserInQueueError") { | ||
res.status(409).json({ message: 'User is already in the queue' }); | ||
} else if (err.name === "UserInSessionError") { | ||
res.status(409).json({ message: 'User is already in an active session' }); | ||
} else { | ||
console.error("Error in createRequest:", err); | ||
res.status(500).json({ message: 'Failed to add request to the queue due to an unknown error' }); | ||
} | ||
} | ||
}; | ||
/* | ||
import { Request, Response } from 'express'; | ||
import { addToQueue } from '../services/queueManager'; | ||
import ReqObj from '../models/ReqObj'; | ||
// Create a new matching request | ||
export const createRequest = async (req: Request, res: Response): Promise<void> => { | ||
const { userId, topic, difficulty } = req.body; | ||
|
||
// Construct request object | ||
const newRequest: ReqObj = { | ||
userId, | ||
topic, | ||
difficulty, | ||
status: 'pending', | ||
createdAt: new Date(), | ||
}; | ||
console.log("FROM CONTROLLER: USER ID IS" + userId); | ||
console.log("FROM CONTROLLER: TOPIC IS" + topic); | ||
console.log("FROM CONTROLLER: DIFFICULTY IS" + difficulty); | ||
// Add the user to the queue | ||
export const deleteRequest = async (req: Request, res: Response): Promise<void> => { | ||
const userId = req.params.userId as string; // Get userId from URL parameters | ||
|
||
try { | ||
await addToQueue(userId, topic, difficulty); | ||
res.status(201).json({ message: 'Match request created successfully', data: newRequest }); | ||
// Try to remove the user from the queue | ||
console.log("Attempting to remove user from queue"); | ||
await removeFromQueue(userId); | ||
res.status(200).json({ message: 'Request successfully removed from the queue' }); | ||
} catch (error) { | ||
console.error('Error adding to queue:', error); | ||
res.status(500).json({ message: 'Internal Server Error' }); | ||
console.error("Error in deleteRequest:", error); | ||
res.status(500).json({ message: 'Failed to remove request from the queue due to an unknown error' }); | ||
} | ||
}; | ||
*/ | ||
|
||
} | ||
|
||
// API to delete a session | ||
export const deleteSession = async (req: Request, res: Response): Promise<void> => { | ||
const sessionId = req.params.sessionId as string; // Get userId from URL parameters | ||
|
||
try { | ||
// Cancel the timeout and remove session from Redis | ||
await cancelSession(sessionId); | ||
res.status(200).json({ message: 'Session successfully deleted' }); | ||
} catch (error) { | ||
console.error("Error in deleteSession:", error); | ||
res.status(500).json({ message: 'Failed to delete session due to an unknown error' }); | ||
} | ||
}; |
Oops, something went wrong.