# calculating CP,CPK

• ### Question

• Hello,

I want to know how do i calculate Cp, Cpk for the for the tests.

i have a CSV file which has USL and LSL as input

I want to generate a report with Cp and Cpk values for those tests.

And i'm very new to this C#

Does anyone has the code that calculates Cp,Cpk values

Please let me know

Thanks

Akshay

Tuesday, March 19, 2019 9:37 AM

### All replies

• Here's an Excel spreadsheet that does it (supposedly).

Look at the formulas they define and then convert them to C#. Mostly they should translate directly. The math functionality for .NET is mostly contained in the Math class. Standard deviation and other math functions can be defined yourself or, more likely, just download a NuGet package that provides them.

Michael Taylor http://www.michaeltaylorp3.net

Tuesday, March 19, 2019 2:05 PM
• Hello,

I want to know how do i calculate Cp, Cpk for the for the tests.

i have a CSV file which has USL and LSL as input

I want to generate a report with Cp and Cpk values for those tests.

And i'm very new to this C#

Does anyone has the code that calculates Cp,Cpk values

Please let me know

Thanks

Akshay

I didn't read the Excel file, I don't know that cp and cpk.

But if you show me how is calculated manually, we can help each other.

BP-LP 2005/2016 @ll rights reserved

Thursday, March 21, 2019 12:39 PM
• Hello,

I read the CSV file. And we have the formula for CP as USL-LSL/6xStd Deviation.

The LSL and USL values will be available in the CSV file for each tests.

Here is the code till where i can read the first column(Tests) of the CSV file.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Cp_Cpk_demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
button2.Enabled = false;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = ("comma seperated value | *.CSV");
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string strfilename = openFileDialog1.FileName;
if (File.Exists(strfilename))
{
textBox1.Text = strfilename;
}
else
{

strfilename = "";
}
if (!string.IsNullOrWhiteSpace(strfilename))
{
textBox1.Text = strfilename;
}
else
{
MessageBox.Show("Please select a file");
}
}
else
{
MessageBox.Show("Please select a file");
}
}

private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{

}

private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text == "")
button2.Enabled = false;
else
button2.Enabled = true;

}
public static DataTable OpenCSV(string filePath)
{
DataTable dt = new DataTable();
FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);

StreamReader sr = new StreamReader(fs);
string strLine = "";
string[] aryLine = null;
string[] tableHead = null;
int columnCount = 0;
bool IsFirst = true;
while ((strLine = sr.ReadLine()) != null)
{
if (IsFirst == true)
{
tableHead = strLine.Split(',');
IsFirst = false;
columnCount = tableHead.Length;
for (int i = 0; i < columnCount; i++)
{
DataColumn dc = new DataColumn(tableHead[i]);
dt.Columns.Add(dc);
}
}
else
{
aryLine = strLine.Split(',');
DataRow dr = dt.NewRow();
for (int j = 0; j < columnCount; j++)
{
dr[j] = aryLine[j];
}
dt.Rows.Add(dr);
}
}
if (aryLine != null && aryLine.Length > 0)
{
dt.DefaultView.Sort = tableHead[0] + " " + "asc";
}
sr.Close();
fs.Close();
return dt;
}

private void button2_Click(object sender, EventArgs e)
{
filecheck();

}
private void filecheck()
{

string strfilename = textBox1.Text;
if (File.Exists(strfilename))
{
textBox1.Text = strfilename;
}
else
{

strfilename = "";
}
if (!string.IsNullOrWhiteSpace(strfilename))
{
textBox1.Text = strfilename;
}
else
{
MessageBox.Show("Please select a valid file");
}
foreach (DataRow dr in OpenCSV(textBox1.Text).Rows)
{
// Get the first column
checkedListBox1.Items.Add(dr["Tests"]);
}

button2.Enabled = false;

}

private void button5_Click(object sender, EventArgs e)
{

}

private void BindDataCSV(string filePath)
}
}

I am little bit stuck to proceed further

Akshay

Friday, March 22, 2019 10:25 AM
• > I am little bit stuck to proceed further

Do you know the formulae for computing standard deviation?  It's not that hard.  Once you have that, the rest is easy.  Note that I modified your "OpenCSV" slightly to convert the values to integer instead of storing them as strings.

