RailsConf 2008

Merry Hoopsmas

Posted by rick Thu, 20 Mar 2008 13:44:00 GMT

‘Tis the season again: March Madness 2008 is just about to kick off. In preparation for the High Holiday we’ve once again done way too much analysis work, gargled with way too many stats, to pick the bracket of 64 winners. For those playing along at home, here’s our notes on how we see the games unfolding:

Round I

Indiana vs. Arkansas:

Indiana should be able to beat Arkansas, during the normal season; the coaching question is hard to call; if Indiana gets to the line (which Arkansas has a tendency to give to opponents) they will make free throws. Almost too close to call. Given the latest history (IU 3-3 under new coach; Arkansas has decent recent wins). Final nod to Arkansas.

UNLV vs. Kent State:

UNLV will not turn over the ball, and you can’t steal from them. Both teams are strongly defensive. Kent State is a better shooting team and will get to the free throw line more often. Based on this, Kent State.

Mississippi State vs. Oregon:

Mississippi State is our highest-ranked #8, Oregon our 3rd-ranked #9. The game is played in Little Rock, which slightly favors Mississippi State. Statistically Mississippi State dominates the inside (rebounding and blocking #6, #2 in the country), Oregon is a great shooting team, but plays almost no defense. Oregon can shoot over Mississippi State’s inside game, and Oregon can put up points efficiently. Miss. St. is a horrible free-throw shooting team, though neither team lives at the line; Miss. St. tends not to foul. Quality of schedule gives it to Miss. St.

BYU vs. Texas A&M:

Both games are both great rebounding teams. Texas A&M on the road plays very poorly (vast difference in the ability to put up points). BYU is a much better shooting team and a great passing team. Both are decent % defensive teams, BYU much better @ 3pt% defense. We see BYU outshooting a low-scoring A&M road team.

Butler vs. South Alabama:

Butler will not turn the ball over. Butler shoots and makes lots of 3’s. South Alabama doesn’t appear to be playing teams which shoot the 3. Butler refuses to rebound, while South Alabama will rebound pretty well. Butler plays basically the slowest ball in the country (hence the rebound #s). South Alabama gets to the free throw line. Butler lost to Drake, played noone else in the 64. Butler is senior-loaded and has been to the tournament a lot. Game is being played in Birmingham. Looks like Butler (even given locale, though we might like to see it go the other way, and it’s a hard call).

Gonzaga vs. Davidson:

Game is being played in Raleigh, NC. Davidson #1 10, Gonzaga #4 7. Both teams have some close losses, some strange losses, a number of easy wins, etc. Davidson will not go to the free-throw line and will not turn over the line. Many of the team stats are similar. Both teams have been to the tournament a number of times. Based upon past Gonzaga history (other than the Munson coached year), Davidson looks marginally better.

Miami vs. St. Mary’s:

St. Mary’s has the best assist defense in the country :-) St. Mary’s defends the 3 very well, and has better points-per-posession and ppp defense. Miami plays a better schedule. Miami shoots great free throws, much better than St. Mary’s. Miami has better (Pomeroy) adjusted offense, St. Mary’s has better defense. Miami can’t seem to win a road game. This is a close call, but the road record is the deciding factor.

West Virginia vs. Arizona:

Arizona shoots free throws well, and Thuggins will put Arizona on the line. Both teams are fairly low-possessions, so a low-possession game. WV blocks a lot, but shoots poor free throws. WV plays an inside game. AZ will shoot the three and get fouled. WV will outrebound AZ. AZ’s defense is horrible. Arizona’s Pomeroy SoS is unbeatable, and they came out of a tough non-conference with only 2 losses (Memphis & Kansas). WV has performed better recently and in their conference. Slight advantage to WV due to locale. Push to WV.

St. Joseph’s vs. Oklahoma:

St. Joe’s is #2 11, Oklahoma #4 6. They play essentially an identical pace, a slow one. Oklahoma defends, St. Joe’s offends. Pomeroy gives Oklahoma a tougher schedule than St. Joe. Game is at a neutral location. Both teams played Gonzaga (St. Joe’s lost, Oklahoma won)—both early. St. Joe’s gets to the foul line and tends to make them. Oklahoma played a tougher schedule. Slight edge to Oklahoma.

USC vs. Kansas State:

Kansas St. has devastating rebound stats. Same points-per-possession stats. Kansas State plays a fast game, USC more down-tempo. USC has a stronger Pomeroy schedule (see also, PAC-10 inflation). Most stats, other than seed, favor Kansas State. Game is being played in Omaha, NE. USC will hit the 3 and Kansas State doesn’t defend that. Kansas State will take it inside. This looks more like and 8-9 instead of a 6-11. Kansas State.

Marquette vs. Kentucky:

Kentucky is playing without Patrick Patterson. Kentucky is prone to turn the ball over, and Marquette is prone to steal the ball. Kentucky has serious problems with point production. No real reason to pick UK.

Baylor vs. Purdue:

Purdue defends, plays slow; Baylor offensive, plays fast. Baylor wins on points-per-possession. Purdue causes lots of turnovers. Baylor gets to the line and shoots better. Purdue is very pesky. Baylor appears to have trouble with slower inside-bound teams (aka Purdue), and Baylor seems to struggle away from home.

Notre Dame vs. George Mason:

Notre Dame will get every rebound. ND our 2nd #5, GM our worst 12. GM played very few notable teams, won their tournament. ND wins on Pomeroy numbers, SoS, and most stats. ND.

Clemson vs. Villanova:

Clemson cannot shoot free throws wroth a damn. Clemson plays a fast ballgame. Clemson’s stats (other than free throws) dominate Villanova’s.

Michigan St. vs. Temple:

Michigan State will outrebound, has comparable offensive stats, and defends better than Temple. Mich. St.

Drake vs. Western Kentucky:

Western shoots well and defends well, playing a pretty fast game. Drake slows the hell out of the game, won’t turn it over. Western commits 20+ fouls a game and Drake is the #8 FT% team in the country. Neither team is playing a strong schedule. Definitely the closest of the 5-12 matchups. Drake’s FT w/ WKU’s fouling gives Drake the win.

Washington State vs. Winthrop:

Winthrop will not hit a free throw, Wash. St. does OK. Both shoot the 3 fairly well, Winthrop defends it well. Wash. St. plays incredibly slow ball. Wash. St. doesn’t rebound; Winthrop does ok on rebounding. Washington State will not turn the ball over. Winthrop has low adjusted Pomeroy offensive efficiencly, won’t play a fast game. Washington State has good off/def Pomeroy numbers, but is in the PAC-10. This will be a slow-ass ballgame. Winthrop’s offense seems anemic, and they rely on a streaky shooter. Washington State’s offense seems limited as well. Game will be close; unlikely to beat Notre Dame. Winthrop’s defense could slump Washington State, so push for Winthrop win.

Vanderbilt vs. Siena:

Siena wants to steal the ball, and refuses to turn it over. Points per possession is similar. Vanderbilt’s defensive PPP is worse than Siena’s. Siena doesn’t foul (question about strength of schedule). Siena doesn’t defend the 3 well, while Vanderbilt is a great 3-point team. This will be an up-tempo game. Both teams give up a lot of offensive rebounds. Siena will steal the ball. Vanderbilt’s adjusted Pomeroy stats are better than Siena’s. Vanderbilt’s SoS numbers look significantly better. Vanderbilt has trouble on the road. Could be a close game. Siena’s center doesn’t score much and they look to be smaller inside (Pomeroy height). Looks like Vanderbilt will take it inside if they have trouble from the permiter. Vanderbilt for the win.

Pitt vs. Oral Roberts:

Pitt is offensively stronger, Oral Roberts is comparably defensively strong. Both teams are comparable in a lot of statistical areas, playing a similar pace of game. Pitt has better SoS. Pitt is on a recent good run and seems to scrap it out in the tournament. Oral Roberts hasn’t got anything compelling to overcome Pitt’s rebounding skill, scrapping, etc.

Connecticutt vs. San Diego:

Statistically there’s really no contest here. UConn. :-(

Louisville vs. Boise State:

Location slightly favors Louisville (Birmingham). Boise St. plays an uptempo game with strong shooting. Louisville defends the shot well. Boise State passes well, though so does Louisville. Adjusting for opponents Louisville’s O/D stats look much better than Boise State’s. Louisville has more tournament experience. I think Pitino will bring Louisville through over a team in a down conference year.

Wisconsin vs. Cal. State Fullerton:

Wisconsin slows it down, plays strong defense, Fullerton plays more offensively. Only Duke seems to have gotten Wisconsin out of their game. Wisconsin gets opponents to foul them and then lives at the line. Fullerton will foul. Wisconsin’s adjusted stats strongly favor Wisconsin (including #1 in defense in the country). Wisconsin’s schedule is vastly stronger than Fullerton’s. It’ll still be a close-scoring game due to the pace, but Wisconsin should prevail.

Stanford vs. Cornell:

Stanford rebounds well, Cornell doesn’t rebound at all. Cornell shoots very very well (5, 6, 11 in country wise) .. 76.27 from the line, though they don’t tend to get to the line (presumably due to the Ivy League competition). Stanford play a bit better offense than Cornell does defense. Game is being played in Anaheim. :/ Cornell’s opposing offense strength sucks. Stanfords adjusted #s look vastly better (even given PAC-10 inflation). Cornell does have an inside presence (7-footer) and strong 3-point shooting, played strong against Duke and beat Siena. It will be a closer game than people probably expect. Cornell is going to play a faster pace than Stanford. Don’t see Cornell winning in Anaheim though.

Georgia vs. Xavier:

Georgia is on a run. :-) hahahah. Georgia’s Gaines and recent home wins shouldn’t be enough to overcome Xavier’s statistical dominance.

Tennessee vs. American:

American turns the ball over a lot esp. given their slow pace. UT will get you to turn the ball over. American shoots 4th 3pt % in the country, but UT defends @ 20th against the 3. UT will outrebound American. Birmingham location favors UT. UT.

Georgetown vs. UMBC:

UMBC is very efficient at scoring, but plays little defense. UMBC never turns over the ball. UMBC is in a bad conference. Georgetown plays good defense. Another slow-ass game. UMBC never turns over the ball, though Georgetown does. Don’t really see how UMBC can be bad on defense in a bad conference and defeat Georgetown.

Texas vs. Austin Peay:

Texas has the #1 TO and TO rate stats in the country. Austin Peay steals a lot but Texas never lets that happen. Austin Peay doesn’t rebound. Texas doesn’t pass the ball. Texas is strong offensively against strong defenses, Austin Peay has horrible SoS numbers. Don’t see them stopping Texas.

Duke vs. Belmont:

Both teams run up and down the floor. Belmont’s defensive stats are too weak to keep up with Duke.

Round II

Notre Dame vs. Winthrop:

Notre Dame is better offensively, while Winthrop is stronger defensively. Notre Dame is a great 3pt% team (#3 in the country) and passes great. Winthrop’s defense is possibly strong enough to pose a challenge to Notre Dame’s offense. Notre Dame is a great rebounding team, Winthrop is decent, especially considering how slow of a game they place. The game will probably be a good one. Doesn’t appear as if Winthrop has the offensive guns to make it past ND.

Clemson vs. Vanderbilt:

A lot of stats are very similar. Clemson will clean up on the boards, but Vanderbilt may kill them on the free-throw line. Clemson defends the three very well, while Vanderbilt relies a lot on the three. Could be matched up pretty well, guards vs. inside game. Clemson will steal the ball. Vanderbilt has trouble on the road. It’s a close close call, but Vanderbilt probably loses on the road.

Pitt vs. Michigan State:

Tiny mile-high edge to Pitt playing in Denver. Mich. St. shoots better and defends shots better than Pitt. Both have great Orp stats. The game will be on the slower side. Nietzel is an unknown quantity, though usually shows up in the tourney. Mich. St. shoots much better free throws. Mich St.’s Pomerowy adjusted numbers are better than Pitt’s. Pitt will probably outrebound Mich. St. Mich. St. seems to be more likely to prevail.

Drake vs. UConn:

Drake beats UConn in both points-per-position (offense/defense) categories. Drake plays slow, doesn’t turn it over. Drake has good Pomeroy adjusted numbers, wrapping around UConn’s. Drake shoots great free throws but doesn’t necessarily get to the line, and UConn isn’t inclined to send anyone to the FT line. UConn gets lots of fouls, but Drake doesn’t tend to commit fouls. Drake is playing outside ball, UConn playing inside ball, blocking every thing that comes into the paint. We see Drake winning on the outside.

Oklahoma vs. Louisville:

Both teams are bad at the free throw line; UL puts other teams there, but it might not make much difference in this game. UL is slightly better defensively. Louisville shoots better, slightly. UL’s Pomeroy adjusted numbers are a little better, while Oklahoma’s SoS is a little better. OK has Griffin and Longar Longar in the middle. UL has Padgett distributing the ball. UL has been pressing lately. It may well be a close game, but we give Louisville the edge.

Kansas St. vs Wisconsin:

This will be Wisconsin’s slow ball against KS’s fast ball. Can Kansas State get to the inside against Wisconsin. Points-per-possession are dead equal, but Wisconsin’s Ppp defense is spectacular. KS rebounds incredibly well, Wisconsin well. Omaha slightly favors Kansas State. Again a question of whether Bo Ryan ball can overcome a skilled fast-paced opponent. No matter how Allen picks this it will be wrong, because Wisconsin is involved. Wisc. hasn’t played a fast-paced game since January. We give the edge to Kansas State.

Marquette vs. Stanford:

Both teams get offensive rebounds, but Marquette allows the other team to get them, significantly. Marquette shuts down the 3, but Stanford doesn’t really shoot it. Marquette will steal the ball, but Stanford doesn’t allow too many steals. Ppp (both offense and defense) are pretty much identical. Pomeroy adjusted numbers are virtually identical. SoS is pretty much the same too. Only one common foe (Sacramento State) that they both beat about the same. Offensive stats are pretty identical. Steals vs. blocks, w/ t-o’s end up averaging out to be about the same. This is a very close statistical matchup. Stanford plays slower, Marquette faster. Marquette beat Wisconsin (@ Wisconsin), which is stylistically similar to Wisconsin (close game, made a few more shots, a couple more free throws). The game is being played in Anaheim, which favors Stanford. Marquette is 7-3 in last 10, Stanford is 6-4. Marquette’s wins are maybe slightly better more recently. This game is pretty much a dead heat. Given that, we pick Stanford for local court advantage.

Purdue vs. Xavier:

Pomeroy adjusted stats favor Xavier offensively, fairly close defensively. Purdue had a rough pre-season. Xavier will outrebound. Purdue is forcing lots of turnovers, and Xavier will turn the ball over. Purdue is going to send Xavier to the line where they are very good. Xavier has good shooting %s. Will Purdue’s forcing turnovers, stealing and blocking overcome their tendency to foul and put Xavier on the line (+ Xavier’s good general shooting)? This is a hard-ass game to pick. The consideration of fouls called is reduced, generally, in the tournament, by fewer calls. We call this an OT game. Seth Davis picks Xavier to go far. We choose Purdue.

Butler vs. Tennessee:

Butler never turns over the ball, plays a slow pace, doesn’t rebound well, defends the 3 well. Butler shoots the 3 better, gets to the free-throw line more. UT relies on turning over the other team, running the ball and hitting the 3, as well as bringing some inside (if Chism, etc., aren’t in foul trouble). Pomeroy numbers for TN are somewhat better, and TN played a hard schedule. Butler is a vastly better free-throw shooting team. TN commits a lot of fouls, though fewer are probably called in the tourney. TN passes the ball better than Butler, somewhat. Not clear that Butler has played anyone who wants to score a lot of points. Tennessee seems to sometimes be able to win against a slower opponent, but not clear they’ve played a team like Butler. Pick Butler.

Davidson vs. Georgetown:

Georgetown passes very well (esp. for a slow possession team), Davidson also passes pretty well, but not as well. Georgetown scores in the paint very well. Hibbert is overrated. Ppp Davidson is right with Georgetown. The Pomeroy adjusted efficiencies favor Georgetown somewhat. Davidson played Duke & UNC tough @ neutral sites, played a tough schedule but didn’t put in a lot of wins; beat Winthrop decisively late in the season. Georgetown plays a tougher schedule, seems to occasionally get a ref on their side ;-) Georgetown shoots poorly from free throw, Davidson better; but Davidson doesn’t send people too often, and Georgetown even less. Raleigh location somewhat favors Davidson. Davidson could do it… it’s a somewhat bold pick.

Saint Mary’s vs. Texas:

Texas beat them soundly @ home earlier in the year. In that game apparently St. Mary’s tried to take it inside and got stomped and were forced to go outside where they didn’t convert. Rick Barnes is a shithead coach, but, still, is he going to lose this one? Texas.

Duke vs. West Virginia:

Duke wants steals & 3’s. WV won’t turn it over but doesn’t defend the 3 well. Duke is very fast-paced, while WV is significantly slower. Duke gets a lot of rebounds (they shoot well, but play a fast tempo). WV doesn’t shoot well. Duke probably cannot put Demarcus Nelson (6’4”) on Joe Alexander (6’8”). Neither team is shooting great free throws. Duke has better Ppp numbers (including adjusted Pomery numbers). Not clear what WV can do to overcome Duke here.

UNC vs. Arkansas:

Arkansas defends a bit better than UNC, but: UNC has Orp rank #1, offensively great stats. Hill & Townes aren’t capable of stopping Hansbrough inside. UNC.

Kansas vs. Kent State:

Kansas is the #1 Ppp offense, adjusted Pomeroy offense, #2 national assists, #21 Orp @ a #119 rank possession pace. Neither team is a stellar free throw % team. Kent plays very slow ball. Kansas puts up a lot of points. Kent’s strategy should be: foul early, foul often. Playing in Omaha, an adjusted 30 minute drive from Lawrence. Kansas.

Memphis vs. Mississippi State:

Rick Stansbury—moron; Dorsey, head case. Miss. St. will turn the ball over, while Memphis will not. Some major shot blocking (a “block party”, in fact). If Dorsey gets in trouble, Memphis is in trouble; and Dorsey is often in foul trouble. Memphis didn’t play much lately (C-USA), other than UT, which was a complete collapse of discipline, and they lost @ home. Memphis has only had one loss; only played UConn, OK, Gtown, w/ big men. Big men vs. Big men. Both teams shoot poorly from the line, but neither really fouls a lot. Miss. St. turns the ball over a lot, while Memphis looks to steal it. Question: if Memphis gets challenged for the first time in a long while, how do they respond to it? Based on the turnovers, probably see Memphis coming out of this.

UCLA vs. BYU:

Have identical points rankings, though different tempos (BYU much faster). UCLA doesn’t shoot the 3, while BYU will do inside or outside. UCLA’s Mbah Moute is maybe injured (maybe just nonsense). BYU rebounds defensively pretty well, but doesn’t do much offensive rebounding at all. They’re playing in Anaheim. UCLA is vastly better at the line than BYU. UCLA dominates the adjusted Pomeroy stats (including PAC-10 inflation). Can’t see BYU making this happen.

Round III

Louisville vs. Butler:

Butler plays slow ball, Louisville significantly faster. Butler will not going to turn it over, nor rebound the ball. Louisville shoots 65.5% free throws, Butler 73%. Louisville defends the three very well, while Butler takes a shit-ton of threes. The question seems to be can Louisville defend the 3 well enough while not getting stuck on the line bricking free throws. We don’t see Butler pulling it off, as we think Louisville will shut down the 3.

Davidson vs. Kansas State:

Kansas State outrebounds, but will turn over the ball a lot more often. Davidson never goes to the free throw line, though they shoot there decently. Davidson shoots better, and Kansas State doesn’t seem to be defending all that well. Kansas State fouls a lot. Questions about Beazley’s health. Picked Davidson.

Stanford vs. Texas:

Playing in Houston. Texas never turns the ball over. TX plays poorly against the Big-10 (Rick Barnes in effect). Common foes—TX beat UCLA @ UCLA (Stanford lost to them 3 times). By transitivity, Big-10 > PAC-10 (see Ballman for a proof that exceeds the margin space). Stanford outrebounds Texas, gets to the line a lot better, both shoot about 69% from the line. TX shoots the 3 better, though Stanford doesn’t really shoot the 3. Can Stanford stop Augustin/Abram? Q: Does Rick Barnes foot-shooting outweigh playing in Houston? Can’t see TX doing this, if they couldn’t do it last year with Durant. Stanford.

Purdue vs. Duke:

Duke is fast-tempo; Purdue down-tempo. Duke shoots 3’s well, Purdue doesn’t really defend it well. Purdue shoots slightly better free throws, defends slightly better. Purdue is slightly better defensive Ppp, but much worse offensively. Otherwise, Duke beats them in pretty much every statistical category. Duke doesn’t have a big guy, but neither does Purdue.

UNC vs. Notre Dame:

Once again, UNC doesn’t leave the greater Tarheel Metro Area (Charlotte). Harangody vs. Hansbrough. UNC plays a fast pace, somewhat faster than ND. They both have great offense #s. UNC shoots inside better, ND shoots the 3 better. Both shoot free throws well, rebound well. TO’s are a push, but UNC gets more steals. UNC plays against better defenses than ND, opposing offenses are basically identical. If any team in this quadrant is going to beat UNC, it’s ND. Probably one hell of a ballgame, but UNC probably wins it.

Kansas vs. Clemson:

Clemson bricks free throws. Kansas rebounds great and has an incredible offense. The few games KU lost one was a rivalry, one was OK St. slowing the game down, and the other was really won at the foul line. Don’t see Clemson doing it.

Memphis vs. Michigan State:

Michigan State passes the ball very well. Izz in the houzze. According to Ballman, Izzo hasn’t had a recruiting class that hasn’t been to the Final Four… this would be the first (update: this stat is a year off, they have one more year). Michigan State is rebounding much better than Memphis. Memphis’ Ppp’s are better. Memphis is almost the worst free throw shooting team in the country, Michigan State is much better. If Memphis’s Dorsey is committing fouls, Memphis will suffer for it. Memphis is defensively stronger. RIMBoy has been feeling the Memphis. Dead heat. We call it for Memphis still.

Drake vs. UCLA:

Phoenix anti-UCLA sentiment in effect. Both shoot free throws well. Drake doesn’t offensively rebound as well. UCLA & Drake are both playing pretty slow pace. UCLA is much more balanced than the UConn team we picked Drake beating. UCLA.

Round IV

Memphis vs. Stanford:

Questions as to the tree’s probation status and sobriety. The Lopezes vs. the Dorsey. Q: does the free throw shooting finally catch up with Memphis? Memphis defends the three very well. See Lopezes getting over on Dorsey, making it up on the line and winning.

Davidson vs. Kansas:

Can’t see Davidson going any further.

Duke vs. UCLA:

Playing in Phoenix. Duke’s tempo is a lot faster. Duke will shoot the three, and UCLA probably won’t defend it. Neither team will turn over much. Ppp numbers (Pomeroy adjusted) are both in the upper echelon; SoS comparable; so dead heat on Pomeroy once PAC-10 inflation taken into account. See Duke coming out of there.

UNC vs. Louisville:

Can Padgett + Caracter take out Lawson & Hansborough in Charlotte? What would UL have to do? UL can’t shoot free throws either. UNC comes out of this one.

Round V

UNC vs. Kansas:

Roy Williams vs. the ghost of Roy Williams, in San Antonio… This will be an awesome ballgame. Kansas has better stats than UNC, generally, though they are both dominant teams. Pomeroy generally favors Kansas. Both teams shoot > 70% from the line (UNC has the advantage there). UNC’s first away game since, what, February. Kansas plays defense, how novel. Kansas.

Duke vs. Stanford:

Both play reasonable defense, Duke has slightly better offense. Duke has no inside game, against Stanford’s twins. Stanford owns offensive rebounding. Turnover rate is comparable. Both are kind of crappy FT shooters. Coach K is too good of a coach. Duke shoots the 3 and steals the ball.

Championship

Kansas vs. Duke:

Duke fouls more; they both shoot about 70% free throws. Kansas rebounds better; they shoot the 3 about the same, Duke defends the 3 a bit better. Bill Self vs. Roy Williams. There’s a first time for everything.

Tags , ,  | no comments

Object Daddy

Posted by rick Tue, 27 Nov 2007 15:14:00 GMT

I’m posting at a new site (b.logi.cx) ... more news on that later. The first article is about a new piece of software I’m developing called Object Daddy, meant to do away with the need for Ruby on Rails fixtures and to greatly ease ActiveRecord model testing. The article about it is LONG, but don’t let that scare you, it’s all in good fun.

Tags , , , , , , , , ,  | no comments

connect 12 show makes Nashville Scene "Critics' Pick"

Posted by rick Wed, 29 Aug 2007 17:54:00 GMT

Check it out—our art show this weekend is listed as the Critics’ Pick.

“CONNECT 12 This exhibit, curated by Ben Vitualla, features the diverse works of 12 of Nashville’s longtime arts warriors. The goal of the exhibit is to educate the viewer about the history and continued growth of our local arts community. Painter Andee Rudloff has exhibited with Untitled Artists and Plowhaus Artists’ Cooperative, in addition to being involved with the successful Arts in the Airport program. Her dreamy landscapes are meant to reflect a sense of memory. Untitled’s husband-and-wife teams are also included in the September exhibit. Alesandra Bellos is “giving away her dreams” in a performance art piece at the opening reception. Her husband, Rick Bradley, is doing an interactive piece featuring monitors showing repeated imagery that explores the idea of machines expressing emotions. Eric Denton will exhibit his quirky photographs in the show alongside wife Tiffany Denton’s fiber collages. Audience participation is encouraged in three installations and one performance art piece. With the majority of Art at the Arcade spaces having stellar shows opening this month and the McKay Otto/Monica Cook show at TAG, downtown is the place to be this Saturday night. Opening reception 6 to 9 p.m. Sept. 1 at Dangenart Gallery; runs through Sept. 28. —BRITTANY CONNER

See ya there!

Tags , , , , ,  | no comments

I'm in an art show this weekend...

Posted by rick Tue, 28 Aug 2007 19:04:00 GMT

Called “Connect 12”. From one of my friend Ben’s press releases:

connect 12

Connect 12 exhibition at Dangenart Gallery:
From September 1 through September 30
Twelve Nashville artists will showcase their work at Dangenart Gallery.

Curator Ben Vitualla has invited Eric Denton, Jimi Benedict, Erika Johnson, Daniel Lai,Samantha Callahan, Sean Jewett, Rick Bradley, Alesandra Bellos, Tiffany Denton, Chris Hill, Andee Rudloff, and Shana Kohnstamm to present work of their own choosing alongside work of his own.
“As curator of this exhibition, my goal is to showcase local artists who have been a fixture in the Nashville visual arts community. This exhibition is an example of the importance of community in the Nashville visual art scene. As a result of years of exhibiting in Nashville, I have been impressed and surprised by the development and direction of local artists’ work. I have compiled a group of artists with varying disciplines, working in varied media. The first exhibition representing these diverse talents in city of Nashville will be called Connect 12,” Vitualla states.

The Nashville visual arts community has been steadily growing since 2000, partly because of the support of individual artists and privately owned galleries. Individual artists’ willingness to help each other with projects and exhibitions in Nashville have kept the visual arts community moving in an upward direction.

A group that was founded in 1991 and resurrected in 2002, the Untitled Artist Group, has given local artists opportunities to show their work in a welcoming and uncensored setting. Creative ideas are shared within this artist-run collective and many relationships formed between talented individuals with diverse backgrounds. Included in the group are painters, sculptors, mixed media artists, installation artists, and photographers. These individuals have worked together with varying degrees of experience from professional working artists to emerging artists paving their own way into the Nashville gallery scene.

Much like the Untitled Artist Group, the Connect 12 exhibition will consist of a diverse group of artists, ranging from a multi media artist who uses monitors, repetitive imagery and viewer participation; an installation artist whose work explores the female gender and topics in female relationships through photography and ephemera; a painter who creates beautiful paintings based on pain and healing; to a graphic designer who continues to work in an effort to make something the public will love and buy; a mixed media artist who reverts back to objects from childhood to capture back the lost youth and to relate the object to the problem of today; and an artist with a long family tradition of working with textile who create expressive fabric collages. Six additional artists working in diverse media round out the show.

“Creating an exhibition with twelve artists who work with various media will be a great undertaking and challenge because each artist has his or her own specific requirements and themes. I will take this challenge and create a show that will educate the viewer and define the visual artist as well as the visual arts community in Nashville,” says Vitualla.

For more information about Connect 12, the artists featured in the show, or Dangenart Gallery, please contact Ben Vitualla at connect.twelve@gmail.com or visit Dangenart.com


PRESS: TENNESSEAN: Downtown Dangenart Gallery celebrates friendship, growth

Connect 12
Exhibition runs September 1, 2007 to September 30,2007
Dangenart Gallery, Nashville, TN
224 – 234 5th Ave. N.
Suite 83 The Arcade
Nashville TN 37219

Tags , , , , , ,  | no comments

Reproducible ETL (aka: "Evaluating ActiveWarehouse-ETL vs. a bunch of GUI bloatware")

Posted by rick Mon, 23 Jul 2007 13:29:00 GMT

Our data migration problem

At my day job (large mental healthcare non-profit) we’re pushing out a Rails-based electronic health record. We have a number of partners who will be using the same system, hosted separately, and contributing data into a common anonymized warehouse of clinical research data. Every installation will end up with not only a production database for day-to-day transaction use, but also a read-only reporting database to offload longer-running report queries onto. Of course current and ongoing development requires database instances for developers, for testing, and for staging prior to production release. Some of the data which feeds the production and development instances comes from static sources (fixture files or similar), while other data comes from conversion of data from a legacy database with significantly (bizarrely, some (e.g., I) might say) different layouts. All of this constitutes a significant data management problem (each of the arrows in the below diagram comprises a data migration task that varies in some way from each of the others).

We have been converting data on a nightly basis for well over a year now, but a couple of months ago, the multiplication of data sources and sinks, along with schema migrations, began to get overwhelming enough that we couldn’t keep up and the ball was, as they say, “dropped”. Realizing the scope of the data management problem, we sketched out what it would take to manage our data if we had to write a tool to do it ourselves. We took a look around at what products (open source and proprietary) were available for data migration (or as the martketroids call it, “ETL”—“extract, transform, and load”). In the midst of all this a few of us went to RailsConf, where I was able to sit in on Anthony Eden’s talk Data Warehouses with ActiveWarehouse. Part of ActiveWarehouse is an ETL tool, ActiveWarehouse-ETL, which looked interesting from we come from (Ruby development). If we had to write our own we would’ve written it in Ruby, with an eye towards testing, automation, reproducibility, and version control of the ETL specs, so finding a Ruby tool for ETL already out there seemed like a step in the right direction.

Learning via reproducible data migration

In doing our research on ActiveWarehouse-ETL we noticed that the documentation is a bit weak but getting better. After grovelling around the web for a while we decided that it was unclear whether AW-ETL was mature enough to handle the data migration work we wanted to throw at it, and we had questions as to whether the ETL tool was too geared for data warehousing to do data migration in a mostly transaction database environment. That is, only one of the many databases with which we’ll be working will have any data warehouse “cubes”, “dimensions”, “facts”, etc. The rest are Rails-ish or reporting-ish standard databases. With this in mind we set out to evaluate AW-ETL systematically.

Thought there’s been some talk of how to unit test an AW-ETL transformation (specified as a “control file”), nothing sufficiently concrete was available. We set about writing an automation tool to allow us to try different types of data migrations. We have gone TDD (and some might say we are sometimes BDD) on our project, so we wanted to be able to specify the behavior of the migration via tests before writing our control files. We mocked something up with some shell scripts and then quickly moved to a Rakefile which would manage our databases and run our tests for ETL, throwing an exception whenever we have a test failure.

We group our tests into “scenarios”, which are simply directories with enough information to specify database schemas, table data, the ETL transformation(s) to use, and the tests we are trying to satisfy:

(If you are interested in downloading and playing with/using this little AW-ETL testing framework, you can find a tarball here)

This turned out to be a valuable methodology, as the documentation was even weaker than it appeared at first glance. While some areas are sufficiently documented, when we would need an example most none were easy to find. We did a lot of spelunking through the AW-ETL code to get us by. We covered some of the basic ground over the course of a day of testing, but ultimately were stumped when it came to figuring out how to preserve a foreign key relationship in a migration. We contacted the AW mailing list, which seems to be responsive, judging from the archives, but so far haven’t made any progress towards figuring out how to specify a foreign key relationship in an AW-ETL control file.

How do we represent a foreign key relationship?

Here’s the core problem ,which is pretty critical for us to be able to solve if we are going to be able to add new “core data” to systems which have been running in production for some time already. Given two tables in a source database and the same two tables in a destination database, where one of the source tables has a column which references the primary key (“id” column in a normal Rails table schema) of the other table, we want to copy our source records into the destination database, but we want to make sure the foreign key relationship between the two tables remains intact, even if the primary keys on the destination database vary wildly. Maybe a picture would help:

So, put a couple of records for each table in the source database, as well as putting an existing record in the destination database. What we want to see after the ETL process is the following:

That is, the source database stays the same, but the destination database now has 5 records in total: the existing 1 record that we started with, and the 4 new records we brought over from the source database.

In our little framework we can specify this with a test like so:

require File.dirname(__FILE__) + '/../test_helper.rb'

class ConversionTest < Test::Unit::TestCase
  def test_conversion_should_copy_data_from_source_to_destination
    with_db 'data_destination_development' do
      assert_equal 2, ActiveRecord::Base.connection.select_value("select count(*) from foos").to_i
      assert_equal 3, ActiveRecord::Base.connection.select_value("select count(*) from bars").to_i
    end
  end

  def test_conversion_should_leave_source_data_intact
    with_db 'data_source_development' do
      assert_equal 2, ActiveRecord::Base.connection.select_value("select count(*) from foos").to_i
      assert_equal 2, ActiveRecord::Base.connection.select_value("select count(*) from bars").to_i
    end
  end

  def test_primary_keys_should_be_distinct
    with_db 'data_destination_development' do
      assert_equal [1, 2], ActiveRecord::Base.connection.select_values("select id from foos").sort.map(&:to_i)
      assert_equal [1, 2, 3], ActiveRecord::Base.connection.select_values("select id from bars").sort.map(&:to_i)
    end
  end

  def test_additional_data_should_be_converted
    with_db 'data_destination_development' do
      assert_equal ['chronic', 'buddha', 'four twenty'], ActiveRecord::Base.connection.select_values("select name from bars order by id")
    end
  end

  def test_foreign_key_relationship_should_be_preserved
    with_db 'data_destination_development' do
      assert_equal [3, 2], ActiveRecord::Base.connection.select_values("select bar_id from foos order by id").to_i
    end
  end
end

After extensive code groveling and experimentation (the documentation is weak in this particular area), the best we’ve been able to get is the following:

Which, isn’t going to suffice since the foreign key references are now misdirected. What we want is to be able to say “hey, the natural key to look up the bar on the other end of this foo.bar_id is the bar.name column, so when you find a matching record with that key, use its id for the foo.bar_id” ... but, we’ve been unable to figure out how to do that in AW-ETL, or if it can be done.

Why bother with all this?

We’re in the processing of choosing a tool for our data migration needs. During the development process (which, as long as the application is in use, will never truly end) developers are highly concerned with issues relating to data—ultimately they want to know what “buckets” data falls into, what are the steps they need to follow to make sure they don’t trash development or production data, and how do we minimize the complexity of the data we have to manage.

The organization is concerned with a bigger issue—with this system running in many instances, how do we have confidence that our data is correct, that reporting and warehousing have clearly defined (and well optimized) schemas, that the data we have can answer the questions we ask, and that we won’t suffer downtime due to data migration problems.

These two perspectives are related but have differing priorities, and different needs which may even be irreconcilable. We’re finding it difficult, in surveying the ETL tools on the market, to find a tool which is usable by the developers on a daily basis, but which is also usable at the organization level in a comprehensible way. Or, put another way, the way that a decent-sized organization (> 1000 employees) tends to use data tools is very different from the way a development team of a dozen tends to use data tools.

What am I talking about? We’ve seen something about how we can take a tool like AW-ETL (whether or not it can handle a foreign key relationship properly—my guess is that it can but the documentation is too sparse and the code base too unfamiliar for us to find it) and subject it to modern agile methodologies: test-driven development, version control, pairing, continuous integration (after all, we have a single command that we can use to launch all our ETL tasks: rake). Given that AW-ETL’s control files are essentially code, and most likely, can even be generated by code in an appropriate ActiveRecord-aware Ruby DSL, we can apply all the techniques we have adopted for the management of code in our team. Productivity and reproducibility are clear benefits.

On the other hand, when we examine other ETL tools on the market we find a different set of features and tradeoffs. Of the general-purpose ETL tools we can find we quickly rule out database-specific tools that tie us to a single vendor’s database technology. In the next pass we curb those which are clearly immature or unworkable after a quick evaluation. Remaining are the set of ETL products which typically support a wide range of extractions (XML, database tables from any number of different databases, various file formats, HTTP requests, SOA services, etc.), a wide range of transformations, and a wide range of load targets (including various non-database targets). Some of these tools have various automation concepts built in, ranging from job sequencing to load clustering to script execution. In other words, they are leagues ahead in terms of overall ETL functionality than anything we would write ourselves, as well as anything AW-ETL is likely to have in the near future, just due to the disparity in the number of paid developers working on these bigger tools (these tools are typically part of a suite of other “business intelligence” (heh), reporting or data mining tools, and there’s mad loot at stake in there somewhere).

But, as we look at how these tools can be used, we tend to find the same things over and over. The primary interface is an all-powerful GUI, sometimes a Windows-only interface, but usually a Java interface that runs on a number of platforms, including the Linux/FreeBSD/OSX platforms we use in-house. There will sometimes be some sort of scripting interface built into the GUI, which suffers from the same problems scripting interfaces tend to suffer from: the authors think Visual Basic is frikkin’ HOT, their language is completely home-grown, there are no good editors, no good testing or version-control tools, the libraries you must draw on are weird and subject to change at every release, etc. These tools will typically have some sort of “automation” functionality, either built into the GUI itself (which presumes you run a server somewhere on your network and let the ETL beast run its own little kingdom), or a very limited “start me as a batch script / cron job” hook somewhere. Here is one of the more compelling (in a “please don’t let Zeldman or Jason Fried see this” sort of way) scheduling interfaces I ran across last week:

That’s what I’m talking about.

Anyway, most of the tools are written in Java, and therefore some of them expose a “Java API”. Downsides: the APIs are typically horrible, the APIs are brittle (i.e., when version 5.3 comes out the stuff you used in 5.2 doesn’t typically work—hope you had a test suite, thx), and often the gap between the basic concepts you’d want to automate and how they are represented in the GUI is so large as to be impassible. Here’s an example from one of the better APIs, and maybe I’m just spoiled by Ruby, but doesn’t it seem like that should be, oh, 5 lines in a decent Ruby DSL?

Back to the point (and you thought there wasn’t one!)... The tools we find, if they have the functionality necessary to handle non-trivial migrations, are geared towards an obsolete, unworkable, and unproductive process of managing data. Enterprise(y) data management is geared around a very small number (ideally, 1) of “experts” using a GUI interface to manage large amounts of data graphically. This means that, without massive effort, the migration definitions are mostly invisible, the process is mostly unmeasurable, and the migrations are mostly untestable (before running, and after running). Without massive effort, the user of the tool has little knowledge of state: what the current state of data is, what would happen if we ran a migration, and what happened the last time we ran one. The changes between one migration set and the next (i.e., the output of the user’s work) are not version-controlled, which means that errors go undetected, it is nearly impossible to “branch” the migration sets for releases or other purposes, rollback is a snapshot-at-best process (a friend of ours calls this “save-game”/”load-game” functionality, and we’ve considered giving a PlayStation + joystick interface to any tools we encounter which have this level of quality assurance).

In short, without applying massive effort, using these tools in your organization has the warm and fuzzy feel of adopting the 1995-era “let’s bet our company’s future on having our file clerks hack our workflow out in a gnarly Visual Basic app that will one day hang like a lead albatross around our collective necks” so-called “strategy”. It should go without saying that an organization willing to grab such a tool and run with it is not typically the organization which sees the point in applying massive additional effort to data migration.

What we’re looking to do is to find a sweet spot, some middle ground. How can we apply modern software methodologies to the process of data management, while using a tool which is powerful enough to do the job, but affords us the ability to actually run it in a lightweight manner and to write a data migration specification that is short, visible, and readable? Perhaps this is too tall an order. If I have good news I’ll let you know :-/

Tags , , , , , ,  | no comments

italy vacation pictures

Posted by rick Wed, 11 Jul 2007 12:08:00 GMT

We took a 2-week (plus a couple of days) vacation to Italy at the end of June. Pictures are up! More words to follow.

Tags , , , ,  | no comments

powerbrick casemod

Posted by rick Thu, 03 May 2007 18:32:00 GMT

In what seems to be an instance of an increasingly common problem, the DC cable on my MacBook’s power brick wore out and wires were visible. Not so good. I called the Apple Store to see if they’d replace it (I’m still in the first year so it might be covered under the limited warranty… I don’t play AppleCare because friends have advised me that the things they tried to get fixed under AppleCare weren’t actually covered, and since those were the sorts of things I’d expect to go wrong I kept my money). The lady asked if wires were visible (aka “we’ve seen this a bunch”) and I said “yes”, to which she replied that it’s up to the discretion of the tech as to whether they would do anything about it, oh, and the next remotely possible available appointment would be Friday. Since I use this computer about 16 hours a day, 6-7 days a week, it’s not so easy for me to let it run down and not boot up again until Friday, over a part they probably would take one look at and say “yeah, here’s a new one” or “oh, you’ll wanna fork over $85”.

So I did what any self-respecting human would do. I got a soldering iron, tore open the power brick (clearly never meant to be opened: the $85 disposable accessory/necessity), made a new connection, and then built myself a new casing. Out of Lego’s, duh.

Enjoy.

Tags , , , ,  | 2 comments

exploratory committee

Posted by rick Fri, 27 Apr 2007 04:29:00 GMT

Hey, today I can officially run for Presidente del Republica Banana de los Estados Unidos, or something like that. I think I’ll start an exploratory committee.

I can remember when 35 was incomparably old. I mean, my dad was 35 back then.

I wonder what my 8- or 12- or 18-year old self would think about me now.

When I was 8 I had just gotten over being on a baseball team, pretty much for the last time ever. I had just gotten my first cassette or so. I was learning about fractions I think.

When I was 12, I frankly can’t remember much from being 12. What was that, 7th grade? Maybe a girl at the swimming pool who was my age and looked about 18, having sproinged out in all the right/wrong places. 6th and 7th grade were a social pain in the ass, and everything was about to go upside down for everyone over the next few years. Shit we didn’t care about before was about to become almost all that was “important”, and the dice were starting to roll—what nice people were about to become cool, or vain, or superficial, or neglected, or mean, or “unpopular”?

At that point I’d also just about decided that the whole Catholic Church and whatever they were calling “God”, “Jesus”, “faith”, and “religion” were basically full of it. That would cause some fun in the following year. I suppose I’m still not supposed to let my grandmother in on that secret (hope she isn’t reading my RSS feed). I got my first computer at age 12, having won a $2 bet on a horse race at 99:1 odds (the same grandmother placed the bet for me). How’s that for mixed transcendental signals?

When I was 18, I spent all my time in school and in clubs and the like, staying away from home a lot of the time, enjoying myself, and really really looking to get out of small town Kentucky. I listened to a lot of music, but in hindsight it wasn’t a very wide selection. I was seemingly always fighting with my father, and I knew everything (right?). I’d had a lot of girlfriends, and had even once been in love. One of my teachers told me that, by the time I got to 30 I’d either be a millionaire or in prison.

So, now, I’m 5 years past (well outside the margin-of-error I’d say on my teacher’s prediction) and have been neither rich nor in jail.

If I’d stayed at that hedge fund until now, and somehow found a way to keep from jumping in front of a train living on Long Island I’d definitely be a millionaire by now. I knew that when I left there back in 1997, I mean the mathematical inevitability of it, and let it go. And that wasn’t a mistake. Instead I went out on my own and spent my money down for a few years as I reapprenticed myself and learned a shit-ton that I’m still building on. Best investment I ever made, though it cost me most of a million bucks.

If I’d gotten unlucky a few times I’d probably gone to jail too. Too many crazy ideas, too many wild nights (and days), too many impulses to see what in the hell would happen if I do this. During the crazy years the accomplices were absolute nut-cases, and I think the crazy years had a high high tide. Most of those guys have settled down a bit too.

Now, I have maybe half a dozen computers (down from a high of around 15 or so running at one point a few years back) and I can do almost anything imaginable with them without too much effort. I can get any music I want other than a few exceptionally hard to find pieces, for free, on demand. I’ve got an unbelievably beautiful and wonderful wife. We have our own house that we just bought. We have only one debt: the mortgage. We make more than we need and we have lots of interests. I think my younger selves would be happy with all those things, though I think they would misunderstand some of them in a lot of ways.

Back in December I had some major revelations that fundamentally changed my outlook on life and how I live it. I finally accepted that I’m a Buddhist, rather than just being interested and inclined in that direction. I cut my hair, gave up alcohol, became a vegetarian (again, though this time more strict than ever before), and took the Boddhisatva vow. Of course, I live in the world, and the world is often too much with me, and it’s hard often to hold on to those realizations, but I know it’s important. It’s changed how I think about many things and it colors how I live day-to-day. It lets me know, deep down, that “everything will be alright.”

It’s not necessarily been rosy, though. Some people take change personally, or more than others. I don’t do all the things I used to and so that puts me aside or outside or less alongside a lot of social circles, which is ok, though I hope people understand that it’s not because of their personalities that I’ve changed. There have been a few times when people have pushed and asked what’s the deal, “why don’t you eat meat?”, “why don’t you drink booze?”, “don’t you believe in God? you don’t go to church…”. A lot of times I haven’t really given the straight dope, because a lot of those people know me to some degree and I’ve already seen a few people comment to others, “looks like he crossed over” or “looks like we lost one”. Someone recently kept pushing and I told them about the changes in December and they just didn’t know how to take it. But some people do, and some people are excited and interested and helpful. The most surprising thing, I’m finding, is which people are which way.

Anyway, what’s threatening? Maybe the things I believe. I believe we are all One, we are all Divine. I believe that time and space are an illusion, and that it is an illusion that we are separate beings. I believe that love and beauty and truth are objective and that they are identical with the Divine, and suffering is their mirror image, and is the product of distance from the Divine. Finally, the universe is All, is consciousness, is divine, and it contains both love and suffering. The whole is both yin and yang, in infinite complexity and unity. As Bill Hicks noted, it’s pretty dangerous to think this way, after all “what’s going to happen to the Economy when we realize that we’re all One?”

Anyway, back to the State of the Union… I’ve got a very interesting job. We are building a large software system for a mental healthcare non-profit. The team of people we have drawn in is unbelievable. They are the best team I’ve seen since working at that hedge fund, and in some ways are better. We are also helping people. Every thing we accomplish will help thousands, perhaps tens or hundreds of thousands of people to live better lives. That’s seriously awesome, and I now see that as a real benefit to the work we’re doing. What we’re doing is hard as shit, though. I’ve been working 60-hour weeks since about October of last year, and it looks like it’ll be another couple months of that—and I’m not the only one. It’s not a death march but we’re all on a long-ass sprint and hoping to “get there” soon. But the thing is big, even with using Rails. We’ve got ~15,000 lines of code, which in any other language would seriously be at least 125,000 lines of code, but you can’t escape coupling and interaction between components, which is really what kills you as systems grow. Anyway, it’s almost ready to launch and people are really pushing for it and getting antsy. Noone outside the team has a real conception of what it takes to build a system this large, and it’s impossible to fully “manage expectations” to make that happen. So, every so often I find myself talking to someone who is agitated but gives us great feedback as they begin to talk, and we do everything we can to take that in and use it and thank them and let them know, “it will be alright.”

But, every week these days I have a day or two where I wake up in the morning, or come home in the evening, or go to bed at night thinking “jesus h. motherfucking christ this shit just ain’t worth it”, and of the people who’d rather I come work for them, without the long hours nor a “customer” unaware of what they want or get; or of simply doing part-time work and hiking and gardening instead. And then I think maybe of buddhist sand art which takes months for a monk to make, placing a grain of sand at a time (only to wipe it all away at the end); or perhaps of some of the guys in my team who have had talks with me and who have stepped up to make things better for us and the people we’re serving; or perhaps I just go to bed and let sleep make it better. Regardless I keep going, somehow so far.

If I sent this back in time as a letter to my 18- or 12- or 8-year old self how would they feel? I think probably the 8- and 12-year olds would see it as some sort of science fiction and maybe would distort it as part of the chimeric personal mythology I carry around in my head still. But I think the 18-year old self would mostly see that it’s been good, with one caveat, that he’d advise me, could he write back, to have more fun and fuck with things quite a bit more, because there’s really no downside, and there’s no point in working all the time and not purely enjoying it.

Maybe I should listen to that self a bit more. I think he’ll be the first appointee to my exploratory committee.

Tags , , , ,  | 5 comments

thought for the day

Posted by rick Sat, 10 Mar 2007 17:39:00 GMT

Since the days are few and far between when a cashier justifiably asks you, “What, are you joining the army?” it’s fitting to make the best of those times when they come.

Tags  | no comments

caipirinha recipe

Posted by rick Sat, 13 Jan 2007 22:22:00 GMT

I think this is basically my friend Kevin Barnes’ recipe, but however I remember how to make it; as quoted to a friend of mine, shoved up here for public reference. Fwiw, I don’t even drink any more :-)

