Javascript if/if else/else not working - javascript

So I have this javascript, but it's not working.
var verbs = [ ["ambulo", "ambulare", "ambulavi", "ambulatus"], ["impedio", "impedire", "impedivi", "impeditus"] ]
var verbNumber = verbs.length - 1;
function randomIntFromInterval(min,max) {
return Math.floor(Math.random()*(max-min+1)+min);
}
/* Picks a verb */
var thisVerb = verbs[randomIntFromInterval(0, verbNumber)];
/* Checks the conjugation */
var second = thisVerb[1];
var secondLength = second.length;
var start = secondLength - 3;
var secondEnding = second.substring(start, secondLength);
var conjugationNumber = 0;
if (secondEnding === "are") {
conjugationNumber = 1;
} else if (secondEnding === "ēre") {
conjugationNumber = 2;
} else if (secondEnding === "ere") {
conjugationNumber = 3;
} else if (secondEnding === "ire") {
conjugationNumber = 4;
} else {
console.log("error");
};
/* Randomly picks how to conjugate */
var tense = randomIntFromInterval(1, 6);
var person = randomIntFromInterval(1, 3);
var number = randomIntFromInterval(1, 2);
var voice = randomIntFromInterval(1, 2);
/* Conjugates */
var thisDictEntry = 0;
if ((conjugationNumber === 1 || 2) && (tense === 1 || 2 || 3)) {
thisDictEntry = 2;
} else if ((conjugationNumber === 3 || 4) && (tense === 1 || 2 || 3)) {
thisDictEntry = 1;
} else if ((tense === 4 || 5 || 6) && (voice === 1)) {
thisDictEntry = 3;
} else if ((conjugationNumber === 3 || 4) && (voice === 2)) {
thisDictEntry = 4;
} else {
console.log("Error");
};
What should happen is a random verb (array within an array) is picked, then becomes randomly conjugated. All the code works up until the if/else if/else statements under the /* Conjugates */. That, for some reason, always sets thisDictEntry to 2.
Why?

The first condition:
((conjugationNumber === 1 || 2) && (tense === 1 || 2 || 3))
should be:
((conjugationNumber === 1 || conjugationNumber === 2) && (tense === 1 || tense === 2 || tense === 3))
the problem with your version is that javascript does the following:
conjugationNumber === 1 // this results in true/false
or
2 // this is always true
because js evaluates it as truthy.

Related

Can a Javascript condition be between numbers?

