admin管理员组

文章数量:1310273

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 of 90 <= 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 over 100. 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
Add a ment  | 

4 Answers 4

Reset to default 6

Your 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)}`));

本文标签: javascriptCodewars GrasshopperGrade book challengeStack Overflow