mean and standard deviation - c#

Im trying to make a mean and standard deviation calculator on visual studio using windows form. It's for a class and I have to use windows form and you have to be able to input data manually or select .txt file wiht the data in it.
Its hard to explain what i need to do because I'm new to this. Basically i need to the what button1_Click does but do the same thing for button2_Click. The thing is, is that it reads a file rather than taking input from user. It stores (not sure if thats the correct word) the values to a list not an array I think. I don't know if i can convert it to an array or add the values to the list as an array or what. I'm really lost!
Here is the exact wording of my professor for this assignment:
"Write a program, using C#, that will find the mean and standard deviation of a number of data points. The program should allow the user to either enter data manually or via a text file."
Any help would be great I'm new to this and my teacher offers little to no help and leaves us to search the internet for answers.
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;
namespace BsweeneyCsharp3_1_
{
public partial class Form1 : Form
{
List<double> values;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
values = new List<double>();
}
void ShowValues()
{
listBox1.Items.Clear();
for (int i = 0; i < values.Count; i++)
listBox1.Items.Add(values[i]);
}
private void button1_Click(object sender, EventArgs e)
{
double value = 0.00;
double sum = 0.00, sumSquares = 0.00, squareSums;
double stdDev = 0.00, mean = 0.00;
if (textBox1.Text.Length == 0)
{
MessageBox.Show("You must enter a value.", "Standard Deviation");
return;
}
try
{
value = double.Parse(textBox1.Text);
values.Add(value);
ShowValues();
textBox1.Text = "";
textBox1.Focus();
}
catch (FormatException)
{
MessageBox.Show("The value you entered is invalid.",
"");
}
for (int i = 0; i < values.Count; i++)
{
sum += values[i];
}
mean = sum / values.Count;
squareSums = sum * sum;
for (int i = 0; i < values.Count; i++)
sumSquares += (values[i] * values[i]);
double numerator = values.Count * sumSquares - squareSums;
double denominator = values.Count * (values.Count - 1);
stdDev = Math.Sqrt(numerator / denominator);
textBox2.Text = mean.ToString();
textBox3.Text = stdDev.ToString("F");
}
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "TXT|*.txt";
double mean = 0.00, stdDev = 0.00, sum = 0.00;
double sumSquares = 0.00, squareSums = 0.00;
int counter = 0;
if (ofd.ShowDialog() == DialogResult.OK)
{
textBox4.Text = ofd.FileName;
}
string line;
System.IO.StreamReader file = new System.IO.StreamReader(textBox4.Text);
List<string> list = new List<string>();
while ((line = file.ReadLine()) != null)
{
listBox2.Items.Add(line);
var dbl = Convert.ToDouble(line);
sum += dbl;
counter++;
}
if (counter > 0)
{
mean = sum / counter;
squareSums += sum * sum;
}
if(counter > 0)
{
sumSquares += Math.Pow((sum - mean), 2);
double numerator = counter * sumSquares - squareSums;
double denominator = counter * (counter - 1);
stdDev = Math.Sqrt(numerator / denominator);
textBox2.Text = mean.ToString();
textBox3.Text = numerator.ToString();
}
}
}
}

I did my best to interpret what you wrote. I took into consideration that you are a new programmer. I avoided major refactoring including adding a much needed method. Start learning about methods/functions which gives you code re-use. A method prevents the problem you have here. The problem is you are calculating the same thing in two different ways.
You stated that the "manual" method (not file read) works correctly so I took that as the source of truth.
relevant code changes to button2_Click
if (counter > 0)//you don't need the same check 2x
{
mean = sum / counter;
for (int i = 0; i < listBox2.Items.Count; i++)
sumSquares += (Convert.ToDouble(listBox2.Items[i]) * Convert.ToDouble(listBox2.Items[i]));
squareSums += sum * sum;
//sumSquares += Math.Pow((sum - mean), 2);//You changed the formula again here
double numerator = counter * sumSquares - squareSums;
double denominator = counter * (counter - 1);
stdDev = Math.Sqrt(numerator / denominator);
textBox2.Text = mean.ToString();
//textBox3.Text = numerator.ToString();//You changed how you did things again
textBox3.Text = stdDev.ToString("F");
}
FYI, I didn't check your math.

