Reputation: 1
Essentially what I want to do is have a while loop in my code, add one to a score until it hits a target which I've found can be done quite easily with a basic while loop. However, In my version of this, it will be slightly different, as you will see in the code below.
What I'm doing is having the user input 4 numbers: Target, Promoters, Neutrals, and Detractors.
For every promoter they enter that gives 100 points, neutrals give 0, and detractors are -100. Then a final average is taken which will be compared to the target they entered at first, this is where I want the while loop to come in, I want the loop to automatically tell the user how many promoters they need to achieve the target.
So, in the example of the user having a target of 75, and them having 3 promoters, 2 neutrals, and 1 detractor. This would give them an average of 33.33 (200/6). And, I've manually worked out they would need 10 more promoters for the score to become 75, therefore, hitting the target they assigned.
I've been playing around with loads of different while loops over the last few days and have come up with nothing so that's why I'm turning to you guys, the experts.
The code is below. This is just the final piece of the puzzle for me now to finish this.
Here is my HTML and JavaScript.
/* eslint-env browser */
// eslint.rc
{
"no-unused-vars" [2, {"args": "none"}]
}
"use strict";
$(document).ready(function () {
$('#target, #proNum, #neuNum, #detNum').change(function () {
var target = $('#target').val();
var proNum = $('#proNum').val();
var neuNum = $('#neuNum').val();
var detNum = $('#detNum').val();
console.log("target is equal to " + target);
console.log("promitors is equal to " + proNum);
console.log("neutrals is equal to " + neuNum);
console.log("detractors is equal to " + detNum);
var targetTot = (target*10);
var prosTot = (proNum*100);
var neusTot = (neuNum*0);
var detsTot = (detNum*-100);
console.log("Target is " + targetTot);
var scoresQuant = +proNum + +neuNum + +detNum;
var scoresTot = prosTot+neusTot+detsTot;
var preCurrent = scoresTot/scoresQuant;
var current = Math.round(preCurrent*100)/100;
console.log("scoresQuant is equal to " + scoresQuant);
console.log("scoresTot is equal to " + scoresTot);
console.log("preCurrent is equal to " + preCurrent);
console.log(current);
$('#current').text(current);
var hypPro = 0;
var scoresTotLoop = scoresTot/100;
var targetLoop = target/10;
while (scoresTotLoop/scoresQuant+hypPro<=targetLoop) {
hypPro++;
}
console.log("hypPro is equal to " + hypPro);
$('#prosToTarget').text(hypPro);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>NPS Calculator</title>
<!-- Linking to external sheets -->
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/script.js"></script>
<!-- End of linking to external sheets -->
<!-- Font Imports -->
<link href="https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,700" rel="stylesheet">
<!-- End of font Imports -->
</head>
<body>
<div id ="headers">
<h1>NPS Calcultor</h1>
<h2>This site will help you work out the total number of promoters you need to achieve your target this month.</h2>
</div>
<div id = "calculator">
<div id = "targetNPS">
<table id ="targetTable">
<tr>
<td>
<h2>Target NPS</h2>
</td>
<td>
<input type="text" class="IO" id = "target"/>
</td>
</tr>
</table>
</div>
<div id = "scores">
<table id = "scoresTable">
<tr>
<td>
<h2>Promoters</h2>
</td>
<td>
<h2>Neutrals</h2>
</td>
<td>
<h2>Detractors</h2>
</td>
</tr>
<tr>
<td class = "pros">
<input type="text" class="IO" id = "proNum"/>
</td>
<td class = "neus">
<input type="text" class="IO" id = "neuNum"/>
</td>
<td class = "dets">
<input type="text" class="IO" id = "detNum"/>
</td>
</tr>
</table>
</div>
<div id = "currentNPS">
<table id = "currentTable">
<tr>
<td>
<h2>Current NPS</h2>
</td>
<td>
<h2 class="IO" id = "current">0</h2>
</td>
</tr>
</table>
</div>
<div id = "prosToTargetNPS">
<table id ="prosToTargetTable">
<tr>
<td>
<h2>Promitors to Target</h2>
</td>
<td>
<h2 class="IO" id = "prosToTarget">0</h2>
</td>
</tr>
</table>
</div>
</div>
</body>
</html>
Upvotes: 0
Views: 457
Reputation: 980
as psinaught already stated, the solution would not be a while loop, but an equation. the posted solution is already heading in the right direction - but as far as i can see only works, when pVal and dVal have the same absolute value. another downside is, since your example has the value 0 for neutrals, the neutral value was removed while simplifying his equation. so as soon, as neutrals get a value different then 0, it will not work anymore...
if everything (counts and values) could be generic, the equation would be:
x = ( n * ( target - nVal ) + d * ( target - dVal) ) / ( pVal - target )
additionally you would want to check, if the target does not be greater than pVal, because of the target being an average, it will not be reachable anymore.
here's the link to my working fiddle: http://jsfiddle.net/bq1f02pk/2/ you can adjust all numbers, regardless of being count or values.
what have i done within the js part:
first i bound an 'onChange' event to all input fields, so the function gets executed, everytime you change a number
$("input").on("change", function() {
next, to make the mathematical part work and get rid of the jquery selectors, i extracted all input values into variables:
var target = parseInt($("#target").val());
var proms = parseInt($("#p").val());
var pVal = parseInt($("#pval").val());
var neuts = parseInt($("#n").val());
var nVal = parseInt($("#nval").val());
var dets = parseInt($("#d").val());
var dVal = parseInt($("#dval").val());
following are some checks, for input validity:
if (target == pVal) { // only achievable without n's and d's
return false;
} else if (target > pVal) { //not reachable
return false;
} else if( neuts == 0 && dets == 0){ //no calculation needed
return false;
}
in my fiddle, those three if's also prints description texts to the user, otherwise one if with || would have been sufficient.
now finally, we have the calculation:
var totals = var totals = ( neuts * ( target - nVal ) + dets * ( target - dVal ) ) / ( pVal - target );
var remaining = totals - proms;
and to help the user understand his problem, you can additionally create a long text to explain the results:
$("#result").text("to reach your target of " + target + " you need " + totals + " promoters in total. you already have " + proms + " promoters, so you need " + remaining + " more promoters!");
Upvotes: 0
Reputation: 1
I've managed to solve the problem, by using the idea of treating it as an equation from above. Here is the solution I found, what I did is took the equation posted by @psinaught and assigned the target as y, combined pros as x, neutrals as n, detractors as d, and then solved for y. Which then produces the equation below which I swapped the correct variables into.
var preProsToTarget = ((detNum*target)+(neuNum*target)+(100*detNum))/(-target+100);
var prosToTarget = Math.max(0,preProsToTarget-proNum);
Upvotes: 0
Reputation:
Consider x
for total promotors required (10+3), p
for input promotors (3), n
for input neutrals (2) and d
for input detractors (1).
So, we have following equation-
(100x + 0n - 100d)/(x+n+d) = 75
or, 100(x - d)/(x+n+d) = 75
or, x-d = 0.75(x+n+d)
Or, x-0.75x = 0.75n + 0.75d +d
Or, 0.25x = 0.75n + 1.75d
Or, x = (75/25)n + (175/25)d
-------(1)
Or, x = 3n + 7d
As n
and d
are already there, 2 and 1,
x = 3*2 + 7*1 = 13 and x-p = 13 - 3 = 10 promotors are required.
How do you implement this in code? As you can see in equation (1)
n
by (target/(100-target))
d
by (100+target)/(100-target)
No need of loop. Here it is assumed that target is always achievable by adding promotors only.
Upvotes: 1