Recursively setting a value depending on range using JavaScript - javascript

I don't know how to word this but this is what I'm trying to do:
if (score >= 0 && score <= 10) overallScore = 0;
else if (score >= 11 && score <= 20) overallScore = 1;
else if (score >= 21 && score <= 30) overallScore = 2;
else if (score >= 31 && score <= 40) overallScore = 3;
else if (score >= 91 && score <= 100) overallScore = 9;
...
Is there any way to recursively do this using a function?

overallScore = Math.max(0, Math.floor((score - 1) / 10));
no need for recursion. But if you need that:
const getOverall = score => score <= 10 ? 0 : getOverall(score - 10) + 1;

Recursion is not really appropriate here, since you can get the required value in constant time. Recursion becomes interesting when you need at least O(logn) time.
But as you ask for it, here is one way to make it recursive:
function range(score, depth = 0) {
return score <= 10 || depth >= 9 ? 0 : range(score-10, depth+1) + 1;
}
console.log(range(0)); // 0
console.log(range(10)); // 0
console.log(range(11)); // 1
console.log(range(60)); // 5
console.log(range(91)); // 9
console.log(range(110)); // 9

Related

Different result of an if else on Javascript [duplicate]

This question already has answers here:
What's the prettiest way to compare one value against multiple values? [duplicate]
(8 answers)
Closed 1 year ago.
I don't know why I keep getting the console.log from if statement even both averages are above 100.
Where did I put my mistake?
const dolphinsScores = 97 + 112 + 101;
const dolphinsAverage = dolphinsScores / 3;
const koalasScores = 109 + 95 + 123;
const koalasAverage = koalasScores / 3;
console.log(dolphinsAverage);
console.log(koalasAverage);
if (dolphinsAverage || koalasAverage < 100) {
console.log('One of the team is already lost')
} else if (dolphinsAverage > koalasAverage) {
console.log('Team Dolphins are the winner of the competition! 🐬🎉');
} else if (koalasAverage > dolphinsAverage) {
console.log('Team Koalas are the winner of the competition! 🐨🎉');
}
this statement
if (dolphinsAverage || koalasAverage < 100)
resolve as
if (true || koalasAverage < 100)
what you need is
if (dolphinsAverage < 100 || koalasAverage < 100)
Your if condition was checking if there is any value in dolphinsAverage which will always be true if there is any value in dolphinsAverage. So try this if you want to know if dolphinsAverage's value is less than 100.
if (dolphinsAverage < 100 || koalasAverage < 100) {
console.log('One of the team is already lost')
} else if (dolphinsAverage > koalasAverage) {
console.log('Team Dolphins are the winner of the competition! 🐬🎉');
} else if (koalasAverage > dolphinsAverage) {
console.log('Team Koalas are the winner of the competition! 🐨🎉');
}
const dolphinsScores = 97 + 112 + 101;
const dolphinsAverage = dolphinsScores / 3;
const koalasScores = 109 + 95 + 123;
const koalasAverage = koalasScores / 3;
console.log(dolphinsAverage);
console.log(koalasAverage);
if ((dolphinsAverage < 100) || (koalasAverage < 100)) {
console.log('One of the team is already lost')
} else if (dolphinsAverage > koalasAverage) {
console.log('Team Dolphins are the winner of the competition! 🐬🎉');
} else if (koalasAverage > dolphinsAverage) {
console.log('Team Koalas are the winner of the competition! 🐨🎉');
}
your if statement should be
if (dolphinsAverage < 100 || koalasAverage < 100) {

Greater than X but less than Y javascript

I am new here, but i'm simply trying to figure out why this javascript is not working in my math program.
For the last two IF statements, i'm comparing numbers. Greater than X but less than Y...
(function(){
if(fieldname4-fieldname3 < 30) return (1));
if ((fieldname4-fieldname3 > 31) && (fieldname4-fieldname3 < 60)) return
(2);
if ((fieldname4-fieldname3 > 60) && (fieldname4-fieldname3 < 90)) return
(3);
})();
Thanks for any help you can give me.
EDIT: I'm going to post the full script when i'm back to my compuer. Sorry for being so vague. It wasn't intentional. I'm still learning.
You can try to write a better code. For example:
(function(){
if(fieldname4-fieldname3 < 30){
return 1; //returns 1 for every number smaller then 30
}
if(fieldname4-fieldname3 >= 30 && fieldname4-fieldname3 <= 60){
return 2; // returns 2 for every number smaller then 60(includes 60) and greater then 30(includes 30)
}
if(fieldname4-fieldname3 > 60 && fieldname4-fieldname3 < 90){
return 3; // returns 3 for number smaller then 90 and greater then 60
}
})();
I hope that this will help you
Just shooting at it in the dark without seeing the script but how about this??
function test (fieldname4, fieldname3) {
var fieldResult = fieldname4 - fieldname3;
if(fieldResult < 30) {
return 1;
} else if ((fieldResult > 31) && (fieldResult < 60)) {
return 2;
} else if ((fieldResult > 60) && (fieldResult < 90)) {
return 3;
}
};

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

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.

Error in JavaScript return code?

Here is the javascript code:
There is an error in code where nightSurcharges is added to total cost even if pickUptime is less than 20.
function TaxiFare() {
var baseFare = 2;
var costPerMile = 0.50;
var nightSurcharge = 0.50; // 8pm to 6am, every night //its flat 0.50 and not per mile
var milesTravelled = Number(document.getElementById("miles").value) || 0;
if ((milesTravelled < 1) || (milesTravelled > 200)) {
alert("You must enter 1 - 200 miles");
document.getElementById("miles").focus();
return false;
}
var pickupTime = Number(document.getElementById("putime").value) || 0;
if ((pickupTime == "") || (pickupTime < 0) || (pickupTime > 23)) {
alert("The time must be 0-23 hours");
document.getElementById("putime").focus();
return false;
}
var cost = baseFare + (costPerMile * milesTravelled);
// add the nightSurcharge to the cost if it is after
// 8pm or before 6am
if (pickupTime >= 20 || pickupTime < 6) {
cost += nightSurcharge;
}
alert("Your taxi fare is $" + cost.toFixed(2));
}
I want nightSurcharge to be added only when pickupTime is >=20, but that's not working right now.
Any help is appreciated. Thanks
This seems obvious to me.
if (pickupTime >= 20 || pickupTime < 6) {
cost += nightSurcharge;
}
This code right here adds nightSurcharge to the cost if pickupTime is greater than or equal to 20, OR less than 6. So of course it's added if it's less than 6.
if (pickupTime >= 20) {
cost += nightSurcharge;
}
Now it will only add to it if it's greater or equal to 20.
your code is:
if (pickupTime >= 20 || pickupTime < 6)
so if pickupTime is less then 6 it'll enter the if as well
http://jsfiddle.net/7rdzC/

Categories

Resources