East Side King

Just wanted to quickly mention that we went to East Side King this past weekend. It’s kind of weird. You have to go to the Liberty bar to go to the restaurant.

So we went in and bought some drinks. First off we were shocked by their bartender. He was really nice and conversational. It’s a bit sad that seems shocking, but it was. They only have something like 5 taps, but their boring beers are Stella Artois and Negro Modello. And their bottled beer selection looks amazing. We got some Left Hand Wheat Beer and headed outside. It’s not a particularly hipster bar despite being in the hipster part of town. Most of the people looked like tech workers coming out for a beer after work.

East Side King is a trailer that they open up gates to. Basically it’s like an outside bar for the place. Except it serves food instead of beer. And the food…

Julie had “Thai Chicken Karaage” and I had “Poor Qui

.Net is a sign

So it came out today that the company that screwed up the appliance rebates in Texas this week had already screwed up in two other states.

But there should have been one big warning sign before that. The fact the firm handling the rebates was using .Net.

Now there are definitely good programmers working in .Net. And you can definitely built working websites with it. I’ve heard from good programmers who’ve done it. But it’s not where the energy is, and .Net seems to be drawing the unemployables. The programmers who can’t get a job anywhere else. The money is in Java. And the excitement is in Ruby, Python, and PHP. .Net positions exist… for other reasons.

And this was pretty obvious when under load they didn’t immediately remove images and other externally loaded static resources. This group didn’t even have the most basic of solutions to the problem in their toolkit.

So while it’s possible that firm you’ve hired that wants to develop in .Net is competent and has some fantastic programmers, chances are that it’s not. And it doesn’t.

Losing Our Bus

So, we found out yesterday that the most convenient bus to me is planned to go away. I can’t say I’m surprised. It goes to a couple industrial parks South of me, tools through my neighborhood, heads downtown and ends up in Enfield. It’s a nice route to have if you need it, but it’s hardly transporting a lot of people. I am sad though, because it’s part of why I was excited about our house. It’s a <20 minute trip downtown on the #9. We're also losing the #328 which went from our area to Barton Creek mall.

It doesn’t look like anyone in my neighborhood is interested in fighting it though.

But there are some interesting positives. The number 30 is going to terminate at the South Congress transit center near my house, and go by Central Market, Barton Creek Mall, and Zilker Park. Which is a pretty nice route. The transit center is probably a 20 minute walk or 10 minute bike ride from my house.

We are getting the number 300 Govalle route going by the West side of Mabel Davis park. While it’s a bit of a walk to get over there, that route goes by the HEB on Riverside, the MetroRail station (which might be useful if my company moves where they’re hinting at), GACA offices and the Blue Theater. So a pretty cool route. I’d thought about taking the 300 before, but it was always a transfer or 1 mile walk. Now it should be a quarter mile walk.

Still a bit sad about the #9. Maybe we’ll get a new route down Burleson when the Pleasant Valley extension to Todd Lane gets built.

Interactivity and Waiting

So I installed a system software update on my PS3 last night and had to wait for it to install. Julie and I wanted to watch a Netflix movie, and it’s tedious that I have to update something on my PS3 pretty much everytime I want to use it, but that’s a rant for another time.

So anytime I install a PS3 software update it always creeps very slowly up to 61% then jumps to 100%. So I’m quite confident the bar is a sham. This got my brainstorming.

Why couldn’t the bar respond to input? Like have it install a second slower per percentage, but if I bang on the buttons or shake the controller the bar moves faster. Make me feel like I have some control over the situation!

Which then made me think – couldn’t you provide me with a simple game like Soduku or Minesweeper to play while I wait.

Which made me think of Noby, Noby Boy where I get to fly a butterfly around the screen while I wait.

I know we want to look “professional”, but I’m sure that customers wouldn’t complain if they weren’t FORCED to go get coffee when they started an install.

I’m freaked out.

So I just got word that one of the second street businesses is looking forward to our play on Saturday. I’m a bit freaked out.

I don’t do audience participation pieces. I don’t do improv. I’m amazed by them. I like to watch some of them. The ones where they don’t single out the most uncomfortable person in the audience and make them the butt of every joke in the show.

But I’m doing a somewhat political comedy about cats on Saturday. From 1:00 to 2:30 in the second street district. It starts outside Austin Java. Moves to the Lofty Dog at 1:30, and then to the City Hall Amphitheater at 2:00.

Yes, we reserved the City Hall.

I’m writing this in collaboration, and that provides some inoculation, but I’m also producing this thing. And I’m a bit freaked out. I know more or less what makes people enjoy themselves with scripted theater. I know the beats you have to hit. I know how much set and costume and light people expect for their money.

