Thursday, March 03, 2011

Ruby Light #2

This is the work of one of my colleagues here at TestFreaks, and is the coolest little meta-programming trick I've seen in a while!

code_timer_helper.rb
module CodeTimerHelper

# Creates a CodeTimer section around the method
#
def timed_method(timer, method_name, section_name = method_name.to_s)
eigenclass = (class << self; self; end)
eigenclass.class_eval do

define_method method_name do |*args, &block|
timer.start(section_name)
begin
super(*args, &block)
ensure
timer.stop(section_name)
end
end
end
end
end

Thursday, February 24, 2011

Ruby Light #1

The Ruby Light series is for Ruby code dumps that amuse me for one reason or another, possibly including commentary.

Here's the first one:

redirect_stdio.rb
# See: http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/

require 'stringio'

module Kernel
def capture_stdout(out = StringIO.new)
begin
$stdout = out
yield
ensure
$stdout = STDOUT
end

out
end

def use_my_stdin(instream)
begin
$stdin = instream
yield
ensure
$stdin = STDIN
end

instream
end
end


converter_test.rb
require 'lib/redirect_stdio'
require 'lib/converter.rb'

class ConverterTest < Test::Unit::TestCase
def test_convert
input_data = [
[ # headers
'rank', # index 0
'', # index 1
'', # index 2
'', # index 3
'', # index 4
'', # index 5
'name', # index 6
'category', # index 7
],
[ # data line 0
'123', # index 0
'', # index 1
'', # index 2
'', # index 3
'', # index 4
'', # index 5
'Foo', # index 6
'Bar', # index 7
],
]

converter = Converter.new
instream = StringIO.new input_data.map{|line| line.join("\t")}.join("\n")
output = capture_stdout do
use_my_stdin(instream) { converter.convert }
end

input_data[1..-1].each do |data|
assert_match /^#{data[6]} is rank #{data[0]} in #{data[7]}$/, output.string
end
end
end

Sunday, January 09, 2011

Wheaton's Law

In which several pleas for a saner New Year are put forward, unified by the concept of Wheaton's Law and made necessary by the attempted assassination of Arizona Rep. Gabrielle Giffords.
  1. Dial it Back: To illustrate the premise that the sort of incendiary remarks made regularly on Fox "News", on the radio (e.g. Messrs. Rush Limbaugh, Glen Beck, et al.) and by an increasing number of politicians, let me quote the news piece linked above:
    At a news conference Saturday night, a clearly emotional Dupnik, who has been close to both Giffords and Roll, repeatedly cited what he characterized as the "vitriol" that has infected political discourse. He said that his own state has become "the mecca for prejudice and bigotry."

    There is reason to believe, he said, that the shooting suspect "may have a mental issue," adding that people like that "are especially susceptible to vitriol."
    And here's a treasure trove of absurdity from The Huffington Post:

    • A statement by Giffords herself, earlier last year and eerily prescient:
      Giffords expressed similar concern, even before the shooting. In an interview after her office was vandalized, she referred to the animosity against her by conservatives, including Sarah Palin's decision to list Giffords' seat as one of the top "targets" in the midterm elections.

      "For example, we're on Sarah Palin's targeted list, but the thing is, that the way that she has it depicted has the crosshairs of a gun sight over our district. When people do that, they have to realize that there are consequences to that action," Giffords said in an interview with MSNBC.

    • It just gets worse:
      During his campaign effort to unseat Giffords in November, Republican challenger Jesse Kelly held fundraisers where he urged supporters to help remove Giffords from office by joining him to shoot a fully loaded M-16 rifle. Kelly is a former Marine who served in Iraq and was pictured on his website in military gear holding his automatic weapon and promoting the event.

      "I don't see the connection," between the fundraisers featuring weapons and Saturday's shooting, said John Ellinwood, Kelly's spokesman. "I don't know this person, we cannot find any records that he was associated with the campaign in any way. I just don't see the connection.

      "Arizona is a state where people are firearms owners - this was just a deranged individual."

    • And finally:
      Law enforcement officials said members of Congress reported 42 cases of threats or violence in the first three months of 2010, nearly three times the 15 cases reported during the same period a year earlier. Nearly all dealt with the health care bill, and Giffords was among the targets.

    So next time you are tempted to say something extreme, nasty, or just mean, stop and make sure your statement is proportional. Words to steer clear of include, but are not limited to: Hitler, Nazi, Stalin, socialist / communist / liberal (which seem to be synonyms in right-wing political discourse in America), devil, terrorist, enemy of the state, un-American, Satan (Prince of Lies), evil, etc.

  2. Guns. What are they good for? (Absolutely nothing?) Though the weapon allegedly used by Jared Lee Loughner (is it an unspoken rule that all political assassins must be known by all three names?) was only a handgun (and not a fully automatic assault rifle, which are also bizarrely legal to buy in the US), he still managed to kill six people and wound 13 others. If we must own guns, is it too much to ask that they be limited to hunting rifles, shotguns, and semi-automatic handguns with six-round clips, the last of which must be locked in a gun safe at a shooting range? Full disclosure: I used to be a stiff opponent of gun control, in any way, shape or form, but for the sole reason that I considered weapons as the last resort of citizens against an illegimate government. Thinking at some length on the last point, it finally dawned on me that even a fully automatic assault rifle would not do much against tanks, planes, and missiles (see: Ruby Ridge, Waco, etc.), thus removing my only point of contention with the idea of gun control. If you think it is wrong for the government to tell you that you cannot own a deadly weapon, would you be OK for it to be legal to purchase a tank? An anti-aircraft gun? An anti-personnel mines? A bomb? Need I go on?

OK, so really only two points. In the spirit of the above, I've made only two New Year's resolutions for 2011, and they're ones that, if I cannot keep, say something about my character:
  1. Make an earnest attempt to abide by Wheaton's Law, and in the instances where I fail,
  2. Make a sincere apology to the victim.

Happy New Year, and let's work together to make 2011 a less ridiculous year.

Friday, November 05, 2010

Software Writing Clichés

If you are writing a book, essay, or blog entry about software development, please refrain from all of the following:

  • Lame references to how everyone in offices drink coffee

  • Lame references to Mondays

Seriously, have we learned nothing from Office Space?

Saturday, September 11, 2010

Välkomna till Sverige

My son just came in from riding his "new" bike, which a slightly older neighbour boy loaned to him. Before that, he was playing in the little park, which is about 50 metres from our front door. And before that, he was helping me pick apples from the big tree in our front yard. And this is just another Saturday in Sweden. :)

We moved here almost a month ago now, to a quiet neighbourhood in the southern suburbs of Stockholm. I'm working for a small Internet company named TestFreaks, which has an office next to T-Centralen, Stockholm's central metro station. It takes me just under ten minutes to walk to the metro station near our house, then 25 minutes on the train, then five minutes from T-Centralen to my office--not a bad commute at all.