I'm looking to identify a category based on this table:
I have an if statement that seems to work for some conditions, but not others. R, P, and Q are working, but conditions that go between numbers aren't returning the right category.
If statement:
function getCategory(featureFunctionalScore, featureDysfunctionalScore) {
if (featureFunctionalScore == 4 && featureDysfunctionalScore == -2) {
return "Performance";
} else if (featureFunctionalScore == 4 && featureDysfunctionalScore <= -1 && featureDysfunctionalScore > 4) {
return "Attractive"
} else if (featureFunctionalScore <= -1 && featureFunctionalScore > 4 && featureDysfunctionalScore == 4) {
return "Expected"
} else if ((featureFunctionalScore >= -2 && featureFunctionalScore <= 2 && featureDysfunctionalScore == -2) || (featureFunctionalScore == -2 && featureDysfunctionalScore >= -2 && featureDysfunctionalScore <= 2)) {
return "Reverse"
} else if ((featureFunctionalScore == 4 && featureDysfunctionalScore == -2) || (featureFunctionalScore == 2 && featureDysfunctionalScore == -1) || (featureFunctionalScore == -1 && featureDysfunctionalScore == 2) || (featureFunctionalScore == -2 && featureDysfunctionalScore == 4)) {
return "Questionable"
} else {
return "Indifferent"
};
};
Am I missing something important?
Update
This statement works in Excel, but I'm struggling to get it to work in JS:
=IF(OR(AND(C3 <= 2, B3 <= -1), AND(C3 <= -1, B3 <= 2)), "R", IF(AND(C3 <= 2, C3 >= -1, B3 <= 2, B3 >= -1), "I", IF(AND(C3 >= 2,B3 >= -1, B3 <= 2),"A", IF(AND(C3 <= 2, B3 <= 4, B3 >= 2), "M", IF(AND(C3 >= 2, B3 >= 2), "P", "Q")))))
This should be what you're looking for. I'm sure it could be optimized, but it works. JSFiddle: https://jsfiddle.net/yxb7tr9n/
function getCategory(x,y){
var answer = -999;
if (x == 4 && y == 4){
answer = "p";
}else if([-1,0,2].indexOf(x) >= 0 && y == 4){
answer = "A";
}else if((x == -2 && y == 4) || (x == -1 && y == 2) || (x == 4, y == -2)){
answer = "Q";
}else if(x == 4 && [-1,0,2].indexOf(y) >= 0) {
answer = "M";
}else if((x == -1 && [-1,0].indexOf(y) >= 0) || (x == 0 && [-1,0,2].indexOf(y) >= 0) || (x == 2 && [0,2].indexOf(y) >= 0)){
answer = "I";
}else if ((x == -2 && [-2,-1,0,2].indexOf(y) >= 0) || (y == -2 && [-2,-1,0,2].indexOf(x) >= 0)) {
answer = "R";
}else{
answer = "??";
}
return answer;
}
UPDATE: Alternate version using a coordinate mapping system. JSFiddle: https://jsfiddle.net/g2d6p4rL/4/
function indexOfCustom (parentArray, searchElement) {
for ( var i = 0; i < parentArray.length; i++ ) {
if ( parentArray[i][0] == searchElement[0] && parentArray[i][1] == searchElement[1] ) {
return i;
}
}
return -1;
}
function getCategory2(x,y){
var p = [[4,4]];
var q = [[-2,4],[-1,2],[2,-1],[4,-2]];
var a = [[-1,4],[0,4],[2,4]];
var m = [[4,2],[4,0],[4,-1]];
var i = [[0,2],[2,2],[-1,0],[0,0],[2,0],[-1,-1],[0,-1]];
var r = [[-2,2],[-2,0],[-2,-1],[-2,-2],[-1,-2],[0,-2],[2,-2]];
coord = [x,y];
if (indexOfCustom(p,coord) >= 0){
return "p";
} else if (indexOfCustom(q,coord) >= 0){
return "Q";
} else if (indexOfCustom(a,coord) >= 0){
return "A";
} else if (indexOfCustom(m,coord) >= 0){
return "M";
} else if (indexOfCustom(i,coord) >= 0){
return "I";
} else if (indexOfCustom(r,coord) >= 0){
return "R";
}else{
return "??";
}
}
Output of all answers:
[-2,-2] = R
[-2,-1] = R
[-2,0] = R
[-2,2] = R
[-2,4] = Q
[-1,-2] = R
[-1,-1] = I
[-1,0] = I
[-1,2] = Q
[-1,4] = A
[0,-2] = R
[0,-1] = I
[0,0] = I
[0,2] = I
[0,4] = A
[2,-2] = R
[2,-1] = Q
[2,0] = I
[2,2] = I
[2,4] = A
[4,-2] = Q
[4,-1] = M
[4,0] = M
[4,2] = M
[4,4] = p

How to make Web Worker async?

The task is: work with large amount of data in the Worker and render the result of the algorithm after each iteration (I render dataObj to the HTML). Using following code make web page freezed and slow. How to avoid it?
onmessage = (e) => {
let number = 0;
let totalNumbers = 0;
let primeNumbers = 0;
if (e.data === "start"){
while(true){
totalNumbers++;
if (isPrime(number)){
primeNumbers++;
}
number++;
let dataObj = {
totalNumbers: totalNumbers,
primeNumbers: primeNumbers
}
postMessage(dataObj);
}
} else{
}
}
function isPrime(n) {
if (n == 2 || n == 3 || n == 5 || n == 7) {
return true;
} else if ((n < 2) || (n % 2 == 0)) {
return false;
} else {
for (var i = 3; i <= Math.sqrt(n); i += 2) {
if (n % i == 0)
return false;
}
return true;
}
}

