1

Hi all I got a very stupid question which I could not figure out how to solve it.

So basically I am trying to calculate how many percentage of increment/decrement for the expense and income of current from past month.

So let's say I got these data:

Current Month Expense: 10454
Current Month Income:   2233
Last Month Expense:    15
Last Month Income:     1500

To calculate the income:

if(thisMonthtotalIncome < lastMonthtotalIncome){
        incomePercentage = Math.round(thisMonthtotalIncome/lastMonthtotalIncome * 100);
    }else if(thisMonthtotalIncome > lastMonthtotalIncome){
        incomePercentage = Math.round((thisMonthtotalIncome/lastMonthtotalIncome));
    }

To calculate the expense:

if(thisMonthtotalExpense < lastMonthtotalExpense){
        expensePercentage = Math.round(thisMonthtotalExpense/lastMonthtotalExpense * 100);
    }else if(thisMonthtotalExpense > lastMonthtotalExpense){
        expensePercentage = Math.round((thisMonthtotalExpense/lastMonthtotalExpense));
    }

I realized the percentage was somewhat wrong because from the data above, I get the expense increases by 697%. Is there any way or correct way to limit it to be in the range of 0% - 100%?

Also, I think that the formula is wrong as well cause I am so lousy at Maths.

Any suggestions? Thanks in advance!

QWERTY
  • 139
  • 1
  • 8

2 Answers2

1

Use these:

incomePercentage = Math.round(thisMonthtotalIncome/lastMonthtotalIncome * 100);
expensePercentage = Math.round(thisMonthtotalExpense/lastMonthtotalExpense * 100);

Always think percentage as fractions. Close to 1. Only multiply by 100 for fanciness:

Note that you never have to limit them.... never.

%DI=2233/1500=1.48666 (148.66%)

%DE=10454/15=696.9333 (69693.33%)

These are huge, and very bad because you only had \$15 at past month and now you have \$10.454. What did you do with those \$10 bucks you saved the past year?... Very bad. Numbers do not lie.

EDIT:

IF you are obtaining several NaN because you obtained a zero income|expense during the last period, this means, the metric itself is very "spiky" for your process. In this case, you can always make a smoother reference:

HistoricIncome =0.2*HistoricIncome +0.8*lastMonthtotalIncome;
HistoricExpense =0.2*HistoricExpense +0.8*lastMonthtotalExpense;    
incomePercentage = Math.round(thisMonthtotalIncome/HistoricIncome * 100);
expensePercentage = Math.round(thisMonthtotalExpense/HistoricExpense * 100);

which calculates an Historic Income|Expense average, by taking the 80% of the actual last month value, but smoothed by the previous calculated historic value. This is enough smooth for not having a close to zero indicator. This is an "exponential average". Several averaging techniques exist for obtaining an historic moving value to use as reference.

Brethlosze
  • 3,010
  • What exactly are the conditionals doing here? They seem to give the same outcome regardless. Not to mention they're missing the = case. – eyeballfrog May 24 '17 at 05:23
  • Why both of the case using same formula? I thought supposed to be opposite of each other? – QWERTY May 24 '17 at 05:24
  • Is there anyway to limit the range of the percentage from 0 to 100? – QWERTY May 24 '17 at 05:34
  • Never limit those. You cannot force numbers when they are bad.... You can play with the data and create some smooth trends for hiding these effects... which most people, accountants, managers, and most finantial people can do, sometimes... :) – Brethlosze May 24 '17 at 05:36
  • Then you take percentages based on the trends, hence you never will have a percentage too far from the 100% – Brethlosze May 24 '17 at 05:37
  • I see thanks so much for the helps! – QWERTY May 24 '17 at 05:39
  • DO you want to be more confused about percentages? you can take percentages of percentages :). Forget that now.. – Brethlosze May 24 '17 at 05:40
  • @hyprfrcb Hey let's say one of the number is 0, I am getting NaN. Just wondering if there is any way to resolve this? – QWERTY Aug 27 '17 at 01:31
  • Yes. If your last month you received zero, and this month anything, your gain|loss is infinite!. Which whatever, means your business is going very bad, or at least, not as smooth as expected. Again, the numbers are not the problem in here, but the process itself. As you could realize, this "differential" metric would be too disperse, and you should use that only when the process is more or less stable around a point, such that you never obtain a zero loss|profit scenario. Here you cannot fix the zero and put i.e. 1e-5. The best in this case is report a "blank" figure for the period. – Brethlosze Aug 28 '17 at 19:21
  • Check the edit. – Brethlosze Aug 28 '17 at 19:31
1

Your algorithm is wrong. At one place you are multiplying with 100, while in the other case you aren't. Multiplying with 100 gives percentage (Per-cent, or per hundred), while not multiplying with 100 just gives you the fraction.

Let me explain how it works:

Say, you have a quantity Q and its initial and final values are Qin and Qfi respectively. Now, to check whether there is an increase or a decrease, you take the ratio, Q(final) / Q(initial), that is, Qfi/Qin.

If this ratio is > 1, then Qfi > Qin, so there is an increase. While, if it is < 1, there is a decrease. To calculate, how much there is an increase or decrease, you subtract this ratio from 1.

So say, Qfi/Qin=0.6. This means, Qfi = 0.6 * Qin. So, Qfi is 0.6 times the Qin. Multiplying 0.6 by 100, we get 60%, which means, it is just 60% of the initial quantity (or we can say it is 40% less). The notion of it being 40% less is captured by the following:

1 - 0.6 = 0.4

This, says that the final quantity (Qfi which is exactly 0.6 * Qin) is 0.4 * Qin less than the value Qin. And multiplying 0.4 with 100, you get 40%, which means Qfi is 40% less than Qin.

Now, coming to your problem, make sure that you multiply by 100 in both the conditions, so that you get a percentage output in each case.

if(thisMonthtotalExpense < lastMonthtotalExpense){
        expensePercentage = 
        Math.round( (thisMonthtotalExpense/lastMonthtotalExpense) * 100);
}else if(thisMonthtotalExpense > lastMonthtotalExpense){
        expensePercentage = 
        Math.round( (thisMonthtotalExpense/lastMonthtotalExpense) * 100);
}

In both the cases, you'll get the expense percentage, with respect to the last month expense. And since, now your formula takes into account the 100 factor, you will get 69700% instead of 697%.

Hope this helps.

  • Is there anyway to limit the percentage in the range of 0 to 100? – QWERTY May 24 '17 at 05:32
  • Definitely not.

    Because your scale is fixed. If something measures 15 and something measures 10454 in the same scale, then of course, 10454 is roughly 697 times 15. There is no way, you could represent 10454 as a multiple of 15 within 0-100. (because, the maximum you could get is 15 * 100 = 1500, much less than 10454).

    Clears your doubt?

    – Naveen Venkat May 24 '17 at 05:52
  • Update: I just realized, you can convert any number into a corresponding number between 0 to 1 using the Sigmoid Function.

    1 / (1 + e^(-x))

    For each real x, you'll get a unique number between 0 and 1. Multiply this with 100, you get a number between 0 and 100.

    Caveat: Keep in mind that, this doesn't intuitively represent any percentage. Sigmoid function is not a linear function (https://en.wikipedia.org/wiki/Sigmoid_function).

    – Naveen Venkat Jun 05 '17 at 07:36
  • hey may I know why for both cases, they are using the same formula? Isnt that supposed to be opposite of each other? – QWERTY Aug 27 '17 at 01:27