To make one pint glass of caipirinha, cut the ends (usually just the tips pretty much) off 2 or 3 well-rinsed limes, depending on size. Cut the limes in half. Flip each half over so the flat side is facing up, and cut cross-ways about 3-4 times (not all the way through, the lime should stay together) and vertically 2-3 times (ditto)—somewhat like prepping an avocado half. Drop the limes into the glass. Now take a tablespoon (or whatever a standard “big spoon” is from your silverware set) and scoop out a huge heap of powdered sugar and throw it in, then do it again. Kevin has an awesome muddler for smashing everything together, but I’m usually stuck using a wooden spoon (whichever end seems to give the best results). Smash that stuff up until it’s a greenish-whitish sugary liquid with big hunks of lime goodness in there. Now pour about half a pint glass’s worth of ice in there (preferably small squares of ice as opposed to big ice-machine-freezer pieces of ice; shaved ice would probably work too), and then top up with cachaca. Stir well, and add lime, sugar, or cachaca to taste.

*note: glass in picture is too small.

Tags , ,  | 1 comment

we interrupt this silence...

Posted by rick Wed, 04 Oct 2006 23:42:00 GMT

to bring you excuses and an explanation:

Nearly everything I’m posting these days is via the tumblelog that Corey and Kevin (does that boy have a website?) and I set up at work, which is at ni.hili.st. It pulls from IRC, command-line, etc. (is there an etc.?) and posts whatever. It’s rails, it’s tested, it’s good. The archives, and the CSS could be touched up, but otherwise it’s nice. Even has a clean IRC bot for your nefari-ization. We’ll post code someday, or just ask and we’ll fling you a tarball.

