views:

180

answers:

4

Hi I would like to start by saying I'd greatly appreciate anyones help on this. I have built a small caculator to calculate the amount a consumer can save annually on energy by installing a ground heat pump or solar panels.

As far as I can tell the mathematical formulas are correct and my client verified this yesterday when I showed him the code. Two problems. The first is that the calculator is outputting ridiculously large numbers for the first result. The second problem is that the solar result is only working when there are no zeros in the fields.

Are there some quirks as to how one would write mathematical formulas in JS or jQuery?

Any help greatly appreciated. Here is the link - http://www.olliemccarthy.com/test/johncmurphy/?page_id=249

And here is the code for the entire function -

$jq(document).ready(function(){ 

// Energy Bill Saver 

// Declare Variables 

var A = "";  // Input for Oil
var B = "";  // Input for Storage Heater
var C = "";  // Input for Natural Gas
var D = "";  // Input for LPG
var E = "";  // Input for Coal 
var F = "";  // Input for Wood Pellets
var G = "";  // Input for Number of Occupants 
var J = "";  
var K = "";
var H = "";
var I = "";

// Declare Constants 

var a = "0.0816"; // Rate for Oil
var b = "0.0963"; // Rate for NightRate
var c = "0.0558"; // Rate for Gas
var d = "0.1579";  // Rate for LPG
var e = "0.121";  // Rate for Coal
var f = "0.0828";  // Rate for Pellets
var g = "0.02675";  // Rate for Heat Pump

var x = "1226.4"; 


// Splittin up I to avoid error 

var S1 = ""; // Splitting up the calcuation for I
var S2 = ""; // Splitting up the calcuation for I
var S3 = ""; // Splitting up the calcuation for I
var S4 = ""; // Splitting up the calcuation for I
var S5 = ""; // Splitting up the calcuation for I
var S6 = ""; // Splitting up the calcuation for I



// Calculate H (Ground Sourced Heat Pump)

$jq(".es-calculate").click(function(){


    $jq(".es-result-wrap").slideDown(300);


    A = $jq("input.es-oil").val();
    B = $jq("input.es-storage").val();
    C = $jq("input.es-gas").val();
    D = $jq("input.es-lpg").val();
    E = $jq("input.es-coal").val();
    F = $jq("input.es-pellets").val();
    G = $jq("input.es-occupants").val();


    J = ( A / a ) + ( B / b ) + ( C / c ) + ( D / d ) + ( E / e ) + ( F / f ) ;

    H = A + B + C + D + E + F - ( J * g ) ;

    K = ( G * x ) ;


    if ( A !== "0" ) { S1 = ( ( ( A / a ) / J ) * K * a ) ; }
    else { S1 = "0" ; }

    if ( B !== "0" ) { S2 = ( ( ( B / b ) / J ) * K * b ) ; }
    else { S2 = "0" ; }

    if ( C !== "0" ) { S3 = ( ( ( C / c ) / J ) * K * c ) ; }
    else { S3 = "0" ; }

    if ( D !== "0" ) { S4 = ( ( ( D / d ) / J ) * K * d ) ; }
    else { S4 = "0" ; }

    if ( E !== "0" ) { S5 = ( ( ( E / e ) / J ) * K * e ) ; }
    else { S5 = "0" ; }

    if ( F !== "0" ) { S6 = ( ( ( F / f ) / J ) * K * f ) ; }
    else { S6 = "0" ; }


    I = S1 + S2 + S3 + S4 + S5 + S6 ;


    if(!isNaN(H)) {$jq("span.es-result-span-h").text(H.toFixed(2));}
    else{$jq("span.es-result-span-h").text('Error: Please enter numerals only');}

    if(!isNaN(I)) {$jq("span.es-result-span-i").text(I.toFixed(2));}
    else{$jq("span.es-result-span-i").text('Error: Please enter numerals only');}

    });

});
+7  A: 
  • The constants are declared as strings. They should be of type number(float);

var a = 0.0816;

  • When doing math operations on string (user input), convert them to float using the function parseFloat;

    A = parseFloat( $jq("input.es-oil").val() );

vsr
+1  A: 

Try wrapping your code inside parseFloat and/or parseInt where appropriate. This section of code is a good candidate:

A = parseFloat( $jq("input.es-oil").val() );     // use parseInt if you expect an integer here
B = parseFloat( $jq("input.es-storage").val() ); // ditto for following lines
C = parseFloat( $jq("input.es-gas").val() );
D = parseFloat( $jq("input.es-lpg").val() );
E = parseFloat( $jq("input.es-coal").val() );
F = parseFloat( $jq("input.es-pellets").val() );
G = parseFloat( $jq("input.es-occupants").val() );

Edit ----

I now see all of your numbers are declared as strings. Don't do that!

Salman A
+1  A: 

Try this, and please to pay attention to the changes I have made

var A; // Input for Oil
var B; // Input for Storage Heater
var C; // Input for Natural Gas
var D; // Input for LPG
var E; // Input for Coal 
var F; // Input for Wood Pellets
var G; // Input for Number of Occupants 
var J;
var K;
var H;
var I;