Related

#region variance & Confidence Calculation

// None yet...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using USBkit; //This is for the costomised dll wrapper.
using System.IO; //This if for binary file operations.
using lbrStatistics; //This is for the statistics library.
namespace USBTL
{
public partial class Form1 : Form
{
int iUSBDevice; //This is the USB enuminator.
bool bUSBDeviceStatus = false; //Status of USB device.
//bool bWriteFileSet = false; //File pathway is set or not.
//bool bWriteTofile = false; //Writting to file.
bool bflasher = false;
float[,] fTemperatureData; //Temperature Data array.
const int iTemperatureDataSize = 128;
const int iNumberOfChannels = 2;
float [] fMeanValue; //This array is for the Mean Value.
float [] fStdDev; //This array is for the standard Deviation.
float[] fVariance; //This array is for the Variance calculations.
float[] fConfidence; //This array is for the Confidence calculations.
float[] fMaxTemperature= new float [2] {30, 30}; //This is the Temperature conversion constand.
float[] fMaxInputVoltage= new float [2] {255*4/5, 255*4/5}; //This is the Input Range coverage constant.
enum ChanID {Chan1, Chan2}; //Just an enumeration for the Analogue Input Channels.
//Class Form1 constructor.
public Form1()
{
InitializeComponent();
}
// Form1_Load opens up the USB Device and initialises the data buffer.
private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Application is starting!!"); //Just a message on the output window
fMeanValue = new float [iNumberOfChannels];
fStdDev = new float [iNumberOfChannels];
fVariance = new float[iNumberOfChannels];
fConfidence = new float[iNumberOfChannels];
for (int y = 0; y < iNumberOfChannels; y++)
{
fMeanValue[y] = 0; //Initialise MeanValue
fStdDev[y] = 0; //Initialise Std Deviation
fVariance[y] = 0; //Initialise Variance
fConfidence[y] = 0; //Initialise Confidence
}
#region USB interogation code
//Interogate and find the address of the USB kit.
for(int Device=0; Device<4; Device++)
{
iUSBDevice = USB.OpenDevice(Device);
if (iUSBDevice != Device)
{
bUSBDeviceStatus = false;
stxtUSBStatus.ForeColor = Color.Red;
stxtUSBStatus.Text = "USB NOT FOUND";
Console.WriteLine("USB Device " + Convert.ToString(Device)+ " not found");
}
else
{
bUSBDeviceStatus = true;
Console.WriteLine("USB Device " + Convert.ToString(Device) +" Found");
stxtUSBStatus.ForeColor = Color.Green;
stxtUSBStatus.Text = "USB "+Convert.ToString(Device)+" OPEN";
break;
}
}
#endregion
#region Array initialisation Code
fTemperatureData = new float[iTemperatureDataSize,iNumberOfChannels];
for(int y=0; y<iNumberOfChannels; y++)
for (int i = 0; i < fTemperatureData.GetLength(y); i++)
fTemperatureData[i,y] = 0;
#endregion
#region If USB device found Enable the timer
if (bUSBDeviceStatus == true)
{
tmrNS.Interval = 200; //Timer is running 5 times a second.
tmrNS.Enabled = true;
}
#endregion
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Console.WriteLine("Application Terminated");
}
private void tmrNS_Tick(object sender, EventArgs e)
{
#region flasher
if (bflasher == false)
{
USB.SetAnalogChannel(1);
bflasher = true;
}
else
{
USB.ClearAnalogChannel(1);
bflasher = false;
}
#endregion
#region Reading analogue channels.
int [] iAnalogueInput = new int [2] {1, 2};
USB.ReadAllAnalog(ref iAnalogueInput[0], ref iAnalogueInput[1]);
pltData1.data = (int) ((float) iAnalogueInput[(int)ChanID.Chan1] * fMaxTemperature[(int)ChanID.Chan1]/fMaxInputVoltage[(int)ChanID.Chan1]);
pltData2.data = (int) ((float) iAnalogueInput[(int)ChanID.Chan2] * fMaxTemperature[(int)ChanID.Chan2]/fMaxInputVoltage[(int)ChanID.Chan2]);
pbTemp.Value = iAnalogueInput[(int)ChanID.Chan1];
#endregion
#region Setup the digital LEDs
int Channel = (int)ChanID.Chan1;
int iBitShift =(int) Math.Round(Math.Log(iAnalogueInput[Channel], 2), 0)-1;
USB.WriteAllDigital(1 << iBitShift);
#endregion
#region Array updates.
for(int y=iNumberOfChannels-1; y>0;y--)
for (int i = fTemperatureData.GetLength(y)-1; i > 0; i--)
fTemperatureData[i,y] = fTemperatureData[i - 1,y];
for(int y=iNumberOfChannels-1; y>0; y--)
fTemperatureData[0,y] = (float) iAnalogueInput[y]*fMaxTemperature[y]/fMaxInputVoltage[y];
#endregion
#region Mean Value Calculation
for (int y = 0; y < iNumberOfChannels; y++)
{
for (int i = 0; i < fTemperatureData.GetLength(y); i++)
fMeanValue[y] += fTemperatureData[i, y];
fMeanValue[y] =(float) Math.Round(fMeanValue[y]/fTemperatureData.GetLength(y),2);
}
#endregion
#region Standard Deviation Calculation
for (int y = 0; y < iNumberOfChannels; y++)
{
for (int i = 0; i < fTemperatureData.GetLength(y); i++)
fStdDev[y] += (float)Math.Pow((double)(fTemperatureData[i, y] - fMeanValue[y]), 2.0);
fStdDev[y] = (float) Math.Round((float)Math.Sqrt(fStdDev[y] / (fTemperatureData.GetLength(y) - 1)),2);
}
#endregion
#region Variance Calculation
//Add here code to calculate the variance
//fVariance[0]=???
#endregion
#region Confidence Calculation
//Add here code to calculate the Confidence
//fConfidence[0]=???
#endregion
//Add here code to write the Mean value, Standard Deviation, Variance and Confidence in textboxs. Hint use labels to indicate which one is which.
//Also add code here to call the statistic library functions
}
private void pbTemp_Click(object sender, EventArgs e)
{
//Nothing implemented for this function.
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (tmrNS.Enabled == true) //Stop Timer.
tmrNS.Enabled = false;
USB.ClearAllAnalog();
USB.ClearAllDigital();
USB.CloseDevice(); //Close USB.
GC.Collect();
}
private void pltData1_Load(object sender, EventArgs e)
{
//Nothing implemented for this event.
}
private void button1_Click(object sender, EventArgs e)
{
//This is just an example of using the statistics library......
//These are are all local variables!!!
float [] fAverageValue = new float [iNumberOfChannels];
float [] fStandardDeviation = new float [iNumberOfChannels];
float [] fVariance = new float [iNumberOfChannels];
float [] fConfidence = new float [iNumberOfChannels];
for (int y = 0; y < iNumberOfChannels; y++)
{
for (int i = 0; i < fTemperatureData.GetLength(y); i++) //This is an example for filling up the data Array
fTemperatureData[i, y] = 100 + 2 / ((float)i + 1); //Generate dummy data
float[] fSingleDimArray= new float [iTemperatureDataSize]; //A temporary array for converting multidimentional arrays to single arrays.
// Array.Copy(fTemperatureData, (int)fTemperatureData.GetLength(128) * y, fSingleDimArray, 0, fTemperatureData.GetLength(y));
for (int i = 0; i < fTemperatureData.GetLength(y); i++)
fSingleDimArray[i] = fTemperatureData[i, y];
fAverageValue[y] = (float) Math.Round(Statistb.Average(ref fSingleDimArray),1); //Calculating Average Value
fStandardDeviation[y] =(float) Math.Round(Statistb.StdDev(ref fSingleDimArray),3); //Calculating Standard Deviation
fVariance[y] = (float) Math.Round(Statistb.Variance(ref fSingleDimArray),1); //Calculating Variance
fConfidence[y] = (float) Math.Round(Statistb.Confidence90(ref fSingleDimArray),3); //Calculating Confidence
//This is for reporting the calculations to the output window.
Console.WriteLine("Average"+y.ToString()+"=" + fAverageValue[y].ToString());
Console.WriteLine("SD"+y.ToString()+"=" + fStandardDeviation[y].ToString());
Console.WriteLine("Var"+y.ToString()+"=" + fVariance[y].ToString());
Console.WriteLine("Conf"+y.ToString()+"=" + fConfidence[y].ToString());
}
}
private void pltData2_Load(object sender, EventArgs e)
{
//Nothing implemented for this event!!
}
}
}
#region Variance Calculation
for (int y = 0; y < iNumberOfChannels; y++)
{
for (int i = 0; i < fTemperatureData.GetLength(y); i++)
fVariance[y] += (float)Math.Pow((double)(fTemperatureData[i, y] - fMeanValue[y]), 2.0);
fVariance[y] = (float)(fVariance[y] / (fTemperatureData.GetLength(y) - 1));
}
#endregion
What confidence intervals are you interested in?

