javascript "less than" if statement failing - javascript

Here is my function:
function reCalculate(i) {
document.getElementById("Q" + i).value = document.getElementById("C" + i).value - document.getElementById("QA" + i).value;
if (document.getElementById("Q" + i).value < 0) {
document.getElementById("Q" + i).value = 0;
}
if (document.getElementById("Q" + i).value < document.getElementById("E" + i).value && document.getElementById("Q" + i).value != 0) {
alert(document.getElementById("Q" + i).value + " is less than " + document.getElementById("E" + i).value + "?");
document.getElementById("Q" + i).value = document.getElementById("E" + i).value;
}
document.getElementById("Q" + i).value = Math.ceil(document.getElementById("Q" + i).value);
}
It checks Q, if it's less than 0, it makes it 0. Then, if it's not 0, but it's less than E, it makes it E. For some reason this function works UNLESS Q is a double digit number.
For example, if Q is 7 and E is 2, then it will leave Q at 7. However, if Q is 10 and E is 2, for some reason it thinks that 10<2, and it changes Q to 2!
Am I missing something here??

When you pull the .value of an element it returns a string. '10'<'2' will return true.
You can simply do a parseInt/parseFloat on the value, ala
var q = parseInt(document.getElementById("Q"+i).value,10)

Thats because it is considering your Q as a string while comparing.
Try the following instead:
function reCalculate(i){
var Z = document.getElementById, P = parseInt;
var qElem = Z("Q"+i);
var q = P(qElem.value, 10);
var c = P(Z("C"+i).value, 10);
var qa = P(Z("QA"+i).value, 10);
var e = P(Z("E"+i).value, 10);
q = c - qa;
if (q < 0) qElem.value = 0;
if (q < e && q != 0){
alert(q+" is less than "+e+"?");
qElem.value = e;
}
qElem.value = Math.ceil(q);
}

May be you should do a
parseFloat(document.getElementById("Q"+i).value)
to make sure you are comparing numbers

You are comparing strings not numbers. Use the unary + to convert to a number:
if (+document.getElementById("Q" + i).value < +document.getElementById("E" + i).value ...)
You should use variables by the way:
var input_one = document.getElementById("Q" + i).value,
input_two = document.getElementById("E" + i).value;
if (+input_one < +input_two) {
}

Related

How to update innerHTML in very long running loop javascript