// Declare Constants 
var a = 0.0816; // Rate for Oil
var b = 0.0963; // Rate for NightRate
var c = 0.0558; // Rate for Gas
var d = 0.1579; // Rate for LPG
var e = 0.121; // Rate for Coal
var f = 0.0828; // Rate for Pellets
var g = 0.02675; // Rate for Heat Pump
var x = 1226.4;

// Splittin up I to avoid error 
var S1; // Splitting up the calcuation for I
var S2; // Splitting up the calcuation for I
var S3; // Splitting up the calcuation for I
var S4; // Splitting up the calcuation for I
var S5; // Splitting up the calcuation for I
var S6; // Splitting up the calcuation for I
// Calculate H (Ground Sourced Heat Pump)
$jq(".es-calculate").click(function(){
    $jq(".es-result-wrap").slideDown(300);

    A = parseInt($jq("input.es-oil").val(), 10);
    B = parseInt($jq("input.es-storage").val(), 10);
    C = parseInt($jq("input.es-gas").val(), 10);
    D = parseInt($jq("input.es-lpg").val(), 10);
    E = parseInt($jq("input.es-coal").val(), 10);
    F = parseInt($jq("input.es-pellets").val(), 10);
    G = parseInt($jq("input.es-occupants").val(), 10);

    J = (A / a) + (B / b) + (C / c) + (D / d) + (E / e) + (F / f);
    H = A + B + C + D + E + F - (J * g);
    K = (G * x);

    S1 = A !== 0 ? (((A / a) / J) * K * a) : 0;
    S2 = B !== 0 ? (((B / b) / J) * K * b) : 0;
    S3 = C !== 0 ? (((C / c) / J) * K * c) : 0;
    S4 = D !== 0 ? (((D / d) / J) * K * d) : 0;
    S5 = E !== 0 ? (((E / e) / J) * K * e) : 0;
    S6 = F !== 0 ? (((F / f) / J) * K * f) : 0;
    I = S1 + S2 + S3 + S4 + S5 + S6;

    $jq("span.es-result-span-h").text(H.toFixed(2));
    $jq("span.es-result-span-i").text(I.toFixed(2));
});

None of this is tested - but if the math is correct as you say, then this should work too. About non-numeric values being inputted; you should apply some kind of filter on the keypress event to only allow numericals.

Sean Kinsey
Your conditionals are backwards on the `S1` - `S6`, please fix so I can +1 :) also they can be simplified over the original, e.g. `(((A / a) / J) * K * a)` can be `((A / J) * K)`.
Nick Craver
Fixed the ternaries. you cannot simplify as you said, as you completely removed the constants from the equation.
Sean Kinsey
@Sean - If it's 0 in the dividend the equation 0's out anyway, you can simplify it. Also dividing and multiplying by any term *can* be removed, since it's equal to `* 1`.
Nick Craver
I didn't look to closely at the equations to be honest, but I see now that they are both divided and multiplied with, so no harm in removing them.
Sean Kinsey
+3  A: 

I would simplify all this down with named variables and objects that make sense, untested but should work:

// Declare Constants 
var rates = { 
  Oil:           0.0816, // Rate for Oil
  StorageHeater: 0.0963, // Rate for NightRate
  NaturalGas:    0.0558, // Rate for Gas
  LPG:           0.1579, // Rate for LPG
  Coal:          0.121,  // Rate for Coal
  WoodPellets:   0.0828, // Rate for Pellets
  HeatPump:      0.02675 // Rate for Heat Pump
};
var x = 1226.4;

// Calculate H (Ground Sourced Heat Pump)
$jq(".es-calculate").click(function(){
    $jq(".es-result-wrap").slideDown(300);
    var normalizedTotal = 0;
    var total = 0;

    $jq.each({
      Oil:           $jq('input.es-oil').val(),
      StorageHeater: $jq('input.es-storage').val(),
      NaturalGas:    $jq('input.es-gas').val(),
      LPG:           $jq('input.es-lpg').val(),
      Coal:          $jq('input.es-coal').val(),
      WoodPellets:   $jq('input.es-pellets').val()
    }, function(key, value) {
      // make sure the value is a float and not a string:
      value = parseFloat(value); 

      // calculate our two totals
      normalizedTotal += value / rates[key];
      total += value;
    });

    var Occupants = parseInt($jq("input.es-occupants").val(), 10);

    var H = total - (normalizedTotal * rates.HeatPump);
    var I = total / normalizedTotal * Occupants * x;

    $jq("span.es-result-span-h").text(H.toFixed(2));
    $jq("span.es-result-span-i").text(I.toFixed(2));
});

I changed the math around a bit as well, since the 0 on the dividend cancels out the other pieces in most places and there was a bit extra in some formulas that cancelled out. Also, the above uses an object to store rates in a bit cleaner way using a convention. Making this wiki so whomever can improve further.

Edit: Turned the calculation of normalizedTotal and total into a simpler $.each()

Nick Craver