Thursday, September 27, 2007

NYC Alternate Side Parking Rule Suspensions

Did anyone know that alternate side parking rules were suspended today for Succoth? Tomorrow, too! I certainly didn't know. And after I'd spent all this time yesterday driving around finding the perfect spot on the "Thursday-Safe" side of the street. Well no more of that. I've entered the 2007 NYC alternate side parking rule suspensions calender into my calendar and is available here as an ics file ready for import into your favorite ics-compatible calendar. I'll post a 2008 calendar when dates become available from the DOT. Enjoy!

Friday, September 21, 2007

iAdditives releases iStrobe Strobe Light for iPhone!

iAdditives, home of dumb and nutritious iPhone/iTouch applications, releases its first and quite possibly its dumbest iPhone application ever: iStrobe. Now you can bring the party on your iPhone wherever you go. Also, iStrobe is great whenever you want someone to tell you that strobe lights can cause seizures. iAdditives is working on its second product, a candle votive simulator called iAmbience. We hope you enjoy our sandbox for dumb iPhone ideas.

Labels:

Saturday, September 15, 2007

Bubble Opera

Our friend Janie Fink's delightful new volume of poetry will be released on October 1. The ingenious title poem is witty, poignant, sexy, inventive, and full of those little truths we experience daily and rarely notice. Janie reminds us to pay attention and appreciate them.

We made a little home for Bubble Opera on the web – read all about it there.

Labels: , ,

Thursday, September 13, 2007

Tiki: Our New Basecamp Issue Tracker!

Haven't you heard? If you've wished for a full-featured bug and task tracker that works with Basecamp, you're not alone. We felt the same, and to that end we're proud to announce our brand-spanking new Basecamp Bug/Task Tracker: Tiki!

Tiki integrates with your Basecamp People, Projects, Companies, and To-Do lists, providing you with a simple but sophisticated issue-tracking lifecycle, including traditional ticket routing and approval, a detailed history, notification lists, time tracking, due dates, and super awesome search.

Take a tour and sign up now for the public beta at:

http://www.tikiden.com

Labels: , , , ,

Tuesday, September 11, 2007

A Visit to the New NY Times Building

We had the pleasure and honor to meet with some folks at The New York Times the other day, and when our meeting was over, they kindly offered to give us a tour.

If you have ever set foot in the old NY Times building, the expression "Old Grey Lady" probably conjures more images in your mind of dark, forlorn corridors and crammed-in people and stuff than of the pre-color version of the paper itself. The executive offices, used by the least number of people, were quite beautiful, but the building's most-used space, the lobby, had all but lost its erstwhile grandeur.

The new building, by staggering contrast, is bright, exquisite, and wholly fresh. Moreover, it's the realization of the integration of function and form to which the greatest design aspires. This hits you immediately when you enter the lobby, a huge, natural-light-filled space enclosed by glass walls, one of which is festooned with an exhibit of photos called Building the Times by Annie Leibovitz. The high-speed elevator system is "smart" – it asks passengers to specify their desired floor before entering, and an automated dispatcher sends you an elevator magically filled with passengers who have the same destination.

The building's climate control system is the stuff of science fiction. A "curtain" of horizontally mounted ceramic tubes reflect or absorb light based on season, time of day, and day- and sunlight levels. This helps keep the exterior of the building at a constant temperature, so the building's HVAC systems don't have to work as hard as they would otherwise. Automated, time-triggered blinds on the outer walls raise and lower as the day progresses to reduce sunlight glare. And throughout the building, localized, adjustable floor vents enable occupants to align air flow with their own comfort levels.

The high, glass ceiling of the newsroom – the "belly of the beast" – evokes the spacious radiance of an atrium. It's almost startling for those familiar with the old newsroom. As we passed a glass-walled conference room filled with earnest-looking faces, my guide remarked that the team within was deciding what stories would be run in the paper the following day. One might assume that these meetings would be conducted in a windowless cloister in some secret location inaccessible to the hoi polloi. But in the new Times building, there are no such barriers. There are a few offices, but even those have semi-transparent walls. Most people work in low-walled cubicles that not only foster an open-plan feel, but also enable you to turn from your monitor and look out the expansive glass walls to city you serve. Here, everyone enjoys the view.