```using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

class program
{
public static DataTable OpenCSV(string filePath)
{
DataTable dt = new DataTable();
FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);

StreamReader sr = new StreamReader(fs);
string strLine = "";
string[] aryLine = null;
string[] tableHead = null;
int columnCount = 0;
bool IsFirst = true;
while ((strLine = sr.ReadLine()) != null)
{
if (IsFirst == true)
{
tableHead = strLine.Split(',');
IsFirst = false;
columnCount = tableHead.Length;
for (int i = 0; i < columnCount; i++)
{
dt.Columns.Add(tableHead[i], typeof(int));
}
}
else
{
aryLine = strLine.Split(',');
DataRow dr = dt.NewRow();
for (int j = 0; j < columnCount; j++)
{
dr[tableHead[j]] = Convert.ToInt32(aryLine[j]);
}
dt.Rows.Add(dr);
}
}
if (aryLine != null && aryLine.Length > 0)
{
dt.DefaultView.Sort = tableHead[0] + " " + "asc";
}
sr.Close();
fs.Close();
return dt;
}

static public void Main()
{
DataTable dt = OpenCSV("x.csv");

// Sum up values and squares.

double sum = 0;
double sumsq = 0;
foreach( DataRow row in dt.Rows )
{
int delta = (int)row["USL"] - (int)row["LSL"];
sum += delta;
sumsq += delta * delta;
}

// Compute standard deviation.

double mean = sum / dt.Rows.Count;
double stdev = Math.Sqrt( sumsq / dt.Rows.Count - mean * mean );

// Compute Cp and Cpk.

foreach( DataRow row in dt.Rows )
{
int usl = (int)row["USL"];
int lsl = (int)row["LSL"];
double Cp = (usl - lsl) / (6 * stdev);
double Cpk = Math.Min(
(usl - mean) / (3 * stdev),
(mean - lsl) / (3 * stdev)
);
Console.WriteLine(
"{0}: {1},{2} {3} {4}",
row["id"], usl,lsl, Cp, Cpk );
}
}
}
```

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Friday, March 22, 2019 8:58 PM
• Hello,
Can you tell me how do i do this using form (please refer
the screenshot which i have attached above)?

Thanks

Akshay

Monday, March 25, 2019 6:49 AM
• No.  I have already done 99% of the work for you.  You can surely figure out how to create a simple form and plug my code into that form.  It shouldn't take you more than a couple of hours.

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Tuesday, March 26, 2019 6:19 AM
• I'm getting this error : specified cast is not valid

How to resolve this

Akshay

Tuesday, March 26, 2019 6:32 AM
• I'm getting this error : specified cast is not valid

How to resolve this

Did you not read Tim's statement?

"Note that I modified your "OpenCSV" slightly to convert the values to
integer instead of storing them as strings."

The error you're showing re an invalid cast will occur if you are still
storing the values in the table as strings. You can't cast a string to
an int.

- Wayne

Tuesday, March 26, 2019 8:57 AM
• Hello,

Thanks for the reply.

I need to get in the way of strings but not int.

How do i do that

Thanks

Akshay

Wednesday, March 27, 2019 9:24 AM

• I need to get in the way of strings but not int.

How do i do that

>I need to get in the way of strings but not int.

Why?

There are a number of problems with the way you have been trying to cobble
together this program from code written by other people. One problem is that
you probably don't really understand much of the code you are being given.
So you aren't able to alter it as needed or as desired, and then must return
to the forums to ask others to make modifications.

Another issue - and it may come into play here - is that you appear to be
pursuing different approaches to the implementation using suggestions from
different people in different threads. For example, the OpenCSV code you
posted in this thread was written by Kyle in this thread:

Reading CSV file
https://social.msdn.microsoft.com/Forums/vstudio/en-US/a32546f5-46f1-444c-a067-9532893d8b71/reading-csv-file?forum=winforms

But in another thread you are trying to use code written by Karen which
doesn't use a DataTable at all and may use a different approach to reading
and parsing the CSV.file:

how to process items in checkedlistbox
https://social.msdn.microsoft.com/Forums/vstudio/en-US/2768df94-9059-40cb-a885-c617dcdd9634/how-to-process-items-in-checkedlistbox?forum=winforms

In this thread you are trying to use code written by Tim but can't adapt it
to your specification even slightly.