But we’re throwing all that to the wind. All volunteer. Lots of chaos. Something like 7 total actors with actual scripted lines. Inviting the public to participate. Frightening.

There’s a potential for rioting here.

I mean I hope not. But the public at large can be somewhat frightening.

I have a lot of respect for people who live outside the black box right now. I don’t know how you deal with the idea that what you’re about to put out there could be very, very un-entertaining.

But it’ll be great, right?

Oh yeah, there’s free parking in the city hall parking garage ’till five.

Please don’t vote the bums out!

In the US we like to “vote the bums out” every 4 years or so. It’s amazing how frequently we’ve done this in our history. Yet if you look at history we’ve gotten nothing for our effort.

This year I encourage you to try something different. Vote for the party in power. Give them an overwhelming majority. I think the best way to create real change is to strangle the Republican party off completely. The reason that Democrats have trouble reaching consensus is that they represent pretty much every reasonable adult in our nation. They’ve got fiscal conservatives, labor unions, most of the LBGT community, and most importantly the majority of US citizens vote for Democrats. Sure the electoral college and Senate give the appearance that there are a lot of people voting Republican, but it simply isn’t true.

I’m not saying the Democrats are deserving of your vote because they have all the answers. I think they’re deserving of your vote because they will be good stewards of your vote until the Republican party is choked off completely. Once Democrats get 60-70% of the vote almost all corporate funding will go either to Democrats, or to the best third party. Suddenly the Republican party will start having to compete with the Libertarians, Greens, and who knows whom else for cash and ideas. Votes that prove you follow through with your beliefs will again become important. Once this ecosystem emerges the Democrats unnatural majority will instantly evaporate as voters move towards viable third parties that more accurately reflect their views. Hopefully this could be done within just one or two election cycles.

So don’t vote the bums out this year, vote them in! Spread the word and vote for real change.

Mackey’s should be fired

Just posted this is a comment on Spike’s piece at the Austinist on Whole Foods CEO Mackey and his stupid ideas to “fix” healthcare.

Mackey sounds like he’s got all sorts of great ideas and is the savior of private health-care. The problem is that his solutions don’t work. My company recently moved to an HSA (which he advocates). It’s only 20% less than our previous health plan, and yet it provides almost no benefits. The only benefit is for me. Since I and my family are healthier than average we can afford to bet (and make no mistake, HSAs are gambling) on the fact that we won’t be too unhealthy in a year to make it cost too much. And since our household makes more money than 80% of households in the U.S. we can afford the high deductible by putting away over $5000 a year as a hedge against getting sick. That $5000 is to cover our full deductible on top of the over $300 per month I pay. But how exactly does a Whole Foods “team member” afford that plan?

I wholeheartedly endorse these “healthy” plans as a benefit for workers. In much the same way that other employee assistance programs (gym memberships, flex time, etc.) are good. It’s great to encourage your employees to be healthy. But being healthy doesn’t prevent accidents, or genetic diseases, or disease caused by external factors like pollution.

It does not solve the problem of how a minimum wage worker without $2000 hanging around in the bank (because what percentage of workers in that bracket can afford to sock away over 12% of their income for health care? and then they’re supposed to save 12% for retirement too?) can afford care with an HSA. Maybe because I’ve had minimum wage jobs I realize how ridiculous that idea is.

HSAs exist. The market, that great god at whose altar Mackey worships, has wholeheartedly rejected them. Why? Because they cost too much and do too little. They’re health care for rich people. If you’re having trouble deciding where to invest your money an HSA might be for you. If you’re wondering how you’ll pay your rent this month, it’s probably not.

Until we expand the insurance base to include all healthy and unhealthy citizens it will become increasingly unaffordable. And conservatives have presented no ways to fix that. Democrats have presented three – socialized medicine, a public option, and requiring the purchase of health insurance. HSAs don’t fix this problem. They just temporarily make health care cheaper for employers. CEOs who think this is a solution rather than a stop-gap should be fired for being ridiculously short-sighted.

Welcome to Ainabulak-3!

So from 1990-1992 I lived in the Soviet Union. My family were officially there as students, so we were placed into foreign student housing in Ainabulak-3. A brand new micro-district in Almaty, Kazakhstan. It was indeed ugly and bleak. Oddly enough in contrast to US development practices they put in the roads last. It’s an interesting practice in a place that has very little rainfall (Almaty is desert). You don’t destroy your roads with construction traffic. So here’s the view out of our back window. The central area became essentially a cul-de-sac. There was a road that curved along one side of it and the central area was used for football and gardens. Essentially a neighborhood park. Of interest are the buildings you see in the near distance. Those are public service buildings. Schools in this case, if I’m remembering correctly.

