Tuesday, September 30, 2008

More Fun With Linq

Say you have a class named BannedProgram and it has a collection of DayOfWeek and a string ProcessName. Now the collection of DayOfWeek is basically a way to set the days of the week it's banned. With this you want to create a collection of these BannedPrograms, each with their own names and days they are banned. Simple, I know. Next you have a list of processes that are currently running and you want to get all the processes that match the names in the BannedPrograms list AND if the current day is a banned day. First you need the day checked function:

private static Func<DayOfWeek, Boolean> dayIsToday = 
  currentDay => currentDay == DateTime.Now.DayOfWeek;

Then you need the method to get the banned processes that are currently running:

private static Process[] GetBannedProcesses(BannedProgram[] programs, Process[] processes)
{
  var processList = from process in processes
  where
  (
    from program in programs
    where program.DaysBanned.Any(dayIsToday)
    select program.ProcessName
  ).Contains(process.ProcessName)
  select process;

  return processList.ToArray();
}
What this is doing: Well if you look at this:
from program in programs
where program.DaysBanned.Any(dayIsToday)
select program.ProcessName
This is going to grab any BannedProgram that has a DayOfWeek that matches today and it will select only it's name. This will give you a list of names of the BannedProcesses that can not be played today.
var processList = from process in processes
where
(
  from program in programs
  where program.DaysBanned.Any(dayIsToday)
  select program.ProcessName
).Contains(process.ProcessName)
This checks to see if any of the currently running processes have a name that matches a name in the banned program list. And now you have a list of processes to kill. Yay. Not sure this is a big deal, just thought it was a fun example of using linq and subselects. USING???
using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Windows.Forms;

More Useless info

Just in case you wanted to create something to kill a process, I have this little bit:
using System;
using System.Diagnostics;

Action<Process> killProcess = currentProcess => currentProcess.Kill();
Process[] processes;
String processToKill;

processToKill = "WAR";
processes = Process.GetProcesses();

processes.Select(currentProcess => currentProcess.ProcessName == processToKill)
.ToList()
.ForEach(killProcess);

I originally intended this as a service that would kill processes that were running on a specific day. IE To stop myself from playing games during the week. Problem was finding a way to stop me from killing the service. Now you can set a service to disallowing stopping it. The idea being that I would have another program that would stop it only if a password was enter correctly. (A certain woman would have this password) Trouble is, I can just open up the task manager and kill the process. Now I have to rely on self control. WHICH IS THE REASON WHY I WANTED THIS IN THE FIRST PLACE.

Tuesday, September 9, 2008

Combining Lambda Expressions

Found this post here but wanted to make a really simple example to demonstrate this. The idea is simple, take something like this:
currentItem => currentItem.BooleanMethodOne() && currentItem.BooleanMethodTwo()
but say you only want to have one clause or both. Well you could make three separate expressions, but what if you wanted to add even more later? What if you wanted to mix and match? What if you're reading thing because you watched to see what page could possibly be on the last page of a google search? Well I have answers... stolen answers. First the needed And and Or methods:

public static Expression<Func<T, Boolean>> And<T>(
   Expression<Func<T, Boolean>> expressionOne,
    Expression<Func<T, Boolean>> expressionTwo
)
{
  //Basically this is like a bridge between the two expressions.  It will take the T
  //parameter from expressionOne and apply it to expression two. So if 
  // oneItem => oneItem.OneMethod() is expressionOne
  // twoItem => twoItem.TwoMethod() is expressionTwo
  //it would be like replacing the twoItem with the oneItem so that they now point
  //to the same thing.
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());
  
  //Now this is to create the needed expresions to return.  It will take both early expressions
  //and use the item from the first expression in both.
                    
  //It will look something like this:
  //currentItem => (currentItem.OneMethod And Invoke(currentItem => currentItem.TwoMethod()))
  //As you can see, it looks to be running expressionOne and then a new method that basically
  //calls expressionTwo with the same value (currentItem)
  return Expression.Lambda<Func<T, Boolean>>(
   Expression.And(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}

public static Expression<Func<T, Boolean>> Or<T>(
Expression<Func<T, Boolean>> expressionOne, 
Expression<Func<T, Boolean>> expressionTwo
)
{
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());

  return Expression.Lambda<Func<T, Boolean>>(
   Expression.Or(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}
And here's a test for it:
String[] list;
  
list = new String[] { "a", "b", "c", "ac", "ab", "cc", "d", "dd", "dc" };

Expression<Func<String, Boolean>> stringLikeA = currentString => currentString.Contains("a");
Expression<Func<String, Boolean>> stringLikeB = currentString => currentString.Contains("b");
Expression<Func<String, Boolean>> stringLikeC = currentString => currentString.Contains("c");

Expression<Func<String, Boolean>> neededUser = And<String>(stringLikeA, stringLikeB);
list.Where(neededUser.Compile());

//a
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 1);  //ab

//a, c, ac, ab, cc, dc
neededUser = Or<String>(stringLikeA, stringLikeC);

Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 6);

//ab, c, ac, cc, dc
neededUser = And<String>(stringLikeA, stringLikeB);
neededUser = Or<String>(neededUser, stringLikeC);
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 5);
USINGS!!ONEONE
using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Monday, September 8, 2008

FIzzBuzz with Linq extension methods

So if you haven't heard of the FizzBuzz test, it's basically taking in a list of numbers and figuring out if they are divisible, cleanly, by two numbers. Say you have 3 and 5 and this is your list:

1
3
5
10
15

If the number is divisible by 3, then return the Fizz string. If the number is divisible by 5, return a Buzz string. If it's divisible by both, then return FizzBuzz.

