Unit Test in c# ,data from .csv file - c#

My test function as follows:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
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.Collections;
namespace ex4
{
[TestClass]
public class UnitTest1
{
public double result = 0.0;
computation co = new computation();
public void valuereq()
{
Stream myStream = null;
var openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = #"C:\Users\Hassan Qamar\Desktop\share market research paper\experiment folder";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
string path = openFileDialog1.FileName;
var readstream = new StreamReader(myStream);
readstream.Close();
string[] datatoprint = File.ReadAllLines(#path);
result = co.LaggedCorrelation(datatoprint);
Console.WriteLine(result);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(9.8,result,0.5);
}
}
}
I am extracting value from .csv file and passing it for computation.
The expected result should be 9.6 approx. But while testing it showing 0 in assert function.
Computation class as follows:
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Collections;
namespace ex4
{
public class computation
{
Form1 f = new Form1();
public double output;
public double LaggedCorrelation(string[] datatoprint)
{
List<double> laggedCorrelation = new List<double>();
int cond = 0;
double n = datatoprint.Length - 1;//removing header row
double xsum = 0.0, ysum = 0.0, x = 0.0, y = 0.0, xy = 0.0, xsquare = 0.0, ysquare = 0.0;
// while (cond < 2)
// {
// double output = 0.0;
double numerator = 0.0, denominator = 0.0;
foreach (var l in datatoprint.Skip(1))
{
string[] s = l.Split(',');
x = Convert.ToDouble(s[cond]); y = Convert.ToDouble(s[cond +1]);
xsum += x; ysum += y;
xy += x * y;
xsquare += x * x; ysquare += y * y;
}
cond++;
numerator = (n * (xy)) - (xsum * ysum);
denominator = (Math.Sqrt(n * xsquare - xsum * xsum)) * (Math.Sqrt(n * ysquare - ysum * ysum));
output = numerator / denominator;
laggedCorrelation.Add(output);
return output;
}
}
}
Computation function give the lagged correlation between 2 given stock.when I work without testing I get the value as required otherwise in test function.
Output remain 0.

You are not calling the valuereq() method inside your Test Method. So it is taking the initial value which is 0 as you assigned on the top public double result = 0.0;
Anyway, try this
[TestMethod]
public void TestMethod1()
{
valuereq();
Assert.AreEqual(9.8,result,0.5);
}
By the way, you don't have to rewrite the actual method in TestClass, all you have to do is create an object of the actual class contains your actual method, and call it inside your TestMethod.
Edit: Assert.AreEqual method should take two parameters result and your expected result, in your case 9.6. So it must be Assert.AreEqual(9.6,result); to get your unit test pass.

The result is 0.0 because you never modify it from the initialized value.
public double result = 0.0; // <-- never changes again.
More plainly you never use what you're testing.
Generally, you want to write a unit test something like this:
[TestMethod]
public void AssertFooHasAWidget() {
// Setup
var foo = new Foo(); // or better, mocking a Foo
// Act
foo.giveWidget();
// Assert
Assert.IsTrue(foo.hasWidget());
}
Other notes:
The input to your test doesn't need to change. If it does, then you don't know if a later success (or failure) is because of the change in input, or a breaking (or fixing!) change in your code.

Related

I try to find nearest double in Array

I try to follow the code here:
C# Finding Nearest Number in Array
but fail.
The only different from my code with the code there is in my code the MinBy is error (there is red underline) which show its an error in Visual Studio.
By the way, this is the the code that I write:
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 WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
double[] array = new double[5] { 0.25, 0.4, 0.5, 0.6, 0.7 };
double TargetNumber = Double.Parse(textBox1.Text);
var nearest = array.MinBy(x => Math.Abs((long)x - targetNumber));
label1.Text = nearest.ToString();
}
}
}
Im new with C# things. Sorry for a noob question.
Thanks in advance.
You overcomplicate things. Here is your "bread-and-butter" helper method which finds the value from array a nearest to the passed value d:
private static double? FindNearestValue(IEnumerable<double> arr, double d)
{
var minDist = double.MaxValue;
double? nearestValue = null;
foreach (var x in arr)
{
var dist = Math.Abs(x - d);
if (dist < minDist)
{
minDist = dist;
nearestValue = x;
}
}
return nearestValue;
}
To use it:
private void button1_Click(object sender, EventArgs e)
{
double[] array = new double[5] { 0.25, 0.4, 0.5, 0.6, 0.7 };
double TargetNumber = Double.Parse(textBox1.Text);
var nearest = FindNearestValue(array, TargetNumber);
label1.Text = nearest.ToString(); // nulls are printed as empty string
}
For small arrays linear search has comparable speed to the binary search. If implementing binary search is problem for you and you're new to c# (didn't get used to LINQ power) then good-ol' foreach is your friend for now.
Sometimes implementing a library to use just one method sounds a little bit like an overkill (even if MoreLINQ is an amazing library)... this code should provide you the same result without using an external library, if it's a good solution for you:
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 WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Double[] array = new Double[] { 0.25, 0.4, 0.5, 0.6, 0.7 };
Double targ = Double.Parse(textBox1.Text);
Double[] arraySorted = array.OrderBy(x => Math.Abs(x - targ)).ToArray();
Int32 idx = Array.IndexOf(array,arraySorted.First());
label1.Text = idx.ToString();
Double arrayValue = array[idx];
Int32 idxLower = 0;
Int32 idxUpper = 0;
if (targ == arrayValue)
idxLower = idxUpper = idx;
else
{
if (targ > arrayValue)
{
idxLower = idx;
idxUpper = idx + 1;
}
else
{
idxLower = idx - 1;
idxUpper = idx;
}
}
label2.Text = idxLower.ToString();
label3.Text = idxUpper.ToString();
}
}
}

