Having trouble with a Javascript adding system (simple but I'm slow) - javascript

So I am trying to make a program here where I press a button and once its pressed I input a number (from 1-3) and then it outputs the inputted value.
Then you can press the button again and add another value (again from 1-3) and it adds the second input to the first input and so on.
This is the code I've got so far and it doesn't work, it just outputs my inputted value and that's it. Nothing gets added and updated.
<script type="text/javascript">
function addone()
{
x=parseInt(prompt("What goal importance did you complete?"));
var sum = 0;
if (x === 1)
{
sum = sum + x;
}
else if (x=== 2)
{
sum = sum + x;
}
else if (x=== 3)
{
sum = sum + x;
}
document.getElementById("myBtn").innerHTML = x;
}
</script>
The button and the ouput are with:
<button onclick="addone()">Coins</button>
<h1>Coins:</h1>
<h4 id='myBtn'>0</h4>

As pointed out by #Aplet123, each time you execute the addOne function, you restart the sum as 0.
The simplest way is to initialize it outside the function.
By the way, there is no need for the elseif conditions in your code, regarding the feature you want to achieve, the best, for readability should be to use a AND condition :
<script type="text/javascript">
var sum = 0;
function addone()
{
x=parseInt(prompt("What goal importance did you complete?"));
if (x >= 1 && x <=3)
{
sum = sum + x;
}
document.getElementById("myBtn").innerHTML = sum;
}
</script>

You have to fix one thing before moving on. You are instantiating the sum as 0 whenever you run the function. To fix this, declare the sum outside of the function. You can reset it if you want later in the program if you like.
Next, you want to accept only 1, 2 or 3 as the input. You can shorten the if else condition so that it checks that input is more than or equal to 1, but less than or equal to 3.
Finally - You are adding the values of input to the sum variable. The variable x is not changing itself. So, you will always see the number you input. Change the innerhtml value to sum.
EDIT - I have also included comments in the code below -
var sum = 0; //Declare sum outside the function
function addone(){
let x=parseInt(prompt("What goal importance did you complete?"));
if (x >= 1 && x <=3){ //Shorten the if else condition
sum += x;
}
document.getElementById("myBtn").innerHTML = sum; //Display the sum
}

Related

How does Javascript variable works?

Recently started learning Javascript.
Given an assignment for my class, to click a button (a number 10 is written on the button), and there has to be "Result = 55". (here all numbers from 0 to 10 are added)
To change words by clicking buttons, wrote code like this:
function myFunction(num) {
var p = document.getElementById("mydata");
for (var i = 0; i <= num; i++) {
sum = sum + i;
p.innerHTML = "Result = " + sum;
}
}
After submitting assignment for school, learned that had to add var sum = 0 above var p = document.getElementById("mydata")
However, do not understand what var sum = 0 means. As for looks already show when to begin and end calculating, feel like it doesn't have to be there.
var sum = 0; declares a local variable named sum, and sets its initial value to 0.
If you don't do this, when you do:
sum = sum + i;
the variable sum is initially undefined, and adding i to it results in NaN (Not a Number).
Some languages (e.g. PHP) automatically treat initialized variables as 0 in arithmetic expressions, but JavaScript doesn't do this, so you need to specify the initial value of the variable.
This has nothing to do with the way the for loop determines when to begin and end. It's about how to correctly add the numbers along the way.
It doesn't have to be before the p assignment, but it needs to be before the for loop.
Also, the line
p.innerHTML = "Result = " + sum;
doesn't need to be inside the loop. You should wait until the loop is done.

Unusual browser error and advice on a Calculate Sum program for javaScript

So I have a problem for class:
Calculate Sums
Create a function called calculateSums that will accept an array of numbers, and return true if the sum of all the positive numbers is greater than or equal to the sum of the absolute value of all the negative numbers.
Method of completion
You should use a while loop in your solution.
It does not matter if you consider 0 a positive or negative number
because it will not change the sum of either side.
After your loop finishes, you should simply return whether the sum of
positive numbers is greater than or equal to the sum of negative
numbers.
It should be possible to call the function as follows:
calculateSums([-1,2]) returns true
calculateSums([-1,2,-3]) returns false
In your code, call your function several times and display the arrays used and the result on your HTML page.
I am having trouble figuring out how to use a while loop to do this. I have one, but it's not right. I am also trying to display the result using "document.getElementByID("message").innerHTML..." and I am getting an error I don't understand.
Here is my code:
/**
* This function calculates the absolute sum of an array of numbers
* #inputs a - an array of numbers
* #returns compare - a boolean
*/
function calculateSum(a) {
//declare variables and set them equal to 0.
var result = 0;
var possum = 0;
var negsum = 0;
var compare;
while (possum >= negsum) {
for (var i = 0; i < a.length; i++) {
var num = a[i];
result = result + Math.abs(num);
if (num%2 == 0) {
possum += result;
} else {
negsum += result;
}
result = 0;
}
if (negsum > possum) {
compare = false;
break;
} else {
compare = true;
break;
}
}
if (compare == true) {
document.getElementById("message").innerHTML = compare;
} else {
document.getElementById("message").innerHTML = compare;
}
return compare;
}
Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Calculate Sums</title>
<script src = "assignment3.js"></script>
</head>
<body>
<script>
calculateSum([-1,2,3,-2]);
calculateSum([-3,1,-5,2]);
</script>
<p id = "message"></p>
</body>
</html>
I would love someone to help understand the error and offer suggestions of a better way to do this.
Here is the error in the browser:
Uncaught TypeError: Cannot set property 'innerHTML' of null
at calculateSum (assignment3.js:34)
at calculateSums.html:12
I am still very new to coding, so I am often times finding myself frustrated. I really appreciate the help I've found on this site.
Update: I figured out how to fix the while statement.
while (possum >= negsum || negsum > possum)
I'm not sure this is exactly how my teacher imagined it being done because we also have these acceptance criteria:
Calculate Sums
Your code must include a function called calculateSums that accepts
an array of numbers and includes a return statement
Your function must include a while loop.
Your code must use Math.abs() to get the absoluate value of any
negative numbers.
Your code must NOT include an infinite loop.
Your code must conditionally return true or false.
Your code must include multiple variations of tests to show your
function works.
The primary problem in your code is as follows:
When the browser receives the HTML markup in your code, it is processed from top to bottom.
So based on the coed you have shared the code executes in the following order:
The head section loads first as it is on the top. And consequently, your external script assignment3.js also gets loaded. (now the function in the script is available on the global namespace)
<head>
<meta charset="UTF-8" />
<title>Calculate Sums</title>
<script src = "assignment3.js"></script>
</head>
The browser then moves on to the body
<body>
<script>
calculateSum([-1,2,3,-2]);
calculateSum([-3,1,-5,2]);
</script>
<p id = "message"></p>
</body>
First, your script tag executes
<script>
calculateSum([-1,2,3,-2]);
calculateSum([-3,1,-5,2]);
</script>
This works well until this line in the calculateSum function
document.getElementById("message").innerHTML = compare;
Because, at this point, your browser has not gotten around to rendering the <p> tag (the script comes before and executes before this can happen). So document.getElementById("message") can't find the p tag and ends up returning nothing (null). And when you try to access a property on null, you get this error Cannot set property 'innerHTML' of null.
So to fix that, (and as a best practice in general) it's best to put your scripts at the end of the body tag like this (and not in the head):
<body>
<p id = "message"></p>
<script src = "assignment3.js"></script>
<script>
calculateSum([-1,2,3,-2]);
calculateSum([-3,1,-5,2]);
</script>
</body>
This ensures that your page load is not blocked by scripts and also has the side effect that the DOM will have been rendered and ready when your code executes.
Coming to your assignment problem specifically, you can use a while loop to iterate over the array and solve it in a simple manner.
Some change notes:
Move DOM manipulation out of the calculateSum method. This method now has a single clear purpose of calculating the sum and return either true or false.
Write a new function runTestCases which basically creates an array of arrays for the different tests we want to run and runs the calculateSum method for each. It also updates the DOM to reflect the result as stated in your problem statement.
Used while loop to iterate over the array in calculateSum
/**
* This function calculates the absolute sum of an array of numbers
* #inputs a - an array of numbers
* #returns compare - a boolean
*/
function calculateSum(a) {
//declare variables and set them equal to 0.
var result = 0;
var possum = 0;
var negsum = 0;
var currentIndex = 0;
while (currentIndex < a.length) {
var e = a[currentIndex++];
if (e < 0) {
// Negative number
negsum += Math.abs(e);
} else {
// Positive number
possum += e;
}
}
return possum >= negsum;
}
function runTestCases() {
// Array of test cases. (You can add or remove tests as needed)
var tests = [
[-1, 2],
[-1, 2, -3]
];
// Get reference of the list element to show the results
var ul = document.getElementById("result");
// Iterate over the tests aray and update dom to show each result
for (var i = 0; i < tests.length; i++) {
var test = tests[i]; // Get the current test case
var result = calculateSum(test); // Get the result
// Create a new DOM element to display the result
var li = document.createElement('li');
li.innerHTML = JSON.stringify(test) + " <b> " + result + "</b>";
//Appenf newly created element to the list
ul.append(li);
}
}
runTestCases();
<div>
<ul id="result"></ul>
</div>
Here is an answer that I think covers all the requirements:
function calculateSums(nums) {
var posSum = 0,
negSum = 0,
i = 0,
num;
while (i < nums.length) {
num = nums[i];
if (num < 0) {
negSum += Math.abs(num);
} else {
posSum += num;
}
++i;
}
return posSum >= negSum;
}
Uncaught TypeError: Cannot set property 'innerHTML' of null
at calculateSum (assignment3.js:34)
at calculateSums.html:12
You have to call the calculateSum() function after the p tag. It is trying to assign value before it is declare. Put your script before the tag.

How to permanently change var?

So, I have a var set in a function and a array(called "card_idx) set up, and I want the var be set to 0 until a certain number is reached in the array but the number doesn't go up in order (1..2..3..4 extra). It jumps around depending on how the person plays ( so it can be like...1...2...2.1....5....3.2...). And I want the var to be set to 0 until a specific number is reached and then it is changed to 1.
I try having it set up like:
var x=0;
if(card_idx == 3.2){
x=1
}
but the moment there no longer on 3.2 it will change back to zero, how do i make it so it will stay 1?
While your example isn't complete enough to reproduce the problem, I imagine you may be running into trouble with variable scope.
JS variables are locally scoped to the function surrounding them, which works to your advantage here. If you declare x at the beginning of the function that goes through your data, the loop can modify it and the value will be retained after the loop completes:
function crunch(data) {
var x = 0;
data.forEach(function (item) {
if (item.index === 3.2) {
x = 1;
}
});
console.log(x);
}
If any item in data had an index of 3.2, x will be set to 1 and printed to the console at the end. The callback to forEach grabs x using closure, but this would work just the same with a for loop.
Using x within the loop, the value will not be reset until crunch returns. Every time crunch is called, x will be set to 0, may be set to 1 if an item has the right index, and will retain that value until the end of crunch.
Now, with forEach, if you were to declare x inside the loop callback rather than in crunch, it would reset every time:
function crunch(data) {
data.forEach(function (item) {
var x = 0;
if (item.index === 3.2) {
x = 1;
}
});
}
Because var operates at the function level, this will not keep its value and will be 0 for every item.
You could try this. Use an extra boolean to check if x has ever been set.
Be aware that your variables are outside the iteration.
var x = 0;
var hasSet = false;
// start looping
if (card_idx == 3.2 && hasSet = false) {
x = 1
hasSet = true;
}
Or maybe (if your question was more clear) this will work out too.
var x = 0;
// start looping
if (card_idx == 3.2 && x <= 0) {
x = 1
}

Is it Possiable to call to previous increments of a variable?

for example lets say i have a loop that is doing basic counting, while the variable is less than 16 the loop will run and at the end of the loop you add 2 to the variable and add one to a "count" variable
what i want to know is if its possible to callback to any of the previous variables for either variable for example can i count all the times count % 2 === 0?
im not quite sure if once a variable makes any kind of change if all previous versions of that variable are gone
http://codepen.io/anon/pen/Gojoxm
var two = 0;
var count = 0;
while ( two < 16) {
two += 2;
count++;
};
console.log(count);
If I understand you right, then no, you cannot. When you assign a new value to a variable, the previous value is lost.
You have to either run this loop again or store intermediate values in an array:
var values = [];
var two = 0;
while (two < 16) {
two += 2;
values.push(two);
}
console.log(values.length); // the same result
Then, you will always be able to do whatever you want with these values.
For example, you can check if there were any odd values:
var anyOddNumbers = values.some(function(x) { return x % 2 === 1; }); // false

value method not working function callback

I am creating a small program that returns the results of a mathematical equation. I have a number input field with the ID and CLASS "value1" (I've attempted to manipulate using both) that allows the user to put in a number value. I have another number input field that is disabled with the ID and CLASS "result1" that displays the results of the equation.
I have a button with the ID solution1_btn that when clicked is suppose to initiate the "multiples" function callback which takes "value1" as an argument.
When I replace "value1" which a physical number e.g. 1000, the results of the equation appears in "result1" without pressing solution1_btn, however when i put "value1" as the argument and press solution1__btn it does not work.
Below is the section of JavaScript code that I have narrowed the problem to and HTML.
JS:
// declare Euler1 assign it to function with parameter num
// click button
var solution1 = document.getElementById("solution1_btn");
// user entered value
//var value1 = document.getElementById("value1");
var value1 = document.getElementsByClassName("result1")[0].value;
//console.log(value1);
// result input field
var result1 = document.getElementById("result1");
function multiples(num) {
// declare sum assign it value 0
var sum = 0;
// declare a for loop that iterates while the counter "i" is less than num
for (var i = 0; i < num; i++) {
// if statement test whether the division remainder of 3 and 5 are equal to 0
if (i % 3 || i % 5 === 0) {
// assigns the value of i to sum
sum += i;
var newSum;
result1.value = newSum;
newSum = sum;
};
};
// returns the value of sum from the function callback argument 1000 etc.
return newSum;
};
var fix = value1;
solution1.onclick = multiples(fix);
HTML:
<label for="value">Enter Value: </label>
<input id="value1" class="value1" type="number" title="value field" placeholder="e.g. 1000">
<button type="button" id="solution1_btn" title="solution 1 button">Enter</button>
<input id="result1" class="result1" type="number" disabled>
Gosh, there is quite a few problems with your code, I'll try to run through them all.
Referencing HTML elements
HTML elements can be referenced in many ways, as you have discovered. Generally, you should pick the most appropriate and stick with it. If you use an id and a class things get confusing quickly - espcially seeing as id's should be unique, but classes need not necessarily be so. In your case, I think you're safest to stick with id, and then always use document.getElementById.
Multiple boolean checks
Regarding this line of code
if (i % 3 || i % 5 === 0) {
You probably expect that that equates to "if i is divisible by 3 or 5", and that is a logical (and often misunderstood) part of boolean logic. In actual fact, you should think "if i is divisible by 3 or i is divisible by 5", which equates to the following in code
if ((i % 3) === 0 || (i % 5) === 0) {
Yes, unfortunately you need to repeat the === 0 part twice.
Variable scope
This one's a big subject, and there is plenty of other information on the subject, but suffice it to say that in your function newSum is defined only inside an if block, and is redefined every iteration of your loop, so it wont contain the sum as you may be expecting.
In any case, it's uneccessary, you should just return sum
function multiples(num) {
// declare sum assign it value 0
var sum = 0;
// declare a for loop that iterates while the counter "i" is less than num
for (var i = 0; i < num; i++) {
// if statement test whether the division remainder of 3 and 5 are equal to 0
if ((i % 3) === 0 || (i % 5) === 0) {
// assigns the value of i to sum
sum += i;
};
};
// returns the value of sum from the function callback argument 1000 etc.
return sum;
};
Event handlers
You are trying to set an event to occur onclick with this code
solution1.onclick = multiples(fix);
This attempts to add an event handler with the result of calling multiples - not multiples itself. You should assign the event handler a function, and assign the value of the field to the result of calling the multiples function.
solution1.onclick = function(){
result1.value = multiples(parseInt(value1.value,10));
};
Working example
Below is a working example of your code, hopefully helps you pull this all together.
var solution1 = document.getElementById("solution1_btn");
var value1 = document.getElementById("value1");
var result1 = document.getElementById("result1");
function multiples(num) {
// declare sum assign it value 0
var sum = 0;
// declare a for loop that iterates while the counter "i" is less than num
for (var i = 0; i < num; i++) {
// if statement test whether the division remainder of 3 and 5 are equal to 0
if ((i % 3) === 0 || (i % 5) === 0) {
// assigns the value of i to sum
sum += i;
};
};
// returns the value of sum from the function callback argument 1000 etc.
return sum;
};
solution1.onclick = function(){
result1.value = multiples(parseInt(value1.value,10));
}
<label for="value">Enter Value: </label>
<input id="value1" class="value1" type="number" title="value field" placeholder="e.g. 1000">
<button type="button" id="solution1_btn" title="solution 1 button">Enter</button>
<input id="result1" class="result1" type="number" disabled>
Here is a fiddle with you problem - I hope solved: http://jsfiddle.net/w0qvdqb2/
There are few different problems in your code, first:
solution1.onclick = multiples(fix);
this means that multiples method should execute and return value is assigned to variable solution1.onclick but solution1.onclick accept callback.
Than based on your comments condition hasn't beed written as it's described.
And mixing with inputs and outputs classes and ids.
Please review updated code.

Categories