Limiting the Value of an input in JavaScript function - javascript

I'm creating the following web app for my employer:
https://jsfiddle.net/kupe2rLL/3/
How it Works: The Missed Opportunity and Engage Results fields populate dynamically as users enter information in the Company Info section.
The Problem: I need to program the app so that the Years in Business input takes no value less than 1 and no value greater than three when calculating the jobsRecovered variable and RevenueYear variable only.
<input type="text" id="yearsOpen" name="yearsOpen" class="form-control" onchange="calculateAll()" required>
var jobsRecovered = (averageJobs * 50) * recovery * yearsOpen;
var revenueYear = jobsRecovered * jobValue;
Preferably, I need the Years in Business input field to accept any value from 0 to infinity on the form input but then change the value of that variable to a minimum of 1 and maximum of 3 when making calculations for the jobsRecovered variable and RevenueYear only. I'd like to implement this solution using a JavaScript function if possible but I am open to alternate solutions.
I researched and implemented the following solution but unfortunately this only limits the min - max range of input on the form itself:
input.addEventListener('change', function(e) {
var num = parseInt(this.value, 10),
min = 1,
max = 3;
if (isNaN(num)) {
this.value = "";
return;
}
this.value = Math.max(num, min);
this.value = Math.min(num, max);
});
Any assistance would be appreciated. (Note: My experience with programming is Beginner level.)

To limit the range of the variable value, you can pass it through if-else statements, or a ternary operation which act like a filter for your values.
e.g.
if (yearsOpen <= 3) ? (if (yearsOpen < 1) ? (yearsOpen = 1) : (yearsOpen = yearsOpen)) : (yearsOpen = 3);
smaller statement if (n <= 3) ? (if (n < 1) ? (n = 1) : (n = n)) : (n = 3);
If-else format:
if (yearsOpen <= 3) {
if (yearsOpen < 1) {
yearsOpen = 1;
} else {
yearsOpen = yearsOpen;
}
} else {
yearsOpen = 3;
}
Hope that makes sense.

Related

Add a number from right to left in the decimal value using javascript

I have an input field where by default I will have $0.00.
when I enter a number, say 1, the input should show $0.01,
again if I enter 2, the input should show $0.12
simultaneously if I press 3, 4, 5, the final output should be $123.45.
Now, If I click delete, it should remove 5, so output will be $123.4
again if I click delete it should remove 4, so output will be $123
If I add a number 2 again here, it should show, $123.2
Is it possible? I am stuck at the last 3 steps.
I have this so far,
let previousTip = 0;
const addingFunction = (value) => {
if(Number(value) <= Number(previousTip)) return Number(value).toFixed(2);
const addNumberRightToLeft = (baseValue, updatedValue) => ((baseValue * 10) + (updatedValue / 100)).toFixed(2);
previousTip = addNumberRightToLeft((Number(previousTip) || 0), value.length > 1 ? value.slice(-1) : value);
return previousTip;
}
my onClick event has
const tipString = addingFunction(e?.target?.value?.trim()?.replace(/[^\d.]/g, '') || '');
Any help will be really appreciated
Here are two functions that should do what you need. You can call the correct one depending on which key is pressed on onKeyPressed
I'm currently not able to test this, but the logic is there.
function addValueToNumber(number,value){
count = 0;
while (number%10 != 0){
number *= 10;
count ++;
}
number += value/10;
for (i=0,i<count-1,i++){
number /= 10;
}
}
function remove(number){
count = 0;
while (number%10 != 0){
number *= 10;
count ++;
}
number = number//10;
for (i=0,i<count-1,i++){
number /= 10;
}
}

Quadratic Expression. Bugs

