I'm playing around with Code Contracts at the moment and I'm not completely sure whether the static methods of the Contract class are powerful enough to compete with mathematical notation of conditions.
Let's assume we got a simple factorial method
int Factorial(int n);
I would express the following conditions:
Precondition:
n >= 0
Postconditions:
Factorial(n) = 1, in case n = 0
Factorial(n) = n*(n-1)*...*1, in case n > 0
These conditions clearly specify the behavior of Factorial in a short and clean way. My question is, whether they can be expressed through Code Contracts.
The precondition is trivial:
Contract.Requires(n >= 0)
The conditional post condition might be expresses using
if(n==0)
Contract.Ensures(Contract.Result<int>() == 1);
if(n > 0)
...
But I don't like the way I need the "if" statement here as it makes the plain list of pre- and postconditions harder to read. I hoped we would have something like
Contract.Ensures(...).InCase(...);
And last but not least, I do not have any idea how to express this, which is a common notation regarding math:
n*(n-1)*...*1
Guess I would need some kind of loop, but this would copy the whole implementation. Is there any smart way to express such notations?
Thank you in advance.
What you are looking for are Unit Tests, not Code Contracts.
Tipically, checks like if n=0, then f(n) = 1 and if n=3, then f(n) = 6 are Test Cases that should be expressed as Unit Tests.
In your case, I think a suitable post condition would be something like "The result is always >= 1". And nothing more than that.
Assuming that your factorial class looks something like this:
public class Factorial
{
public int Compute(int n)
{
if (n == 0)
return 1;
return n * Compute(n - 1);
}
}
a suitable Unit Test written with the NUnit Framework would be:
[TestFixture]
public class FactorialTests
{
[TestCase(0, 1)]
[TestCase(1, 1)]
[TestCase(2, 2)]
[TestCase(7, 5040)]
[TestCase(10, 3628800)]
public void Compute_ReturnsCorrectResult(int n, int expectedResult)
{
var sut = new Factorial();
Assert.AreEqual(expectedResult, sut.Compute(n));
}
}
Update (after the comments)
Stating result >= 1 does not fully specify the algorithm.
I don't think the Code Contract's job is to specify the algorithm in detail. the algorithm is specified by the method.
If the Code Contract was a complex piece of logic like the method itself, then I guess we would need a Code Contract Contract to verify that the Code Contract performs the correct checks. This obviously leads to infinite recursion.
I didn't expect n*(n-1)*...*1 to be accepted by the compiler. But some generic range operator in a LINQ-flavoured way would surely be a gread addition, e.g. From(n).To(1).Product() or From(n).To(m).Sum()
If there was such a form of expressing factorials (and probably there is) you could certainly use it in your code, rather than the Code Contracts.
Update 2
Just for fun, I found a LINQ way of computing Factorials:
Enumerable.Range(1, n == 0 ? 1 : n).Aggregate((a, i) => a * i);
You could try to the following:
Contract.Ensures(Contract.Result<int>() == AlternativeFactorial(n));
where AlternativeFactorial is:
[Pure]
public static int AlternativeFactorial(int n)
{
if(n==0)
return 1;
if(n > 0)
{
//Alternative implementation.
}
}
Of course anything you use in a contract should be side-effect free (pure).
Now as far as the factorial implementation, I cannot come up with a more compact "alternative" implementation than w0lf's. What you should consider though is changing the return value of your method from int to BigInteger. Factorials can get very large very quickly. Also note that by adding a post-condition on the factorial value, you will pretty much double the time your method will take to return a result. This can be resolved by building CodeContracts only on the debug configuration.
Related
I was looking how some of the .Net core libraries were implemented and one of many things that caught my eye was that in Dictionary<TKey, TValue> class some numeric comparisons where done doing a casting to (uint) even though at my naive eyes this didn't impacted the logic.
For example on
do { // some magic } while (collisionCount <= (uint)entries.Length);
collisionCount was initialized at 0 and always incremented (collisionCount++) and thus entries being an array its length will not be negative either see source code
as opposed to
if ((uint)i >= (uint)entries.Length) { // some code }
source code line
where i could become negative in some occasions when doing the following, see debug img
i = entry.next;
and thus using it as positive would change the program flow (due to two's complement)
See an extract of the class code:
// Some code and black magic
uint hashCode = (uint)key.GetHashCode();
int i = GetBucket(hashCode);
Entry[]? entries = _entries;
uint collisionCount = 0;
if (typeof(TKey).IsValueType)
{
i--;
do
{
if ((uint)i >= (uint)entries.Length) // <--- Workflow impact
{
goto ReturnNotFound;
}
entry = ref entries[i];
if (entry.hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entry.key, key))
{
goto ReturnFound;
}
i = entry.next;
collisionCount++;
} while (collisionCount <= (uint)entries.Length);
}
// More cool stuffs
Is there any performace gain or what is the reason for this?
The linked Dictionary source contains this comment;
// Should be a while loop https://github.com/dotnet/runtime/issues/9422
// Test in if to drop range check for following array access
if ((uint)i >= (uint)entries.Length)
{
goto ReturnNotFound;
}
entry = ref entries[i];
The uint comparison here isn't faster, but it helps speed up the array access. The linked github issue talks about a limitation in the runtime compiler, and how this loop structure allows further optimisations. Since this uint comparison has been performed explicitly, the compiler can prove that 0 <= i < entries.Length. This allows the compiler to leave out the array boundary test and throw of IndexOutOfRangeException that would otherwise be required.
In other words, at the time this code was written, and performance profiling was performed. The compiler wasn't smart enough to make simpler, more readable code, run as fast as possible. So someone with a deep understanding of the limitations of the compiler tweaked the code to make it better.
I need to write a function to find a product of arithmetic progression elements (using recursion). I have only vague idea how to do it – something like this:
public static int product(int n)
{
if (n == 0)
return 0;
else
return <some code> * product(n-1);
}
Could you at least give me a hint?
The following code should do the trick:
public static int Product(int arithInitial, int arithDifference, int n)
{
if (n == 1)
return GetArithmeticSeriesTerm(arithInitial,arithDifference,1);
else
return GetArithmeticSeriesTerm(arithInitial,arithDifference,n) * Product(arithInitial, arithDifference, n-1);
}
public static int GetArithmeticSeriesTerm(int initial, int difference, int position)
{
return initial+difference*(position-1);
}
I have created a new method to get the elements of the arithmetic progression. I've also changed the base case of the recursion to be n==1 and then put the call to the arithmetic series term.
It should hopefully be pretty self explanatory as to what it does.
For the first four terms of the series 1,3,5,7,... you would call it as
int result = Product(1,2,4)`
Note: You don't need two methods for this but I feel that introducing the second method makes it clearer what the code is doing. You could of course just inline the expression and of course your base case can in fact be simplified to just initial if you wanted to make it a bit cleaner. Using the full method though makes it very intuitive of why we are doing that.
you need to write a function which take 3 arguments first Term(f) , common difference(d) , and total number of term (n) in AP.
int fun(int f,int d,int n){
if(n==0) return 1;
else (f+(n-1)*d) * fun(f,d,n--);
}
EDIT: Originally, this post's example had dealt with hash codes, so you will see some comments using param.GetHashCode(), rather than (1+param). To get more to the point, I have changed the functions to calculate one plus the absolute value of some number.
Let's say that I want to create a function that calculates the absolute value of some integer (without using Math.Abs). I could write something similar to:
int absoluteValueOfOnePlus(int param)
{
int onePlusParam= 1 + param;
return ((onePlusParam> 0) ? (onePlusParam) : (-onePlusParam) );
}
I'm looking to limit the scope of onePlusParm to within the ternary statement--something similar to:
int absoluteValueOfOnePlus(intparam)
{
return (((int onePlusParam = 1 + param) > 0) ? (onePlusParam) : (-onePlusParam) );
}
I understand that this is not valid C#, but it proves a good example for what I'm trying to perform--create some variable which exists only in the scope of a ternary operator.
The parts of a ternary expression are expressions. If the language designers were to allow what you're asking for, they would probably do it for all expressions rather than just for ternary expressions. You would then also be able to do if ((int n = foo()) != 0) bar(n);.
In C#, declarations are statements, not expressions. So the answer is no, you can't do this. However, the for statement can take a declaration, so the closest you can get to a single statement is this:
for (int i = param.GetHashCode();;)
return (i > 0) ? i : -i;
which is technically a single statement, albeit a compound one, and on two lines. But that looks awful code and I wouldn't write it like that.
If your main concern is minimizing the scope of i, then use a small scope for it:
int positiveHash(string param)
{
// Some statements here...
// ...
// Start a small scope
{
int i = param.GetHashCode();
if (...)
return ((i > 0) ? (i) : (-i) );
}
// Some more C# statements here.
// i is out of scope here.
}
I would simply write:
int GetPositiveHash(string param)
{
return Math.Abs(param.GetHashCode());
}
or
int GetPositiveHash(string param)
{
int hashCode = param.GetHashCode();
return Math.Abs(hashCode);
}
The aids readability, maintainability and more importantly in this case avoid premature optimization which is the root of all evil.
If you are really worried about performance then profile you code and see where your biggest bottlenecks are. I'd be surprised if GetPosiitiveHash() is causing the biggest bottleneck.
You might like to have a look at the .Net Framework source code for String.GetHashCode(). You'll see that a ternary operator is going to have quite a minimal saving compared what going on inside the GetHashCode() method.
It's worth remembering:
The full version of the quote is "We should forget about small
efficiencies, say about 97% of the time: premature optimization is the
root of all evil." and I agree with this. Its usually not worth
spending a lot of time micro-optimizing code before its obvious where
the performance bottlenecks are.
from The fallacy of premature optimization
You could substitute having a data variable (i) in scope to having a function variable in scope. The advantage is a function is more likely to be written only once and not likely to be misused.
int positiveHash(string param)
{
Func<int, int> absoluteValue = i => (i > 0) ? i : -1;
return absoluteValue(param.GetHashCode());
}
And my attempt
static int positiveHash(string param)
{
return new List<string>() {param}.Select(s => s.GetHashCode()).Select(i => (i > 0) ? (i) : (-i)).Single();
}
(Of course your code (and mine) is bad,you need to split your method into 2 smaller ones)
and the updated question
static int absoluteValueOfOnePlus(int intparam)
{
return new List<int> { intparam }.Select(n => n + 1).Select(i => (i > 0) ? (i) : (-i)).Single();
}
Besides just creating a new block you could also use the built in Absolute value function Math.Abs(...) or define your own lambda/function;
...built in ...
public static int hash(string param)
{
return Math.Abs(param.GetHashCode());
}
... lambda ...
static Func<int, int> abs = i => i > 0 ? i : -i;
public static int hash(string param)
{
return abs(param.GetHashCode());
}
... static function ...
static int Abs(int i)
{
return i > 0 ? i : -i;
}
public static int hash(string param)
{
return Abs(param.GetHashCode());
}
I am quite new to C# and I was wondering if there is a Class or a data structure or the best way to handle the following requirement...
I need to handle a COUPLE of int that represent a range of data (eg. 1 - 10 or 5-245) and I need a method to verify if an Int value is contained in the range...
I believe that in C# there is a class built in the framework to handle my requirement...
what I need to do is to verify if an INT (eg. 5) is contained in the range of values Eg (1-10) ...
in the case that I should discover that there is not a class to handle it, I was thinking to go with a Struct that contain the 2 numbers and make my own Contain method to test if 5 is contained in the range 1-10)
in the case that I should discover that there is not a class to handle
it, I was thinking to go with a Struct that contain the 2 numbers and
make my own Contain method to test if 5 is contained in the range
1-10)
That's actually a great idea as there's no built-in class for your scenario in the BCL.
You're looking for a range type; the .Net framework does not include one.
You should make an immutable (!) Int32Range struct, as you suggested.
You may want to implement IEnumerable<int> to allow users to easily loop through the numbers in the range.
You need to decide whether each bound should be inclusive or exclusive.
[Start, End) is probably the most obvious choice.
Whatever you choose, you should document it clearly in the XML comments.
Nothing exists that meets your requirements exactly.
Assuming I understood you correctly, the class is pretty simple to write.
class Range
{
public int Low {get; set;}
public int High {get; set;}
public bool InRange(int val) { return val >= Low && val <= High; }
}
A Tuple<int,int> would get you part of the way but you'd have to add an extension method to get the extra behavior. The downside is that the lower- and upper-bounds are implicitly Item1 and Item2 which could be confusing.
// written off-the-cuff, may not compile
public static class TupleExtension
{
public static bool InRange(Tuple<int, int> this, int queryFor)
{
return this.Item1 >= queryFor && this.Item2 <= queryFor;
}
}
You could create an extension if you want to avoid making a new type:
public static class Extensions
{
public static bool IsInRange(this int value, int min, int max)
{
return value >= min && value <= max;
}
}
Then you could do something like:
if(!value.IsInRange(5, 545))
throw new Exception("Value is out of range.");
i think you can do that with an array.
some nice examples and explanation can be found here:
http://www.dotnetperls.com/int-array
Nothing built in AFAIK, but (depending on the size of the range) an Enumerable.Range would work (but be less than optimal, as you're really storing every value in the range, not just the endpoints). It does allow you to use the LINQ methods (including Enumerable.Contains), though - which may come in handy.
const int START = 5;
const int END = 245;
var r = Enumerable.Range(START, (END - START)); // 2nd param is # of integers
return r.Contains(100);
Personally, I'd probably go ahead and write the class, since it's fairly simple (and you can always expose an IEnumerable<int> iterator via Enumerable.Range if you want to do LINQ over it)
In F#, you can generate a set of numbers, just by saying [1..100].
I want to do something similar in C#. This is what I have come up with so far:
public static int[] To(this int start, int end)
{
var result = new List<int>();
for(int i = start; i <= end; i++)
result.Add(i);
return result.ToArray();
}
By doing this, I can now create a set by saying 1.To(100)
Unfortunately, this is not nearly as readable as [1..100]. Has anyone come up with a better way to do this in C#? Is it more readable if it is lowercase? 1.to(100), for instance? Or, is "To" a bad word? Is something like 1.Through(100) more readable?
Just looking for some thoughts. Has anyone else come up with a more elegant solution?
EDIT:
After reading the responses, I have re-written my To method using the range:
public static int[] To(this int start, int end)
{
return Enumerable.Range(start, end - start + 1).ToArray();
}
I am still looking for thoughts on the readability of 1.To(100)
Enumerable.Range(1, 100);
I like the idea of using To. The alternative Enumerable.Range has a subtle flaw imo. The second parameter is not the value of the last element, it is the length of the enumeration. This is what I've done in the past:
public IEnumerable<int> To(this int start, int stop)
{
while (start <= stop)
yield return start++;
}
EDIT: If you want the result as an int[], just add .ToArray():
int[] theSet = 1.To(100).ToArray();
I think something like Set(1,100) or IntSequence(1,100) is easier to read than using an extension method.
Personal opinion though...
Your answer to your own question is fine. Just don't use a List if you are concerned about performance. Constructing a list and constantly expanding it is foolish. Just construct an array of the appropriate size. Use an extension method
public static int[] To(this int num)
{
//do work
}
I think you're worried too much that the language doesn't exactly express the particular syntactic thing that you want.
The way I see it, extension methods are a nice bit of sugar, but I wonder if you're really using it so much to justify the "surprise" of the extension method.
Within the domain of the language C#, it is more appropriate to spell out via the method name what you're trying to do. This feels more like Ruby than C#. This feels more like it wants to be in class by itself, especially if you wanted to add ranges with skip patterns (ie, the numbers from 1 to 10 by threes). I think that
public class RangedArray {
public static int[] Generate(int from, into to, int by=1) { /* ... */ }
}
is a perfectly acceptable to express this in C#.