From 11e30f5fccbd7900ee868dc9fadf058fa334db78 Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Thu, 6 Nov 2025 18:05:48 +0000 Subject: [PATCH 1/6] Add initial implementation of mean calculation and tests --- prep/mean.js | 37 +++++++++++++++++++++++++++++++++++++ prep/mean.test.js | 12 ++++++++++++ prep/package.json | 16 ++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 prep/mean.js create mode 100644 prep/mean.test.js create mode 100644 prep/package.json diff --git a/prep/mean.js b/prep/mean.js new file mode 100644 index 000000000..c378b7b73 --- /dev/null +++ b/prep/mean.js @@ -0,0 +1,37 @@ +/* +Let’s consider a list of prices in a bill: +4.6, 5.03, 7.99, 8.01 +instead of writing the like below +const price0 = 4.6; +const price1 = 5.03; +const price2 = 7.99; +const price3 = 8.01; +We can write it as an array literal +const items = [4.6, 5.03, 7.99, 8.01]; + +The Array object, as with arrays in other programming languages, enables storing a collection +of multiple items under a single variable name, and has members for performing common array operations. +Arrays can store items of any type & multiple pieces of information. + +In JavaScript, we can use [] notation to access specific elements in the array using index numbers. +The index numbers start from 0. + + +const items = [4.6, 5.03, 7.99, 8.01]; +console.log(items[0]); // 4.6 +console.log(items[1]); // 5.03 +console.log(items[2]); // 7.99 +console.log(items[3]); // 8.01 +// Accessing elements using index numbers +*/ +const items = [4.6, 5.03, 7.99, 8.01]; +function calculateMean(list) { + // Calculate the sum of all elements in the array + const sum = list.reduce( + (accumulator, currentValue) => accumulator + currentValue, + 0 + ); + // Calculate the mean by dividing the sum by the number of elements + const mean = sum / list.length; + return mean; +} diff --git a/prep/mean.test.js b/prep/mean.test.js new file mode 100644 index 000000000..22b24b55c --- /dev/null +++ b/prep/mean.test.js @@ -0,0 +1,12 @@ +/* +test("does something as described below", () => { + // test implementation goes here +}); +*/ +test("calculates the mean of a list of numbers", () => { + const list = [3, 50, 7]; + const currentOutput = calculateMean(list); + const targetOutput = 20; + + expect(currentOutput).toEqual(targetOutput); // 20 is (3 + 50 + 7) / 3 +}); diff --git a/prep/package.json b/prep/package.json new file mode 100644 index 000000000..663b964da --- /dev/null +++ b/prep/package.json @@ -0,0 +1,16 @@ +{ + "name": "prep", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "jest": "^30.2.0" + } +} From 3cb29a05ca2867b60c8dd968537c74fe3abee781 Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Fri, 7 Nov 2025 17:03:55 +0000 Subject: [PATCH 2/6] Refactor mean calculation and tests for clarity and functionality --- prep/mean.js | 24 +++++++++++++++++++++++- prep/mean.test.js | 14 ++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/prep/mean.js b/prep/mean.js index c378b7b73..2aec83fb7 100644 --- a/prep/mean.js +++ b/prep/mean.js @@ -23,7 +23,7 @@ console.log(items[1]); // 5.03 console.log(items[2]); // 7.99 console.log(items[3]); // 8.01 // Accessing elements using index numbers -*/ + const items = [4.6, 5.03, 7.99, 8.01]; function calculateMean(list) { // Calculate the sum of all elements in the array @@ -35,3 +35,25 @@ function calculateMean(list) { const mean = sum / list.length; return mean; } + */ +//const list = [4.6, 5.03, 7.99, 8.01]; +function calculateMean(list) { + //1. sum the elements of the array + let sum = 0; + for (let i = 0; i < list.length; i++) { + const arrayInValue = Number(list); + if (typeof list[i] === "number" && !isNaN(list[i])) { + sum += list[i]; + } + } + //2. determine the length of the array + let count = list.length; + //3. divide #1 by #2 + const mean = sum / count; + //4. return #3 + return mean; +} +console.log(calculateMean([4.6, 5.03, 7.99, 8.01])); +console.log(calculateMean([3, "50", 7])); + +//module.exports = calculateMean; diff --git a/prep/mean.test.js b/prep/mean.test.js index 22b24b55c..8b893a0b9 100644 --- a/prep/mean.test.js +++ b/prep/mean.test.js @@ -2,7 +2,19 @@ test("does something as described below", () => { // test implementation goes here }); + + */ +//mean.test.js +const mean = require("./mean"); // Import the mean function from mean.js +test("calculates the mean of a list of numbers", () => { + expect(mean([3, 50, 7])).toBe(20); // 20 is (3 + 50 + 7) / 3 + expect(mean([4.6, 5.03, 7.99, 8.01])).toBeCloseTo(6.4075); // 6.4075 is (4.6 + 5.03 + 7.99 + 8.01) / 4 + expect(mean([10, 20, 30, 40, 50])).toBe(30); // 30 is (10 + 20 + 30 + 40 + 50) / 5 + expect(mean([1, 2, 3, 4, 5, 6])).toBe(3.5); // 3.5 is (1 + 2 + 3 + 4 + 5 + 6) / 6 +}); +/* +The expect statement is used to create an assertion that checks if the output of the mean function matches the expected value. test("calculates the mean of a list of numbers", () => { const list = [3, 50, 7]; const currentOutput = calculateMean(list); @@ -10,3 +22,5 @@ test("calculates the mean of a list of numbers", () => { expect(currentOutput).toEqual(targetOutput); // 20 is (3 + 50 + 7) / 3 }); + +*/ From 3d4c4072900c18bbd170d1fa462ad408f75156dc Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Tue, 18 Nov 2025 20:16:10 +0000 Subject: [PATCH 3/6] Update mean.js --- prep/mean.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/prep/mean.js b/prep/mean.js index 2aec83fb7..f30eafb97 100644 --- a/prep/mean.js +++ b/prep/mean.js @@ -36,6 +36,7 @@ function calculateMean(list) { return mean; } */ +/* //const list = [4.6, 5.03, 7.99, 8.01]; function calculateMean(list) { //1. sum the elements of the array @@ -57,3 +58,23 @@ console.log(calculateMean([4.6, 5.03, 7.99, 8.01])); console.log(calculateMean([3, "50", 7])); //module.exports = calculateMean; +*/ +function calculateMean(list) { + //1. sum the elements of the array + let sum = 0; + for (const item of list) { + const value = Number(item); + if (!isNaN(value)) { + sum += value; + } + } + + //2. determine the length of the array + let count = list.length; + //3. divide #1 by #2 + const mean = sum / count; + //4. return #3 + return mean; +} +console.log(calculateMean([4.6, 5.03, 7.99, 8.01])); +console.log(calculateMean([3, "50", 7])); From 17dea8ed3d092b071473cbfa43917d52c59e4b2f Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Sat, 29 Nov 2025 14:50:23 +0000 Subject: [PATCH 4/6] deleted prep --- prep/mean.js | 80 ----------------------------------------------- prep/mean.test.js | 26 --------------- prep/package.json | 16 ---------- 3 files changed, 122 deletions(-) delete mode 100644 prep/mean.js delete mode 100644 prep/mean.test.js delete mode 100644 prep/package.json diff --git a/prep/mean.js b/prep/mean.js deleted file mode 100644 index f30eafb97..000000000 --- a/prep/mean.js +++ /dev/null @@ -1,80 +0,0 @@ -/* -Let’s consider a list of prices in a bill: -4.6, 5.03, 7.99, 8.01 -instead of writing the like below -const price0 = 4.6; -const price1 = 5.03; -const price2 = 7.99; -const price3 = 8.01; -We can write it as an array literal -const items = [4.6, 5.03, 7.99, 8.01]; - -The Array object, as with arrays in other programming languages, enables storing a collection -of multiple items under a single variable name, and has members for performing common array operations. -Arrays can store items of any type & multiple pieces of information. - -In JavaScript, we can use [] notation to access specific elements in the array using index numbers. -The index numbers start from 0. - - -const items = [4.6, 5.03, 7.99, 8.01]; -console.log(items[0]); // 4.6 -console.log(items[1]); // 5.03 -console.log(items[2]); // 7.99 -console.log(items[3]); // 8.01 -// Accessing elements using index numbers - -const items = [4.6, 5.03, 7.99, 8.01]; -function calculateMean(list) { - // Calculate the sum of all elements in the array - const sum = list.reduce( - (accumulator, currentValue) => accumulator + currentValue, - 0 - ); - // Calculate the mean by dividing the sum by the number of elements - const mean = sum / list.length; - return mean; -} - */ -/* -//const list = [4.6, 5.03, 7.99, 8.01]; -function calculateMean(list) { - //1. sum the elements of the array - let sum = 0; - for (let i = 0; i < list.length; i++) { - const arrayInValue = Number(list); - if (typeof list[i] === "number" && !isNaN(list[i])) { - sum += list[i]; - } - } - //2. determine the length of the array - let count = list.length; - //3. divide #1 by #2 - const mean = sum / count; - //4. return #3 - return mean; -} -console.log(calculateMean([4.6, 5.03, 7.99, 8.01])); -console.log(calculateMean([3, "50", 7])); - -//module.exports = calculateMean; -*/ -function calculateMean(list) { - //1. sum the elements of the array - let sum = 0; - for (const item of list) { - const value = Number(item); - if (!isNaN(value)) { - sum += value; - } - } - - //2. determine the length of the array - let count = list.length; - //3. divide #1 by #2 - const mean = sum / count; - //4. return #3 - return mean; -} -console.log(calculateMean([4.6, 5.03, 7.99, 8.01])); -console.log(calculateMean([3, "50", 7])); diff --git a/prep/mean.test.js b/prep/mean.test.js deleted file mode 100644 index 8b893a0b9..000000000 --- a/prep/mean.test.js +++ /dev/null @@ -1,26 +0,0 @@ -/* -test("does something as described below", () => { - // test implementation goes here -}); - - -*/ -//mean.test.js -const mean = require("./mean"); // Import the mean function from mean.js -test("calculates the mean of a list of numbers", () => { - expect(mean([3, 50, 7])).toBe(20); // 20 is (3 + 50 + 7) / 3 - expect(mean([4.6, 5.03, 7.99, 8.01])).toBeCloseTo(6.4075); // 6.4075 is (4.6 + 5.03 + 7.99 + 8.01) / 4 - expect(mean([10, 20, 30, 40, 50])).toBe(30); // 30 is (10 + 20 + 30 + 40 + 50) / 5 - expect(mean([1, 2, 3, 4, 5, 6])).toBe(3.5); // 3.5 is (1 + 2 + 3 + 4 + 5 + 6) / 6 -}); -/* -The expect statement is used to create an assertion that checks if the output of the mean function matches the expected value. -test("calculates the mean of a list of numbers", () => { - const list = [3, 50, 7]; - const currentOutput = calculateMean(list); - const targetOutput = 20; - - expect(currentOutput).toEqual(targetOutput); // 20 is (3 + 50 + 7) / 3 -}); - -*/ diff --git a/prep/package.json b/prep/package.json deleted file mode 100644 index 663b964da..000000000 --- a/prep/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "prep", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "jest" - }, - "keywords": [], - "author": "", - "license": "ISC", - "type": "commonjs", - "devDependencies": { - "jest": "^30.2.0" - } -} From c136f37a924f889f4fcde788797fc95d4c1f81c4 Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Wed, 3 Dec 2025 00:34:22 +0000 Subject: [PATCH 5/6] Implement delete completed tasks feature and update UI accordingly --- Sprint-3/todo-list/index.html | 77 +++++++++++++++++++------------ Sprint-3/todo-list/package.json | 5 +- Sprint-3/todo-list/script.mjs | 27 +++++++---- Sprint-3/todo-list/style.css | 22 ++++++++- Sprint-3/todo-list/todos.mjs | 13 +++++- Sprint-3/todo-list/todos.test.mjs | 60 ++++++++++++++++++++---- 6 files changed, 150 insertions(+), 54 deletions(-) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..1bfdb1cd8 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -1,40 +1,57 @@ - - - - ToDo List - - + + + + ToDo List + + - - - -
-

My ToDo List

+ + + +
+

My ToDo List

-
- - -
+
+ + +
+ +
    -
      -
    + +
    + +
    - - - -
    - + +
    + diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json index ce181158a..440674b2a 100644 --- a/Sprint-3/todo-list/package.json +++ b/Sprint-3/todo-list/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "serve": "http-server", - "test": "NODE_OPTIONS=--experimental-vm-modules jest" + "test": "set NODE_OPTIONS=--experimental-vm-modules && jest" }, "repository": { "type": "git", @@ -17,7 +17,8 @@ }, "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", "devDependencies": { + "cross-env": "^10.1.0", "http-server": "^14.1.1", - "jest": "^30.0.4" + "jest": "^30.2.0" } } diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..d65768b42 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -1,4 +1,4 @@ -// Store everything imported from './todos.mjs' module as properties of an object named Todos +// Store everything imported from './todos.mjs' module as properties of an object named Todos import * as Todos from "./todos.mjs"; // To store the todo tasks @@ -7,16 +7,18 @@ const todos = []; // Set up tasks to be performed once on page load window.addEventListener("load", () => { document.getElementById("add-task-btn").addEventListener("click", addNewTodo); + document + .getElementById("delete-completed-btn") + .addEventListener("click", deleteCompletedTodos); // Populate sample data - Todos.addTask(todos, "Wash the dishes", false); + Todos.addTask(todos, "Wash the dishes", false); Todos.addTask(todos, "Do the shopping", true); render(); }); - -// A callback that reads the task description from an input field and +// A callback that reads the task description from an input field and // append a new task to the todo list. function addNewTodo() { const taskInput = document.getElementById("new-task-input"); @@ -29,6 +31,12 @@ function addNewTodo() { taskInput.value = ""; } +// A callback that deletes all completed tasks +function deleteCompletedTodos() { + Todos.deleteCompleted(todos); + render(); +} + // Note: // - Store the reference to the
      element with id "todo-list" here // to avoid querying the DOM repeatedly inside render(). @@ -45,12 +53,11 @@ function render() { }); } - // Note: // - First child of #todo-item-template is a
    • element. // We will create each ToDo list item as a clone of this node. // - This variable is declared here to be close to the only function that uses it. -const todoListItemTemplate = +const todoListItemTemplate = document.getElementById("todo-item-template").content.firstElementChild; // Create a
    • element for the given todo task @@ -62,15 +69,15 @@ function createListItem(todo, index) { li.classList.add("completed"); } - li.querySelector('.complete-btn').addEventListener("click", () => { + li.querySelector(".complete-btn").addEventListener("click", () => { Todos.toggleCompletedOnTask(todos, index); render(); }); - - li.querySelector('.delete-btn').addEventListener("click", () => { + + li.querySelector(".delete-btn").addEventListener("click", () => { Todos.deleteTask(todos, index); render(); }); return li; -} \ No newline at end of file +} diff --git a/Sprint-3/todo-list/style.css b/Sprint-3/todo-list/style.css index 535e91227..bb2f80654 100644 --- a/Sprint-3/todo-list/style.css +++ b/Sprint-3/todo-list/style.css @@ -41,7 +41,7 @@ h1 { .todo-input button { padding: 10px 20px; font-size: 16px; - background-color: #4CAF50; + background-color: #4caf50; color: white; border: none; border-radius: 6px; @@ -105,3 +105,23 @@ h1 { text-decoration: line-through; color: gray; } + +/* Styling for delete completed button */ +.todo-actions { + margin-top: 20px; + text-align: center; +} + +.delete-completed-btn { + padding: 10px 20px; + font-size: 16px; + background-color: #f44336; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; +} + +.delete-completed-btn:hover { + background-color: #da190b; +} diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs index f17ab6a25..a7b245601 100644 --- a/Sprint-3/todo-list/todos.mjs +++ b/Sprint-3/todo-list/todos.mjs @@ -26,4 +26,15 @@ export function toggleCompletedOnTask(todos, taskIndex) { if (todos[taskIndex]) { todos[taskIndex].completed = !todos[taskIndex].completed; } -} \ No newline at end of file +} + +// Delete all completed tasks from the todos list +export function deleteCompleted(todos) { + // Filter out all completed tasks, keeping only incomplete ones + // We iterate backwards to avoid index shifting issues + for (let i = todos.length - 1; i >= 0; i--) { + if (todos[i].completed) { + todos.splice(i, 1); + } + } +} diff --git a/Sprint-3/todo-list/todos.test.mjs b/Sprint-3/todo-list/todos.test.mjs index bae7ae491..40965bc00 100644 --- a/Sprint-3/todo-list/todos.test.mjs +++ b/Sprint-3/todo-list/todos.test.mjs @@ -13,7 +13,7 @@ function createMockTodos() { { task: "Task 1 description", completed: true }, { task: "Task 2 description", completed: false }, { task: "Task 3 description", completed: true }, - { task: "Task 4 description", completed: false }, + { task: "Task 4 description", completed: false }, ]; } @@ -29,7 +29,6 @@ describe("addTask()", () => { }); test("Should append a new task to the end of a ToDo list", () => { - const todos = createMockTodos(); const lengthBeforeAddition = todos.length; Todos.addTask(todos, theTask.task, theTask.completed); @@ -42,7 +41,6 @@ describe("addTask()", () => { }); describe("deleteTask()", () => { - test("Delete the first task", () => { const todos = createMockTodos(); const todosBeforeDeletion = createMockTodos(); @@ -53,7 +51,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[1]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the second task (a middle task)", () => { @@ -66,7 +64,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the last task", () => { @@ -79,7 +77,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[1]); - expect(todos[2]).toEqual(todosBeforeDeletion[2]); + expect(todos[2]).toEqual(todosBeforeDeletion[2]); }); test("Delete a non-existing task", () => { @@ -94,7 +92,6 @@ describe("deleteTask()", () => { }); describe("toggleCompletedOnTask()", () => { - test("Expect the 'completed' property to toggle on an existing task", () => { const todos = createMockTodos(); const taskIndex = 1; @@ -111,13 +108,12 @@ describe("toggleCompletedOnTask()", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); Todos.toggleCompletedOnTask(todos, 1); - - expect(todos[0]).toEqual(todosBeforeToggle[0]); + + expect(todos[0]).toEqual(todosBeforeToggle[0]); expect(todos[2]).toEqual(todosBeforeToggle[2]); expect(todos[3]).toEqual(todosBeforeToggle[3]); }); - test("Expect no change when toggling on a non-existing task", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); @@ -130,3 +126,47 @@ describe("toggleCompletedOnTask()", () => { }); }); +describe("deleteCompleted()", () => { + test("Delete all completed tasks from a mixed list", () => { + const todos = createMockTodos(); + // Mock list has 2 completed tasks (Task 1 and Task 3) + Todos.deleteCompleted(todos); + + expect(todos).toHaveLength(2); + expect(todos[0]).toEqual({ task: "Task 2 description", completed: false }); + expect(todos[1]).toEqual({ task: "Task 4 description", completed: false }); + }); + + test("Delete completed tasks from a list with no completed tasks", () => { + const todos = [ + { task: "Task 1", completed: false }, + { task: "Task 2", completed: false }, + ]; + const todosBeforeDeletion = [...todos]; + + Todos.deleteCompleted(todos); + + expect(todos).toEqual(todosBeforeDeletion); + expect(todos).toHaveLength(2); + }); + + test("Delete completed tasks from a list where all tasks are completed", () => { + const todos = [ + { task: "Task 1", completed: true }, + { task: "Task 2", completed: true }, + { task: "Task 3", completed: true }, + ]; + + Todos.deleteCompleted(todos); + + expect(todos).toHaveLength(0); + }); + + test("Delete completed tasks from an empty list", () => { + const todos = []; + + Todos.deleteCompleted(todos); + + expect(todos).toHaveLength(0); + }); +}); From e0474df98a7ae1ba58b6c9812442f11889848b85 Mon Sep 17 00:00:00 2001 From: Baba05206 Date: Sun, 7 Dec 2025 19:20:02 +0000 Subject: [PATCH 6/6] added two additional tests and ran the test to ensure these still passed --- Sprint-3/todo-list/todos.test.mjs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Sprint-3/todo-list/todos.test.mjs b/Sprint-3/todo-list/todos.test.mjs index 40965bc00..0dd18bea9 100644 --- a/Sprint-3/todo-list/todos.test.mjs +++ b/Sprint-3/todo-list/todos.test.mjs @@ -169,4 +169,35 @@ describe("deleteCompleted()", () => { expect(todos).toHaveLength(0); }); + + test("Delete completed tasks from a mixed list where the last item is completed", () => { + const todos = [ + { task: "Task 1", completed: false }, + { task: "Task 2", completed: true }, + { task: "Task 3", completed: false }, + { task: "Task 4", completed: true }, + ]; + + Todos.deleteCompleted(todos); + + expect(todos).toHaveLength(2); + expect(todos[0]).toEqual({ task: "Task 1", completed: false }); + expect(todos[1]).toEqual({ task: "Task 3", completed: false }); + }); + + test("Delete completed tasks from a mixed list with consecutive completed tasks", () => { + const todos = [ + { task: "Task 1", completed: false }, + { task: "Task 2", completed: true }, + { task: "Task 3", completed: true }, + { task: "Task 4", completed: true }, + { task: "Task 5", completed: false }, + ]; + + Todos.deleteCompleted(todos); + + expect(todos).toHaveLength(2); + expect(todos[0]).toEqual({ task: "Task 1", completed: false }); + expect(todos[1]).toEqual({ task: "Task 5", completed: false }); + }); });