August 26, 2007
@ 07:18 PM

Inspired by this.

My Working Theory: Average Developer Ability to Perform Career Calculus = 1 / Volatility of Job.

This doesn't hold for "great developers" (ex.: Jim Little, Michael Nelson.) They learn because they enjoy it. They would be learning the same stuff if they were working as longshoremen.

I don't think it goes for developers in places where the management encourages growth either (like Solutions IQ), but I've never worked in a place like that, so I'm not sure if it's just the developers I've met from these places, they don't hire weenies, or it's really the environment.

For me, maybe my motivation is my "packed bag": I've never worked in one place a really long time, and I am usually in some phase of culture shock. I always kind of keep one bag packed in case I have a really bad day and need the relief of moving on.

The place I work now has extremely low volatility. You could easily start here as a developer and work until you retire. There are many incentives to stick around, and overall, it's a really great place to work. If they need you to retrain for something else, it's unlikely that you'd get forced out, and they would probably make sure you had access to whatever training you needed.

Unfortunately, this means that most developers don't get a lot of push to spend personal time and effort keeping their saws sharp when they've already got the job.

The thing I hear most often is that "there is more to life." True, but I don't think spending a small amount of personal time keeping your skills up to date is enough to impact a normal life. It's harder when you have a family, but not being able to spend, say, 5 hours a week sharpening sounds weak to me. If you can't even do that, you shouldn't be eating lunch.

I think this has been and continues to be one of the greatest problems in our industry today.


 
Categories:

The other day, Lane (sits in same little office as me, sometimes works together with me) asked how to find all the clients with at least one active plan:

image image

He had written some code that did the filtering in code (i.e., get got a list of all plans, then accumulated a distinct list of clients for the plans that were active.) This code didn't work for a completely unrelated reason. We fixed that problem and left it at that. This was a good problem for me to play with to learn more about projections and subqueries in NHibernate, so I took the problem home with me. This stuff confuses me and seems to be rather poorly documented: there is a section of the NH documentation that touches on this functionality but doesn't really explain what a projection is, or any other background info.

So, my menal definition of a projection is, you build an NH query then get something else about the set of objects your query defines, such as aggregate information.

Of course, there is also this post from Oren, which has lots of clues and a good description of his sample (I find the NH documentation samples kind of hard to follow sometimes,) but his solution only works on the "trunk" (circa Nov. 2006). I can't find where the "Expression.Property" is implemented in 1.2GA NH.

So for the clients-with-active-plans problem, My first thought was, "Let's just group the active plans by client, and project the clients":

IList<Client> clientsWithActivePlans = 
      session.CreateCriteria(typeof(Plan))
            .SetProjection(Projections.ProjectionList()
            .Add(Projections.Property("Client"))
            .Add(Projections.GroupProperty("Client")))
            .Add(Expression.Eq("IsActive", true))
            .List<Client>();

This results in:

image

I am expecting a list of 3 clients: I have 5 clients in the database, one with no plans, one with plans but none active, the rest with active plans.

"from" does have 3 entries, but why does each row have 2 objects in it? I was expecting just the Client object. Here is the SQL:

SELECT 
   this_.ClientID as y0_, 
   this_.ClientID as y1_ 
FROM 
   [Plan] this_ 
WHERE 
   this_.IsActive = @p0 
GROUP BY 
   this_.ClientID; 

@p0 = 'True'

Not sure why ClientID is selected twice...what if I remove the Property projection...does group by get me the grouping column/object automatically?

IList<Client> clientsWithActivePlans = 
session.CreateCriteria(typeof(Plan))
            .SetProjection(Projections.GroupProperty("Client"))
            .Add(Expression.Eq("IsActive", true))
            .List<Client>();

Yields this SQL:

SELECT 
   this_.ClientID as y0_ 
FROM 
   [Plan] this_ 
WHERE 
   this_.IsActive = @p0 
GROUP BY 
   this_.ClientID; @p0 = 'True'

This looks better...but it only fetches the IDs. The Clients are then lazy loaded if you iterate over them:

Console.WriteLine("Clients with active Plans:");
foreach (Client client in clientsWithActivePlans)
   Console.WriteLine(client.Name);

Generates:

SELECT 
   client0_.ID as ID0_0_, 
   client0_.Name as Name0_0_ 
FROM 
   Client client0_ 
WHERE 
   client0_.ID=@p0; 

@p0 = '2'

For each Client in the list.

How about making this query into a detached criteria, and fetching full Clients where the Client exists in the above query (i.e., use the above query as a subquery.)

DetachedCriteria clientIDsWithActivePlans =
 DetachedCriteria.For<Plan>()
      .SetProjection(Projections.ProjectionList()
      .Add(Projections.GroupProperty("Client")))
      .Add(Expression.Eq("IsActive", true));

IList<Client> clientsWithActivePlans = session.CreateCriteria(typeof(Client))
      .Add(Subqueries.PropertyIn("ID", clientIDsWithActivePlans))
      .List<Client>();

Gives me one query to the database:

SELECT 
   this_.ID as ID0_0_, 
   this_.Name as Name0_0_ 
FROM 
   Client this_ 
WHERE 
   this_.ID in (
      SELECT this_0_.ClientID as y0_ 
      FROM [Plan] this_0_ 
      WHERE this_0_.IsActive = @p0 
      GROUP BY this_0_.ClientID); 

@p0 = 'True'

and no lazy loading the clients as we iterate over the list.

