Two Guys Arguing

NaNoBloMo Recap

Posted in Uncategorized by youngnh on 11.29.10

Sum up the last month of blogging in 120 characters or less (gotta leave space for a URL on the end):

Clojure solves programs naturally, elegantly and — holy crap! it’s 10 o’clock at night and none of my ideas panned out.

Best skill you developed by writing 15 blog posts in 30 days:

Formulating ideas and writing them down helps me break them down. I always felt like I had the quintessential software skill of “breaking the problem down”, but this excercise really taught me that is a separate skill from making my problems smaller. To belabor the point, one approach leaves you with a lot of problems that you have to solve, and the other is the excercise of ignoring a lot of solutions. I have written posts on ideas I thought were small and elegant, but they scrolled in at 5 or 6 screens of text. I tried not to do that this month, and in the process, felt like I got better at extracting smaller problems from large ones.

Favorite post of the last 30 days:

I really enjoyed writing the HP-15C program. The manual was something that took me some searching to find, so it was with great pleasure that I uploaded it to our site for others to find, and it was a fun challenge to write a program in 400-something bytes when every digit is an instruction.

Would you do this again next year?

I would commit to a less-demanding writing schedule. Considering that last year I stone-cold quit NaNoBloMo after maybe 2 posts, I’m really happy that I stuck it out until the end this year. I’m not terribly interested in being a pundit and even though I’ve got a lot of opinions, what I wanted to do with this month was write about writing software. There are new killer Clojure libraries emerging daily. It’s satisfying to use what someone else wrote to solve a problem. It’s personally instructive to try and fathom their design decisions. It’s enduringly useful to others to have concrete examples of good software available.

Having to post something every 2 days is too strict. The amount of time required to produce a post every 2 days was exactly right, the problem came when I failed to get anything working in the 3-4 hours a night I spent fiddling with stuff. Starting out I had a grand idea planned and outlined how every two days I’d move on to a new topic and use some new Clojure library to address that day’s topic, but I ran into issues after the first post and never got back on track. I think a post every 4 days would be a good amount. Enough time to queue up posts if things go swimmingly, and enough to recover and take a new tack if they don’t.

Which posts did you half-ass?

I started early, my fifth post, Start Tomcat from the REPL was an old text file I had lying around in case I ever had to actually do that again. I cleaned it up for an easy post. My Oracle post was the same way, the only difference is the old text file the Oracle post came from represented weeks of effort and failure and forum posts and hair pulling and lots of swearing. I’ve got a lot more old text files on installing Oracle for semantic technologies. I’m glad I didn’t use them.

Chasing the Sun, was one of my favorite posts since it led to a lot of interesting study for me and pointed towards a solution to a long-standing challenge of Ben’s. It was a half-assed post that I started writing maybe an hour before publishing. I had spent all day working on something else that didn’t turn out. That post contained no code, no real grasp of the astronomical concepts, just me plugging numbers into online calculators.

Copyright 1988 is as half-assed as it comes. I click-clacked that one out after getting home from work on a Friday, minutes before rushing out the door to catch the latest Harry Potter film with friends.

I didn’t half-ass the Konquest post, I just couldn’t get to an elegant, complete solution so I think it came off as half-finished.

Any last words before spending the coming months trying to forget that you ever did this?

I’ll have it known that my co-blogger Ben (if he doesn’t stumble at the finishing line) beat me handily at getting his posts in on time and deserves the TwoGuys NaNoBloMo trophy.

Submitting too close to midnight bit me twice and those posts appeared a day later than they were due. I submitted a post 7 minutes before midnight on November 9th, but unbeknownst to me our blog (at least my profile) was set to Eastern time, so it was published with a November 10th timestamp. I immediately rectified the timezone problem, but 3 minutes before midnight on the Saturday after Thanksgiving it totally slipped my mind that I was in Portland, Oregon. So that post showed up on an even numbered day as well.

Probability of Konquest

Posted in Uncategorized by youngnh on 11.28.10

I really like the KDE game, Konquest. It reminds me of another game I like, KDice. KDice has a handy table reference to tell what the odds of an attack succeeding are. Calculating the odds of winning a confrontation in Konquest is, undeniably, more complex.

First, a little about the calculation of a winner in Konquest. There are two sides to every confrontation, an attacker and a defender. Each has a number of ships, and each has a “Kill Percentage”, a measure of the probability that they will destroy an enemy ship. The game conducts the battle by having each side “roll” in turn to determine if an opposing ship is destroyed. First the defender rolls to see whether they destroyed a ship or not, then the attacker. When one side is destroyed, the remaining side is the victor.