Otherwise, we’re entering the crunch on the CenterNet rewrite, which is, as far as we know (and we’re gaining ground on this claim every day, I think) the largest Ruby on Rails application on the planet. (and for all that, we’re still at about 5,000 lines of actual code, with ~130 database tables—stuff that in your “10:1 code ratio is bullshit” pipe and smoke it!) It’s reaching the point where if we’re not working, posting to ni.hili.st, or practicing our skyhooks on the crazy elementary school basketball court (half-covered with discarded furniture and shizzle and bongo drums) then we’re drinking beer. Which leaves about nil time for writing to weblogs.

So, sorry (oh, sosorry). Will write again when I’m bored, fired, or drunk. :-)

Tags  | 3 comments

autotest + growl

Posted by rick Tue, 12 Sep 2006 11:48:00 GMT

Corey and I hacked some glue last night to attach AutoTest to Growl. Really simple, but putting those two cool tools together is really powerful.

Tags , , , ,  | no comments

MacBook

Posted by rick Sat, 02 Sep 2006 21:21:00 GMT

My faithful iBook G4 has been growing a bit long in the tooth and it’d finally crossed the pain threshold a few weeks back and so I started pricing a MacBook. At work we’re building a large Rails application, and our test suites need to be run regularly. We have a continuous integration server which will run on each check-in, but unless you’re running the tests on your own machine it’s gonna be a pain when you commit broken code. Our (intel + Linux) build server can run the test suite in about 2 minutes, the MacBook 2.0Ghz systems and the MacBookPro’s all come in around 2 minutes as well. The g4 Powerbooks are coming in at around 6 minutes (painful), but my iBook G4 runs the tests in right at 10 minutes (OUCH). If I were using the laptop for just email and web browsing it would be fine, but having TextMate, Firefox, the entire Ruby/Rails server and development environment, Postgres, and often iTunes, SubEthaEdit, iChat, etc., all going, it’s not suitable for a developer machine.

