Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Functions Pass Information Into Functions Function Declarations vs. Function Expressions

Grzegorz Zielinski
Grzegorz Zielinski
5,838 Points

Function problem - variable is getting ignored.

Hello,

After I finished one o the videos about functions I tried to write some function by myself to practice my skills a bit - create a function that ask for a low and high number, and then give a random number in range between those two numbers (Match.random).

Code

const min = prompt('low'); const max = prompt('high');

function getRandomNumber(min, max) { return Math.floor( Math.random() * (max - min) + min); }

console.log(`Random number from ${min} to ${max} is ${getRandomNumber(min, max)}.`);

As a result I'm getting number which is equal to Math.random() * (max - min) instead od Math.floor( Math.random() * (max - min) + min); and it seems like second variable "min" at the end of calculation is - for some reason, getting ignored by function.

I got pretty confused with this one, cause even MDN says that funcion should look like that:

MDN

MDN Math.random()

function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; }`

What looks exactly the same as the way I've done it.

Please help me with this one, thanks!

2 Answers

As far as I understand when you input a number through the prompt method, it turns the number into a string. There are multiple ways to convert this string value into a number value.

One method is to use the parseInt() method as highlighted below:

const min = parseInt( prompt("low") ); const max = parseInt( prompt("high") );

parseInt() method will attempt to convert the string into a number, specifically an integer. You can also try parseFloat() which does the same thing, but into a decimal number instead of an integer.

You can also try the unary method:

const min = prompt('low'); const max = prompt('high');

function getRandomNumber(+min, +max) { return Math.floor( Math.random() * (+max - +min +1) + +min); }

console.log(`Random number from ${+min} to ${+max} is ${getRandomNumber(+min, +max)}.`);

To be honest, I haven't tested this for you, but I don't see why it shouldn't work. The UNARY method of attaching the '+' immediately before the variable converts the string value into a number value. As far as I know, it won't work if you apply it to the variable when you declare it.

As for why it only works with the variable "min", interestingly when you apply any mathematical operator, -, /, * other than +, you will find the JS automatically tries to "automatically" convert the string into a number. if you use the + operator before converting it into a number you'll find it adds it like a string. For example:

const num1 = prompt("num1"); const num2 = prompt("num2"); // lets say you enter 60 and 70 respectively.
console.log(num1 + num2); // expected return = 6070, concatenating the two strings
console.log (num1 - num2); // = -10, converting both the variables into numbers

// After some testing, I think the main reason why it's ignoring the maximum value is: (lets assume max=20 and min=10)
(max - min +1) + min; // So without the Math.random method this returns 1110, because it's done 20-10+1=11, + "10"=1110

(Math.random() *  (max - min +1)) + min; 
/* With the method this returns NaN10, for some reason now the maths in parentheses is not a number and the string "10" is concatenated to the end! So where does this leave us?*/

{ return Math.floor( Math.random() * (max - min +1) + min); }
/* Testing this on the console returns NaN, so not sure what's going on here, but it makes sense that the reason your getting a random number between 0 and 10 is because it's returning 10, the min value only.*/

// Alternatively it could be that it's trying to do:
/*
Math.floor( Math.random() * (20 - 10 +1)  + "10"); so it actually makes more sense that your code is trying to do randomNum*11 = (lets say) 5.6 => Math.floor(5.6 + "10") must somehow ignore the string, therefore returning a random number between 0 and 5
*/

Sorry, if that's confusing, had to do some figuring out myself there. I'm not sure if this is even the reason why, but just what makes sense to me.

In conclusion, the whole "automatic" conversion of string to number returns some odd results and probably shouldn't be relied upon!

Grzegorz Zielinski
Grzegorz Zielinski
5,838 Points

Yes, first solution with adding "parseInt" works!

So the correct version of code is:

const min = parseInt(prompt('low')); 
const max = parseInt(prompt('high'));


function getRandomNumber(min, max) { 
  return Math.floor( Math.random() * (max - min +1) + min); 
}

console.log(`Random number from ${min} to ${max} is ${getRandomNumber(min, max)}.`);

About second part of your answer - I understand what you mean, and I've even decided to check it!

I've added console.log command before math calculations, and I've left "min" value without parseInt, which means when code uses it it's a string, and then casue there is "+" it turns it to a number instead of using it in calculation, thats why it was ignored in previous oryginal version of my code.

You can see it here, or by typing it into console:

const min = prompt('low'); 
const max = parseInt(prompt('high'));


function getRandomNumber(min, max) { 
    console.log(typeof(min));  // shows that min is still a sting
    console.log(typeof(max)); // already a number casue of parseInt()
  return Math.floor( Math.random() * (max - min +1) + min); // here - as you said, first min gets "automatically" converted to number cause of "-", but second one is not used as a part of calculation, instead of that "+" was used to turns it into number, that's why it was ignored before.

}

console.log(`Random number from ${min} to ${max} is ${getRandomNumber(min, max)}.`);

console.log(typeof(min));  //string
console.log(typeof(max)); //number

Thanks for help, and for explaining me that!

Steven Parker
Steven Parker
229,783 Points

The standard formula for a random number within inclusive limits is:

Math.floor(Math.random() * (max - min + 1) + min)

The formula in your examples is missing the "+ 1". See if that fixes it.

If not, please post the code using Markdown formatting (as I did here) and mention which limits you are testing it with.

Grzegorz Zielinski
Grzegorz Zielinski
5,838 Points

Thank you for your answer and for the link, I've used it to update my post and it looks more clear now :)

Unfortunately function doesn't work even if I add "+1" to it. After an edit i looks like that now:

Code

const min = prompt('low'); const max = prompt('high');

function getRandomNumber(min, max) { return Math.floor( Math.random() * (max - min +1) + min); }

console.log(`Random number from ${min} to ${max} is ${getRandomNumber(min, max)}.`);

Usually I type in 10 as a low, and 20 as a high and it still shows me numbers in range from 0 to 10. I've tried with other numbers as well and result is still the same - it shows the number below the range of a numbers I had typed in.

Like I wrote before - in my opinion second variable "min" in this code is getting ignored by a function for some reason, and I don't know why.

[EDIT]

When I delete

const min = prompt('low'); const max = prompt('high');

and I type in manualy for the example

sayGreeting(5,10)

Code works fine, it only gets confused when I get a numbers from prompt values.

Steven Parker
Steven Parker
229,783 Points

The results from "prompt" are strings. Before you do math on them, you should covert them to numbers:

const min = parseInt(prompt('low'));
const max = parseInt(prompt('high'));