FAQ: Code Challenges: JavaScript Fundamentals - calculateWeight()

Hi there !

I tried to use an if / else if / else statement for this exercise. When I try the example given in the exercise, ie. console.log(calculateWeight(100, ‘Jupiter’)); , I get 37.8 as if I entered ‘Mercury’ as the second argument.
I can’t seem to find out the reason, can you help me please ? Here’s my code :

const calculateWeight = (earthWeight, planet) => {
  if (planet = 'Mercury') {
    return earthWeight * 0.378;
  } else if (planet = 'Venus') {
    return earthWeight * 0.907;
  } else if (planet = 'Mars') {
    return earthWeight * 0.377;
  } else if (planet = 'Jupiter') {
    return earthWeight * 2.36;
  } else if (planet = 'Saturn') {
    return earthWeight * 0.916;
  } else {
    return 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.';
  };
};

That is an assignment operator being used to check for identity. The correct operator is ===.

1 Like

I was wondering if in this case, the user input a UpperCase string. How we could handle it? I have tried something but it’s not working. Follow bellow my code

// Write your function here:

const calculateWeight = (earthWeight, planet) => {
  String.toLowerCase(planet)
  if (planet === 'jupiter'){
    return earthWeight * 2.36
  } else if (planet === 'mercury'){
    return earthWeight * 0.378
  } else if (planet === 'venus'){
    return earthWeight  * 0.907
  } else if (planet === 'mars'){
    return earthWeight  * 0.377;
  } else if (planet === 'saturn'){
    return earthWeight  * 0.916;
  } else {
    return 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.'
  }  
}

// Uncomment the line below when you're ready to try out your function
console.log(calculateWeight(100, 'JUPITER')) // Should print 236

// We encourage you to add more function calls of your own to test your code!

looking at the documentation:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase

we can read that toLowerCase returns the converted string.

In this example that you presented me, they attribute the string to a variable, I tried to do the same passing the parameter to the lowercase function and didnt work as well. Doesn’t it work for parameters?

// Write your function here:


const calculateWeight = (earthWeight, planet) => {
  planet.toLowerCase()
  if (planet === 'jupiter'){
    return earthWeight * 2.36
  } else if (planet === 'mercury'){
    return earthWeight * 0.378
  } else if (planet === 'venus'){
    return earthWeight  * 0.907
  } else if (planet === 'mars'){
    return earthWeight  * 0.377;
  } else if (planet === 'saturn'){
    return earthWeight  * 0.916;
  } else {
    return 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.'
  }  
}

// Uncomment the line below when you're ready to try out your function
console.log(calculateWeight(100, 'JUPITER')) // Should print 236

// We encourage you to add more function calls of your own to test your code!

.toLowerCase() works fine, it just returns a lower case copy of the original string, it doesn’t mutate the string itself.

Currently, you do nothing with the returned lower case string.

1 Like

I got it! Thank you! I attributed the value of the parameter into a variable and I evoked the variable on the if statement instead the parameter. Worked fine!

const calculateWeight = (earthWeight, planet) => {
    let lower 
    lower = planet.toLowerCase()
    if (lower === 'jupiter'){
      return Math.round(earthWeight * 2.36)
    } else if (lower === 'mercury'){
      return Math.round(earthWeight * 0.378)
    } else if (lower === 'venus'){
      return Math.round(earthWeight  * 0.907)
    } else if (lower === 'mars'){
      return Math.round(earthWeight  * 0.377)
    } else if (lower === 'saturn'){
      return Math.round(earthWeight  * 0.916)
    } else {
      return 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.'
    }  
  }

  console.log(calculateWeight(100, 'JuPiTer')) // Should print 236

Whilst playing around on this challenge, I wrote the following code:


const calculateWeight = (earthWeight, planet) => {
if (planet != ‘Mercury’ || ‘Venus’ || ‘Mars’ || ‘Jupiter’ || ‘Saturn’) {
return ‘Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.’
} else if (planet=‘Jupiter’) {
return ‘Jupiter’;
}
}

console.log(calculateWeight(100, ‘Jupiter’))

It prints “Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.” to the console.