So, I bit the bullet and bought a MacBook today. I first went to the Apple Store here in Nashville. That was full-on Noe Valley-style mayhem. I could swear I saw an arm dog or two, and, was it just me or were those toddlers both named Tyler? Regardless, they informed me that they had absolutely zero of the white MacBooks in stock (white being important because they’re the cheaper ones, and the black ones are a rip off: $200 extra gets you 20GB of extra disk and a coat of black paint). Damn!

So, I rolled out of Noe Valley and hit the CompUSA over at “leading economic indicator mall” (aka “100 Oaks”), which mall seems to be indicating a pretty hard economic spell ahead. Anyway, CompUSA was almost a ghost town, but they did have the MacBook I wanted, for the mandated same price, and I said “hook me up, yo.”

As an aside, CompUSA, if our store is any indication, is a shortable stock (are they even publicly traded? Presumably—too lazy to look). What few customers are there seem to be frustrated most of the time. When I went to check out they took me to the business checkout area where they apparently have the laptops sequestered, and there was some problem with the register over there so the guy walked me back to the main registers. None of those registers were staffed and there were about 5 or 6 people (the entire customer population of the store I’m guessing) obviously trying to figure out how to get checked out. One lady exclaimed, ” You work here! Wow. How can we get checked out?” To which the man leading me around the store said, “I’m about to open a register”, adding that he was going to check me out first (which seemed to cause some exasperation amongst the customer population, but, well, I just smiled as politely as I could and let the man fulfill his little prophecy).

