function mathProb() {
var x = parseInt(prompt("Enter first integer", ""));
var y = parseInt(prompt("Enter the second integer", ""));
var operand = prompt("Enter type of operation", "");
if (operand == "+" || "add") {
var sum = x + y;
document.write("Your sum is " + sum);
} else if (operand == "-") {
var difference = x - y;
document.write("Your difference is " + difference);
} else if (operand == "*") {
var product = x * y;
document.write("Your product is " + product);
} else if (operand == "/") {
var quotient = x / y;
document.write("Your quotient is " + quotient);
} else {
document.write("Oops something went wrong");
}
}
Well to start I am reading a book on JavaScript and have been doing pretty well, I am now on functions and was getting those until parameters were introduced can someone explain what a parameter is in a clear simple way?
Why does this function work when named function mathProb() and function mathProb(x,y,operand)?
And a third question off of the previous one is why when I call the function in html
(<input type="button" value="Calculator" onclick="mathProb()"/>)
I have to use mathProb() even if its named mathProb(x,y,operand). If I call it using that name it wont work. Please help?
First, the line:
if(operand=="+"||"add")
Will always be true, as the expression "add" will always return a true-ish value. You probably mean to use:
if(operand=="+" || operand=="add")
Your question about parameters is probably a pretty broad topic. Basically, a parameter is a variable given to a function so that the function can be generalized to work with any data. For example, if you wanted to write a function that can add two numbers, the function must know which two numbers to add. These numbers would be supplied as parameters:
function add(x, y)
{
return x + y; // x and y are variables known within this function
}
You'd then call your function as so:
var oneplusone = add(1, 1); // Adds 1 and 1
Using this knowledge, you could rewrite your code as this:
function mathProb(x, y, operand)
{
// No need for var x, etc as these can now be passed in..
}
Then call your function:
mathProb(
parseInt(prompt("Enter first integer","")), // This is x
parseInt(prompt("Enter the second integer","")), // This is y
prompt("Enter type of operation","") // This is operand
);
Keep in mind you could still call your function mathProb without the parameters:
mathProb();
...if you really wanted to. JavaScript does allow this (unlike many other languages). However, within your function, the variables x, y and operand will be undefined which might cause unexpected results if you don't account for that.
You need call and pass function like mathProb(1,2,'+')
HTML:
<input type="button" value="Calculator" onclick="mathProb(1,2,'+')"/>
Javacript:
function mathProb(x,y,operand)
{
//var x = parseInt(prompt("Enter first integer",""));
//var y = parseInt(prompt("Enter the second integer",""));
//var operand = prompt("Enter type of operation","");
if(operand=="+"|| operand=="add")
{
var sum = x+y;
document.write("Your sum is " +sum);
}
else if(operand=="-")
{
var difference = x-y;
document.write("Your difference is " +difference);
}
else if(operand=="*")
{
var product = x*y;
document.write("Your product is " +product);
}
else if(operand=="/")
{
var quotient = x/y;
document.write("Your quotient is " +quotient);
}
else
{
document.write("Oops something went wrong");
}
}
Related
This question already has an answer here:
Why does this JavaScript code print "undefined" on the console?
(1 answer)
Closed 1 year ago.
I make a simple calculator using javascript. I am providing those code below. But the problem is when i run those code. i saw a undefined output. I dont know why that text is showing. I want to remove that.
function addition(x, y) {
var sum = x + y;
document.write("Addition of two number is : " + sum);
}
function substract(x, y) {
var sub = x - y;
document.write("Subtraction of two number is : " + sub);
}
function multiply(x, y) {
var multiply = x * y;
document.write("Multipication of two number is : " + multiply);
}
function division(x, y) {
var division = x / y;
document.write("Division of two number is : " + division);
}
var x = parseInt(prompt("Enter the first number : "));
var y = parseInt(prompt("Enter the second number : "));
var operator = prompt("Enter the operator : ");
if (operator == "+") {
document.write(addition(x, y));
} else if (operator == "-") {
document.write(substract(x, y));
} else if (operator == "*") {
document.write(multiply(x, y));
} else if (operator == "/") {
document.write(division(x, y));
} else {
document.write("Invalid Operator. Please choose operator between +,-,* or /. <br> Thanks for using our calculator. ");
}
Calling document.write(x) causes x to be written. If x is a function call, it will write whatever that function call returns. Since all of your functions don't explicitly return something, they return (here it comes) undefined.
Your operator functions don't return anything, they write directly to the page.
However the lines that execute these functions write to the page the return of these functions, which is undefined
So to solve this, you have 2 options:
replace document.write("blah") with return "blah" in operator functions
remove document.write() from the caller: document.write(addition(x, y))
I am doing a coding challenge that reads like this:
Create a function runningAverage() that returns a callable function object. Update the series with each given value and calculate the current average.
rAvg = runningAverage();
rAvg(10) = 10.0;
rAvg(11) = 10.5;
rAvg(12) = 11;
I got a working solution, yet they also want the results to be rounded like this:
rAvg(13) = 13.50678; => 13.50
rAvg(13) = 13.50; => 13.50
rAvg(13) = 13.5; => 13.5
rAvg(13) = 13; => 13
Here is my code:
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let averageArray = average.toString().split('.');
//to get the number of decimal places
//e.g 11.543 ==> ['11', '543']
if ((Array.from(averageArray[1]).length) >= 2) {
return average.toPrecision(2);
}
else if ((Array.from(averageArray[1]).length) = 1) {
return average.toPrecision(1);
}
else {
return average;
}
}
}
I tested parts of the function separately and it seems to work, yet when I invoke it I get the message 'cannot convert undefined or null to object'.
This sounds like a fun coding challenge!
In this case, you want toFixed(), not toPrecision(). toPrecision() essentially allows you determine how many digits TOTAL (including those on the left of the decimal point) should appear, whereas toFixed() focuses on the number of digits to the right of the decimal point. Feel free to look these two methods up on MDN. When you read that toPrecision() may return exponential notation, this should make you pause and think, "That's weird. Why does this happen? When does this happen?", rather than "this detail is unimportant."
Your .length = 1 comparison needs to be modified to a ===.
Your code currently fails if an integer is the first number provided to rAvg(). In your first conditional, Array.from(undefined) may run, which is not permissible in JavaScript. You should consider ways to only work with "the digits to the right of the decimal" only if "there are digits to the right of the decimal."
Here is a working solution including all the suggestions, in case someone is interested:
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let numIsDecimal = average.toString().includes('.');
if (numIsDecimal) {
let averageArray = average.toString().split('.');
//to get the number of decimal places
//e.g 11.543 ==> ['11', '543']
if ((Array.from(averageArray[1]).length) >= 2) {
return Number(average.toFixed(2));
}
if ((Array.from(averageArray[1]).length) === 1) {
return Number(average.toFixed(1));
}
}
else {
return Number(average);
}
}
}
Not sure if this works but try it
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let averageArray = average.toString().split('.');
if ((Array.from(averageArray[1]).length) >= 2) {
return Math.round(average.toPrecision(2) * 2) / 2;
} else if ((Array.from(averageArray[1]).length) == 1) {
return Math.round(average.toPrecision(1) * 2) / 2;
} else {
return Math.round(average * 2) / 2;
};
};
};
I have this code to ask for a number to show in a td. But its not working properly.
The user should only be able to enter a value between the min and max passed in the func1. And the number must be a valid number.
If these conditions are met the td should should show the number entered by the user, otherwise it should appear again the prompt for the user enter a valid number.
The code is working if the user enter a valid number at first, for example in this case the min is 1 and the max is 10, if the user enter a number betwene these two values it works, the number entered by the user appears on the td. However if the user enters for example the number 0, it appears the message "The value 0 is not valid" and it appears again the prompt, and this is correct. However then if the user enter a valid number like 1 it appears undefined instead of 1 in the td.
Do you know why?
HTML
<tr>
<td>Number</td>
<td id="tdNumber"></td>
<td>
<button onclick="func1()">Add</button>
</td>
</tr>
JS
let config = {
numberX: NUMBER_X
}
function showConfig() {
document.getElementById(TD_NUMBER).innerHTML = config.numberX;
}
function func1() {
config.numberX = func2(1, 10, P_CONSTANT);
showConfig();
}
function func2(min, max, p = P_CONSTANT) {
var number = parseInt(prompt("Enter a number between " + min + "and " + max));
if (!Number.isInteger(number)) {
alert("The number " + number + " is not valid.");
func1();
} else if (number > max || number < min) {
alert("The number " + number + " is not valid");
func1();
} else {
return number;
}
}
The way you've written your func1 and func2, they can call each other an unlimited number of times. So imagine this case:
func1() is called (call this func1_A)
func1_A calls func2() to get the number (this is func2_B)
user enters invalid number, func2_B starts another call of func1 (func1_C)
this new invocation func1_C calls func2() to get a new number (func2_D)
user enters valid number, func2_D returns it, func1_C assigns it to numberX
func1_C returns, execution returns to func2_B which has been waiting, func2_B has nothing left to do so it returns undefined
func1_A gets undefined from func2_B and assigns it to numberX
Basically, the fact that you have these functions calling each other will keep adding new invocations to the stack which the old ones have to wait on before they can return. And importantly, the old ones will resume - this means the last thing to happen will always be func1 assigning the most recent return value of func2, which if the user ever entered an invalid number, will be undefined.
Pointy is right: this is a very poor format and is prone to a lot of issues. It isn't an approach you should pursue. At minimum your code shouldn't be needlessly prone to stack overflow errors by having unnecessary recursive function calls.
You can simplify this a lot with a while loop. I'm also a fan of meaningful names, and func1/func2 are as far away from meaningful as you can get, so I've renamed the functions.
const NUMBER_X = 10;
const P_CONSTANT = "???";
const TD_NUMBER = "tdNumber";
let config = {
numberX: NUMBER_X
};
function showConfig() {
console.log(document.getElementById(TD_NUMBER));
document.getElementById(TD_NUMBER).innerHTML = config.numberX;
}
function setNumber() {
config.numberX = getValidNumber(1, 10, P_CONSTANT);
showConfig();
}
function getValidNumber(min, max, p = P_CONSTANT) {
var isValid = false;
var number;
do {
number = parseInt(prompt("Enter a number between " + min + " and " + max));
if(!Number.isInteger(number)) {
alert("The number " + number + " is not valid.");
} else if(number > max || number < min) {
alert("The number " + number + " is not valid");
} else {
isValid = true;
}
} while(!isValid);
return number;
}
<table>
<tr>
<td>Number</td>
<td id="tdNumber"></td>
<td><button onclick="setNumber()">Add</button></td>
</tr>
</table>
The structure of your program is the real problem. It could probably be made to work, but it's simply not the way to do it. Instead, have func2() return some value that indicates an invalid number, and do the iteration inside func1():
const INVALID = {};
function func1() {
let p;
for (p = func2(1, 10); p === INVALID; p = func2(1, 10)) {
alert("Invalid value");
}
config.numberX = p;
showConfig();
}
function func2(min, max, p = P_CONSTANT) {
var number = parseInt(prompt("Enter a number between " + min + "and " + max));
if(!Number.isInteger(number)){
return INVALID;
}
if(number > max || number < min){
return INVALID;
}
return number;
}
when func1 calls func2,
func1 waits for a response.
If the entry is wrong func1 never gets its answer because func2 calls func1 again...
In total this makes 2 func1 functions which both await a response,
and if the new entry is wrong this will make it a third;
Only the last one on this stack will get a return,
while all the others func1 will continue to wait in vain
the correct way to code this is:
const tdNumber = document.getElementById('td-number')
, NUMBER_X = 10
, minVal = 1
, maxVal = 10
, config = { numberX: NUMBER_X }
;
function setNumber()
{
let numberStr = ''
, numberIn = 0
, badEntry = true
;
do
{
numberStr = prompt( "Enter a number between " + minVal + "and " + maxVal )
numberIn = parseFloat( numberStr )
badEntry = ( !Number.isInteger( numberIn ))
|| numberIn < minVal
|| numberIn > maxVal
;
if ( badEntry )
{ alert("The number " + numberStr + " is not valid") }
}
while ( badEntry )
tdNumber.textContent = config.numberX = numberIn
}
table {
border-collapse: collapse;
margin: 1em;
}
td {
border: solid grey 1px;
padding: 1em;
text-align : center;
}
#td-number {
width : 4em
}
<table>
<tr>
<td>Number</td>
<td id="td-number"></td>
<td><button onclick="setNumber()">Add</button></td>
</tr>
</table>
I am trying to learn javascript, I am playing with a game that picks a random number.
I would like to have 2 functions, random and guess. Random generates a new number between 1-10. Guess is where it checks if the number was guessed, if not re-runs the random function and generates a new number to try.
var x;
function random(){
let x = Math.floor((Math.random() * 10) + 1);
guess();
}
function guess(x){
if(x === 3){
alert('you are correct!');
}else{
alert('try again');
random();
}
}
random();
This just alerts try again every time, i'm guessing because it's not generating a new number each time the function is called?
How can you create the random function so it generates a new number each time its called?
***** Correction, it appears to generate a new number but x is undefined within the guess function**
The x in the guess() is the x that gets passed to it as a parameter. I would remove the var x; declaration and pass a value when calling like guess(x)
function random(){
const x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x){
if(x === 3){
alert('you are correct!');
}else{
alert('try again');
random();
}
}
random();
The guess function's signature says that it takes a parameter x, but you're not passing any value to the function when it's called, so it's assigning undefined to x when it runs guess, which will never equal 3. You can take 2 approaches to fix this. First, you could make x a global variable by getting rid of the let where you define x in the random function and removing x from guess's function signature, like so:
var x;
function random() {
x = Math.floor((Math.random() * 10) + 1);
guess();
}
function guess() {
if (x === 3) {
alert(x + '- you are correct!');
}
else {
alert(x + '- try again');
random();
}
}
random();
Or, you could use x as a parameter for the guess function by removing the var x; global declaration and passing x to guess when you call it in the random function, like so:
function random() {
let x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x) {
if (x === 3) {
alert(x + '- you are correct!');
}
else {
alert(x + '- try again');
random();
}
}
random();
I personally wouldn't even have a random function. I'd just define x within guess and call guess from within itself. And, I'd use randojs.com to make the randomness more readable. Here's how I'd do it:
function guess() {
let x = rando(1, 10);
if (x === 3) return alert(x + '- you are correct!');
alert(x + '- try again');
guess();
}
guess();
<script src="https://randojs.com/1.0.0.js"></script>
Note that the return statement would stop the execution of the function right then and there, so it wouldn't progress to the "try again" alert if the number was guessed correctly.
Here's some detailed code that will help you understand how to run such a game in the browser.
See the comments for explanation of how it works (and search for information on MDN to learn more about any particular topic.)
Happy coding!
// Identifies HTML elements
const
guessInput = document.getElementById("guessInput"),
outputParagraph = document.getElementById("outputParagraph");
// Makes a global variable that all functions can access
let globalNum;
// Invokes the main function
playGame();
function playGame(){
// Invokes the randomizer function and stores the result in the global variable
globalNum = getRandomNumber();
//console.log(globalNum);
// Invokes the output function
setOutput("Guess a number from 1 to 10");
// Assigns a function that will be invoked whenever the user changes the input field
guessInput.addEventListener("change", respondToGuess);
// Puts the focus in the input element
guessInput.focus();
}
// Defines a listener function that can automatically see the triggering event
function respondToGuess(event){
// Gets the `target` element of the event and stores it in a local variable
const localReferenceToInputElement = event.target
// The text of an `<input>` element lives in its "value" property
const inputText = localReferenceToInputElement.value;
// Tries to convert the text string to an integer (and store it locally as 'guess')
let guess = parseInt(inputText);
// If the conversion failed, changes the output accordingly
if(!guess){ setOutput("Please enter a valid number"); }
// If the number is out of range, changes the output
else if(guess < 1 || guess > 10){ setOutput("Only numbers from 1 to 10 are allowed"); }
// If the guess doesn't match the stored number, changes the output
else if(guess !== globalNum){ setOutput("Try again..."); }
// If we got this far, the guess was correct, so changes output and ends game
else{
setOutput("You guessed it!");
reset();
}
}
function getRandomNumber(){
// Returns a random number into whatever function called this function
const x = Math.floor((Math.random() * 10) + 1);
return x;
}
function setOutput(outputText){
// The text of a paragraph element lives in its `innerHTML` property
outputParagraph.innerHTML = outputText;
}
function reset(){
// Clears the input and stops listening for changes
guessInput.value = "";
guessInput.removeEventListener("change", respondToGuess);
}
<input id="guessInput" />
<p id="outputParagraph"></p>
I have done some changes to your code.
You have problem with the concept of function calling function.
In real code it will kill your memory.. your function calls function the function not close and call the function again and again... and its fill the memory .
var x;
// flag correct will close the loop when you have right umber
var correct = false;
function random() {
x = Math.floor((Math.random() * 10) + 1);
guess(x);
}
function guess(x) {
if (x === 3) {
alert('you are correct!');
// if number is right flag is up
correct = true;
} else {
alert('the number is ' + x + ' try again');
}
}
// loop until the number is right
while (correct != true) {
random();
}
I have a program that randomly generates two numbers (x and y) and asks the user to multiply them. Once they multiply them, it will tell them if they get it right or wrong. The thing I'm having problems with is that if they get the answer correct, it should then generate a new set of numbers. I'm not sure how to make the program perform that function again. Also it has to clear the answer field no matter if they get it right or wrong. Thanks!
var x, y; // global variables for randomly generated numbers
var correct = ['Very good!', 'Excellent!', 'Correct - Nice work!', 'Correct - Keep up the good work!'];
var incorrect = ['No. please try again.', 'Wrong. Try once more.', 'Incorrect - Dont give up!', 'No - Keep trying.'];
// getting two random numbers between 1-12 then assigning them to x and y
function generateNumbers() {
function aNumber() {
return Math.floor((Math.random() * 12) + 1);
}
x = aNumber();
y = aNumber();
}
// generating the question that will be used with the random numbers x and y
function genQuestion() {
generateNumbers();
document.getElementById('question').value = x + " times " + y;
}
// function that is performed when the button "check answer" is clicked. It will generate one of 4 answers depending
//if it's right or wrong and will add 1 to the value of total. If it's incorrect it won't add anything
function buttonPressed() {
var correctans = correct[Math.floor(Math.random() * 4)]; // randomly selecting an answer if it's correct
var incorrectans = incorrect[Math.floor(Math.random() * 4)]; // randomly selecting an answer if it's incorrect
var answer = document.getElementById('answer').value;
if (answer == x * y) // correct
{
function genQuestion() {
generateNumbers();
document.getElementById('question').value = x + " times " + y;
}
window.alert(correctans);
var total = document.getElementById('total').value++;
}
else { // incorrect
window.alert(incorrectans);
}
}
You're not calling the genQuestion function, and it makes little sense to redefine it.
// function that is performed when the button "check answer" is clicked. It will generate one of 4 answers depending
//if it's right or wrong and will add 1 to the value of total. If it's incorrect it won't add anything
function buttonPressed() {
var correctans = correct[Math.floor(Math.random() * 4)]; // randomly selecting an answer if it's correct
var incorrectans = incorrect[Math.floor(Math.random() * 4)]; // randomly selecting an answer if it's incorrect
var answer = document.getElementById('answer').value;
if (answer == x * y) // correct
{
//call genQuestion to create new question
genQuestion();
window.alert(correctans);
var total = parseInt(document.getElementById('total').value)++;
}
else { // incorrect
window.alert(incorrectans);
}
//clear 'answer' field
document.getElementById('answer').value = '';
}