Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NW-6 | Fikret Ellek | JS1| [TECH ED] Complete week 3 exercises | WEEK-3 #193

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

fikretellek
Copy link

@fikretellek fikretellek commented Jan 3, 2024

Learners, PR Template

Self checklist

  • I have committed my files one by one, on purpose, and for a reason
  • I have titled my PR with COHORT_NAME | FIRST_NAME LAST_NAME | REPO_NAME | WEEK
  • I have tested my changes
  • My changes follow the style guide
  • My changes meet the requirements of this task

Changelist

Briefly explain your PR.

Questions

Ask any questions you have for your reviewer.

Copy link

@pseudopilot pseudopilot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @fikretellek . This is really good and every implementation you created here will definitely work.
Though, I'd like to help you to make your solutions more effective and readable. Please, check my comments below and let me know if you have any difficulty with it.

Comment on lines +68 to +76
if (alphabetLower.includes(char)) {
const value = (alphabetLower.indexOf(char) + shift) % 26;
return alphabetLower[value];
} else if (alphabetUpper.includes(char)) {
const value = (alphabetUpper.indexOf(char) + shift) % 26;
return alphabetUpper[value];
} else {
return char;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good and definitely should work. Though it may be optimised in a few ways:

  1. For now each time we call the function rotateCharacter we check/iterate the same array of letters 2 times:
  • 1st time when we call includes
  • 2nd time when we call indexOf
    Can we avoid using includes at all in this task and just use only indexOf and only once?
    What this method returns us when there is no value we search in array?
  1. In the worst case (e.g. the argument is a number) we will check 2 arrays of letters before returning original value back. But I think we can use one array of letters (e.g. alphabetLower) instead of two if we utilise the string methods toLowerCase() and toUpperCase()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see, yes it makes the code more efficient. So that way we will turn the chat in to lower case and then check if it is included in the lower case array. Then shift the char and return upper case or lower case. When there is no matching element (char is not a letter) in the array we will get -1 and return the char itself

Comment on lines +9 to +11
const hour = time.slice(0, 2);
if (Number(hour) > 12) {
return `${Number(hour) - 12}:${time.slice(3, 5)} pm`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good! But we still can improve it. Do we really need to call Number(hour) twice or we can do it only once somehow?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can assign it to a variable and use it multiple times. I couldn't see it 😔

Comment on lines +49 to +68
const type = ["♣", "♦", "♥", "♠"];
let num = cards.slice(0, -1);

if (number.includes(num) && type.includes(cards.slice(-1))) {
if (num === "A") {
result = 11;
} else if (num === "J") {
result = 10;
} else if (num === "Q") {
result = 10;
} else if (num === "K") {
result = 10;
} else {
result = Number(num);
}
return result;
} else {
return "Invalid card rank.";
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solution will definitely work! Though we can make it more effective.
Try rewriting it using Objects instead of Arrays for storing cards and their values like:

const cards = {
  '2': 2,
  '3': 3,
  ...
}

We can use Object for card types too.
In this case we won't need to use includes and iterate through the whole list of cards every time.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can just return

return card[cards.slice(0, -1)] && type[cards.slice(-1)] ? number[cards.slice(0, -1)] : "Invalid card rank." ;

🤯

Comment on lines +10 to +20
if (denominator === 0) {
return "Error (Denominator cannot be zero)";
} else if (
(fraction < 1 && fraction > 0) ||
(fraction > -1 && fraction < 0)
) {
return true;
} else {
return false;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's all correct. But I have some ideas how to make it a little shorter:

  if (denominator === 0) {
    return "Error (Denominator cannot be zero)";
  }
  
  return (fraction > -1 && fraction < 1 && fraction !== 0);
}

Let me explain you a couple of things here.
First, If the first check is true (denominator === 0) then the function returns an error and the rest of it won't be performed. If it is false then the function continue to work anyway. It means that we don't really need else here.

Second point is that comparison like fraction < 1 results in either true or false. It mean that we don't really need to write something like:

if (fraction > 1) {
  return true;
} else {
  return false;
}

We can just write return fraction > 1 and that's it.

In this task we have few conditions to check, but the approach may be the same: return (fraction > -1 && fraction < 1 && fraction !== 0); because the result of these 3 checks will be either true or false.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using return to break the loop. That is brilliant 🤩 . I understand if the comparison returns true or false, there is no need to check with if statement.

Comment on lines +3 to +12
if (a <= 0 && b <= 0 && c <= 0) {
return false;
} else {
if (a + b > c && b + c > a && c + a > b) {
return true;
} else {
return false;
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will definitely work! But again it may be improved:

  1. a <= 0 && b <= 0 && c <= 0 - this check means that if all 3 sides are equal to 0, then it's not a triangle. But in fact it's not a triangle if either of the sides is equal to 0. Either a, or b, or c.

  2. As for the rest of this function, could you try refactor it yourself using my advice from is-proper-fraction.js task?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it's gonna be like

function isValidTriangle(a, b, c) {
  if (a <= 0 && b <= 0 && c <= 0) {
      return false;
    }
  return (a + b > c && b + c > a && c + a > b)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I actually meant was using || instead of && in the first if check:

  if (a <= 0 || b <= 0 || c <= 0) {
    return false;
  } else {
    return (a + b > c && b + c > a && c + a > b); // for this line your refactoring is perfect!

or... we can even make it shorter:

return !(a <= 0 || b <= 0 || c <= 0) || (a + b > c && b + c > a && c + a > b);

but the last may be not very clear.

Copy link
Author

@fikretellek fikretellek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much @pseudopilot for your time and brilliant code review. I've learned a lot 🙏

Comment on lines +68 to +76
if (alphabetLower.includes(char)) {
const value = (alphabetLower.indexOf(char) + shift) % 26;
return alphabetLower[value];
} else if (alphabetUpper.includes(char)) {
const value = (alphabetUpper.indexOf(char) + shift) % 26;
return alphabetUpper[value];
} else {
return char;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see, yes it makes the code more efficient. So that way we will turn the chat in to lower case and then check if it is included in the lower case array. Then shift the char and return upper case or lower case. When there is no matching element (char is not a letter) in the array we will get -1 and return the char itself

Comment on lines +9 to +11
const hour = time.slice(0, 2);
if (Number(hour) > 12) {
return `${Number(hour) - 12}:${time.slice(3, 5)} pm`;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can assign it to a variable and use it multiple times. I couldn't see it 😔

Comment on lines +3 to +12
if (a <= 0 && b <= 0 && c <= 0) {
return false;
} else {
if (a + b > c && b + c > a && c + a > b) {
return true;
} else {
return false;
}
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it's gonna be like

function isValidTriangle(a, b, c) {
  if (a <= 0 && b <= 0 && c <= 0) {
      return false;
    }
  return (a + b > c && b + c > a && c + a > b)
}

Comment on lines +10 to +20
if (denominator === 0) {
return "Error (Denominator cannot be zero)";
} else if (
(fraction < 1 && fraction > 0) ||
(fraction > -1 && fraction < 0)
) {
return true;
} else {
return false;
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using return to break the loop. That is brilliant 🤩 . I understand if the comparison returns true or false, there is no need to check with if statement.

Comment on lines +49 to +68
const type = ["♣", "♦", "♥", "♠"];
let num = cards.slice(0, -1);

if (number.includes(num) && type.includes(cards.slice(-1))) {
if (num === "A") {
result = 11;
} else if (num === "J") {
result = 10;
} else if (num === "Q") {
result = 10;
} else if (num === "K") {
result = 10;
} else {
result = Number(num);
}
return result;
} else {
return "Invalid card rank.";
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can just return

return card[cards.slice(0, -1)] && type[cards.slice(-1)] ? number[cards.slice(0, -1)] : "Invalid card rank." ;

🤯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants