Problem with a string: how to do a rating with javascript - javascript

I can't implement the function tipPercentage that takes the argument rating as a string and return the values:
terrible or poor, then returns 3
good or great, then returns 10
excellent, returns 20
none of the above, returns 0
the input format for custom testing must be that the first line contains a integer, n, denoting the value of rating
HELP FOR A BEGGINNER!!!

You can use a switch statement to do this relatively easily, we check the input rating, then return the relevant tip percentage.
If we don't have a tip percentage for the rating, we'll fall back to the default condition, and return 0.
One could also use a map, though a switch statement is probably more flexible.
// Takes rating as a string and return the tip percentage as an integer.
function tipPercentage(rating) {
switch ((rating + "").toLowerCase()) {
case "terrible":
case "poor":
return 3;
case "good":
case "great":
return 10;
case "excellent":
return 20;
default:
return 0;
}
}
let ratings = ["excellent", "good", "great", "poor", "terrible", "meh", null];
for(let rating of ratings) {
console.log(`tipPercentage(${rating}):`, tipPercentage(rating))
}

function tipPercentage(rating) {
switch(rating) {
case "terrible":
case "poor":
return 3; break;
case "good":
case "great":
return 10; break;
case "excellent":
return 20; break;
default:
return 0;
}
}

Instead of a switch statement you could simply use an object:
const tipPercentage = {
'excellent': 20,
'good': 10,
'great': 10,
'terrible': 3,
'poor': 3,
}
const myRatings = [
"excellent",
"good",
"great",
"terrible",
"whatever",
undefined
];
for (let rating of myRatings) {
// Tip percentage, or 0 if it doesn't exist
console.log(rating, tipPercentage[rating] || 0)
}

Related

How can i check two variables in a switch-case statement?

The question is something like this.
You are given a cubic dice with 6 faces. All the individual faces have a number printed on them. The numbers are in the range of 1 to 6, like any ordinary dice. You will be provided with a face of this cube, your task is to guess the number on the opposite face of the cube.
Ex:
Input:
N = 6
Output:
1
Explanation:
For dice facing number 6 opposite face
will have the number 1.
I did it using a normal switch-case by checking all six faces and returning the respective die face number value, which passed my test cases. However, I need to simplify the code. Is it possible for me to do so?
oppositeFaceOfDice(N) {
//code here
switch(N){
case 1:return 6;
break;
case 6:return 1;
break;
case 2:return 5;
break;
case 5:return 2;
break;
case 3:return 4;
break;
case 4:return 3;
break;
default: return -1;
}
}
oppositeFaceOfDice(N) {
switch(N){
case 1||6 : return 6?1:6;
break;
case 2||5: return 2?5:2;
break;
case 3||4: return 4?3:4;
break;
}
}
Use an object literal instead of a switch statement:
function oppositeFaceOfDice(N) {
return {1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 1}[N];
}
Or use #DavidThomas' suggestion above which is particularly clever:
function oppositeFaceOfDice(N) {
if(N < 1 || N > 6) return undefined;
return 7 - N;
}
Other than rewriting the codes, since in your case, the codes are very clear and easy to debug, you can remove the break statement since it's not necessary.
oppositeFaceOfDice(N) {
//code here
switch(N){
case 1:return 6;
case 6:return 1;
case 2:return 5;
case 5:return 2;
case 3:return 4;
case 4:return 3;
}
}

Identify in which range a given number falls in array of object

I have an array of objects like
const score_card = [
{ "range":"0.6-1.5", "point":"10"},
{ "range":"1.6-2.5", "point":"20"},
{ "range":"2.6-3.5", "point":"30"},
{ "range":"3.6-4.5", "point":"40"},
{ "range":"4.6+", "point":"50"}
]
Now if I receive a number 1.7 then I need to find out that in which range it falls, so in my example it falls in 1.6-2.5 and associated points for it is 20.
Since the score_card array will be the same all the time, I have used switch case as follows:
let number = 1.7
switch(number) {
case (number>=0.6 || number<=1.5):
console.log('points : 10')
break;
case (number>=1.6 || number <=2.5):
console.log('points : 20')
break;
case (number >=2.6 || number <=3.5):
console.log('points : 30')
break;
case (number>=3.6 || number<=4.5):
console.log('points : 40')
break;
case (number>=4.6):
console.log('points : 50')
break;
default:
console.log('none')
}
Now the problem is the number (in our example 1.7) which we have passed in switch case is a part of an array and this switch case is written inside loop to get number one by one.Which makes code longer and possibly slower And I have to do this 4 more time for different cases.
So can anyone help me and suggest me a way to handle this efficiently?
You have to make changes for your last last condition/range
const score_card = [
{ "range": "0.6-1.5", "point": "10" },
{ "range": "1.6-2.5", "point": "20" },
{ "range": "2.6-3.5", "point": "30" },
{ "range": "3.6-4.5", "point": "40" },
{ "range": "4.6+", "point": "50" }
]
const getPoints = score => {
let points = 0;
score_card.some(slab => {
let [low, high] = slab.range.split('-');
if (score >= +low && score <= +high) points = +slab.point;
})
return points;
}

