JS: Grading System of a school Any Fix (Error== undefined) [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
A school has the following rules for the grading system:
// a. 45 to 50 - D
// b. 50 to 60 - C
// c. 60 to 80 - B
// d.Above 80 - A
Ask the user to enter marks, name as well as Roll No and print the corresponding grade
const school_grading_system = () => {
let student_details = {
name_of_student: prompt("Enter your name:"),
roll_number_of_student: Number(prompt("Enter your Roll No: ")),
marks_of_student: Number(prompt("Enter your marks out of 100: ")),
percentage_obtained_student: function() {
return ((this.marks_of_student / 100) * 100)
}
}
if (this.percentage_obtained_student >= 80 && this.percentage_obtained_student < 80) {
console.log(`${this.percentage_obtained_student}:Good Job! You have scored A Grade`)
} else if (this.percentage_obtained_student >= 60 && this.percentage_obtained_student < 60) {
console.log(`${this.percentage_obtained_student}: Good! You have obtained B Grade`)
} else if (this.percentage_obtained_student >= 50 && this.percentage_obtained_student < 60) {
console.log(`${this.percentage_obtained_student}: Good! You have obtained C Grade`)
} else if (this.percentage_obtained_student >= 45 && this.percentage_obtained_student < 50) {
console.log(`${this.percentage_obtained_student}: Good! You have obtained D Grade`)
}
}
console.log(school_grading_system())

// Rule 1: Kinda keep it simple
// As total marks are going to be 100 so no need for a percentage method
const school_grading_system = () => {
let student_details = {
name_of_student: prompt("Enter your name:"),
roll_number_of_student: Number(prompt("Enter your Roll No: ")),
marks_of_student: Number(prompt("Enter your marks out of 100: "))
}
if (student_details.marks_of_student >= 45 && student_details.marks_of_student < 50) {
return "Grade D"
} else if (student_details.marks_of_student >= 50 && student_details.marks_of_student < 60) {
return "Grade C"
} else if (student_details.marks_of_student >= 60 && student_details.marks_of_student < 80) {
return "Grade B"
} else if (student_details.marks_of_student >= 80 && student_details.marks_of_student <= 100) {
return "Grade A"
}
}
console.log(school_grading_system())
// Note: I have not displayed the name and marks stuff because I hope you are capable enough to do that so I am leaving that upon you

There are some problems within your code that lead to the result being wrong, let's break them down:
The use of this keyword in your school_grading_system (outside the student_details object) is the window object and NOT student_details object so when you try this.percentage_obtained_student that is translated to window.percentage_obtained_student and as window dosen't have an attribute called percentage_obtained_student the result of that call would be undefined that lead to deliver the wrong results. So instead of this.percentage_obtained_student you should use student_details.percentage_obtained_student to get the needed piece of data.
Another issue is the your conditions found on the if .. else statements. Let's imagine a student having 80 as his score, when you say student_details.percentage_obtained_student >= 80 && student_details.percentage_obtained_student < 80 this condition will never be satisfied because it negates itself as that conditon translates to IF the SCORE is greater than or equal to 80 AND the score is less than 80 but we cannot have a number bigger or equal and lower than itself at the same time (I couldn't describe more accurately).
With that being said, here's a corrected version of your code:
const school_grading_system = () => {
let student_details = {
name_of_student: prompt("Enter your name:"),
roll_number_of_student: Number(prompt("Enter your Roll No: ")),
marks_of_student: Number(prompt("Enter your marks out of 100: ")),
}
/** the conditons are now refined */
if (student_details.marks_of_student >= 80) {
console.log(`${student_details.marks_of_student}:Good Job! You have scored A Grade`)
} else if (student_details.marks_of_student >= 60) {
console.log(`${student_details.marks_of_student}: Good! You have obtained B Grade`)
} else if (student_details.marks_of_student >= 50) {
console.log(`${student_details.marks_of_student}: Good! You have obtained C Grade`)
} else if (student_details.marks_of_student >= 45) {
console.log(`${student_details.marks_of_student}: Good! You have obtained D Grade`)
}
}
school_grading_system();
By the way, you function has some unhandled cases, to mention some, it doesn't take into consideration the case of a score LESS THAN 45. Also, it doesn't handle wrong user inputs like when the user types a number higher than 100.

Here is a shorter way of doing the grading work:
// 45 to 50 - D
// 50 to 60 - C
// 60 to 80 - B
// Above 80 - A
const grades=[[101,"*** impossible - you must have cheated!"],[80,"A"],[60,"B"],[50,"C"],[45,"D"],[0,"E or below"]];
[95,23,57,-5,45,83,110,74,62].forEach(s=>
console.log(`your score of ${s} gets you the grade ${(grades.find(([g])=>s>=g)??[0,"below ZERO"])[1]}`))

Related

Grading Students in JS with recursion - Range Error