Here’s the view of the front of the building. I’ve blurred my sister as she tends to not enjoy pictures of herself from this time period. Our building is on the right. The shorter buildings in the near foreground are more public service buildings. If memory serves a kindergarden and grocery strore. In between the six story building and the magazine is a minor arterial with bus service.

So why do I bring this up, other than to show off some pictures illustrating how ugly the Soviet Union often was? Because I was panning over google earth recently looking at the area, and saw the term “microdistrict”. So I looked that up and found this info:

Microdistrict, or microraion , is a residential complex—a primary structural element of the residential area construction in the Soviet Union and in some post-Soviet states. … According to the Construction Rules and Regulations of the Soviet Union, a typical microdistrict covered the area of 10–60 hectares (30–160 acres), up to but not exceeding 80 hectares (200 acres) in some cases, and comprised residential dwellings (usually multi-story apartment buildings) and public service buildings. As a general rule, major motor roads, greenways, and natural obstacles served as boundaries between microdistricts, allowing an overall reduction in city road construction and maintenance costs and emphasizing public transportation. Major motor roads or through streets were not to cross microdistricts’ territories. The entrances to a microdistrict’s territory were to be located no further than 300 meters (1000 ft) apart. Standards also regulated the accessibility of the public service buildings (excluding schools and pre-school facilities) by imposing a 500-meter (1,500–foot) limit as the farthest distance from any residential dwelling. One of the city-planners’ tasks was to ensure that the fewest number of public buildings was built to cover the microdistrict’s territory in accordance with the norms. Typical public service structures include secondary schools, pre-school establishments (usually combined kindergarten and nursery), grocery stores, personal service shops, cafeterias, clubs, playgrounds, and building maintenance offices, as well as a number of specialized shops. The exact number of buildings of each type depended on the distance requirement and the microdistrict’s population density and was determined by means of certain per capita standards.

I had no clue it was that planned, but it was very easy to walk. It was easy to get out of our cluster of buildings to a main road to catch a bus. While the store near us wasn’t that great, it was close, and schools were very close. Most of the vehicular traffic were taxicabs and it was easy for them to learn the district since they only had to learn how to get to a particular area and then the customer could direct them into the correct building segment or just drop them off on the main road, since it was a very quick walk into any given segment.

So before I go into what we could learn from this, here is the Google Maps view now.

View Larger Map

I’m blown away by the amount of green now. As you can see from my pictures it was pretty lifeless.

It’s interesting to me, though when we think about cul-de-sacs and planning. We tend to think of cul-de-sacs as the enemy, but when you look at this area, pretty much everything is a cul-de-sac. I take away some pretty good planning ideas from this:

  • Access to arterials. No residence or business should be more than ‘x’ distance from an arterial
  • Access to public services. Every ‘x’ area should have space for schools, restaurants, grocery stores, and commercial.
  • Buffer space. Every residential and business area should have a buffer from the main road, but should be a walkable distance to it.

While most people see the Soviets planned to a joke, there’s a lot of sense to what they are doing. And this should appeal to fiscal conservatives as well, because this sort of planning makes the best use of government provided resources like roads and public transit. It’s very SimCity, but it’s amazing how little of this sort of planning actually goes on.

It would be very interesting to me to see what strong central planning for infrastructure would create in an unzoned city like Houston.

Syncing Comments with Facebook

I’m posting this here in case anyone else wants to pick it up and run with it. I wrote a piece of code to sync my facebook notes and blog post comments. All of my blog posts already are added to facebook via RSS feed, but I was ending up with essentially two conversations. First install Services_Facebook from the PEAR repository. Then you’ll need to create a new private application with a Facebook developer account. Set the “Connect URL” to point at this script. Then uncomment the commented out section. Visit the page and you’ll be redirected to facebook. Authorize the app, and then take the session key that is returned when your are redirected and insert it into the appropriate place in the script. Comment out the code again.

You’ll need to replace all references to “blog/Blog.php”, “blog/Post.php”, and “blog/Comment.php” as those are custom to this site, but it should be fairly easy to replace them with something like a wrapper for blogger or wordpress.

I run this as a cron job on my server every 20 minutes.

require_once 'Services/Facebook.php';
require_once 'blog/Blog.php';
require_once 'blog/Post.php';
require_once 'blog/Comment.php';
ini_set("display_errors","1");


class FacebookUtils {
    private static $instance;

    public function getInstance() {
        Services_Facebook::$apiKey = '<>';
        Services_Facebook::$secret = '<>';
        if(!FacebookUtils::$instance) {
            FacebookUtils::$instance = new FacebookUtils();
        }
        return FacebookUtils::$instance;
    }

    public function getApi() {
        $api = new Services_Facebook();
        $api->sessionKey = '<>';
        return $api;
    }