It’s pretty easy to determine the probability of successfully attacking an undefended planet. Likewise, there’s no battle if no fleet attacks. So we’ll start with a 1 v 1 battle where both sides have a 50% kill percentage. The ways in which the battle could be resolved are:

d kill, a doesn’t roll = d wins 0.5000000
d miss, a kills = a wins 0.2500000
d miss, a miss, d kill = d wins 0.1250000
d miss, a miss, d miss, a kill = a wins 0.0625000
d miss x N, a miss x N, d kill = d wins (1-dkp)^N * (1-akp)^N * dkp
d miss x N+1, a miss x N, a kill = a wins (1-dkp)^N+1 * (1-akp)^N * akp

N doesn’t have to get very large before the probability of those outcomes quickly reaches zero.

Rounding to 4 digits, I found that the odds of a 1v1 matchup going 22 rolls or more is 0%.
Adding together the probabilities of all outcomes, I got 66.6667% chance that the defense would hold against the attacker.

So there’s only a 1 in 3 chance of an attacker winning an otherwise even matchup. First strike is a valuable advantage in Konquest.

If the attacker sends forces with a better kill percentage, say 60% against a defending force of 50%, I calculate the odds of attacker winning at 43.75%.

If the attacker doubles his forces, 2 attackers versus 1 defender, the situation changes a bit. The ways in which the battle could be resolved are:

d kill, a kill = a wins 0.250000
d kill, a miss, d wins the 1v1 = d wins 0.166667
d kill, a miss, a wins 1v1 = a wins 0.083334
d miss, a kill = a wins 0.250000

and for each of the above outcomes, there could be N misses before them:

d miss x N, a miss x N, d kill, a kill = a wins
d miss x N, a miss x N, d kill, a miss, d wins the 1v1 = d wins
d miss x N, a miss x N, d kill, a miss, a wins the 1v1 = a wins
d miss x N, a miss x N, d miss, a kill = a wins

This drops the percentage significantly, but it’s midnight and this post is due, so check back later to see how much.

a small stack

Posted in Uncategorized by youngnh on 11.25.10

This Thanksgiving, I’m thankful for modern computer architectures.

Ben’s post on Piet and dealing with it’s stack prompted me to dig up my old HP-15C calculator, a relic my father handed down to me which also operates on a stack architecture. If you’re interested in all of its capablities, you can download the pdf manual, but in a nutshell, the calculator has a fixed size stack and 67 7-byte registers.

The stack’s size is fixed at 4, each position on the stack is a 7-byte register, called the x, y, z and t registers. Push more than 4 numbers onto it and the first items will fall off the end. t is the bottom of the stack, and x is the top. The number shown in the HP-15C’s display is always the x-register. Extra storage is provided by the 67 addressable registers. The registers are divided into data and program registers. The exact allocation of each is changeable, but by default 20 registers are allocated for data, 46 are registered for program instructions and 1 is special, called the index register. The data registers are accessed and written to using the RCL and STO buttons followed by a register address. Register addresses are the numbers 0-9 or .0-.9 (a decimal key followed by a digit key).

What to Write

As an excercise in programming the HP-15C, I decided to tackle Ben’s sunwalker challenge. I dug into the Explanatory Supplement to the Astronomical Almanac which had equations for roughly calculating the position of the sun relative to the earth for any day within two hundred years of the latest epoch, the year 2000.

The equations will give us the Right Ascension and Declination of the Sun which is the first step towards pinpointing where in the sky an observer from Earth would see it.

To do so, we start with the Julian Date of the day in question, JD.
From that, we’d like to calculate where in it’s ecliptic, the Sun is. This measurement is called λ.


λ = L + 1.915 sin G + 0.020 sin 2 G

Where L is the mean longitude corrected for aberration, and G is the mean anomaly.


L = 280.460 + 36000.770 T
G = 357.528 + 35999.050 T

T is the number of centuries since the epoch. Along with T, there’s only one other number we need to calculate, ε, the obliquity of the ecliptic.


T = JD - 2451545.0 / 36525
ε = 23.4393 - 0.01300 T

Having calculated the Sun’s ecliptic longitude, we can then convert it’s position into a position on the Celestial Sphere relative to the center of the Earth, given as right ascension, α, and declination, δ.


tan α = cos ε sin L / cos L
sin δ = sin ε sin L

Get to the Program Already

In pseudo-code, the program looks like this:

357.528
35999.050
RCL .1
* +
STO .3

This is the calculation of G, and it pushes two numbers onto the stack, retrieves T from the .1 register, multiplies and adds and then stores the result for further calculations to use in the .3 register.

