"+" behaving strangely in my functions - javascript

i'm making a mathematics app.
there, i want to be able to generate mathematic tasks with randomized operations.
var generator = {
operations: [
"+",
"-",
"*",
"/"
],
randomOperation: function(amount) {
if (amount == 2) {
return this.operations[Math.round(Math.random())];
}
if (amount == 4) {
return this.operations[Math.floor(Math.random() * 4)];
}
},
addOperand: function(operand, maxSize, minSize) {
var op = operand;
console.log('op ' + op);
if (operand == 2||4) {
console.log('getting random operand');
op = this.randomOperation(operand);
}
var number = this.randomNumber(maxSize, minSize);
console.log('number ' + number);
this.tasks.push({
value: number,
operation: op
});
console.log('added ' + op + ' ' + number);
}
// other stuff
}
so i want to be able to call the method with varying arguments:
'+', if i definitely want it to be a +
'-', if i want a -
and so on
if i pass a number (2 or 4), it is supposed to generate randomly out of 2 (+-) or 4 (+-*/)
but something really strange happens...
the console output is:
op +
getting random operand
number 2
added undefined 2
why is '+' considered 2||4 ?
it is clearly coming in as '+', but then somehow... passed to randomOperation(), which, of course, returns nothing.
thanks
PS: is there a way to paste code on here without the pain of manually correcting all the indentations? it's really annoying :(

The expression operand == 2 || 4 is parsed as (operand == 2) || 4.
It will be true if operand == 2, or 4 otherwise.
Both possible results are "truthy", and therefore the if branch is always taken, regardless of the value of operand
If instead you want the branch to be taken only if the operand is 2, or 4, you need:
(operand == 2 || operand == 4)