What is the short form of this compare variable code

Is there a way that I can combine these two codes into one? I want to check if some variables are equal to 0 or equal to 1 or equal to 2 or greater than 2 and less than 5 or greater than 5. Should I write a code for each variable or I can write a code for all variables?
<script>
if (NRIRDL==0){
XRIRDL=0;
}
else if (NRIRDL == 1){
XRIRDL = 1;
}
else if (NRIRDL == 2){
XRIRDL = 1.8;
}
else if (NRIRDL > 2 && NRIRDL < 5){
XRIRDL = 0.9 * NRIRDL;
}
else {
XRIRDL = NRIRDL - 1;
}
// code below is the same as code above, but variables are different.
if (NRIRDR==0){
XRIRDR=0;
}
else if (NRIRDR == 1){
XRIRDR = 1;
}
else if (NRIRDR == 2){
XRIRDR = 1.8;
}
else if (NRIRDR > 2 && NRIRDR < 5){
XRIRDR = 0.9 * NRIRDR;
}
else {
XRIRDR = NRIRDR - 1;
}
</script>
actually, it can be written shorter with ternary operator and without multiple if conditions, check it out:
function getValue(n) {
return n >= 2 && n < 5 ? n * 0.9 : n == 0 ? 0 : n == 1 ? 1 : n - 1;
}
var var1 = 0;
var var2 = 1;
var var3 = 2;
var var4 = 3;
var var5 = 5;
console.log(getValue(var1)); // outputs 0
console.log(getValue(var2)); // outputs 1
console.log(getValue(var3)); // outputs 1.8
console.log(getValue(var4)); // outputs 2.7
console.log(getValue(var5)); // outputs 4
Just use getValue(n) function: pass your variable and it will return needed value that can be stored into another variable like var XRIRDL = getValue(NRIRDL); or var XRIRDR = getValue(NRIRDR);
You could make it into a function:
function yourFunction(val) {
if (val == 0){
return 0;
}
else if (val == 1){
return 1;
}
else if (val == 2){
return 1.8;
}
else if (val > 2 && val < 5){
return 0.9 * val;
}
else {
return val - 1;
}
XRIDR = yourFunction(NRIDR);
XRIDL = yourFunction(NRIDL);
When you OR the two inputs together, you lose valuable information about which one of the two inputs triggered that condition.
Mike's answer might not fit your needs because you can't update the values independently of one another (i.e. if NRIDR == 0 and NRIDL == 2, it sounds like you don't want both XRIDR and XRIDL to equal 1.8.)
You could put it inside a function. Here's a copy paste of your code inside a function.
function xrirdr(dr_or_dl){
var XRIRDL = null;
if (dr_or_dl==0){
XRIRDL=0;
}
else if (dr_or_dl == 1){
XRIRDL = 1;
}
else if (dr_or_dl == 2){
XRIRDL = 1.8;
}
else if (dr_or_dl > 2 && dr_or_dl < 5){
XRIRDL = 0.9 * dr_or_dl;
}
else {
XRIRDL = dr_or_dl - 1;
}
return XRIRDL;
}
You can pass NRIRDL or NRIRDR in the function and it will get you your XRIRDL
<script>
if (NRIRDL==0 || NRIRDR==0 ){
XRIRDL=0;
XRIRDR=0;
}
else if (NRIRDL == 1 || NRIRDR == 1)){
XRIRDL = 1;
XRIRDR = 1;
}
else if (NRIRDL == 2 || NRIRDR == 2)){
XRIRDL = 1.8;
XRIRDR = 1.8;
}
else if ((NRIRDL > 2 && NRIRDL < 5) || (NRIRDR > 2 && NRIRDR < 5) ){
XRIRDL = 0.9 * NRIRDL;
XRIRDR = 0.9 * NRIRDR;
}
else {
XRIRDL = NRIRDL - 1;
XRIRDR = NRIRDR - 1;
}
</script>

