Matt Brundage

Archive for 2011

Wednesday, 26 October 2011

Deer population control: the final solution?

Recently, Annie went walking in Sligo Creek Park and saw a sign announcing the ongoing deer population management initiative, which involves mass killing. The Montgomery County Dept. of Parks will be reviewing public comments through November 10th, and Annie felt compelled to respond.

The letter below is her response to the Montgomery County Dept. of Parks.

cute little deer While my husband and I understand people’s concern regarding the current deer population, we strongly oppose your plans for a mass killing of deer when there’s a more humane alternative available. We’ve found information about a protein contraception vaccine that has been effectively used in Gaithersburg and other areas[1]. We’ve also found information that supports the effectiveness and safety of this method and it shows a 60% reduction in the deer population[1][2]. The cost of this method is lower than what is shown on the reports cited on your website.[3]

From NIST: “Two-shot PZP vaccination programs, sponsored by the HSUS, have been more than 90 percent successful at blocking pregnancies for one year in white-tailed deer and wild horses in other areas of the country. In addition to its proven effectiveness, the PZP vaccine can be delivered easily by darts, cannot pass into the food chain, does not affect normal mating behavior, shows no side effects and allows a return to fertility when no longer administered.”[1]

Even if the contraceptive method has to be done annually, the deer population and the need for contraceptive vaccines will decline[2]. This is a better solution than the annual killing of these deer.

If deer have no natural predators, are we to reduce ourselves to the levels of animals and simply kill? What makes us different is that we have the ability to feel compassion. I’ve been in a car accident involving a deer; deer have eaten plants from my garden. However, I don’t see this as justification for a mass killing of these animals. Deer can’t come to public meetings, send emails, or protest for their right to live. It’s our responsibility to protect those who don’t have a voice and are being inhumanely treated.

Works cited

[1] Deer Immunocontraception at NIST
[2] Deer Contraception Works!
[3] Immunocontraception (Deer Birth Control)

Tuesday, 4 October 2011

Jens Lekman and the improbable synchronicity

Small Image A few years ago, KEXP introduced me to the music of Jens Lekman, a Swedish-born singer-songwriter. I was immediately taken with his blend of indie pop, with a sound reminiscent of a less-snooty Sufjan Stevens, or perhaps a peppier Stephin Merritt or the Smiths. I picked up his second album, the excellent Night Falls Over Kortedala.

Recently, I put his album into heavy rotation again, for no single defining reason. I was particularly drawn to “Shirin”, a song in which Jens falls for his Persian hairdresser: the song’s namesake, Shirin.

When Shirin cuts my hair it’s like a love affair / Let those locks fall to the ground or let them stay mid-air…

Shirin pulls my head to the side, but in the mirror I can see a tear in her eye…

The song is charming (but not mawkishly so) and is impeccably arranged, with Beach Boys-esque “ooos” and “aaahs” rounding out an ample, wordless vocal tag. In short, “Shirin” alone is deserving of its own blog post, but wait, there’s more.

Last week, while walking home from work, I saw a generic-looking business card in the street gutter. Now, 99.9% of the time, I don’t just go picking up random pieces of garbage off the street, but for some reason this business card (lying face-down, mind you!) piqued my interest as I bent down to pick it up.

Shirin apparently works at Hair Cuttery

Friday, 12 August 2011

Stale cache mitigation with query string automation!

So you’ve been a good little developer and define expires headers for page assets such as CSS, JS, and images. Let’s say you specify that the caching of CSS files expires one week after initial access. But if you modify a CSS file, your visitors could potentially load stale cache for up to one week.

One solution is to rename the file. For example, main.css would become main.2011-08-12.css This will effectively create a unique cached version of the CSS file. But this solution could get cumbersome with frequent updates, or with disparate references to the asset. A second solution is to add a query string to any references to the asset, for instance, main.css?2011-08-12. Proxy servers will treat this reference as a dynamic file and will likely not cache it. Browsers will treat this as if it were a unique file and re-cache it.

A refinement to our second solution is to automatically add a query string to references to the asset, but only when it’s necessary to do so. The following function, assetQueryString(), does just that. It takes two arguments:

  1. The reference to the page asset
  2. (optional) Maximum file age (in days) in which the query string will be appended

