Friday, June 27, 2008

Change Dispensed

{

Steve posted a coding challenge a few days ago - a change dispenser. I thought it would be a nice exercise for my fledgling Python skills and implemented it with just a small variation on pluralizing coin denominations.

def make_change(amt):
output = "Change is "
coins = (['quarte|r|rs', 25], ['dim|e|es', 10], ['nicke|l|ls', 5], ['penn|y|ies',1])
for i in coins:
r = amt // i[1]
if(r > 0):
coinout = re.split('\|', i[0])
output += "%d %s%s " % (r, coinout[0], coinout[1:][r > 1])
amt = amt - (r * i[1])
print output

make_change(48)




A few things I learned along the way:


* I was reminded that dictionary objects do not guarantee order.


* I was using Python regular expressions to do a match on the string "this |and|or that" and discovered if you use match with simply \|(\w+) it returns nothing since the match must start from the beginning of the string!


* I was going to use a lambda expression for the pluralization but that's such a large hammer for what in the end would become a split



Python's behavior with booleans is another point of interest - when I test the following: coinout[1:][r > 1] I'm taking advantage of anything true being a 1. I wonder if this is "bad" but it's a seductive thing to take advantage of...



}

Monday, June 23, 2008

Deep Fried Bytes, Yegge, Interviewing

{

Found a good podcast today, "Deep Fried Bytes." Skip the first episode but the second on interviewing is a gem. Although it was posted on May 29, it ties in quite well with thoughts delivered (not simply written, but delivered) by Steve Yegge in his recent post on finding good people, Done and Gets Things Smart. Not only is it entertaining to hear Ayende Rahein take nonusers of using blocks to task, but later Scott Belware seems to be on the same page as Yegge on how you can know if people are "good."  Here is his approach (listen to the podcast if you want total accuracy):

- I don't ask questions I do pair programming for interviews...
- Interview questions are irrelevent... most of the people asking interview questions are showing the people who are interviewing what they know
- Ask for a code sample with unit tests that run inside Visual Studio
- If that's okay ask them to come in for 4 hours of pair programming
- Most interview related items would come up during the pair programming session

}

Thursday, June 12, 2008

C# Multiple Replace Extension Methods, Levithan Style