We found a townhouse to rent, one of about 40 in a little neighbourhood that was built in the 60s. The house is 100 square metres, up from 75 square metres in Dublin and 50 in Tokyo. Kai has his own bedroom, with a full-sized single bed and wallpaper with aeroplanes! The kitchen / dining room, our room, and a spare bedroom that we are using as an office round out the second floor (AKA the first floor in Sweden, the one at ground level is called the ground floor, often labelled 0 on elevators). Downstairs is a large living room and one more bedroom, which we're planning to turn into a "gym" by putting an elliptical trainer in it.

As I mentioned, our neighbourhood has its own little park, which is situated in the centre of a loop of townhouses. There are lots of kids around, and they leave toys in the park to share since it is private to our neighbourhood. There are at least four kids almost exactly Kai's age, and many more slightly older. He is very excited to play with the "big kids", and his best friend is a six year-old girl named Mina who thinks it is very funny that Kai speaks English and not Swedish. Hopefully, he'll pick up Swedish quickly from playing with the kids. We're also signing him up for kindergarten so that Lyani can concentrate on finding a job. He's very excited about going after he and Lyani went to take a tour of the kindergarten last week.

We're enjoying a nice, long summer, which seems to be drawing to a close, but still gives us tee-shirt weather like today. Later on, we're going over to a friend's house for a cookout.

So far, we're enjoying life in Sweden indeed!

Friday, August 13, 2010

Test Driven Development by Example, in Ruby

I have long been interested in the Ruby programming language. Luckily for me, I've just gotten a job which requires me to write code in Ruby, meaning that I finally have to learn Ruby properly. The hardest part of learning a new language for me is finding an interesting and somewhat challenging problem to work on with the new language. Little exercises like the Towers of Hanoi or the Fibonacci sequence are decent problems for programming interviews, but mainly test logic and basic language syntax.

I had just finished reading Programming Ruby 1.9, and was ready to sink my teeth into actually writing some Ruby. Being a long-time proponent of Test Driven Development, an interesting idea occurred to me. In Kent Beck's Test Driven Development: by Example book, he uses the example of adding different currencies together. This is a pretty easy problem to understand, and relatively easy to code up, but has just enough complexity in design to offer me some interesting practice with Ruby. In the book, Beck writes all of his unit tests and code in Java--I wrote the same tests and code in Ruby.

For readers who do not have their copy of Test Driven Development: by Example handy, the problem in a nutshell can be stated by one test:

  • $5 + 10 CHF = $10 if rate is 2:1


Or, in plain English: adding five US dollars to 10 Swiss francs should yield 10 US dollars if the exchange rate is 2 Swiss francs to 1 US dollar. Users of Test Driven Development (hereafter TDD) will not be surprised to learn that writing this test required writing many smaller tests first, such as adding two dollar amounts, converting a dollar amount into a franc amount, etc.

I was able to work through the 15 chapters of the example in two days (maybe six hours of coding time). Ruby's MiniTest unit testing framework is an xUnit variant, just like the JUnit framework that Beck uses in the book, so my Ruby tests are virtually the same as his Java tests. The class design is also the same, with the one exception that I did not need the Expression interface that his Java design requires, thanks to duck typing. It felt to me like duck typing simplified the Ruby code quite a bit, as compared to the Java code. There were certainly several times when Beck needed a page to present some refactorings to clean up the design that took me one line in Ruby. All told, my Ruby version was 62 lines of functional code and 78 lines of test code, as opposed to 91 and 89, respectively, in the Java version.

So, with no further ado, here is the example. I'll show you the tests first, then the functional code, then finally the log of all of my commits while working on this problem (my Git repository is available for anyone who wants it: http://www.jmglov.net/opensource/src/tdd-by-example_ruby_git.tar.gz).

Test code: test_Money.rb

#!/usr/bin/env ruby1.9.1

require 'money'
require 'test/unit'

class TestMoney < MiniTest::Unit::TestCase
def test_multiplication
five = Money.dollar(5)
assert_equal(Money.dollar(10), five * 2)
assert_equal(Money.dollar(15), five * 3)
end

def test_equality
assert(Money.dollar(5) == Money.dollar(5))
refute(Money.dollar(5) == Money.dollar(6))
refute(Money.dollar(5) == Money.franc(5))
end

def test_currency
assert_equal(:USD, Money.dollar(1).currency)
assert_equal(:CHF, Money.franc(1).currency)
end

def test_simple_addition
five = Money.dollar(5)
sum = five + five
bank = Bank.new
reduced = bank.reduce(sum, :USD)
assert_equal(Money.dollar(10), reduced)
end

def test_plus_returns_sum
five = Money.dollar(5)
sum = five + five
assert_equal(five, sum.augend)
assert_equal(five, sum.addend)
end

def test_reduce_sum
sum = Sum.new(Money.dollar(3), Money.dollar(4))
bank = Bank.new
result = bank.reduce(sum, :USD)
assert_equal(Money.dollar(7), result)
end

def test_reduce_money
bank = Bank.new
result = bank.reduce(Money.dollar(1), :USD)
assert_equal(Money.dollar(1), result)
end

def test_reduce_money_different_currency
bank = Bank.new
bank.add_rate(:CHF, :USD, 2)
result = bank.reduce(Money.franc(2), :USD)
assert_equal(Money.dollar(1), result)
end

def test_identity_rate
assert_equal(1, Bank.new.rate(:USD, :USD))
end

def test_mixed_addition
five_bucks = Money.dollar(5)
ten_francs = Money.franc(10)
bank = Bank.new
bank.add_rate(:CHF, :USD, 2)
result = bank.reduce(five_bucks + ten_francs, :USD)
assert_equal(Money.dollar(10), result)
end

def test_sum_plus_money
five_bucks = Money.dollar(5)
ten_francs = Money.franc(10)
bank = Bank.new
bank.add_rate(:CHF, :USD, 2)
sum = Sum.new(five_bucks, ten_francs) + five_bucks
result = bank.reduce(sum, :USD)
assert_equal(Money.dollar(15), result)
end

def test_sum_times
five_bucks = Money.dollar(5)
ten_francs = Money.franc(10)
bank = Bank.new
bank.add_rate(:CHF, :USD, 2)
sum = Sum.new(five_bucks, ten_francs) * 2
result = bank.reduce(sum, :USD)
assert_equal(Money.dollar(20), result)
end
end


Functional code: money.rb


class Money
attr_reader :amount, :currency

def initialize(amount, currency)
@amount = amount
@currency = currency
end

def self.dollar(amount)
Money.new(amount, :USD)
end

def self.franc(amount)
Money.new(amount, :CHF)
end

def ==(other)
@amount == other.amount &&
@currency == other.currency
end

def *(multiplier)
Money.new(@amount * multiplier, @currency)
end