The function determines the file modification date and determines whether or not to append a query string, and for how long. The value of the query string, conveniently, is the last modification date of the file. Or, more accurately, it’s the number of days between the Unix Epoch and the last modification date.


function assetQueryString ($filePath, $maxAge = 7) {
	$today = intval(strtotime(date("Y-m-d")) / 86400);
	$fileDate = intval(strtotime(date("Y-m-d", filemtime($_SERVER['DOCUMENT_ROOT'].$filePath))) / 86400);
	$days = $today - $fileDate;

	if ($days <= $maxAge) {
		$filePath .= "?".$fileDate;
	echo $filePath;

// usage:
<link rel="stylesheet" href="<?php assetQueryString("/templates/style/main.css"); ?>">


<cffunction name="assetQueryString" returntype="string" output="FALSE">
	<cfargument name="filePath" type="string" required="TRUE" />
	<cfargument name="maxAge" type="numeric" default="7" required="FALSE" />

	<cfparam name="Variables.unixFileDate" default="0" />
	<cfset Variables.expandedFilePath = expandPath(filePath) />
	<cfset Variables.unixEpoch = CreateDate(1970,1,1) />

	<cfif fileExists(Variables.expandedFilePath)>
		<!--- determine last modified date --->
		<cfset Variables.unixFileDate = DateDiff("d", Variables.unixEpoch, getFileInfo(Variables.expandedFilePath).lastmodified) />

		<!--- determine today's date --->
		<cfset Variables.unixTodaysDate = DateDiff("d", Variables.unixEpoch, Now()) />

		<!--- append unique query string to file path if the file was recently modified --->
		<cfif Variables.unixTodaysDate - Variables.unixFileDate LTE maxAge>
			<cfset filepath &= "?" & Variables.unixFileDate />

	<cfreturn filepath />

<!--- usage: --->
<link rel="stylesheet" href="<cfoutput>#assetQueryString("/templates/style/main.css")#</cfoutput>">
Saturday, 6 August 2011

Sisyphus: rock and roll

Sometimes I feel as if the act of listening to my music collection is becoming a Sisyphean task. Let me explain:

Since I began my digital music collection in earnest in 2005, I’ve amassed close to 14,000 tracks, most of which I’ve simply ripped from my CD collection or downloaded from podcasts. How much music is this, exactly? Over 36 continuous days. If I were to average one hour of listening per day, it would take me close to two and a half years to traverse through my entire collection without repeating a single track.

While this is infinitely cool, it also presents a problem, as my “oldest” tracks were last heard as far back as May 2009. And this queue of old tracks keeps growing ever larger, as I keep amassing tracks but don’t really increase my average listening time per day. Quality songs are getting lost in the shuffle, so to speak. It’s easy to forget about them if they only come around once every two or three years. At the same time, new or unknown artists have it equally bad, as they have scant time to impress me with their music.

My only hope? Weeding. I rarely weed, as I understand all too well my penchant for rediscovering lost music.

Wednesday, 29 June 2011

Chesapeake ADHD Center of Maryland

Chesapeake ADHD Center of MarylandChesapeake ADHD Center of Maryland is my most recent client: an ADHD psychotherapy practice in Silver Spring, MD. As was the case with Ann Dolin’s site, the original codebase was inherited. Apparently, the website was originally created in an old version of Dreamweaver — and all of its WYSIWYG glory. Sigh. With over 150 pages (and file names such as cooltext449991252_001.png) the codebase had become an unmaintainable morass of untemplated spaghetti, with nary a single redeemable line of code. The site was razed to the ground and reborn in the ashes.

Chesapeake ADHD has undergone more of a reorganization than a redesign; in fact, I view my design as more of an improvement upon the original — the essential design elements can still be seen.

When I inherited the project, the site’s Page Speed score was a somewhat respectable 78. Now? Try 96. The law of diminishing returns should kick in soon.

Wednesday, 11 May 2011

Ann Dolin

Ann Dolin You may remember a site refresh I did for Ann Dolin last summer: her own tutoring business, Educational Connections. This spring finds her personal site,, getting a subtle makeover and a substantial speed boost.

Before the refresh, the site’s Page Speed score hovered in the high eighties. Not bad, by any measure. The original codebase was inherited, and I had done all I could to increase page load times (save for completely redoing the site, which was using a WordPress template of questionable character). The stars realigned with this recent redesign, and her Page Speed score is positively screaming with a score of 97.

Monday, 4 April 2011

Three albums dropping soon

Three of my favorite artists are releasing fresh new studio albums in the coming weeks, and I’m super-psyched!

Panda Bear

me, me, me panda! In 2007, Panda Bear released Person Pitch, an album as close to perfection as technically possible. His latest, Tomboy, is already exceeding my expectations, and I can’t wait to hear the album in its entirety. Oh wait: the album is streaming on NPR until April 12th.

Fleet Foxes

I saw the Foxes in early July 2008, when hype for the band was first building. Some claim that they’ve pigeon-holed themselves into a folksy, lush, baroque sound; if I concede that point, I still believe this works to their advantage. Right before the release of their debut album, an old school mate of mine, Josh Tillman, joined the band. While he’s been with Fleet Foxes for going on three years, Helplessness Blues will be his first recording with the band.

My Morning Jacket

MMJ appear to be caught in a Catch-22. They can’t exactly revisit the old sound, the reverb-laden At Dawn and It Still Moves, without coming across as overly nostalgic also-rans. At the same time, their last release, Evil Urges, somehow diverged simultaneously into both white-boy falsetto funk, slow steel-guitar numbers, and standard AOR pop-radio fare. MMJ has promised a “reset” of sorts for their latest, Circuital. Needless to say, the record will probably blow me away.

Thursday, 3 March 2011

CSS resetting with the negation pseudo-class

My derivation of Eric Meyer’s latest Reset CSS, but for current browsers:

:not(button):not(input):not(optgroup):not(option):not(select):not(textarea) {margin:0; padding:0; border:0; font-size:100%; font:inherit; vertical-align:baseline;}

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;}

body {line-height:1;}

ol, ul {list-style:none;}

blockquote, q {quotes:none;}
blockquote:before, blockquote:after, q:before, q:after {content:''; content:none;}

table {border-collapse:collapse; border-spacing:0;}

Meyer’s first rule — in which we reset margins, padding, borders, and fonts — quickly becomes unwieldy as we explicitly list out all elements, save for a few typically used in forms. Instead, the negation pseudo-class provides a succinct way of selecting these elements. Internet Explorer 8 and below will still need to be fed the more verbose rule, however.


Ah. It turns out I spoke too soon. The negation pseudo class carries a higher specificity than a simple element selector. So in practice, my method would be at least cumbersome. It was a nice mind exercise while it lasted…

Tuesday, 11 January 2011


Something strangely fascinating happens when I filter my digital music library with the simple keyword “swim” — nothing but standout Grade-A™ songs:

  • R.E.M.’s “Nightswimming”. The song represents R.E.M. at their commercial (and arguably creative peak) and is right up there with “Fall on Me” and “Find the River” in the upper echelon of R.E.M. songs.
  • Small Image Surfer Blood’s “Swim”. Bombastic power-pop surf rock with an ocean’s worth of reverb. “Swim” plays as the musical equivalent of an extreme off-roading Jeep. Do yourself a favor and buy this right now.
  • A couple singles from Canadian folk-rock band Great Lake Swimmers, “Pulling on a Line” and “Your Rocky Spine.” Both are melodic, and exude a certain pop craftiness.
  • Caribou’s “Odessa” from Swim. In the same vein as Hot Chip, “Odessa” is an organic-sounding dance track with a tight flute riff and a killer bass line. Someone needs to sample this and rap over the top. Pronto!
  • Tyler Ramsey’s cover of Jackson Browne’s “These Days” from A Long Dream About Swimming Across the Sea.
  • Camera Obscura’s “Swimming Pool”. A twee little duet. Sample lyric: “My head’s been lying dormant like a sleepy little mouse.”
  • Frightened Rabbit’s “Swim Until You Can’t See Land”. Yeah, yet another quality Scottish rock band. I swear, I don’t do this on purpose.