Whilst I know that this isn’t the right logical route to answer the challenge, I can’t work out why it doesn’t print ‘Jupiter’ to the console??
The weird thing is that whilst battling it I tried the following code in the second line:
if (planet != ‘Jupiter’) {

And it then worked as I’d expect, by printing Jupiter to the console.

Please can someone explain where I went wrong with the logical test?

Many thanks

you seem to be pretty close to figuring out the problem? What if you attempt:

if (planet != ‘Jupiter’ || 'Venus' )

what happens then? Combined what you already know, clearly 'venus' is true for some reason. What if we then do:

if ('Venus')

what happens then? What does this tell us?

Well my thinking is that it’s something about the || not working how I’d expect with the !=

What I think I’m asking the function to do is check that the planet DOES NOT equal Mercury OR Venus OR Mars etc etc. (I put capitals to emphasise the logic)
If that test is true, then return the error message.
If that test is not true, then continue to the else if and return the string ‘Jupiter’.

I’m afraid I’m not sure what you mean about the ‘venus’ bit you wrote?

Thanks for the help :slight_smile:

if you try all the code samples i provided, what do we learn from that?

Or Venus doesn’t equal what? Or Mars doesn’t equal what?

Thanks - I did try them, but I didn’t see what you where getting at…
But I think I may now understand what you mean!!

If I just have the two, like you wrote:

if (planet != ‘Jupiter’ || ‘Venus’ )

Then if I test for Jupiter, that statement will be true, because Jupiter does not equal Venus! Hence it will display the error message.

Problem is that I can’t work out how to do a test that works how I’m intending, as if I use && then obviously it’s a totally different test, as (I think) it would test that the string matches all of them. Somehow I need to give a list of conditions to test against, where the test comes back true only if the string is not found amongst the list I’m testing for…

you don’t do this comparison? In fact, you don’t do any comparison with 'Venus', so JS will simply see if 'Venus' is a truthy value, which is why included this code sample:

if ('Venus')

where for humans its obvious that:
check that the planet DOES NOT equal Mercury OR Venus OR Mars etc etc

we really mean: check that planet does not equal Mercury or that the planet does not equal Venus etc. For a computer, this isn’t the case.

Please can I ask then, just for my learning (not for this particular challenge where I could solve it with an ‘else’ at the end of the function), how would I do a test that behaved as I intended?
i.e. quickly check that a string does not match a list of options, without writing a long “if, else if” statement?

Another strange one for me. When running the tests on my code I’m getting the right results in the console (so an answer of 236 when using ‘Jupiter’ and an answer of ‘Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.’ when using any string other than the names of the prescribed planets.

As far as I can see I’m satisfying the criteria of the tests, I’m not getting any error messages but the test continues to fail for me.

Again would someone mind having a look at my code for anything obvious:

// Write your function here:
const calculateWeight = (earthWeight, planet) => {
  if (planet === 'Mercury') {
    return earthweight * 0.378;
  } else if (planet === 'Venus') {
    return earthweight * 0.907;
  } else if (planet === 'Mars') {
    return earthWeight * 0.377;
  } else if (planet === 'Jupiter') {
    return earthWeight * 2.36;
  } else if (planet === 'Saturn') {
    return earthWeight * 0.916;
  } else {
    return 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.';
  }
}

// Uncomment the line below when you're ready to try out your function
console.log(calculateWeight(100, 'Jupiter')) // Should print 236

// We encourage you to add more function calls of your own to test your code!

You have a couple of earthweights rather than earthWeights in there (i.e. capitalised W)

AHHHHHH! I did the same thing last night. I’ve got to stop trying to code when I should be asleep.
Thanks for your help.

we would need some kind of list (array), and then check if the element is in the array. We could do this manually using a loop, but given this is a common use case, someone already wrote a higher order function (includes) for it.

Great thanks - we haven’t covered arrays or loops, so I’ll hold out for future lessons!

Extra Study

The following makes use of an object with planet properties, and a logical expression to resolve the return value.

 > const calculateWeight = (earthWeight, planet) => {
     return {
       'Mercury': 0.378,
       'Venus': 0.907,
       'Mars': 0.377,
       'Jupiter': 2.36,
       'Saturn': 0.916
     }[planet] * earthWeight || 'Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn.';
   }
<- undefined
 > calculateWeight(100, 'Jupiter')
<- 236
 > calculateWeight(100, 'Pluto')
<- "Invalid Planet Entry. Try: Mercury, Venus, Mars, Jupiter, or Saturn."

When the planet is not found in the property list, the result of the math is either 0 or NaN (we can find this out with a little experimenting) which results in the default operand being returned.

 > a = {
     'Mercury': 0.378,
     'Venus': 0.907,
     'Mars': 0.377,
     'Jupiter': 2.36,
     'Saturn': 0.916
   }
<- {Mercury: 0.378, Venus: 0.907, Mars: 0.377, Jupiter: 2.36, Saturn: 0.916}
 > a['Pluto'] * 100
<- NaN

NaN is falsy, hence,

 > NaN || 'Default'
<- Default

Objects are not too hard to get a handle on but logical expressions take some study and practice to be able to formulate. Time well spent.

1 Like