Object calculating validation C#

My goal is to make this program to take a number of pizzas and types of pizzas and count how much they cost. I decided to go with an object solution. The problem is it doesn't calculate it and it lets the program run even when The fields are empty. I literally have no idea why it doesn't calculate it. I'm also new to objects so there may be some logical mistakes.
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 Assignment_2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void OrderButton_Click(object sender, EventArgs e)
{
double withTax = 0;
double tax = 0;
double subTotal = 0;
var pizzas = new Pizza[3];
if(ValidateAndDeclareQuantities())
{
pizzas = Declare();
subTotal = CalcSubTotal(pizzas);
tax = CalcTax(pizzas);
withTax = CalcWithTax(pizzas);
}
}
bool ValidateAndDeclareQuantities()
{
var combolist = new List<ComboBox>();
combolist.Add(comboBox1);
combolist.Add(comboBox2);
combolist.Add(comboBox3);
var textboxlist = new List<TextBox>();
textboxlist.Add(Quantity1);
textboxlist.Add(Quantity2);
textboxlist.Add(Quantity3);
for (int i = 0; i < 3; i++)
{
if (combolist[i].Text == "Cheese" || combolist[i].Text == "Vegetable" || combolist[i].Text == "Meat")
{ }
else combolist[i].Text = "Wrong input";
}
int[] Quantities = new int[3];
for (int i = 0; i < 3; i++)
{
if (int.TryParse(textboxlist[i].Text, out Quantities[i])&&textboxlist[i].Text!=null)
{ }
else { textboxlist[i].Text = "Wrong input"; }
}
return true;
}
Pizza[] Declare()
{
var pizzas = new Pizza[3];
string type;
int price;
type = comboBox1.Text;
price = int.Parse(Quantity1.Text);
Pizza pizza1 = new Pizza(type, price);
pizzas[0] = pizza1;
type = comboBox2.Text;
price = int.Parse(Quantity2.Text);
Pizza pizza2 = new Pizza(type, price);
pizzas[1] = pizza2;
type = comboBox3.Text;
price = int.Parse(Quantity3.Text);
Pizza pizza3 = new Pizza(type, price);
pizzas[2] = pizza3;
return pizzas;
}
double CalcSubTotal(Pizza[] pizzas)
{
double subTotal = 0;
for (int i = 0; i < 3; i++)
{
subTotal += pizzas[i].Price;
}
return subTotal;
}
double CalcTax(Pizza[] pizzas)
{
double tax = 0;
for (int i = 0; i < 3; i++)
{
tax += pizzas[i].Tax;
}
return tax;
}
double CalcWithTax(Pizza[] pizzas)
{
double withTax = 0;
for (int i = 0; i < 3; i++)
{
withTax += pizzas[i].WithTax;
}
return withTax;
}
void WriteOut(double subTotal, double tax, double withTax)
{
lblSubTotal.Text = "" + subTotal;
lblTax.Text = "" + tax;
lblTotal.Text = "" + withTax;
}
}
}
And the class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_2
{
class Pizza
{
string type;
int quantity;
public double Price;
public double SubTotal;
public double Tax;
public double WithTax;
public Pizza(string type, int quantity)
{
this.type = type;
this.quantity = quantity;
FindPrice();
CalcSubTotal();
CalcTax();
CalcWithTax();
}
private void FindPrice()
{
switch (type)
{
case "Cheese":
Price = 9.95;
break;
case "Vegetables":
Price = 10.95;
break;
case "Meat":
Price = 11.95;
break;
}
}
private void CalcSubTotal()
{
SubTotal = Price * quantity;
}
private void CalcTax()
{
Tax = SubTotal * 0.13;
}
private void CalcWithTax()
{
WithTax = SubTotal + Tax;
}
}
}
Solution form
The quick answers:
ValidateAndDeclareQuantities never returns false. It should (probably) return false when you set "Wrong Input".
(Minor) int[] Quantities = new int[3]; is never used, aside from writing to it.
(Minor) var pizzas = new Pizza[3]; is also never used. It just gets overwritten by Declare a few lines later. Pizza[] pizzas=null; or just Pizza[] pizzas; is a better alternative. Not the greatest structure here though.
(Minor) Your variable called price in Declare is poorly named as it appears to actually be quantity. Things like this easily throw people off.
WriteOut is never called. withTax, tax and subTotal in OrderButton_Click are probably being computed correctly, but the values aren't being outputted.
The longer answer
It's a bit on the messy side! I appreciate that it's just a learning thing - we've all been there - but good code hygiene is just as important (if not more important) than the structure of the language.
UX: Don't overwrite what the user entered - specifically, don't replace the textbox input with "wrong input"; That's better off going on some other label. I would imagine you've already felt how weird this kind of experience is whilst testing the code.
Named things that don't need a specific class: Like a cheese pizza and a ham one. Enums are your friend! Use them instead of strings like "Cheese":
public enum PizzaType{
Cheese,
Tomato
}
Using enums in this way helps avoid the wonderful world of pain that is unexpected capitalisation and it's considerably faster too. CheEse pizza anyone?
Repetition: Large portions of your code are repetitive too; You'll want to practice avoiding it as much as you can. ('DRY'/ 'Don't Repeat Yourself'). A little forward planning helps massively. Everybody has preferences on code structure; mine here would be a separate "Pizza displayer" class which holds a quantity input box and does the validation too.
Junk: Slightly related to the above, you're creating a bunch of Lists and arrays which get created each time the function is called and then are just chucked out. Create a single array of some more abstract type (like an array of "Pizza displayers") and keep that array as a property on the Form. It's minor here, but being more aware of how much trash your program creates helps make your code go faster.
Notes on floats: You should never, ever use float/ double for money. Use decimal instead, or just do everything in pennies. Floating points aren't precise and you'll hit a rounding issue sooner or later.

