This is one of those times where the solution is staring me right in the face but I can't seem to find it! So please be patient with me. The kata instruction is the following:
Complete the function so that it finds the mean of the three scores passed to it and returns the letter value associated with that grade.
Numerical Score Letter Grade 90 <= score <= 100 'A' 80 <= score < 90 'B' 70 <= score < 80 'C' 60 <= score < 70 'D' 0 <= score < 60 'F'
Tested values are all between 0 and 100. There is no need to check for negative values or values greater than 100.
Here is my solution:
function getGrade (s1, s2, s3) {
var score = (s1 + s2 + s3) / 3;
if (90 <= score && score >= 100) {
return 'A';
} else if (80 <= score && score > 90) {
return 'B';
} else if (70 <= score && score > 80) {
return 'C';
} else if (60 <= score && score > 70) {
return 'D';
} else if (0 <= score && score > 60) {
return 'F';
}
}
getGrade(5,40,93);
getGrade(30,85,96);
getGrade(92,70,40);
Can't for the life of me figure out what I am doing wrong.
This is one of those times where the solution is staring me right in the face but I can't seem to find it! So please be patient with me. The kata instruction is the following:
Complete the function so that it finds the mean of the three scores passed to it and returns the letter value associated with that grade.
Numerical Score Letter Grade 90 <= score <= 100 'A' 80 <= score < 90 'B' 70 <= score < 80 'C' 60 <= score < 70 'D' 0 <= score < 60 'F'
Tested values are all between 0 and 100. There is no need to check for negative values or values greater than 100.
Here is my solution:
function getGrade (s1, s2, s3) {
var score = (s1 + s2 + s3) / 3;
if (90 <= score && score >= 100) {
return 'A';
} else if (80 <= score && score > 90) {
return 'B';
} else if (70 <= score && score > 80) {
return 'C';
} else if (60 <= score && score > 70) {
return 'D';
} else if (0 <= score && score > 60) {
return 'F';
}
}
getGrade(5,40,93);
getGrade(30,85,96);
getGrade(92,70,40);
Can't for the life of me figure out what I am doing wrong.
Share Improve this question edited Sep 12, 2020 at 22:03 ggorlen 57.4k8 gold badges110 silver badges154 bronze badges asked Jan 30, 2017 at 7:12 Aaron MatthewsAaron Matthews 1284 silver badges13 bronze badges 5-
2
In other words, you test for
90 <= score >= 100
instead of90 <= score <= 100
and so on. – JJJ Commented Jan 30, 2017 at 7:15 -
2
Moreover, as you're using
else
, you don't need to (and shouldn't) specify both bounds at each level.if (score > 90) { ... } else if (score > 80) { ... } ...
– T.J. Crowder Commented Jan 30, 2017 at 7:16 - A grade must be within a limit like (score >=90 && score <=100) return 'A'. – samar Commented Jan 30, 2017 at 7:17
-
@Teemu I guess you misread it. Its
90
less than score, which is correct. Issue is OP has added>= 100
and he cannot have values over100
. Hence failing – Rajesh Commented Jan 30, 2017 at 7:17 - Thank you for the explanations everyone, they really helped me figure out where I was going wrong – Aaron Matthews Commented Jan 31, 2017 at 6:54
4 Answers
Reset to default 6Your conditions in if statement are all wrong. These are the right conditions
function getGrade (s1, s2, s3) {
var score = (s1 + s2 + s3) / 3;
if (score >= 90 && score <= 100) {
return 'A';
} else if (score >= 80 && score < 90) {
return 'B';
} else if (score >= 70&& score < 80) {
return 'C';
} else if (score >= 60 && score < 70) {
return 'D';
} else {
return 'F';
}
}
your conditions are wrong and you don't need multiple check in same if .Change your code to this:
function getGrade (s1, s2, s3) {
var score = (s1 + s2 + s3) / 3;
if (score >= 90 && score <= 100) {
return 'A';
} else if (score >= 80 && score < 90) {
return 'B';
} else if (score >= 70 && score < 80) {
return 'C';
} else if (score >= 60 && score < 70) {
return 'D';
} else{
return 'F';
}
}
console.log(getGrade(5,40,93));
console.log(getGrade(30,85,96));
console.log(getGrade(92,70,40));
You could use only if
clauses without else
parts and check only the lower bound, because you have already checked the upper bound.
The check for upper 100
is missing, because your given range is between 0
and 100
.
function getGrade(s1, s2, s3) {
var score = (s1 + s2 + s3) / 3;
if (score >= 90) {
return 'A';
}
if (score >= 80) {
return 'B';
}
if (score >= 70) {
return 'C';
}
if (score >= 60) {
return 'D';
}
return 'F';
}
console.log(getGrade(5, 40, 93));
console.log(getGrade(30, 85, 96));
console.log(getGrade(92, 70, 40));
Whenever you find yourself writing long chains of if
-else
statements, see if you can find a pattern and use a lookup table. Here, we have only 5 grade buckets, but what if we had 20 or 100? You can see the if
-else
approach isn't scalable.
In this case, if we use the string "FFFFFFDCBAA"
then we've enumerated all 5 grade buckets in a way that lets us index into after dividing the score by 10. The code for that would be: "FFFFFFDCBAA"[score/10|0]
where | 0
is the floor operation, chopping off the decimal. The extra "A"
handles the case of 100.
Secondly, the arguments to the function (s1, s2, s3)
make no sense. Why 3 scores? If we have 4 score, or 20 scores, the function can't be used and we have to rewrite the whole function with the right number of arguments (and the 20-argument one will be pretty ugly). I realize this header is what the kata author gave you, but there's no reason we can't make it handle any number of arguments using (...args)
and still pass the tests. If we take the average of the arguments using args.reduce((a, e) => a + e, 0) / args.length
, we're left with the following solution:
const sum = a => a.reduce((a, e) => a + e, 0);
const avg = a => sum(a) / a.length;
const getGrade = (...args) => "FFFFFFDCBAA"[avg(args)/10|0];
[
[0],
[0, 100, 50],
[90, 95, 100],
[80, 60],
[81, 79],
[80, 59],
].forEach(test => console.log(`${test} => ${getGrade(...test)}`));