After the tour, we had lunch in the cafeteria, a giant, split-level space that features an organic and locally grown selection straight from the Whole Foods playbook.

Exiting the elevator and crossing the lobby, gazing again at the collage of Leibovitz photos, one is struck that Piano's vision was simple: a truly humane office environment, built for people and the way they work.

Labels: , ,

Monday, September 10, 2007

time warping

I've been going through my collection of music videos. When I was about 12 I started recording videos off of MTV and late night talk shows of musicians/bands/artists that were interesting to me or that I liked. This summer I had the opportunity to borrow a DVD recorder and downsize the clutter. I've been taking these tapes and recording the videos and live footage onto the hard drive then transferring to a DVD. One of the funniest things I think is seeing where my tastes changed and watching some of these videos...and listening to the lyrics. Have you ever thought about how cheesy some of those glam rock band ballads were? I stopped recording videos and live performances around 2005.

So let's take a small trip through the late 80s and 90s to about 2 yrs ago.

1) Guns N Roses - Welcome to the Jungle
2) L.A. Guns - Ballad of Jayne
3) R.E.M. - Shiny Happy People
4) Metallica - One (still one of the best videos)
5) Jellyfish - Baby's Coming Back
6) They Might Be Giants - Don't Let's Start
7) Aerosmith - MTV Unplugged
8) Tori Amos - God
9) Nirvana - Come As You Are
10) Temple of the Dog - Hunger Strike
11) Pearl Jam - MTV Unplugged
12) EMF - Unbelieveable
13) Smashing Pumpkins - Today
14) Guns N' Roses - November Rain (could never find that short story)
15) Edie Brickell and New Bohemians - What I Am
16) Elastica - Connection (remember the snarl?)
17) Sqiurrel Nut Zippers - Put the Lid On It
18) Fiona Apple - Sleep to Dream
19) Poe - Hello
20) Save Ferris - The World is New
21) Beck - Devil's Haircut
22) Ani Difranco - Sessions at West 54
23) Aimee Mann - Pavlov's Bell
24) Liz Phair - Extraordinary
25) Indigo Girls - One Perfect World

Labels:

Thursday, September 6, 2007

Loopy Inspiration

A friend sent this link to me. It's a recording of a live in-studio session of "Just For Now" by Imogen Heap (in Toronto, I think). A simply beautiful convergence of high and low tech.

Sunday, September 2, 2007

Topological Sort in PHP