Point being, on a Saturday, when people are throwing so much cash (er, probably credit, actually) down the street that the Apple Store can’t keep the hardware in stock, CompUSA has plenty of stock and noone to buy it—at essentially the same price. And when people do come in and are ready to pay for a purchase, there’s not enough staff on hand to actually take their money in a timely manner.

That’s a sign of a store that’s adrift, and I’m guessing that it’s a sign of the company at large being adrift.

But, I’m pretty damn happy, because I got the item I wanted with no hassle, for the same price as anywhere else, got good advice from their Mac guy, and was checked out as a priority (because I was buying a big-ticket item I’m going to presume).

So, I’ll be spending some time this weekend configuring my new laptop. Thanks go to Corey for documenting (yet again) the process of setting up a MacBook for Rails development.

More later.

Tags , ,  | no comments

"The Timeless Way of Building", patterns, architecture, and software

Posted by rick Mon, 05 Jun 2006 03:27:00 GMT

I mentioned earlier that I’ve been reading Christopher Alexander’s The Timeless Way of Building (TWoB hereafter). I finally finished it this morning after N months of reading on it. On the one hand I’m just like that: I’ll have 5+ (or 10+) books lying around open and partly read for months at a time, meaning that nothing really gets read quickly. On the other hand, I think TWoB deserves a slow and considered reading, and that’s how I approached the book.

TWoB is, on the surface, a book about architecture. It even says so in the title. It’s author is a well-known architect (still living, even, as far as I know). With its two sequels (A Pattern Language and The Oregon Experiment ) it has, however, caused quite a stir in another field—that of software development. TWoB was published in 1979, after 14 years of effort, so we’re now over 40 years from its inception.

In 1995 the so-called “Gang of Four” (GoF) text Design Patterns: Elements of Reusable Object-Oriented Software was published. Inspired by Alexander’s work on pattern languages for building, the authors (and their collaborators) brought “patterns” and pattern languages to computer software. Since that time the adoption of patterns in the software community as both paradigm and panacea has been rapid and widespread. A simple search for pattern-titled books on software in any decent library, or on web stores such as Amazon will produce a dizzying array of results. There are design patterns, analysis patterns, configuration patterns, integration patterns, deployment patterns, you name it. There are publishers who appear to believe that no book should be printed for consumption by software developers (and their management cousins) unless the word “patterns” appears on both cover and spine. There are job applicants going to interviews who know the 23 patterns in GoF by heart, speak them like some sort of creole dialect, and couldn’t code their way out of a soggy paper sack.

As a long-time software developer (ok, I never used a punch card, but I’ve been around long enough to know the following…) I can readily say that ours is an industry beset by marketers, marketroids, buzzwords, acronyms, predatory vendors, incompetence and an infinite amount of hype. As an industry our tools are mostly broken, our projects mostly failures, our memories systemically too short, and our confidence mostly beyond our abilities. Not only do we almost never have a solid gauge on how competent we (ourselves) are at what we do, it seems that everyone outside our profession is even worse at judging our competence. Not only are many programmers better suited (for the benefit of both those near to them and those working in our field at large) at doing lawn work or, better yet, washing dishes at restaurants where the health department doesn’t inspect very often; but mind-bogglingly destructive practices are promoted as “best” practices on the backs of the opinions of vocal better-off-washing-dishes incompetents and unscrupulous vendors willing to sell any buzzword or acryonym so long as the slogan is heard wide and the coffers are filled deep.