While it is a general rule that each thread should address one issue only,
and that each issue in the development of a program should be dealt with in
its own thread, there has to be some coordination and consistency between
threads that pertain to the same program. Trying to create a program using
suggestions from different posters in different threads which take different
approaches is futile. It also can waste a considerable amount of time and
effort expended by those trying to assist.

When there is a connection between code being developed in different threads
at the same time you should include links to the other threads so that
duplication of effort can be avoided. Note as well that it is usually frowned
upon and discouraged when individuals appear to be trying to get others to
write a complete program for them. Helping with problems big or small is what
we are here for, but not to provide free programming services.

You have not said why you are trying to create this program. Is it for personal
use only? Or for academic credit? Or commercial gain? Or as a learning exercise?

Trying to learn how to program in any language requires considerable systematic
study up front. To learn language features, syntax, etc. Without that foundation
one cannot become a successful programmer. You simply cannot become a competent
programmer just by looking at code written by others and getting others to
solve every problem you encounter.

If you lack the knowledge at the moment to complete this project, it might be
wiser to step back for a spell and study the rudiments. Then you will be much
better equipped to make changes to code samples to better conform to your
requirements.

Now as to your "requirement" to use strings in the DataTable rather than ints,
you should explain why you feel this is necessary. Then someone can agree or
disagree, and if they agree then suggest code changes that are appropriate.

Meanwhile if you still haven't gotten Tim's code to work and want to use
strings in the table consider these alterations.

As you appear to be storing strings in the DataTable as per Kyle's original
code, alter the following line you showed in the last screenshot from:

```int delta = (int)row["val2"] - (int)row["val1"];
```

to this:

```int delta = int.Parse(row["val2"].ToString())
- int.Parse(row["val1"].ToString());
```

(Are you sure you have the order correct according to the data being used?
Should it be val2 - val1 as you have, or val1 - val2?)

Make similar changes to the code to initialize the variables usl and lsl.

Note that int.Parse will throw an exception at run time if a string is passed to it which
isn't a valid integer value.

- Wayne

Wednesday, March 27, 2019 8:40 PM
• Hi,

I have two Form windows. Form1 and Form2.

I need to get the calculated data of Cp and Cpk on form2.

Could you please tell me how can i do this

Here is the screenshots and the code that I am using

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Reading_CSV_file
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btOK.Enabled = false;
}

private void button1_Click(object sender, EventArgs e)
{
btBROWSE.Enabled = false;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = ("comma seperated value | *.CSV");
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string strfilename = openFileDialog1.FileName;
if (File.Exists(strfilename))
{
textBox1.Text = strfilename;
}
else
{

strfilename = "";
}
if (!string.IsNullOrWhiteSpace(strfilename))
{
textBox1.Text = strfilename;
}
else
{
MessageBox.Show("Please select a file");
}
}
else
{
MessageBox.Show("Please select a file");
}
}

private void textBox1_TextChanged(object sender, EventArgs e)
{

if (textBox1.Text == "")
btOK.Enabled = false;
else
btOK.Enabled = true;

}

private void Form1_Load(object sender, EventArgs e)
{

}

public static DataTable OpenCSV(string filePath)
{
DataTable dt = new DataTable();
FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);

StreamReader sr = new StreamReader(fs);
string strLine = "";
string[] aryLine = null;
string[] tableHead = null;
int columnCount = 0;
bool IsFirst = true;
while ((strLine = sr.ReadLine()) != null)
{
if (IsFirst == true)
{
tableHead = strLine.Split(',');
IsFirst = false;
columnCount = tableHead.Length;
for (int i = 0; i < columnCount; i++)
{
DataColumn dc = new DataColumn(tableHead[i]);
dt.Columns.Add(dc);
}
}
else
{
aryLine = strLine.Split(',');
DataRow dr = dt.NewRow();
for (int j = 0; j < columnCount; j++)
{
dr[j] = aryLine[j];
}
dt.Rows.Add(dr);
}
}
if (aryLine != null && aryLine.Length > 0)
{
dt.DefaultView.Sort = tableHead[0] + " " + "asc";
}
sr.Close();
fs.Close();
return dt;
}

DataTable dt;