Vector folding using Divide et Impera in c#

I'm in trouble on a College project.The project needs to be done using c# as a programming language and made in Windows Form like.
The program executes. I know it has flaws but at least i want to know how to get of this error: http://postimg.org/image/gwuzmyc73/ .
For the problem i need to fold a vector using the Divide et Impera.
I need to insert a number from the keyboard n, the generated vector would be like a=(1,2,3,4,5,6,7) and the final elements are 1,3,5,7.
The problem sounds like:
A vector of n elements.We define its folding by overlaping the 2 halfs,if n is odd.The 2 halfs are folded again until de subvector reaches 1 element.Utilize Divide et Impera.
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 Plierea_Vectorilor
{
public partial class Form1 : Form
{
public int n;
public int i;
public int[] efinal = new int[50];
public string m = new string(new char[50]);
public int Ls, Ld;
public char[] aux = new char[50];
public Form1()
{
InitializeComponent();
}
public void Pliaza(int p,int q)
{
if (p == q)
{
efinal[p] = 1;
}
else
{
if ((q - p + 1) % 2 != 0)
{
Ls = (p + q) / 2 - 1;
}
else
{
Ls = (p + q) / 2;
}
Ld = (p + q) / 2 + 1;
}
Pliaza(p, Ls);
Pliaza(Ld, q);
/*
string ss = Ls.ToString();
string sd = Ld.ToString();
for (i = p; i <= Ls; i++)
{
aux[0] = 'S';
string.Concat(aux, ss);
string.Concat(aux, " ");
string m = aux.ToString();
string.Concat(aux, m[i]);
}
for ( i = Ld; i <= q; i++)
{
aux[0] = 'D';
string.Concat(aux,Ld);
string.Concat(aux, " ");
string m = aux.ToString();
string.Concat(aux, m[i]);
}
*/
}
private void button1_Click(object sender, EventArgs e)
{
Pliaza(1, n);
for (i = 1; i <= n; i++)
{
if (efinal[i]!=0)
{
label2.Text = Convert.ToString(i);
}
}
}
private void label2_Click(object sender, EventArgs e)
{
}
}
}
You're ALWAYS executing the Pliaza function FROM Pliaza. Aren't you missing a finish condition?
The recursive loop must be finished sometime in someway, else you will get that stack overflow.
A StackOverflowException usually means you have uncontrolled recursion going on. Reviewing your code, I see that Pliaza calls itself twice, using different variables ... but there is no path for Pliaza to exit without calling itself. You need some path to let the recursion bottom out. Very likely this would be to add a return; statement after the efinal[p] = 1; line.