I was trying to work on this hackerrank problem.
Every student receives a grade in the inclusive range from
0-100 to .
Any less than 38 is a failing grade.
Sam is a professor at the university and likes to round each student's according to these rules:
If the difference between grade the and the next multiple of
5 is less than 3, round up to the next multiple of 5. If the value of grade is less than 38, no rounding occurs as the
result will still be a failing grade.
Given the initial value of for each of Sam's students, write code to
automate the rounding process.
My code is:
function gradingStudents(grades) {
const roundup = y => y + 1;
{
if ( grades < 38 || grades % 5 === 0) return grades;
else if ( grades % 5 < 4 && grades % 5 !== 0) return roundup(grades);
}
{
if (roundup % 5 === 0) return roundup;
else { gradingStudents(roundup + 1) }
}
}
gradingStudents(38) // -> 39
I tried to use Math.ceil(grades) inside the variable roundup but output didnt change. So, when you invoke the function with a number that is not before a multiple of 5 (e.g. 43) it returns the proceeding number. However, if it is the number before a multiple of 5 it gives a range error. "maximum call stack size reached."
As far as I got, the code doesnt proceed to the second part. Even if it did, I am not sure if it would fetch the current value of the function roundup when dealing with if statements in the second block.
What do I dont get in here?
Also, this is actually meant for an array output but since I am a beginner I am pretty much okay with this one for the start as well :D .
Javascript solution:
function gradingStudents(grades) {
return grades.map((grade) => {
if (grade > 37) {
const offset = 5 - (grade % 5);
if (offset < 3) {
grade += offset;
}
}
return grade;
});
}
Try this:
function gradingStudents(grades) { //input: 43
var finalGrade;
if(grade < 38)
return grades;
else{
var gradeDif = grades % 5; //3
if(gradeDif > 3){
return grades;
}
else {
return grades + (5 - gradeDif); //Output: 45
}
}
}
One solution calculates the next multiple of 5 no bigger than the grade and uses that value to test whether or not to round up (next5 - grade < 3).
We write a simple function to round an individual grade and then for a list of grades use .map with that function.
const roundGrade = (grade) => {
const next5 = 5 * Math.ceil (grade / 5)
return (grade < 38) ? grade : (next5 - grade < 3) ? next5 : grade
}
const gradingStudents = (grades) =>
grades .map (roundGrade)
console .log (gradingStudents ([73, 67, 38, 33]))
Note that, like most solutions to this problem, no recursion is needed.
1-Use the Array.prototypt.map according to the question logic.
const gradingStudents = (grades) => grades
.map(n => (n >= 38 && n % 5 >= 3)?(n + ( 5 - ( n % 5 ) )):n )
let result = gradingStudents([0,25,38,56,89,77,78,57,58])
console.log(result)
My solution is this
function gradingStudents(grades) {
grades.map((grade,i)=>{
if(grade >= 38){
let fg = (grade/5).toString().split('.');
if(fg[1]>5){
grades[i]=((parseInt(fg[0],10)+1) * 5);
};
}
});
return grades;
}
console.log(gradingStudents([73,67,38,33]));
my solution:
function gradingStudents(grades) {
return grades.map(function(grade) {
return (grade >= 38 && grade % 5 >= 3) ? grade + 5 - (grade % 5) : grade;
});
}

Why is my score for guessing the age not working?

I am creating a game that guesses the names from the images. There are 10 rounds in each game and after the 10 rounds there is a bonus round which you have to guess how old they are and you wager your points. You have to guess within 2 years of their age. If you guess right then the amount you wagered is added to your existing score. If it is incorrect then you score is decreased by the amount you wagered.
If i guess 2 below the actual age it adds up correctly.
If i guess the exact age it adds up correctly.
BUT if I guess 2 years above the actual age it decreases the score which it is not supposed to do. I don't know what i am doing wrong.
Here's a preview of my code:
var age = calcAge(celeb_q_a[celeb_q_a.length-1].dob);
age = age.toFixed(0);
alert(age);
var user_age = document.getElementById("answer-age").value;
var prev_score = score * 10;
if ((((age - 2) == user_age)) || (age == user_age) || ((2 + age) == user_age)) {
prev_score += (document.getElementById("wage").value * 1);
}else{
prev_score -= (document.getElementById("wage").value * 1);
}
I would suggest changing to a pair of "less than or equal" and "greater than or equal" to include all values between age+2 and age-2 respectively. I.e.
if ((age + 2) <= user_age && (age - 2) >= user_age) {
// do stuff
}
You can simplify the condition by testing for the ages that fail:
if ((age - 2) < user_age) || ((age + 2) > user_age) {
prev_score -= (document.getElementById("wage").value * 1);
} else {
prev_score += (document.getElementById("wage").value * 1);
}
You have to guess within 2 years of their age
You can simplify your ranged validation using below code:
/* run tests */
console.log(isAnswerCorrect(17, 20, 2)) // expect false
console.log(isAnswerCorrect(18, 20, 2)) // expect true
console.log(isAnswerCorrect(19, 20, 2)) // expect true
console.log(isAnswerCorrect(20, 20, 2)) // expect true
console.log(isAnswerCorrect(21, 20, 2)) // expect true
console.log(isAnswerCorrect(22, 20, 2)) // expect true
console.log(isAnswerCorrect(23, 20, 2)) // expect false
/* checker */
function isAnswerCorrect(guess, actual, range) {
if (guess < actual - range || actual + range < guess) {
return false
} else {
return true
}
}