I am trying to integrate an array

I am trying to pull the total from the program and putting it into an array to be displayed when the program is closed but the current code has a problem as it takes the last number inputted and squashes it together with the number in array slot 0. How do I fix this?
string[] Sales = new string[5];
int i = 0;
string Invoice = "";
int numberOfInvoices = 0;
decimal totalOfInvoices = 0m;
decimal invoiceAverage = 0m;
string Total = "";
private void btnCalculate_Click(object sender, EventArgs e)
{
//sets the variables
decimal subtotal = Convert.ToDecimal(txtEnterSubtotal.Text);
decimal discountPercent = .25m;
decimal discountAmount = Math.Round(subtotal * discountPercent, 2);
decimal invoiceTotal = subtotal - discountAmount;
//retrieves the data from the form
txtSubtotal.Text = subtotal.ToString("c");
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString("c");
txtTotal.Text = invoiceTotal.ToString("c");
//preforms the various math functions
numberOfInvoices++;
totalOfInvoices += invoiceTotal;
invoiceAverage = totalOfInvoices / numberOfInvoices;
Total = Convert.ToString(invoiceTotal);
for (int i = 0; i < Sales.Length; i++) ;
{
Sales[i] += Total + "\n";
}
txtNumberOfInvoices.Text = numberOfInvoices.ToString();
txtTotalOfInvoices.Text = totalOfInvoices.ToString("c");
txtInvoiceAverage.Text = invoiceAverage.ToString("c");
txtEnterSubtotal.Text = "";
//sets the focus on Enter Subtotal
txtEnterSubtotal.Focus();
}
private void btnClearTotals_Click(object sender, EventArgs e)
{
numberOfInvoices = 0;
totalOfInvoices = 0m;
invoiceAverage = 0m;
txtNumberOfInvoices.Text = "";
txtTotalOfInvoices.Text = "";
txtInvoiceAverage.Text = "";
txtEnterSubtotal.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++) ;
{
foreach (string Tot in Sales)
{
Total += Tot;
}
}
MessageBox.Show(Total, "Invoices");
//closes the program
this.Close();
}
This is what I get when I enter 100, 200, 300, 400, and 500.
375.0075.00,
150.00,
225.00,
300.00,
375.00
I would use a list...
Creating a list
var Sales = new List<int>();
Then to add to the list
Sales.Add(total);
You can keep adding to the list.
Looks like you're converting numbers to strings needlessly, from the looks of it just work with decimals and ints.
Hope this helps.