JavaScript, I can not understand switch parameter

I recently started to study javascript
I'm currently watching Javascript course in Udemy.
While code challenging, There's something I cant get it about parameter of 'switch'
let john = {
fullName: 'John Smith',
bills: [124, 48, 268, 180, 42],
calcTips: function() {
this.tips = [];
this.finalValues = [];
for (let i = 0; i < this.bills.length; i++) {
let percentage;
let bill = this.bills[i]
switch (bill) { // If I put parameter as 'bill' variation, The result is only defalut.
case bill < 50:
percentage = 0.2;
break;
case bill >= 50 && bill < 200:
percentage = 0.15;
break;
default:
percentage = 0.1;
}
this.tips[i] = bill * percentage;
this.finalValues[i] = bill + bill * percentage;
}
}
}
john.calcTips();
console.log(john);
However
let john = {
fullName: 'John Smith',
bills: [124, 48, 268, 180, 42],
calcTips: function() {
this.tips = [];
this.finalValues = [];
for (let i = 0; i < this.bills.length; i++) {
let percentage;
let bill = this.bills[i]
switch (true) { // If I put 'ture' as a parameter, It work's. Why?
case bill < 50:
percentage = 0.2;
break;
case bill >= 50 && bill < 200:
percentage = 0.15;
break;
default:
percentage = 0.1;
}
this.tips[i] = bill * percentage;
this.finalValues[i] = bill + bill * percentage;
}
}
}
john.calcTips();
console.log(john);
I've searched in google about this problem.
But I can't find specific way to solve this issue.
I'll appreciate your help.
Switch statements compare values strictly. Which means that you can compare for the exact value of the switch variable.
switch (x) {
case 1: console.log(1); break;
case 2: console.log(2); break;
}
You can do a trick however if you want to make the switch statement work on numerical ranges like this:
var x = this.dealer;
switch (true) {
case (x < 5):
alert("less than five");
break;
case (x < 9):
alert("between 5 and 8");
break;
case (x < 12):
alert("between 9 and 11");
break;
default:
alert("none");
break;
}
The implementation works on the strict comparison of booleans. The switch statement is for true and will match wherever the case is true.
Related question: Switch on ranges of integers in JavaScript
The switch statement tests the value of a variable and compares it with multiple cases. Once the case match is found, a block of statements associated with that particular case is executed. So in this case you switching on a constant value.
More detail :
javascript: using a condition in switch case

Letter grade value to number value then averaged