Make sure a sum is asked only once (js)

I have a multiplication game and I want a random number 12 times but how can I get that without it getting a number repeated. This is what I've tried but I keep getting 'Undefined' returned. (I'm using Firefox 51.0.1)
$(".input").val("");
var numbers_used = [];
var current_number = 0;
var max_num = 12;
var base_number = parseInt(prompt("Enter which table you want to practice.", "5"));
var maxScore = 12;
var questionsAnswered = 0;
var questionsAnsweredCorrect = 0;
var questionsAnsweredWrong = 0;
var asked1 = false;
var asked2 = false;
var asked3 = false;
var asked4 = false;
var asked5 = false;
var asked6 = false;
var asked7 = false;
var asked8 = false;
var asked9 = false;
var asked10 = false;
var asked11 = false;
var asked12 = false;
function new_random_number() {
var new_current_number = Math.round(Math.floor((Math.random() * max_num) + 1));
return new_current_number;
}
function overallNumber() {
current_number = new_random_number();
if((current_number == 1 && !asked1) ||
(current_number == 2 && !asked2) ||
(current_number == 3 && !asked3) ||
(current_number == 4 && !asked4) ||
(current_number == 5 && !asked5) ||
(current_number == 6 && !asked6) ||
(current_number == 7 && !asked7) ||
(current_number == 8 && !asked8) ||
(current_number == 9 && !asked9) ||
(current_number == 10 && !asked10) ||
(current_number == 11 && !asked11) ||
(current_number == 12 && !asked12)
){
if(current_number == 1)
asked1 = true;
if(current_number == 2)
asked2 = true;
if(current_number == 3)
asked3 = true;
if(current_number == 4)
asked4 = true;
if(current_number == 5)
asked5 = true;
if(current_number == 6)
asked6 = true;
if(current_number == 7)
asked7 = true;
if(current_number == 8)
asked8 = true;
if(current_number == 9)
asked9 = true;
if(current_number == 10)
asked10 = true;
if(current_number == 11)
asked11 = true;
if(current_number == 12)
asked12 = true;
return current_number;
} else overallNumber();
When I continuously call this function it just starts returning 'Undefined'. Any Solutions? Thx :)
The code should be self-explanatory, main thing is that you have to keep track of the used numbers using an array.
var number;
var maxNumber = 5;
var usedNumbers = [];
function getUnusedRandomNumber(){
// keep generating a random number, until you find one that has not been used
do{
var randomNumber = getRandomNumber();
}
while(usedNumbers.indexOf(randomNumber) != -1);
// store used numbers into array
usedNumbers.push(randomNumber);
return randomNumber;
}
function getRandomNumber() {
var randomNumber = Math.round(Math.floor((Math.random() * maxNumber) + 1));
return randomNumber;
}
alert(getUnusedRandomNumber());
alert(getUnusedRandomNumber());
alert(getUnusedRandomNumber());
alert(getUnusedRandomNumber());
alert(getUnusedRandomNumber());
A more condensed code is to generate random number without repetition is
var nums = [], numsLen = 12, maxNum = 12, num;
while (nums.length < numsLen) {
num = Math.round(Math.random() * maxNum);
if (nums.indexOf(num) === -1) {
nums.push(num);
}
}
console.log(nums);

How do you return the resulting object in a function?

