As a recent assignment for my coding bootcamp, we've been asked to create a function that takes an array of numbers as an argument and outputs them to an array of letter grades. I am stuck!
I've tried re-working and refactoring my code, changing the placement of different parts of the program, looking through MDN...
let grades = []
function getLetterGrades(grades) {
let grade = grades.map
if (grade < 60) {
return "F";
} else if (grade < 70) {
return "D";
} else if (grade < 80) {
return "C";
} else if (grade < 90) {
return "B";
} else if (grade < 100) {
return "A";
}
console.log(grades);
}
getLetterGrades([95, 85, 71]);
The results will only output the numbers I've entered into the function call.
You are using .map() wrong. What you are doing is comparing the map method to a number. You are not executing anything.
function getLetterGrades(grades) {
return grades.map(function(grade) {
if (grade < 60) {
return "F";
} else if (grade < 70) {
return "D";
} else if (grade < 80) {
return "C";
} else if (grade < 90) {
return "B";
} else if (grade < 100) {
return "A";
}
});
}
var letters = getLetterGrades([95, 85, 71]);
console.log(letters)
Your main issue is this:
let grade = grades.map
You are not invoking the .map method with (), so instead grade is winding up holding a reference to the native map function. And, that function isn't a number, so none of your conditions become true, so you continue past the if statement and just log the array that you passed in.
Instead, you must invoke .map() and supply its required parameter (a function that will be called for each item in the source array). Your if statement should be the body of that function:
let grades = []
function getLetterGrades(grades) {
let letterGrades = grades.map(function(grade){
if (grade < 60) {
return "F";
} else if (grade < 70) {
return "D";
} else if (grade < 80) {
return "C";
} else if (grade < 90) {
return "B";
} else if (grade < 100) {
return "A";
}
});
console.log(letterGrades);
}
getLetterGrades([95, 85, 71]);
Look at this solution:
let grades = []
function getLetterGrades(grades) {
// add an array (grade) that will hold the output
let grade = []
// iterate over grades with forEach()
grades.forEach(item => {
// item will be equal 95 on the first iteration
// 85 on the second, and 71 on the third - these
// values come from the passed 'grades' parameter
if (item < 60) {
grade.push("F");
} else if (item < 70) {
grade.push("D");
} else if (item < 80) {
grade.push("C");
} else if (item < 90) {
grade.push("B");
} else if (item < 100) {
grade.push("A");
}
})
// console.log(grade) - NOT grades!
console.log(grade);
}
getLetterGrades([95, 85, 71]);
The problem was not with the method you chose - the problem was you didn't finish your function. Here's another solution with map():
let grades = []
function getLetterGrades(grades) {
let grade = grades.map(item => {
if (item < 60) {
return "F";
} else if (item < 70) {
return "D";
} else if (item < 80) {
return "C";
} else if (item < 90) {
return "B";
} else if (item < 100) {
return "A";
}
})
// console.log(grade) - NOT grades!
console.log(grade);
}
getLetterGrades([95, 85, 71]);
In this case the main difference between forEach() and map() is that map() returns a NEW array (that's why you return values in the function body), and forEach() doesn't (we had to create the array - grade- manually, and push values into this "hand-made" array).
Look below to see what would happen, if we used forEach() WITHOUT a manually created array:
// THIS IS NOT A GOOD SOLUTION!
// IT GIVES YOU THE ANSWER IN THIS SMALL EXAMPLE
// (so you see that it's possible)
// BUT IN ANY LARGER CODE THIS IS THE
// 100% SURE SOURCE OF ERRORS.
let grades = []
function getLetterGrades(grades) {
grades.forEach((item, index) => {
if (item < 60) {
grades[index] = "F";
} else if (item < 70) {
grades[index] = "D";
} else if (item < 80) {
grades[index] = "C";
} else if (item < 90) {
grades[index] = "B";
} else if (item < 100) {
grades[index] = "A";
}
})
// console.log(grades) - NOT grade!
console.log(grades);
}
getLetterGrades([95, 85, 71]);
(I used the second argument of forEach() - that's index) THIS IS NOT A GOOD SOLUTION! Why? We "destroyed" our original grades array by overwriting it in getLetterGrades() - DON'T DO THIS!
As stated on map() takes a function and runs it once on each object in the array. To be clear on how you're trying to use it:
function getLetterGrades(grade) {
if (grade < 60) {
return "F";
} else if (grade < 70) {
return "D";
} else if (grade < 80) {
return "C";
} else if (grade < 90) {
return "B";
} else if (grade < 100) {
return "A";
}
}
x = [95, 85, 71];
//=> [A, B, C]
x.map(getLetterGrades);
Functionally, this is what the other answers are doing, they just aren't naming the method.
Post edited to change link as comment pointed out better resource.
Related
// The challenge is to say if someone got 15 out of 20 questions, they would have 75% score, which is a C.
// 15/20 is 75%...you got a C (75%)!
// 90 to 100, A, B 80-89, C 70-79, D 60-69, F 0-59
How do I add the letter grades into my function string return function call?
let studentGrade = function (score, total =100) {
let totalGrade = (score / total)
let totalPercent = (totalGrade * 100)
if (score >=90 && score <=100) {
console.log('You got an A!')
}
else if (score >=80 && score <=89) {
console.log('You got an B!')
}
else if (score >=70 && score <=79) {
console.log('You got an C!')
}
else if (score >=60 && score <=69) {
console.log('You got a D!')
}
else if (score <=59 ) {
console.log('You got an E!')
}
return (`You scored ${score} of a total of ${total} questions, that is ${totalPercent}%, which is a X`)
}
let studentOne = studentGrade (50, 100)
console.log(studentOne)
Add an unset variable at the beginning like let thisGrade;. Set thisGrade to A or whatever the grade is, in the if-else logic.
Then you can use template substitution to include ${thisGrade} in your return value.
You can also reduce repetition by having only one console.log statement after the termination of the if-else logic, which is also referring to thisGrade.
Assuming that you're only interested in the letter being returned you could structure your code something like this.
let studentGrade = (score, total = 100) => {
const totalGrade = (score / total);
const totalPercent = (totalGrade * 100);
let grade;
if (score >=90 && score <=100) {
grade = "A";
} else if (score >=80 && score <=89) {
grade = "B";
} else if (...) {
...
} else {
...
}
console.log(`You got a ${grade}!`); // Could be grammatically incorrect but you could wrap logic to make this correct
return grade;
}
let studentOne = studentGrade(95, 100);
console.log(studentOne); // "A"
By doing this you have the option to remove the log statement from the studentGrade function entirely giving it the single responsibility of calculating the grade and not having to deal with the output.
Thank you, that helped!
let studentGrade = function (score, total) {
let totalPercent = (score / total) * 100
let letterGrade = ''
if (totalPercent >= 90) {
letterGrade = 'A'
}
else if (totalPercent >=80) {
letterGrade = 'B'
}
else if (totalPercent >=70) {
letterGrade = 'C'
}
else if (totalPercent >=60) {
letterGrade = 'D'
}
else {
letterGrade = 'F'
}
return `You scored ${score} of a total of ${total} questions, that is
${totalPercent}%, which is a ${letterGrade}`
}
let studentOne = studentGrade (50, 100)
console.log(studentOne)
I am trying to solve the Fizz Buzz question with an extra layer.
This is what I have so far. All this works fine but I need one more extra condition.
It's JS Unit testing
For any other input (valid or otherwise) return a string representation of the input
printFizzBuzz = function(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
} else if (i % 3 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else {
console.log(i);
}
}
};
Thank you!
You can use .toString() (JS toString) to change the number in string:
function printFizzBuzz(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
if (i % 3 === 0 && i % 5 === 0) {
console.log("FizzBuzz");
} else if (i % 3 === 0) {
console.log("FizzBuzz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else {
console.log(i.toString());
}
}
};
printFizzBuzz();
Looking at the question, it is not asking for a loop, it is asking for any value passed to the function. So the answer should look more like this
function printFizzBuzz(input) {
// Your code goes here
if (typeof input !== ‘number’) {
return String(input)
}
let by3 = input % 3
let by5 = input % 5
switch(0) {
case by3 + by5:
return "FizzBuzz"
case by3:
return "Fizz"
case by5:
return "Buzz"
default:
return input.toString()
}
}
}
If I was the interviewer, I would prefer the answer to look more like this
function printFizzBuzz(input) {
// Your code goes here
for (var i = 1; i <= 20; i++) {
let by3 = i % 3
let by5 = i % 5
switch(0) {
case by3 + by5:
console.log("FizzBuzz")
break
case by3:
console.log("Fizz")
break
case by5:
console.log("Buzz")
break
default:
console.log(i.toString())
}
}
}
}
printFizzBuzz()
I'm new to code so my mistake is probably obvious but,
When I go and test the calculator, it reads "A" then where ever the proper grade should be then Undefined. Idk where I'm going wrong.
I've tried a lot of different variations, and can't get the calculator to work properly. I'm not sure where the problem is.
function calculateGrade(grade) {if (parseInt >= "90"){
alert ("A");
}
else if (parseInt >= "80" === parseInt < "90"){
alert ("B");
}
else (parseInt >= "70" === parseInt < "80");{
alert ("C");
}
if (parseInt >= "60" === parseInt < "70"){
alert ("D");
}
else if (parseInt < "60"){
alert ("F");
}}
var inputGrade = prompt("Enter a grade:");
var parsedInt = parseInt(inputGrade);
var finalGrade = calculateGrade(parsedInt);
alert(finalGrade);
Suggestions and errors in your code
You already have parsed into number, so leave the '90' quotes from the numbers.
Don't use magic names and global variables. Your function accepts the grade argument. Use it in your code.
Your if else conditions are wrong. Some of them are without else if. You can left the second part of each else if conditions.
Return the final which you expect from the function.
function calculateGrade(grade) {
let final = '';
if (grade >= 90) {
final = 'A';
} else if (grade >= 80) {
final = 'B';
} else if (grade >= 70) {
final = 'C';
} else if (grade >= 60) {
final = 'D';
} else {
final = 'F';
}
return final;
}
let inputGrade = prompt("Enter a grade:");
let parsedInt = Number.parseInt(inputGrade);
let finalGrade = calculateGrade(parsedInt);
alert(finalGrade);
You could use a patttern with early exit and start frim the smallest value check to the greatest value.
The early exit returns a function and no more check is performed, because the function has ended with return statement.
For taking an integer value with parseInt, you should use a radix of 10, because without and with leading zero the number is treated as octal number, which you do not want.
A last advice, please do not use name of build in functions or objects or reserved words as variable names. This could lead to not proper working code and to searching without reason.
function calculateGrade(grade) {
if (grade < 50){
return "F";
}
if (grade < 60){
return "E";
}
if (grade < 70) {
return "D";
}
if (grade < 80) {
return "C";
}
if (grade < 90) {
return "B";
}
return "A";
}
var inputGrade = prompt("Enter a grade:"),
grade = parseInt(inputGrade, 10),
finalGrade = calculateGrade(grade);
console.log(finalGrade);
Try it
function calculateGrade(grade) {
if (grade < 60){
alert ("F");
}
else if (grade >= 60 && grade < 70){
alert ("D");
}
else if(grade >= 70 && grade < 80);{
alert ("C");
}
else if (grade >= 80 && grade < 90){
alert ("B");
}
else if (grade >= 90){
alert ("A");
}
}
var inputGrade = prompt("Enter a grade:");
var parsedInt = parseInt(inputGrade);
var finalGrade = calculateGrade(parsedInt);
alert(finalGrade);
1. Create a function toLetterGrade that takes an array of percentages and returns an array of corresponding grade letters. For example:
toLetterGrade([90,80,55,85]); //returns ["A","A-","C","A"]
2. Create a function toGradePoints that takes an array of letter grades and returns a corresponding array of grades points. For example:
toGradePoints(["A","A-","C","A"]); //returns [4.0,3.7,2.0,4.0]
3. Create a function GPA that takes an array of percentages and returns the corresponding grade point average.
I'm trying to do number 1, and this is the code I have so far, but it only gives me the letter grade for the last number in the array. What am I doing wrong?
var arr
function toLetterGrade(arr) {
for (i = 0; i < arr.length; i++) {
if (arr[i] >= 85) {
textG = "A";
} else if (arr[i] >= 80) {
textG = "A-";
} else if (arr[i] >= 75) {
textG = "B+";
} else if (arr[i] >= 70) {
textG = "B";
} else if (arr[i] >= 65) {
textG = "B-";
} else if (arr[i] >= 60) {
textG = "C+";
} else if (arr[i] >= 55) {
textG = "C";
} else if (arr[i] >= 50) {
textG = "D";
} else {
textG = "F";
}
}
return textG;
}
document.write(toLetterGrade([90, 80, 70]))
Output is B.
You are overwriting your variable with every cycle of the loop, that's why you are getting only one - the last grade.
I suggest you to use an empty array variable to store results inside.
With every loop you will assign new grade to the textG variable and then push it into the result array. The textG variable gets reseted with every loop textG = '' so there's no risk to duplicate/overwrite results.
After all cycles of the for loop, the result array is returned.
function toLetterGrade(arr) {
var textG = '';
var result = [];
for (i = 0; i < arr.length; i++) {
textG = '';
if (arr[i] >= 85) {
textG = "A";
} else if (arr[i] >= 80) {
textG = "A-";
} else if (arr[i] >= 75) {
textG = "B+";
} else if (arr[i] >= 70) {
textG = "B";
} else if (arr[i] >= 65) {
textG = "B-";
} else if (arr[i] >= 60) {
textG = "C+";
} else if (arr[i] >= 55) {
textG = "C";
} else if (arr[i] >= 50) {
textG = "D";
} else {
textG = "F";
}
result.push(textG);
}
return result;
}
document.write(toLetterGrade([90, 80, 70]))
For the first part, you could use an object and iterate the keys for the wanted grade.
function getGrade(p) {
var grade = 'F';
Object.keys(grades).some(function (k) {
if (p >= grades[k]) {
grade = k;
return true;
}
});
return grade
}
var grades = { A: 85, 'A-': 80, B: 70, 'B-': 65, 'C+': 60, C: 55, D: 50, F: '' }
console.log([90, 80, 55, 85].map(getGrade));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You're assigning the grade to a variable and then overwriting it with each iteration.
try textG.push('A') instead
You are overwriting your return value with each iteration.
Try creating an array, and adding the solution onto the array.
var solutionArr = [];
solutionArr.push("A");
jsfiddle
I make this simple code to check letter grade from a numerical
const letterGrade = (n) => {
let resultGrade = "";
if (n >= 90) {
resultGrade = "A";
} else if (n >= 80 || n > 89) {
resultGrade = "B";
} else if (n >= 70 || n > 79) {
resultGrade = "C";
} else if (n >= 60 || n > 69) {
resultGrade = "D";
} else if (n < 59) {
resultGrade = "E";
} else {
alert("Input your grade first");
}
return `Your grade is ${resultGrade}`;
};
console.log(letterGrade(75));
I have a randomizer that gives me 6 different letters and 6 different numbers. This is going to, in the end, be used for a hex number.
I am trying to create a randomizer that will choose between the number or the letter for each slots of the hex (1-6).
I can create one that chooses in between them, but once it chooses, it doesn't know what they number to letter transition was
Example:
if (mega === 1) {
return "a";
}
It does not remember that transition once inside of the letter/number chooser.
If anyone understands what I'm getting at, please help! Thank you. :)
//edit -- entire code
`
Variables Below Here
//Numbers
var ayy2 = Math.random() * 10;
var ayy = Math.floor(ayy2);
var lmd2 = Math.random() * 10;
var lmd = Math.floor(lmd2);
var qua2 = Math.random() * 10;
var qua = Math.floor(qua2);
var abc2 = Math.random() * 10;
var abc = Math.floor(abc2);
var cdf2 = Math.random() * 10;
var cdf = Math.floor(cdf2);
var lgt2 = Math.random() * 10;
var lgt = Math.floor(lgt2);
//Letters
var mega2 = Math.random() * 7;
var mega = Math.floor(mega2);
var nade2 = Math.random() * 7;
var nade = Math.floor(nade2);
var shot2 = Math.random() * 7;
var shot = Math.floor(shot2);
var suck2 = Math.random() * 7;
var suck = Math.floor(suck2);
var pepe2 = Math.random() * 7;
var pepe = Math.floor(pepe2);
var lols2 = Math.random() * 7;
var lols = Math.floor(lols2);
//Choices Between Hexes\\
var shrek2 = Math.random() * 3;
var shrek = Math.floor(shrek2);
var tpkek2 = Math.random() * 3;
var tpkek = Math.floor(tpkek2);
var waffl2 = Math.random() * 3;
var waffl = Math.floor(waffl2);
var snipe2 = Math.random() * 3;
var snipe = Math.floor(snipe2);
var optic2 = Math.random() * 3;
var optic = Math.floor(optic2);
var fazed2 = Math.random() * 3;
var faze = Math.floor(fazed2);
// Just for Dylan: ff88c6
//Functions Below Here\\
//Letter Returns
function returnLetter1() {
if (mega === 1) {
return "a";
}
if (mega === 2) {
return "b";
}
if (mega === 3) {
return "c";
}
if (mega === 4) {
return "d";
}
if (mega === 5) {
return "e";
}
if (mega === 6) {
return "f";
} else {
return "f";
}
}
function returnLetter2() {
if (nade === 1) {
return "a";
}
if (nade === 2) {
return "b";
}
if (nade === 3) {
return "c";
}
if (nade === 4) {
return "d";
}
if (nade === 5) {
return "e";
}
if (nade === 6) {
return "f";
} else {
return "f";
}
}
function returnLetter3() {
if (shot === 1) {
return "a";
}
if (shot === 2) {
return "b";
}
if (shot === 3) {
return "c";
}
if (shot === 4) {
return "d";
}
if (shot === 5) {
return "e";
}
if (shot === 6) {
return "f";
} else {
return "f";
}
}
function returnLetter4() {
if (suck === 1) {
return "a";
}
if (suck === 2) {
return "b";
}
if (suck === 3) {
return "c";
}
if (suck === 4) {
return "d";
}
if (suck === 5) {
return "e";
}
if (suck === 6) {
return "f";
} else {
return "f";
}
}
function returnLetter5() {
if (pepe === 1) {
return "a";
}
if (pepe === 2) {
return "b";
}
if (pepe === 3) {
return "c";
}
if (pepe === 4) {
return "d";
}
if (pepe === 5) {
return "e";
}
if (pepe === 6) {
return "f";
} else {
return "f";
}
}
function returnLetter6() {
if (lols === 1) {
return "a";
}
if (lols === 2) {
return "b";
}
if (lols === 3) {
return "c";
}
if (lols === 4) {
return "d";
}
if (lols === 5) {
return "e";
}
if (lols === 6) {
return "f";
} else {
return "f";
}
}
//Return Numbers
function returnNumber1() {
var zz = qua;
return zz;
}
function returnNumber2() {
var mm = lmd;
return mm;
}
function returnNumber3() {
var hh = ayy;
return hh;
}
function returnNumber4() {
var jj = abc;
return jj;
}
function returnNumber5() {
var ww = cdf;
return ww;
}
function returnNumber6() {
var rr = lgt;
return rr;
}
/*
This next little bit here is for my enjoyment and because it's necessary for the script. :P
*/
//Obviously, the above are to get a number of 1 or 2 (0 being else so 66/33% chances w/e) to find out if it will be a number or letter.
//But, I can't find a way for the function below to show me what the hexes will be WITH the number>letter from the returnL's.
//Could it be that I possibly would have to move the mega === x below the hexchoices? sigh
function returnHexChoice1() {
if (shrek === 1) {
return zz;
} else {
return mega;
}
}
//Finals of the script display necessary.
//DID I WIN???????
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ )
{
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function hex() {
return "philosophy";
}
Wow, you are pretty impressive with variable naming. I usually name mines "fart" or something like that. That is also because if you try to make use of constructs of a programming language, you will not need as many variables.
Before you ask any other questions, tou might want to check out a tutorial. If javascript is what is interesting you, try here : for example here : http://www.htmldog.com/guides/javascript/. Learn about functions, arrays, etc.
For example, all your returnLetterX() are the same except they use a different value. Try making just one returnLetter(value) that uses value to know what to return. Also, instead of a long set of if/else statements on the same variable, you can use a switch. That's exactly what they're made for !
Then your returnNumberX functions don't do anything, except map from your names to the number. You might want to use arrays, so you have less names.
Finally, all your rand() calls at the start are repetitive as well. Combined with arrays, you can easily do this in a loop.
Your code then could look something like :
function letter(let)
{
switch(let)
{
case 0: return 'a';
case 1: return 'b';
case 2: return 'c';
case 3: return 'd';
case 4: return 'e';
case 5: return 'f';
}
// even better, use an array :
// var abcdef = ['a', 'b', 'c', 'd', 'e', 'f'];
// return abcdef[let];
}
function hexChoice(num, let, choice)
{
if (choice == 0) // 0 for 33%, 1-2 for 67%
return letter(let);
else
return num;
}
// this is not the best way to pick hex values !
for(var i=0; i<6; i++)
{
var number = Math.floor( Math.random() * 10 );
var letter = Math.floor( Math.random() * 6 ); // there are only 6 letters !
var letnum = Math.floor( Math.random() * 3 );
var hex_digit = hexChoice(number, letter, letnum);
// now do something with your hex digit... print it, add it to the "color" string ?
}
You can see it's much smaller, and much easier to read for a programmer.
Once you understand all this code and you are capable to write something similar by yourself you can wonder what is the best way to pick a a random hex digit, though it already is in the getRandomColor you copied from somewhere. Search the internet (this site, tutorials...) it is a question that is asked a lot already and does not need re-asking.