var star = 4125;
var moon = 2946;
var max = 50;
//-----------------------------------------------------------------------------------
var a,b,c,d,e,f;
var starx,moonx,tokenx;
var token = 0;
var txt;
for (a = max ; a >= 0 ; a--)
{
for (b = 0 ; b <= max ; b++)
{
for (c = 0 ; c <= max ; c++)
{
for (d = 0 ; d <= max ; d++)
{
for (e = 0 ; e <= max ; e++)
{
for (f = 0 ; f <= max ; f++)
{
starx = 75 * (a + b + c + d + e + f);
moonx = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);
if (starx <= star && moonx <= moon && tokenx >= token)
{
token = tokenx;
txt = tokenx + ',' + starx + ',' + moonx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + '<br>\n';
document.getElementById("txt").innerHTML += txt;
console.log(txt);
}
}
}
}
}
}
}
Need help. I am very new to javascript. I would like to run those javascript in android. innerHTML don't update until the loop completed. And can't see console log in android too.
If you want to show the output of the loop at each iteration you can use setInterval()
like so:
for(let a = 0; a < 10; a++) {
document.body.innerHTML += "Hello world!" +a +"<br />";
}
document.body.innerHTML += "<br /> Loop but shows output at each iteration: <br />";
let a = 0;
let aLoop = setInterval(function() {
if(a < 10) {
document.body.innerHTML += "Hello world!" +a +"<br />";
a++;
} else {
clearInterval(iLoop);
}
}, 100);
However, this would require you to convert a lot of your code and would get messy. If all you wish to do is see the output on android you can try alert(txt); to see the output instead.
Use generator function* to yield text. DOM element innerHTML could be updated via setInterval timer.
function* cal() {
var star = 4125;
var moon = 2946;
var max = 50;
var a, b, c, d, e, f;
var starx, moonx, tokenx;
var token = 0;
var txt;
for (a = max; a >= 0; a--) {
for (b = 0; b <= max; b++) {
for (c = 0; c <= max; c++) {
for (d = 0; d <= max; d++) {
for (e = 0; e <= max; e++) {
for (f = 0; f <= max; f++) {
starx = 75 * (a + b + c + d + e + f);
moonx = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);
if (starx <= star && moonx <= moon && tokenx >= token) {
token = tokenx;
txt = tokenx + ',' + starx + ',' + moonx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + '<br>\n';
// document.getElementById("txt").innerHTML += txt;
console.log(txt);
yield txt;
}
}
}
}
}
}
}
}
function run() {
gen = cal();
setInterval(()=> document.getElementById("txt").innerHTML +=
gen.next().value, 10);
}
run();
Web workers can do long running task.
See here:
https://www.w3schools.com/html/html5_webworkers.asp
Notes:
Chrome doesn't support web workers when load script from local.
You have to add option Chrome.exe --allow-file-access-from-files
Firefox allow local file.
<!DOCTYPE html>
<html>
<body>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button><br><br>
<pre id="txt">
Hello
</pre>
<script>
var w;
function startWorker()
{
if(typeof(Worker) !== "undefined")
{
if(typeof(w) == "undefined")
{
w = new Worker("StarForge.js");
}
w.onmessage = function(event)
{
document.getElementById("txt").innerHTML += event.data;
};
}
else
{
document.getElementById("txt").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker()
{
w.terminate();
w = undefined;
}
</script>
</body>
</html>
And in the StarForge.js
function gen()
{
var moon = 2946;
var star = 4125;
var max = 50;
var a,b,c,d,e,f;
var moonx,starx,tokenx;
var token = 0;
var txt;
for (a = 0 ; a <= max ; a++)
{
for (b = 0 ; b <= max ; b++)
{
for (c = 0 ; c <= max ; c++)
{
for (d = 0 ; d <= max ; d++)
{
for (e = 0 ; e <= max ; e++)
{
for (f = 0 ; f <= max ; f++)
{
tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);
moonx = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
starx = 75 * (a + b + c + d + e + f);
if (tokenx >= token && moonx <= moon && starx <= star)
{
token = tokenx;
txt = tokenx + ',' + moonx + ',' + starx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f;
postMessage(txt)
console.log(txt);
}
}
}
}
}
}
}
postMessage("--- End ---");
console.log("--- End ---");
}
gen();

Dynamically create RegExps groups to match patterns lower than or greater than a desired value

I've made two JavaScript functions to dynamically create RegExps groups that match numbers lower than or greater than the number that is sent in the parameter. The purpose of these functions is to do something like this or this but dynamically, I need it for an App for building RegExps, this code made a group that match a particular group of numbers, later you could use the returned group to complete your final RegExp.
Here is the function to create a RegExp to find patterns greater than a desired value:
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\\d"));
}
}
a.push("\\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
Example of use:
var regstr = getGreaterUintRegEx(124);
// (12[5-9]|1[3-9]\d|[2-9]\d\d|\d{4,})
var regstr = getGreaterUintRegEx(500);
// (50[1-9]|5[1-9]\d|[6-9]\d\d|\d{4,})
And here is the function to create a RegExp to find patterns lower than a desired value:
//Find lower than numbers
function getLowerUintRegEx(n) {
if (n == 0) return false;
if (n == 1) return "(0)";
if (n > 0 && n < 10) return "[0-" + (n - 1) + "]";
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "0":
a.push(((s.slice(0, t - i) == "1") ? "" : (Number(s.slice(0, t - i)) - 1)) + "9" + (new Array(i)).join("\\d"));
break;
case "1":
a.push("[1-9]" + (new Array(i - 1)).join("\\d"));
break;
default:
a.push(s.slice(0, t - i) + "[0-" + (Number(s.charAt(t - i)) - 1) + "]" + (new Array(i)).join("\\d"));
}
}
if (t - 1 > 1) a.push("\\d{1," + (t - 1) + "}");
a.push("0");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
Example of use:
var regstr = getLowerUintRegEx(498);
// (49[0-7]|4[0-8]\d|[0-3]\d\d|\d{1,2}|0)
var regstr = getLowerUintRegEx(125);
// (12[0-4]|1[0-1]\d|[1-9]\d|\d{1,2}|0)
I want to make these functions more simply and less slow. It takes more than a second with big numbers. Is there any other easier method? Somebody knows a robust algorithm with less steps?
You'll get a big speedup just by removing unnecessary data structures (each call creates several Arrays and a Function, none are needed).
Here's a rewrite of just getGreaterUintRegEx:
function getGreaterUintRegEx(n) {
var nStr = String(n);
var len = nStr.length;
var result = '(';
var ds = '';
var i;
for (i = len - 1; i >= 0; i--) {
switch (nStr.charAt(i)) {
case '9': result += `${+nStr.slice(0, i) + 1}0${ds}|`; break;
case '8': result += `${nStr.slice(0, i)}9${ds}|`; break;
default: result += `${nStr.slice(0, i)}[${+nStr.charAt(i) + 1}-9]${ds}|`;
}
ds += '\\d';
}
return `${result}\\d{${len + 1},})`;
}
I've used ES6 template strings just for readability. They're currently supported across evergreen browsers, but you'll want to swap them for the old '' + '' if you want to support IE11.
This is not the way that I would solve the problem, but you are not looking for a better solution but actually want a review of your code, suggestions and optimisations that give the same functionality as your original (which is working code).
Anyway, below is a suggestion. The code is more readable, I have no intention of testing its performance.
var reduceRight = Function.prototype.call.bind(Array.prototype.reduceRight);
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length - 1;
var a = reduceRight(s, function(acc, v, i) {
var x = s.slice(0, i);
if (v === '9') {
x = Number(x) + 1 + '0';
} else if (v === '8') {
x += '9';
} else {
x += '[' + (Number(v) + 1) + '-9]';
}
acc.push(x + '\\d'.repeat(t - i));
return acc;
}, []);
a.push('\\d{' + (t + 2) + ',}');
return '(' + a.join('|') + ')';
}
//Find greater than numbers: original
function getGreaterUintRegEx1(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\\d"));
}
}
a.push("\\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
var out = document.getElementById('out');
for (var i = 0; i < 100000; i += 1) {
var suggested = getGreaterUintRegEx(i);
var original = getGreaterUintRegEx1(i);
if (suggested !== original) {
var txt = suggested + '!==' + original;
out.textContent = txt;
throw new Error(txt);
}
}
out.textContent = suggested + '\n' + original + '\nSame results';
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.1/es6-shim.js"></script>
<pre id="out"></pre>
way to complicated, your approach. And way to limited.
function getInts(str){
return String(str).match(/[+-]?\d+/g).map(Number);
}
function greaterThan(w){
return function(v){ return v > w }
}
function lowerThan(w){ //
return function(v){ return v < w }
}
getInts(someString).filter( greaterThan(473) )
or the more generic approach:
var is = (function(is){
for(var key in is) is[key] = Function("w", "return function(v){return v " + is[key] + " w}");
return is;
})({
eq: "===",
neq: "!==",
gt: ">",
lt: "<",
gteq: ">=",
lteq: "<="
});
is.typeof = function(w){ return function(v){ return typeof v === w }};
getInts(someString).filter( is.lt(92) );

I am having trouble with a few javascript do while loops

I am writing a code guessing program to test the security of some iPhone passwords (This is not in anyway connected to anything illegal or is used to break into actual iPhones). The do/while loops just end all response once they occur and the last two lines don't print to the console.
print("Hi!");
print("I am a password security tester.");
var tries = 0
var guess1 = 0
var guess2 = 0
var guess3 = 0
var guess4 = 0
var guess = (guess1 * 1000) + (guess2 * 100) + (guess3 * 10) + guess4;
var password1 = (Math.floor(Math.random()*9));
var password2 = (Math.floor(Math.random()*9));
var password3 = (Math.floor(Math.random()*9));
var password4 = (Math.floor(Math.random()*9));
var password = (password1 * 1000) + (password2 * 100) + (password3 * 10) + password4;
print("This is the randomly genorated password: " + password);
print("And now begins the guessing");
do{
guess1 + 1;
tries + 1;
}while (password1 != guess1);
do{
guess2 + 1;
tries + 1;
}while (password2 != guess2);
do{
guess3 + 1;
tries + 1;
}while (password3 != guess3);
do{
guess4 + 1;
tries + 1;
}while (password4 != guess4);
print("Complete in " + tries + " tries");
print("The answer is: " + guess);
Jacob Ewing's answer is correct, but another problem is that guess will still be 0 at the end, because it doesn't automatically update. You'll need to do:
var guess = (guess1 * 1000) + (guess2 * 100) + (guess3 * 10) + guess4;
Before:
print("Complete in " + tries + " tries");
print("The answer is: " + guess);
You need to be using a += operator instead of just +
Saying guess1 + 1 returns the value of guess1 + 1, but does not increment that value directly, so you get an infinite loop.

JavaScript encoding with Special characters

I wanted to write a method to escape special chars like 'ä' to their responding Unicode (e.g. \u00e4).
For some reason JS finds it amusing to not even save the 'ä' internally but use 'üÜ' or some other garble, so when I convert it spits out '\u00c3\u00b6\u00c3\u002013' because it converts these chars instead of 'ä'.
I have tried setting the HTML file's encoding to utf-8 and tried loading the scripts with charset="UTF-8" to no avail. The code doesn't really do anything special but here it is:
String.prototype.replaceWithUtf8 = function() {
var str_newString = '';
var str_procString = this;
for (var i = 0; i < str_procString.length; i++) {
if (str_procString.charCodeAt(i) > 126) {
var hex_uniCode = '\\u00' + str_procString.charCodeAt(i).toString(16);
console.log(hex_uniCode + " (" + str_procString.charAt(i) + ")");
str_newString += hex_uniCode;
} else {
str_newString += str_procString.charAt(i);
}
}
return str_newString;
}
var str_item = "Lärm, Lichter, Lücken, Löcher."
console.log(str_item); // Lärm, Lichter, Lücken, Löcher.
console.log(str_item.replaceWithUtf8()); //L\u00c3\u00a4rm, Lichter, L\u00c3\u00bccken, L\u00c3\u00b6cher.
I have no idea how or why but I just restarted the server again and now it's displaying correctly. To follow up; here's the code for everyone who's interested:
String.prototype.replaceWithUtf8 = function() {
var str_newString = '';
var str_procString = this;
var arr_replace = new Array('/', '"');
var arr_replaceWith = new Array('\\/', '\\"');
for (var i = 0; i < str_procString.length; i++) {
var int_charCode = str_procString.charCodeAt(i);
var cha_charAt = str_procString.charAt(i);
var int_chrIndex = arr_replace.indexOf(cha_charAt);
if (int_chrIndex > -1) {
console.log(arr_replaceWith[int_chrIndex]);
str_newString += arr_replaceWith[int_chrIndex];
} else {
if (int_charCode > 126 && int_charCode < 65536) {
var hex_uniCode = '\\u' + ("000" + int_charCode.toString(16)).substr(-4);
console.log(hex_uniCode + " (" + cha_charAt + ")");
str_newString += hex_uniCode;
} else {
str_newString += cha_charAt;
}
}
}
return str_newString;
}
Use '\\u' + ('000' + str_procString.charCodeAt(i).toString(16) ).stubstr(-4); instead to get the right escape sequences - yours do always start with 00. Also, instead of a for-loop processing your string, .replace() might be faster.
On your question:
console.log("Lärm, Lichter, Lücken, Löcher."); // Lärm, Lichter, Lücken, Löcher.
does not sound as you really sent the file with the right encoding. Might be a server problem, too, if it is correctly saved already.
String.prototype.replaceWithUtf8 = function() {
function r(r) {
for (var t, n, e = "", i = 0; !isNaN(t = r.charCodeAt(i++)); ) n = t.toString(16),
e += 256 > t ? "\\x" + (t > 15 ? "" :"0") + n :"\\u" + ("0000" + n).slice(-4);
return e;
}
var a, c, o, u, s, e = "", i = this, t = [ "/", '"' ], n = [ "\\/", '\\"' ];
for (a = 0; a < i.length; a++) c = i.charCodeAt(a), o = i.charAt(a), u = t.indexOf(o),
u > -1 ? e += n[u] :c > 126 && 65536 > c ? (s = r(o), e += s) :e += o;
return e;
};
prompt("Your escaped string:","Lärm, Lichter, Lücken, Löcher.".replaceWithUtf8());
alert("L\xe4rm, Lichter, L\xfccken, L\xf6cher.");
Unicode encoding only makes every character 6 digits. But for characters above 127 to 256, we can actually make these hexdecimal with less bytes (4 digits per character).

Writing a program to find out the sum of the negative elements and positive elements of the array

My code runs well up until the point it is expected to return the result - it does not add up any of the values entered by the user.
a = (prompt("a:"));
b = (prompt("b:"));
c = (prompt("c:"));
negativeSum = Number(0);
positiveSum = Number(0);
var test = [a, b, c];
for (i = 0; i < test.length; i++) {
if (isNaN(test[i])) {
alert(test[i] + " : incorrect input.");
}
else
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum = Number(test[i]++);
}
else {
alert(test[i] + " : positive.")
positiveSum = Number(test[i]++);
}
}
alert(positiveSum + " : sum of +ve elements");
alert(negativeSum + " : sum of -ve elements");
isn't sum of negatives always less then sum of positives.
if you speaking about absolute diff.
than try
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum += Number(test[i]);
}
else {
alert(test[i] + " : positive.")
positiveSum += Number(test[i]);
}
//after the loop
return Math.abs(negativeSum) > positiveSum;
Several things - no need for Number(0) - just using 0 will do.
The line:
positiveSum = Number(test[i]++);
Simply assigns the value of test[i] + 1 (this is what the post increment ++ operator does) to positiveSum. It doesn't add it up to positiveSum (same is true for negativeSum.
This should work better:
negativeSum = 0;
positiveSum = 0;
var test = [a, b, c];
for (i = 0; i < test.length; i++) {
if (isNaN(test[i])) {
alert(test[i] + " : incorrect input.");
}
else
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum += test[i];
}
else {
alert(test[i] + " : positive.")
positiveSum += test[i];
}
}
In my code the line:
negativeSum += test[i];
Is equivalent to:
negativeSum = negativeSum + test[i];
You're not summing anything, you're incrementing each number you've input. You want positiveSum += (each number).
You should also convert the element to a number before doing the comparison to zero and the rest.

Categories

Resources