www.BrettDaniel.com

Side Effects

When discussing most medications, doctors usually list expected benefits first, then possible side effects. For chemotherapy drugs, the discussion is reversed: first doctors list expected side effects, then possible benefits. Each drug has its own unique side effect "signature" and regimen of secondary drugs with their own set of side effects. I have already written about hair loss and strange dreams. I recently experienced a new unexpected side effect: something caused my right leg to swell like an overstuffed sausage.

It is a frustratingly inexplicable side effect. It occurs after the Docetaxel treatments I have gotten every third week for the last few months. The drug's documentation says it occurs "in rare cases" but the root cause is not well known. I got a series of tests to rule out particularly bad possibilities like poor circulation, a blood clot, or problems with my lymphatic system. My surgeon says it does not appear to be related to surgery. That makes it just another random, mildly annoying side effect of chemotherapy. It didn't hurt; I just had to tie my shoe more loosely.

But what to do about it? The doctor prescribed some medication to reduce the swelling. It seems to be working. In the six days between treatments, I lost nine pounds, all from the leg! Of course, the medicine has its own set of side effects. Fatigue, in particular, but that goes away when I take another pill (for unrelated reasons) whose side effects include insomnia.

To test whether the swelling is really caused by the Docetaxel, the doctor omitted it from this week's treatment. She is still deciding whether to reduce the dosage, spread it out, or leave it unchanged. In any case, I am more than happy to accept a sausage leg if the drug takes care of the cancer.

Silly Videos

A friend complained that I had not posted any new videos since creating a YouTube account for the JUnit Music Box demonstration. So here are some silly videos from several years ago.

The 2006 Winter Olympics curling event provided a convenient target for Nerf suction cup darts.

My grandmother's and cousin's dogs were just puppies in August 2004.

In October 2004, Eric demonstrated his unicycle skills in the hallway of Purdue's Hillenbrand Hall.

In February 2004, my suitemate Matt hung a rope swing from the loft in his dorm.

At my sister's high school graduation party in June 2003, the pinata did not work quite as expected.

Lego Siebel Center

I recently read that Lego released models of The Guggenheim and Fallingwater as a part of its new "Architecture" series. That news inspired me to design a Lego version of the University of Illinois' Thomas M. Siebel Center for Computer Science.

Lego Siebel Center facing southwest

I cannot comment on how Siebel Center's architecture compares to The Guggenheim or Fallingwater, but the building has some interesting features that were a challenge to translate into Lego. In particular, choosing the correct scale, building the angled sections, and sculpting the topology of the courtyard took a lot of experimentation. Fortunately, Siebel Center is one of the most photogenic buildings on campus, so the web is filled with pictures that I could reference [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].

The key to figuring out an appropriate scale came from this detailed floor plan. I needed a scale that provided a good level of detail, allowed walls and other structures to be subdivided into "nice" Lego sizes, and produced a model of reasonable size. As is often the case, the simplest solution was the best: if I used a single 1×1×1 block for each window, then everything fell together like magic. At this scale, the full model is about 70 studs (≈22 inches) long by 60 studs (≈19 inches) wide. I have not yet measured the actual size of Siebel Center's windows to determine the Lego-to-real life scale.

I started with the western wall of the building since it is a sheer face of brick and windows and I had a picture reference handy. From there, I continued roughly counterclockwise until I reached the glass-faced northern facade which angles out from the main body of the building. I built this pie-shaped section separately and slid it into place against an otherwise blank wall. Many angled "wing" pieces hide the gap.

A patio sits in a depression at the bottom of the angled section. I first attempted to orient the depression to the main building and rest of the courtyard but found that the grass and stairways did not meet the patio nicely. Instead, I connected the slope to the patio and slid the slope under the rest of the grass using stubless plates.

You can view the digital model in Lego Digital Designer. I would love to build the model in real life, but according to LDD, it would cost around $850. I could probably reduce the price by refining the design and buying bulk pieces. Maybe the computer science department could sponsor its construction?

The following images show the completed design. There are more perspectives in the gallery.

Lego Siebel Center facing southeast Lego Siebel Center facing northeast Lego Siebel Center facing northwest

Eclipse JUnit Music Box

I wrote an Eclipse plugin that turns Eclipse's built-in JUnit runner into a music box. The following video demonstrates the plugin:

Each test class is assigned one of seven chords in the key of C major. The assignment is deterministic, so a particular sequence of tests will play the same "song". Passing test methods play a pleasing arpeggio, while failing tests play an ugly dissonant chord. The time each test method takes to execute determines the speed of the music. If more than one test class runs, then the music resolves to the tonic at the end of the session.

Here is the plugin (including source code). To try it out, simply save the .jar file in Eclipse's plugins directory and restart Eclipse. I tested it in Eclipse version 3.4.0 running on JDK 6. The plugin requires MIDI, so if you do not hear any sound when running JUnit tests, your computer probably lacks an appropriate MIDI device or it is configured incorrectly. Try running this simple class to test your MIDI setup.

I am not the first to think of making JUnit play music. There is a Musical JUnit project on SourceForge, but it has not been updated in three years. It also uses prewritten samples, while mine produces sound programmatically.

Cancer Update: Hair Edition

Chemotherapy causes hair loss by damaging fast-growing cells in the hair follicles. I lost the hair on my head very quickly after my first treatment back in September. My eyebrows and eyelashes followed midwinter. I joked with friends that I was constantly surprised throughout the day, but they would never know since I lacked eyebrows.

Guide to facial expressions on a face without eyebrows.

Some of the hair has returned since switching to a new set of drugs. Still no eyebrows, though, and the hair on my head is thin and patchy like a poorly-watered lawn. There is also a strange dark blotch of "normal" hair on the back of my head that a colleague said looked like the start of a Hare Krishna topknot.

Hair splotch

Weird, but no big deal. Baldness is a normal side-effect of chemotherapy, and I will likely keep my head shaved until I finish treatments.

Crunch Time

Every profession has deadlines, but the culture of crunch time is particularly prevalent in high-tech fields. The tendency toward late nights and last-minute sprints is one of the few things I dislike about computer science and programming. Nearly-perfect software takes time.

Even so, I have found myself buried in crunch time more often than I like to admit. Over the last month, for example, I spent many 10-plus-hour days writing my latest research paper. I was curious how this stretch of time compared to previous research papers'. Now that the deadline has passed, I can satisfy my curiosity by examining the papers' revision control system. It contains every edit made to each of the last five papers I was involved in.

The following chart shows how the papers grew as their deadlines approached.

Research paper growth as a deadline approaches

Vertical jumps represent lines added or removed from a paper. Horizontal plateaus represent the length of time between changes. Crunch time is obvious in this diagram: around ten days before a deadline, a paper's growth rate increases, and the length of time between edits decreases. For example, the last ten days of the most recent paper, shown in red, contained about 75% of the paper's total edits.

This number, the fraction of edits in the final ten days, creates an interesting "crunchiness" metric. The following chart shows the metric for each of the papers.

Fraction of edits in the final ten days before a deadline

This chart echoes how I would qualitatively rank the papers: "Automated Testing of Refactoring Engines" was easily the most crunchy and "Predicting Effectiveness of Automatic Testing Tools" was the least.

More research is needed to determine if crunchiness correlates with paper acceptance.

Wanted: eA Ligature

Do any typographers read this weblog? If so, I have a request: I would like an eA ligature for a paper I am writing in LaTeX. Something like the following but in the standard Computer Modern typeface. An italicized version would also be nice.

eA ligature

I need it for a word with InnerCaps that appears throughout the paper. As it is, the separate letters appear too far apart, and the tails do not line up nicely when I play with the kerning. LaTeX already has æ and Æ; why not the other six combinations? Or every two-letter combination? There are only (26 × 2)2 = 2,704 of them.

Related

I now have four library cards

I now have four library cards: Champaign, Indianapolis Central, suburban Indianapolis, and an Indiana public library access card.

Geohashing Point not in a Cornfield

Most Midwestern geohashing points fall in corn or soybean fields. Yesterday's point for the Danville, Illinois graticule was different. It fell near an interesting wooded area, and the return trip passed an amazing quarry. See the trip report for the full story.

Panorama of a quarry near the 2009-04-18 40 -87 geohashing point

Taught Go to two people in as …

Taught Go to two people in as many days. Anyone else want to learn?

PET scan and blood test. PET …

PET scan and blood test. PET shows no metabolic activity in the leg tumors. Blood counts surprisingly low, so chemo postponed one week.

Unauthorized Charge

Someone got my credit card number and charged $893.39 to a website in Italy. The charge should be reversed in 10 days and a new card is in the mail.

