My thoughts as an enterprise Java developer.

Saturday, November 01, 2008

Lego Mindstorm NXT program

I temporarily had a Lego Mindstorm NXT and wrote the following program for it using LeJOS.  Enjoy:
import java.util.*;
import lejos.nxt.*;
import lejos.util.*;

public class Dingbot {
public static void main (String[] aArg) throws Exception {
new ButtonWatcherThread(new TimerListener() {
public void timedOut() {
running = !running;
}
}).start();
motorRight.smoothAcceleration(true);
motorLeft.smoothAcceleration(true);
final float circumference = 17.5f;
final int distanceBuffer = 50;
final int rotateDistance = 80;
UltrasonicSensor distSensor = new UltrasonicSensor(SensorPort.S4);
LightSensor litSensor = new LightSensor(SensorPort.S2);
litSensor.setFloodlight(true);

LCD.drawString("Hi",1,1);
int startTime = (int)System.currentTimeMillis();
boolean blinkLight = true;
Random random = new Random();
while(startTime + 60*1000 > (int)System.currentTimeMillis()) {
if(running) {
int cmDist = distSensor.getDistance();
while(running && cmDist > distanceBuffer) {
LCD.drawString("   ",1,2);
LCD.drawInt(cmDist,1,2);
int distance = cmDist - distanceBuffer;
if(distance > 5) {
distance = 3;
}
int degrees = (int)(360 * distance / circumference);
setSpeed();
motorRight.rotate(degrees, true);
motorLeft.rotate(degrees, true);
cmDist = distSensor.getDistance();
litSensor.setFloodlight(blinkLight);
blinkLight = !blinkLight;
LCD.drawInt(litSensor.readNormalizedValue(),1,4);
}
boolean turnPositive = random.nextBoolean();
while(running && cmDist <>
LCD.drawString("   ",1,2);
LCD.drawInt(cmDist,1,2);
setSpeed();
if(turnPositive) {
motorRight.rotate(180);
} else {
motorRight.rotate(-180);
}
cmDist = distSensor.getDistance();
}
} else {
try {
Thread.sleep(500);
} catch(InterruptedException ie) {
//Ignore
}
}
}
}

public static void setSpeed() {
int soundLevel = sound.readValue();
LCD.drawString("   ",1,3);
LCD.drawInt(soundLevel,1,3);
int speed = (100 - soundLevel) * 9;
motorRight.setSpeed(speed);
motorLeft.setSpeed(speed);
}
static Motor motorRight = Motor.B;
static Motor motorLeft = Motor.C;
private static SoundSensor sound = new SoundSensor(SensorPort.S1);
private static boolean running = false;
}

class ButtonWatcherThread extends Thread {
public ButtonWatcherThread(TimerListener tl) {
this.tl = tl;
this.setDaemon(true);
}
public void run() {
wasPressedLast = touchSensor.isPressed();
while(true) {
boolean isPressed = touchSensor.isPressed();
if(wasPressedLast != isPressed) {
if(isPressed) {
tl.timedOut();
}
wasPressedLast = isPressed;
}
try {
Thread.sleep(100);
} catch(InterruptedException ie) {
//Ignore
}
}
}
private TimerListener tl;
private boolean wasPressedLast;
private TouchSensor touchSensor = new TouchSensor(SensorPort.S3);
}

Friday, October 31, 2008

Why do geeks celebrate Christmas on Halloween?

Because Oct. 31 = Dec. 25

Thursday, October 02, 2008

Digital money

I think digital money should have these features:
  1. Hard to counterfit
  2. Hard to duplicate (and use twice)
  3. Easy to transfer to another person with minimal involvement of a 3rd party
  4. Easy to use, track, store, verify, etc
  5. Transaction fees must be very, very low.
  6. Minimal Big Brother tracking.
Here is one idea for how to accomplish that:
A user would go to a website and enter payment info and the website would send the user an image file. The file would be a picture of the amount of money that it represents (for ease of use) and would have comments in it that record the originating website, amount and any other needed info. The website would generate the image so that is unique (i.e. the bits are unique) and would store the image bits and amount in a database. The file would have to be large enough so that a brute force attempt to generate random files would be too expensive.
When the user needs to split an amount (make change), they would send it to the website and request the new amounts. The website would verify that it was valid (in their DB), send new image files to the user, and delete the record for the old file.
When the user needs to send money to another person they would just get the correct amount (using splitting or multiple files) and send those files to the other person. The other person would send them to the website to get their own files so that the old file is invalid and they have a valid file. Once the other person saw that they were valid they would complete the transaction with the first person.
Verification consists of sending to the website to get an new file. If the file was invalid the webiste would just give an error message. Anytime a user receives money from another user they must verify it (get a new file) to make sure that it is valid.
The user could cash out the file by going to the website and requesting payment.
Transaction fees would be limited to the initial payment and requesting payment.