I recently had the need to put together a dependency sort routine, also known as a topological sort, and assumed there were millions available in PHP. I did not immediately find a stand-alone class (i'm sure there are many, but after searching I decided I liked the challenge of putting together my own). So nothing super glitzy or flashy here, but maybe something handy to you in a pinch. The Wikipedia entry was clear and helpful for breaking down the logical steps and after a few variations I arrived at the following class (and helper Node class). If you find it helpful please use it in your code. This code was written in PHP5 but should be compatible with PHP4.

A topological sort is useful when you want to load a bunch of libraries or modules some of which may be dependent upon each other. And it has many applications in graphing and plotting, especially with regard to vertices on a graph.

I want to also thank Jacob Good for his blog entry on Topological Sorting in C# which really helped get me started.
<?php
/**
* Sorts a series of dependency pairs in linear order
*
* usage:
* $t = new TopologicalSort($dependency_pairs);
* $load_order = $t->tsort();
*
* where dependency_pairs is in the form:
* $name => (depends on) $value
*
*/
class TopologicalSort
{
var $nodes = array();

/**
* Dependency pairs are a list of arrays in the form
* $name => $val where $key must come before $val in load order.
*
*/
function TopologicalSort($dependencies=array(), $parse=false)
{
if ($parse) $dependencies = $this->parseDependencyList($dependencies);
// turn pairs into double-linked node tree
foreach($dependencies as $key => $dpair) {
list($module, $dependency) = each($dpair);
if (! isset($this->nodes[$module]))
$this->nodes[$module] = new TSNode($module);
if (! isset($this->nodes[$dependency]))
$this->nodes[$dependency] = new TSNode($dependency);
if (! in_array($dependency,$this->nodes[$module]->children))
$this->nodes[$module]->children[] = $dependency;
if (! in_array($module,$this->nodes[$dependency]->parents))
$this->nodes[$dependency]->parents[] = $module;
}
}

/**
* Perform Topological Sort
*
* @param array $nodes optional array of node objects may be passed.
* Default is $this->nodes created in constructor.
* @return sorted array
*/
function tsort($nodes=array())
{
// use this->nodes if it is populated and no param passed
if (! @count($nodes) && count($this->nodes))
$nodes = $this->nodes;

// get nodes without parents
$root_nodes = array_values($this->getRootNodes($nodes));

// begin algorithm
$sorted = array();
while(count($nodes)>0) {
// check for circular reference
if (count($root_nodes) == 0) return false;

// remove this node from root_nodes
// and add it to the output
$n = array_pop($root_nodes);
$sorted[] = $n->name;

// for each of its children
// queue the new node finally remove the original
for($i=(count($n->children)-1); $i >= 0; $i--) {
$childnode = $n->children[$i];
// remove the link from this node to its
// children ($nodes[$n->name]->children[$i]) AND
// remove the link from each child to this
// parent ($nodes[$childnode]->parents[?]) THEN
// remove this child from this node
unset($nodes[$n->name]->children[$i]);
$parent_position = array_search($n->name,$nodes[$childnode]->parents);
unset($nodes[$childnode]->parents[$parent_position]);
// check if this child has other parents
// if not, add it to the root nodes list
if (!count($nodes[$childnode]->parents)) array_push($root_nodes,$nodes[$childnode]);
}

// nodes.Remove(n);
unset($nodes[$n->name]);
}
return $sorted;
}

/**
* Returns a list of node objects that do not have parents
*
* @param array $nodes array of node objects
* @return array of node objects
*/
function getRootNodes($nodes)
{
$output = array();
foreach($nodes as $name => $node)
if (!count($node->parents)) $output[$name] = $node;
return $output;
}

/**
* Parses an array of dependencies into an array of dependency pairs
*
* The array of dependencies would be in the form:
* $dependency_list = array(
* "name" => array("dependency1","dependency2","dependency3"),
* "name2" => array("dependencyA","dependencyB","dependencyC"),
* ...etc
* );
*
* @param array $dlist Array of dependency pairs for use as parameter in tsort method
* @return array
*/
function parseDependencyList($dlist=array())
{
$output = array();
foreach($dlist as $name => $dependencies)
foreach($dependencies as $d) array_push($output, array($d => $name));
return $output;
}
}

/**
* Node class for Topological Sort Class
*
*/
class TSNode
{
var $name;
var $children = array();
var $parents = array();

function TSNode($name="") {
$this->name = $name;
}
}
?>
Here is an example implementation for a series of modules which much be loaded based on pre-defined dependencies:
<?php

// define dependencies
// these definitions might be loaded from various modules at runtime
$module_dependencies['user'] = array('database','system','network','admin');
$module_dependencies['database'] = array('system','network');
$module_dependencies['network'] = array('system');
$module_dependencies['admin'] = array('system','network','database');
// in this example, the module called "system" has no dependencies

// pass this dependency tree to the constructor
// If the second parameter is true, it signals the passed array
// must first be converted internally into dependency pairs
$t = new TopologicalSort($module_dependencies, true);

$safe_load_order = $t->tsort();

// if tsort returns false, there was a dependency loop
if (! $safe_load_order)
die("There was a loop in dependency requirements.");

print_r($safe_load_order);

?>
As I wrote above, I did find some implementations in other languages. And within some larger code libraries in PHP. But I just wanted a stand-alone class. Here is a topological sort in Perl. And here is one in Java. And here is one in Ruby. And here is one even built into Unix.

Labels: