diff --git a/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 1.png b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 1.png new file mode 100644 index 0000000..bb251dc Binary files /dev/null and b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 1.png differ diff --git a/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 2.png b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 2.png new file mode 100644 index 0000000..b6a8511 Binary files /dev/null and b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 2.png differ diff --git a/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 3.png b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 3.png new file mode 100644 index 0000000..48b7390 Binary files /dev/null and b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 3.png differ diff --git a/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 4.png b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 4.png new file mode 100644 index 0000000..2638c58 Binary files /dev/null and b/INFO-1208 (PHP)/Labs/Lab 7/Screenshot 4.png differ diff --git a/INFO-1208 (PHP)/Labs/Lab 7/arrays.php b/INFO-1208 (PHP)/Labs/Lab 7/arrays.php new file mode 100644 index 0000000..ef2f947 --- /dev/null +++ b/INFO-1208 (PHP)/Labs/Lab 7/arrays.php @@ -0,0 +1,103 @@ + + + + + PHP Lab 7 + + + + +

Months of the Year

+ "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ]; + + print_r($months); + + echo "

"; + + $months[13] = "Winter"; + $months[14] = "Construction"; + + foreach ($months as $type => $value) { + echo "The month of $value is month number $type
"; + } + ?> + +

Pizza Toppings

