Rounding up to the nearest multiple of 5 - javascript

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))

Related

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

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]}`))

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

How can I convert these 'if' statements to an algorithm

I'm trying to convert these 'if' statements to an algorithm, so that I can have many more stages instead of being limited to 10. How would I go about converting it? I just can't wrap my head around the logic!
function getStage(km) {
if (km > 2 && km < 4){
return 1;
}
else if (km > 4 && km < 6){
return 2;
}
else if (km > 6 && km < 8){
return 3;
}
else if (km > 8 && km < 10){
return 4;
}
else if (km > 10 && km < 12){
return 5;
}
else if (km > 12 && km < 14){
return 6;
}
else if (km > 14 && km < 16){
return 7;
}
else if (km > 16 && km < 18){
return 8;
}
else if (km > 18 && km < 20){
return 9;
}
else if (km > 20 && km < 22){
return 10;
}
}
I have tried this:
function getStage(km) {
var tempStage = 0;
for (var i = 0; i < stages; i++) {
var stage = i + 1;
var tempKm = stage * 2;
var nextKm = stage + 2;
if (km > tempKm && km < nextKm) {
tempStage = stage;
}
}
return tempStage;
}
Perhaps I shouldn't be using a for loop? Is there a better way of doing this?
Maybe you are looking for Math.floor
function getStage(km) {
return Math.floor(km / 2)
}
console.log(getStage(2));
// 1
console.log(getStage(10));
// 5
console.log(getStage(11));
// 5
You can just use math to do this. No loops or conditionals necessary.
Notice that your input intervals increase in "steps" of 2, and your outputs increase in "steps" of 1. This makes me think maybe we should divide km by 2.
Since we always want an integer answer, we can use the Math.floor function.
Some examples:
Math.floor(3/2) = 1
Math.floor(4.1/2) = 2
etc.
Depending on what you want to return for edge cases (what if km = 2 or km = 4, or any multiple of 2?) we might be done here. If you wish to return 1 when k=4, 2 when k=6, etc., you'll need to do a little more work.
*** In general: *** if you are working with numbers and you find yourself writing a lot of cases, you can usually use some combination of simple mathematical operators to calculate the result. For problems like these, try thinking about your input/output pairs, and what the relationship is between them.
You could take the floored value of km divided by two plus one.
10 is the upper limit.
function getStage(km) {
return Math.min((km >> 1) + 1, 10);
}
console.log(getStage(2.1)); // 2
console.log(getStage(3)); // 2
console.log(getStage(4)); // 4
Try something like this. This is general solution which applies not only to 2*n series.
const stages = [2, 4, 6, 8, 10, 13, 15, 16, 20]; //should be ordered. Else sort it first.
const getStage = km => stages.indexOf(stages.find(i => km < i));
console.log(getStage(5)); //2
console.log(getStage(1.5)); //0
console.log(getStage(8.1)); //4
console.log(getStage(15)); //7
console.log(getStage(22)); //-1 out of index

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

Check whether a number is divisible by another number If not make it divisable in Javascript

I want to check whether a number (7) is divisible by another number (5), If the number is divisible by the number then I need to return the same number. If the number is not divisible by another number I need to make it divisible and return the updated value.
var i =7;
if (i % 5 == 0) {
alert("divisible by 5");
} else {
alert("divisible not by 5");
}
Here if the condition satisfy then I need to return the same value. If the condition is not satisfied I need to add the required number and make it next divisible. (Like 7 is not divisible by 5 so I need add 3 to 7 and return the value 10 which is divisible by 5).
Are there any Math functions exists to implement the same?
What you want, it seems like, is this:
function roundTo(n, d) {
return Math.floor((n + d - 1) / d) * d;
}
For n 10 and d 5, you get 10 back. For n 7 and d 5, you also get 10. What the code does is add one less than the divisor to the input number, and then divides by the divisor. It then gets rid of any fractional part (Math.floor()) and multiplies by the divisor again.
You can do that by using a simple while loop:
function doThat(number, divider) {
while(number % divider !== 0) {
number++;
}
return number;
}
doThat(12, 5); // => returns 15
Here's a fiddle: https://jsfiddle.net/rdko8dmb/
You could use this algorithm:
i % n = r, where i = 7, n = 5, and r = 2.
Then, make i = i + (n - r). i.e. i = 7 + (5-2) → 10. Then you can use this for your division.
Try this
function divisible(dividend, divisor){
if (dividend % divisor == 0) {
return dividend;
} else {
var num = dividend + (divisor-(dividend % divisor));
return num;
}
}
var res = divisible(7, 5);
console.log(res);
Here is the fastest and cleanest way to do that:
function shift(number, divider)
{
return number + (divider - (number % divider)) % divider;
}
It takes number and moves it up by the difference from (our unit) divider to the remainder to make it divisible by the divider. The % divider makes sure that if there is no difference number doesn't get pushed up by a full unit of the divider.
I do not know if this will work for all numbers... But you might try this
7 % 5 = 2. If you subtract 2 from 5 you will get 3... This is the number you need to add to 7. 16 % 5 = 1 subtract 1 from 5 = 4 .. 4 + 16 = 20
Another example 16 % 13 = 3 ... 13-3 = 10 16+10 = 26 26/13 = 2
Here's an example of function that finds next higher natural number that is divisble by y
https://www.jschallenger.com/javascript-basics/find-next-higher-number
Option 1
while (x % y !== 0) x++;
return x;
}
Option 2
if(x % y == 0){
return x;
}
else{
for(i = x+1; i > x; i++){
if(i % y == 0){
return i;
}
}
}

Categories

Resources