{

A couple of nights ago I blogged about an implementation of a technique to replace multiple patterns in a string on a single pass. Steve Levithan had an entry on the approach (not mine in specific, just the approach and commenting on a few weaknesses). It inspired a few things out of me: first, making the multiple replace an extension method of the string class, and second to duplicate Steve's approach which enables a more robust model because you can use metasequences etc...

Here is the code (included the using statement since the use of ToArray() from the Dictionary key collection isn't available without System.Linq):

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

static class RegexExtender {
public static string MultiReplace(this string target, Dictionary replacementDictionary) {
return Regex.Replace(target,
"(" + String.Join("|", replacementDictionary.Keys.ToArray()) + ")",
delegate(Match m) { return replacementDictionary[m.Value]; }
);
}

public static string LevithansMultiReplace(this string target, Dictionary replacementDictionary)
{
foreach (string key in replacementDictionary.Keys) {
Regex r = new Regex(key, RegexOptions.None);
target = r.Replace(target, replacementDictionary[key]);
}
return target;
}

}


Here is some usage:




// the original approach, as an extension method
string x = "Holly was a hunter";
Dictionary rdict = new Dictionary();
rdict.Add("Holly", "Hannah");
rdict.Add("hunter", "hatter");
Console.WriteLine(x.MultiReplace(rdict));

// Steve's technique
rdict = new Dictionary();
rdict.Add(@"[A-z]", "x");
rdict.Add(@"\d", "y");
string test = "David is 33";
Console.WriteLine(test.LevithansMultiReplace(rdict));




}

Tuesday, June 10, 2008

Regex: replace multiple strings in a single pass with C#

{

I wish I could say I was the clever one to think of this but I ran into it in my copy of the Python Cookbook (the original author is Xavier Defrang, the Python implementation here). It's cool enough that I ported it today - I'll know I'll use the C# implementation of it quite often:

        static string MultipleReplace(string text, Dictionary replacements) {
return Regex.Replace(text,
"(" + String.Join("|", adict.Keys.ToArray()) + ")",
delegate(Match m) { return replacements[m.Value]; }
);
}
// somewhere else in code
string temp = "Jonathan Smith is a developer";
adict.Add("Jonathan", "David");
adict.Add("Smith", "Seruyange");
string rep = MultipleReplace(temp, adict);


}

Sunday, June 08, 2008

Languages And Thinking

{

I'm approaching the end to a rough week and should be coding but the virus scanner on my office machine is slowing development to a point where it's not bearable for me.  I'll pass the time with a quick thought about how programming languages affect thinking and why it makes me both picky about languages I use and also curious to see how the different languages solve problems.

I will confess that the project I've been working on is written in VB.NET.  The reason for that was very practical since our client was adept at VBA and needed to, on occasion, get to the code level of things.  I'd spent a lot of time in Visual Basic (the "classical" VB) so I thought nothing of it - perhaps somewhat of a refreshment after so many years away.  As we wrote more and more code, I started noticing a lot of nested "If" statements in the style of:

If Some Condition Then
If SomeOtherCondition Then
If YetAnotherCondition Then


You get the picture.



I remember working with a different VB programmer and she was also given to writing a lot of nested conditions in the same manner even though we were using C#:



if(cond){
if(cond2){
if(cond3){


At the time it really bothered me in a "code smell" sort of way; nesting conditions, I would have argued, invites clutter and entropy. Since I've been attending Hanselman University for a while now I can say with more technical gravitas that they increase cyclomatic complexity and this was why they smelled bad. The alternative I would have wished for would have been:



if(cond && cond2 && cond3){
...
}


Pretty natural, right?  Actually no, especially if you're coming from Visual Basic because the Visual Basic And and Or operators don't do short circuit evaluation.  If you combine boolean expressions you have to make a mental note to verify that they both will work at runtime - that there is no dependency between them.  That's something a C# progammer completely takes for granted often writing code like this which is a ticking bomb in VB.NET (it won't go off until you're demonstrating the app to your client, trust me):



If Not MyCollection Is Nothing And MyCollection(0) = "Something" Then
...


One expects the second expression will be passed if the first fails in a "short circuit" approach. Unfortunately, Visual Basic .NET will attempt to evaluate the second even if the first is not true!



To clean this all up the VB.NET folks provided the AndAlso and OrElse operators which do traditional short circuit evaluation. I read somewhere that the reason And and Or were left as is was for backward compatibility and people who were "upgrading" their code from Visual Basic to Visual Basic.NET. Using these operators you're back to thinking "normally" as a C#, C, Javascript, etc... developer.



So back to my original thought - nested If blocks are a simple way around an operator that doesn't short circuit and it's a way of thinking if you've spent a lot of time writing Visual Basic code. The language is what drives that even though there may be alternatives. Even though it may produce cyclomatic complexity. Some people tell me picking a language is just a simple process of picking a tool, but I think it's more than that; it's picking a way of thinking. That's why it's not only important to me, it's interesting to see how different languages lead us in different directions. Even if an idiom is available elsewhere, it's getting to think that way that is most often  the trick to being better in both languages.



One more side note, I can chart a few different ways in which new languages have affected me. Take a look at the type of thing I did before a lot:



foreach(string s in stuff){	
master += s + ",";
}
master = master.Substring(0, master.Length -1);


Nowadays:



// like a map, I first started thinking this way from perl
stuff.ForEach(delegate(string s) { master += s + ","; });
// like a join, very Pythonic
String.Join(",", stuff.ToArray())


}

Sunday, June 01, 2008

Galloway et. al. Roundtable Podcast

{

If you haven't and you do Microsoft development, give an ear to John Galloway, K. Scott Allen, Scott Koon, and Keven Dente in their "Technology Roundtable" podcast.  There are a lot of podcasts I find entertaining, (like Joel and Jeff's discussions) but these guys seem to do what I do - and to contextualize that since it may sound presumptuous, they deal with Microsoft development tools building "real world" software.  

I try to have "take aways" from podcasts so from the first more impetus to investigate Ninject and dependency injection as well as more investigation of LINQ to SQL and the ADO.NET Entity framework (opinions flew on these, I'd like to develop some of my own).  Finally, even though I'll probably skip the beta, I will look forward to .NET 3.5 SP1 since ASP.NET Dynamic Data will be packaged therein.

The second podcast had a great discussion on javascript libraries. I've used jQuery and YUI and Prototype on different projects and while my fondness for Prototype/Scriptaculous is probably greatest of all I am always eager to hear other people's experiences. The framework I have yet to do anything serious with is Dojo - I did some quick prototyping of their flyout menu with ASP.NET server code and I hate to say it but the ASP.NET Menu control was a lot more effective and fast. While it wasn't explicitly stated, this podcast has dampened my interest for the ASP.NET Ajax stuff - I looked at it again a few weeks ago and it seemed so... heavy.  I'm not sure who mentioned it in the podcast but they said it seemed more oriented for writing controls versus Ajaxy type applications.  I would have to concur with my limited knowledge.

I'll stay tuned, it will be interesting to see what they talk about next time.

}

Saturday, May 31, 2008

Knowing C

{

I've been having a good time listening to the StackOverflow podcasts. Joel's a great curmudgeon and Atwood is as opinionated as ever.  An ongoing disagreement between the two has been the usefulness of knowing C.  Joel's adamant about its importance and Atwood thinks there is much else a developer can spend their time in understanding. 

Eric Sink has since chimed in with a post called C and Morse Code wherein he reveals his cards: like Joel, he thinks it's of vital importance if you want to reach past mediocrity:

I'm not going to take a black-and-white stance on this.  I won't go so far as to say that every developer must learn C.  I've met lots of developers without C experience who are successful and making positive contributions to important software projects.

Furthermore, I'll admit that knowing C is not a magic solution to poor skills.  A lousy developer who happens to know C is simply better equipped to hurt himself or somebody nearby.

However, I can say these two things:

  1. All of the truly extraordinary developers I know are people who really understand the kind of low-level details that C forces you to know.
  2. Every programmer without C experience has a clear path of personal development:  Learn C.  Get some real experience using C to write a serious piece of software.  Even if you never use it again, you'll be a better programmer when you're done.

My relationship with C is tenuous at best. I spent a few months some years ago delving into it (and C++) seriously - I'm curious to go back and find some of that code but it was a few machines ago*.  I remember during that time I'd work on little toy programs (mostly an implementation of some algorithm) in C and then have the need for a utility and write it in something else.  It would be interesting to take Eric up on his second point of writing a "serious piece of software" using the language.  One interesting angle on this is how one would keep said "serious piece of software" strictly in the realm of C, without venturing too much into the world of C++ and object orientation done poorly.

So brainstorm question: what's something nice and useful that could be implemented strictly within C? (That one might not yawn and think *gosh* that would take 1 minute to do in Python).

}


*Great memories of Me, Markus, and bcc32 in a coffee house somewhere in southern California.  Too far gone are those days...

Thursday, May 29, 2008

Splitting Files with Python

{

I've been recently needing to generate sql scripts from large Excel spreadsheets. But once the script is finished I've had issues getting SQL Management Studio to execute as large a script in a single run. The solution? Split up the file with a little Python that takes it's arguments like this:

ipy Splitter.py  LargeFile.sql 3

#import clr
#pass arguments like so:
# THISSCRIPT.PY FILE NUM_PARTS
# ipy Ringil.py LargeFile.sql 4

import sys

if(len(sys.argv) == 3):
splits = int(sys.argv[2])
f = open(sys.argv[1])
data = f.readlines()
lc = len(data)/splits
print "number of lines", len(data)
for c in range(0,splits):
outstream = open("data" + str(c + 1) + ".sql", 'w')
for line in data[:lc]:
outstream.write(line)
outstream.close()
del data[:lc]
f.close()
else:
print "Expected arguments: file and number of splits\n example: ipy Splitter.py LargeFile.sql 4"


 



}

Tuesday, May 20, 2008

It's speed that counts

{

I usually don't talk about hardware because I don't pay too much attention to it unless something is bothering me.  However I've discovered something interesting about myself in the last week.  I've done a lot of my development over the last few years on an enormous HP zd8000.  I jokingly called it "the 747" because of its size and girth - 10 lbs and a 17" screen.  For a guy like me who's usually also carrying a few books in his bag it's quite a load as evidenced by my going through at least one laptop bag (my current one is also in poor shape). 

So because of some changes at work I got to try out a machine I'd liked the thought of - another HP but this one with a small 13" screen and weighing perhaps 4 lbs.  It's a great little machine and has a cool look but after about a week I'm back to the 747.

Why go back to the back pains and encumbrance of this massive machine?  One simple reason: speed.  It's got twice the RAM (2GB) and a much faster processor.  I didn't think about this much but for a person like me who is usually running an instance of SQL Server, an IDE of some sort, a text editor, web browsing with 10 tabs open, listening to music, chatting up friends (Messenger is no joke when it comes to resources), etc, etc - you get the picture - it's frustrating to be on a beautiful, compact machine that you have to wait around for. I'd rather exchange power with encumbrance for convenience with time penalties.

Or, as I like to joke with my South Dakota friends, I'm like a guy who exchanged his Chevy Silverado for a crossover vehicle... until he realized that he made his living hauling lumber.

Footnote: I ordered a Thinkpad T61 which should be a foot in both worlds. I guess my bit of the economic stimulus went to China.

}

Monday, May 19, 2008

Nregex mention

{

Steven mentions Nregex in a list of regular expression testers online. Nregex is still up and still useful especially if you need to work with .NET's implementation of regular expressions. A coworker of mine just used it to build a parser for Sql Reporting Services RDL files.  Steven's own RegexPal is a fairly intense implementation of regular expressions in javascript, complete with syntax highlighting.

}

Monday, May 12, 2008

Workaholism

{

Matt from 37Signals blogs about workaholics with the following assertions: they don't get as much done (most of the time) and they focus on inconsequential details.

Many leapt to the defense of workaholics - people who, it seems, are workaholics themselves. Because I'm often labeled a workaholic I'm trying to see past my emotions and yet it still doesn't smell like the truth to me.

And even more so because this weekend I watched Triumph of the Nerds, Cringley's chronicling of the personal computer industry from it's humble roots in what would become Silicon Valley.  As he interviewed people, I couldn't help but think that software development is experiencing a culture change.  The people who got the boat off the ground were almost entirely obsessed with their work, even down to the details.  I have a hard time imagining an Andy Hertzfeld, Woz, or young Bill Gates as a 501 developer.

Even if you go forward a few years, guys like John Carmack don't fit the mould of "balanced life/time to go pick up my kids and watch TV!"

These days though, I think what used to be hobbyism is now simply work and fair game for any person who wants a way to earn their keep and "clock out" for life afterwards.  This is not to say that it wasn't that way before, it just seems like much more commitment was involved.  Or maybe the moral is that no one with a 501 development attitude did anything noteworthy.

But even as I write that and play my hand as a kid who grew up on the folklore of the early computer industry I have to do a gut check because me staying at work late building yet another website for someone is not the same as writing the first GUI.  Not even close...

I take away the notion that there isn't necessarily a direct relationship between time spent at work and productivity but I also know that if I had the 9-5 attitude with no tendency to "get into" my profession, I might as well be an accountant. And as grandiose as it may seem, I'd love to have one idea that really matters versus a lifetime of mediocrity so I could rush home to have a "life."

}

Saturday, May 10, 2008

Old Computer Books

 

{

I was recently feeling ashamed of myself after reading Atwood's Programmers Don't Read Books...  post for what he called Programming book pornography: "The idea that having a pile of thick, important-looking programming books sitting on your shelf, largely unread, will somehow make you a better programmer."  To clarify, I actually do read the books I have bought but I'm guilty of keeping a full shelf for the sake of showing off my long and continuing struggle to be a good programmer. 

One way I can soften this sort of conceit is by thinking of how I'm really proud and boastful of my friends in real life who do things that amaze me. I'm not shy to boast on their behalf.  In the same way a lot of these old books are like old friends that have seen me through some pretty turbulent times.  I carried Francesco Balena's Programming Visual Basic 6.0 around for years when I was training people on VB6, COM, and ASP.  Another set of heavy books I spent many a quality night in a hotel room with were Gary Cornell's Core Java and Core Java Advanced Features. I don't have a formal computer science education but I consider a large part of my education the 7 or so years I spent on the road, in various hotel rooms, reading and practicing what I needed to know.

If truth be told there are a few there that I didn't get much out of.  I never did run Slashcode and I never did more than tinker with Bryce.  But I'm not ashamed to say that I had hopes of doing so that time supplanted with other things.

I packed them away and made room for some of the books I have piled on top of the shelves.  Since I don't travel much and remain in project mode I'm not as efficient about reading what I have but a smaller shelf is more tidy and palatable.  I won't wait so long before my next big cleanup.

So the big question: what to do with these books?

}

Thursday, May 08, 2008

Processing.js

{

John Resig of jQuery fame has released a library called Processing.js for javascript graphics. Yes, you read that right: Javascript graphics.

Earlier this week I was in some training and the instructor asked what future we saw for Silverlight.  My response was that I can't drink the koolaid just yet; while there are certainly applications in streaming media in which Silverlight will compete to the death with Flash, for web applications I see people taking Javascript to the level where its maturity with the browser makes most applications feasible. I also like the competitive environment around the Javascript libraries - the Dojo, jQuery, YUI, Scriptaculous, and other people trying to outdo one another just means better ideas, faster turn arounds, and a better experience. 

}

Monday, May 05, 2008

C# Extension Method for Generic Collections

{

Tinkering a bit with extension methods tonight, inspired in part by Scott Hanselman to write something I've frequently needed with generic collections: to spit them out in some delimited format.  Here are the extension class and method:

    static class EnumerableExtensions
{
public static string AsDelimited<T>(this List<T> obj, string delimiter)
{
List<string> items = new List<string>();
foreach (T data in obj) {
items.Add(data.ToString());
}
return String.Join(delimiter, items.ToArray());
}
}





You can spit out your delimited instances of any List<T> now:

            List<string> test = new List<string>(new string[] { "David", "Morgan", "Philip" });
Console.WriteLine(test.AsDelimited(" => "));

List<int> primes = new List<int>(new int[] { 2, 3, 5, 7, 11, 13, 17 });
Console.WriteLine(primes.AsDelimited(" , "));





}

Thursday, April 24, 2008

Twy

{

I'm still trying different things with Twining.  I'd thought about writing some "front end" type experience for usage but it really crystallized as a need when I showed it to a person I know and there seemed to be a disconnect in how it could be used.  For me it's natural to set my path environment variable, launch favorite text editor X and then run things from the command line or a script, but it's a nuisance if you're used to a one stop shop for being able to use some tool.  And as much as I want language as the focal point in the word "tool" there is something practical in the notion of something you download and click a button to execute with.

Enter Twy, which I pieced together after looking at a few samples of a hosted DLR engine in a Windows Forms app.  Now one need not figure out how to install or configure anything, or worry about creating and disposing of script files.

If you want to write something that hosts the DLR engine, take a look first at these samples on Voidspace.  There are other samples online if you hunt and peck but be aware that things have changed between the various releases of IronPython.  A few gotchas for me:

1. Redirecting standard output:

// where engine references the ScriptEngine type
// and ms references a Stream of some sort
engine.Runtime.IO.SetErrorOutput(ms, Encoding.UTF8);
engine.Runtime.IO.SetOutput(ms, Encoding.UTF8);



Many examples of this are deprecated for the IronPython 2.x beta

2. Referencing classes in mscorlib:

Be aware that doing the following:

import clr
clr.AddReference("System")



is not going to be enough to get types out of mscorlib.  Although types will load from System, you'll need to get a reference to the assembly directly if you plan to use it in your hosted engine.  I had a little trouble with the StringBuilder but easily resolved it with the following after a tip on the IronPython mailing list.

Assembly assem = Assembly.GetAssembly(Type.GetType("System.Text.StringBuilder"));
scope = engine.CreateScope();
engine.Runtime.LoadAssembly(assem);



3. The only novel thing I did that I didn't see a lot of was loading a module so that you could utilize it with your hosted engine.  I added Twining.py to the project and set Visual Studio to copy it to the compile destination.  I then have the following code which keeps the module available for later use:

string p = Path.Combine(Environment.CurrentDirectory, "Twining.py");
scope = engine.Runtime.ExecuteFile(p);

// later on:

ScriptSource source =
engine.CreateScriptSourceFromString(input,
SourceCodeKind.Statements);
object res = source.Execute(scope);



All in all not rocket science, it's amazing how much power one has at their fingertips in such a small application.  I would love to see other modules, especially ones that define some interesting type of DSL, have utilities like this that let you play around without much effort.


Oh yeah, the project and source.  Download it here, I'll clean up a bit more later.


}

Sunday, April 20, 2008

Getting better with meta-thinking

{

Some excerpts from a great post from Ola Bini, one of the JRuby core developers:

In short, I believe that being able to abstract and understand what goes on in a programming language is one way to become more proficient in that language, but not only that - by changing your thinking to see this part of your environment you generally end up programming differently in all languages...

A little further on, emphasis is mine:

... I call this meta-level thinking. I think it's mostly a learned ability, but also that there is an aptitude component.

Cheers for this as a "learned ability" which would give one pretentious enough to call his blog "Metadeveloper" some hope.

}

Saturday, April 19, 2008

Generic Enum Parsing in C#

{

Generics, as it were, are passe to talk about these days. However, I found myself dealing with enumerations on Friday and was a little surprised there wasn't an approach to parsing these out in a more generic fashion. I scribbled the following, perhaps it will be of value to someone:

enum Test { 
v1,
v2,
v3
}
public static T EnumParser<T>(string givenValue)
{
return (T)Enum.Parse(typeof(T), givenValue, true);
}
//usage:
Test val = EnumParser<Test>("v1");

}

Tuesday, April 15, 2008

Sense of urgency

{

One thing I’ve come to realize is that urgency is overrated. In fact, I’ve come to believe urgency is poisonous. Urgency may get things done a few days sooner, but what does it cost in morale? Few things burn morale like urgency. Urgency is acidic.
- read the whole post

Jason Fried of 37Signals neglects to mention one aspect that seems to come back over and over to haunt those of us who live with "urgency"; that it costs dearly to rework things that were done in a hurry.

}

From TFS to SVN

{

My project at work added some remote developers and it was decided that rather than try to figure out TFS, which we use for everything internally, we'd use SVN. I'm not used to SVN since we used Team Foundation Server for source control and Visual SourceSafe before that - I've used TortoiseSVN quite a bit to get source code from projects online, but never as a primary source control environment for a big project.

So far it's a breeze. I installed VisualSVN Server and configured repositories and users - this took about 10 minutes.  After that I was up and running with TortoiseSVN in about 3 or 4 minutes.

Hm...

Because in a parallel universe a completely different project I'm working on required me to install the TFS client for Visual Studio 2008.  On my super duper 4GB Ram, 3 Ghz, desktop machine at work it took about 45 minutes.

Just the client.

So yeah, I've been thinking about that contrast quite a bit all day.  One thing I think is interesting is the contrast between small teams as I heard discussed at CodeMash earlier this year and the features of TFS: all the note taking, task assignment, iteration,  etc, etc... On a "one to two pizza" team (e.g. a Google, Amazon), how many people go in depth with those features versus some massive team of developers (e.g. a government agency)?

}

Monday, April 14, 2008

Twining

{

Now has a its own location. I'll still post of goings on, but will keep the external site as a source of updates and documentation. There's a form there for feedback as well.

}