Store the outcome of an algorithm that looks for prime numbers in a file (C#)

I am trying to make a program that looks for prime numbers, displays them in the console and stores the numbers in a file. The program already stores the numbers in a file, but it doesn't display the numberrs in the console. Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Priemgetallen
{
class Program
{
static void Main()
{
using (StreamWriter writer = new StreamWriter("C://Users//mens//Documents//PriemGetallen.txt"))
{
Console.SetOut(writer);
Act();
}
}
static void Act()
{
double maxGetal = double.MaxValue;
Console.WriteLine("--- Primes between 0 and 100 ---");
for (int i = 0; i < maxGetal; i++)
{
bool prime = PrimeTool.IsPrime(i);
if (prime)
{
Console.Write("Prime: ");
Console.WriteLine(i);
}
}
}
public static class PrimeTool
{
public static bool IsPrime(int candidate)
{
// Test whether the parameter is a prime number.
if ((candidate & 1) == 0)
{
if (candidate == 2)
{
return true;
}
else
{
return false;
}
}
// Note:
// ... This version was changed to test the square.
// ... Original version tested against the square root.
// ... Also we exclude 1 at the end.
for (int i = 3; (i * i) <= candidate; i += 2)
{
if ((candidate % i) == 0)
{
return false;
}
}
return candidate != 1;
}
}
}
}
That's because of the line Console.SetOut(writer);. You are sending console output to the file.
Rather than do it the way you are, ditch the StreamWriter and instead use:
if (prime)
{
var primeText = string.Format("Prime: {0}", i);
Console.WriteLine(primeText );
File.AppendAllText(#"C:\Users\mens\Documents\PriemGetallen.txt",
primeText + Environment.NewLine);
}

Why can't I find Sum() of this HashSet. says "Arithmetic operation resulted in an overflow."

I was trying to solve this problem projecteuler,problem125
this is my solution in python(just for understanding the logic)
lim = 10**8
total=0
found= set([])
for start in xrange(1,int(lim**0.5)):
s=start**2
for i in xrange(start+1,int(lim**0.5)):
s += i**2
if s>lim:
break
if str(s) == str(s)[::-1]:
found.add(s)
print sum(found)
the same code I wrote in C# is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
public static bool isPalindrome(string s)
{
string temp = "";
for (int i=s.Length-1;i>=0;i-=1){temp+=s[i];}
return (temp == s);
}
static void Main(string[] args)
{
int lim = Convert.ToInt32(Math.Pow(10,8));
var found = new HashSet<int>();
for (int start = 1; start < Math.Sqrt(lim); start += 1)
{
int s = start *start;
for (int i = start + 1; start < Math.Sqrt(lim); i += 1)
{
s += i * i;
if (s > lim) { break; }
if (isPalindrome(s.ToString()))
{ found.Add(s); }
}
}
Console.WriteLine(found.Sum());
}
}
}
the code debugs fine until it gives an exception at Console.WriteLine(found.Sum()); (line31). Why can't I find Sum() of the set found
The sum is: 2,906,969,179.
That is 759,485,532 greater than int.MaxValue;
Change int to long in var found = new HashSet<long>(); To handle the value.
You can also use uint however instead of long, however I would recommend using long.

Categories

Resources