How can I improve my code, and why does it not run? - javascript

This code is meant to take a number score from 0 to 100 and print the grade.
This is for school and is using a simplified version of javascript from the website 'codehs.com' I've been stuck on this for a while now, I would like help fixing my code.
/* This code is meant to take a number score from 0 to 100 and print
the grade. */
function start(){
/*given list */
lettergrade(100);
lettergrade(83);
lettergrade(68);
lettergrade(91);
lettergrade(47);
lettergrade(79);
}
/* this will print the grades above by using If/else if statements */
function lettergrade(score){
if(score = 90-100){
return("A");
}
else if(score = 80-90){
return("B");
}
else if(score = 70-79){
return("C");
}
else if(score = 60-69){
return("D");
}
else if(score = 0-59){
return("F");
}
}
The Expected result is to print the letter grades, A-F and the +/- sign if needed, but the code does not run.

There were multiple places wrong with your code:
lettergrade(100) is wrong because your function defined as letterGrade, there is case sensitivity in JS
if(score = 90-99) is wrong because if statement is expecting expression which you can choose to use == or ===. Single equal sign = meant for value assignment, not for comparison. And 90-99 is wrong, that is calculation not range. Correct way should be if(score >= 90 && score <= 99)
/* this will print the grades above by using If/else if statements */
function letterGrade(score){
if(score >= 90 && score <= 99){
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 if(score >= 0 && score < 60){
return("F");
}
}
function start(){
/*given list */
console.log(letterGrade(100));
console.log(letterGrade(83));
console.log(letterGrade(68));
console.log(letterGrade(91));
console.log(letterGrade(47));
console.log(letterGrade(79));
}
start();

The syntax is full of errors
Watch out for case sensitivity
You want an else statement to check if score is not valid
function letterGrade(score){
if(score >= 90 && score <= 100) {
return "A";
}
else if(score >= 80 && score < 90){
return "B";
}
else if(score >= 70 && score <= 79){
return "C";
}
else if(score >= 60 && score <= 69){
return "D";
}
else if(score >= 0 && score <= 59){
return "F";
}
else {
console.error(`Err: ${score} is not a valid score`);
}
}
Normal usage :
console.log(letterGrade(85)); // "B"
console.log(letterGrade(100)); // "A"
console.log(letterGrade(1)); // "F"
Handle errors :
console.log(letterGrade(4242)); // "Err: 4242 is not a valid Score"
console.log(letterGrade(-42)); // "Err: -42 is not a valid Score"
console.log(letterGrade("Hello World!")); // "Err: "Hello World!" is not a valid Score"

Related

Grade Conversion in HTML

So, I have been working on this code for class, and everything I have done never seems to work! My work is in Visual Code Studio, and it does not bring up any sort of errors. I've looked it up and everything, and I just can't figure out why I can't get an output!
It is a grade conversion. By reading my code I guess you can figure out the parameters of the conversion. I just can't seem to figure out what is going on!
<!DOCTYPE HTML>
<html>
<pre>
<body>
<script>
var grade=95;
if ((grade >= 90) (and) (grade <= 100)) {
document.write("A+ -- Exceptional!");
} else if ((grade >= 80) (and) (grade <= 89)) {
document.write("A -- Excellent!");
} else if ((grade >= 70) (and) (grade <= 79)) {
document.write("B -- Good!");
} else if ((grade >= 60) (and) (grade <= 69)) {
document.write("C -- Satisfactory");
} else if ((grade >= 50) (and) (grade <= 59)) {
document.write("D -- Barely Acceptable");
} else if ((grade >= 0) (and) (grade <= 49)) {
document.write("F -- Failure");
} else {
document.write("An accepted grade was not implemented into the system.");
}
</script>
</body>
</pre>
</html>
and is not a javascript operator.
Replace every (and) with &&
var grade = 95;
if (grade >= 90 && grade <= 100) {
document.write("A+ -- Exceptional!");
} else if (grade >= 80 && grade <= 89) {
document.write("A -- Excellent!");
} else if (grade >= 70 && grade <= 79) {
document.write("B -- Good!");
} else if (grade >= 60 && grade <= 69) {
document.write("C -- Satisfactory");
} else if (grade >= 50 && grade <= 59) {
document.write("D -- Barely Acceptable");
} else if (grade >= 0 && grade <= 49) {
document.write("F -- Failure");
} else {
document.write("An accepted grade was not implemented into the system.");
}
Also you should not have <pre> tags outside of the <body>

My code keeps returning undefined underneath the output

My JavaScript function keeps returning undefined underneath the correct output value.
let grade;
function getGrade(score) {
// Write your code here
if (score >= 25 && score <= 30) {
console.log('A');
}
else if (score >= 20 && score <= 25) {
console.log('B');
}
else if (score >= 15 && score <= 20) {
console.log('C');
}
else if (score >= 10 && score <= 15) {
console.log('D');
}
else if (score >= 5 && score <= 10) {
console.log('E');
}
else {
console.log('F');
}
return grade;
}
You haven't defined your grade. And it will always be undefined.
One way to do it is as follows:
function getGrade(score) {
var grade = "";
// Write your code here
if (score >= 25 && score <= 30) {
grade = "A";
}
else if (score >= 20 && score <= 25) {
grade = "B";
}
else if (score >= 15 && score <= 20) {
grade = "C";
}
else if (score >= 10 && score <= 15) {
grade = "D";
}
else if (score >= 5 && score <= 10) {
grade = "E";
}
else {
grade = "F";
}
return grade;
}
console.log(getGrade(27))
It seems you have return grade; at the bottom, but grade doesn't seem to be defined anywhere.
You should to set your variable "grade" value, or just delete
return grade;
Always check the console. It's currently singing at you, telling you grade is undefined.
You're trying to return something you haven't assigned a value to.
function getGrade(score) {
// ... //
return grade; //<-- nowhere do you define grade
}
Should be
function getGrade(score) {
let grade;
if (score >= 25 && score <= 30) grade = 'A';
else if (score >= 20 && score <= 25) grade = 'B';
else if (score >= 15 && score <= 20) grade = 'C';
else if (score >= 10 && score <= 15) grade = 'D';
else if (score >= 5 && score <= 10) grade = 'E';
else grade = 'F';
console.log(grade);
return grade;
}
Use return instead of console.log()
function getGrade(score) {
if (score >= 25 && score <= 30) {
return 'A'
}
else if (score >= 20 && score <= 25) {
return 'B'
}
else if (score >= 15 && score <= 20) {
return 'C';
}
else if (score >= 10 && score <= 15) {
return 'D';
}
else if (score >= 5 && score <= 10) {
return 'E';
}
else {
return 'F';
}
}
console.log(getGrade(20))
As there is difference of 5 b/w each grade range so you can use division and Math.floor
function getGrade(score) {
let grades = 'FEDCBA'
return score === 30 ? 'A' : grades[Math.floor((score)/5)]
}
console.log(getGrade(20))
console.log(getGrade(19))
console.log(getGrade(30))

Run multiple else if statements

When I run this code, only the INVALID (over 100) and High Distinction works. Any number below 80 also shows High Distinction. What have I done wrong?
function calculateGrade() {
var fvalue = Number(prompt('Please enter final score for unit. Enter a whole number only'));
document.write('The final score entered is ' + fvalue + '<br />');
if (fvalue > 100) {
document.write('INVALID');
} else if (80 <= fvalue <= 100) {
document.write('High Distinction');
} else if (70 <= fvalue <= 79) {
document.write('Distinction');
} else if (60 <= fvalue <= 69) {
document.write('Credit');
} else if (50 <= fvalue <= 59) {
document.write('Pass');
} else if (0 <= fvalue <= 49) {
document.write('Fail');
} else if (fvalue < 0) {
document.write('INVALID');
}
}
calculateGrade()
Your comparison syntax is invalid. You need to check one boundary at a time:
if (80 <= fvalue && fvalue <= 100) {
Same for the others.
To take it a step further, you only need to check one boundary, because the higher end is excluded by the else:
if (fvalue > 100) {
document.write('INVALID');
} else if (80 <= fvalue) {
document.write('High Distinction');
} else if (70 <= fvalue) {
// ...
This isn't java.
But you can surely try this.
else if ( (fvalue >= 80) && (fvalue<= 100)) {
document.write('High Distinction');

Converting Score to Grade simpler. Is there a simpler way to write the following code?

It is somewhat tedious writing all the else if statements. Is there a simpler way to write the following code?
function convertScoreToGradeWithPlusAndMinus(score) {
// your code here
if(score <= 100 && score >= 98) return "A+";
else if(score <= 97 && score >= 93) return "A";
else if(score <= 92 && score >= 90) return "A-";
else if(score <= 89 && score >= 88) return "B+";
else if(score <= 87 && score >= 83) return "B";
else if(score <= 82 && score >= 80) return "B-";
else if(score <= 79 && score >= 78) return "C+";
else if(score <= 77 && score >= 73) return "C";
else if(score <= 72 && score >= 70) return "C-";
else if(score <= 69 && score >= 68) return "D+";
else if(score <= 67 && score >= 63) return "D";
else if(score <= 62 && score >= 60) return "D-";
else if(score <= 59 && score >= 0) return "F";
else return "INVALID SCORE";
}
var output = convertScoreToGradeWithPlusAndMinus(91);
console.log(output); // --> 'A-'
Shorter code is not better code always. You can write a very short version of this code by using ascii and some math tricks. But it will not be readable later by other ones. I think readablity and performance are two most important thing to consider.
var limits = ['-','','+','+']
function convertScoreToGradeWithPlusAndMinus(score) {
if(score==100) return 'A+';
if(score<59) return 'F';
var lCode = 74 - Math.floor(score/10);
var sign = limits[Math.floor((score % 10)/3)]
return String.fromCharCode(lCode)+ sign;
}
score : <input id="scoreBox" type="text"/>
<input onclick="alert(convertScoreToGradeWithPlusAndMinus(scoreBox.value))" value="calculate" type="button"/>
So the first thing to notice is that if a condition is "true", your function returns. So the "else if"s can be replaced by simple "if"s... The other thing is that since your ranges are continuous, you don't really need to test for a max and min each time:
function convertScoreToGradeWithPlusAndMinus(score) {
if(score > 100 || score < 0) return "INVALID SCORE";
if(score >= 98) return "A+";
if(score >= 93) return "A";
if(score >= 90) return "A-";
if(score >= 88) return "B+";
if(score >= 83) return "B";
if(score >= 80) return "B-";
if(score >= 78) return "C+";
if(score >= 73) return "C";
if(score >= 70) return "C-";
if(score >= 68) return "D+";
if(score >= 63) return "D";
if(score >= 60) return "D-";
return "F";
}
var output = convertScoreToGradeWithPlusAndMinus(91);
console.log(output); // --> 'A-'
I don't know if you count this as less tedious? Personally, my preferred way is to make a data structure mapping limits to values, end then simple loop on that until I find the right value.
function convertScoreToGradeWithPlusAndMinus(score) {
if(score > 100 || score < 0) return "INVALID SCORE";
var map = [
{max: 98, grade: "A+"},
{max: 93, grade: "A"},
{max: 90, grade: "A-"},
{max: 88, grade: "B+"},
{max: 83, grade: "B"},
{max: 80, grade: "B-"},
{max: 78, grade: "C+"},
{max: 73, grade: "C"},
{max: 70, grade: "C-"},
{max: 68, grade: "D+"},
{max: 63, grade: "D"},
{max: 60, grade: "D-"}
];
for(var loop = 0; loop < map.length; loop++) {
var data = map[loop];
if(score >= data.max) return data.grade;
}
return "F";
}
You still have the tedious job of defining your map though - I don't think you can avoid it in a case like this one.
Hope this helps!
Answered a while ago, but I encountered this question too. I think the following provides a nice middle way between the other two answers:
function convertScoreToGradeWithPlusAndMinus(score) {
if (score > 100 || score < 0) return "INVALID SCORE";
// sign logic
let sign = "";
if (score % 10 < 3) sign = "-";
if (score % 10 > 7 || score === 100) sign = "+";
// letter logic
if (score < 60) return "F";
if (score < 70) return "D" + sign;
if (score < 80) return "C" + sign;
if (score < 90) return "B" + sign;
return "A" + sign;
}

Which style of code is better: being efficient or separating concerns?

I wonder if this might come down to personal taste or if there is a generally agreed upon answer to this. I've got a piece of code that could be written in one of two ways and though I think it's something of a trivial example in terms of efficiency, I'd like to know what the generally accepted answer is for future extrapolations.
Here's the code I currently have, essentially a score is passed and some text is updated accordingly. The colour of the text is also changed by the score value.
function getBSTotalText(score) {
var scoreText;
if (score >= 0 && score <= 12) {
scoreText = "0 - 12 HIGH RISK";
}
else if (score >= 13 && score <= 14) {
scoreText = "13 - 14 MODERATE RISK";
}
else if (score >= 15 && score <= 16) {
scoreText = "15 - 16 LOW RISK";
}
else if (score >= 16) {
scoreText = "16+ NO RISK";
}
else {
scoreText = "";
}
return scoreText;
}
function getBSTotalColour(score) {
var colour;
if (score >= 0 && score <= 12) {
colour = "red";
}
else if (score >= 13 && score <= 14) {
colour = "amber";
}
else if (score >= 15 && score <= 16) {
colour = "yellow";
}
else if (score >= 16) {
colour = "grey";
}
else {
colour = "white";
}
return colour;
}
Now I could easily refactor this into one function and just get it to return an array or object to save basically copying and pasting the same code into a distinct function which from my understanding would conform to DRY but then break SOLID. Would best practice be to keep these functions distinct or merge them into one?
In this example, I'd say there's a compelling reason to refactor to a single function as both functions are concerned with the same thing - getting some formatted text.
function getBSTotalDisplayInfo(score) {
var result = {};
if (score >= 0 && score <= 12) {
result.colour = "red";
result.scoreText = "0 - 12 HIGH RISK";
}
else if (score >= 13 && score <= 14) {
result.colour = "amber";
result.scoreText = "13 - 14 MODERATE RISK";
}
else if (score >= 15 && score <= 16) {
result.colour = "yellow";
result.scoreText = "15 - 16 LOW RISK";
}
else if (score >= 16) {
result.colour = "grey";
result.scoreText = "16+ NO RISK";
}
else {
result.colour = "white";
result.scoreText = "";
}
return result;
}
Check what part of the code is repeated and move that into an extra function. In your case it's actually quite easy:
function getBSTotal(score) {
// returns some kind of enum
if (score >= 0 && score <= 12)
return 0;
else if (score >= 13 && score <= 14)
return 1;
else if (score >= 15 && score <= 16)
return 2;
else if (score >= 16)
return 4;
else
return 5;
}
function getBSTotalText(score) {
// now map the enum either to a text
return ["0 - 12 HIGH RISK",
"13 - 14 MODERATE RISK",
"15 - 16 LOW RISK",
"16+ NO RISK"
][getBSTotal(score)] || "";
}
function getBSTotalColour(score) {
// … or map it to a color
return ["red",
"amber"
"yellow",
"grey",
"white"
][getBSTotal(score)];
}
You still can make it more efficient by evaluating getBSTotal(score) only once and passing that to the mapping functions instead of score.

Categories

Resources