My Contributions to Project
For the backend, I essentially made some KNN features for searching for most relevant student. Raymond technically suggested this to me so I implemented somehting similar to that:
Student Controller
package com.nighthawk.spring_portfolio.mvc.search;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/student")
@CrossOrigin(origins = "https://rik-csa.github.io/")
public class StudentController {
private List<Student> students = new ArrayList<>();
public StudentController() {
// Initialize your student list
students.add(new Student("John Kim", Arrays.asList("Math", "Physics"), "Chicago", true));
// Add more sample students here...
}
@PostMapping("/add")
public ResponseEntity<String> addStudent(@RequestBody Student newStudent) {
students.add(newStudent);
return ResponseEntity.ok("Student added successfully");
}
@PostMapping("/findMostRelevant")
public ResponseEntity<Student> findMostRelevantStudent(@RequestBody Student newStudent,
@RequestParam int k) {
Student mostRelevantStudent = KNNStudentSelection.findMostRelevantStudent(students, newStudent, k);
return ResponseEntity.ok(mostRelevantStudent);
}
@GetMapping("/allStudents")
public ResponseEntity<List<Student>> getAllStudents() {
return ResponseEntity.ok(students);
}
}
// Student Class
package com.nighthawk.spring_portfolio.mvc.search;
import java.util.List;
public class Student {
private String name;
private List<String> subjectsKnown;
private String preferredLocation;
private boolean internshipPreferred;
// Constructors (including a no-arg constructor)
public Student() {
}
public Student(String name, List<String> subjectsKnown, String preferredLocation,
boolean internshipPreferred) {
this.name = name;
this.subjectsKnown = subjectsKnown;
this.preferredLocation = preferredLocation;
this.internshipPreferred = internshipPreferred;
}
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getSubjectsKnown() {
return subjectsKnown;
}
public void setSubjectsKnown(List<String> subjectsKnown) {
this.subjectsKnown = subjectsKnown;
}
public String getPreferredLocation() {
return preferredLocation;
}
public void setPreferredLocation(String preferredLocation) {
this.preferredLocation = preferredLocation;
}
public boolean isInternshipPreferred() {
return internshipPreferred;
}
public void setInternshipPreferred(boolean internshipPreferred) {
this.internshipPreferred = internshipPreferred;
}
}
// KNN Finder
package com.nighthawk.spring_portfolio.mvc.search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class KNNStudentSelection {
// KNN algorithm for student selection
public static Student findMostRelevantStudent(List<Student> students, Student newStudent, int k) {
Map<Double, Student> distanceMap = new HashMap<>();
// Calculate Euclidean distance for each student
for (Student student : students) {
double distance = calculateDistance(student, newStudent);
distanceMap.put(distance, student);
}
// Sort distances and get the top k neighbors
List<Double> distances = new ArrayList<>(distanceMap.keySet());
Collections.sort(distances);
// Return the most relevant student
return distanceMap.get(distances.get(0));
}
private static double calculateDistance(Student student1, Student student2) {
// Simple distance calculation based on preferences
double subjectDistance = calculateSubjectDistance(student1.getSubjectsKnown(), student2.getSubjectsKnown());
double locationDistance = student1.getPreferredLocation().equals(student2.getPreferredLocation()) ? 0 : 1;
// Euclidean distance
return Math.sqrt(Math.pow(subjectDistance, 2) + Math.pow(locationDistance, 2));
}
private static double calculateSubjectDistance(List<String> subjects1, List<String> subjects2) {
// Jaccard similarity for subject distance
List<String> union = new ArrayList<>(subjects1);
union.addAll(subjects2);
List<String> intersection = new ArrayList<>(subjects1);
intersection.retainAll(subjects2);
return 1 - ((double) intersection.size() / union.size());
}
}
Frontend:
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1, h2 {
margin-bottom: 10px;
}
form {
margin-bottom: 20px;
}
label {
display: inline-block;
width: 150px;
margin-bottom: 5px;
}
input[type="text"], input[type="number"] {
width: 300px;
padding: 5px;
}
button {
padding: 8px 15px;
cursor: pointer;
}
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Selection</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Student Selection</h1>
<h2>Add New Student</h2>
<form id="addStudentForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="subjects">Subjects Known (comma-separated):</label>
<input type="text" id="subjects" name="subjects" required><br><br>
<label for="location">Preferred Location:</label>
<input type="text" id="location" name="location" required><br><br>
<label for="internship">Internship Preferred:</label>
<input type="checkbox" id="internship" name="internship"><br><br>
<button type="submit">Add Student</button>
</form>
<h2>Find Most Relevant Student</h2>
<form id="findStudentForm">
<label for="newStudent">New Student Information:</label><br>
<input type="text" id="newStudent" name="newStudent" placeholder="Enter name, subjects, location, internship preference"><br><br>
<label for="k">Number of Neighbors (k):</label>
<input type="number" id="k" name="k" min="1" value="1"><br><br>
<button type="submit">Find Most Relevant Student</button>
</form>
<div id="result"></div>
</body>
</html>
<script>
document.getElementById('addStudentForm').addEventListener('submit', addStudent);
document.getElementById('findStudentForm').addEventListener('submit', findMostRelevantStudent);
function addStudent(event) {
event.preventDefault();
const formData = new FormData(event.target);
const studentData = {
name: formData.get('name'),
subjectsKnown: formData.get('subjects').split(',').map(subject => subject.trim()),
preferredLocation: formData.get('location'),
internshipPreferred: formData.get('internship') === 'on'
};
fetch('http://localhost:4100/api/student/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(studentData),
})
.then(response => response.text())
.then(message => alert(message))
.catch(error => console.error('Error:', error));
}
function findMostRelevantStudent(event) {
event.preventDefault();
const formData = new FormData(event.target);
const newStudentInfo = formData.get('newStudent').split(',').map(info => info.trim());
const newStudent = {
name: newStudentInfo[0],
subjectsKnown: newStudentInfo[1].split(',').map(subject => subject.trim()),
preferredLocation: newStudentInfo[2],
internshipPreferred: newStudentInfo[3] === 'true' || newStudentInfo[3] === '1' || newStudentInfo[3] === 'on'
};
const k = formData.get('k');
fetch(`http://localhost:4100/api/student/findMostRelevant?k=${k}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newStudent),
})
.then(response => response.json())
.then(data => {
document.getElementById('result').innerText = `Most relevant student: ${data.name}`;
})
.catch(error => console.error('Error:', error));
}
</script>