Why is my C# code coming up with zero's in message box upon clicking exit?

I am trying to get my message box to show the invoice subtotals stored in my array...5 of them to show in a message box using the foreach method.
I am supposed to input a wage and it then does some calculation and stores the subtotal value into the array. I declared an array and index called decArray and intIndex.
Can anyone tell me what I'm missing or doing wrong?
Thank you in advance!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace InvoiceTotal
{
public partial class frmInvoiceTotal : Form
{
public frmInvoiceTotal()
{
InitializeComponent();
}
// TODO: declare class variables for array and list here
decimal[] decArray = new decimal[5];
int intIndex = 0;
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
if (txtSubtotal.Text == "")
{
MessageBox.Show(
"Subtotal is a required field.", "Entry Error");
}
else
{
decimal subtotal = Decimal.Parse(txtSubtotal.Text);
if (subtotal > 0 && subtotal < 10000)
{
decimal discountPercent = 0m;
if (subtotal >= 500)
discountPercent = .2m;
else if (subtotal >= 250 & subtotal < 500)
discountPercent = .15m;
else if (subtotal >= 100 & subtotal < 250)
discountPercent = .1m;
decimal discountAmount = subtotal * discountPercent;
decimal invoiceTotal = subtotal - discountAmount;
discountAmount = Math.Round(discountAmount, 2);
invoiceTotal = Math.Round(invoiceTotal, 2);
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString();
txtTotal.Text = invoiceTotal.ToString();
for (intIndex = 0; intIndex <= decArray.Length - 1; intIndex++)
{
DecArray[intIndex] = InvoiceTotal
}
}
else
{
MessageBox.Show(
"Subtotal must be greater than 0 and less than 10,000.",
"Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show(
"Please enter a valid number for the Subtotal field.",
"Entry Error");
}
txtSubtotal.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
string totalstring = "";
foreach (decimal value in decArray)
{
totalstring += value + "\n";
MessageBox.Show(totalstring + "\n", "Order Totals");
}
this.Close();
}
}
}
If you add a count variable to increment your arrays count then you could add more than the one amount. You would also want to allow the array to resize as needed.
decimal[] decArray = new decimal[5];
int _indexCount = 0;
private void btnCalculate_Click(object sender, EventArgs e)
{
...
if (decArray.Count() == _indexCount)
{
var elementHolder = decArray;
decArray = new T[(decArray.Length + 1) * 2];
for (int i = 0; i < elementHolder.Length; i++)
{
decArray[i] = elementHolder[i];
}
}
decArray[_indexCount] = invoiceTotal;
_indexCount++;
}
Something like that should work.
Edit:
Reason you get so many Messages is because the MessageBox.Show() is inside the foreach loop just put it outside the loop and you will only see one.
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
string totalstring = "";
foreach (decimal value in decArray)
{
totalstring += value + "\n";
}
MessageBox.Show(totalstring + "\n", "Order Totals");
this.Close();
}
You are never assigning to your decArray (e.g. decArray[0] = n;)