I am a beginner in JavaScript programming and this is my first project. I am trying to find the factors of a quadratic expression using the standard factorization method. I have explained the logic I used in the code as a comment at the beginning of the main JavaScript function and I have also listed the bugs I have detected so far at the end of the code. I depended solely on my logic based on previous exercises I have done to write this code, so I am hoping to learn a lot from your corrections. I don't know where the bugs are coming from in the code. I would be very grateful if you can help me figure out any. Thank you.
<!DOCTYPE html>
<html>
<head>
<title>Factorization of Quadratic Expression</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div id="box">
<div id="inner">
<p>Quadratic Equation <span id="warning">MUST</span> be in this format
<span id="format">ax<sup>2</sup> + bx + c</span></p>
<p>Use the caret symbol (<span id="caret">^</span>) for exponent, e.g x^2</p>
<input type="text" placeholder="Enter quadratic equation" id="equation" required/><br/>
<br/>
<button id="solve">Answer</button>
<p id="solution"></p>
</div>
</div>
<script type="text/javascript">
// get button and paragraph to display solution
let solution = document.getElementById('solution');
let solve = document.getElementById('solve');
// solve quadratic equation
solve.onclick = function() {
/* This is the main function of the code that finds the factors a quadratic expression.
I assume you already have an understanding of quadratic expressions but I will
explain
the logic I used in the code. Assuming you have a quadratic expression f(x),
f(x) = x^2 - 4x + 4
I first multiplied the coefficient of x^2 which is +1 in this case with the constant
which
is +4. Then I find two numbers whose product gives the value of the constant +4 and
whose
sum gives the value of the coefficient of x which is -4. The numbers are -2 and -2.
Then I substitute the numbers with the value of the coefficient of x adding the
literal.
f(x) = x^2 - 2x - 2x + 4
Next is grouping the first two quadratic coefficients and the last two using
parentheses.
f(x) = (x^2 - 2x) - (2x - 4)
The arithmetic symbol of the constant changes because once you expand it will give
you the former expression.
Next is to finding the greatest common divisors of both groups and simplify.
f(x) = x(x - 2) - 2(x - 2)
Next is getting the common factors.
f(x) = (x - 2)(x - 2) // Final answer
Last line of code outputs the answer and it is the biggest challenge I am having
because it seems I can only display a specific arithmetic symbol '+' (I chose to use
this because I wrote the code using an all positive quadritic expression) in this
case though it varies depending on the quadratic expression, like the one I used in
this comment. */
// get expression from input
let equation = document.getElementById('equation').value;
// validate expression (Only did this for fun and to get the feel of a real-world
project)
// if input was an empty string
if(equation === '') {
solution.innerHTML = 'Error: No expression found! Please fill out the input field';
}
// if a symbol is missing or is there is none
else if((equation.match(/(\+|\-)/g) === null) || (equation.match(/(\+|\-)/g).length < 2))
{
solution.innerHTML = 'Error: Missing symbol in expression';
}
// if the expression is not in the specified format
else if((equation.match(/\s/g).length < 2) || (equation.match(/\s/g).length > 2)) {
solution.innerHTML = 'Error: Missing or excess whitespace character in expression';
}
// if the exponent of x is not 2
else if(equation[equation.indexOf('^') + 1] !== 2) {
solution.innerHTML = 'Error: Exponent of x must be equal to 2';
}
// none of these validations work by the way not sure why
// get coefficient of x^2, x and the constant in the equation from input
array = equation.trim().split(''),
sign1 = array.indexOf('+'),
sign2 = array.lastIndexOf('+'),
getCoefficient_x2 = array.slice(0, array.indexOf(sign1 !== -1 ? '+' : '-') +
2).join(''),
getCoefficient_x = array.slice(array.indexOf(sign1 !== -1 ? '+' : '-') + 2,
array.lastIndexOf('+') - 1).join(''),
getConstant = array.slice(array.lastIndexOf(sign2 !== -1? '+' : '-') + 2).join(''),
cox2 = parseInt(getCoefficient_x2) || 1,
cox = parseInt(getCoefficient_x) || 1,
c = parseInt(getConstant);
// solving quadratic equation
let product = cox2 * c,
sum = cox,
factors = getFactors(product),
sum_product = [],
_gcd = 0,
gcd_ = 0,
cfactor = [];
// get factors whose product is equal to the constant and whose sum is equal to
coefficient of x
for(let i = 0; i < factors.length; i++) {
for(let j = 0; j < factors.length; j++) {
if((factors[i] * factors[j] === product) && (factors[i] + factors[j] === sum)) {
sum_product = [factors[j], factors[i]];
}
}
}
// grouping
// get greatest common divisor of both groups
_gcd = gcd(cox2, sum_product[0]);
gcd_ = gcd(sum_product[1], c);
// finding the common factors of the expression
/* since the computer never makes a mistake I will only factor the first grouping as this
will determine the other. */
cfactor.push(cox2 / _gcd, sum_product[0] / _gcd);
// expression of factorization is given as:
solution.innerHTML = `(${_gcd > 1 ? _gcd : ''}x + ${gcd_})\
(${cfactor[0] > 1 ? cfactor[0] : ''}x + ${cfactor[1]})`;
}
// function to get all negative and positive factors of a number
function getFactors(number) {
var factors = [],
i = 0;
if(number === undefined) number = 0;
for(i = -number; i <= number; i++) {
if(number % i === 0) factors.push(i);
}
return factors;
}
// function to get the greatest common divisor of two numbers
function gcd(num1, num2) {
var numFac = [], gcd, maxNum = Math.max(num1, num2);
for(let n = 1; n <= maxNum; n++) {
if(num1 % n == 0 && num2 % n == 0) {
numFac.push(n);
}
}
return Math.max(...numFac);
}
// Bugs
/* (1) Outputs an unexpected value if the coefficient of x is greater than the constant.
(2) Outputs an unexpected value if the expression uses a negative number.
(3) Outputs an unexpected value if coefficient of x and the constant have no common
factors to determine the the sum and product respectively.
(4) None of the validation codes works.
(5) I am not sure how I can vary the signs of the symbol depending on the give expression.
*/
</script>
</body>
</html>
About the 4th bug: Your validations are working, the inner content of solution is being modified, but your final answer is overwriting it. You could add a boolean variable valid = false if one of your validations returns an error, and before changing the innerHTML of solution for the final answer, check if valid = true, if it is not, don't print your final answer.
Like this:
var valid = true;
if (equation === '') {
solution.innerHTML = 'Error: No expression found! Please fill out the input field';
valid = false;
}
// if a symbol is missing or is there is none
else if ((equation.match(/(\+|\-)/g) === null) || (equation.match(/(\+|\-)/g).length < 2)) {
solution.innerHTML = 'Error: Missing symbol in expression';
valid = false;
}
// if the expression is not in the specified format
else if ((equation.match(/\s/g).length < 2) || (equation.match(/\s/g).length > 2)) {
solution.innerHTML = 'Error: Missing or excess whitespace character in expression';
valid = false;
}
// if the exponent of x is not 2
else if (equation[equation.indexOf('^') + 1] !== 2) {
solution.innerHTML = 'Error: Exponent of x must be equal to 2';
valid = false;
}
And in your final answer:
if (valid) {
solution.innerHTML = `(${_gcd > 1 ? _gcd : ''}x + ${gcd_})\
(${cfactor[0] > 1 ? cfactor[0] : ''}x + ${cfactor[1]})`;
}
Thank very much. I understand. I'm enlightened, it slipped my mind that the code
will continue to the next line even if one of the if statements is true. I might have thought I was returning the error message. Thanks again.