1
Fizz
Buzz
Buzz
FizzBuzz
Pretty simple and in actuality pretty easy to do with old C# tools, but I wanted to do this with Linq. With the use of Funcs, Actions, and Linq extension methods it can be done fairly easily. Technically you can do the whole thing in one line if you don't want to bother with refactoring.

I have no idea how to format this cleanly, so sorry if the format is confusing. Basically it is take a list, get the ones you want, concatenate it with the next list.
public static IList<KeyValuePair<Int32, String>> ConvertListOfIntegersWithLinqMethods(IList<Int32> listToConvert, Int32 fizzNumber, Int32 buzzNumber)
{
var result =
  listToConvert
    .Where(WhereBothDivisible(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("FizzBuzz"))
    .Concat(
  listToConvert
    .Where(WhereBuzzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Buzz")))
    .Concat(
  listToConvert
    .Where(WhereFizzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Fizz")))
    .Concat(
  listToConvert
    .Where(WhereNeitherDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Nothing")));

 return result.ToList().OrderBy(currentItem => currentItem.Key).ToList();                
}
Using these:
private static Func<Int32, KeyValuePair<Int32, String>> selectKeyValuePair(String value)
{
 return currentItem => new KeyValuePair<Int32, String>(currentItem, value);
}
          
private static Func<Int32, Boolean> WhereBothDivisible(Int32 fizzNumber, Int32 buzzNumber)
{           
 return  currentItem => IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereFizzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereBuzzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

 private static Func<Int32, Boolean> WhereNeitherDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

Tuesday, September 2, 2008

Beyond the wall

So I never gave a solution to this problem and thought I might do that real fast. If you recall, this was the main sticking point of creating a Func for a select clause:
Func<User, EHH??> selectUserID = currentUser =>  new { currentUser.ID, currentUser.UserName };
Well there is no one solution to this, but there is an easy and clean solution:
 public class UserQueryItem
 {
   public UserQueryItem ( Int32 userID, String userName )
   {
      UserID = userID;
      UserName = userName;
   }

   public Int32 UserID { get; set; }
   public String UserName { get; set; }
 }
Create a class to hold the information.
 Func<User, UserQueryItem> selectUserID = currentUser =>  new UserQueryItem { UserID = currentUser.ID, UserName = currentUser.UserName };
Or

 Func<User, UserQueryItem> selectUserID = currentUser =>  new UserQueryItem (currentUser.ID, currentUser.UserName);
Pretty simple, just a little more work.

Friday, August 29, 2008

DID U NO?!?!!111

So maybe I'm slow, but it just dawned on me that:
 SomeClass class = new SomeClass() { SomeProperty = "" };
Is the same as:
 SomeClass class = new SomeClass { SomeProperty = "" };
What?? Look closely. The "new SomeClass" no longer needs the () if you are using 3.0's property initializers. Not ground breaking, but interesting.

And now for Contravariance

Take the classes in the last post (First, Second, Third) and assume they are exactly the same in this example. In Covariance, we learned that whatever variable to you set equal to the return of a method has to be equal in type of larger. Or in other words, it has to have equal or less functionality.
  Second second = ReturnThird();  //OK since second has less functionality

  Third third = ReturnSecond(); //BAD since third has more functionality
Now I think you can guess what Contravariance is, but if you can't it's ok. Most likely you're a tool just like me. Contravariance is the movement from small to large meaning that the type must be equal to or larger than. Following the "in other words" manor, it has to have equal or more functionality. Now small note before I go on, saying that it has to have more/less functionality can be somewhat dangerous. After all, Third could inherit from Second and add no functionality, but I find this is an easier way to think of it. I suppose another way of thinking of it is that with Covariance the return type has to have equal or more knowledge. Meaning, Second has full knowledge of what First is, but Second has no idea what Third is. Anywho, onto some examples. Say we take the FillX methods and add something to it.
  private void FillFirst(First firstToFill)
  {
    firstToFill.FirstOutput = "";
  }

  private void FillSecond(Second secondToFill)
  {
    secondToFill.SecondOutput = "";
  }

  private void FillThird(Third thirdToFill)
  {
    thirdToFill.ThirdOutput = "";
  }
Right off the bat you might notice that if methods allowed Covariance with parameters, you'd be in trouble. After all, if FillThird allowed parameter covariance, you could pass in a First object. What what that object do with ThirdOutPut? As things are, you would have a bad day. Lucky for you, at least if you aren't adamant about wanting Covariance in parameters, this can't happen. Well shoot, I just gave away the fun of this post. Oh well, I'll keep going in case you just have more time.
  Action<First> fillFirstAction = FillFirst;
  //No problems here since FillFirst expects a First
    
  Action<Second> fillSecondAction = FillFirst;
  //Still no problems although this may look odd.  But remember, FillFirst
  //just needs an object that : First, it doesn't care if the object
  //has more functionality than first.
  //
  //The FillFirst method uses the FirstOutput property and by inheritance
  //the Second being passed in has said property
    
  Action<Second> fillThirdAction = FillThird;
  //Not gonna happen.  The FillThird expects a third or smaller object.  Since
  //Third : Second, third is smaller than second.  Implications?  Look in the 
  //FillThirdMethod
  //
  //The method expects the object to have the ThirdOutput property which means
  //Second has to inherit from Third.  We know this to be untrue.
So basically Contravariance is used with parameters in methods to guarantee the object being passed in has at least the functionality used within the method. Apparently there was a problem in the lobby so there will be no refreshments served tonight.