The user could have requested multiple files with various amounts to make it easier.
If someone tries to make a copy of the file in order to use it twice only the first copy would be validated.

The user would need to remember to not make any changes to the image (i.e. rotation) because that would invalidate the file. Therefore the image formats that Windows Explorer can rotate should be avoided or the files always marked as read-only.

This idea could work for trading anything (different currencies, stocks, etc). Each website would have its own file type but websites or users could translate between the different file types.

Comments?

Wednesday, August 06, 2008

Spell check what others write

I think programs should spell and grammer check what others wrote. i.e. If I am reading a webpage it should have some way of marking bad spelling or grammer with a way to see suggested improvements. That would allow me to understand the intent better when the grammer or spelling is poor.

Do you agree that adding this feature to browers, IM clients, etc would be useful?

Monday, June 16, 2008

XSL: Preserving line feeds, tabs, and spaces in data while still wrapping text

I had data in XML that had line feeds, spaces, and tabs that I wanted to preserve (so I couldn't use

) but I also wanted the lines to wrap when the side of the screen was reached (so I couldn't use

).

After some research and help from a co-worker (Patricia Eromosele) I made the XSL template below that achieves that. An example of how to call it follows:


<p>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="text"/>
</xsl:call-template>
</p>



<xsl:template name="prewrap">
<xsl:param name="text" select="."/>
<xsl:variable name="spaceIndex" select="string-length(substring-before($text, ' '))"/>
<xsl:variable name="tabIndex" select="string-length(substring-before($text, '&#x09;'))"/>
<xsl:variable name="lineFeedIndex" select="string-length(substring-before($text, '&#xA;'))"/>
<xsl:choose>
<xsl:when test="$spaceIndex = 0 and $tabIndex = 0 and $lineFeedIndex = 0"><!-- no special characters left -->
<xsl:value-of select="$text"/>
</xsl:when>
<xsl:when test="$spaceIndex > $tabIndex and $lineFeedIndex > $tabIndex"><!-- tab -->
<xsl:value-of select="substring-before($text, '&#x09;')"/>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'&#x09;')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$spaceIndex > $lineFeedIndex and $tabIndex > $lineFeedIndex"><!-- line feed -->
<xsl:value-of select="substring-before($text, '&#xA;')"/>
<br/>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'&#xA;')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$lineFeedIndex > $spaceIndex and $tabIndex > $spaceIndex"><!-- two spaces -->
<xsl:value-of select="substring-before($text, ' ')"/>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><!-- should never happen -->
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

Tip: Java thread dumps on linux

To get a thread dump in Java on linux run "pkill -3 java"

Ethical programming

It should be noted that no ethically-trained software engineer would ever consent to write a DestroyBaghdad procedure. Basic professional ethics would instead require him to write a DestroyCity procedure, to which Baghdad could be given as a parameter.
-- Nathaniel Borenstein
(Passed on by Reid Nimz.)

Friday, February 15, 2008

Rename multiple files

Options for renaming multiple files on Windows
  1. Windows explorer: It only renames them to xxxx (y).ext where the only thing that varies is y (an incrementing number).
  2. Various utilities available for download: I don't like to risk running some unknown program for something that seems so simple.
  3. Command line for in do command. To prepend "3-" to every directory that starts with "60-" run: for /d %i in (60-*) do ren %i 3-%i

Monday, February 11, 2008

Geek Status

In my IM client I set my status to the following. I admin that I'm a geek but it's fun!
echo "JANS" | sed "s/A//" | sed "s/J/Ava/" | sed "s/N/il/" | sed "s/S/able/"

Monday, February 04, 2008

3 paychecks in February

I get paid bi-weekly on Fridays and this year I get 3 paychecks in February. I was wondering how often that happens and with Excel's help I found that it happens every 56 years. I also found that a month with 3 paychecks will be 5-7 months later than the last month with 3 paychecks. In 2010 there will be 3 months with 3 paychecks.

Tuesday, January 29, 2008

Explaing zero-based arrays

Sometimes people have a hard time understand zero-based arrays but I just realized that ages are zero-based.

The first year of life someone is 0 years old.
The 2nd year of life someone is 1 year old.
Etc.

Friday, January 25, 2008

Genome assembler

I have been listening to "The Genome War" and it seems like the the difficulty of assembling the pieces from the Shotgun sequencing isn't has hard as described in the book.

Data points:
Base pairs in the Human Genome: 3 billion.
Different types of base pairs: 4
Sequence length: 2,000
Maximum number of sequences per whole genome: 1,500,000
Number of reads to get coverage: 12
Total number of sequences to assemble: 18,000,000
Total ends to match: 36,000,000
Length of an end: 50 base pairs (13 bytes can store 52 base pairs)