Javascript Time Complexity Analysis

Hi there I have been researching and trying to learn how to check for the time complexity of certain algorithms. I've seen this video which was very helpful.
That being said I wondered off and started trying to work out the Worsts Case and an average case of certain algorithms.
1
I believe in the following snippet it is O(n) since to ind the value for sin we have to loop the entire array.
function mySin(x, iterNum) {
var mxx = -x*x;
var sin = 1;
var n = 0;
var term = 1;
for (var i = 1; i <= 2*iterNum; i++) {
n = n + 2;
term = term * mxx / ( n*(n+1) );
sin = sin + term
}
sin = x*sin;
console.log(sin + " = my function.");
console.log(Math.sin(x) + " math.sin");
}
Thanks again
2
function calculateFibonacciSum (num) {
if(cachedNumbers[num]) {
return cachedNumbers[num];
}
if(('number' === typeof num) && num <= 0) {
throw new Error ('Fibonnci series starts with 0. Please, enter any interget greater than or equal to 0');
}
else if(('number' === typeof num) && num === 0) {
return 0;
}
else if(('number' === typeof num) && (num === 1 || num === 2)) {
return 1;
}
else {
var value = calculateFibonacciSum(num-1) + calculateFibonacciSum(num-2);
cachedNumbers[num] = value;
return value;
}
}
While for this one I think it is also O(n) since in the first if/else statement the tc is O(1) since its contestant whilst the final else statement we must loop all the numbers and if the number is not calculated then call the function again (aka recurssion).
TIA
Both of these seem correct to me. Here's a bit more explanation:
1.
This is in fact O(n), as there are n iterations of the loop, the rest constant time; and n is proportional to iterNum
2.
This one is also linear time, but only since you cache the results of previous calculations. Otherwise it would be O(2n).
It is linear time since it essentially runs a loop down to the base cases (0 and 1). In fact, you could re-write this one using a loop instead of recursion.

