I'm trying to write a very simple program to calculate liquid nicotine strengh. Basically it's (strengh / nicStrengh) * amount. And it always comes out as 0.
private void lblCalculate_Click(object sender, EventArgs e)
{
int strengh = Convert.ToInt32(txtBoxDesiredStrengh.Text);
int nicStrengh = Convert.ToInt32(txtBoxNicStrengh.Text);
int amount = Convert.ToInt32(txtBoxAmount.Text);
int result = strengh / nicStrengh * amount;
string resultStr = result.ToString();
label1.Text = resultStr;
}
When you divide integer to integer the result is integer as well; e.g.
5 / 10 == 0 // not 0.5 - integer division
5.0 / 10.0 == 0.5 // floating point division
In your case strengh < amount that's why strengh / amount == 0. If you want result being int (say 3) put it as
int result = strengh * amount / nicStrengh;
if you want double result (i.e. floating point value, say 3.15) let system know that you want floating point arithmetics:
double result = (double)strengh / nicStrengh * amount;
Try this
private void button1_Click(object sender, EventArgs e)
{
int s = int.Parse(textBox1.Text);
int n = int.Parse(textBox2.Text);
int a = int.Parse(textBox3.Text);
int result = (s / n) * a;
label1.Text = result.ToString();
}
or this if result is with comma
private void button1_Click(object sender, EventArgs e)
{
double s = double.Parse(textBox1.Text);
double n = double.Parse(textBox2.Text);
double a = double.Parse(textBox3.Text);
double result = (s / n) * a;
label1.Text = result.ToString();
}
I'm trying to determine whether or not there is data outliers in a list of doubles. Basically if anything is below 10 percent of the limits or above 90 percent. I have the following code working, but it doesn't work properly with negative numbers and I'm not seeing what is wrong. Is there a better way to approach there, or is there something glaring in the code or math?
public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
foreach (double result in results)
{
//detect if any result values are in the low or high regions of the acceptable limits
double deltaAbsolute = (limits.High - limits.Low) < 0 ? (limits.High - limits.Low) * -1 : limits.High - limits.Low;
double absoluteResult = result < 0 ? result * -1 : result;
double lowLimitAbsolute = limits.Low < 0 ? limits.Low * -1 : limits.Low;
double upperThreshold = 0.9 * deltaAbsolute + limits.Low;
double lowerThreshold = 0.1 * deltaAbsolute + limits.Low;
if (absoluteResult >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (absoluteResult <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
}
return false;
}
public class Limits
{
public double High { get; set; }
public double Low { get; set; }
public string Error { get; set; }
}
If the limits are [-10, 0] and a result is -5, with the current code you'll effectively be checking if 5 is in [11, 19], which is not correct.
I suggest to keep the sign of the boundaries increasing/decreasing them by the 1/10-th of the range and then check the original result value against this reduced range:
double deltaAbsolute = Math.Abs(limits.High - limits.Low);
double lowerThreshold = limits.Low + 0.1 * deltaAbsolute;
double upperThreshold = limits.High - 0.1 * deltaAbsolute;
if (result >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (result <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
Why are you recalculating limits IN the loop.
If High > Low then you don't need any of the absolute stuff.
public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
if(limits.High < limits.Low)
{
throw new ArgumentOutOfRangeException();
}
double delta = limits.High - limits.Low;
double upperThreshold = 0.9 * delta + limits.Low;
double lowerThreshold = 0.1 * delta + limits.Low;
foreach (double result in results)
{
//detect if any result values are in the low or high regions of the acceptable limits
if (result >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (result <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
}
return false;
}
I've been doing an app since few days ago but it's wrong and I do not know why.
I've done the same operation in various ways. I've searched here on the blog, but I still get the incorrect result.
I hope you can help me:
I'm calculating the ** Mean and Standard Deviation**. The Mean is OK. The Standard Deviation is wrong. This is my code:
LinkedList<Double> lista = new LinkedList<Double>();
int contador = 0;
private void btnAgregar_Click(object sender, EventArgs e)
{
lista.AddLast(Convert.ToDouble(txtNum.Text));
MessageBox.Show("Se agregó el número: " + txtNum.Text);
contador++;
txtNum.Text = "";
txtNum.Focus();
}
Double media;
Double desviacionE = 0;
Double suma = 0;
private void btnCalcular_Click(object sender, EventArgs e)
{
media = 0;
calculaMedia();
calculaDesviacionE();
}
public void calculaMedia()
{
foreach (var item in lista)
{
String valorItem = item.ToString();
suma = suma + Convert.ToDouble(valorItem);
}
media = suma / contador;
txtMedia.Text = "" + media;
}
public void calculaDesviacionE()
{
Double average = lista.Average();
Double sum = 0;
foreach (var item in lista)
{
sum += ((Convert.ToDouble(item.ToString()))*(Convert.ToDouble(item.ToString())));
}
Double sumProm = sum / lista.Count();
Double desvE = Math.Sqrt(sumProm-(average*average));
txtDesv.Text = "" + desvE;
}
I hope You can help me!
Thank You
Following the rules for standard deviation found at http://en.wikipedia.org/wiki/Standard_deviation
LinkedList<Double> list = new LinkedList<Double>();
double sumOfSquares = 0;
double deviation;
double delta;
list.AddLast(2);
list.AddLast(4);
list.AddLast(4);
list.AddLast(4);
list.AddLast(5);
list.AddLast(5);
list.AddLast(7);
list.AddLast(9);
double average = list.Average();
Console.WriteLine("Average: " + average);
foreach (double item in list)
{
delta = Math.Abs(item - average);
sumOfSquares += (delta * delta);
}
Console.WriteLine("Sum of Squares: " + sumOfSquares);
deviation = Math.Sqrt(sumOfSquares / list.Count());
Console.WriteLine("Standard Deviation: " + deviation); //Final result is 2.0
You need to subtract the average before squaring.
// Population Standard Deviation
public void populationStandardDev()
{
Double average = lista.Average();
Double sum = 0;
foreach (var item in lista)
{
Double difference = item - average;
sum += difference*difference;
}
Double sumProd = sum / lista.Count(); // divide by n
Double desvE = Math.Sqrt(sumProd);
}
// Standard deviation
public void standardDev()
{
Double average = lista.Average();
Double sum = 0;
foreach (var item in lista)
{
Double difference = item - average;
sum += difference*difference;
}
Double sumProd = sum / (lista.Count()-1); // divide by n-1
Double desvE = Math.Sqrt(sumProd);
}
The formula depends on the set of data you have.
Is it the entire population? Then you should use the Population Standard Deviation (divisor: n).
Is the data a sample of a set? Then you should use the Sample Standard Deviation (divisor: n - 1)
You may find an easier-to-understand guide here: Laerd Statistics - Standard Deviation, which also has a handy Calculator for both solutions.
So, it is as #Greg answered, though I would first check if the list holds any values to avoid division by zero.
double stdDeviation = 0;
if (lista.Any())
{
var avg = lista.Average();
var sumOfSquares = lista.Sum(item => Math.Pow(item - avg, 2));
stdDeviation = Math.Sqrt(sumOfSquares / [divisor goes here]);
}
return stdDeviation;
Where the divisor be lista.Count() for population or (lista.Count() - 1) for samples.
Thanks to Laurence Burke in my other question for the isMaybeMoney function, I am able to determine whether an input is money or not.
What I'm doing now is trying to calculate the total after interest but I keep getting Infinity written to the screen. What in the world is wrong with my interestsaccrued function? It's supposed to be $3,522.55 when I use $1,234 as the starting balance with 3.5% interest.
Can someone please help me out?
static float money;
static void Main()
{
string[] myMaybeBalances = Accounts.GetStartingBalances();
myIsMaybeMoneyValidator Miimv = new myIsMaybeMoneyValidator();
ArrayList interests = Miimv.interestsAccrued(myMaybeBalances);
foreach (object interest in interests)
{
Console.WriteLine(interest);
}
Console.ReadLine();
}
public ArrayList interestsAccrued(string[] myMaybeBalances)
{
ArrayList interests = new ArrayList();
foreach (string myMaybeBalance in myMaybeBalances)
{
bool myResult = isMaybeMoney(myMaybeBalance);
if (myResult == true)
{
decimal[] rates = Accounts.GetRates();
for (int i = 0; i < rates.Length; i++)
{
decimal rate = rates[i];
float total = 1;
int n_X_t = 360;
while (n_X_t != 0)
{
rate = (1 + rates[i] / 12);
float myRate;
float.TryParse(rate.ToString(), out myRate);
total = total * myRate;
total = total * money;
n_X_t = n_X_t - 1;
}
interests.Add(total);
}
}
}
return interests;
}
public bool isMaybeMoney(object theirMaybeMoney)
{
string myMaybeMoney = theirMaybeMoney.ToString();
float num;
bool isValid = float.TryParse(myMaybeMoney,
NumberStyles.Currency,
CultureInfo.GetCultureInfo("en-US"), // cached
out num);
money = num;
return isValid;
}
You are multiplying total by the rate each step through the while loop, which seems reasonable enough, but you also multiply total by the value of the variable "money", which as far as I can tell is the starting balance.
So you multiply by the starting balance 360 times. If only my savings accounts worked like that! I'm not sure if the rest of the logic is correct, but for a start, try moving the
total = total * money;
to be under the line
float total = 1;
(or better yet just change from
float total = 1;
to
float total = money;
and get rid of the line
total = total * money;
altogether)
The codes you have is not evaluate. NO BENEFIT of construct loop for interest calculate!
This is not needful yet introduce much of risk for high complication
Here is codes you want for use of FUNCTIONARY encapsulate :
static void Main()
{
var interests = new List<decimal>();
foreach (string possibleBalance in Accounts.GetStartingBalances())
foreach (decimal rate in Accounts.GetRates())
{
decimal balance;
if (!decimal.TryParse(possibleBalance, NumberStyles.Currency, CultureInfo.CurrentCulture, out balance))
continue;
decimal interest = CalculateInterestAccrued(balance, rate, 12, 30);
interests.Add(interest);
}
foreach (decimal interest in interests)
Console.WriteLine(interest);
Console.ReadKey();
}
static decimal CalculateInterestAccrued(decimal principal, decimal rate, int compoundsPerYear, int years)
{
return principal * (decimal)Math.Pow((double)(1 + rate / compoundsPerYear), compoundsPerYear * years);
}
thanks,
PRASHANT :)
I need to know if a number compared to a set of numbers is outside of 1 stddev from the mean, etc..
While the sum of squares algorithm works fine most of the time, it can cause big trouble if you are dealing with very large numbers. You basically may end up with a negative variance...
Plus, don't never, ever, ever, compute a^2 as pow(a,2), a * a is almost certainly faster.
By far the best way of computing a standard deviation is Welford's method. My C is very rusty, but it could look something like:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 1;
foreach (double value in valueList)
{
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
k++;
}
return Math.Sqrt(S / (k-2));
}
If you have the whole population (as opposed to a sample population), then use return Math.Sqrt(S / (k-1));.
EDIT: I've updated the code according to Jason's remarks...
EDIT: I've also updated the code according to Alex's remarks...
10 times faster solution than Jaime's, but be aware that,
as Jaime pointed out:
"While the sum of squares algorithm works fine most of the time, it
can cause big trouble if you are dealing with very large numbers. You
basically may end up with a negative variance"
If you think you are dealing with very large numbers or a very large quantity of numbers, you should calculate using both methods, if the results are equal, you know for sure that you can use "my" method for your case.
public static double StandardDeviation(double[] data)
{
double stdDev = 0;
double sumAll = 0;
double sumAllQ = 0;
//Sum of x and sum of x²
for (int i = 0; i < data.Length; i++)
{
double x = data[i];
sumAll += x;
sumAllQ += x * x;
}
//Mean (not used here)
//double mean = 0;
//mean = sumAll / (double)data.Length;
//Standard deviation
stdDev = System.Math.Sqrt(
(sumAllQ -
(sumAll * sumAll) / data.Length) *
(1.0d / (data.Length - 1))
);
return stdDev;
}
The accepted answer by Jaime is great, except you need to divide by k-2 in the last line (you need to divide by "number_of_elements-1").
Better yet, start k at 0:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 0;
foreach (double value in valueList)
{
k++;
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
}
return Math.Sqrt(S / (k-1));
}
The Math.NET library provides this for you to of the box.
PM> Install-Package MathNet.Numerics
var populationStdDev = new List<double>(1d, 2d, 3d, 4d, 5d).PopulationStandardDeviation();
var sampleStdDev = new List<double>(2d, 3d, 4d).StandardDeviation();
See PopulationStandardDeviation for more information.
Code snippet:
public static double StandardDeviation(List<double> valueList)
{
if (valueList.Count < 2) return 0.0;
double sumOfSquares = 0.0;
double average = valueList.Average(); //.NET 3.0
foreach (double value in valueList)
{
sumOfSquares += Math.Pow((value - average), 2);
}
return Math.Sqrt(sumOfSquares / (valueList.Count - 1));
}
You can avoid making two passes over the data by accumulating the mean and mean-square
cnt = 0
mean = 0
meansqr = 0
loop over array
cnt++
mean += value
meansqr += value*value
mean /= cnt
meansqr /= cnt
and forming
sigma = sqrt(meansqr - mean^2)
A factor of cnt/(cnt-1) is often appropriate as well.
BTW-- The first pass over the data in Demi and McWafflestix answers are hidden in the calls to Average. That kind of thing is certainly trivial on a small list, but if the list exceed the size of the cache, or even the working set, this gets to be a bid deal.
I found that Rob's helpful answer didn't quite match what I was seeing using excel. To match excel, I passed the Average for valueList in to the StandardDeviation calculation.
Here is my two cents... and clearly you could calculate the moving average (ma) from valueList inside the function - but I happen to have already before needing the standardDeviation.
public double StandardDeviation(List<double> valueList, double ma)
{
double xMinusMovAvg = 0.0;
double Sigma = 0.0;
int k = valueList.Count;
foreach (double value in valueList){
xMinusMovAvg = value - ma;
Sigma = Sigma + (xMinusMovAvg * xMinusMovAvg);
}
return Math.Sqrt(Sigma / (k - 1));
}
With Extension methods.
using System;
using System.Collections.Generic;
namespace SampleApp
{
internal class Program
{
private static void Main()
{
List<double> data = new List<double> {1, 2, 3, 4, 5, 6};
double mean = data.Mean();
double variance = data.Variance();
double sd = data.StandardDeviation();
Console.WriteLine("Mean: {0}, Variance: {1}, SD: {2}", mean, variance, sd);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
public static class MyListExtensions
{
public static double Mean(this List<double> values)
{
return values.Count == 0 ? 0 : values.Mean(0, values.Count);
}
public static double Mean(this List<double> values, int start, int end)
{
double s = 0;
for (int i = start; i < end; i++)
{
s += values[i];
}
return s / (end - start);
}
public static double Variance(this List<double> values)
{
return values.Variance(values.Mean(), 0, values.Count);
}
public static double Variance(this List<double> values, double mean)
{
return values.Variance(mean, 0, values.Count);
}
public static double Variance(this List<double> values, double mean, int start, int end)
{
double variance = 0;
for (int i = start; i < end; i++)
{
variance += Math.Pow((values[i] - mean), 2);
}
int n = end - start;
if (start > 0) n -= 1;
return variance / (n);
}
public static double StandardDeviation(this List<double> values)
{
return values.Count == 0 ? 0 : values.StandardDeviation(0, values.Count);
}
public static double StandardDeviation(this List<double> values, int start, int end)
{
double mean = values.Mean(start, end);
double variance = values.Variance(mean, start, end);
return Math.Sqrt(variance);
}
}
}
/// <summary>
/// Calculates standard deviation, same as MATLAB std(X,0) function
/// <seealso cref="http://www.mathworks.co.uk/help/techdoc/ref/std.html"/>
/// </summary>
/// <param name="values">enumumerable data</param>
/// <returns>Standard deviation</returns>
public static double GetStandardDeviation(this IEnumerable<double> values)
{
//validation
if (values == null)
throw new ArgumentNullException();
int lenght = values.Count();
//saves from devision by 0
if (lenght == 0 || lenght == 1)
return 0;
double sum = 0.0, sum2 = 0.0;
for (int i = 0; i < lenght; i++)
{
double item = values.ElementAt(i);
sum += item;
sum2 += item * item;
}
return Math.Sqrt((sum2 - sum * sum / lenght) / (lenght - 1));
}
The trouble with all the other answers is that they assume you have your
data in a big array. If your data is coming in on the fly, this would be
a better approach. This class works regardless of how or if you store your data. It also gives you the choice of the Waldorf method or the sum-of-squares method. Both methods work using a single pass.
public final class StatMeasure {
private StatMeasure() {}
public interface Stats1D {
/** Add a value to the population */
void addValue(double value);
/** Get the mean of all the added values */
double getMean();
/** Get the standard deviation from a sample of the population. */
double getStDevSample();
/** Gets the standard deviation for the entire population. */
double getStDevPopulation();
}
private static class WaldorfPopulation implements Stats1D {
private double mean = 0.0;
private double sSum = 0.0;
private int count = 0;
#Override
public void addValue(double value) {
double tmpMean = mean;
double delta = value - tmpMean;
mean += delta / ++count;
sSum += delta * (value - mean);
}
#Override
public double getMean() { return mean; }
#Override
public double getStDevSample() { return Math.sqrt(sSum / (count - 1)); }
#Override
public double getStDevPopulation() { return Math.sqrt(sSum / (count)); }
}
private static class StandardPopulation implements Stats1D {
private double sum = 0.0;
private double sumOfSquares = 0.0;
private int count = 0;
#Override
public void addValue(double value) {
sum += value;
sumOfSquares += value * value;
count++;
}
#Override
public double getMean() { return sum / count; }
#Override
public double getStDevSample() {
return (float) Math.sqrt((sumOfSquares - ((sum * sum) / count)) / (count - 1));
}
#Override
public double getStDevPopulation() {
return (float) Math.sqrt((sumOfSquares - ((sum * sum) / count)) / count);
}
}
/**
* Returns a way to measure a population of data using Waldorf's method.
* This method is better if your population or values are so large that
* the sum of x-squared may overflow. It's also probably faster if you
* need to recalculate the mean and standard deviation continuously,
* for example, if you are continually updating a graphic of the data as
* it flows in.
*
* #return A Stats1D object that uses Waldorf's method.
*/
public static Stats1D getWaldorfStats() { return new WaldorfPopulation(); }
/**
* Return a way to measure the population of data using the sum-of-squares
* method. This is probably faster than Waldorf's method, but runs the
* risk of data overflow.
*
* #return A Stats1D object that uses the sum-of-squares method
*/
public static Stats1D getSumOfSquaresStats() { return new StandardPopulation(); }
}
We may be able to use statistics module in Python. It has stedev() and pstdev() commands to calculate standard deviation of sample and population respectively.
details here: https://www.geeksforgeeks.org/python-statistics-stdev/
import statistics as st
print(st.ptdev(dataframe['column name']))
This is Population standard deviation
private double calculateStdDev(List<double> values)
{
double average = values.Average();
return Math.Sqrt((values.Select(val => (val - average) * (val - average)).Sum()) / values.Count);
}
For Sample standard deviation, just change [values.Count] to [values.Count -1] in above code.
Make sure you don't have only 1 data point in your set.