I'm developing a programme to manipulate costs history and eventually a prediction.
The problem I've faced is that I want to calculate modifiers which will be use on the costs history to remove season variance. I need two diffent ways to calculate them and those two are nearly the same except places where it will be a multiplication instead of an addition.
An example would be :
private void CalculAndSumEveryPeriodeModifier()
{
List<double> averages = MovingAverage.Averages;
for (int i = 0; i < averages.Count; ++i)
{
averages[i] = costsList[i + NbPeriode / 2] / averages[i] // Division changed to substraction
modifiers[((i + NbPeriode / 2) % NbPeriode)] += averages[i];
}
}
I've made an attempt with an abstract class having a private abstract method that takes two doubles. The concrete classes can then implement this method to divide or subtract the doubles at certain points in the algorithm.
The problem with this approach is that I don't know how to unit test it. Can I test the abstract class with the moq framework if yes how? Else I need to test both concrete class which will duplicate code since the tests will be the same.
Is there a way to unit test my attempt or is there a better approach?
Kevin
Why not factor out the common code of the two unit test methods into a shared method?
private int[] input = new int[] { 2, 8, 6, 1, 5, 1, 7, 5, 2, 4 };
[TestMethod]
public void TestVariantA()
{
var obj = new ConcreteA();
DoTest(obj, input, new int[] { -2.8, 3, 1.4, -3.2, 1 });
}
[TestMethod]
public void TestVariantB()
{
var obj = new ConcreteB();
DoTest(obj, input, new int[] { 0.2632, 1.7500, 1.3397, 0.2381, 1.2500 });
}
private void DoTest(AbstractType obj, int input, int expected)
{
...
}
Related
using System;
namespace reverse
{
class Program
{
static void Main(string[] args)
{
int[] a = new int [10];
for (int i= 0; i<a.Length; i++)
{
a[i] = int.Parse(Console.ReadLine());
}
}
}
}
here I can get values from a user by pressing enter key after each time i give the value but I want to give value as a whole with comma. Thanks!
I would suggest to gradually step towards functional programming.
Why?
Weel, with words from Eric Lippert from "Functional programming for beginners"
I will talk about the “why” a little bit, but basically it boils down to
a great many bugs are caused by bad mutations.
By taking a page
from functional style and designing programs so that variables and
data structures change as little as possible, we can eliminate a
large source of bugs.
Structuring programs into small functions
whose outputs each depend solely on inputs
makes for programs that
are easy to unit test.
the ability to pass functions as data
allows us to create new and interesting control flows and patterns,
like LINQ.
Rewriting your code
Use Linq in a single and simple line:
int [] res =
Console.ReadLine () // read the input
.Split (',') // transform it into an array
.Take (10) // consider only the first 10 strings
.Select (int.Parse) // transform them into int
.ToArray (); // and finally get an array
You can add a check after the Split and before Take:
.Where (d => {int t; return int.TryParse (d, out t);}).Take
Try this one and read comments to get more info :
static void Main()
{
string input = Console.ReadLine(); // grab user input in one whole line
string[] splitted = input.Split(','); // split user input by comma sign ( , )
int[] a = new int[splitted.Length]; // create a new array that matches user input values length
for(int i = 0; i < splitted.Length; i++) // iterate through all user input values
{
int temp = -1; // create temporary field to hold result
int.TryParse(splitted[i], out temp); // check if user inpu value can be parsed into int
a[i] = temp; // assign parsed int value
}
}
This method will ensure that program will execute even if user wont input numerics. For example if user input will be :
1 , 2,3,45,8,9898
The output will be :
{ 1, 2, 3, 45, 8, 9898 }
But if the input will be :
1,adsadsa,13,4,6,dsd
The output will be :
{ 1, 0, 13, 4, 6, 0 }
I'm trying to solve a problem on code wars and the unit tests provided make absolutely no sense...
The problem is as follows and sounds absolutely simple enough to have something working in 5 minutes
Consider a sequence u where u is defined as follows:
The number u(0) = 1 is the first one in u.
For each x in u, then y = 2 * x + 1 and z = 3 * x + 1 must be in u too.
There are no other numbers in u.
Ex: u = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]
1 gives 3 and 4, then 3 gives 7 and 10, 4 gives 9 and 13, then 7 gives 15 and 22 and so on...
Task:
Given parameter n the function dbl_linear (or dblLinear...) returns the element u(n) of the ordered (with <) sequence u.
Example:
dbl_linear(10) should return 22
At first I used a sortedset with a linq query as I didnt really care about efficiency, I quickly learned that this operation will have to calculate to ranges where n could equal ~100000 in under 12 seconds.
So this abomination was born, then butchered time and time again since a for loop would generate issues for some reason. It was then "upgraded" to a while loop which gave slightly more passed unit tests ( 4 -> 8 ).
public class DoubleLinear {
public static int DblLinear(int n) {
ListSet<int> table = new ListSet<int> {1};
for (int i = 0; i < n; i++) {
table.Put(Y(table[i]));
table.Put(Z(table[i]));
}
table.Sort();
return table[n];
}
private static int Y(int y) {
return 2 * y + 1;
}
private static int Z(int z) {
return 3 * z + 1;
}
}
public class ListSet<T> : List<T> {
public void Put(T item) {
if (!this.Contains(item))
this.Add(item);
}
}
With this code it still fails the calculation in excess of n = 75000, but passes up to 8 tests.
I've checked if other people have passed this, and they have. However, i cannot check what they wrote to learn from it.
Can anyone provide insight to what could be wrong here? I'm sure the answer is blatantly obvious and I'm being dumb.
Also is using a custom list in this way a bad idea? is there a better way?
ListSet is slow for sorting, and you constantly get memory reallocation as you build the set. I would start by allocating the table in its full size first, though honestly I would also tell you using a barebones array of the size you need is best for performance.
If you know you need n = 75,000+, allocate a ListSet (or an ARRAY!) of that size. If the unit tests start taking you into the stratosphere, there is a binary segmentation technique we can discuss, but that's a bit involved and logically tougher to build.
I don't see anything logically wrong with the code. The numbers it generates are correct from where I'm standing.
EDIT: Since you know 3n+1 > 2n+1, you only ever have to maintain 6 values:
Target index in u
Current index in u
Current x for y
Current x for z
Current val for y
Current val for z
public static int DblLinear(int target) {
uint index = 1;
uint ind_y = 1;
uint ind_z = 1;
uint val_y = 3;
uint val_z = 4;
if(target < 1)
return 1;
while(index < target) {
if(val_y < val_z) {
ind_y++;
val_y = 2*ind_y + 1;
} else {
ind_z++;
val_z = 3*ind_z + 1;
}
index++;
}
return (val_y < val_z) ? val_y : val_z;
}
You could modify the val_y if to be a while loop (more efficient critical path) if you either widen the branch to 2 conditions or implement a backstep loop for when you blow past your target index.
No memory allocation will definitely speed your calculations up, even f people want to (incorrectly) belly ache about branch prediction in such an easily predictable case.
Also, did you turn optimization on in your Visual Studio project? If you're submitting a binary and not a code file, then that can also shave quite a bit of time.
I am writing a cards game, and need to draw random cards from pile. I am using Random and Random.Next(..) for that.
Now I want to debug my application, and want to be able to reproduce certain scenarios by using the same Random sequence.
Can anyone help...? I couldn't find an answer over several searches.
Thanks.
Use the overload of the Random constructor which accepts a seed value
static Random r = new Random(0);
This will produce the same sequence of pseudorandom numbers across every execution.
You will need to seed your random number generator. Assuming you're using System.Random, use
Random r = new Random(<some integer>);
which starts the sequence at <some integer>.
But an important note here: you will need to research your random number generator carefully. Else it will be possible to decipher your sequence which will make playing your game unintentionally profitable for an astute user. I doubt you'll be using Random once you pass to production. (Technically it's possible to decipher a linear congruential sequence - which is what C# uses - in a little over three drawings.)
Create a System.Random instance with the same seed:
Random random = new System.Random(1337);
Use the same seed in Random constructor. That guarantee you that Next() will give the same results. For example
Random randomGen1 = new Random(5);
Random randomGen2 = new Random(5);
int r1 = randomGen1.Next();
int r2 = ramdomGen2.Next();
if(r1 == r2)
{
Console.WriteLine("Great success!!");
}
Possibly a bit of overkill for this case (using a seed will give you repeatability) but a good shape for dealing with dependencies over which you do not have full control is to wrap the dependency and access it through an interface. This will allow you to swap in a version that gives specified behaviour for unit testing/ debugging.
e.g.
public interface IRandom {
int Get();
}
public class DefaultRandom : IRandom {
private readonly Random random;
public DefaultRandom() {
random = new Random();
}
public int Get() {
return random.Next();
}
}
public class TestRandom : IRandom {
private readonly List<int> numbers;
private int top;
public TestRandom() {
numbers = new List<int> {1, 1, 2, 3, 5, 8, 13, 21};
top = 0;
}
public int Get() {
return (top >= numbers.Count)
? 0
: numbers[top++];
}
}
One of the nice aspects of this method is that you can use specific values (say, to test edge cases) which might be hard to generate using a fixed seed value.
I have one data source like -4,-3,-3,-2,-1,0,1,2,2,3,4 , I have one function and this function can capture repeated number for example in this data source we have -3,2 are repeated .The repeated numbers are reported in end of the program.
I couldn't find good example(I spent 3 hours).
How can I implement a unit test with NUnit that can be test the same situation and it tells me the results, if you have some example , It will be very useful to me.(Really appreciated).
You can use TestCase attributes for simple data like what you've described.
[Test]
[TestCase(new[] { -4, -3, -3, -2, -1, 0, 1, 2, 2, 3, 4 }, new []{-3,2})]
public void YourTest(int[] given, int[] expected)
{ ... }
Note: ReSharper (at least my version of it) doesn't honor multiple test cases like this one so I had to confirm multiple test cases with the NUnit GUI.
First things first - get a working test. Something like this:
[Test]
public void DetectsMinusThreeAndTwo()
{
RepeatingDigitsDetector target = new RepeatingDigitsDetector();
int[] source = new int[] { -4, -3, -3, -2, -1, 0, 1, 2, 2, 3, 4 };
int[] expected = new int[] { -3, -2 };
int[] actual = target.GetRepeats(source);
Assert.AreEqual(expected.Length, actual.Length, "checking lengths");
for (int i = 0; i < expected.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "checking element {0}", i);
}
}
Later, you can start adding in goodies like the TestCase or TestCaseSource attributes. But if you're trying to do TDD (as the tdd tag implies), you need to start with a test.
I would recommend TestCaseSource in this instance. Several tests could make the data harder to read inside the TestCase attribute.
As your test data gets complex, it will be difficult to handle.
Consider storing your data in another source such as excel, json or Database.
I personally like storing test data in embedded json files.
The package JsonSectionReader provides good support for this.
We need to make some small program for school that rolls 5 dices and see if you get a three of a kind with it, if so, increase points etc.
The problem isnt to reading out the dice, I have the knowledge to get it done, but I want it to be a little efficient, not a ugly piece of code that takes up half a page. I have found ways to filter out the the duplicates in an array, but not the other way around. It rolls with 5 dices, so its an array with 5 numbers, is there like a built in function or a nice, efficient way of returning the number that has been rolled three times or return null if none of the number are rolled three times?
Hope anyone can push me in the right direction. :)
You can do it easily and succinctly with LINQ:
var diceRolls = new[] {1, 3, 3, 3, 4};
var winningRolls = diceRolls.GroupBy(die => die).Select(groupedRoll => new {DiceNumber = groupedRoll.Key, Count = groupedRoll.Count()}).Where(x => x.Count >= 3).ToList();
What this is doing is grouping the rolls by the roll number ("Key") and the count of occurrences of that roll. Then, it's selecting any rolls that have a count greater than or equal to 3. The result will be a List containing your winning rolls.
One approach is to store a 6-element array containing the count of how many dice have that face. Loop through the 5 dice and increment the appropriate face's total count.
var rolls = new List<Roll>();
// run as many rolls as you want. e.g.:
rolls.Add(new Roll(5));
var threeOfAKindRolls = rolls.Where(r => r.HasThreeOfAKind());
public class Roll
{
public Roll( int diceCount )
{
// Do your random generation here for the number of dice
DiceResults = new int[0]; // your results.
ResultCounts = new int[6]; // assuming 6 sided die
foreach (var diceResult in DiceResults)
{
ResultCounts[diceResult]++;
}
}
public int[] DiceResults { get; private set; }
public int[] ResultCounts { get; private set; }
public bool HasThreeOfAKind()
{
return ResultCounts.Any(count => count >= 3);
}
}
This code can be shortened somewhat if you don't need the result counts to perform other tests on the results:
public Roll( int diceCount )
{
// Do your random generation here for the number of dice
DiceResults = new int[0]; // your results.
}
public bool HasThreeOfAKind()
{
ResultCounts = new int[6]; // assuming 6 sided die
foreach (var diceResult in DiceResults)
{
// Increment and shortcut if the previous value was 2
if( (ResultCounts[diceResult]++) == 2) return true;
}
return false;
}
Given what you are describing your answer as looking like it sounds like you're trying to do a massive comparison. That's the wrong approach.
Pretend it's 20 dice rather than 5, a good answer will work just as well in a larger case.
I would use something like the following:
public int? WinningRoll(IEnumerable<int> rolls)
{
int threshold = rolls.Count() / 2;
var topRollGroup = rolls.GroupBy(r => r)
.SingleOrDefault(rg => rg.Count() > threshold);
if (topRollGroup != null)
return topRollGroup.Key;
return null;
}
This will work with any number of rolls, not just 5, so if you had 10 rolls, if 6 of them were the same value, that value would be returned. If there is no winning roll, null is returned.