Each digit of the numbers, however corresponds to a single-byte instruction. RCL and STO operations consume 2 bytes. Here’s the whole listing in three columns, the machine instruction, the corresponding keyboard input and the pseudo-code equivalent:


001 - 42,21,11     f LBL A     A:         -- start program labeled A
002 -    45  0     RCL 0       RCL 0      -- fetch JD from register 0
003 -        2     2                      -- calculate T
004 -        4     4
005 -        5     5
006 -        1     1
007 -        5     5
008 -        4     4
009 -        5     5           2451545.0
010 -       30     -           -
011 -        3     3
012 -        6     6
013 -        5     5
014 -        2     2
015 -        5     5           36525
016 -       10     /           /
017 -    44 .1     STO .1      STO .1     -- store T in register .1
018 -        2     2                      -- calculate L
019 -        8     8
020 -        0     0
021 -       48     .
022 -        6     6           280.460
023 -       36     ENTER
024 -        3     3
025 -        6     6
026 -        0     0
027 -        0     0
028 -        0     0
029 -       48     .
030 -        7     7
031 -        7     8           36000.770
032 -    45 .1     RCL .1      RCL .1
033 -       20     *           *
034 -       40     +           +
035 -    44 .2     STO .2      STO .2     -- store L in register .2
036 -        3     3                      -- calculate G
037 -        5     5
038 -        7     7
039 -       48     .
040 -        5     5
041 -        2     2
042 -        8     8           357.528
043 -       36     ENTER
044 -        3     3
045 -        5     5
046 -        9     9
047 -        9     9
048 -        9     9
049 -       48     .
050 -        0     0
051 -        5     5           35999.050
052 -    45 .1     RCL .1      RCL .1
053 -       20     *           *
054 -       40     +           +
055 -    44 .3     STO .3      STO .3     -- store G in register .3
056 -    45 .2     RCL .2      RCL .2     -- calculate λ
057 -        1     1
058 -       48     .
059 -        9     9
060 -        1     1
061 -        5     5           1.915
062 -    45 .3     RCL .3      RCL .3
063 -       23     sin         sin
064 -       20     *           *
065 -       40     +           +
066 -       48     .
067 -        0     0
068 -        2     2           0.020
069 -       36     ENTER
070 -        2     2           2
071 -    45 .3     RCL .3      RCL .3
072 -       20     *           *
073 -       23     sin         sin
074 -       20     *           *
075 -       40     +           +
076 -    44 .4     STO .4      STO .4     -- store λ in register .4
077 -        2     2                      -- calculate ε
078 -        3     3
079 -       48     .
080 -        4     4
081 -        3     3
082 -        9     9
083 -        3     3           23.4393
084 -       36     ENTER
085 -       48     .
086 -        0     0
087 -        1     1
088 -        3     3           0.01300
089 -    45 .1     RCL .1      RCL .1
090 -       20     *           *
091 -       40     +           +
092 -    44 .5     STO .5      STO .5     -- store ε in register .5
093 -       24     cos         cos        -- calcuate α
094 -    45 .4     RCL .4      RCL .4
095 -       23     sin         sin
096 -       20     *           *
097 -    45 .4     RCL .4      RCL .4
098 -       24     cos         cos
099 -       10     /           /
100 -   43  25     tan-1       tan-1
101 -    44  1     STO 1       STO 1      -- store α in register 1
102 -    45 .5     RCL .5      RCL .5     -- calculate δ
103 -       23     sin         sin
104 -    45 .4     RCL .4      RCL .4
105 -       23     sin         sin
106 -       20     *           *
107 -   43  23     sin-1       sin-1
108 -    44  2     STO 2       STO 2      -- store δ in register 2

Help! I rooted my evo, now what do I do?

Posted in Uncategorized by benjaminplee on 11.24.10

A few weeks ago I rooted my HTC Evo 4G using the unrevoked 3 tool to flash my phone’s firmware and allow full root access to the internals.  The unrevoked app was one of the best user experiences I have seen in a while (walks you through each step with a nice clean interface).  Everything went great until the end when I was left wondering…

Am I done?  What do I do now?

Mount the file system as root

From the great Droid Incredible rooting tutortial over jonamerica.com

  1. Turn the phone off
  2. Reboot the phone by holding down the power button and down-volume button
  3. From the menu, select recovery
  4. After the phone boots into recovery mode, select partitions
  5. Select mount /system
  6. Now, from your machine (with the android sdk tools installed) execute “adb shell”
  7. Now your are connected with root access

Wireless Tether

I had trouble with the Android Wifi-Tether app on the app store so I downloaded the latest code from the Google Code homepage.  Install, enable access control (so that you can approve/deny anyone connecting by MAC) and go!