I think I've only just scratched the surface with what you could do with Projections and Subquery criterions in NHibernate. I hope Oren posts more about this and I hope I have more time to play around with this on my own to get a better handle on how it works.


 
Categories: database | nhibernate

I might be one of the few NHibernate users using Code Rush (and not resharper,) but here goes:

Using NHibernate, I need all the properties and methods on my model classes to be virtual. It's tedious to go and add virtual to them all the time, and CodeRush is perfectly capable of doing this for us.

The CodeRush "p" family of templates look like this:

image

Notice the #PropertyDefaultScope template. This is where is says "public" or "private", and also happens to be where "static" gets inserted if we're in a static class. This seems like a good place to insert my "virtual".

image

There's #StaticIfNeeded, the one that decides to add "static." Let's see how that works. Maybe we can make a "#VirtualIfPossible#" template that is at least a little smart about this - i.e., doesn't add virtual if we're doing a static method, etc.

image

Notice that it has to be in a static class to work. Let's do that same thing, but when we're _not_ in a static class:

image

Now we can add that to the #PropertyDefaultScope template:

image

Now when I declare properties, they will be virtual by default, making it easier to build NHibernate model classes, as well as use Rhino Mocks and other things that thrive on virtualness:

image


 
Categories: nhibernate | CodeRush

After reading this, I am inspired to point out my favorite fire fox trick: In firefox, you can assign keywords to bookmarks. So, for example, I have a bookmark for gmail, I assign the keyword "m". In the address bar, I type "m" and get gmail. "r" = google reader, "s" = safari books online, etc.

I only have about 10 bookmarks in the browser, and in fact, the only reason I have those is because of this shortcut feature. For all other bookmarks I just use del.icio.us.


 
Categories: tool

August 25, 2007
@ 01:50 AM

I sometimes find it convenient and necessary to run scheduled tasks or services as myself. I know this is bad, but what can I say. I've been cleaning up my act.

We recycle passwords every 45 days. Password reset day is always kind of stressful for me. I am going along with my business and bam! Locked out. Call help desk. "You again?" Get unlocked...

Next time, I'll be ready:

@('localhost','server1','server2','server3') `
| %{gwmi -Class Win32_Service -computerName $_ `
| where {$_.StartName -like '*cbilson'} `
| select Name, StartName, Status }

So that's the services, what about scheduled tasks? Well, there is the Win32_ScheduledJob WMI class, but it looks like that doesn't find scheduled tasks created using the scheduled task wizard? It's not working for my scheduled tasks anyway. Bummer.

Of course, this is a band-aid. They should just check the event log on my login server and see why I got locked out. Or maybe monitoring this kind of stuff even. I wonder what they do when an authority figure locks out their account. Even scarier: when a service account locks out! Our help desk doesn't seem to know how to trouble shoot this problem though and since we're still in business, I guess it's not as serious a problem as I am making it out to be.

 

 


 
Categories: PowerShell

I've been a big fan of most of the practices I learn from Agile for a long time. I've never been a big fan of zealotry, though. To me, the core of agile is about continuous self-improvement and everything else comes from that. If you adopt a couple of good practices just because some guru told you to, and you haven't really learned how to evaluate your own situation and discover ways to improve your self or your team, you're missing it.

On that note, I'd like to thank jrwren for these hilarious agile videos. We've had lots of intense agile-buzzword-flying-around action at work and it's nice to see the human side and smile again.


 
Categories: agile | humor

August 6, 2007
@ 06:36 AM

It was kind of hard to install with UAC getting in the way, but Virtual Earth 3D is awesome. I still wish they would do a rich client like google earth, but this is already better than google earth, both in terms of usability of the interface and amount of data/detail. Here's looking in the direction of my house and Mt. Ranier from the office building I work in (looking east):

Here is the view I get from my office window (looking north into commencement bay):

I can't describe how uncanny this looks. The shapes are perfect. The colors are almost there. The real world has more colors and is higher res. It kind of gives me goose bumps. Makes me feel like I live in the Sims or 2nd Life.


 
Categories: bs

August 1, 2007
@ 06:24 AM

This morning, while preparing a presentation for a developer audience not too familiar with Domain Driven Design, I realized that the first computer domain model I ever encountered was actually this game I played when I was in 5th grade: SCRAM.

SCRAM was a nuclear power plant simulator/game for the Atari 400/800, developed by the legendary game design guru, Chris Crawford. You were in charge of keeping a nuclear power plant running at optimal performance, while keeping it from melting down in the face of earthquakes and equipment failures. It boggles the mind that this game was written in 16K of Atari Basic (although, I looked at the source code as a kid, and it was full of assembly language packed in strings, which inspired me to learn 6502 assembly.)

In order to play SCRAM, worldly fifth grader that I was, I needed to learn the ubiquitous language of nuclear power: cooling towers, pumps, cooling rods, condensers, tertiary cooling systems, the NRC. In fact, I remember learned the word "tertiary" for this game. How cool is that!

While the NRC would not have likely certified me to run a nuclear power plan after playing this game, it gave me a very strong sense for how (at least in the model) a nuclear power plant works, something which I retain to this day. No wonder they had this game in my school!

I think domain modeling in business software has a lot of similarities to domain models in simulators. In fact, I think when we are building business software, all we are really doing is building a simulation of some business activity people used to do. In some cases, the model has been around for a while and the business has completely changed since people did it, but we're still kind of conceptually simulating what people would have done.

Too bad I can't get people at my work to see they are just playing games on a simulator. We'd have a lot more fun!


 
Categories: