{
Derek Sivers writes about switching back to PHP from Ruby on Rails after attempting to rewrite cdbaby. Raganwald references an intersting series from Chad Fowler on "Rewrites" and why they are so difficult.
Although it seems to be a little disagreement over the existence of beautiful code, a refactor I did today was pleasant to my eye.
Starting with:
string result;
if (parameterLessCommands.Contains(commandName))
{
result = RunArglessCommand(user, commandName);
}
else {
string commandArg = RetrievePairCommandArg(commandData);
result = RunArgCommand(user, commandName, commandArg);
}
return result;
Ending with:
return
(parameterLessCommands.Contains(commandName)) ?
RunArglessCommand(user, commandName) :
RunArgCommand(user, commandName,
RetrievePairCommandArg(commandName));
I'll take it. ()?: is your friend!
I've always wanted to work for Microsoft. My first chance was right out of college when a professor of mine passed my resume to his friend up there. I had some embarrasing crap about how I'd always wanted to work for "the company." It was all true but I can imagine the HR person directing anything that sappy to the trash. Instantly.
But it's just as well - Steve McConnell has an interesting comment about how much time at Microsoft may be spent in meetings - for developers:
When I was at Microsoft in 1990-91 I probably spent less than 5 hours a week in meetings. In contrast, I had a former Microsoft employee tell me earlier this year that on the team he was on he was booked in meetings from 10:00-4:00 5 days a week. Lots of managers at other companies have told me that they're in meetings all day every day and get most of their "real work" done during evenings and weekends, so obviously there's a big difference between Microsoft 1990 and Microsoft 2007, and among different companies.
As I hit "publish" from my previous post on pivot tables, a thought struck me on another most excellent use for them. No, really - for the next job interview:
SELECT
CASE
WHEN I % 5 = 0 AND I % 3 = 0 THEN 'FizzBuzz'
WHEN I % 3 = 0 THEN 'Fizz'
WHEN I % 5 = 0 THEN 'Buzz'
ELSE CONVERT(VARCHAR(2), I)
END
FROM dbo.fnPivot(100)
I taught a T-SQL Programming class this week and in the process looked over some old books on the subject. One in particular I've enjoyed was the Transact-SQL Cookbook from O'Reilly - I have yet to find as novel an approach to SQL, coming from the ideas of set theory rather than tutorials on querying. I'm biased too, my best friend in highschool was Slovenian and one of the authors, Aleš Špetič, hails from that fine country.
A cool idea from the very first chapter is the pivot table, a numeric range that can come in handy for many different types of operations. The book, which is probably circa Microsoft SQL Server 7, demonstrates the building of a pivot table using some hardcoded insert statements followed with a cartesian join that generates the range.
It occured to me in SQL 2000 and higher one can use a User Defined Function and get all the benefits with a little bit more flexibility. Here is a simple approach to the same concept:
CREATE FUNCTION fnPivot(@BOUND INT)
RETURNS @Pivot TABLE(I INT)
AS
BEGIN
DECLARE @I INT
SET @I = 1
WHILE @I <= @BOUND BEGIN
INSERT INTO @Pivot VALUES(@I)
SET @I = @I + 1
END
RETURN
END
GO
The approach is different but the benefits are similar. A simple one from the first chapter is building a calendar of a given range of days. I've adapted it to use the function above:
SELECT
CONVERT(CHAR(10), DATEADD(d, i, CURRENT_TIMESTAMP), 121) [date],
DATENAME(dw, DATEADD(d, i, CURRENT_TIMESTAMP)) [day]
FROM
dbo.fnPivot(7)
date day
---------- ------------------------------
2007-09-13 Thursday
2007-09-14 Friday
2007-09-15 Saturday
2007-09-16 Sunday
2007-09-17 Monday
2007-09-18 Tuesday
2007-09-19 Wednesday
Kaizen is all about small improvements that never stop coming. With respect to Nregex, I plan to keep it moving as a project by spending small amounts of time on new features that will hopefully make it more useful.
Tonight's new feature, though it was really something I did on Saturday morning, is a bookmarklet that should make it a little easier to get into the site from elsewhere (like your favorite IDE).
A few weeks ago my boss noticed some latency issues, especially with larger documents. I've added a "manual" mode that will let you press a button or just hit your enter key to evaluate a regex, rather than it being processed as you type. Animated gifs give a little feedback on wait time.
If you have a request for a feature, please submit it here. If you have a handy regex you solved some problems with, please submit it too. I'm currently at work on a "library" that I hope to cover some basic regular expressions (phone, zip, ssn, and so on) with.
I was just missing the old Paul Graham, the one who would write wisdom for the type of programmer that I imagined myself to be. The most recent essay, Holding A Program In One's Head, is that treat I've been waiting for.
Scott Hanselman was noting that many people who'd updated the locations of their tools on his 2007 Ultimate Developers Tools List had emailed or contacted him asking him to update his reference.
He lamented the fact that they didn't simply use HTTP 301 redirects (Moved Permanently) which tools can easily use to update referenced links.
I must confess, I was one of those people. I just lazily made a default.asp that had one line:
Response.Redirect("http://www.nregex.com")
But 301 redirect are pretty simple whether you use .NET or lazily throw an ASP script somewhere.
'classic ASP
Response.Status="301 Moved Permanently"
Response.AddHeader "Location", "http://foo/bar.asp"
'.NET
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://foo/bar.asp");
Source: seoconsultants.
I embarrassed myself today (yelling at the work desk, telling everyone I'd take them to McDonalds) but with good cause: a tool I wrote some time back made it to Scott Hanselman's 2007 Ultimate Developer/Power User Tools List. The goal of the tool was simple: to do browser based evaluation of regular expressions using the .NET engine. Prior to writing it I would frequent Rexv.org but because the engines supported there were different, I'd usually have to do some conversion to get things to the .NET world.
There are quite a few .NET Regular Expression tools: Expresso, which is my first and favorite since I've used it longest, but also tools like Roy Osherove's The Regulator. The problem with these tools, however, was that as fat clients I wasn't always easily able to use them: I work on different machines (home, work, client sites) and also assist people quite a bit away from my desk.
There are also quite a few Regular Expression tools for the web, Rexv, which I mentioned before but also RegexPal. But these tools support either javascript or alternate implementations so patterns like (?<foo>\w+) usually return some kind of error.
The way Nregex works is pretty straight forward: I'm using YUI for the Ajax library and working with the .NET implementation of the regular expression on the server. A simultaneous goal of mine is to get into more of YUI because I'm always building little knick-knacks in javascript and I think it's the library to beat right now.
Of course it's a fledgling: I worked on it a few nights when I could and fixed bugs here are there when I had a moment. Please use it and give me feedback since that will be my biggest help in making it better.
One more thing: I'm trying to collect useful regular expressions. I'd like to build a good library of expressions to help users of the tool. Use the feedback form and let me know if you've got one you've found handy. Don't worry if it's not .NET specific, I'll do the translation.
#!/usr/bin/env python
f = open("c:\\temp\\Original.txt")
f2 = open("c:\\temp\\Unique.txt", "w")
uniquelines = set(f.read().split("\n"))
f2.write("".join([line + "\n" for line in uniquelines]))
f2.close()
function BuildArray(){
// just builds a random array to work with
var testArray = new Array();
testArray.push('Test 0');
testArray.push('Test 1');
testArray.push('Test 2');
testArray.push('Test 3');
return testArray;
}
function GetShiftOrder(testObject){
// this is what sorts things out
var upperBound = testObject.length;
var newOrder = new Array();
var shuffledArray = new Array();
builder:
while(newOrder.length < upperBound){
n = parseInt(Math.random() * upperBound);
for(i=0;i<newOrder.length;i++){
if(newOrder[i] == n){
continue builder;
}
}
newOrder.push(n);
shuffledArray.push(testObject[n]);
}
alert(newOrder + '\n' + shuffledArray);
}
from System import *
def multiples(num, thresh):
multi = []
for i in range(2,thresh):
m = num * i
if(m < thresh):
multi.append(m)
else:
break
return multi
primeThresh = 5000
print DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")
nums = range(2,primeThresh)
for n in nums:
nums = set(nums) - set(multiples(n, primeThresh))
print nums
print DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")
from System import *
primeThresh = 5000
print DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")
nums = range(2,primeThresh)
for n in nums:
for m in range(2,primeThresh):
try:
mult = n * m
if(mult > primeThresh):
break
nums.remove(mult)
except:
pass
print nums
print DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")