Profit!

This post has nothing to do with Clojure or Lisp.  Nada.  Zip.  Zilch.
This post has no opinion of Richard Stallman.  Nada. Zip. Zilch.

Tagged with: , , ,

Pro Tips: IE Caching Can Byte

Posted in Uncategorized by benjaminplee on 11.22.10

Be careful when doing cross-browser AJAX because IE and Firefox handle client-side caching very differently.  Last week I ran into a situation where a new in our app was misbehaving in IE but working perfectly in Firefox.  The culprit ended up being IE’s caching of our AJAX calls to kick off jobs and poll to see if they were finished.  IE was caching all AJAX calls by default which reaked havok on our user’s workflow.  Firefox sends an “If-Modified-Since” header on subsequent GET requests giving the server the chance to determine if a resource cache can be used or not.  IE 8 doesn’t.

To make matters worse, I had actually added some anti-caching logic into our code … but had accidentally moved the code to a point where it wasn’t being invoked (oops!).

The solution ended up being adding an extra parameter to each AJAX request populated with the current timestamp value in miliseconds

var url = "http://our-app/action?no_cache=" + new Date().getTime();

JQuery’s AJAX utilities methods do this by default (so long as the cache option isn’t set to false) but it doesn’t look like Prototype.js does by default.   From Prototype’s AJAX documentation:

You can use parameters with both GET and POST requests. Keep in mind, however, that GET requests to your application should never cause data to be changed. Also, browsers are less likely to cache a response to a POST request, but more likely to do so with GET.

Together, IE stopped caching our requests and everything went back to normal.

Tagged with: , , ,

Notes to self: Keep SVN in sync w/ Git The Poor Man’s Way

Posted in Uncategorized by benjaminplee on 11.12.10

There is probably a much better/faster way to do this leveraging git-svn, but for the poor fool who has to keep an SVN repo in sync w/ the development Git repo for client consumption … here are a couple helpful one liners…

Copy from the Git repo directory to the SVN repo directory

rsync -r $GIT_DIR $SVN_DIR

Detect if there are any non-.svn folder differences between the directories after (good sanity check)

diff -r $GIT_DIR $SVN_DIR | grep -v '\.svn' | wc

Programming Anti-Patterns: Releasing Cthulhu

Posted in Uncategorized by benjaminplee on 11.10.10

Some code is elegant.  Some code is a quick fix hack.
Some code is maintainable.  Some code release Cthulhu.

These are just a few gems I have found over the past year or so…

 

Math is for the Weak Pattern

if(result == 1) {
    obj.foo(0);
}
else if(result == 2) {
    obj.foo(1);
}
else if(result == 3) {
    obj.foo(2);
}
else if(result == 4) {
    obj.foo(3);
}

Subtraction is a poor abstraction;


Scare the Next Guy Pattern

// ... Base DAO containing transaction logic for whole application ...
if(connection.isOpen()) {
   aSimple.MethodCall();

    // TODO:
}
// ... more complex TX logic ...

Because, what he doesn’t know … might be nothing … or might be something


Decoy Security Pattern

<pre>public Connection getNewConnection() {
    Long.Full.Package.Name.Connection c = new Long.Full.Package.Name.Connection();

    return new Long.Full.Package.Name.Connection();
}

No cups in this shell game, just database connections


Missing Father Pattern

try {
    foo.bar();
}
catch(Exception e) {
    throw e;
}

If dad is never around, you end up playing catch with yourself

All codes have been modified and rewritten to protect the guilty.
Tagged with:

Start Tomcat from the REPL

Posted in Uncategorized by youngnh on 11.10.10

One of the first things that I wrote in Clojure was a few files that launched a tomcat server from a repl. My code was separated into 3 files:

  • tomcat.clj created a Tomcat server through the Embedded class, which you could then start and stop from the repl
  • tomcat_loader.clj which handled separating classloaders for tomcat itself and the webapps deployed to it
  • classloading.clj which held generic utility functions for creating class loaders and searching file paths

Creating an embedded tomcat engine is an excercise in Clojure-Java iterop:

(defn create-embedded-tomcat [#^String hostname app-base contexts]
  (let [embedded (Embedded.)
        engine (.createEngine embedded)
        host (.createHost embedded hostname app-base)
        http-connector (.createConnector embedded hostname 8080 "http")
        ssl-connector (.createConnector embedded hostname 8443 true)]
    (.setParentClassLoader engine tomcat-shared-loader)
    (doall (map #(% embedded host) contexts))
    (.addChild engine host)
    (.addEngine embedded engine)
    (.addConnector embedded http-connector)
    (.addConnector embedded ssl-connector)
    embedded))

app-base is a file path from which Tomcat will serve webapps out of, it’s webapps/ in the standalone distribution, but creating your own engine, you can now set it to anywhere you’d like. contexts is a list of Context objects, applications that you want Tomcat to serve that might not be in the app-base folder. I wrote a helper fn to create then:

(defn context [path war-file]
  (fn [embedded host]
    (let [context (.createContext embedded path war-file)]
      (.addChild host context))))

(context "/myapp" "/home/awesomesauce/dinosaur-app.war")

The Embedded object that create-embedded-tomcat returns has .start and .stop methods on it, so no need for special Clojure fns for them, just invoke the methods directly on the object.

The classloading magic happens in tomcat.clj‘s ns header. It :uses tomcat_loader.clj which creates 3 classloaders:

(def thread-context-loader (.. (Thread/currentThread) getContextClassLoader))

(def tomcat-common-loader (create-class-loader (expand-paths tomcat-common-path) thread-context-loader))
(def tomcat-catalina-loader (create-class-loader (expand-paths tomcat-catalina-path) tomcat-common-loader))
(def tomcat-shared-loader (create-class-loader (expand-paths tomcat-shared-path) tomcat-common-loader))

Each of these class-loaders are created via create-class-loader which takes a “loader-map” and a parent classloader to create a URLClassLoader. The 3 “loader-maps” are specified like so:

(def *catalina-home* (or (System/getProperty "catalina.home") (System/getProperty "user.home")))

(def tomcat-common-path 
     {*catalina-home*
      {"common/classes" :dir
       "common/i18n/" :glob
       "common/endorsed/" :glob
       "common/lib/" :glob}})

(def tomcat-catalina-path 
     {*catalina-home*
      {"server/classes" :dir
       "server/lib/" :glob}})

(def tomcat-shared-path 
     {*catalina-home*
      {"shared/classes" :dir
       "shared/lib/" :glob}})

So they’re simple maps that specify where to find jars and class files on the system. With this hierarchy of classloaders set up, Clojure then has the means to find the classes it needs when we ask it to instantiate a Tomcat server.

I haven’t run this code in a while and it’s getting late, but when I get a chance, I’ll scrub it and run it through it’s paces and post it somewhere you can get your hands on it.

Notes to self: Find all files NOT containing text

Posted in Uncategorized by benjaminplee on 02.09.10

Handy script to find all files in a given subfolder that do NOT contain a certain text line. Sorted for easy reading:

find ./PATH/TO/FOLDER -type f -size +1c ! -exec grep -q ‘SEARCH TEXT’ {} \; -print | sort

King of the nerds – Quick and Dirty Programming Contest Winners

Posted in Uncategorized by benjaminplee on 01.24.10

Winning a vendor sponsored timed programming contest at a three day technical conference (CodeMash**) which you voluntarially traveled to in Northern Ohio in the middle of January is a double edged sword.

One the one side you are the king of the nerds.
On the other side …  you are the king of the nerds.

A few weeks ago Josh Schramm, Kevin Berridge, and I (all past Dayton Flyers and college roomates) took in a great CodeMash conference and decided to enter a StoutSystems sponsored programming SmackDown just for kicks.

We won.  All hail the kings of the nerds.

Granted only ~15 teams entered (from 1 -3 people each) but none the less, we won and only one other team submitted even a failed attempt before our winning one.

Josh posted our solution in Ruby to GitHub and I have since cleaned it up a bit, added the original rules, a C# & Linq solution Kevin did while we were there and a new one of my own making in Ruby.

I am planning to write the solution in a few different languages and designs.  If anyone else has an entry or can suggest a way to make the Ruby variant any cleaner or more idiomatic … please leave me a comment or fork my repo on GitHub.

Latest Ruby variation:

lines = []

File.open('../input.txt').each { |line| lines << line }

lines = lines[1..lines.size].
              map     { |line| line.split("\t") }.
              each    { |line| line[1] = line[1].gsub(/[^a-zA-Z]/, '').reverse }.
              reject  { |line| line[1].to_s.empty? }.
              sort    { |x, y| (x[1] <=> y[1]) == 0 ? (x[5].to_f <=> y[5].to_f) : (x[1] <=> y[1]) }.
              collect { |line| line.join("\t") }.
              insert(0, lines[0])

File.open("output.txt", 'w') { |f| f.write(lines) }

** CodeMash was an absolute blast.  Great sessions, good people, nice venue, and rockin’ live music.

Long live esenihc lavivrus

Follow

Get every new post delivered to your Inbox.