Into this dire ecosystem some decade ago was launched a good-intentioned campaign to bring Alexander’s brilliant insights (and after combing through just one of his many texts, I believe Mr. Alexander has earned the descriptive “genius”) into the industry of software development. Having read a number of discussions of how influenced the GoF were by Alexander’s pattern languages, and how good their intentions, I truly believe they believed they were doing the industry a great service. I think they may have even done so. If you catch a contradictory tone here (or a hesitance) though, it’s because I don’t believe we have seen that service yet bear fruit. Worse, I have my doubts it ever will.

While reading TWoB I was repeatedly struck by how powerful the authors concepts were, how clearly they were related, how inevitably the Good followed from his observations and suggestions. I was drawn back repeatedly to the realization that there were so many parallels between software and architecture. I was truly compelled by his invocation of Taoist principles, his explanation of the Quality Without a Name, and that quality’s inevitability: as a consequence of breathing life into a building, a community, a town.

Alexander exposed systematically the problems resulting from our modern methods of industrial, methodical, mechanical construction of not just our buildings but our lifestyles. He digs deep into the living way to build, to live, that all of us instantly recognize when we see it. He drew in the foundations of Eastern philiosophies. He shows a way back, through a simplifying and life-giving formalism (the pattern language) to the practice of building and living in a manner that is whole and alive, The Way that is timeless, which infuses our surroundings with the Quality Without a Name, which ultimately releases us from the need for the pattern language itself and returns us to the natural way of living and building which balances the forces around us and simplifies life and happiness.

Looking from his viewpoint back into the past decade of pattern-inspired software development I see that “pattern” has become just a replacement word for the (abysmal and soul-sucking) marketroid buzzword “best practice”. A pattern is something you’ve done at least twice, or something that someone smarter (or richer, or more cutting-edge) says you ought to be using instead of solving problems on your own. “Just show me the patterns I need to know”, says the lazy developer, “and don’t make me learn all that other nonsense.”

Even the inspired writing on patterns for software has hit at such a narrow scope and has left behind the core, the foundation, of what makes Alexander’s work so compelling, so powerful. Alexander’s patterns were a way of summarizing and exposing living techniques for those who could recognize them, but who had been robbed of their innate knowledge of those techniques by the distracting and numbing systems of modernity. In a tiny way the patterns were a shorthand, but more importantly they are a temporary crutch to be used to escape the paradoxes and failures of modern systems (which produce buildings, communities, and lives without the Quality Without a Name) and to return to our basic living understanding of how to make living places that are perfectly adapted to their environment and the problems they face.

What was brought over was stripped completely of Alexander’s core, stripped of purpose, and converted to a set of tiny rules showing common techniques for handling tiny problems. Where Alexander’s patterns cover concepts from the scale of individual windows up through the process of constructing a living neighborhood, covering also patterns of repair; software patterns, where they are helpful at all, are mired at the level of the window pane.

Even these are contentious. The simple and common “Singleton” pattern from the GoF book is the subject of much chest-thumping and vitriol these days. If such a simple pattern cannot even be agreed to be “good” or “alive” or to encourage the Quality Without a Name I wonder what software “patterns” could.

At one point in TWoB Alexander writes:

In short, a building laid out by a pattern language process, and which comes to life because of it, will die again, quite certainly, when it is built, unless the process of construction is the same—unless, that is, the same spirit which generated rooms that are just right, entrances where they should be, light coming from the right directions . . . is carried on into the details, and also shapes the columns, and the beams, the window frames, the doors, the vaults, the colors and the ornament as well.

And what strikes me is that Alexander’s pattern language is so far reaching that only the tiniest part of it deals with those details of construction (windows and columns and doors, etc.), otherwise dealing with all the powerful layers above these. These other tiny patterns are indeed important, but so as well is this other final once-omitted piece: the patterns of the process of building. In software we have, with a few tiny exceptions (I would include Martin Fowler’s Analysis Patterns book in this area, which addresses a slightly higher-level set of patterns that sometimes feel as if they could generate the Quality Without a Name in a software system) only patterns about nails and window pains and door knobs. We have nothing about building down from the higher levels, always ensuring we first make something living. We have nothing, really, about the process of construction, or the process of repair, that fits with Alexander’s core drive, that produces systems and interactions that are alive.

We have continued in the business of making dead systems, while deluding ourselves into thinking we have learned something that could make a thing that is living.

At the risk of having Amazon sue me for grabbing one of their reviews (go ahead and sue me), here’s one of the many reviews of the GoF book:

My only critique of the book is that it is very heavy on examples. It is all relevant and if you have the time to read and digest it all you will be a better programmer. However, there are more consice books that do a better job of distilling the important concepts of design patterns and books that provide better modern approachs. This is the type of book that you have to read in school becuase it is a classic. I would equate to classic literature like Homer or War and Peace. They are important in a scholarly sense if you wants a deep historic understanding of the topic. However, you can understand and use design patterns without reading other books and you will save a lot of time.

Another good analogy is the way calculus is taught in school. First they teach you in-depth complicated way. They take you through all the steps the inventor went through to come up with it. Then they show you the short cuts that are used in common practice. You have a better understanding of the topic because you know the hard way but you would be foolish not use the short cuts.

So you can read this book and get an indepth understanding or you can skip this step and go straight the a consice book that shows you how patterns are used practically today.

(source)

In one sense a perfectly reasonable review, if you’re sitting out in cubicle land looking for a book that will get your head above water with whatever the important thing is you Must Know to stay afloat in a hyper-competitive industry. Replace the subject matter (design patterns) with any other modern buzzword or “best practice”, say XML, JSP, CSS, Unit Testing, Continuous Integration, Behavior-Driven Development, JMX, Ruby on Rails, etc., etc., etc.; and you could publish that review 500 times and have people give it 4- and 5-star ratings. Buy that book, or become unemployable.

Pretty dismal, sure, but them’s the breaks. Only, after reading the primary source, it’s truly depressing. 90%+ of TWoB was pure Eastern philosophy. The book was primarily about how languages of patterns exist already in the world, have existed since the beginning of society. They are visible in the oldest and newest buildings and towns that are “living”, not “dead”. Alexander had been looking for The Way to build something alive, and spent 14 years writing this first volume to help communicate it. It’s powerful. The book is essentially about the Tao and a way we can practically shrug off the blinding layers of automated and modernized living and building to get back to the Tao.

The only thing that carries over to software development though is the smallest and weakest part of the “crutch”. The Tao is left behind. The Way is not here.

It is clear in reading TWoB that a pattern language which is not driven by the need to make something that is alive, that is the best that it can be, will be incapable of making anything at all that is alive. Even missing a single important step will result in the realization of a living design which is itself dead.

It is obvious to me now that, despite it’s seeming inevitable proliferation, that the software “patterns” movement is stillborn. In its best moments it uncovers a few nodes in the lower reaches of the graph of a useful pattern language, which appears doomed to never reach the important upper reaches where it could ever result in a living system. Otherwise, this “movement” is mostly a vehicle for buzzword proliferation, a hook onto which tireless unscrupulous vendors hawk the next beta release of snake oil, a veil behind which hides laziness and confusion masquerading as work and knowledge.

If I seem a bit jaded or cynical, perhaps I am. But it’s really aggravating to see all the sound and fury dedicated to “improving” the horrid state of software development and realize that the vast bulk of it really does signify nothing. Patterns are worthless if they are adopted without any of the important fundamentals that could ever make them “work”. Calling what passes for patterns in software “patterns” is actually insulting to Alexander, and tangentially, to anyone who has ever built something which has the Quality Without a Name.

This is not an attempt to insult the Gang of Four and their comrades who wished, and worked, to bring Alexander’s insights across the border into our field. On the one hand, perhaps what they were trying to do is impossible. On the other, they surely knew they were beset on all sides by wolves: the wolf of incompetence, the wolf of capitalism, the wolf of undisciplined practitioners, the wolf of Good Enough, . . . the pack goes on.

There has never been a software system built which comes near to having that Quality. In the direction we’re headed I can’t see that any such system will ever be built.

Is it possible to build software that is “alive”, that has the Quality Without a Name?

I can’t be sure, clearly. I’ve been thinking about this for months, the duration of the time spent reading TWoB, and may well think about it for 14 years as Alexander did, and perhaps the full 41 years it took to get us from that book’s inception to know. And I probably will still not have an answer by then.

Regardless, it will take more than replacing “best practice” with “pattern”.

We don’t have, as a species, the history in software that we have with building. Software is in some fundamental ways different from building: software is all design, the building must be part of the design process (sorry waterfall proponents, but this much has become clear in the past decade); software is malleable, like clay rather than stone, and we know that, for some real value of Good that Good software stays this way; that we know so much less about software; that software is complex like mathematics, in ways that physical things like buildings cannot be; that software doesn’t wear out, but that software can run only so long as the world supports the way it runs; that people don’t sit inside software and read a book; that people don’t look at software (at least not yet) and have clear feelings about it; that software is more destructively dominated by fashion than even architecture; that tools which are themselves destructive to building whole and living systems are often championed as The One True Way to build a system. Let me stop before I start enumerating the languages and tools which have done so much to so many for so long, sucking the very hope of life out of systems and developers alike.

Where industrial techniques are the enemy of living architecture, software development is, at this point in time, only willing to think of industrial techniques. From where I sit this forecloses the possibility of The Quality Without a Name from software. Without this, why bother with “patterns” at all?

The only thing positive I suppose I can say at this point is that any attempt to build living systems in software is most likely to come from a small group who work long years on building systems in a way that mirrors the way we build living homes and communities. Perhaps someone will gain insights like Alexander’s and still have the time to share them with us. Perhaps some of us will have the sense to listen.

