Manchester | 26-ITP-Jan | Mehroz Munir | Sprint 1 | Coursework exercises#1018
Manchester | 26-ITP-Jan | Mehroz Munir | Sprint 1 | Coursework exercises#1018MehrozMunir wants to merge 3 commits intoCodeYourFuture:mainfrom
Conversation
ykamal
left a comment
There was a problem hiding this comment.
Good work so far. 🎉 Just a few things to clear out. Well done 👍 . Let me know when the changes are done.
Sprint-1/fix/median.js
Outdated
| const middleIndex = Math.floor(list.length / 2); | ||
| const median = list.splice(middleIndex, 1)[0]; | ||
| let median = null; | ||
| if (Array.isArray(list) && !list.every((item) => typeof item != "number")) { |
There was a problem hiding this comment.
Excellent check of valid types for each item in an array. 👍
There are a few things to improve here:
You're doing a double negative check here. One positive check would reduce the complexity.
Use the early return method, where if your data doesn't match a certain criterion, you just stop with either a return or an error. More: https://gomakethings.com/the-early-return-pattern-in-javascript/
There was a problem hiding this comment.
Thank you so much, that was really helpful. I have implemented this now.
Sprint-1/fix/median.js
Outdated
| const median = list.splice(middleIndex, 1)[0]; | ||
| let median = null; | ||
| if (Array.isArray(list) && !list.every((item) => typeof item != "number")) { | ||
| numericList = list.filter((item) => typeof item === "number"); |
There was a problem hiding this comment.
Hmm, something about the declaration of these variables numericList and sortedList doesn't seem right. Think about the scope, think about mutability. What keywords should you use here to ensure your scope is proper, to avoid implicit globals?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types
There was a problem hiding this comment.
Ahh yes, I now understand the scope better after reading this. Thanks.
| median = (medianArray[0] + medianArray[1]) / 2; | ||
| } else median = sortedList.splice(middleIndex, 1)[0]; | ||
| } | ||
| return median; |
There was a problem hiding this comment.
Nice, organised return statement. If the above code falls through, this will catch it.
But question ❓ Can a median be null? Does it have to be a number? Or is null fine?
There was a problem hiding this comment.
Yes, it can't be null. I have added a check at the end for that. Let me know if it seems right. Thanks
Sprint-1/fix/median.js
Outdated
| sortedList = numericList.toSorted((a, b) => a - b); | ||
| const middleIndex = Math.floor(sortedList.length / 2); | ||
| if (sortedList.length % 2 === 0) { | ||
| const medianArray = sortedList.splice(middleIndex - 1, 2); |
There was a problem hiding this comment.
Hmm. .splice() is a mutating operation. It changes the original array. The goal here is to access the value at a certain index of the array. In that regard, calculating the index would be a better solution for odd/even-length arrays. That will preserve the original array for later operations. Whereas right now, if you did more operations below, you'd be working with a mutated/changed array with fewer items in it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
There was a problem hiding this comment.
Yeah, that's totally right. I have changed the code here to not use splice method and instead use the array index to access the values.
Sprint-1/implement/dedupe.js
Outdated
| @@ -1 +1,12 @@ | |||
| function dedupe() {} | |||
| function dedupe(arr) { | |||
| if (arr.length === 0) return arr; | |||
There was a problem hiding this comment.
Nice length check here 👍 But could the array just not be present, i.e. null/undefined?
There was a problem hiding this comment.
Oh yes, I thought about these null/ undefined checks when working on these test files, but as this case was not described already, I thought we might not be supposed to do this.
But I think it is always a good practice to have those checks. I have added them now. Kindly check, please.
Sprint-1/implement/dedupe.js
Outdated
| if (arr.length === 0) return arr; | ||
| else { | ||
| dedupeArray = []; | ||
| arr.forEach((element) => { |
There was a problem hiding this comment.
This is generally good logic. Well done 👍
However, if you want a much simpler approach, a better data structure would be a Set. You'd create a set from this array, then return an array of the set.
that'd do this for you.
https://www.geeksforgeeks.org/javascript/how-to-convert-set-to-array-in-javascript/
There was a problem hiding this comment.
Thank you for introducing Set into my life. I am using them now.
There was a problem hiding this comment.
Hehe, happy to do so. But ensure you follow the goals of the current chapter. There's always another advanced technique, but follow the goal/description of the task, even if it's painful to do so.
Sprint-1/implement/max.js
Outdated
| @@ -1,4 +1,6 @@ | |||
| function findMax(elements) { | |||
| function findMax(array) { | |||
| numbersArray = array.filter((value) => typeof value === "number"); | |||
There was a problem hiding this comment.
Excellent type check. But also ensure to do null/undefined check
Sprint-1/implement/sum.js
Outdated
| @@ -1,4 +1,10 @@ | |||
| function sum(elements) { | |||
| function sum(array) { | |||
| numbersArray = array.filter((value) => typeof value === "number"); | |||
There was a problem hiding this comment.
Same here, null/undefined check should be added
There was a problem hiding this comment.
Also, look into .reduce() after this section is over.
There was a problem hiding this comment.
Yes, I read about reduce, and it seems better to use that here.
| if (element === target) { | ||
| return true; | ||
| } | ||
| for (const element of list) { |
There was a problem hiding this comment.
Ah, you must use a for-loop, I see. Otherwise, .includes() would be fine. Poor thing 🤣
| @@ -0,0 +1,16 @@ | |||
| function getFinalFrequency() { | |||
| let finalFrequency = 0; | |||
| const fs = require("fs"); //getting file system to read file | |||
There was a problem hiding this comment.
require/imports should be at the top of the files. This is syntactically valid, but, practically discouraged.
There was a problem hiding this comment.
Thank you for highlighting that. I will follow this from now on. Thanks.
Thank you so much for your valuable feedback. I have committed the changes after your feedback. Please review my code now. |
Sprint-1/implement/max.js
Outdated
| function findMax(elements) { | ||
| function findMax(array) { | ||
| if (!Array.isArray(array)) throw new Error(array + " is not an array"); | ||
| let numbersArray = array.filter((value) => typeof value === "number"); |
There was a problem hiding this comment.
for variables that are not later reassigned, you can use const as it's recommended and is safer. A const won't be allowed to be reassigned so you can't accidentally redeclare the same variable or change it. (Unless it's an object, in that case you can still mutate its state using its methods).
There was a problem hiding this comment.
Thanks I will do that from now on. Made this change in the code as well.
Sprint-1/implement/sum.js
Outdated
| function sum(array) { | ||
| if (!Array.isArray(array)) throw new Error(array + " is not an array"); | ||
| let numbersArray = array.filter((value) => typeof value === "number"); | ||
| let initialValue = 0; |
There was a problem hiding this comment.
It's good that you're getting in the habit of clean code, but for most things reduce(), you do not need to declare the initial value as a variable, just use it in the reduce().
| @@ -0,0 +1,17 @@ | |||
| const fs = require("fs"); //getting file system to read file | |||
Sprint-1/implement/dedupe.test.js
Outdated
| // Then it should return an empty array | ||
| it("given an empty array it should return an empty array", () => { | ||
| const array = []; | ||
| dedupeArray = dedupe(array); |
There was a problem hiding this comment.
I think this one slipped through the crack. Let's add a keyword
Sprint-1/implement/dedupe.test.js
Outdated
| // When passed to the dedupe function | ||
| // Then it should thrown an error | ||
| [null, 930, "just a string", undefined, {}].forEach((val) => | ||
| it("throw an error if the input is not an array", () => |
There was a problem hiding this comment.
This is causing the test name to not be unique. Perhaps there is a better way to do this? Do the iteration inside the test? Or something better?
ykamal
left a comment
There was a problem hiding this comment.
Overall, well done 👍 There's a problem with unique test name in dedupe.test.js. Once that's sorted, we can close this one.
And median === null check will actually be reached so we can remove that check for now.
Thank you for the feedback. I have created separate test cases in the dupe.test.js file for these tests. I hope that is the right way to do this. |

Learners, PR Template
Self checklist
Changelist
In this PR, I am submitting changes made in the exercise files.