def +(addend)
Sum.new(self, addend)
end

def reduce(bank, to_currency)
rate = bank.rate(@currency, to_currency)
Money.new(@amount / rate, to_currency)
end
end

class Bank
def initialize
@rates = {}
end

def reduce(expression, to_currency)
expression.reduce(self, to_currency)
end

def add_rate(from, to, rate)
@rates[[from, to]] = rate
end

def rate(from, to)
return 1 if from == to
@rates[[from, to]]
end
end

class Expression
end

class Sum
attr_reader :augend, :addend

def initialize(augend, addend)
@augend = augend
@addend = addend
end

def reduce(bank, to_currency)
amount = @augend.reduce(bank, to_currency).amount +
@addend.reduce(bank, to_currency).amount
Money.new(amount, to_currency)
end

def +(addend)
Sum.new(self, addend)
end

def *(multiplier)
Sum.new(@augend * multiplier, @addend * multiplier)
end
end


Commit log

  1. TestMoney#test_multiplication fails to compile (C1 : Multi-Currency Money)

  2. test_Dollar: TestDollar should subclass Test::Unit::Testcase instead of MiniTest::... (C1 - Multi-Currency Money)

  3. test_Dollar: should be Dollar.new(...) (C1 - Multi-Currency Money)

  4. test_Dollar#test_multiplication: red bar! (C1 - Multi-Currency Money)

  5. TestDollar#test_multiplication: green bar! (C1 - Multi-Currency Money)

  6. Dollar#times sets @amount (green bar) (C1 - Multi-Currency Money)

  7. Dollar#times real implementation (green bar) (C1 - Multi-Currency Money)

  8. TestDollar#test_multiplication object modified (RB) (C2 - Degenerate Objects)

  9. TestDollar expects new obj from Dollar#times (ERR) (C2 - Degenerate Objects)

  10. Dollar#times returns new obj (GB) (C2 - Degenerate Objects)

  11. TestDollar#test_equality (RB) (C3 - Equality for All)

  12. Dollar#== return true (GB) (C3 - Equality for All)

  13. TestDollar#test_equality tests inequality (RB) (C3 - Equality for All)

  14. Dollar#== actual implementation (GB) (C3 - Equality for All)

  15. test_Dollar: switched to ruby1.9.1 and MiniTest

  16. TestDollar#test_multiplication asserts equality(GB) (C4 - Privacy)

  17. Dollar#amount is protected (GB) (C4 - Privacy)

  18. TestFranc#test_multiplication (ERR) (C5 - Franc-ly Speaking)

  19. Copied Dollar to Franc (GB) (C5 - Franc-ly Speaking)

  20. Added Money class (GB) (C6 - Equality for All, Redux)

  21. Dollar subclasses Money (GB) (C6 - Equality for All, Redux)

  22. Pushed Dollar#== up to Money (GB) (C6 - Equality for All, Redux) (Ruby eliminates the need to fool around with casts and instance variables!)

  23. Added TestFranc#test_equality (GB) (C6 - Equality for All, Redux)

  24. Franc subclasses Money (GB) (C6 - Equality for All, Redux)

  25. Removed Franc#== (GB) (C6 - Equality for All, Redux)

  26. TestMoney#test_equality exposes a bug (ERR): we should have moved the protected attr_reader :amount up to Money

  27. Pushed protected @amount up to Money (GB) (C7 - Apples and Oranges)

  28. Money#== compares classes (GB) (C7 - Apples and Oranges)

  29. TestDollar#test_multiplication use Money#dollar(GB) (C8 - Makin' Objects) (Ruby's duck typing eliminates the Money#times compiler error from the book!)

  30. Using Money#dollar in all tests (GB) (C8 - Makin' Objects)

  31. Added Money#franc factory (GB) (C8 - Makin' Objects)

  32. test_Money requiring 'money' breaks tests (ERR) (C8 - Makin' Objects) (This is a Ruby-only problem, since the Java tests probably do an 'import com.wycash.money.*')

  33. All classes declared in money.rb (GB) (C8 - Makin' Objects)

  34. Deleted dollar.rb and franc.rb (GB) (C8 - Makin' Objects)

  35. Money#currency and unit tests for same (GB) (C9 - Times We're Livin' In)

  36. Currency becomes an instance variable (GB) (C9 - Times We're Livin' In)

  37. Pulled up Money#currency (GB) (C9 - Times We're Livin' In)

  38. Added currency param to Franc#new (ERR) (C9 - Times We're Livin' In)

  39. Money#franc and Franc#times pass nil currency (RB) (C9 - Times We're Livin' In)

  40. Franc#times calls Money#franc which passes :CHF(GB) (C9 - The Times We're Livin' In)

  41. Money#dollar passes :USD (GB) (C9 - The Times We're Livin' In)

  42. Pushed up Dollar#new and Franc#new to Money (GB) (C9 - The Times We're Livin' In)

  43. Inlined factory in Dollar and Franc #times (GB) (C10 - Interesting Times)

  44. Dollar and Franc#times pass @currency to ctor (GB) (C10 - Interesting times)

  45. Dollar and Franc#times return a Money obj (RB) (C10 - Interesting Times)

  46. Backed out #times returning Money (GB) (C10 - Interesting Times)

  47. TestMoney#test_different_class_equality (RB) (C10 - Interesting Times)

  48. Money#== checks currency rather than class (GB) (C10 - Interesting Times) (This change feels more natural in Ruby, where duck typing means that testing class is rarely the best way forward)

  49. Franc#times returns a Money obj (GB) (C10 - Interesting Times)

  50. Dollar#times returns a Money obj (GB) (C10 - Interesting Times)

  51. Pulled up Money#times (GB) (C10 - Interesting Times)

  52. Removed explicit Money#currency (GB) (we already have attr_reader :currency, so this is unnecessary; the fact that I stuck it in there in the beginning means I still have some way to go to think natively in Ruby)

  53. Moved attr_reader :currency to top of money.rb (GB) (just to improve readability, in my opinion)

  54. Money#dollar and #franc return Money obj (GB) (C11 - The Root of All Evil)

  55. Removed Dollar class (GB) (C11 - The Root of All Evil)

  56. Removed Franc class (RB) (C11 - The Root of All Evil)

  57. Removed TestMoney#test_dft_class_inequality (GB) (and TestFranc#test_equality, which is equivalent to removing the third and forth assertions in testEquality() from TDDbE p.52) (C11 - The Root of All Evil)

  58. Removed TestFranc#test_multiplication (GB) (and test_Franc.rb, since there are no tests left in the file) (C11 - The Root of All Evil)

  59. Moved tests in test_Dollar.rb to test_Money.rb (GB) (tests are easier to keep track of all in one file, and since we don't have a Dollar subclass any more, the test naming convention is broken anyway)

  60. Added TestMoney#test_simple_addition (ERR) (C12 - Addition, Finally)

  61. Implemented Money#+ (GB) (C12 - Addition, Finally) (obvious implementation)

  62. TestMoney#t_smpl#add uses Expressions, Banks (ERR) (C12 - Addition, Finally)

  63. Fake implementation of Bank#reduce (GB) (C12 - Addition, Finally) (there should have been a red bar step before this one, but returning nil from Bank#reduce causes a compilation error in Ruby due to the lack of a formal return specification, i.e. def [Money] reduce...)

  64. TestMoney#t_smpl_add should add five + five (GB) (oversight on my part)

  65. TestMoney#test_plus_returns_sum (ERR) (C13 - Make It)

  66. Money#+ returns a Sum obj (GB) (C13 - Make It)

  67. Added TestMoney#test_reduce_sum (RB) (C13 - Make It)

  68. Bank#reduce actually adds (ERR) (C13 - Make It) (this seems like a bug in the TDDbE book to me; as we made the amount field protected in a previous chapter)

  69. Implemented Money#reduce (ERR) (C13 - Make It) (this should be a green bar, according to TDDbE, but the protected Money#amount accessor is called again)

  70. Made Money#amount public to stop errors (GB) (we want to be able to follow TDDbE closely, despite the seeming bug--I should do this exercise in Java as well to see if there really is a bug)

  71. Bank#reduce special case for Money (GB) (C13 - Make It)

  72. Implemented Money#reduce (GB) (C13 - Make It)

  73. Removed "cast" and class check from Bank#reduce(GB) (C13 - Make It)

  74. TestMoney#test_reduce_money_different_currency (RB) (C14 - Change)

  75. Hard-coded CHF -> USD in Money#reduce (GB) (C14 - Change)

  76. Added bank parameter to all #reduce methods (GB) (C14 - Change)

  77. Moved rate calculation to Bank#rate (GB) (C14 - Change)

  78. Bank stores rates in hashtable (ERR) (C14 - Change) (because Ruby can use an array--or any other object, for that matter--as a hash key, we don't need the Pair class from TDDbEx; we can simply use a two-element array ([from_currency, to_currency]) as our rate hash key)

  79. Bank#rate returns 1 when from and to are equal (GB) (C14 - Change)

  80. Added TestMoney#test_mixed_addition (RB) (C15 - Mixed Currencies) (this would throw "a host of compile errors" in Java, according to TDDbE, but duck typing means we compile just fine and simply fail a test)

  81. Sum#reduce reduces both arguments (GB) (C15 - Mixed Currencies)

  82. Stubbed out Sum#+ (GB) (C15 - Mixed Currencies) (we just did this to stay in sync with TDDbE--Java's type system required the stub, but Ruby's duck types care not)

  83. Added TestMoney#test_sum_plus_money (ERR) (C16 - Abstration, Finally)

  84. Real implementation of Sum#+ (GB) (C16 - Abstration, Finally)

  85. Added TestMoney#test_sum_times (ERR) (C16 - Abstration, Finally)

  86. Implemented Sum#times (GB) (C16 - Abstration, Finally)

  87. Redefined Money and Sum#times as #* (GB) (this seems more Ruby-native to me)

  88. TestMoney#test_plus_same_currency_returns_money(RB) (C16 - Abstraction, Finally)

  89. Removed TestMoney#t_plus_same_curr_ret_mny (GB) (C16 - Abstraction, Finally) (we removed this test because a clean way to have Money#+ return a Money object instead of a Sum was not obvious)

Saturday, May 30, 2009

Essays in Idleness 01: Singularities and Data Storage

I posit the following theorem: that cosmic phenomena that have one or more attributes that are infinite (or approaching infinity quickly enough to be considered effectively infinite) resist direct observation.

An example of just such a phenomenom is a black hole, where the density of matter--and, as a result the strength of the gravitational field--at its core is infinite or effectively infinite, causing a singularity (i.e. a point where the rules of physics pertaining to space/time do not hold [1]).

Let's assume for a moment that I could directly observe the core of a black hole, the singularity itself. Since the density of matter is infinite, I am effectively observing an infinite amount of matter. So far, so good. I can simply jot down on my notepad that the quantity of matter is ∞ and move on.

Now what if I want to make observations about one or more characteristics of the matter? Say, I want to write down a simple binary value (i.e. true or false) that represents whether each particle of matter is a boson, which I determine by noting whether it has integer spin (as opposed to a fermion, which has half-integer spin [2]). Now I have a problem, because my notepad will have to be infinitely large, in order to contain one bit of information about each particle of matter in the singularity.

Ah-ha, you may now be saying, but the universe is infinite, so your notepad can be as well. Which leads us to the difficult realisation that the universe is likely *not* infinite at all, but rather finite and expanding or contracting somewhere between 0 and twice the speed of light. Of course, proving whether the universe is infinite is well outside the scope of this essay (though there are pointers to information on this topic, should the intrepid reader wish [3]). So let us take the easy way out and pretend that we know for sure that the universe is finite (see footnote A if you'd rather not take the easy way out), and there we have a proof of my theorem: you cannot store an infinite amount of data anywhere in the finite universe, so direct observation of a singularity is theoretically impossible.

This may rankle some readers, who would tell me that they can observe something, say a bird singing in a tree, without storing any data about the experience. I, of course, would claim that they are wrong: any observation results in data storage somewhere, be it on your retina, various places in your brain, and quite possibly on Twitter's or Blogger's servers as you share your experience with others after the fact.

In the case of the bird singing, there is a staggeringly large but potentially finite amount of data available. The way that you deal with this as a human observer is to capture the experience at a relatively low resolution: you consider only the notes the bird is singing, the colours of its plumage, the tree it is sitting in, the local weather conditions, how it makes you feel, etc. In the case of observing a singularity, you have no such luxury, since you can lower the resolution to one single data point and still have to record that one bit of data for an infinite amount of matter.

The way this problem is dealt with in real life is to observe not the singularity itself, but the effects of the singularity on the portion of its surroundings that lie outside of its event horizon. From this, and using the abstract tools of mathematics, we can determine much about the makeup of the singularity.

In our theoretical discussion, there may be another solution: create a second singularity to record the data garnered from directly observing the first. If you find a way to do that, do post it in the comments.




Footnotes

A: What if the universe is infinite? You could potentially store your data, though you'd have to be careful about not writing it over stars, planets, etc. This would lead to storage fragmentation, which would be most difficult to cope with, given the limitations imposed by the speed of light. Your best bet is to stream your data by flicking a light on and off, with every tick (defined as say, a number of milliseconds equal to the atomic weight of hydrogen or some other well-known finite number--using π here would be a very bad idea) representing one particle of matter.

Wednesday, March 11, 2009

How Long Must We Sing This Song?

From the New York Times:
CRAIGAVON, Northern Ireland — Barely three days after two British soldiers were shot to death by a dissident faction of the Irish Republican Army, another I.R.A. breakaway group claimed responsibility on Tuesday for an ambush that killed a police officer on Monday night in this town 25 miles southwest of Belfast.


That's the bad news. The good news (or at least, better news), is this (from the same article):
Politicians on both sides of the divide between the Protestant and Roman Catholic communities in the province denounced the killing as the work of “terrorists” [...]

The reaction in Craigavon [...] suggested that for now, [concerns that the peace might be destroyed] might be overblown. The town, in the county of Armagh, a major sectarian battlefield in the past, has a mixed population of Catholics and Protestants, but people approached at random at the site of the shooting and in shopping malls seemed confident that the peace would survive the shootings.

A 25-year-old Catholic man who gave his name only as William said that he supported Sinn Fein, the main nationalist party in the power-sharing government, and that he “feared something like this was going to happen” when I.R.A. sentiment split over the peace agreement. “There is still a small minority out there who agree with shootings and all that,” he said. “I don’t agree with it myself. There was a time when I may have agreed with it. But it is the wrong time. Violence is in the past.”


It looks like most Northern Irish people have put the Troubles behind them, and that the latest violence is nothing but disaffected youths doing what disaffected youths do. This is now a social issue, I think, and not a Republican one. Give people hope for their future, and they are much less likely to turn to terrorism (see "Three Cups of Tea: One Man's Mission to Promote Peace... One School at a Time", by Greg Mortenson).

Wednesday, April 09, 2008

Thou shalt grok Unicode!

Working programmers simply must grok Unicode!

I thereby propose the following course of study:

  1. Read "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)", by Joel Spolsky

  2. Read "There Ain't No Such Thing as Plain Text", by Jeff Atwood

  3. Read "On the Goodness of Unicode", by Tim Bray

  4. Read the aforementioned Wikipedia article on Unicode

  5. Perl programmers, read: "Unicode-processing issues in Perl and how to cope with it", by Ivan Kurmanov

  6. Write a UTF-8 version of "Hello, World!" in each programming language that you ordinarily use. (See below.)


Speaking of which, wanna know how to say "Hello, world!" in a wide variety of natural languages? Here's the list, with the language names omitted. See how many you can identify, and brag in the comments how awesome you are!

  • Hello, World!

  • 世界、こんにちは!

  • مرحبا ، العالم!

  • 你好,世界!

  • Bonjour, le monde!

  • Hallo, welt!

  • Ciao, mondo!

  • 안녕하세요, 세계!

  • Olá, mundo!

  • Здравствуй, мир!

  • Здравей, свят!

  • Hola, mundo!

  • Halló, Heimur!

Sunday, September 30, 2007

Dusk, Dawn, and 30-Day Challenges

Note: This post is old old old, and is being published now just for the sake of self-ridicule; none of my 30 day challenges were met, and only one was even begun.

Frequent readers of this blog will need no introduction to my good friend and erstwhile roommate, Ota. Frequent readers of this blog will also know that I subscribe to the Neal Stephenson never-say-in-100-words-what-you-can-say-in-1000 school of writing, so said (illusory?) frequent readers will not be surprised that I shall now proceed to tender an introduction to the illustrious Ota anyway.

I met Ota on the very first day of classes back at The College of William and Mary in 1997. We had both signed up for Japanese 101, and the first day entailed learning the fine art of 自己紹介 (jikoshoukai, self-introduction). Both of us claimed to be from Virginia, and Computer Science majors. As computer geeks are wont to do, we sized each other up warily, then met after class to compare programming credentials. I had more "serious" experience, having written a couple of trivial programs as a consultant (but in Visual Basic--a toy language). He was more into game programming, and showed up to class the next day with a floppy in hand (in 1997, the idea of transferring files over a network was iffy at best, except to Unix geeks, which I would not become for another year or two). I went home, popped the floppy in, and copied the binary over to my hard drive. Executing it (I seem to remember it being a compiled QuickBasic binary, but I suppose it could have been written in Visual C++; maybe Ota remembers) revealed a tasty riff on Pong; multicoloured balls flew about, and you had to smack them this way and that without letting them go in your goal (at least, if I recall correctly, which I may not; 10 years still seems a long time ago to me).

So Ota, having proven himself as a cool game programmer, rapidly became one of my friends. We worked together on the various group projects demanded in Japanese class, and started meeting occasionally for lunch or breakfast at the Caf (our dining hall). Toward the end of freshmen year, when it came time to decide on housing for the next year, we agreed to room together, in the Japanese House, which was a dorm for students of Japanese and Japanese exchange students.

Three years after graduation (well, just two for me; I took five years and thus graduated in 2003), we found ourselves both living in the Tokyo area, and started hanging out more frequently than once every three years. :)

A year later, I was working in Shibuya and he in Naka-Meguro, so we started meeting for lunch once a week, a habit that we have more or less maintained until the present.

Ota has had a blog for even longer than I have, and he's written in it even more infrequently than I have. ;) This is until about a month ago, when he started blogging at Dusk and Dawn a cool little bi- (tri-?) lingual blog he and his girlfriend do. I subscribed to the feed a couple of weeks ago, but did not have time to actually read any of the blog until today.

I have to say, it is neat. The layout is nice, the photos adorning the header are gorgeous, and the writing is interesting. I was especially inspired by his post entitled "The 30-day challenge; a year of self-improvement". I like the idea of trying to bootstrap a good habit by just committing to it for a month, and seeing what happens.

Ota and I had all sorts of contests back in school, some of them involving self-improvement and some... well, not. So I think this is a great opportunity for me to announce my own 30-day challenge goals, and see if Ota and I can keep each other honest and inspired. :)

  • October 2007 - (same as Ota's, but a lesser time) run, every day, for at least 15 minutes (Ota is doing 30, but I don't have that kind of time, man!). My motivation here is two-fold: to become more fit overall, and to increase my endurance so I can become a more effective striker on the futsal pitch.

  • November 2007 - no swearing. I have a, let's say, colourful vocabulary, which is not always the most appropriate to every situation. 'specially situations in which my baby boy is also a participant. I'll go the entire month without uttering a swear word (should there be an accidental slip, I'll pay for it with a household chore, above and beyond my normal share).

  • December 2007 - TBD

  • January 2008 - TBD

  • February 2008 - (same as Ota's) write a blog post a day. I enjoy writing, and need to do it a lot to keep my prose honed.

  • March 2008 - TBD

  • April 2008 - TBD

  • May 2008 - (same as Ota's, but with a twist) read a book a week... about software engineering or the management thereof. Reading a book a week would be a slam-dunk goal for me, since I average that already. But I have quite a backlog of work-related reading to do, and I am always wanting to pick up tips here and there to improve my craft.

  • June 2008 - TBD

  • July 2008 - TBD

  • August 2008 - TBD

  • September 2008 - TBD

Monday, September 17, 2007

iHave become iNfected

Note: this post is old old old, and finally published just for historical curiosity, mostly my own.

Yes, it is strange but true; this Linux jockey has succumbed to the world's most powerful marketing machine and is typing this blentey on the sweet sweet virtual QWERTY keyboard of an iPhone. Worse yet (because the iPhone is not mine--'tis a company plaything), I must confess to buying my wife a MacBook for last Christmas. Disgraceful, I know.

I originally bought the MacBook for the hardware; I was planning to just peek at Mac OS X, then partition most of the drive out for Linux, using a filesystem that both Linux and OS X could use. But tragically, I waited too long, and when I finally got around to trying Boot Camp, it failed to repartion my drive. A real hacker would have booted up a Gentoo LiveCD and fired up GNU parted, but I feared the potential time sink and the wrath of my wife--who had become quite enamoured of OS X--if things did not go according to plan. So I ended up sticking with the Mac OS, but mainly using my old Linux 'top, as I could not live with giving up my Openbox keybindings and virtual workspace config.

So what, you may be wondering, do I think of the iPhone? Well, given that I am typing this on one, feel free to assume that I *love* it. This weekend, I've used it for checking my Gmail (which works, but shame on Google for not detecting the iPhone User Agent and doing something optimised for the iPhone's screen size, like we do), reading through my WWdN:iX backlog (reading blogs may well be one of the iPhone's--and, by extension, the iPod Touch) killer apps; a native RSS/Atom reader might be a good idea), and written this blog entry.

So the iPhone works as advertised, and will work even better once some of the bigger sites out there get their act together and offer an optimised experience.

Sunday, August 05, 2007

チルドビール3本&グラスセット

...or how the Japanese have misplaced their damned language and replaced it with English.

Chilled Beer and Glass Set
All my Japan-bound readers who are fans of beer should beat a path to your local 7-11 and pick up the titular 「チルドビール3本&グラスセット」, or "Chilled Beer 3 count and Glass Set", from Kirin.

Aside from being a indicator of a sad (to me, lover of Japanese lanugage) linguistic phenomenon, it is a good value at ¥749 for a bottle each of Kirin Ichiban (KIRIN 一番搾り), Kirin Grand Ale (グランドエール), and Kirin Maroyaka Kobo (まろやか酵母)--each of which retail separately for ¥250--and a decent if faux-haute couture beer glass (I assign the faux prefix due to the fact that the glass is basically an attempt to dress up what RateBeer.com has assured me is called a "footed Pilsner"--or were they going for the "tulip"?--which is completely unnecessary for any of the beers it ships with; RateBeer.com calls for an English pint or Shaker for the Grand, and suggests that either would be appropriate for the Ichiban and the Maroyaka, plus a Dimpled mug, Lager glass, or Stein.

So you save ¥1 outright (what a deal!) and get a free glass that, while it is not as fancy as it pretends to be, can be used to drink beer from. :) That is OK by me!

What is less OK by me is the fact that there exists a perfectly fine Japanese word for all but one word in the title (「ビール」, though I would entertain the argument that there is not a great word for 「グラス」--「水飲み」 is perfectly reasonable, but is not much in common usage anymore, and 「猪口」 is not quite the same thing), yet Kirin has chosen to use katakana loan words instead. This is actually worse than 和製英語 (wasei eigo--"Made in Japan" English); at least the latter is Japanese in origin.

Japanese companies, try using the Japanese language for naming your products. I would not want to see them go as far as the French, who have erected the ediface of the Académie française in a foolish and ultimately doomed attempt to halt linguistic evolution, but I would like Japanese people to have some pride in their language.

Groove to my Flickr set to view more gratuitous pictures of beer.

Thursday, August 02, 2007

SoftwareCompanies.getByName("Fog Creek").getProductByName("Copilot").getUsers().getSatisfiedUsers().increment;

Fog Creek CopilotI have been reading "Joel on Software" for years, but I have not until this week used a Fog Creek product.

Until my sister's laptop crashed right as we were trying to set up a Skype video chat. :(

My wife and I live in Tokyo, and have a three month old baby boy who has not met my parents, my sister, or her nine-month old baby girl, since all of those relatives live in Virginia. So Skype video chats (which are few and far between, unfortunately) are basically the only way we have to connect.

I am a Linux user, and my wife uses a shiny new Mac Book. But I seemed to remember Joel mentioning that Copilot supported Mac OS X, so I grabbed the Mac, browsed on over to joelonsoftware.com, found copilot.com after a few missed clicks (usability tip: stick the product links *above* the support links, as I would assume the crushing majority of "Joel on Software" readers are not--yet!--Fog Creek customers, so most people want to buy or try before they need support).

I clicked on the "Help Someone" tab (beautiful, functional layout, BTW!), snagged a free trial, and read my sis the code over the phone (well, SkypeOut from my wife's Mac to her phone). After a pause of 20 seconds for the 980K app bundle to download, mount (on my end), and execute, we were connected, and I saw that I had 90 seconds to work! :)

I have not used Windows since 1999 or so, so Windows XP is a little unfamiliar to me, but I blasted over to the Control Panel, then "User Accounts". Created a new user, turned on the "Welcome Screen" so my sister would not be auto-logged into her borked account, and restarted the computer. With 30 seconds left in my free trial. From over 10,865 kilometres away! On a Mac! Without knowing Windows from a hole in the ground, really!

Now *that* is software that Just Works.

And then I look into the purchase options, and see that I can buy a Day Pass, for $5.00 US, that gives me unlimited usage for one day. And I can pay with PayPal! Needless to say (so why am I saying it?), I grabbed one right then and there for the next time somebody in my family needs my help.

And I hate giving free tech support, usually. But Copilot makes it so easy to help on my terms: when I want to, from the comfort of my own home, with "Joel on Software" and other fine blogs loaded up in Firefox, sipping a fine beer.

Thanks, Fog Creek! Now I feel a burning need to purchase the Project Aardvark DVD! :)

Sunday, July 22, 2007

OpenSolaris Journal II: BeleniX hdinstaller

Continuing to play with BeleniX, I used the hdinstaller tool to install it for reals so I could boot OpenSolaris from my hard drive.

The install itself came off without a hitch. I:
  1. Booted off the LiveCD
  2. Ran hdinstaller
  3. Selected my hard drive
  4. Deleted all my partitions
  5. Created one Solaris partition
  6. Chose auto-layout with swap, /usr, and /opt as slices
  7. Installed GRUB to the MBR
  8. Set the root password

After the install finished, I booted up off the hard drive, logged in as root, created a user account, logged in as that user, and ran startgui kde to start X:
bad interpreter: Permission denied
To read the rest of my tale of woe, click through my " Open Solaris Journal - BelleniX hdinstaller" Flickr set.

Wednesday, July 18, 2007

OpenSolaris Journal I: BeleniX LiveCD

I booted a Dell Latitude D620 up with an OpenSolaris Starter Kit that I picked up from Saturday's TLUG meeting for Erin (yeah, I know; I'm a short-stopping bastard). Selected the BeleniX 32 bit LiveCD, and after selecting a keyboard layout (jp106, which was not honoured by KDE) and saying OK to the autodetected screen resolution / colour depth / etc., I found myself in KDE 3.5, and snapped a screenshot with import -window root belenix.png (import is from the ImageMagick).

BeleniX LiveCD, KDE desktop
Let me just say that the fact that the LiveCD Just Worked was very impressive to me, given the fact that Solaris is known for supporting less end user hardware than Linux (whether this is fair to Solaris is a topic that I will be exploring in future OpenSolaris journal entries).

Having said that, I quickly ran into problems (stop reading here unless you want to see my criticisms).

I just wanted to send my screenshot over to another box so that I could upload it to Flickr and stick it in this blog entry (I like "blentry", are you guys cool with that?). So, I plugged in the network and ran /etc/init.d/dhcp start, which returned success right away. So I then ran ifconfig -a to see what IP address I got.

No network?
To my surprise, I saw that I had only lo0, which is the loopback interface for localhost (127.0.0.1 sweet 127.0.0.1). "That won't play!" quoth I, and double-clicked on the "BeleniX Info" icon on the desktop. To my delight, it was a guide / FAQ (this doc, I think). I searched for "net", but all of the hits assumed that the NIC was detected and claimed by a driver, which mine was clearly not.

So I Googled more, then tried some stuff which you can see in my Flickr set, before being defeated by my bad memory (I could not recall how to load Solaris kernel modules; or more precisely, where to find which kernel modules one can load with modload or whatever it is).

So, having spent 10 minutes trying to get the network working, I turned my attention to USB mass storage, for I have a AU WIN W41H (Flash, sorry) phone that acts like a USB hard drive. First, I just plugged it in in hopes that vold and KDE would cooperate and give me a little icon on the desktop to which to drag my screenshot image. No such luck. So I tried mounting manually, but could not figure out which entry in the /dev filesystem was appropriate. So I Googled more:
This stuff "worked", but then I tried to mount the correct device and the mount command just hung for 60+ seconds until I unplugged the USB cable.

So all of my screenshots were taken the old-fashioned way, with my keitai's camera. :)

The bottom line is that I spent 20 minutes trying unsuccessfully to get my screenshots off the BeleniX box, and I consider myself well above average competency when it comes to Unix. But this is really a documentation problem, and one that I'll be happy to help solve once I get my Solaris admin legs back. :)

Good work, OpenSolaris and BeleniX crews! The product looks nice and Just Works; at least 95% of the way.

Tuesday, July 17, 2007

Earthquake and Fire II

We're fine, people in Niigata are less so.

Earthquake Information Issued at 10:19 JST 16 Jul 2007

There were a series of earthquakes starting at 10:13 JST yesterday (2007/07/16). The epicentre was in Niigata Prefecture (新潟県), where the larger quakes reached 6-upper on the Japan Meteorological Agency seismic intensity scale (if that sounds just like the Wikipedia article, don't worry, I am only plagiarising myself).

Earthquake Information Issued at 10:19 JST 16 Jul 2007 (Kanto)

Down here in Tokyo, it was only a shindo 3, so our experience was summed up by the JMA as follows:
Felt by most people in the building. Some people are frightened. Dishes in a cupboard rattle occasionally. Electric wires swing slightly.

As I said, people in Niigata were not exactly OK; 7 dead / 790 injured, according to the Daily Yomiyuri. Also, there was a fire at a nuclear power plant; from the same article:
The Nos. 2, 3, 4 and 7 reactors at the Kashiwazaki-Kariwa nuclear power station in the prefecture automatically shut down after the earthquake, according to Tokyo Electric Power Co. A small fire broke out in an electricity transformer of the No. 3 reactor, but no damage was reported to the reactor. The fire was extinguished at about noon.

Google News info: http://news.google.com/news?as_q=niigata+earthquake&svnum=10&as_scoring=r&ie=UTF-8&oe=UTF-8&tab=wn&resnum=0&ct=property-revision&cd=1&btnG=Google+Search&as_epq=&as_oq=&as_eq=&as_qdr=&as_drrb=b&as_mind=15&as_minm=6&as_maxd=17&as_maxm=7&as_nsrc=&as_nloc=&as_occt=any

Niigata quake damage

Sunday, July 15, 2007

News Hounds: We watch FOX so you don't have to

Note: this post was originally made to Politics Schmolitics, another blog to which I contribute.

Pretty cool news aggregator blog: http://www.newshounds.us/. They also have a nice YouTube videos page.

I found it through YouTube while watching the two Wolf Blitzer interviews with Michael Moore:





Oh shit, there's more:


Sanjay Gupta says a lot of good stuff here, but the thing I like the most is his point about how we need to spend more on preventative care so we will not have to spend so much on care after people get sick, which is harder and thus, more expensive.

On to Larry King Live (which I just misspelled as "Larry Kink Live", much to my amusement):







Gupta points out that "free health care" is not "free", says France is "drowning in taxes" and running a 15 billion dollar deficit. From a US Department of the Treasury press release, entitled "U.S. Fiscal Outlook Improves Significantly in December Fiscal Year to Date Deficit Down; Monthly Surplus Up More than 300 Percent":
The Fiscal Year to Date deficit ($80 billion) is down 33 percent ($39 billion) compared to the same period last year. The President's tax relief has stimulated strong economic growth. This strong growth has contributed to record-level receipts and the creation of more than 7.2 million jobs since August 2003. October to December receipts for FY 07 are at $574 billion, running 8 percent ($43 billion) higher compared to the same period for FY 06.

So even though we are not "drowning in taxes", we are running an 80 billion dollar deficit (five times that of France, which is pretty much the same per capita; France's population of 63,713,926[1] is 21.16% of our own population of 301,139,947[2]), and that is a "significant improvement". Hrm... what would be one way to pay for universal healthcare without raising taxes to the "drowning" point? Maybe reducing the 4.06%[3] of GDP we spend on the military (and that was in 2005, estimated, let's see what the GAO thinks about this year... this just in: the GAO's search functionality fucking sucks! To wit: my search for keywords "military spending" for this year returns a bunch of hits, all of which are to PDFs with almost worthless abstracts. Let's see if Google can do better: my search for keyword "military spending" on site:gao.gov turns up this (Warning: PDF; click here for Google's HTML version) as the ninth result. Ugh. In the 21st century, transparency means findability, and while PDFs are great for reading and printing, they are not ideal for searching, quoting, and sourcing. Note to the GAO: please provide HTML versions of all of your documents!)...

Where was I? Oh yes, military spending. The CIA World Factbook says that we spent 4.06%[3] of GDP--or 536.33 billion dollars (based on a GDP (official exchange rate) of $13.21 trillion[6]), or $1786.40 per person per year (based on a GDP - per capita (PPP) of $44,000[6]). The 2007 military budget (Warning: PDF; click here for Google's HTML version) says $439.3 billion, but that is just what is budgeted, not what is being spent. I had hoped that the GAO would give me a good number on what is being spent, but I could not find it in finite time. :(

Anyway, even if we take the DoD's numbers at face value, that would still be 3.3%[6] of GDP, or $1463.22 per capita. I don't know about you, but that is a sizeable chunk of my total tax bill. Assuming the mean US tax rate of 17.5%[7] and the mean household income of $58,208[8] (as of the 2001 census), the average household pays $10,186.40 in taxes per annum. Assuming the average household contains 2.0 people (I could only find census data for Hispanic households, which was 2.58[9], so I'm fudging the number, but in a way that actually weakens my case), that is $5093.20 per capita, making our military spending an astounding 35% of each person in America's tax dollars!

As an aside, if you want to read something amusing, try the rosy picture painted by the CIA World Factbook of the US economy on for size.

And now, the exciting conclusion of the Michael Moore vs. Sanjay Gupta fight, refereed by the disgusting hack excellent journalist, Harry Thing Larry King.



[1] SOURCE: CIA World Factbook
[2] SOURCE: CIA World Factbook
[3] SOURCE: CIA World Factbook
[4] DIRECT SOURCE: Wikipedia
[5] INDIRECT SOURCE: FY 2007 Department of Defense Budget, page 19. I verified that Wikipedia was, as of 2007/07/15 01:20 GMT, correctly representing this data
[6] SOURCE: CIA World Factbook
[7] SOURCE: WWW.WORLDWIDE-TAX.COM (please do not view me using this source as claiming it is reputable; I used it only because I could not find hard numbers from the US government--I tried both the IRS and the CIA World Factbook--and it came up quickly in a Google search)
[8] SOURCE: U.S. Census Bureau
[9] SOURCE: U.S. Census Bureau (not a very good source, but the best I could find; see the above points about the relationship between transparency and findability)

Wednesday, July 11, 2007

A Blunt Instrument

This is a shite post, but I am way too busy with Life, Work, and Fatherhood.

My love for Penny Arcade has been chronicled here before, of that I feel certain, though I am too lazy and/or short of time to poke and prod at the daemons that lurk in the dusty corners of my archives, for to force them to relinquish said juicy tidbit of blog wherein I proclaim Yea! Unto the very Floor of Hea'vn! dost my love for the Arcade of the Penny soar!

Tycho BraheLeaving aside the excellent art and the irreverent humour, the thing that really keeps me coming back like a literary junkie is the excellent writing of Monsignor Tycho Brahe, pictured at left.

To wit, this is one of the most amazing bits of prose I have encountered in recent history:
I have faith that, in a fundamentally just universe, things will be set right. And, in those cases where the universe is slow to act, let my rage be the instrument.

Thursday, June 28, 2007

Apparently I am an American Idiot

...for being so late to the party on this one!

Green Day - American IdiotI am speaking, of course, of Green Day's 2005 effort, "American Idiot", which I do not hesitate to call the best rock concept album of this century. Holy shit! This is the leftist answer to the likes of American idiots like Toby Keith (yeah, as if angry jingoistic bullshit will help "win" the "War" on "Terror").





One of my personal favourite lines from the album is this one:
Well maybe I'm the faggot America.
I'm not a part of a redneck agenda.
Now everybody do the propaganda.
And sing along to the age of paranoia.


Now, let the debate begin on whether this is a punk rock album. I hold that punk more an attitude than a musical style, and Green Day's (correctly) anti-(fucking idiotic) establishment stance is very much in keeping with punk rock stalwarts such as The Clash ("Know Your Rights", anyone?). Three cords and yelling do not punk rock make, kids.

SFB, care to comment?

Sunday, June 24, 2007

Mitsuya's Liquor

Or Sam's Town Strikes Back.

It has been quite busy recently, so I've not had a chance to blog much, but we took a walk over to Daiso and Mitsuya's today, so I figured I'd dust off this entry and add a few photos to my directions.


Sam dusts off a bottle of Segura Viudas Brut Reserva NV for me.

I went into Sam's tonight to restock my beer fridge with a bottle each of Балтика 3 Классическое and Heather Ales Kelpie Seaweed Ale, and decided while I was there to grab a bottle of the bubbly to celebrate the end of a truly hellish work week. Sam recommended the Segura Viudas Brut Reserva NV, a real value at ¥1,450, and I was not disappointed. I am not a big champagne fan, but this was a very nice, dry one that even I could appreciate.

So if you too want to experience the magic that is Mitsuya's Liquor, clicky clicky for the map.

Directions:

  • From Tokyo Metro Minami-Asagaya Station (南阿佐ケ谷):
      Minami-Asagaya Station, exit 2b
    1. Assuming you are coming from Shinjuku, get off the train and take the transfer passage under the tracks--it is in the middle of the platform--to the other side (if you are coming from Ogikubo simply stay on the same platform), then go out the turnstiles and up the stairs.
    2. Alley leading into the shopping arcade
    3. The left fork of the stairs (exit 2b) will dump you out in front of the Suginami-ku-yakusho (杉並区役所--ward office).
    4. Turn right and walk in front of the kuyakusho, taking the first right, which is a little path between the kuyakusho and Asagaya Middle School (阿佐ケ谷中文).
    5. The path will take you out behind the fenced-in playground of the school and to a small alley.
    6. Mituya's from the Minami-Asagaya Station side
    7. Turn left to follow the fence, then right with the alley when it turns (approximately 30 metres).
    8. The alley will dead-end into a shopping arcade; turn left, take five steps or so and Mitsuya's will be on the right-hand side of the arcade (you'll recognise it by the beer and wine bottles in boxes out front).

  • From JR Asagaya Station (阿佐ケ谷):
      Asagaya Station, North Exit
    1. Take the North Exit, then turn left and walk to the corner of the main street (there is a McDonald's across the street more or less in front of you).
    2. Cross the street, then the entrance to the shopping arcade will be horizontally to your right (at two o'clock on the dial of a watch, or at an angle of roughly 50 degrees--one radian?).
    3. Pass a Book-Off on the left
    4. Head into the arcade, and follow it for roughly 600 metres (you will pass a Laox on the right, then a Book-Off on the left, then a Peacock on the left).
    5. After you pass the Peacock, you will pass two alleys on the left, and Mitsuya will be on your left hand side, on the corner of the second alley.
    6. Pass a Peacock on the left
    7. Again, look for boxes of beer and wine out front.








Mitsuya's from the Asagaya Station side