java.util.Random’s Magic Number 0x5DEECE66D

Java's java.util.Random class is used to produce a sequence of pseudo-random numbers. As part of a recent recreational programming project, I needed to copy a given Random object such that both the original and copy produced the same sequence of values. While hacking together a quick-and-dirty solution, I learned some interesting facts about the implementation of the Random class.

The usual way to ensure that two Random objects produce the same sequence of values is to supply the same seed values to two new instances.

long seed = ...;
Random r1 = new Random(seed);
Random r2 = new Random(seed);

However, in this particular project I had no control over the instantiation of the Random object, and I could not access the original seed. Ideally, the Random class would provide a getSeed method that one could use to create a new object, but Java's implementation does not. This omission is particularly strange since the class stores the value but hides it in a private member variable.

The seed is stored as a java.util.concurrent.atomic.AtomicLong for thread safety. A new seed value is XOR'd with a constant multiplier and truncated to 48 bits before being stored.

public class Random ... {
    ...
    private final AtomicLong seed;
    private final static long multiplier = 0x5DEECE66DL;
    private final static long mask = (1L << 48) - 1;
    ...
    synchronized public void setSeed(long seed) {
        seed = (seed ^ multiplier) & mask;
        this.seed.set(seed);
        ...
    }
}

The class perturbs the seed in this way to increase the period of the generator. That is, Random will produce a sequence of values that does not repeat for a very long time. How long? This analysis by a University of Utah mathematics professor says, "the period of the returned values should be 2^48, which is better than the 2^32 of most 32-bit generators."

But why does it use the magic number 0x5DEECE66D? The analysis says it was chosen simply because researchers determined empirically that it produces a sequence of values satisfying various randomness tests [1, 2, 3]. Also, the same number and algorithm is used in C's nrand48 function.

The rand48() family of functions generates pseudo-random numbers using a linear congruential algorithm working on integers 48 bits in size. The particular formula employed is r(n+1) = (a * r(n) + c) mod m where the default values are for the multiplicand a = 0x5deece66d = 25214903917 and the addend c = 0xb = 11. The modulo is always fixed at m = 2 ** 48. r(n) is called the seed of the random number generator.

Thus, my project could XOR the field value with 0x5deece66d to recover the current seed.

It is easy to get the value of the private variable using reflection. (To be clear, this breaks the entire concept of encapsulation, and I emphatically discourage this kind of fragile reflection in production code. Nevertheless, it worked well enough for a small personal project.)

public long getCurrentSeed(Random random) throws Exception {
    // Access private field to get the seed
    Field seedField = random.getClass().getDeclaredField("seed");
    seedField.setAccessible(true);
    AtomicLong seedFieldValue = (AtomicLong) seedField.get(random);
    // Unperturb the seed from the magic multiplier
    return seedFieldValue.get() ^ 0x5DEECE66DL;	
}

Then, one can use this seed to create a copy of the original Random object.

Random original = ...
Random copy = new Random(getCurrentSeed(original));

Calling the next* methods on either object will produce the same sequence of values. Exactly what my project needed.

Two-Factor Authentication using OpenID and a Mobile Device

Two-factor authentication is a security procedure that verifies a user's identity using two pieces of information: one that a person knows (such as a secret password) and another provided by something he or she has (such as an ID card). Recently, VeriSign released an an iPhone application that provides a one-time password, enabling two-factor authentication on "40 web sites that are part of the VIP Network, including eBay, PayPal and AOL".

Two-factor authentication using a mobile device is an excellent idea. People rarely leave the house without their mobile phone, and as smart phones become more widespread, such an application could remove the need for easily-misplaced security tokens. But why just 40 websites? What the press release does not mention is that since VeriSign is an OpenID identity provider, the iPhone application can provide two-factor authentication for any site that accepts an OpenID login.

Fortunately, there is no reason why this kind of two-factor authentication must be tied to VeriSign. MyOpenID provides a service called CallVerifID that verifies identity with a call to one's mobile phone. The only thing still missing (as far as I am aware) is an open-source implementation independent of any third-party service.

Therefore, I make the following request to the LazyWeb. I use phpMyID on this website, making it my OpenID identity provider. It should be possible to make this simple application accept a second authentication factor provided by a mobile phone application. Any takers?

Geohashing Trip

Another geohashing trip, this time with an interesting hike along railroad tracks, a science experiment, and a history lesson.
Older Posts