Variables occasionally don't generate: max call stack size issue

Error detailed towards bottom of post, but before getting to that, I'll give some background info. I have the following script, which generates:
1) TWO DIFFERENT NUMBERS BETWEEN 2 & 20
var GenerateRandomNumber1to20No1 = GenerateRandomNumber1to20No1();
$('.GenerateRandomNumber1to20No1').html(GenerateRandomNumber1to20No1);
function GenerateRandomNumber1to20No2() {
var min = 2, max = 20;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20No1) ? random: GenerateRandomNumber1to20No2();
}
var GenerateRandomNumber1to20No2 = GenerateRandomNumber1to20No2();
$('.GenerateRandomNumber1to20No2').html(GenerateRandomNumber1to20No2);
function GenerateRandomNumber1to20No3() {
var min = 2, max = 20;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20No1 && random!==GenerateRandomNumber1to20No2) ? random: GenerateRandomNumber1to20No3();
}
2) TWO DIFFERENT NUMBERS LESS THAN THE PREVIOUS 2 NUMBERS
function GenerateRandomNumber1to20lessthanNo1() {
var min = 2, max = GenerateRandomNumber1to20No1-1;
var random = Math.floor(Math.random() * (max - min + 1)) + 1;
return random;
}
var GenerateRandomNumber1to20lessthanNo1= GenerateRandomNumber1to20lessthanNo1();
$('.GenerateRandomNumber1to20lessthanNo1').html(GenerateRandomNumber1to20lessthanNo1);
function GenerateRandomNumber1to20lessthanNo2() {
var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20lessthanNo1) ? random: GenerateRandomNumber1to20lessthanNo2();
}
var GenerateRandomNumber1to20lessthanNo2 = GenerateRandomNumber1to20lessthanNo2();
$('.GenerateRandomNumber1to20lessthanNo2').html(GenerateRandomNumber1to20lessthanNo2);
3) 2 DIFFERENT PRIME NUMBERS
function PrimeNumber1() {
var PrimeNumber1= ['3', '5', '7', '11'];
var PrimeNumber1random= PrimeNumber1[Math.floor(Math.random() * PrimeNumber1.length)];
return PrimeNumber1random;
}
var PrimeNumber1replacer= PrimeNumber1();
$('.PrimeNumber1replacer').html(PrimeNumber1replacer);
function PrimeNumber2() {
var PrimeNumber2= ['3', '5', '7', '11'];
var PrimeNumber2random= PrimeNumber2[Math.floor(Math.random() * PrimeNumber2.length)];
return (PrimeNumber2random !== PrimeNumber1replacer) ? PrimeNumber2random: PrimeNumber2();
}
var PrimeNumber2replacer= PrimeNumber2();
$('.PrimeNumber2replacer').html(PrimeNumber2replacer);
I USE THESE VARIABLES TO REPLACE ELEMENTS WITH CORRESPONDING CLASSES WITH THE VALUES OF THE RESPECTIVE VARIABLES
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20lessthanNo1"></span>
<span class = "GenerateRandomNumber1to20lessthanNo2"></span>
<span class = "PrimeNumber1replacer"></span>
<span class = "PrimeNumber2replacer"></span>
Sometimes, the code works fine: the variables generate and the elements are replaced with those variables. Other times, the variables don't populate and I get one of the two following errors:
Uncaught RangeError: Maximum call stack size exceeded
at GenerateRandomNumber1to20lessthanNo2 *[or No1]*
OR
Uncaught TypeError: PrimeNumber2 *[or 1]* is not a function
at PrimeNumber2
I tried to do some research on Stackoverflow and it seems it might be an issue with recursion, but I have no idea how to fix this issue. If anyone has any advice, I would appreciate it.
Thank you!
You get a stack overflow because almost none of the JS engines are ES6 compliant yet so even though you use tail recursion you blow the stack. The best thing right now is to rewrite it into a loop that does the same until you have succeded.
function generateRandomNumber(predicate = v => true) {
const min = 2;
const max = 20;
let random;
do {
random = Math.floor(Math.random() * (max - min + 1)) + 1;
} while (!predicate(random));
return random;
}
// two different numbers
const first1 = generateRandomNumber();
const second1 = generateRandomNumber(v => v !== first1);
// two different number less than previous
const first2 = generateRandomNumber();
const second2 = generateRandomNumber(v => v < first2); // possible infinite loop
// two different prime numbers
function isPrime(n) {
if (n % 2 === 0) return n == 2
const limit = Math.sqrt(n);
for (let i = 3; i <= limit; i += 2) {
if (n % i === 0)
return false;
}
return true;
}
const first3 = generateRandomNumber(isPrime);
const second3 = generateRandomNumber(v => isPrime(v) && v !== first3);
I've left out the code that puts the values onto the DOM since it's not very interesting. I don't name the variables after the function since they share the same namespace and thus after setting the name GenerateRandomNumber1to20No1 the function has been replaced with the value.
Note that i mention the "two different number less than previous" that you might get an infinite loop. There is a 5,5% chance that the first random number is 2. There is no number generated by that same function which is smaller than 2 and thus it will not terminate.

Validating users input between min and max using a function

I'm trying to make a function that asks the user for a number in between whatever number is passed to the functions min and max, eg.(1,10) I can't seem to get it to work though, what am I missing/ doing wrong here?
function getProductChoice(min, max) {
do {
var productIndex = parseInt(prompt('Enter your product choice', '0'));
} while( isNaN(productIndex) || productIndex <= max || productIndex >= min);
getProductChoice(1,6);
};
I'm assuming you want to stop prompting when the given number satisifies the range. However, your current code does the opposite, continuing to run when the productIndex is less than the max or greater than the min. Try switching your max and min in the conditional.
In this example I've also pulled the getProductChoice() function call out of the function, as recursion is not necessary.
function getProductChoice(min, max) {
do {
var productIndex = parseInt(prompt('Enter your product choice', '0'));
} while( isNaN(productIndex) || productIndex <= min || productIndex >= max);
};
getProductChoice(1,6);

Categories