    public function getNoteId($user, $title) {
        $title = addslashes($title);
        $fql = "SELECT note_id
                  FROM note
                 WHERE uid = $user
                   AND title = '$title'";

        $result = $this->getApi()->fql->query($fql);

        $notes = array();
        foreach ($result->note as $note) {
            return $note->note_id;
        }
    }
    public function getUserName($uid) {
        $fql = "SELECT first_name, pic_small
                 FROM user
                 WHERE uid = $uid";

        $result = $this->getApi()->fql->query($fql);
        foreach($result->user as $user) {
            return array(
                "first_name" => "$user->first_name",
                "pic" => "$user->pic_small",
            );
        }

    }
    public function getComments($id) {
        $fql = "SELECT post_id, fromid, time, text, id
                  FROM comment
                 WHERE object_id = $id
                 ORDER by time desc";

        $result = $this->getApi()->fql->query($fql);
        $comments = array();
        foreach($result->comment as $comment) {
            $comments[] = array(
                "id" => "$comment->id",
                "text" => "$comment->text",
                "time" => "$comment->time",
                "from" => $this->getUserName($comment->fromid),
                "post_id" => "$comment->post_id",
            );
        }
        return $comments;
    }
}

    $api = FacebookUtils::getInstance();
    /*
    if(empty($_REQUEST["session_key"])) {
        header("Location: http://www.facebook.com/login.php?api_key=" 
            . Services_Facebook::$apiKey 
            . "&connect_display=popup&v=1.0"
            . "&next=http://www.facebook.com/connect/login_success.html"
            . "&cancel_url=http://www.facebook.com/connect/login_failure.html"
            . "&fbconnect=true&return_session=true"
            . "&session_key_only=true"
            . "&req_perms=read_stream,publish_stream,offline_access");
    }
    else {
        print $_REQUEST["session_key"];
    }
    exit;
    */
    $blog = new Blog("NDLKM2VHYWYTZDZHMI1MYTG1LTHKN2YTZWU5NGZLNMI4ZGU0");
    $posts = Post::getPosts('OWNER_UID',Array($blog->UID), 
        " and visible = 'True' order by DATE desc limit 0, 5 ");

    $map = array();
    foreach($posts as $post) {
        $map[$post->UID] = $api->getNoteId("675098370", $post->TITLE);
    }

    foreach($map as $postUID => $noteID) {
        $localComments = Comment::getComments('POST_UID',Array($postUID));
        $fbComments = $api->getComments($noteID);

        $addLocal = array();
        $addRemote = array();
        foreach($fbComments as $fbComment) {
            $foundComment = false;
            foreach($localComments as $localComment) {
                $fbText = preg_replace("/^.* on Tim's blog says.../", "", $fbComment["text"]);
                if($fbText == $localComment->COMMENT) {
                    $foundComment = true;
                }
            }
            if(!$foundComment) {
                $addLocal[$fbComment["id"]] = $fbComment;
            }
        }
        foreach($localComments as $localComment) {
           $foundComment = false;
            foreach($fbComments as $fbComment) {
                $fbText = preg_replace("/^.* on Tim's blog says.../", "", $fbComment["text"]);
                if($fbText == $localComment->COMMENT) {
                    $foundComment = true;
                }
            }
            if(!$foundComment) {
                $addRemote[$localComment->UID] = $localComment;
            }
        }
        print "Post " . $postUID . "n";
        print "Add locally:n";
        print_r($addLocal);
        print "Add remote: n";
        print_r($addRemote);
        foreach($addLocal as $fbComment) {
            $c = new Comment();
            $c->set('POST_UID',$postUID);
            $c->set('NAME', $fbComment["from"]["first_name"]);
            $c->set('ICON', $fbComment["from"]["pic"]);
            $c->set('TITLE', $fbComment["from"]["first_name"] . " on Facebook says...");
            $c->set('COMMENT', $fbComment["text"]);
            #$c->set('EMAIL', $this->director->getPostParam('commentemail'));
            #$c->set('URL', $this->director->getPostParam('commenturl'));
            #$c->set('NOTIFY', $this->director->getPostParam('commentnotify'));
            $c->set('DATE', date('Y-m-d H:i:s', $fbComment["time"]));
            #$c->set('IP',$this->director->getServerParam('REMOTE_ADDR'));
            $c->update();
        }

        foreach($addRemote as $comment) {
            $result = $api->getApi()->users->callMethod('comments.add', array(
                'session_key' => $api->getApi()->sessionKey,
                'object_id' => $noteID,
                'text' => $comment->NAME . ' on Tim's blog says...' . $comment->COMMENT,
            ));
        }
    }