incorrect variable declaration? or erratic modulo behavior? - javascript

why, in the following code, does modB always equal 1? ESPECIALLY considering b % 2 doesn't?
var b = 0;
var modB = 0;
function buttonState() {
b++;
modB = b % 2;
if (modB = 1) {
theButtonState = true;
} else {
theButtonState = false;
}
console.log(b%2);
console.log(modB);
console.log(theButtonState);
}

Change the following line of code:
if (modB = 1)
to
if (modB == 1)
and then try running the program again.
You can do it this way too as (Felix explained):
theButtonState = modB == 1;
Brevity in code improves its readability immensely.

Related

find helper JavaScript

I have found this script on the Mozilla Development Network as an example.
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
Could you explain me what the double "+" means right after the "start"? Will it change the value of the start variable?
Thank you
This is the same as
var old_value = start;
start = start + 1;
if (element % old_value < 1) {
...
Read the value of the variable and then increase it by one.
The double "+" after a variable means that it will increase that variable by 1 after it has used it in the statement.
So in your case element % start++ < 1 is equivalent to element % start < 1; start = start+1;
On the other hand, having the "++" before the variable, means it will first increment the variable, and then execute the statement.
Here are some examples of this behaviour:
var a = 1;
var b = a++;
console.log(b); // 1
console.log(a); // 2
var c = 1;
var d = ++c;
console.log(d); //2
console.log(c); //2
var test = 2;
if (8 % test++ < 1) {
console.log("will log");
}
test = 2;
if (8 % ++test < 1) {
console.log("will NOT log");
}

for loop in javascript is skipping else if condition half the time

I'm was just fiddling around with javascript and I wrote function using Math.random that I thought would return a coin-flip. Then I was curious so I ran it through a loop to test how often it flips true/false. I found out my loop is skipping about half of the else if conditions, and was able to verify this by catching them in the errors var. So, why is it doing this?
var truths = 0;
var alternativetruths = 0;
var errors = 0;
function game() {
var score = Math.random()*10;
return score>5;
}
for(i=0;i<999999;i++) {
if (game() === true) {
truths++
} else if (game() === false) {
alternativetruths++
} else {
errors++
}
}
console.log("truths:",truths,"alternativetruths:",alternativetruths,"errors:",errors)
truths: 500393 alternativetruths: 249580 errors: 250026
Your code calls game() twice. If the first call isn't true, then the second might or might not be true.
Just call game() once and assign the result to a variable. Don't make explicit comparisons to true and false; if statements work off boolean values, and your function already returns one of those.
for (var i = 0; i < 999999; i++) {
var result = game();
if (result)
truths++;
else
alternativetruths++;
}
Because you're calling game twice, and thus getting two different random flags.
The minimal change is to remember the number:
for(i=0;i<999999;i++) {
var flag = game();
if (flag === true) {
truths++
} else if (flag === false) {
alternativetruths++
} else {
errors++
}
}
But a couple of other notes:
If flag is a boolean (and it is, it's the result of the > operator), then if (flag === true) is pointless. Just use if (flag). The result of the === operator is a boolean too, so if you don't trust them to be true or false, where do you stop? :-) if ((flag === true) === true)?
Separately, if (flag === false) should just be if (!flag).
If flag is a boolean (and it is), then if you have if (flag), having else if (!flag) and then else doesn't make any sense. There is no way you'll reach that final else. Just if (flag) { } else { } is all you need.
But, game isn't fair, it has a very slight bias toward returning false. Remember, the range returned by Math.random() * 10 is 0 to just under 10, so checking for > 5 means you're skipping the midpoint. Because you're dealing with very small fractional numbers, you don't notice the bias, but it's there; it would be more obvious if you rounded to whole numbers, at which point it would be roughly 40%/60% true/false. You want >= 5 for fair results.
game can rather moer succinctly be written: return Math.random() >= 0.5;.
Because you're not declaring i, you're falling prey to The Horror of Implicit Globals (that's a post on my anemic little blog). Remember to declare your variables.
Re > vs. >=, here's an example where I've rounded to whole numbers to make the effect clearer:
for (var n = 0; n < 4; ++n) {
setTimeout(test.bind(null, n, true), 200 * n);
setTimeout(test.bind(null, n, false), 200 * n + 100);
}
function test(num, gte) {
var truths = 0;
var alternativetruths = 0;
var errors = 0;
function game() {
var score = Math.floor(Math.random() * 10);
return gte ? score >= 5 : score > 5;
}
for (var i = 0; i < 999999; i++) {
var flag = game();
if (flag) {
truths++;
} else {
alternativetruths++;
}
}
showStats(num, gte, truths, alternativetruths);
}
function showStats(num, gte, truths, alternativetruths) {
var total = truths + alternativetruths; // Should be 999999 of course
var truthsPercent = (truths * 100) / total;
var altPercent = (alternativetruths * 100) / total;
console.log(num, gte ? ">=" : ">", "truths:", truths, "alternativetruths:", alternativetruths, "(" + truthsPercent.toFixed(2) + "% vs. " + altPercent.toFixed(2) + "%)");
}
.as-console-wrapper {
max-height: 100% !important;
}
You need to assign game to a var before test for its value. Otherwise, everytime yout check the value with game() you will check a new value. So it can be false at the first check and true at the second and for this reason increment your errors.
Try this:
for(i=0;i<999999;i++) {
let gameResult = game();
if (gameResult === true) {
truths++
} else if (gameResult === false) {
alternativetruths++
} else {
errors++
}
}

Recursive function or loop in javascript?

I am trying to write a recursive function, but I am completely lost as to how to implement it. I currently have the following:
function change(p){
// code for function
}
var c1 = change(start);
var c2 = change(c1);
var c3 = change(c2);
// etc. etc.
Is there any way to do this with a while loop? For example:
while(currentResultofFunction != goal)
nestedly loop through as before until reaches true
function change(p) {
if (p != 1) { // your condition
change(p);
} else return p;
}
What about:
var val = start;
while(val) //or while val != goal
val = change(val);
What you are doing, is not recursive. You maybe mean iterative.
You can loop through the variables in this way:
var n = 2;
for (var i = 1; i <= n; i++) {
if (i == 1) window['c1'] = change(start);
else window['c' + i] = change(window['c' + (i - 1)]);
}

How to change a variable to something if it's undefined?

I don't have my script completed yet or anything so I can't post the code. Basically I need a variable to change and keep going through a function increasing by one until it reaches its destination. Something like:
function one(a) {
var x = a;
var max = 3;
if (a < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
}
}
function two(x) {
var change = x+1;
one(change);
}
It all works how I need it but when I first enter function one how would I make it so when x = a doesn't have a value that it will by default be 0?
something like...
function one(a) {
var x = a;
var max = 3;
if (x = undefined) {
x = 0;
} else {
if (x < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
}
}
}
function two(x) {
var change = x+1;
one(change);
}
Any ideas?
You could do this:
function one(a) {
var x = a || 0;
if (x < 3) {
//debugger;
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
alert('Done');
}
}
function two(x) {
x++;
one(x);
}
one();
FIDDLE
var x = a || 0 means x is a if a can be asserted as true or 0.
x++ means x = x + 1
You can check to see if the variable is defined and send it in the functions argument by using the short hand conditional.
typeof(a)=="undefined" ? 0 : a;
You can change your code to:
function one(a) {
var x = (typeof(a)=="undefined" ? 0 : a);
var max = 3;
if (x < 3) {
// some code
two(x);
} else {
// function will end here quitting the whole thing and possibly other code
return;
}
}
Fiddle: http://jsfiddle.net/gBBL2/
var x = (typeof a === 'undefined') ? 0 : a;
If a is undefined, use 0. Otherwise use a as the value of x.

Max call stack exceeded

I understand what maximum call stack exceeded is. However, is there a workaround for this for my code? Furthermore, there will be a time where it eventually will stop looping, that is when position > counter1.
var a = 0;
var b = 1;
var c;
var counter1 = 1;
var position = 0;
window.onload = function() {
var position = prompt("Please enter the position number.","0");
calc1();
}
function calc1() {
if(position <= counter1) {
c = a+b;
counter1++;
calc2();
}
else {
callResult();
}
}
function calc2() {
if(position <= counter1) {
a = b+c;
counter1++;
calc3();
}
else {
callResult();
}
}
function calc3() {
if(position <= counter1) {
b = c+a;
counter1++;
calc1();
}
else {
callResult();
}
}
function callResult() {
if (position %3 == 1) {
document.getElementById("answer").innerHTML = a;
}
else if (position %3 == 2) {
document.getElementById("answer").innerHTML = b;
}
else {
document.getElementById("answer").innerHTML = c;
}
}
You should avoid recursion and use loop. Something like this:
window.onload = function() {
var position = prompt("Please enter the position number.","0");
maincalc();
}
function maincalc() {
var subcalc = [ calc1, calc2, calc3 ];
var calccount = 0;
while(position <= counter1) {
subcalc[ calccounter ]();
calccounter = (calccounter +1) % 3;
}
}
The value of position is given once and never changed.
You then check, if(position <= counter1) in each call calc1, calc2, calc3 which call each other thus:
calc1 -> calc2 -> calc3 -> calc1 -> ...
This will clearly continue until you run out of stack space.
Perhaps if you increment position instead of counter1 or keep calling while position is greater than the counter this problem will go away,
i.e.
if(position > counter1)
You probably need to step back and think about what you are really trying to do.
as I understand you are calculating Fibonacci numbers sum?
see this Javascript Fibonacci answer to learn how to do it much easier and without any recursive calls

Categories

Resources