Tags , , ,  | 2 comments

thought on politics

Posted by rick Mon, 15 May 2006 12:33:00 GMT

One does not distill truth from politics—one instead becomes drunk on self-righteousness.

Tags , ,  | 1 comment

art-talk weather forecast rides again!

Posted by rick Mon, 27 Feb 2006 00:17:00 GMT

In order to make automated “7 day Art weather forecast” emails like these on the new AirSet art-talk calendar I had to update my ruby script. Here’s the new version (and you’ll note that the bulk of the code deals with cleanup of bastardized input):


#!/usr/bin/ruby

require 'open-uri'
require 'rexml/document'
require 'rexml/xpath'
require 'time'

URL = "http://www.airset.com/syndicate/public/1391/week.xml" 

def cleanup(text, keep_stars = false)
  result = text.
    gsub(/&amp;/, '&').
    gsub(/&[lr]?quot;/, '"').
    gsub(/&apos;/, "'").
    gsub(/&#39;/, "'").
    gsub(/&gt;/, '>').
    gsub(/&lt;/, '<').
    gsub(/&nbsp;/, ' ').
    gsub(%r{</?[^>]+>}, '').
    gsub(/\*\s*\*/, '**').
    gsub(/\342\200\235/, '"').
    gsub(/\342\200\234/, '"').
    gsub(/\342\200\231/, "'").
    gsub(/\342\200\223/, " -- "). 
    gsub(/\342\200\224/, " -- "). 
    gsub(/\303\242/, "a").
    gsub(/\303\251/, "e").
    gsub(%r{/+\s*$}, '')

  result.gsub!(/\s*\*\s*/, '') unless keep_stars
  result
end

def wordwrap(text, line_width = 70)
  text.gsub( /\n/, "\n\n" ).gsub( /(.{1,#{line_width}})(\s+|$)/, "\\1\n")
end

def output(title, time, location, link, description)
  title       = cleanup(title)
  time        = cleanup(time)
  location    = cleanup(location)
  link        = cleanup(link)
  description = wordwrap(cleanup(description, true))

  puts "#{time.chomp} - #{title}" 
  puts "    online:  <#{link.chomp}>" 
  puts "  location:  #{location}\n\n" 
  description.split("\n").each {|l| puts "   #{l}"}
  puts "" 
end

def fetch_document(link)
  open(link) { |f| return f.read.split("\n").join(' * ') }
end

def extract_location(doc)
  doc =~ %r{<span\s+class="evDescAndLoc">([^<]+)</span>}
  place  = $1 || ''
  place = place.sub(/^.* at /, '').gsub(/\s+\*\s+/, '')
  doc =~ %r{<span\s+class="evAddress">(.*?)</span>}
  address = $1 || ''
  address = address.gsub(/Get map/, '').gsub(/\s+\*\s+/, '')
  place += " / #{address}" unless address =~ /^\s*$/
  place
end

def extract_description(doc)
  doc =~ %r{<span\s+class="evNote">(.*?)</span>}
  return ($1 || '')
end

def retrieve_data(item)
  # Extract title and time
  if item.elements['title'].text =~ /\(([^)]+)\)\s*$/
    time = $1
  else
    t = Time.parse item.elements['pubDate'].text
    hour = t.hour % 12
    hour = 12 if 0 == hour
    time = "%02d/%02d/%4d (%d:%02d%sM)" % 
      [t.month, t.day, t.year, hour, t.min, t.hour > 11 ? 'P':'A']
  end

  title = cleanup(item.elements['title'].text.sub(/\([^)]+\)\s*$/, ''))
  link = item.elements['link'].text
  doc = fetch_document(link)
  location = extract_location(doc)
  description = extract_description(doc)

  [title, time, location, link, description]  
end

  puts "7 Day Art Weather Forecast" 
  puts
  puts "  ... see the Art-Talk Calendar for more events:" 
  puts
  puts "  online at: <http://www.airset.com/Public/Calendars.jsp?id=1391>" 
  puts
  puts " -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --" 
  puts

open(URL) do |f|
  xml = REXML::Document.new(f.read)
  REXML::XPath.each(xml, '//item') do |item|
    title, time, location, link, description = retrieve_data(item)
    output(title, time, location, link, description)
  end
end

Tags , , ,  | no comments

Nashville Dynamic Languages mailing list

Posted by rick Fri, 24 Feb 2006 14:29:00 GMT

I’ve set up a Google Groups mailing list for the Nashville Dynamic Languages group—which is a pretty informal social and technical group of people (predominantly located in Nashville) who are interested in dynamic programming languages (Smalltalk, Ruby, Lisp, Io, etc.). We had a get-together earlier in the week to test the waters and had a really good turn out. There’s a heavy Ruby (+ Ruby on Rails) bent, but there’s a lot of interest as well in other languages.

We’ll have another meeting soon here in town—we’ll sort the details out on the mailing list.

UPDATE: I’ve also secured the (oh so hard to acquire) domain name NASHDL.ORG in case we want to put together some sort of website.

Tags ,  | no comments

mail2post gateway code

Posted by rick Sat, 11 Feb 2006 04:45:00 GMT

For years and years I’ve used a perl script to convert inbound emails to my site to posts on the site (that technique has probably been patented by some asshat within the past year—such being the USPTO & the Internet). I was using a flat-file archive of my own creation which was dead simple and geared towards mostly “link log” type posts. The front-end was a PHP engine I wrote (also years and years ago) which would simply spray those flat-filed posts to the page on demand.

Now that I’m almost switched over to Ruby on Rails and Typo I needed to update the tool which receives email and makes posts from it. Here’s the Ruby code to do it:

#!/usr/local/bin/ruby

require File.dirname(__FILE__) + '/../config/boot'
require File.dirname(__FILE__) + '/../config/environment'

#
# process an email, extract link data and create a Typo post with tags
#
# TODO: care about someone other than me using this 
#   (grep for /[Rr]ick/ below...)
class InboundMailer < ActionMailer::Base
  def initialize
    @tags = {}
  end

  def receive(mail)
    # extract the subject, split into tag words
    tags = mail.subject.split(/\s+/)

    # extract the relevant body fragment(s)
    body = mail.body.split("\n")

    buffer = [] 
    body.each do |line| 
        break if line =~ /^(?:\s*-+)|Rick/  # when is the mail finished?
        if line =~ /^\s*$/  # whitespace separates posts
          article = create_article(buffer)
          set_article_tags(article, tags)
          buffer = []
        else
          buffer << line
        end
    end
  end

  # given a set of lines comprising a post, turn this 
  # into an Article, returning the Article
  def create_article(lines)
    title = lines.shift
    Article.create :title => title, :body => lines.join("\n"), 
      :author => 'rick', :user_id => 1, :allow_comments => true, 
      :text_filter_id => 5
  end

  # associate an Article with a set of Tag instances
  def set_article_tags(article, tags) 
    tags.each do |t|
      unless @tags[t]
        begin Tag.create :name => t, :display_name => t rescue nil; end
        @tags[t] = true
      end
      my_tag = Tag.find(:first, :conditions => ['name = ?', t])
      article.tags << my_tag
    end
  end
end

# process the email
InboundMailer.receive(STDIN.readlines.join(''))
Yeah, there's a little bit of the old hardwiring there. Feel free to unwire for your own needs.

Tags ,  | no comments

Converting rickbradley.com to Ruby on Rails

Posted by rick Tue, 07 Feb 2006 16:16:00 GMT

I’m in the midst of converting this site over from the home-grown PHP engine that has served so well for years to a Typo installation, with various grafted on bits of Ruby on Rails to tie the bits and pieces together. The data conversion from my custom flat-file datastore was almost trivial: it took ~13 minutes to convert some 5000 posts, and the script was just:

require File.dirname(__FILE__) + '/../config/boot'
require File.dirname(__FILE__) + '/../config/environment'

exclude = {}

# convert rickbradley.com entries into typo weblog posts
ARGV.each do |filename|
  STDERR.puts "new file [#{filename}]" 
  tag = File.basename(filename).gsub(/\.\d+$/, '')
  next if exclude[tag]
  File.open(filename) do |file|
    # create the tags entry for this file
    begin Tag.create :name => tag, :display_name => tag rescue nil; end  
    my_tag = Tag.find(:first, :conditions => ['name = ?', tag])
    file.readlines.each do |line|
      timestamp, url, title, body = line.split /#%#/
      title.chomp!
      (body ||= '').chomp!
      url.sub!(/^\//, 'http://www.rickbradley.com/')
      body = %Q{<a href="#{url}">#{title}</a>} + (body != '' ? " - #{body}" : '')
      datetime = Time.parse(timestamp)
      puts "[#{timestamp}]->[#{datetime}] [#{title}] [#{body}] [#{tag}]" 

      # create a post from this data
      article = Article.create :title => title, :body_html => body,
         :author => 'rick', :created_at => datetime, 
         :updated_at => datetime, :user_id => 1

      # link the post and its tags
      article.tags << my_tag
    end
  end
end

(and most of that was just dealing with the silly one-line-per-post flat file format I hacked up in 5 minutes 5 years ago).

Things left to do (this list is for me as much as anyone):

  • convert over my handful of notes posts
  • bring over static pages
  • change the “theme”
  • update the mail -> post procmail handler
  • put all the hidden stuff (images, etc.) into the public/ subdirectory for rails
  • alias the old link scheme via RoR routes
  • look at optimizing the unbelievably slow-ass “archives” sidebar query so I can actually use it.

Then, the point of all this nonsense (other than getting out from under PHP) is that I’ll make a minor hack to the ‘ping’ functionality for posts on this site and a handful of others, so that any post on the other sites ends up creating a mirrored post on this site, with appropriate categories and/or tags.

Tags ,  | no comments | no trackbacks