Saturday, June 25, 2011

Cool Tools: VirtuaWin

Virtual desktop software allow you have several desktops, and switch between them easily.  This is the equivalent of virtual memory, but for desktop real estate. Good virtual desktop software allows you to move windows between virtual desktops, and will have good usability including hot keys.  VirtuaWin is a great free virtual desktop app for windows,  go install it .  Once installed you should do the following:

  •     Customize the notification area to always show the VirtuaWin Tray Icon

  •     Use C-A-Right, C-A-Left, C-A-Up, C-A-Down to navigate between your desktops

  •     Left Click on the VirtuaWin icon to interact with your windows

  •     Right Click on the VirtuaWin icon to play with settings



Enjoy, and be sure leave comments if there are tools you'd like more information on.

Saturday, June 18, 2011

Cool Tools: Paint.Net

Paint.Net is a nice compromise between advanced picture editing software, and picture editing software usable by humans. The biggest problem I had with paint.net is figuring out how to download it. In what I assume is an attempt to make advertising dollars, this website exists that make it impossible to download Paint.net without accidentally downloading crap.  Here's a direct paint.net download link.



Update here are my usages of Paint.Net:

Tuesday, May 10, 2011

Cool IEnumerable Tricks Part 1: GroupBy

IEnumerable, or what most people refer to as LINQ, has changed the way I program. If you love LINQ and you already fully understand this blog post, leave a comment with a topic you'd like me to post about. If you're not so comfortable with LINQ, try to follow along. This post will only take a few minutes, but may change the way you program for life.

While we go through this blog post (and future posts in this series) make sure you understand how every function works, if you don't understand a function, you certainly won't understand the next function. Some of this stuff is hard to grasp and I find the best way to understand the code is to try it in a debugger. It took me a few tries to wrap my head around what is going on, so expect to spend some time experimenting with this code.

I learn best when I'm trying to solve a problem, so lets define a simple problem: How to determine if the random number generator equally distributes integers mod 10.

Step 1: Generate a stream of random numbers:

var seed = new Random();
var countSamples = 10*1000
var randomStream = Enumerable.Range(0,countSamples).Select(r=>seed.Next());


In the above sample, we generate countSamples random numbers. We do this by producing countSamples integers via Enumerables.Range, than for each of those integers we apply a transformation. In this case the transformation ignores the input value, and returns a random number.



Step 2: Compute how many of each random number have each modulus (0..9).



randomStream.GroupBy(r=>r%10).Select(x=>new {x.Key,count=x.Count()}).OrderBy(r=>r.Key);

In the above sample, we use GroupBy to split the random numbers into groups based on their %10 value. For each group, we return a new object containing the modulus (x.Key) and the count of each group. Finally we sort based on the modulus.  The output is below:



































































Key count

0



959



1



938



2



1037



3



1028



4



951



5



1009



6



1029



7



1011



8



1038



9



1000




In a future post I'll describe how to create our own IEnumerable functions.

Monday, April 18, 2011

Leading by praise: How to use a carrot when you really want a stick.

Many naive leaders believe they have two ways to enact change in their followers.  The first way is "the carrot" aka praising good behavior. The second way is "the stick"  aka criticizing bad behavior.  In my experience, the stick is extremely ineffective. I'd say the only time the stick has any positive impact is when the follower doesn't realize she's doing something wrong, or how serious that wrong thing is.  

The goal of this post is how to use a carrot when you want a stick.  First lets recall how to use a carrot effectively in general: Keep it timely, short, specific and often (the one minute manager is my hero).  Any time you see a new good behavior praise it.  When you praise,  be as specific as possible so the follower knows both the behavior you are praising and the valuable impact of that behavior.  It's easy to praise when things go well, but how do we praise when things are going poorly?

When things are going poorly, there's only one thing you can do - put your followers in a position where they perform good behaviors.  Scope their work so they have no choice but to perform good behaviors.  From that good behavior, apply praise.  Even if that behavior is accidental, still give praise.   Slowly, sometimes painfully slowly, you'll get more opportunities to give praise, and you'll get more good behaviors.  Keep giving praise, eventually the fruit of your labor will pay off.

Praising weak performers can be a time consuming delicate process, but it's like lighting a fire: at first you have to work really hard to spark the tinder, then pay close attention while the kindling catches to make sure you don't lose your delicate flame, finally you'll have a fire raging, and you can lean back and relax knowing not only have you lit a fire, but that fire can be used to light other fires.

Friday, April 15, 2011

Google killed the video store

As a younger man I remember arguing with a co-worker about the death of local storage. 



Me: Who wants to store data themselves?  I can store all data in the cloud, where it will be preserved forever!

Wiser co-worker: What incentive does this cloud have to keep your data? I'll keep my data on my local hard drive thank you very much!

 

8 years later my co-worker was  correct. I got the following letter from Google today:



Later this month, hosted video content on Google Video will no longer be available for playback. <snip> We’ve added a Download button to the video status page, so you can download any video content you want to save. If you don’t want to download your content, you don’t need to do anything. (The Download feature will be disabled after May 13, 2011)

Ouch for being wrong,  and double ouch for having to download all my videos to my hard drive.

Notes:

  • Astute readers will note, I actually got a decent deal since I got 8 years of free storage and $/GB has plummeted in that time.

  • This isn’t the first time my “bet on a cloud service” has failed. I lost all my face tags when polar rose was bought by apple and shutdown.

  • I’m a slow learner, and still use the cloud for the primary copy of all my media.

Sunday, April 3, 2011

Software Engineering “The Soft Skills”

To date, I've focused my blog on the "computer" parts of software engineering. However, as I've grown as a software engineer, one of my largest aha moments is the realization that software engineering is all about people. As such, I'll start posting articles dealing not just with computers, but also with communication, people leadership and management. These "people skills" are as important to a software engineer as the ability to crank out a design specification. For the hardcore among you that think people skills have nothing to do with software, consider this.

Friday, April 1, 2011

Impedance MisMatch: IEnumerable<T> to DataTable

I had to work with a class that consumed a System.DataTable today. DataTable is an old class that pre-dates generics in the CLR. DataTable carries typed data as an array of System.Object - double plus yuck! As you can imagine the code I use these days has compiler verified type safety by using IEnumerable everywhere. So how did I convert from my beloved IEnumerable to the yucky DataTable? With reflection of course! This simple method solves our problems:



public static DataTable ToDataTable(IEnumerable rows)
{
var tableToReturn = new DataTable();

// get properties of T
var properties = typeof (T).GetProperties().Where(p => p.MemberType == MemberTypes.Property);

// Convert T's properties to columns in the DataTable
foreach (var p in properties)
{
tableToReturn.Columns.Add(p.Name, p.PropertyType);
}

//populate rows
foreach (var row in rows)
{
T row1 = row;
var propertyValuesAsEnumerable = properties.Select(p => p.GetValue(row1, null));
tableToReturn.Rows.Add(propertyValuesAsEnumerable.ToArray());
}
return tableToReturn;
}