Macaroni casserole

The following details Greg Opperman’s recipe for vegan macaroni and “cheese”. Likely one of the tastiest of dishes I’ve ever had. It’s a touch elaborate, but well worth the effort.

Veggie Beef

  • 1 cup TVP
  • 2 cups water
  • 2 tbsp vegetable oil
  • 2 tbsp mild chili powder
  • 1 tbsp cumin
  • 1 tsb soy sauce
  • 1 veggie broth cube
  • 1 tbsp Sriracha
  • ¼ cup chopped sage leaves
  1. Combine ingredients in a saucepan.
  2. Boil then simmer.
  3. Adjust flavours as necessary.

Main sauce

  • ½ cup flour
  • ½ cup vegetable oil
  • 4 cups unflavoured “milk” (soy, almond or rice)
  • 1½ tbsp tumeric
  • 1½ tbsp madras curry
  • 1 tbsp garam masala
  • 2 tbsp soy sauce
  • 1 veggie broth cube
  • 1 tbsp yellow mustard
  • 1 inch fresh ginger
  • 4 cloves garlic
  • 1 batch veggie beef (as per above)
  • 1 cup nutritional yeast flakes
  • 8 ounces peas
  • 8 ounces corn
  • 1 pound rotini pasta (al dente)
  1. Make a roux with the oil, flour and milk.
  2. Add the spices and bring to a bubble.
  3. Simmer with the remaining ingredients.

Topping

  • ¼ cup sage leaves
  • 1 cup panko breadcrumbs
  • 8 ounces margarine
  1. Melt the margarine.
  2. Add the sage.
  3. Add the breadcrumbs and combine.

Combine

  1. Preheat the oven to 400°F.
  2. Pour the main sauce into the casserole dish, followed by the topping.
  3. Bake for 30 minutes (you’ll want the topping to be crispy, which may require broiling).

Invasive browser sniffing

Take the a:visited pseudo-class and use it to determine if the client’s browser has visited a site. Do this en masse with a subset of Alexa’s top 1m websites and you can build up a fairly detailed profile of a visiting brower’s history.

var sites = [
  'http://google.com',
  'http://facebook.com'
];

