I've tried to make a function where you're supposed to enter two numbers in two different boxes and loop it until you put in a valid number!
var x = parseInt(prompt("Please enter a number!"));
var y = parseInt(prompt("Please enter a number!"));
function add(x, y) {
var z = x + y;
var i = false;
do {
if (isNaN(x)) {
alert("Invalid entry. Please enter a number!")
} else if (isNaN(y)) {
alert("Invalid entry. Please enter a number!")
} else {
alert(x + " + " + y + " = ");
i = true;
}
while (i == false);
}
}
add(x, y);
There are a couple of problems with this code:
Your while is misplaced.
The parameters x and y don't make sense, because the user needs to input them.
The prompts asking for the numbers are outside of the loop.
Here is the fixed code:
function add() {
do {
var x = parseInt(prompt("Please enter a number!"));
var y = parseInt(prompt("Please enter a number!"));
var z = x + y;
var i = false;
if (isNaN(x)) {
alert("Invalid entry. Please enter a number!")
} else if (isNaN(y)) {
alert("Invalid entry. Please enter a number!")
} else {
alert(x + " + " + y + " = " + z);
i = true;
}
}
while (i == false);
}
add();
There are a couple of issues:
It's syntactically invalid. You've ended up with a free-standing while (i == false); (which would fine, but it would never end if i is ever false) and a dangling } under your code. You need to move the while line beneath the closing } of the do.
If x or y is NaN, your add function loops until they change...but no code in that loop ever changes them.
I don't know what you want add to do (since just adding numbers doesn't require a function), but if the goal is to keep prompting the user, you have to move the prompts into the loop:
function add() {
var x, y, z;
var valid = false;
while (!valid) {
x = parseInt(prompt("Please enter a number!"));
y = parseInt(prompt("Please enter a number!"));
valid = !isNaN(x) && !isNaN(y);
if (!valid) {
alert("Invalid entry. Please enter a number!")
}
}
z = x + y;
// Do something with z
}
add();
You can also do it recursively without using a do while loop at all, by asking x and y values until both are correct. Also, note that I used a radix value of 10 for parseInt(string, radix);, the reason being that the documentation describes radix as:
An integer that represents the radix of the above mentioned string.
Always specify this parameter to eliminate reader confusion and to
guarantee predictable behavior. Different implementations produce
different results when a radix is not specified.
See more from the documentation of parseInt.
The code example:
function askXY(x, y) {
var x_ = x,
y_ = y;
if(typeof x_ === "undefined") {
x_ = parseInt(prompt("Please enter a number for x!"), 10);
}
if(typeof y_ === "undefined") {
y_ = parseInt(prompt("Please enter a number for y!"), 10);
}
if(isNaN(x_) || isNaN(y_)) {
alert("Invalid entry. Please enter a number!");
// The magic is here, we keep the x or y if either one of those are correct
// and if not, we give undefined so that value will be asked again from the user
return askXY(
!isNaN(x_) ? x_ : undefined,
!isNaN(y_) ? y_ : undefined
);
}
// success!
alert(x_ + " + " + y_ + " = " + (x_ + y_));
}
askXY();
See my JSFiddle example.
The isNaN() is a JavaScript function. It returns true if the given value is not a number (NaN).
var a = isNaN('127') ; // Returns false
var a = isNaN('1273 ') ; // Returns false
var b = isNaN(-1.23) ; // Returns false
var c = isNaN(5-2); // Returns false
var d = isNaN(0) ; // Returns false
var e = isNaN("Hell o") ; // Returns true
var f = isNaN("2005/12/12"); // Returns true
Try this:
$(document).ready(function() {
var x = parseInt(prompt("Please enter the first number!"));
var y = parseInt(prompt("Please enter the second number!"));
function add(x, y) {
var z = x + y;
var i = false;
do {
if (isNaN(x)) {
alert("Invalid entry for first number. Please enter a number!");
x = parseInt(prompt("Please enter first number again!"));
} else if (isNaN(y)) {
alert("Invalid entry for second one. Please enter a number!");
y = parseInt(prompt("Please enter Second number again!"));
} else {
z = x + y;
alert(x + " + " + y + " = " + z);
i = true;
}
}while (i == false);
}
add(x, y);
});
This is a compiled demo version. Checkout the Fiddle:
Fiddle
Related
My problem question as in the practice course goes as follows:
Write a JavaScript program to create a function which takes 2 integers as inputs. The function divides the first integer with second integer as long as the result (Quotient) is an integer (i.e. remainder is zero) and return the quotient as result. Your output code should be in the format console.log("Result is ", variableName)
And below is my code:
var num = prompt("Enter number to divide");
var d = prompt("Enter divisor");
function divide(x, y) {
var result;
if (d === 1) {
result = num;
} else {
while (num % d === 0) { //while error
result = num / d;
}
}
return result;
}
var output = divide(num, d);
console.log("Result is: ", output);
If I remove the while loop, program works fine but the problem description says I have to use it.
What am I doing wrong?
There are a few issues:
1) If your function receives the arguments x and y, then use those inside his scope, don't access the global variables.
2) You are never changing the variables that are evaluated on the while condition, so the evaluation will be the same, ever!
3) Another good thing you can do is add some validation on the received arguments.
Now, your code, can be rearranged to this one:
function divide(x, y)
{
if (isNaN(x) || isNaN(y))
return "Invalid arguments!";
if (y === 1)
return x;
while (x % y === 0)
{
x = x / y;
}
return x;
}
var num = prompt("Enter number to divide");
var d = prompt("Enter divisor");
var output = divide(num, d);
console.log("Result is: ", output);
Your while loop is depending of num, but you donĀ“t assign a new value to it after a cycle. This lead to that the condition stays always the same.
var num = prompt("Enter number to divide");
var d = prompt("Enter divisor");
function divide(x, y) {
var result = x;
if (y === 1) {
return result;
} else {
while (result % y === 0) {
result = result / y;
}
}
return result;
}
var output = divide(num, d);
console.log("Result is: ", output);
I've an element (x) of type=number. In my work to verify it's value is a number before performing mathematical operations I've concluded that elements of type "number", while having builtin validation and helpful input controls, still assign their values as text and will require a conversion to number before performing mathematical operations. My question - Is this true or is there something wrong in my code? Here's my work. Entered the number 6.
x = document.createElement("input");
x.type = "number";
x.step = "0.1";
x.min = "0";
x.max = "9999";
x.defaultValue = "1";
var p = document.getElementById(x.id).value;
isThisNumber(p);
function isThisNumber(z) {
alert(typeof z + " --- " + typeof (z)); // returns "string --- string"
if (z.isNaN) {
alert("it's not number");
} else {
alert("it's a number"); // returns false - it's a number
}
if (z.toFixed) {
alert("it's a number");
} else {
alert("it's not a number"); // returns false - it's not a number
}
var a = z + z;
alert("sum is : " + a); // returns "66"
var b = Number(z);
var b2 = b + b;
alert("sum is : " + b2); // returns "12"
}
Ref:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number
So I have a very basic conditional statement but I am trying to get a different answer. I want to have a default command of else that if a user is inputting something greater than 10 that they get an alert of "the numbers are only from 1-10" what is a way I can do this?
var number = 7;
var stringGuess = prompt("guess a number");
var guess = Number(stringGuess);
if (guess === number) {
alert("you got it");
}
else if(guess > 10) {
alert(" Too High Guess Lower");
}
else if (guess < number) {
alert("Too low guess higher!");
}
else {
}
Modified a little bit of your code:
I used switch for the conditions which basically judge if guess is matching the number or below or above. Then add txt as extra information if the guess is out of 1-10.
var number = 7;
var stringGuess = prompt("guess a number");
var guess = Number(stringGuess);
switch ( true ) {
case ( guess === number ):
alert('You got it!');
break;
case ( guess > number ):
var txt = ( guess > 10 ) ? ' and the number is smaller than 10' : '';
alert( 'Too high' + txt );
break;
case ( guess < number ):
var txt = ( guess < 1 ) ? ' and the number greater than 1' : '';
alert( 'Too low' + txt );
break;
}
You can try this and they do exactly the same thing by using IF ELSE.
var number = 7;
var stringGuess = prompt("guess a number");
var guess = Number(stringGuess);
var txt = ( guess > 10 ) ? ' and the number is smaller than 10' : '';
if ( guess < 1 ) txt = ' and the number greater than 1';
if ( guess === number ) {
alert('You got it!');
} else if ( guess > number ) {
alert( 'Too high' + txt );
} else {
alert( 'Too low' + txt );
}
You have a good case for breaking things into functions, in order to hide the how, and talk about the what it is you're trying to accomplish.
function isInBounds (low, x, high) { return low <= x && x <= high; }
function isAnswer (x, number) { return x === number; }
function gt (x, number) { return x > number; }
function generateRandomInt (floor, ceiling) {
return Math.floor(Math.random() * (ceiling - floor)) + floor;
}
var lowerBound = 1;
var upperBound = 10;
// the +1 is because Random will never, ever be equal to the high number
// so a random number between 1 and 10 really means between 1 and 11
var answer = getRandomInt(lowerBound, upperBound + 1);
var successMessage = "You got it!";
var failureMessage = "Guess again!";
var errorMessage = "Error: guess must be a number between "
+ lowerBound + " and " + upperBound + ".";
function checkGuess (x) {
var message = "";
if (isInBounds(lowerBound, x, upperBound)) {
message = isAnswer(x, answer) ? successMessage : failureMessage;
} else {
message = errorMessage;
}
alert(message);
}
I'm using ternary assignment to set the value of message.
var x = isTrue ? truthyValue : falseyValue;
You can even nest these on the truthy or falsey paths.
var result = a ? x : b ? y : z;
// if a == true, x, else if b == true, y, else z
That said, you may want to be careful with that setup.
I am trying to create a script that will take 2 inputs and calculate the sum. I would like both inputs to be validated before the calculation takes place - inputs must range between 0 and 10.
However when I input values over 10 in both fields (e.g. 50), I am only getting one validation error instead of two.
What could be wrong?
function calc() {
var x, y, z, text1, text2;
// Get the value of the input field with id="numb"
x = Number(document.getElementById("val01").value);
y = Number(document.getElementById("val02").value);
// If x is Not a Number or less than one or greater than 10
if (isNaN(x) || x < 0 || x > 10) {
text1 = "Input not valid";
document.getElementById("validation1").innerHTML = text1;
} else if (isNaN(y) || y < 0 || y > 10) {
text2 = "Input not valid";
document.getElementById("validation2").innerHTML = text2;
} else {
z = x + y;
document.getElementById("total").innerHTML = z;
}
}
<p>Please input a number between 0 and 10:</p>
1st number:<input id="val01" required> <b id="validation1"></b> <br>
2nd Number:<input id="val02" required> <b id="validation2"></b> <br>
<button onclick="calc()">click</button><br /> sum = <span id="total">0</span>
You could use a flag and check it for the calculation.
Skip the else parts and use the flag instead.
var ok = true;
if (isNaN(x) || x < 0 || x > 10) {
ok = false;
text1 = "Input not valid";
document.getElementById("validation1").innerHTML = text1;
}
if (isNaN(y) || y < 0 || y > 10) {
ok = false;
text2 = "Input not valid";
document.getElementById("validation2").innerHTML = text2;
}
if (ok) {
z = x + y;
document.getElementById("total").innerHTML = z;
}
If your first validation fails (if (...)), you do not execute the second validation (else if (...)) anymore.
Instead, run the validations separately from each other and only do the calculation if both succeed, e.g.:
function calc() {
var x, y, z, text1, text2;
// Get the value of the input field with id="numb"
x = Number(document.getElementById("val01").value);
y = Number(document.getElementById("val02").value);
var valid = true;
// If x is Not a Number or less than one or greater than 10
if (isNaN(x) || x < 0 || x > 10) {
text1 = "Input not valid";
document.getElementById("validation1").innerHTML = text1;
valid = false;
}
if (isNaN(y) || y < 0 || y > 10) {
text2 = "Input not valid";
document.getElementById("validation2").innerHTML = text2;
valid = false;
}
if(valid) {
z = x + y;
document.getElementById("total").innerHTML = z;
}
}
You only get one validation because of the way your logic inside the if else statement is built.
You only go "inside" one of the three statements, because you're using if else if, when you need to go inside multiple ones, you can just use a sequence of if()
<script>
function calc() {
var x, y, z, text1, text2;
// Get the value of the input field with id="numb"
x = Number(document.getElementById("val01").value);
y = Number(document.getElementById("val02").value);
var invalidX = true;
var invalidY = true;
// If x is Not a Number or less than one or greater than 10
if (isNaN(x) || x < 0 || x > 10) {
invalidX = false;
text1 = "Input not valid";
document.getElementById("validation1").innerHTML = text1;
}
if (isNaN(y) || y < 0 || y > 10) {
invalidY = false;
text2 = "Input not valid";
document.getElementById("validation2").innerHTML = text2;
}
if (invalidX && invalidY) {
z = x + y;
document.getElementById("total").innerHTML = z;
}
}
</script>
Hope that is what you were looking for. Notice that I also included two variables with booleans that control if the input is valid.
Remove the else if condition in your code for the second valida ation that u are doing.
I'm new to javascript and I'm having a hard time figuring out how to get this factorial function to work. Here's my code now.
var x = prompt("Enter a number"); {
function fact(x) {
if (x < 0) {
return ("Enter a positive integer");
}
else {
return (x * fact(x-1))
}
}
}
var result = fact(x)
document.write("The factorial of" + x + "is" + result);
Thanks for the help!
your base case is wrong for a recursive factorial. change it to
function fact(x) {
if (x <= 1) {
return 1
}
else {
return (x * fact(x-1))
}
}
Your definition of factorial is wrong. The traditional recursive definition of factorial is:
F(x) => x == 1 ? 1 : x * F(x-1)
Or you can use the iterative definition
F(x) => var i = 1; for (j = 1..x) i = i * j
In javascript, the recursive version would be:
function factorial (x) {
if (x == 1) return x;
return x * factorial(x-1);
}
The iterative version would be:
function factorial (x) {
var result = 1;
for (var y = 1; y <= x; y++) {
result = result * y;
}
return result;
}
You can add the negative number check in the above functions. But in my opinion that would obscure the purpose of the function (which is to implement the traditional definition of factorial). A better approach is to move the negative number if() check outside of the factorial function. The if (x < 0) check has its own purpose that is separate from calculating factorials: input validation.
In every recursive function, there exists a stopping condition (in your case its if(x<=1)) without which, the function would go to infinite recursion. You had not added that stopping condition. Following is the working updated program:
var x = prompt("Enter a number"); {
function fact(x) {
if (x < 0) {
return ("Enter a positive integer");
}
else if(x <=1){
return 1;
}
else {
return (x * fact(x-1))
}
}
}
var result = fact(x)
document.write("The factorial of " + x + " is " + result);
In addition to fixing the flawed algorithm, I recommend moving your prompt into its own function for separation of concerns.
I also like the idea of using a while statement for this as well as doing a parseInt on the input:
function fact(x) {
while (x > 1) {
return (x * fact(x-1));
}
return x;
}
function doFact() {
var x = parseInt(prompt("Enter a positive integer"));
if (x < 1) {
doFact();
} else {
var result = fact(x);
alert("The factorial of " + x + " is " + result);
}
}
doFact();