private void btOK_Click(object sender, EventArgs e)
{
dt = OpenCSV(textBox1.Text);
foreach (DataRow dr in dt.Rows)
{
// Get the first column
checkedListBox1.Items.Add(dr["Tests"]);
btOK.Enabled = false;
}
}

class Value
{
string testname;
string value1;
string value2;
public Value(string t, string v1, string v2)
{
testname = t;
value1 = v1;
value2 = v2;
}

public string Testname { get { return testname; } }
public string Value1 { get { return value1; } }
public string Value2 { get { return value2; } }
}

private void btGetValues_Click(object sender, EventArgs e)
{

List<Value> list = new List<Value>();

foreach (var i in checkedListBox1.CheckedItems)
{
int index = checkedListBox1.Items.IndexOf(i);
Value v = new Value(dt.Rows[index][0].ToString(), dt.Rows[index][1].ToString(), dt.Rows[index][2].ToString());
list.Add(v);
}

foreach (Value i in list)
{
MessageBox.Show(i.Testname + i.Value1 + i.Value2);

}
}

}
}

Akshay

Monday, April 1, 2019 5:16 AM
• Hi,

This is my CSV file

Can you please tell me how do i read the 1st column date and the second test1 column and fetch USL and LSL values

Akshay

Friday, April 5, 2019 7:17 AM
• Hi,

Has anyone calculated Cp, Cpk (process capability) for the tests generated?

Akshay

Wednesday, April 10, 2019 1:22 PM

• Has anyone calculated Cp, Cpk (process capability) for the tests generated?

How does this question differ from your earlier (as yet unmarked as Answered) thread?

calculating CP,CPK
https://social.msdn.microsoft.com/Forums/vstudio/en-US/893bcb38-c438-4ac5-9ca1-1392abd8ed1d/calculating-cpcpk?forum=csharpgeneral

- Wayne

Wednesday, April 10, 2019 6:48 PM
• I already wrote this code for you, earlier in the thread.  If you are not willing to learn anything from the answers you get, then you should stop asking questions and go pay someone to write this code for you.

By the way, your table of values is in error.  USL means "upper" and LSL means "lower"; the USL value must be larger than the LSL value.

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Wednesday, April 10, 2019 8:42 PM
• Yes.  Have you?  Because you already have the code to do so.

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Wednesday, April 10, 2019 8:43 PM
• Hi,

Sorry about asking this . Could you please tell me how do i get the test1sum for only those tests between the specific dates from two date pickers. Here is the code which you had given. I'm having issue in calculating Standard deviation

private void button2_Click(object sender, EventArgs e)
{
dt = GetDataTabletFromCSVFile(File.Text);

foreach (DataRow row in dt.Rows)
{
if (Convert.ToDateTime(row["Date"]) <= Convert.ToDateTime(DateTo.Text) && Convert.ToDateTime(row["Date"]) >= Convert.ToDateTime(DateFrm.Text))
{

double test1sum = 0;
double sum = 0;
double sumsq = 0;
foreach (DataRow Row in dt.Rows)
{
test1sum = test1sum + Convert.ToDouble(row["Test1"]);
Double delta = double.Parse(row["USL"].ToString()) - Double.Parse(row["LSL"].ToString());
sum += delta;
sumsq += delta * delta;
}

double mean = test1sum / dt.Rows.Count;
double stdev = Math.Sqrt(sumsq / dt.Rows.Count - mean * mean);

Double usl = Convert.ToDouble(row["USL"]);
Double lsl = Convert.ToDouble(row["LSL"]);
double Cp = (usl - lsl) / (6 * stdev);
double Cpk = Math.Min(
(usl - mean) / (3 * stdev),
(mean - lsl) / (3 * stdev)
);
Console.WriteLine(
"{0}: {1},{2}, {3}, {4}",
row["Test1"], usl, lsl, Cp, Cpk);

Akshay

Friday, April 12, 2019 10:13 AM
• > I'm having an issue calculating Standard deviation

What issue are you having?  Please don't make us guess what problems you are seeing.

Your data set as you posted it has two major problems.  First, I hope you can see that there is only one row with the date filled in.  What do you think the value of row["Date"] is going to be for the other rows?

Second, as I have said 3 times before, the USL and LSL columns are swapped.  The LSL value must always be lower than the USL value.

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Friday, April 12, 2019 8:54 PM