matching characters in strings in visual C#

I'm working on visual C#
to calculate the word error rate
I have one textbox for the refrence which is the correct sentance
and one for the hypothesis which is wrong one.
in order to calculate WER I need to calculate :
substitution : the word that has been changed which was my first question
Insert : the words that had been inserted in the sentence
Deleted: the words that had been deleted from the original sentence
For EX:
refrence: This is a NPL program.
hypothesis: it is an NPL cool.
it: substitution
is: correct
an :substitution
NPL:correct
program: deleted
cool: inserted
I tried the algorithm that dasblinkenlight proposed ( thank you so much by the way )
I worked but there is a runtime error I couldn't figure it out, in line
int x= Compute(buffer[j], buffer_ref[i]);
Index was outside the bounds of the array.
and here is my code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string [] hyp = new string[20];
string [] refrence = new string[20];
string [] Anser= new string[20];
string[] buffer = new string[20];
string[] buffer_ref = new string[20];
int count = 0; // number of words
string ref2=" " ;
string hyp2 = " ";
string Anser2 = " ";
string buffer2 = " ";
int corecct_c=0;
int corecct_d = 0;
int corecct_i = 0;
//====================================================================
public Form1()
{
InitializeComponent();
for (int i = 0; i <= 19; ++i)
{
hyp[i] = null;
buffer[i] = null;
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
refrence = this.textBox2.Text.Split(' ');
buffer_ref = this.textBox2.Text.Split(' ');
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
hyp = this.textBox1.Text.Split(' ');
buffer = this.textBox1.Text.Split(' ');
//hyp = this.textBox1.Text;
// fname1.Add(this.textBox1.Text);
}
public void correct(string[] R)
{
for (int i = 0; (i <= 19) && (R[i] != "."); ++i)
{
if (buffer[i] == refrence[i])
{ buffer[i] = "0";
buffer_ref[i] = "0";
corecct_c = corecct_c + 1;
Anser[i] = "C";
}
}
}
// function that compute 2 strings
public static int Compute(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
public void sub(){
for (int j = 0;j<=19;j++)
{
if (buffer[j].IndexOf("0") != -1)
{
for (int i = 0; i <= 19; i++)
{
if (buffer_ref[j].IndexOf("0") != -1)
{
int x= Compute(buffer[j], buffer_ref[i]);
if (x > 3)
{
buffer[j] = "0";
Anser[j] = "S";
}
}//end if
}
}//end if
}//end for
}// end fun
private void button1_Click(object sender, EventArgs e)
{
correct(refrence);
sub();
for (int i = 0; (i <= 19) && (refrence[i] != "."); ++i)
{
//loop intialize
ref2 = ref2 + " " + refrence[i];
hyp2 = hyp2 + " " + hyp[i];
Anser2 = Anser2 + " " + Anser[i];
buffer2 = buffer2 + " " + buffer[i];
count++;
}
listBox1.Items.Add(" Refrence :" + ref2);
listBox1.Items.Add(" HYp :" + hyp2);
listBox1.Items.Add(" Anser:" + Anser2);
listBox1.Items.Add(" buffer:" + buffer2);
listBox1.Items.Add(count);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
can you help me please ?
There is a built-in way to test if two lines are identical, but there is no built-in way to tell if two lines are similar. You need to implement an algorithm that measures string similarity, such as the Levenshtein Distance - a very common Edit Distance algorithm. Lines with small edit distance can be declared similar depending on some threshold specific to your requirements.
You'll need to use an algorithm that compares the "distance" between two strings:
The closeness of a match is measured in terms of the number of
primitive operations necessary to convert the string into an exact
match. This number is called the edit distance between the string and
the pattern. The usual primitive operations are:
insertion: cot → coat
deletion: coat → cot
substitution: coat → cost

How to compare 2 character strings?

I am making a typing game and I need to compare a generated string and input string character by character to and then calculate % accuracy.
But it seems am missing something because the function does no compare well.
Am I doing something wrong ?
private void Button_Click(object sender, RoutedEventArgs e)
{
int percentage = 0;
int mistakes = 0;
string input = TextBox1.Text;
string letter = TextBox2.Text;
char[] letters1 = letter.ToCharArray();
char[] input1 = input.ToCharArray();
for (int j = 0; j < input1.Length; j++)
{
if (input1[j] != letters1[j])
mistakes = mistakes +1;
else if (input1[j] == letters1[j])
mistakes = mistakes;
}
percentage = 100 - ((mistakes / letters1.Length) * 100);
Label2.Content = percentage;
}
You're performing integer arithmetic and losing the fractional portion of the result of your division. When you divide two integers, the result is another integer (and you lose the fractional part).
percentage = 100 - ((mistakes / letters1.Length) * 100);
Given your code above, and assuming letters1 is 30 characters long and there are 20 mistakes, then 20 / 30 (or any amount of mistakes from the total characters available, except when every character is wrong), will result in:
percentage = 100 - ((20 / 30) * 100);
// 100 - ((0) * 100) == 100
Converting one of those values to a double should retain the fractional portion of the division:
percentage = 100 - ((mistakes / Convert.ToDouble(letters1.Length) * 100);
// = 100 - ((20 / 30.0) * 100) == 100 - ((0.6666666) * 100) == 33.333333
Hope this works for you.
private void Button_Click(object sender, RoutedEventArgs e)
{
float percentage = 0;
float mistakes = 0;
string input = TextBox1.Text;
string letter = TextBox2.Text;
char[] letters1 = letter.ToCharArray();
char[] input1 = input.ToCharArray();
for (int j = 0; j < input1.Length; j++)
{
if (input1[j] != letters1[j])
{
mistakes++;
}
}
percentage = 100 - ((mistakes / letters1.Length) * 100);
Label2.Content = percentage.ToString();
}

Resources