CLO Analysis Report
body {
font-family: Arial, sans-serif;
}
.container {
margin-top: 20px;
}
table {
width: 100%;
margin-top: 20px;
}
th, td {
text-align: center;
vertical-align: middle;
}
.table-section {
margin-top: 40px;
}
CLO Analysis Report
Course Details
Course Code:Course Name:
Programme:
Lecturer Name:
Semester:
Total Students:
% of Students Achieving the Benchmark for Each CLO
Learning Outcome
Benchmark
% Achieved
Remark
% of Students Achieving the Total Learning Outcomes
Total LOs
Number of Students Achieved
% Achieved
CLO Performance Data
Student Name
Student ID
CLO1
CLO2
CLO3
CLO4
CLO5
CLO6
Total CLO
U
P
OK
let studentData;
document.addEventListener("DOMContentLoaded", function () {
studentData = JSON.parse(localStorage.getItem("studentData"));
console.log("Student Data:", studentData);
const moduleData = JSON.parse(localStorage.getItem("moduleData"));
if (!studentData || studentData.length === 0) {
console.error("No student data found in localStorage.");
return;
}
if (!studentData || studentData.length === 0 || !moduleData || !moduleData.courseworkRows) {
alert("Missing data! Please return to the main or student page to input the required data.");
return;
}
// Populate Course Details
document.getElementById("courseCode").textContent = moduleData.courseCode;
document.getElementById("courseName").textContent = moduleData.courseName;
document.getElementById("programme").textContent = moduleData.programme;
document.getElementById("lecturerName").textContent = moduleData.lecturerName;
document.getElementById("semester").textContent = moduleData.semester;
document.getElementById("totalStudents").textContent = moduleData.totalStudents;
// Populate hidden inputs
document.getElementById("hiddenCourseCode").value = moduleData.courseCode || "";
document.getElementById("hiddenCourseName").value = moduleData.courseName || "";
document.getElementById("hiddenProgramme").value = moduleData.programme || "";
document.getElementById("hiddenLecturerName").value = moduleData.lecturerName || "";
document.getElementById("hiddenSemester").value = moduleData.semester || "";
console.log("Raw Coursework Weight:", moduleData.courseworkWeight);
console.log("Raw Exam Weight:", moduleData.examWeight);
const courseworkWeight = parseFloat(moduleData.courseworkWeight || "0") / 100;
const examWeight = parseFloat(moduleData.examWeight || "0") / 100;
const totalCLOs = 6; // Fixed number of CLOs (CLO1 to CLO6)
if (courseworkWeight === 0 || examWeight === 0) {
console.error("Weights are zero or missing. Check moduleData:", moduleData);
alert("Error: Coursework or exam weights are missing or invalid. Please check your inputs.");
return;
}
console.log("Student Data:", studentData);
console.log("Module Data:", moduleData);
console.log("Coursework Weight:", courseworkWeight);
console.log("Exam Weight:", examWeight);
const cloBenchmarks = calculateCLOBenchmarks(studentData, moduleData, courseworkWeight, examWeight, totalCLOs);
const loBenchmarks = calculateLOBenchmarks(studentData, totalCLOs);
console.log("CLO Benchmarks:", cloBenchmarks);
console.log("LO Benchmarks:", loBenchmarks);
populateCLOBenchmarkTable(cloBenchmarks, studentData.length);
populateLOBenchmarkTable(loBenchmarks, studentData.length);
populateCLODataTable(studentData, totalCLOs);
});
function calculateCLOBenchmarks(studentData, moduleData, courseworkWeight, examWeight, totalCLOs) {
const cloBenchmarks = Array(totalCLOs).fill(0).map(() => ({ total: 0, achieved: 0 }));
studentData.forEach(student => {
console.log("Processing student:", student);
// Process Coursework
student.coursework.forEach((score, index) => {
const cwRow = moduleData.courseworkRows[index];
if (cwRow && cwRow.clos) { // Ensure cwRow and cwRow.clos exist
cwRow.clos.forEach(clo => {
const cloIndex = parseInt(clo.lo.replace("LO", "")) - 1;
const weightedScore = (score * courseworkWeight * clo.percent) / 100;
cloBenchmarks[cloIndex].total += weightedScore;
});
}
});
// Process Final Exam
student.finalExam.forEach((score, index) => {
const feRow = moduleData.finalExamRows[index];
if (feRow && feRow.clos) { // Ensure feRow and feRow.clos exist
feRow.clos.forEach(clo => {
const cloIndex = parseInt(clo.lo.replace("LO", "")) - 1;
const weightedScore = (score * examWeight * clo.percent) / 100;
cloBenchmarks[cloIndex].total += weightedScore;
});
}
});
// Check if benchmarks are achieved for each CLO
cloBenchmarks.forEach((clo, index) => {
const totalScore = student.coursework[index] + student.finalExam[index];
console.log(`CLO${index + 1} - Total Score for Student:`, totalScore);
if (totalScore >= 50) {
clo.achieved++;
console.log(`CLO${index + 1} - Benchmark Achieved`);
}
});
});
return cloBenchmarks;
}
function calculateLOBenchmarks(studentData, totalCLOs) {
const loBenchmarks = Array(totalCLOs).fill(0);
studentData.forEach(student => {
const totalLOScores = Array(totalCLOs).fill(0);
student.coursework.forEach(score => {
totalLOScores[0] += score;
});
student.finalExam.forEach(score => {
totalLOScores[1] += score;
});
console.log("Total LO Scores for Student:", totalLOScores);
const achievedLOCount = totalLOScores.filter(score => score >= 50).length;
loBenchmarks[achievedLOCount - 1]++;
console.log("Achieved LO Count for Student:", achievedLOCount);
});
return loBenchmarks;
}
function populateCLOBenchmarkTable(cloBenchmarks, totalStudents) {
const cloBenchmarkTable = document.getElementById("clo-benchmark-table").querySelector("tbody");
cloBenchmarks.forEach((clo, index) => {
const percentAchieved = clo.total ? ((clo.achieved / totalStudents) * 100).toFixed(2) : 0;
const remark = percentAchieved >= 50 ? "Achieved" : "Review Needed";
cloBenchmarkTable.innerHTML += `
CLO${index + 1}
${(clo.total / totalStudents).toFixed(2)}
${percentAchieved}%
${remark}
`;
});
}
function populateLOBenchmarkTable(loBenchmarks, totalStudents) {
const loBenchmarkTable = document.getElementById("lo-benchmark-table").querySelector("tbody");
loBenchmarks.forEach((count, index) => {
const percentAchieved = ((count / totalStudents) * 100).toFixed(2);
loBenchmarkTable.innerHTML += `
${index + 1} LOs
${count}
${percentAchieved}%
`;
});
loBenchmarkTable.innerHTML += `
Total
${totalStudents}
100%
`;
}
function populateCLODataTable(studentData, totalCLOs) {
const tableBody = document.getElementById("cloDataTable");
studentData.forEach((student, idx) => {
const row = document.createElement("tr");
row.innerHTML = `
${student.name || `Student ${idx + 1}`}
`;
for (let i = 0; i < totalCLOs; i++) {
row.innerHTML += `${i < student.coursework.length && student.coursework >= 50 ? "Achieved" : "No"}`;
}
tableBody.appendChild(row);
});
}
// Populate CLO Performance Table
const cloTable = document.getElementById("cloDataTable");
studentData.forEach((student, index) => {
const row = document.createElement("tr");
row.innerHTML = `
${student.name || `Student ${index + 1}`}
${student.coursework[0] >= 50 ? "Achieved" : "No"}
${student.coursework[1] ? (student.coursework[1] >= 50 ? "Achieved" : "No") : "NA"}
${student.finalExam[0] >= 50 ? "Achieved" : "No"}
${student.finalExam[1] ? (student.finalExam[1] >= 50 ? "Achieved" : "No") : "NA"}
NA
NA
${student.coursework.filter(m => m >= 50).length + student.finalExam.filter(m => m >= 50).length}
${student.coursework[0] >= 50 || student.finalExam[0] >= 50 ? "Achieved" : "No"}
${student.coursework[1] >= 50 || student.finalExam[1] >= 50 ? "Achieved" : "No"}
`;
cloTable.appendChild(row);
});
document.getElementById("okButton").addEventListener("click", function () {
const tableRows = document.querySelectorAll("#cloDataTable tr");
const cloData = [];
tableRows.forEach(row => {
// Extract Student ID
const studentId = row.querySelector("input[name='student_ids[]']")?.value.trim() || "";
// Extract CLO1-CLO6 (columns 3 to 8)
const cloCells = Array.from(row.querySelectorAll("td")).slice(2, 8); // CLO1=td[2], CLO6=td[7]
const cloResults = cloCells.map(cell => cell.textContent.trim());
// Extract Total CLO (column 9)
const totalClo = row.cells[8]?.textContent.trim() || "0";
cloData.push({
student_id: studentId,
clo1: cloResults[0] || "No",
clo2: cloResults[1] || "No",
clo3: cloResults[2] || "No",
clo4: cloResults[3] || "No",
clo5: cloResults[4] || "No",
clo6: cloResults[5] || "No",
total_clo: totalClo
});
});
// Append CLO data to the form
const form = document.getElementById("submitCLOForm");
const cloDataField = document.createElement("input");
cloDataField.type = "hidden";
cloDataField.name = "clo_data";
cloDataField.value = JSON.stringify(cloData);
form.appendChild(cloDataField);
form.submit();
});
// Function to create hidden input fields
function createHiddenField(name, value) {
const input = document.createElement("input");
input.type = "hidden";
input.name = name;
input.value = value;
return input;
}
< /code>
Код PHP для вставки данных < /p>
< /code>
sql table < /p>
CREATE TABLE clo_performance (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id VARCHAR(50) NOT NULL,
course_code VARCHAR(50) NOT NULL,
course_name VARCHAR(255) NOT NULL,
programme VARCHAR(50) NOT NULL,
lecturer_name VARCHAR(255) NOT NULL,
semester VARCHAR(50) NOT NULL,
clo1 VARCHAR(20),
clo2 VARCHAR(20),
clo3 VARCHAR(20),
clo4 VARCHAR(20),
clo5 VARCHAR(20),
clo6 VARCHAR(20),
total_clo INT,
domain_u VARCHAR(20),
domain_p VARCHAR(20)
);
< /code>
Я ожидал, что они вставит данные в таблицу SQL, и все, что я получил, - это «нет данных CLO», и данные не были вставлены. src = "https://i.sstatic.net/vuvxkyth.png"/>
Подробнее здесь: https://stackoverflow.com/questions/794 ... -sql-table