Rounding up to the nearest multiple of 5

I am trying to write a Javascript function rounding up to the nearest multiple of 5. But you only round up if the difference between the variable and the roundup to the multiple of 5 is less than 3. (so 53 would round up to 55, but 52 would stay 52.)
Also if the grade is < 38 its an F.
The code below is what I have but it is not running properly. How can I fix it?
Thanks!!
grade = 71
function roundGrade (grade) {
const remainder = grade % 5
if (grade < 38) {
return "fail"; }
else if (remainder >= 3) {
grade; }
else if (remainder < 3) {
grade-remainder+5
}
}
If the remainder is 3 or above, you simply need to add 5 and subtract the remainder, which can be done with grade += 5 - remainder. Also note that you don't need your second else if conditional at all, as you only want to modify grade if the remainder is greater than or equal to 3. Finally, you need to make sure that your function actually returns grade with return grade.
This can be seen in the following:
function roundGrade(grade) {
const remainder = grade % 5;
if (grade < 38) {
return "fail";
} else if (remainder >= 3) {
grade += 5 - remainder;
}
return grade;
}
console.log(roundGrade(71));
console.log(roundGrade(74));
calculate the remainder of grade / 5 and add it to the grade if the remaining is less than 3, otherwise return the grade as is.
const grade1 = 71
const grade2 = 73
const grade3 = 33
function roundGrade(grade) {
if (grade < 38) return "fail"
const rem = grade % 5;
return rem < 3 ? grade : grade + (5 - rem)
}
console.log(roundGrade(grade1))
console.log(roundGrade(grade2))
console.log(roundGrade(grade3))

Codewars: Grasshopper - Grade book challenge

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.
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 ) {
return 'B';
} else if (score >= 70 ) {
return 'C';
} else if (score >= 60) {
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)}`));

Find the sum of a Javascript array and divide by its length

I'm almost embarrassed to ask this.
I'm a beginner programmer, and Javascript is very confusing to me. I managed to put together this much with the help of my instructor, but there are some simple things I can't get right.
I tried search Stack Overflow for a thread that would answer my question, but all of them I've seen contain code that I haven't learned about yet, so they're all just gibberish to me.
What I'm trying to do is add all the values of an Array and divide the sum by the array's length, ergo, find the average. The description of the assignment is find the average of any number of students' grades.
My two problems are
I can't figure out how to get the sum of all numeric values in the Array and,
For some reason, array.length returns one more than the actual length of the Array, even if I add a -1. (ex. if I enter 6 values, the array.length would return 7.)
I know where the problem is but I can't figure out what I need to enter. This assignment is due tomorrow, so anyone's time and effort is appreciated.
Here is my script:
<script type="text/javascript">
var allGrades = new Array();
var g = 0;
var l = 0;
var s = 0;
var t = 0;
do {
allGrades[g] = window.prompt("Please enter one grade for each window. After you enter a grade, enter an 'x' to see the average of the grades you entered.", "")
g++;
}
while (allGrades[g - 1] != "x")
for (l = 0; l < allGrades.length - 1; l++) {
s += allGrades[l] // Where I think the problem is
}
t == s / g - 1;
g == allGrades.length - 1; //
window.alert(g)
switch (t) {
case (t >= 90):
window.alert("Your average grade is " + (t) + ". " + "This is an A.")
break;
case (t >= 80 && t < 90):
window.alert("Your average grade is " + (t) + ". " + "This is a B.")
break;
case (t >= 70 && t < 80):
window.alert("Your average grade is " + (t) + ". " + "This is a C.")
break;
case (t >= 60 && t < 70):
window.alert("Your average grade is " + (t) + ". " + "This is a D.")
break;
case (t <= 60):
window.alert("Your average grade is " + (t) + ". " + "This is a failing grade.")
break;
}
</script>
I'm sorry if what I'm asking seems dumb. I've only been taking web programming for about two months, so I could really use some help!
Kyle
== is the comparison operator. You need to use the assignment operator (=) here:
t==s/g-1;
And the lines near it.
Also, for your own sake, do not use single-letter variable names unless you have a good reason for doing so.
Here's a cleaner way of writing the script:
var grades = [];
do {
var input = window.prompt("Please enter one grade for each window. After you enter a grade, enter an 'x' to see the average of the grades you entered.", "");
grades.push(parseFloat(input));
} while (input != 'x');
var sum = 0;
for (int i = 0; i < grades.length; i++) {
sum += grades[l];
}
var average = (sum / grades.length) * 100;
var grade;
if (average >= 90) {
grade = 'A';
} else if (average >= 80) {
grade = 'B';
} else if (average >= 70) {
grade = 'C';
} else if (average >= 60) {
grade = 'D';
} else {
grade = 'failing grade';
}
alert('Your average grade is ' + average + '. ' + 'This is a ' + grade);
t==s/g-1;
g==allGrades.length-1; //
Are both Comparisons, for assignment they should be
t=s/g-1;
g=allGrades.length-1;

Categories

Resources