Good day, all! :)
For the past month, I have been working on a function to return 2 or more THREE.js materials in 1 function at 1 time. I've run into a small problem though. For some reason, I can't get this function to return the MeshBasicMaterial object AS WELL AS the MeshLambertMaterial data object. I KNOW my code is right because I've gone over it over 40 times already looking for errors.
Here's the WHOLE code:
/**
* A function for converting hex <-> dec w/o loss of precision.
*
* The problem is that parseInt("0x12345...") isn't precise enough to convert
* 64-bit integers correctly.
*
* Internally, this uses arrays to encode decimal digits starting with the least
* significant:
* 8 = [8]
* 16 = [6, 1]
* 1024 = [4, 2, 0, 1]
*/
// Adds two arrays for the given base (10 or 16), returning the result.
// This turns out to be the only "primitive" operation we need.
function add(x, y, base)
{
var z = [];
var n = Math.max(x.length, y.length);
var carry = 0;
var i = 0;
while (i < n || carry)
{
var xi = i < x.length ? x[i] : 0;
var yi = i < y.length ? y[i] : 0;
var zi = carry + xi + yi;
z.push(zi % base);
carry = Math.floor(zi / base);
i++;
}
return z;
}
// Returns a*x, where x is an array of decimal digits and a is an ordinary
// JavaScript number. base is the number base of the array x.
function multiplyByNumber(num, x, base)
{
if (num < 0) return null;
if (num == 0) return [];
var result = [];
var power = x;
while (true)
{
if (num & 1)
{
result = add(result, power, base);
}
num = num >> 1;
if (num === 0) break;
power = add(power, power, base);
}
return result;
}
function parseToDigitsArray(str, base)
{
var digits = str.split('');
var ary = [];
for (var i = digits.length - 1; i >= 0; i--)
{
var n = parseInt(digits[i], base);
if (isNaN(n)) return null;
ary.push(n);
}
return ary;
}
function convertBase(str, fromBase, toBase)
{
var digits = parseToDigitsArray(str, fromBase);
if (digits === null) return null;
var outArray = [];
var power = [1];
for (var i = 0; i < digits.length; i++)
{
// invariant: at this point, fromBase^i = power
if (digits[i])
{
outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase);
}
power = multiplyByNumber(fromBase, power, toBase);
}
var out = '';
for (var i = outArray.length - 1; i >= 0; i--)
{
out += outArray[i].toString(toBase);
}
return out;
}
function decToHex(decStr) {
var hex = convertBase(decStr, 10, 16);
return hex ? '0x' + hex : null;
}
function hexToDec(hexStr) {
if (hexStr.substring(0, 2) === '0x') hexStr = hexStr.substring(2);
hexStr = hexStr.toLowerCase();
return convertBase(hexStr, 16, 10);
}
function instr(str, val)
{
if(typeof(str) === 'string')
{
str = str.toString(str);
val = val.toString(val);
in_str = str.indexOf(val);
return in_str;
}
else
{
api_messagebox('Please use a string!');
}
return false;
}
function Get_RGBA(hexVal, getwhich)
{
hexVal = hexVal || '';
getwhich = getwhich || 0;
var commaSeperated = 0;
//if(typeof(hexVal) === 'string')
//{
// Removes the first character from the input string
if(hexVal.length === 8) { hexVal = hexVal.substring(1, hexVal.length); }
if(hexVal.length === 10) { hexVal = hexVal.substring(0, hexVal.length); }
// Now let's separate the pairs by a comma
for (var i = 0; i <= hexVal.length; i++)
{
// Iterate through each char of hexVal
// Copy each char of hexVal to commaSeperated
commaSeperated += hexVal.charAt(i);
// After each pair of characters add a comma, unless this
// is the last char
commaSeperated += (i % 2 == 1 && i != (hexVal.length - 1)) ? ',' : '';
}
// Lets now remove the 0x
if(instr(commaSeperated, '0x'))
{
commaSeperated = commaSeperated.substr(4);
}
if(instr(commaSeperated, ','))
{
// Lets now remove all "," 's
commaSeperated = commaSeperated.replace(/,/g, '');
if( getwhich < 0 ) { getwhich = 0; }
if( getwhich > 5 ) { getwhich = 5; }
alpha = [];
red = [];
green = [];
blue = [];
allcol = [];
sixcol = [];
alpha[0] = commaSeperated[0]+commaSeperated[1];
red[0] = commaSeperated[2]+commaSeperated[3];
green[0] = commaSeperated[4]+commaSeperated[5];
blue[0] = commaSeperated[6]+commaSeperated[7];
allcol[0] = alpha[0]+red[0]+green[0]+blue[0];
sixcol[0] = red[0]+green[0]+blue[0];
if( getwhich === 0 ) { fi_string = alpha[0]; }
if( getwhich === 1 ) { fi_string = red[0]; }
if( getwhich === 2 ) { fi_string = green[0]; }
if( getwhich === 3 ) { fi_string = blue[0]; }
if( getwhich === 4 ) { fi_string = allcol[0]; }
if( getwhich === 5 ) { fi_string = sixcol[0]; }
if( getwhich === 4 && fi_string.length != 10 || fi_string.length != 9 ) { getwhich = 5; }
if( getwhich === 5 && fi_string.length != 8 || fi_string.length != 7 ) { getwhich = 4; }
// Split the commaSeperated string by commas and return the array
return fi_string.toString();
}
//}
}
function isArray(myArray)
{
return myArray.constructor.toString();
//myArray.constructor.toString().indexOf("Array") > -1;
}
//EntityMaterial(0, 0, 0xFF44CFFC, 1, 0xFF000000, 4, 4, 0, 1.0, 0.8, "LambertBasicMaterial", 1)
function EntityMaterial(ptex, side, color, wire, wirecolor, col_type, col_wire_type, shading, transparent, opacity, mat_type, overdraw)
{
ptex = ptex || 0;
side = side || 0;
color = color || 0xFF006400;
wire = wire || 0;
wirecolor = wirecolor || 0xFF006400;
col_type = col_type || 4;
col_wire_type = col_wire_type || 4;
shading = shading || false;
transparent = transparent || 0.0;
opacity = opacity || 1.0;
mat_type = mat_type || "BasicMaterial";
overdraw = overdraw || true;
color = decToHex(color.toString());
wirecolor = decToHex(wirecolor.toString());
var gRGBA1 = Get_RGBA(color, col_type);
var gRGBA2 = Get_RGBA(wirecolor, col_wire_type);
var mat = 0;
if(mat_type === 'BasicMaterial')
{
this.materials = new THREE.MeshBasicMaterial
(
{
color: parseInt(gRGBA1, 16)
}
)
}
else if(mat_type === 'LambertMaterial')
{
this.materials = new THREE.MeshLambertMaterial
(
{
color: parseInt(gRGBA2, 16),
opacity: opacity,
wireframe: wire,
transparent: transparent
}
)
}
else if(mat_type === 'LambertBasicMaterial')
{
//new empty array.. could also be written as this.materials = new Array();
this.materials = [];
var mats = this.materials;
var basicMat = new THREE.MeshBasicMaterial( { color: parseInt(gRGBA1, 16) } );
var lambertMat = new THREE.MeshLambertMaterial( { color: parseInt(gRGBA2, 16), opacity: opacity, wireframe: wire, transparent: transparent } );
mats.push(basicMat);
mats.push(lambertMat);
api_messagebox(mats);
return mats;
}
}
Thank you so much!
Sincerely,
~Mythros
Right, I finally got around to trying it out and it all runs well for me.
To make sure we don't have any differences in environments take a look at the fiddle I made and let me know if it works for you as expected or if there's any other problems you need help with:
JSFiddle of original code
Small changes:
commented out the
api_messagebox(mats)
as it's undefined.
added lots of log statements so check out the web console.
Edit
I fixed the color problem by using THree.js' Color object as follows:
var color = new THREE.Color("rgb(0,0,255)");
But you may be doing this somewhere as the GET_RGBA function you are calling seems to be missing from the code you gave me.
As to making it wiremesh, I checked the Lambert object and it definitely had wiremesh = 1 set.
Make sure that the wire var you're passing is actually set to true, I set it explicitly in this updated fiddle

Categories

Resources