I'm writing a script for my schools web form for calculating credits and gpa values. When I run the input for letter grades I convert to uppercase and then check with if/else statements for A-F options and convert the value of the input to a number value which is then passed to another function to average the total for the column inputs which is then returned back to a letter grade. The issue i'm having is that when i use my keyup jquery function it returns a NaN value instead of a letter... HELP
function CalcGPA(a,b,c,d,e,f,g,h,i,j){
var initial=a+b+c+d+e+f+g+h+i+j;
var total=initial/10;
return total;}
function Convert(a){
var b=a.value.toUpperCase();
if(b.value="A")
{
b=4.0;
return b;
}
else if(b.value="A-")
{
b=3.67;
return b;
}
else if(b.value="B+")
{
b=3.33;
return b;
}
else if(b.value="B")
{
b=3.0;
return b;
}
else if(b.value="B-")
{
b=2.67;
return b;
}
else if(b.value="C+")
{
b=2.33;
return b;
}
else if(b.value="C"){
b=2.0;
return b;
}
else if(b.value="C-")
{
b=1.7;
return b;
}
else if(b.value="D")
{
b=1.0;
return b;
}
else {
b=0.0;}
return b;}
function toLetter(a){
if(a<=4||a>=3.68)
{
a="A";
}
else if(a<=3.67 || a>=3.34)
{
a="A-";
}
else if(a<=3.33 || a>=3.1)
{
a="B+";
}
else if(a<=3.0 || a>=2.68)
{
a="B";
}
else if(a<=2.67 || a>=2.34)
{
a="B-";
}
else if(a<=2.33 || a>=2.1)
{
a="C+";
}
else if(a<=2.0 || a>=1.8)
{
a="C";
}
else if(a<=1.7 || a>=1.4)
{
a="C-";
}
else if(a<=1.3 || a>=1.1)
{
a="D+";
}
else if (a=1.0)
{
a="D";
}
else {
a="F";}
return a;}
You should use parseInt or parseFloat in your toLetter function I suppose, and in your if statements, use two equal signs instead of one in order to compare:
function toLetter(a) {
var a = parseInt(a); //or parseFloat if you need decimals.
//rest of your code...
I strongly recommend a little refactoring here, for instance, instead of declaring and then returning, just return:
else if(b.value == "B+")
{
return 3.33;
}
Another improvement, move your statements to a switch:
switch(b.value) {
case "B+" :
return 3.33;
case "B" :
return 3.0;
}
And, one thing I would do, instead of conditions or cases, use a map:
var scoresForValues = {
"A": 4.0,
"A-": 3.67,
"B+": 3.33 //Keep filling until you get all your values.
};
And then your Convert function would be really simple and short:
function Convert(a) {
var b = a.value.toUpperCase();
return scoresForValues[b];
}
Use parseInt for integers or if you want to use decimal values, use parseFloat.
There are a couple of things here:
First, you are trying to compare using "=", and that can't work. You need to use "==". For example, else if(b.value="C+") should be else if(b.value=="C+")
Second, you've made b a string when you declared it and assigned the input to it:
var b=a.value.toUpperCase();
So, don't assign the numerical value to it and return it, just return the numerical value. Same for your a variable in toLetter. Just return the letter value and you can bail out of all your elseif lines as soon as you have a match.
So, instead of a="B-";, just return "B-"
finally, you should probably use switch case instead of your pile of if... else if. NOTE: you don't need break; after return 3 (for instance) because a return bails you out of the function. If you're using case switch for anything not causing a return, leaving out break; will cause you a lot of hurt.
function Convert(a){
var b=a.value.toUpperCase();
switch (b) {
case "A":
return 4.0;
break;
case "A-":
return 3.67;
break;
case "B+":
return 3.33;
break;
case "B":
return 3;
break;
case "B-":
return 2.67;
break;
case "C+":
return 2.33;
break;
case "C":
return 2;
break;
case "C-":
return 1.67;
break;
case "D":
return 1;
break;
default:
return 0;
}

Javascript: for, switch and Math.rand in one and not working right

I'm currently working on an idle game and have encountered a problem.
I'm trying to create a function that will lessen the value of 1 of 6 variables (each represents a type of worker) a number of times. However, if one of these 6 variables is at 0, I need it to pick one of the other 5, and I can't get that to work.
With fiddling around, I have gotten this:
function killWorker(amount){
var job;
for (var i=0;i<amount;i++){
job = Math.floor((Math.random()*6)+1);
switch (job){
case 1:
if(unass_workers>0){
unass_workers -= 1;
}else{
i-=1;
}
case 2:
if(farm_workers>0){
farm_workers -= 1;
}else{
i-=1;
}
break;
case 3:
if(tree_workers>0){
tree_workers -= 1;
}else{
i-=1;
}
break;
case 4:
if(metMine_workers>0){
metMine_workers -= 1;
}else{
i-=1;
}
break;
case 5:
if(golMine_workers>0){
golMine_workers -= 1;
}else{
i-=1;
}
break;
case 6:
if(paper_workers>0){
paper_workers -= 1;
}else{
i-=1;
}
break;
default:
console.log("error: killWorker() didn't work properly");
break;
}
}
}
This worked when I did low amounts, but when I increased the amount higher the whole thing crashed. I'd be quite happy to drastically change the function if it would work better, and I am using jquery too if that could help get an easier or more effective solution.
As i said, what probably happens is that amount is larger than the sum of X_workers, resulting in an infinite loop.
A fix that keeps your logic correct would be to check that enough workers can be killed:
function killWorker(amount){
if (amount < unass_workers + farm_workers + ...) return "Genocide";
var job;
for (var i=0;i<amount;i++){
...
}
A better way to organize your data structures could be:
var workerNames = [ 'unass', 'farm', 'tree', 'metMine', 'golMine', 'paper' ];
var workers = {
unass : 23,
farm : 45,
tree : 6,
metMine : 99,
golMine : 3,
paper: 43
}
function getRandomLiveJobName() {
var jobs = workerNames.filter(function(name) {
return workers[name] > 0;
});
return jobs[Math.floor(Math.random()*jobs.length)];
}
function killWorkers(amount) {
for (;amount--;) {
var job = getRandomLiveJobName();
if (!job) return "Genocide";
workers[job]--;
}
}
killWorkers(150);
console.log(workers); // { farm: 0, golMine: 0, metMine: 64, paper: 5, tree: 0, unass: 0 }
Of course it could be optimized by not creating a new array each time you need a random live job by updating a single array inside killWorkers, but i think it's easier to read now.

Categories

Resources