+ + $vegetables, + "Meats" => $meats, + "Cheeses" => $cheeses + ]; + + foreach ($toppings as $type => $value) { + echo "$type: "; + if (is_array($value)) { + foreach ($value as $number => $topping) { + echo "$topping, "; + } + } else { + echo "$type is $value
"; + } + echo "
"; + }; + + echo "
"; + + $prices = [ + "Small" => 6.99, + "Medium" => 8.99, + "Large" => 13.99, + "X-Large" => 18.99, + "Supersize" => 22.99 + ]; + + asort($prices); + + foreach ($prices as $type => $value) { + echo "$type: $value
"; + }; + + echo "
"; + + ksort($prices); + + foreach ($prices as $type => $value) { + echo "$type: $value
"; + }; + ?> + + + \ No newline at end of file diff --git a/INFO-1208 (PHP)/Labs/Lab 7/info1208-lab7-l_mclean215318.zip b/INFO-1208 (PHP)/Labs/Lab 7/info1208-lab7-l_mclean215318.zip new file mode 100644 index 0000000..b842606 Binary files /dev/null and b/INFO-1208 (PHP)/Labs/Lab 7/info1208-lab7-l_mclean215318.zip differ diff --git a/INFO-1208 (PHP)/Notes/form.php b/INFO-1208 (PHP)/Notes/form.php new file mode 100644 index 0000000..1f8d6c0 --- /dev/null +++ b/INFO-1208 (PHP)/Notes/form.php @@ -0,0 +1,59 @@ + +

This is a header!

+ + +

This is still a header!

+ +
+ + + +

+ + + + +

+ + + + +

+ + + + +

+ + + + +

+ + + +

+ + + + +

+ + + +
+ +world!'; +echo $text; +echo strip_tags($text); \ No newline at end of file diff --git a/INFO-1208 (PHP)/Notes/week2.php b/INFO-1208 (PHP)/Notes/week_2_in_class.php similarity index 100% rename from INFO-1208 (PHP)/Notes/week2.php rename to INFO-1208 (PHP)/Notes/week_2_in_class.php diff --git a/INFO-1208 (PHP)/Notes/week_4_in_class.php b/INFO-1208 (PHP)/Notes/week_4_in_class.php new file mode 100644 index 0000000..b6a9b29 --- /dev/null +++ b/INFO-1208 (PHP)/Notes/week_4_in_class.php @@ -0,0 +1,64 @@ +'; +echo "123" + 1; +echo '
'; +echo "123" + "1"; +echo '

'; + +// Arithmetic operators. +echo 'Arithmetic operators
'; +echo 'Addition (+) ' . 1 + 2 . '
'; +echo 'Subtraction (-) ' . 2 - 1 . '
'; +echo 'Multiplication (*) ' . 2 * 2 . '
'; +echo 'Division (/) ' . 4 / 2 . '
'; +echo 'Modulus (%) ' . 4 % 2 . '
'; +$a = 1; +$a++; +echo 'Increment (++) ' . $a . '
'; +$a--; +echo 'Decrement (--) ' . $a . '
'; +echo '
'; + +// Assignment operators. +echo 'Assignment operators
'; +$a = 2; +echo $a . '
'; +$a += 2; +echo $a . '
'; +$a -= 2; +echo $a . '
'; +$a *= 2; +echo $a . '
'; +$a /= 2; +echo $a . '
'; +echo '
'; + +// Comparison operators. +echo 'Comparison operators
'; +$a = 1; +$b = 2; +$c = '2'; + +echo ($a < $b) . '
'; +echo ($a > $b) . '
'; +echo ($a == $b) . '
'; +echo ($a != $b) . '
'; +echo ($b == $c) . '
'; +echo ($b === $c) . '
'; +echo '
'; + +// Formatting numbers. +echo 'Formatting numbers
'; + +echo 'Round (2.49): ' . round(2.49) . '
'; +echo 'Number Format (21233122):' . number_format(21233122) . '
'; +echo 'Printf: '; +$sub = 5; +$tax = 0.65; +printf('The subtotal is %u, making the tax +%.2f.', $sub, $tax); +echo '
'; +echo 'Mt Rand: ' . mt_rand(0, 100); \ No newline at end of file diff --git a/INFO-1208 (PHP)/Notes/week_6_in_class.php b/INFO-1208 (PHP)/Notes/week_6_in_class.php new file mode 100644 index 0000000..fb72af7 --- /dev/null +++ b/INFO-1208 (PHP)/Notes/week_6_in_class.php @@ -0,0 +1,133 @@ +
'; + +// Using the concatenation assignment operator (.=) +$string1 = 'Hello'; +$string2 = 'World'; +$string1 .= ' ' . $string2; +echo $string1; +echo '

'; + +// Using double quotes (") to directly concatenate variables within a string +$string1 = 'Hello'; +$string2 = 'World'; +$concatenation = "$string1 $string2"; +echo $concatenation; +echo '

'; + +/* Newlines */ + +// Using the "\n" escape sequence +echo "Line 1\nLine 2\nLine 3"; +echo '

'; + +// Using double quotes (") +echo "Line 1 +Line 2 +Line 3"; +echo '

'; + +// Using PHP_EOL constant, which represents the correct end-of-line character +echo "Line 1" . PHP_EOL . "Line 2" . PHP_EOL . "Line 3"; +echo '

'; + +// Using the nl2br() function to insert HTML line breaks (\n) before all newlines in a string +$text = "Line 1\nLine 2\nLine 3"; +echo nl2br($text); +echo '

'; + +/* Handling HTML String Input */ + +// htmlspecialchars() +$string = "Test & 'Example'"; +$safe_string = htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); +echo $safe_string; +echo '

'; + +// htmlentities() +$string = "Test & 'Example'"; +$safe_string = htmlentities($string, ENT_QUOTES, 'UTF-8'); +echo $safe_string; +echo '

'; + +/* Encoding and Decoding */ + +// Encode +$url = urlencode("https://fanshawec.ca?programs=iwd&cpa"); +echo $url; +echo '

'; + +// Decode +$url = urldecode("https%3A%2F%2Ffanshawec.ca%3Fprograms%3Diwd%26cpa"); +echo $url; +echo '

'; + +/* Adjusting strings */ + +// substr() +$string = "You are a wizard, Harry."; +$substr = substr($string, 9, 6); +echo $substr; +echo '

'; + +// strtok() +$string = "Luke, I am your father."; +$substr = strtok($string, ","); +echo $substr; +echo '

'; + +// strlen() +$string = "May the odds be ever in your favour."; +$length = strlen($string); +echo $length; +echo '

'; + +// Uppercase / Lowercase +$string = "hello world"; +echo ucfirst($string); +echo '

'; +echo ucwords($string); +echo '

'; +echo strtoupper($string); +echo '

'; +echo strtolower('HELLO WORLD'); +echo '

'; + +/* Replacing Strings */ + +// str_replace() +$search = 'world'; +$replace = 'everyone'; +$subject = 'Hello world!'; +echo str_replace($search, $replace, $subject); +echo '

'; + +// str_ireplace() +$search = 'WORLD'; +$replace = 'everyone'; +$subject = 'Hello world!'; +echo str_ireplace($search, $replace, $subject); +echo '

'; + +// trim() +$string = " hello world "; +echo trim($string); +echo '

'; + +// rtrim() +$string = "hello world!!!"; +echo rtrim($string, '!'); +echo '

'; + +$string = " hello world"; +echo ltrim($string); +echo '

'; + diff --git a/INFO-1208 (PHP)/Notes/week_7_in_class.php b/INFO-1208 (PHP)/Notes/week_7_in_class.php new file mode 100644 index 0000000..5b44afe --- /dev/null +++ b/INFO-1208 (PHP)/Notes/week_7_in_class.php @@ -0,0 +1,201 @@ += 18) ? 'Yes' : 'No' + +// Alternatively, you could write the above like this, but the above saves lines of code. +if ($age >= 18) { + $can_vote = 'Yes'; +} +else { + $can_vote = 'No'; +} + +// ----------------------------- +// Switch statements +// ----------------------------- + +// E.g. +switch ($isOlympicYear) { + case 2023: + break; // Without a break, the code will continue executing to the next case. + + case 2024: + break; + + case 2025: + break; + + default: // Default is the equivalent to an ELSE + break; +} + +// Using a switch like above instead of the following +if ($year === 2023) { + // +} +elseif ($year === 2024) { + // +} +elseif ($year === 2025) { + // +} + +// ----------------------------- +// For loops +// ----------------------------- + +// E.g. +for ($i = 1; $i < 5; $i++) { + echo "This is the $i -th iteration."; +} + +// ----------------------------- +// While loops +// ----------------------------- + +// E.g. +$i = 1; +while ($i < 5) { + echo "This is the $i -th iteration."; + $i++; +} + +// ----------------------------- +// Passing Arguments by Reference +// ----------------------------- + +function add_five(&$value) { + $value += 5; +} + +$num = 2; +add_five($num); +echo $num; // Outputs: 7 + +// ----------------------------- +// Using the ... operator +// - Allows for any number of arguments +// ----------------------------- + +function sum(...$numbers) { + $sum = 0; + + for ($i = 0; $i < count($numbers); $i++) { + $sum += $numbers[$i]; + } + + return $sum; +} + +echo sum(1, 2, 3, 4); // Output: 10 + \ No newline at end of file diff --git a/INFO-1208 (PHP)/Notes/week_8_in_class.php b/INFO-1208 (PHP)/Notes/week_8_in_class.php new file mode 100644 index 0000000..12cc005 --- /dev/null +++ b/INFO-1208 (PHP)/Notes/week_8_in_class.php @@ -0,0 +1,194 @@ +'; +print_r($months); +echo ''; + +// Getting value from index +echo '
';
+print_r($months[1]);
+echo '
'; + +// Short hand +$months = [ + 'January', // Index = 0 + 'February', // Index = 1 + 'March', // Index = 2 +]; + +/* Associative Arrays */ + +$months = [ + 'month1' => 'January', + 'month2' => 'February', + 'month3' => 'March' +]; +echo '
';
+print_r($months);
+echo '
'; +echo '
';
+print_r($months['month1']);
+echo '
'; + +/* Working with Arrays */ + +// range() +$numbers = range(1, 10); // Same as $numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +echo '
';
+print_r($numbers);
+echo '
'; + +$numbers = range(1, 10, 2); // Same as $numbers = [1, 3, 5, 7, 9]; +echo '
';
+print_r($numbers);
+echo '
'; + +// Adding to arrays +$months = [ + 'January', // Index = 0 + 'February', // Index = 1 + 'March', // Index = 2 +]; +// Add to index 3 +$months[3] = 'April'; +// Change index 2 +$months[2] = 'May'; +// Add to end of array +$months[] = 'June'; +echo '
';
+print_r($months);
+echo '
'; + +/* Merging Arrays */ +$sem1grades = [ + 'math' => 90, + 'chemistry' => 67, + 'biology' => 88, + 'history' => 45, + 'gym' => 60, +]; +$sem2grades = [ + 'philosophy' => 87, + 'art' => 99, + 'physics' => 71, + 'gym' => 60, +]; + +// array_merge() +$allGrades = array_merge($sem1grades, $sem2grades); +echo '
';
+print_r($allGrades);
+echo '
'; + +// Array Union +$allGrades = $sem1grades + $sem2grades; +echo '
';
+print_r($allGrades);
+echo '
'; + +/* Multidimensional arrays */ +$meats = [ + 'Pepperoni', + 'Bacon', + 'Ham', +]; +$cheeses = [ + 'Mozzarella', + 'Cheddar', + 'Swiss', +]; +$veggies = [ + 'Onions', + 'Peppers', + 'Mushrooms', +]; +$toppings = [ + 'Meats' => $meats, + 'Cheeses' => $cheeses, + 'Veggies' => $veggies, + 'Size' => 'Medium', +]; +echo $toppings['Veggies'][1]; +echo '

'; + +/* Printing Arrays */ + +// foreach() +foreach ($toppings as $type => $value) { + echo "{$type}:
"; + if (is_array($value)) { + foreach ($value as $number => $topping) { + echo "Topping #{$number} is $topping
"; + } + } + else { + echo "{$type} is $value
"; + } + echo "
"; +} + +$words = [ + 'The', + 'cow', + 'jumped', + 'over', + 'the', + 'moon', +]; +// implode() +$sentence = implode(' ', $words); +echo $sentence; +echo '

'; +// explode() +$words2 = explode(' ', $sentence); +echo $words2; +echo '

'; + +/* Sorting Arrays */ + +$array1 = [ + 3, + 1, + 4, + 1, + 5, + 9, +]; +// sort() +sort($array1); +echo '
';
+print_r($array1);
+echo '
'; +// rsort() +rsort($array1); +echo '
';
+print_r($array1);
+echo '
'; + +$assocArray = [ + 'a' => 3, + 'b' => 1, + 'c' => 4, +]; +// asort() +asort($assocArray); +echo '
';
+print_r($assocArray);
+echo '
'; +$assocArray = [ + 'a' => 3, + 'b' => 1, + 'c' => 4, +]; +// ksort() +ksort($assocArray); +echo '
';
+print_r($assocArray);
+echo '
'; diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/.vscode/launch.json b/INFO-3168 (JS 2)/Labs/Lab 3/.vscode/launch.json new file mode 100644 index 0000000..8ccc8f6 --- /dev/null +++ b/INFO-3168 (JS 2)/Labs/Lab 3/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome with Live Server", + "url": "http://127.0.0.1:5500/index.html", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/analytics.js b/INFO-3168 (JS 2)/Labs/Lab 3/analytics.js index e107019..7d233af 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/analytics.js +++ b/INFO-3168 (JS 2)/Labs/Lab 3/analytics.js @@ -14,20 +14,73 @@ export function getPassingStudents(students, passMark = 70) { return passingStudents; } -function calculateCourseAverages(students) { - +export function calculateCourseAverages(students) { + const groupedCourses = students.reduce((accumulator, { course, grade }) => { + if (!accumulator[course]) { + accumulator[course] = { total: 0, count: 0 }; + } + + accumulator[course].total += Number(grade); + accumulator[course].count += 1; + + return accumulator; + }, {}); + + return Object.entries(groupedCourses).reduce((accumulator, [course, values]) => { + accumulator[course] = values.count === 0 ? 0 : values.total / values.count; + return accumulator; + }, {}); } -function getTopPerCourse(students) { +export function getTopPerCourse(students) { + const topStudentsByCourse = students.reduce((accumulator, student) => { + const currentTopStudent = accumulator[student.course]; + if (!currentTopStudent || student.grade > currentTopStudent.grade) { + accumulator[student.course] = student; + } + + return accumulator; + }, {}); + + return Object.values(topStudentsByCourse); } -function calculateOverallStatistics(students) { - const summary = document.getElementById("summary"); - summary.innerHTML += `

Total Students: ${students.length}


-

Average Grade:


-

Highest Grade:


-

Lowest Grade:


-

Average Attendance: %


-

Unique Courses:


`; +export function calculateOverallStatistics(students) { + if (students.length === 0) { + return { + totalStudents: 0, + averageGrade: 0, + highestGrade: 0, + lowestGrade: 0, + averageAttendance: 0 + }; + } + + const totals = students.reduce((accumulator, { grade, attendance }) => { + const numericGrade = Number(grade); + const numericAttendance = Number(attendance); + + accumulator.totalStudents += 1; + accumulator.gradeTotal += numericGrade; + accumulator.attendanceTotal += numericAttendance; + accumulator.highestGrade = Math.max(accumulator.highestGrade, numericGrade); + accumulator.lowestGrade = Math.min(accumulator.lowestGrade, numericGrade); + + return accumulator; + }, { + totalStudents: 0, + gradeTotal: 0, + attendanceTotal: 0, + highestGrade: -Infinity, + lowestGrade: Infinity + }); + + return { + totalStudents: totals.totalStudents, + averageGrade: totals.gradeTotal / totals.totalStudents, + highestGrade: totals.highestGrade, + lowestGrade: totals.lowestGrade, + averageAttendance: totals.attendanceTotal / totals.totalStudents + }; } \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/index.html b/INFO-3168 (JS 2)/Labs/Lab 3/index.html index 0056b91..b18970b 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/index.html +++ b/INFO-3168 (JS 2)/Labs/Lab 3/index.html @@ -9,9 +9,9 @@

Student Performance Analytics Dashboard

- - - + + + @@ -31,10 +31,5 @@

Summary

- - - - - \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/main.js b/INFO-3168 (JS 2)/Labs/Lab 3/main.js index e69de29..4710fb9 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/main.js +++ b/INFO-3168 (JS 2)/Labs/Lab 3/main.js @@ -0,0 +1,35 @@ +import { students } from "./data.js"; +import { calculateOverallStatistics } from "./analytics.js"; +import { getTopThree, uniqueCourses } from "./utils.js"; +import { renderTable, renderSummary } from "./ui.js"; +import { toggleTheme, loadTheme } from "./theme.js"; + +let filteredStudents = [...students]; + +const nameSearchInput = document.getElementById("nameSearch"); +const minGradeInput = document.getElementById("minimumGrade"); +const minGradeValue = document.getElementById("gradeValue"); + +const applyFilters = () => { + const nameFilter = nameSearchInput.value.toLowerCase(); + const minGrade = parseInt(minGradeInput.value); + + filteredStudents = students.filter((student) => student.name.toLowerCase().includes(nameFilter) && student.grade >= minGrade); + + const topThree = getTopThree(filteredStudents); + renderTable(filteredStudents, topThree); + + const stats = calculateOverallStatistics(filteredStudents); + renderSummary(stats, uniqueCourses(filteredStudents).length); +}; + +nameSearchInput.addEventListener("input", applyFilters); +minGradeInput.addEventListener("input", () => { + minGradeValue.textContent = minGradeInput.value; + applyFilters(); +}); + +document.getElementById("themeToggle").addEventListener("click", toggleTheme); + +loadTheme(); +applyFilters(); \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/style.css b/INFO-3168 (JS 2)/Labs/Lab 3/style.css index e1c0208..a04bbbe 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/style.css +++ b/INFO-3168 (JS 2)/Labs/Lab 3/style.css @@ -19,4 +19,58 @@ table td, table th { table th { background-color: #f0f0f0; +} + +button { + padding: 8px 12px; + margin: 10px 0; + cursor: pointer; +} + +.gold { + background-color: gold; +} + +.silver { + background-color: silver; +} + +.bronze { + background-color: #cd7f32; +} + +.dark { + background-color: #1f1f1f; + color: white; +} + +.dark table { + background-color: #2b2b2b; + color: white; + border-color: white; +} + +.dark table td, +.dark table th { + border-color: white; +} + +.dark table th { + background-color: #444; +} + +.dark button { + background-color: #444; + color: white; + border: 1px solid white; +} + +.dark input { + background-color: #333; + color: white; + border: 1px solid white; +} + +.dark #summary { + color: white; } \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/theme.js b/INFO-3168 (JS 2)/Labs/Lab 3/theme.js index e69de29..6a5465d 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/theme.js +++ b/INFO-3168 (JS 2)/Labs/Lab 3/theme.js @@ -0,0 +1,17 @@ +export function loadTheme() { + const savedTheme = localStorage.getItem("theme"); + + if (savedTheme === "dark") { + document.body.classList.add("dark"); + } +} + +export function toggleTheme() { + document.body.classList.toggle("dark"); + + if (document.body.classList.contains("dark")) { + localStorage.setItem("theme", "dark"); + } else { + localStorage.setItem("theme", "light"); + } +} \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/ui.js b/INFO-3168 (JS 2)/Labs/Lab 3/ui.js index 67ad3b4..f599214 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/ui.js +++ b/INFO-3168 (JS 2)/Labs/Lab 3/ui.js @@ -6,22 +6,46 @@ const passingStudents = getPassingStudents(students); const passingIds = passingStudents.map(student => student.id); const tableBody = document.getElementById("studentTableBody"); -students.forEach(student => { - const row = document.createElement("tr"); - const name = document.createElement("td"); - name.textContent = student.name ?? "-"; - const course = document.createElement("td"); - course.textContent = student.course ?? "-"; - const grade = document.createElement("td"); - grade.textContent = student.grade ?? "-"; - const attendance = document.createElement("td"); - attendance.textContent = student.attendance + "%" ?? "-"; - const assignmentAvg = document.createElement("td"); - assignmentAvg.textContent = calculateAssignmentAverage(student); - const status = document.createElement("td"); - status.textContent = passingIds.includes(student.id) ? "Pass" : "Fail"; - const city = document.createElement("td"); - city.textContent = student.address.city ?? "-"; - row.append(name, course, grade, attendance, assignmentAvg, status, city); - tableBody.appendChild(row); -}); \ No newline at end of file +export function renderTable(students, topThree) { + tableBody.innerHTML = ""; + students.forEach(student => { + const row = document.createElement("tr"); + + if (topThree[0] && student.id === topThree[0].id) { + row.classList.add("gold"); + } else if (topThree[1] && student.id === topThree[1].id) { + row.classList.add("silver"); + } else if (topThree[2] && student.id === topThree[2].id) { + row.classList.add("bronze"); + } + + const name = document.createElement("td"); + name.textContent = student.name ?? "-"; + const course = document.createElement("td"); + course.textContent = student.course ?? "-"; + const grade = document.createElement("td"); + grade.textContent = student.grade ?? "-"; + const attendance = document.createElement("td"); + attendance.textContent = student.attendance + "%" ?? "-"; + const assignmentAvg = document.createElement("td"); + assignmentAvg.textContent = calculateAssignmentAverage(...student.assignments); + const status = document.createElement("td"); + status.textContent = passingIds.includes(student.id) ? "Pass" : "Fail"; + const city = document.createElement("td"); + city.textContent = student.address.city ?? "-"; + row.append(name, course, grade, attendance, assignmentAvg, status, city); + tableBody.appendChild(row); + }) +} + +export function renderSummary(stats, uniqueCourseCount) { + const summary = document.getElementById("summary"); + summary.innerHTML = ""; + summary.innerHTML += `

Summary

+

Total Students: ${stats.totalStudents}

+

Average Grade: ${stats.averageGrade.toFixed(2)}

+

Highest Grade: ${stats.highestGrade}

+

Lowest Grade: ${stats.lowestGrade}

+

Average Attendance: ${stats.averageAttendance.toFixed(2)}%

+

Unique Courses: ${uniqueCourseCount}

`; +} \ No newline at end of file diff --git a/INFO-3168 (JS 2)/Labs/Lab 3/utils.js b/INFO-3168 (JS 2)/Labs/Lab 3/utils.js index c4a6dcc..28eb31d 100644 --- a/INFO-3168 (JS 2)/Labs/Lab 3/utils.js +++ b/INFO-3168 (JS 2)/Labs/Lab 3/utils.js @@ -1,7 +1,17 @@ -export function calculateAssignmentAverage(student) { - if (!student.assignments || student.assignments.length === 0) { - return false; +export function calculateAssignmentAverage(...grades) { + if (grades.length === 0) { + return 0; } - const total = student.assignments.reduce((sum, score) => sum + score, 0); - return total / student.assignments.length; + + const total = grades.reduce((sum, score) => sum + score, 0); + return total / grades.length; +} + +export function getTopThree(students) { + const sorted = [...students].sort((a, b) => b.grade - a.grade); + return sorted.slice(0, 3); +} + +export function uniqueCourses(students) { + return [...new Set(students.map(({ course }) => course))]; } \ No newline at end of file