$(function(){
  for (var i in sites) {
    $("#test").html("
      <li><a href='"+sites[i]+"'>"+sites[i]+"</a> </li>
    ");
    if ($("#test a").css('color') == "rgb(0, 204, 0)")
      $("#test li").appendTo("#visited");
    else
      $("#test li").appendTo("#not-visited");
    }
});

The ethics of this technique are questionable, especially if you retain this data and associate it with an email address or a registered user account. The only way I can see to protect against it is to disable JavaScript on all but the few sites you trust.

You could augment it to only send a sampling of 50 sites, respond with an ajax post, then determine which 50 to check next (e.g. if a user has visited a site specific to tech news, poll your next 50 on the most popular tech news sites). This concept is used at What The Internet Knows About You.

Fondue and fudge

This recipe works well both as fondue (while hot) and a soft fudge (while cold).

  • ¼ cup margarine
  • 225 grams dark chocolate
  • ½ tbsp flour
  • ½ cup corn syrup
  • ½ tsp vanilla
  • 2 tbsp soy milk
  1. Melt the chocolate and liquids in a double boiler.
  2. Sift in the flour to thicken the mixture up.

Misinterpreting problem spaces

Polls and elections aren’t the same type of thing. The former asks for descriptive data, the latter for prescriptive preferences. To illustrate the hazards of this common misunderstanding, let’s go over some other ways data can partitioned and the problems that arise from confusing them.

Ordered data vs unordered data

Ordered data has an innate linear ordering, whereas unordered data doesn’t.

Ordered
How many apples can you eat in one sitting? (0, 1, 2…)
Unordered
What was the last type of apple you ate? (Granny smith, red delicious…)

When unordered data is confused as ordered data, a relationship is erroneously implied between the items.

unordered-as-ordered

When ordered data is confused as unordered, data trends are buried.

ordered-as-unordered

Ordered discrete vs ordered continuous

With discrete data, there exist two values for which there is no valid value in between, whereas continuous data can always be broken down into more detail.

Discrete
How many thermostats do you have in your house? (0, 1, 2…)
Continuous
What is the average temperature in your house? (22.1°C, 20.3°C…)

When discrete data is confused as continuous, inappropriate conclusions can be reached (chances are you have 2.3 thermostats in your house).

discrete-as-continuous

When continuous data is confused as discrete, granularity is lost. We can’t tell from the graph below whether there’s a large portion of 0.0km entries, if only odd decimal entries exist (0.1, 0.3, 0.5…), or any other detail hidden by these brackets.

continuous-as-discrete

Simple data vs compound data

Compound data have multiple values that bear some relation to each other.

Simple
How big is your television diagonally (24″, 32″, 34″…)
Compound
What are the dimensions of your television (20″x18″, 24″x20″…)

Compound data can be misrepresented as multiple simple data axes by ignoring the coupling between the two values, whereby the conditional probabilities are lost. Worse, it can be restricted down to a single simple data axis, whereby relevant data is entirely discarded (e.g. do sampled televisions only exist at certain aspect ratios?).

compound-as-simple

Descriptive data vs prescriptive preferences

Descriptive
What did you have for dinner last night?
Prescriptive
What should we have for dinner tonight?

The difference is subtle, but it’s there. With descriptive data, respondents have no incentive to tactically misrepresent their opinions. With prescriptive preferences, respondents (aka voters) are aware that their response will influence a future that likely affects them and will vote accordingly.

When prescriptive preferences are confused as descriptive data, a few things can happen:

  • Continuous data can be filtered down into discrete data. Instead of allowing degrees of preference, ballots are restricted to binary expressions of support.
  • Compound data can be filtered down into simple data. Although multiple options exist, ballots restrict the voter to supporting a single candidate.

Both confusions are present when Plurality voting is used in lieu of a more expressive ballot, where in voters could express more than just a single binary preference for a single option. Maybe this comes from ignorance of alternative voting methods, technical restrictions from the online voting application used, or seeing everything as a nail when you’re holding a hammer; Take your pick.

When Plurality voting is used to obtain prescriptive preferences, the same type of analytical fallacy is being made as is detailed in the above examples, all of which lead to a poor understanding of the underlying reality the data represents.

Implementing Schulze STV

Thus far, my implementation of Schulze STV has worked fairly well. The downside I’ve recently run into is in simulating real world multiple winner elections. Take Vancouver’s 2008 municipal election as an example, in which 32 candidates ran for 10 seats. The problem-space we’re looking at consists of 32 choose 10 nodes and (32 choose 10) x 11 edges. For those unfamiliar with binomial coefficients, that’s roughly 64 million nodes and 709 million edges. Exponential runtime is a bitch.

For the purposes of heuristic development, let’s look at Tideman’s A03. It’s a set of 989 ballots to elect 7 winners from 15 candidates. Schulze STV computes the winning set as B/D/E/F/H/K/N by looking at 6435 nodes and 51480 edges. How do we best prune the number of candidates down so as to look at a smaller subset, yet still produce the same winning set in most cases? Well, what’s quickly available? We can easily calculate the sum of all votes, standard deviation, and whatnot.

If we wanted to prune off the least preferred by sum (indicated by larger sums), we’d be cutting off one of a winner Schulze STV would want to elect. Alternatively, let’s look at the number of voters that mark each candidate in first place. If a voter marks two candidates in first place, split their vote between the two.

That heuristic seems great at first as it didn’t accidentally eliminate winning candidates and it reduced the number of nodes to 120, a 98% reduction in problem space size. However, the winning set would now be computed by SchulzeSTV as A/B/D/E/G/L/N, which is significantly different. Furthermore, the heuristic is going to incentivize tactical voting. Sometimes there aren’t any easy shortcuts and the best thing to do is just optimize the implementation.

Vancouver Open Data

Some months ago, there was talk in Vancouver about opening up the city’s data. As of yesterday, that data is now widely accessible in open formats at data.vancouver.ca. One such data layer is the bike routes in the city. There’s a lot more and it’ll be fun to see where it leads.

Short codes

With the advent of Twitter, shortened URLs have become all the rage: http://bit.ly/5dk33b, http://imgur.com/9G2rL, http://www.reddit.com/9dfo1. This kind of thing really isn’t all that hard to do.

$short_code = substr(preg_replace(
  array('/\//', '/\+/'),
  array('-', '_'),
  base64_encode(sha1(serialize($data, $salt), true))
), 0, 7);

Your $salt might be something as simple as a manually generated random string. If your data is time sensitive, it could be microtime(). Fancier two-way conversions are doable, in which you convert your primary key into a base-62 number, but I’ve yet to find a need for that.

Root latke waffles

  • 8 cups shredded root vegetables (e.g. yam, sweet potato, beet, carrot, onion, etc.)
  • 1 cup flour
  • ½ cup cornstarch
  • 1 tsp salt
  • ½ cup water
  • ¼ cup oil
  • spices to taste

Shred the vegetables in a food processor (if you try this by hand, you’re likely to be at it all day). Mix the dry and wet separately before combining. Fry them up in a waffle iron and serve hot with any kind of dressing that suits: ketchup, salad dressing, raw tahini. It’s all good.

Motivated hobbies

Start a project around a subject you feel passionate about. It’s surprising how quickly you can get things done when there’s internal motivation. My most recent project went from prototype to useful application in about 10 days. I have to say, there’s a bit of pride that goes along with reaching a presentable milestone.

Modern Ballots

One of the difficulties I’ve run into with my recent project is explaining what it is a back-end web service does. In response, I’ve put a small web app up at modernballots.com. This front-end lets you create elections, but has no direct knowledge of voting systems. The winner is calculated remotely through the election web service, which is publicly available for other programmers to use.

At the moment, the front-end only requests the winner as calculated by Schulze STV, but that’s just to make the interface simpler.