This:
if (operand == 2||4) {
doesn't mean "if operand == 2, or operand == 4" -- it means "if operand == 2, then true, otherwise 4.
You want to say:
if ((operand == 2) || (operand == 4)) {

That is not how you can check to see if a value is one or the other. What that code is doing is
if ( (operand==2) || 4 )
So id operand is 2 it is true, else it returns 4 which is truthy value. So basically it will always be true.
The check needs to be
if( operand == 2|| operand == 4)
or you can use modulus
if (operand %2 === 0)
or indexOf
if ([2,4].indexOf(operand)>-1)

Related

How can I add 2 and 4 to odd numbers in JavaScript?

I am a beginner in Javascript now I have started, the only background I have is HTML and CSS. I'm trying to make a program that prints whether a number is even or odd. But to the odd numbers to add 2 and 4. My code :
function isEvenExceptTwoOrFour(number) {
if (number%2 == 0 ) {
console.log("The number is even");}
else {
console.log("The number is odd ")
}
}
You could write an if..else statement like this, using Logical Or (||) to check each of your conditions.
Below I used the statement
if (number === 2 || number === 4 || number % 2 === 1)
This checks if number === 2 or number === 4 or number % 2 === 1 (if the number is odd)
Code:
function isEvenExceptTwoOrFour(number) {
if (number === 2 || number === 4 || number % 2 === 1) {
console.log("Number is considered odd");
} else {
console.log("Number is considered even")
}
}
isEvenExceptTwoOrFour(1);
isEvenExceptTwoOrFour(2);
isEvenExceptTwoOrFour(6);
Write a function that accepts an array of exceptions, and returns a new function that accepts a number. The closure (the function that's returned) will then 1) check to see if the number is in the array, and return false otherwise 2) check to see if the number is even, and return true, otherwise 3) return false.
// Pass in the exceptions array and return a function
// that will accept a number
function checkIsEvenExcept(exceptions) {
return function (n) {
if (exceptions.includes(n)) return false;
return n % 2 === 0 && true;
return false;
}
}
const exceptions = [2, 4, 18];
// Assign the result of calling `checkIsEvenExcept` with the
// exceptions array to a variable. This will be the function that
// we can call
const isEven = checkIsEvenExcept(exceptions);
// We can now call that function with a number
// that we need to check
console.log(isEven(6));
console.log(isEven(2));
console.log(isEven(1));
console.log(isEven(4));
console.log(isEven(8));
console.log(isEven(18));
You can just add conditions whether the number is 2 or 4.
function isEvenExceptTwoOrFour(number) {
if ( number === 2 || number === 4 ||| number % 2 !== 0){
console.log("The number is odd ")
return
}
console.log("The number is even")
}

"not equal value or type to", isnt working properly: Javascript

I have this code
function myFunction() {
var randomNumber = Math.floor(Math.random() * (1000-1+1))+1;
if ((String(randomNumber).substring(-1) !== "7") || (String(randomNumber).substring(-1) !== "8") || (String(randomNumber).substring(-1) !== "9")) {
alert(randomNumber);
}
else{
myFunction();
return;
}
}
The output should be so that 7, 8 and 9 can't be the last digit, and if it is it will be skipped.
But it doesn't seem to work, 7, 8 and 9 is frequently the last digit in the integer. Can somebody help me to get this working?
EDIT:
(String(randomNumber).substring(String(randomNumber).length-1) !== "7")
DOES THE TRICK
TLDR
x !== ("0" || "8" || "9")
If the comparison is meant to be "x is not '0' or '8' or '9', then it will need to be split into different comparisons.
x !== "0" || x !== "8" || x !== "9"
What's happening in the original comparison?
The parens () are grouping "0" || "8" || "9" which is resulting in "0".
This group is being compared first, before ===, due to operator precedence.
How come the result of the group is "0"?
The logical OR operator checks if the left-hand argument is "truthy". If yes, then it is returned, if no, the right-hand argument is returned.
For example:
let variable = A || B
If A is truthy, A is assigned to variable, otherwise B is assigned to variable.
Apologies if the wrong terminology is used.

Recursion check whether a series of operations yields a given number

In the book Eloquent JS in the section of recursion, a program was given:
Consider this puzzle: by starting from the number 1 and repeatedly
either adding 5 or multiplying by 3, an infinite amount of new numbers
can be produced. How would you write a function that, given a number,
tries to find a sequence of such additions and multiplications that
produce that number? For example, the number 13 could be reached by
first multiplying by 3 and then adding 5 twice, whereas the number 15
cannot be reached at all.
I have following program which look like checks it, but I don't know how to make it print he sequence.
function tester (value, key) {
if (value == key) {
return 1;
}
else if (value > key) {
return 0;
}
else {
if ( tester(value+5, key) || tester(value*3, key) ) {
return 1;
}
return 0;
}
}
Your version is a little odd to me, returning 1 or 0 rather than true or false. Are you mostly used to a language that conflates booleans with such integers? But it looks like it should work.
I would write it a bit differently. I generally prefer my recursion to count down to smaller inputs. You can write a simple function to test the values like this:
const m3a5 = (n) => n < 1
? false
: n == 1
? true
: m3a5(n - 5) || (n % 3 === 0 && m3a5(n / 3))
console.log(m3a5(13)) //=> true
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> true
This should be entirely equivalent to yours, modulo the boolean/int differences.
With this one, you can can then expand it in a fairly straightforward manner to allow you to capture the steps:
const m3a5 = (n, steps = []) => n < 1
? false
: n == 1
? steps
: m3a5(n - 5, ['+5'].concat(steps))
|| (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
console.log(m3a5(13)) //=> ['*3', '+5', '+5']
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> ['*3', '+5, '+5', '+5']
Note that this will show one possible path, not all of them. For instance ['+5', '*3'] is another possible result for m3a5(18), one which you would get by switching the main branch to
: (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
|| m3a5(n - 5, ['+5'].concat(steps))
But if you want all the paths, that would be significantly different code.
You could store the sequence and if found the calculation return the sequence.
function tester(key, value = 1, sequence = value) {
if (value > key) {
return false;
}
if (value === key) {
return sequence;
}
return tester(key, value + 5, '(' + sequence + ' + 5)')
|| tester(key, value * 3, sequence + ' * 3');
}
console.log(tester(15));
console.log(tester(11));
console.log(tester(24));
console.log(tester(37));

JavaScript if else statement ignored

I have a simple if statement below:
function calculateTotal() {
if (tanksize != 1 || tanksize != 2) {
var setupPrice = basicPrice + StatPrice() + DigiStatPrice() + IRPrice() + UVPrice() + cagePrice();
var setupPrice2 = toFixed(setupPrice, 2);
} else {
var setupPrice = basicPrice;
var setupPrice2 = toFixed(setupPrice, 2);
}
//display the result at the top of page
var divobj = document.getElementById('totalPrice');
divobj.innerHTML = "£" + setupPrice2;
//display the result at the bottom of page
var divobj = document.getElementById('totalPrice2');
divobj.innerHTML = "£" + setupPrice2;
}
But when the tanksize variable is set to 1 or 2, the setupPrice variable is still calculated by adding the basicPrice + StatPrice...etc.
You need to use:
if (tanksize !== 1 && tanksize !== 2) {
with the && operator, or
if (!(tanksize ===1 || tanksize === 2)) {
In your code, you have the first block executing any time the value is not 1 or is not 2, which equates to it always executing.
If the value is 1, then tanksize != 2 is true so tanksize!=1 || tanksize!=2 is true.
If the value is 2, then tanksize != 1 is true so tanksize!=1 || tanksize!=2 is true.
In other words, tanksize!=1 || tanksize!=2 is always true, no matter what the value of tanksize is.
This statement is always true:
if(tanksize!=1 || tanksize!=2){
because, when tanksize = 1, tanksize is different of 2
and when tanksize = 2, tanksize is different of 1.
It is not a javascript error, you just need to change your logic to make the right test in the if...
Try if(tanksize!=1 && tanksize!=2){ instead of if(tanksize!=1 || tanksize!=2){
Your Logic is wrong..
As a matter of fact, OR Operator for two NOT EQUALS is always TRUE ( check boolean table for this) and the conditional statement "if" checks for TRUE or FALSE, hence your code will always return TRUE
Use something like
if(tanksize!=1 && tanksize!=2){
# Your code
}
(tanksize!=1 || tanksize!=2) always will be true by this statement. Change operator || to &&
your first condition is always true, cuz for example if some x = 1, is different of 2 and vice versa.
so this condition is kind of equal to.
if(true) {
// ...
}

A quick way to test equality of more than 2 values at once?

I was wondering if there was a quick way to test the equality of more than two values in js. Something similar to (= 6 6 6).
In the console, I tried things like...
1 == 1 == 1 == 1
true
2 == 2 == 2 == 2
false
0 == 0 == 0
false
0 == 0 == 0 == 0
true
...which was amusing, but also puzzling.
Is there a quick way of doing this in js?
Thanks.
The reason you got unexpected behavior is because we need to adjust your expectations in js a bit ;) 2 == 2 == 2 == 2 does 3 comparisons, all from left to right. The first comparison is the leftmost 2 == 2, which evaluates to true. After that we get the result of the first comparison being compared to (what is in this case) the 3rd 2. Ie, true === 2, which is false. And finally, we get false === 2, which is also false.
It might help to visualize it as such:
(((2 == 2) == 2) == 2)
I think in general a === b && b === c might be what you're looking for.
EDIT: Ah, and sorry I keep switching out the == for ===. It's just habit. And it's a habit I'd recommend. the === operator doesn't do type casting, so it evaluates the value proper, not a casted version of the value.
It's because true == 1 but true != 2
You can try:
function isEquals() {
var flag = true;
for(var i=1; i<arguments.length; i++) flag = flag && (arguments[i] == arguments[0]);
return flag;
}
isEquals(2,2,2); // true
or:
function isEquals() {
var ar = arguments;
return Array.prototype.every.call(arguments, function(a){return a==ar[0];});
}
Yes you can, but you need to use the "Logical Operators" like the && or || to check more than 1 statement like (x<1 && y>0).
You can use this as a quick easy reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
If you have more than three values, it might be more convenient to create a function for use on an array:
function allEqual(arr) {
return arr.every(function (x, i) {
return i === 0 || x === arr[i - 1];
});
}
allEqual([1, 1, 1])
ES6:
function allEqual(...arr) {
return arr.every((x, i) => i === 0 || x === arr[i - 1]);
}
allEqual(1, 1, 1)
As an addition to #vp_arth's answer you could even add a method to the Array prototype
Array.prototype.isHomogeneous = function(){
return Array.prototype.every.call(this, function(c,i,a){ return c === a[0];})
}
So you could do
[1,2,3].isHomogeneous() = false
[1,1,1].isHomogeneous() = true

Categories