Technique:
So if you made a database table with a column to store the end code (from the outside) and a sequence column to store the sequence that for that end, you would have 2 rows per sequence for a total of 36,000,000 rows. Each row would have 513 bytes of info for a total of 17 GB of data.
Then make a table called End48 with a Key48 column for 48 base pairs (12 bytes) and a Value52 for 52 base pairs (13 bytes).
Fill that table so that each end in the main table is put in the Value52 column and and the first 48 base pairs of that end are put in the Key48 column.
Continue stripping down the end base pairs into tables End44, End40, End36, ..., End8, End4. (You actually only have to go as far down as the DB can easily sort the key column -- I think current DBs wouldn't need any End tables).
Then you can start by sorting the key column of the smallest End table and continue until all of the sequences are sorted by their end pieces. Finally go through the sorted results and join any sequences that have the same end value. A lot of this processing could occur as the data comes in so you wouldn't have to wait until the end to do all of the computing.

This assumes that sequences always end at the same point which I am not sure is true. If that isn't true then you might end up with multiple copies of the genome in the final assembly stage but that would not be a problem.

That technique could be easily done with a few thousand dollars of hardware today and I assume it would not have taken a super-computer in 1999-2000.

So what am I missing because apparently the problem was much more difficult to solve?

Reference: http://en.wikipedia.org/wiki/Human_genome_project

Tuesday, January 22, 2008

What kind of programming work do you like best?

When interviewing candidates I would ask them the following question:
What kind of programming work do you like best?

They always (3-4 interviews) gave then same answer: Creating new software.
Since that isn't the answer that I would give I asked my co-workers and between 4 of us we had 3 different answers:
  1. Creating something new
  2. Debugging problems.
  3. Improving (adding features, improving performance, etc).
Would you give one of those answers? Do you have a different answer?

Wednesday, January 02, 2008

Zooming to better use desktop space

On a real-life desktop I will often move toward an object to work with it. i.e. When I want to work with the calendar I will move closer to it. That allows better use of my desktop because some objects are "zoomed out" and therefore take less space (in my field of view).

Has anyone ever tried to incorporate a similar idea into a GUI. Icons, minimize/maximize, and resizing are somewhat like that but not quite enough. It would be nice to resize something to a "zoomed out size". i.e. I could set a size for my email program when it isn't in use and it would be shrunk to fit in that space when desired.

Monday, December 17, 2007

Telecommuting

I telecommute one day per week and used to telecommute 2 days per week. I would like to telecommute more but my employer isn't very open to doing that (except short-term for a specific project). I don't know of any Java enterprise developers that do major telcommuting (4 days per week or more). I have also not seen very many telecommuting jobs for enterprise Java developers. Why don't more exist?

Technorati Profile

Wednesday, December 12, 2007

Subversion: Moving tags

I wish Subversion had a better way of moving tags. The only way that I know to move a tag is to remove the file from the tag and then copy it again. Revision tree browsers don't seem to handle that very well. This also requires keeping the directory structure under the trunk and tag in sync.

Use case: We have thousands of "maps" and we want to tag which version of each map is the "production" version. We need to be able to easily get the production version of all maps.

Can anyone suggest a better way to address our use case?
I have considered properties also but then we can't get the prod version of all files easily. Merging to the tag doesn't appear to be very easy either.

Monday, November 26, 2007

IntelliJ default class javadoc comment

Why does the default IntelliJ default class javadoc comment use non-standard syntax? Instead of creating a line with "User: jstauffer" it could create a line with "@author jstauffer". The other lines that it creates (Date and Time) probably don't have javadoc syntax to use but why not use the javadoc syntax when available?

For reference here is an example:
/**
* Created by IntelliJ IDEA.
* User: jstauffer
* Date: Nov 13, 2007
* Time: 11:15:10 AM
* To change this template use File | Settings | File Templates.
*/

Naming abstract classes

Normally I see abstract classes named as AbstractClass. But when there are many abstract classes that leads to needing to type at least AbstractC when using code completion. Therefore I suggest that abstract classes be named ClassAbstract so that code completion is more usable. "Abstract" is a modifier on the class name anyway and it doesn't need to be in the primary position. What do you think?



I know this isn't a huge deal -- I am just suggesting it as a minor improvement.

Wednesday, November 21, 2007

Defaults have consequences: Microsoft Word margins

How much paper would be saved each year it Microsoft changed the default margins in Word to 1" on each side (or even 1/2")?

Friday, October 19, 2007

Autoboxing quiz

Does widening or autoboxing happen first? Which param method will be called from the autoboxing method? If one param method is commented out then it will have no problem calling the other.

private static void autoboxing() {
Integer integer = new Integer(2);
param(integer);
}

private static void param(int param) {
System.out.println("param(int " + param + ")");
}

private static void param(Object param) {
System.out.println("param(Object " + param + ")");
}