<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Spatula</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/" />
    <link rel="self" type="application/atom+xml" href="http://spatula.net/mt/blog/atom.xml" />
    <id>tag:spatula.net,2010-06-03:/mt/blog//2</id>
    <updated>2011-02-04T07:23:31Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 5.02</generator>

<entry>
    <title>Modulating and Demodulating Signals in Java</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2011/02/modulating-and-demodulating-signals-in-java.html" />
    <id>tag:spatula.net,2011:/mt/blog//2.12</id>

    <published>2011-02-04T07:18:47Z</published>
    <updated>2011-02-04T07:23:31Z</updated>

    <summary><![CDATA[I've been studying up to take my Amateur Radio License exam, and was kind of intrigued to read about the different ways ham operators send digital data.&nbsp; It got me to thinking that it might be fun to try some...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[I've been studying up to take my <a class="zem_slink" href="http://en.wikipedia.org/wiki/Amateur_radio" title="Amateur radio" rel="wikipedia">Amateur Radio</a> License exam, and was kind of intrigued to read about the different ways ham operators send digital data.&nbsp; It got me to thinking that it might be fun to try some modulation/demodulation trickery on my own, just to see what I could do with very little effort.&nbsp; In the spirit of ham radio, and because the FCC doesn't allow coded transmissions on Amateur Radio (you can modulate data, but you have to make it public how you're doing it), I present a strategy I'm calling Harmonic Relative Amplitude Modulation 8.&nbsp; I suppose you could call it HRAM8 if you wanted.&nbsp; I haven't researched to see if anyone else is modulating signals this way; it's entirely possible this isn't even my idea.&nbsp; But it's a nice way to learn about generating complex waves and demodulating them with <a class="zem_slink" href="http://en.wikipedia.org/wiki/Fast_Fourier_transform" title="Fast Fourier transform" rel="wikipedia">Fast Fourier Transforms</a> in Java.<br /><br />First a few design principles.&nbsp; I wanted to do something very simple that anyone could implement easily.&nbsp; I also wanted it to sound pleasing to the ear, having lived through far too many years of annoying fax and modem communications.&nbsp; I wanted it to be reasonably robust, though it needn't be perfect.&nbsp; And I wanted to keep the bandwidth under 1kHz, while maximizing throughput.<br /><br />I came up with a strategy in which I assign a base frequency and base amplitude, and associate the base frequency and its harmonics with bits 0-7 of a byte.&nbsp; If a bit is set to 1, its amplitude is 4 times the base amplitude, otherwise its amplitude is the base amplitude.<br /><br />I opted not to use a clock of any kind, deciding instead to simply observe when bit patterns change.&nbsp; This proved to be problematic, given words like "mucopolysaccharides" which have repeating characters.&nbsp; On the first repeat, the "clock" is lost.<br /><br />In keeping with my design principles, I opted for a simple and easy solution: I added a parity bit.&nbsp; The parity mode switches between even parity and odd parity with every character; even numbered characters get even parity and odd numbered characters get odd parity.&nbsp; So even if characters repeat, the bit pattern will change by at least 1 bit every time.&nbsp; I'm not currently testing the parity bit to report errors; that is yet to come. <br /><br />Each byte is modulated long enough to ensure proper transformation with FFT, which turns out to be two times the base frequency.&nbsp; In my present naive demodulation strategy, I simple scroll through the sample data at half the width of a single character, looking for bit patterns to change.&nbsp; When receiving a random signal off-air, this probably would not be adequate and a better strategy would need to be devised to be sure demodulation began at the start of a new character.&nbsp; I'm also thinking of having a "sync character" after every 32-byte frame, so if things go out of sync, they won't do it for more than 32 bytes.<br /><br />I'm using the excellent <a href="http://sites.google.com/site/piotrwendykier/software/jtransforms">JTransforms</a> library for Java to do the FFT along with a fairly slow sample rate and small FFT window size to make the FFT computations very quick.&nbsp; Fortunately the harmonics are spaced out well enough that this relatively low fidelity is adequate.<br /><br />Without further ado, how about some code?<br />
<pre><code>
package net.spatula.sandbox;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;

public class Sandbox {
	private static final int NUMBER_OF_CHANNELS = 1;
	private static final int BITS_PER_SAMPLE = 16;
	private static final int BIT_SET_MULTIPLIER = 4;
	private static final int BITS_PER_WORD = 8;
	private static final int SAMPLE_RATE = 8000; // 44100 if you want a really nice, clean sin wave, but then you must change FFT_SIZE to at least 16384 too
	private static final int BYTES_PER_SAMPLE = 2;
	private static final int BASE_FREQUENCY = 110;
	private static final int FRAME_SIZE = 32;
	private static final int SAMPLES_PER_CHARACTER = SAMPLE_RATE / BASE_FREQUENCY * 2;
	private static final double BASE_AMPLITUDE = 4095;
	private static final int FFT_SIZE = 4096; // 16384 if you use 44100 as the sample rate. FFT happens faster with smaller sizes.

	public void modulate(String string) throws LineUnavailableException, IOException {

		byte[] buffer = new byte[FRAME_SIZE * SAMPLES_PER_CHARACTER * BYTES_PER_SAMPLE];
		ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
		ShortBuffer shortBuffer = byteBuffer.asShortBuffer();

		for (int i = 0; i &lt; string.length() &amp;&amp; i &lt; FRAME_SIZE; i++)
		{
			byte byteToModulate = (byte) string.charAt(i);

			modulateByte(shortBuffer, byteToModulate, i % 2 == 0);
		}

		playByteArray(buffer);

		demodulateSampleBuffer(shortBuffer);
	}

	private void modulateByte(ShortBuffer shortBuffer, byte byteToModulate, boolean even) {
		for (int sampleCount = 0; sampleCount &lt; SAMPLES_PER_CHARACTER; sampleCount++)
		{
			double time = (double) sampleCount / (double) SAMPLE_RATE;
			double sampleValue = 0;
			int oneBits = 0;

			// sum the signals for each bit
			for (int bitNumber = 0; bitNumber &lt; BITS_PER_WORD; bitNumber++)
			{
				boolean bitSet = ((byteToModulate &amp; (byte) (Math.pow(2, bitNumber))) != 0);
				if (bitSet)
				{
					oneBits++;
				}
				sampleValue += Math.sin(2 * Math.PI * BASE_FREQUENCY * (bitNumber + 1) * time) * BASE_AMPLITUDE * (bitSet ? BIT_SET_MULTIPLIER : 1);
			}

			// add in the parity bit
			boolean setParity = ((even &amp;&amp; (oneBits % 2 != 0)) || (!even &amp;&amp; (oneBits % 2 == 0)));
			sampleValue += Math.sin(2 * Math.PI * BASE_FREQUENCY * (BITS_PER_WORD + 1) * time) * BASE_AMPLITUDE * (setParity ? BIT_SET_MULTIPLIER : 1);

			// average the signals
			sampleValue /= (BITS_PER_WORD + 1);
			shortBuffer.put((short) sampleValue);
		}
	}

	private void playByteArray(byte[] buffer) throws LineUnavailableException, IOException {
		InputStream is = new ByteArrayInputStream(buffer);
		AudioFormat audioFormat = new AudioFormat(SAMPLE_RATE, BITS_PER_SAMPLE, NUMBER_OF_CHANNELS, true, true);
		AudioInputStream ais = new AudioInputStream(is, audioFormat, buffer.length / audioFormat.getFrameSize());
		DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
		SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

		sourceDataLine.open();
		sourceDataLine.start();

		byte[] playBuffer = new byte[buffer.length];
		int bytesRead;
		while ((bytesRead = ais.read(playBuffer, 0, playBuffer.length)) != -1)
		{
			sourceDataLine.write(playBuffer, 0, bytesRead);
		}
		sourceDataLine.drain();
		sourceDataLine.stop();
		sourceDataLine.close();
	}

	private void demodulateSampleBuffer(ShortBuffer shortBuffer) {
		DemodulatedCharacter lastChar = null;
		for (int i = 0; i &lt; shortBuffer.capacity(); i += SAMPLES_PER_CHARACTER / 2)
		{
			DemodulatedCharacter nextChar = demodulateCharacter(shortBuffer, i, SAMPLES_PER_CHARACTER / 2);
			if (!nextChar.equals(lastChar))
			{
				lastChar = nextChar;
				System.out.print(nextChar);
			}
		}
		System.out.println();
	}

	private DemodulatedCharacter demodulateCharacter(ShortBuffer shortBuffer, int offset, int length) {
		float[] floatArray = new float[FFT_SIZE * 2];
		for (int i = offset; i &lt; shortBuffer.capacity() &amp;&amp; i &lt; offset + length; i++)
		{
			floatArray[i - offset] = shortBuffer.get(i);
		}

		FloatFFT_1D fft = new FloatFFT_1D(FFT_SIZE);
		fft.realForward(floatArray);

		int multiplier = (int) (BASE_FREQUENCY / ((float) SAMPLE_RATE / (float) FFT_SIZE));

		long maxPower = findMaxPower(floatArray, multiplier);

		int value = 0;
		for (int i = 0; i &lt; BITS_PER_WORD; i++)
		{
			int index = (i + 1) * multiplier;
			long power = computePowerAtIndex(floatArray, index);
			if (power &gt; (maxPower / (BIT_SET_MULTIPLIER / 2)))
			{
				value += Math.pow(2, i);
			}
		}

		DemodulatedCharacter character = new DemodulatedCharacter();
		character.setData((char) value);

		long parityPower = computePowerAtIndex(floatArray, (BITS_PER_WORD + 1) * multiplier);
		if (parityPower &gt; (maxPower / (BIT_SET_MULTIPLIER / 2)))
		{
			character.setParity(true);
		}

		return character;

	}

	private long findMaxPower(float[] floatArray, int multiplier) {
		long maxPower = 0;
		for (int i = 0; i &lt; BITS_PER_WORD; i++)
		{
			int index = (i + 1) * multiplier;
			long power = computePowerAtIndex(floatArray, index);
			if (power &gt; maxPower)
			{
				maxPower = power;
			}
		}
		return maxPower;
	}

	private long computePowerAtIndex(float[] floatArray, int index) {
		return (long) Math.sqrt(Math.pow(floatArray[index * 2], 2) + Math.pow(floatArray[index * 2 + 1], 2));
	}

	private static class DemodulatedCharacter {
		private char data;
		private boolean parity;

		public char getData() {
			return data;
		}

		public void setData(char data) {
			this.data = data;
		}

		public boolean isParity() {
			return parity;
		}

		public void setParity(boolean parity) {
			this.parity = parity;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + data;
			result = prime * result + (parity ? 1231 : 1237);
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			DemodulatedCharacter other = (DemodulatedCharacter) obj;
			if (data != other.data)
				return false;
			if (parity != other.parity)
				return false;
			return true;
		}

		@Override
		public String toString() {
			return String.valueOf(getData());
		}
	}

	/**
	 * @param args
	 * @throws LineUnavailableException
	 * @throws IOException
	 */
	public static void main(String[] args) throws LineUnavailableException, IOException {

		new Sandbox().modulate(args[0]);
	}

}
</code>
</pre>

<div style="margin-top: 10px; height: 15px;" class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://www.zemanta.com/" title="Enhanced by Zemanta"><img style="border: medium none; float: right;" class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_e.png?x-id=9bd8c9c8-bcb5-4a4e-85fc-5fb83952e9b9" alt="Enhanced by Zemanta" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>]]>
        
    </content>
</entry>

<entry>
    <title>The GMAC Saga Continues</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/11/the-gmac-saga-continues.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.11</id>

    <published>2010-11-17T21:30:29Z</published>
    <updated>2010-11-17T21:39:53Z</updated>

    <summary>It&apos;s a shame that natural selection fails to operate efficiently in our species and that it doesn&apos;t seem to apply to customer service drones in large corporations.I finally got a reply today from GMAC to the Washington DC Better Business...</summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="gmacassholes" label="GMAC assholes" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[It's a shame that natural selection fails to operate efficiently in our species and that it doesn't seem to apply to customer service drones in large corporations.<br /><br />I finally got a reply today from GMAC to the Washington DC Better Business Bureau.&nbsp; (Read my <a href="http://spatula.net/mt/blog/2010/11/gmac-mortgage-customer-service-so-bad-its-criminal.html">previous post</a> for the back-story.)<br /><br />It turns out that not only did they apply the $556 refund sent from our flood insurance company meant for our closed GMAC account to our new GMAC account, they also have been calculating our payments incorrectly for the new account.&nbsp; We would not have discovered this had it not been for their losing the $556 initially and drawing our attention as a consequence.<br /><br />In their response, they claim to have anticipated the incorrect amount for our property taxes, which is of course impossible-- the correct amount was on our HUD-1 statement from closing, and it's the same amount they had been charging us when they held our previous loan.&nbsp; They went on to claim our taxes had "increased" (false) and that this meant we now had an escrow shortfall, tempered somewhat by the $556 they incorrectly placed in our new escrow account.<br /><br />The tone of the response was unnecessarily condescending and attempted to place the blame for this miscalculation on us.&nbsp; It even insinuated that we hadn't been paying our bills.<br /><br />I rejected their response.&nbsp; Here's my reply:<br /><br /><blockquote><span id="messageViewControl_bodyLabel"><p style="line-height: 150%;"><span style="line-height: 150%; font-family: Georgia; font-size: 10pt;"><font face="Verdana"><font face="Verdana"><font face="Verdana">I am rejecting this response because:</font></font></font></span></p>
<ul><li><font face="Verdana"><font face="Verdana"><font face="Verdana"><strong><span style="line-height: 150%; font-family: Georgia; font-size: 10pt; font-weight: normal;"></span></strong>GMAC's assertion that our taxes have increased is false.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">We
 have paid, on time, every time, exactly the amounts stated on all our 
bills from GMAC.&nbsp; Our payments have been made using GMAC's own automatic
 withdrawal bill payment system.<br /></font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">If the escrow amount billed was incorrect, this mistake is GMAC's.&nbsp; They have not acknowledged that this is their error.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">The
 correct tax, insurance, and escrow information was made available to 
GMAC at the time they acquired our loan, which was prior to our first 
monthly payment.&nbsp; GMAC subsequently produced statements for the 
incorrect amount.&nbsp; Again, this was not our error; we paid the amount due
 on time using GMAC's automatic payment system.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">The
 escrow shortage we presently face was caused by GMAC's own error.&nbsp; GMAC
 has not acknowledged that this was their error, not ours.<br /></font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">At
 the time this complaint was originally opened, GMAC had no idea where 
the missing $556 was.&nbsp; It was many days later before they finally 
discovered they had placed it into a different account.&nbsp; GMAC has not 
addressed their gross lack of accountability for incoming funds/refunds.<br /></font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">GMAC took money that was destined for one account and placed it in a different account.&nbsp; This is an incorrect banking practice.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">GMAC has not acknowledged their woefully inadequate and incompetent customer service.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">GMAC has not apologized for their woefully inadequate and incompetent customer service.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">GMAC
 has failed to adequately explain why they billed us for the incorrect 
amount, especially in their light of their possession of documents from 
closing indicating what the correct amount should have been.</font></font></font></li><li><font face="Verdana"><font face="Verdana"><font face="Verdana">This
 escrow shortfall issue is tangential to the reason this complaint was 
opened and would not have been discovered had it not been for GMAC's 
incompetence in handling the refund correctly.&nbsp; It would no doubt have 
continued until our next tax payment was due before it was noticed, at 
such time we would have found ourselves in dire circumstances.&nbsp; GMAC 
must explain why this happened and what it will do to prevent future 
errors of this magnitude.</font></font></font></li></ul>I am unable to accept a response from GMAC which contains false and misleading information and which omits critical details.<br /></span><br /></blockquote>At least I know where the money is now.<br />]]>
        
    </content>
</entry>

<entry>
    <title>GMAC Mortgage: Customer Service So Bad It&apos;s Criminal</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/11/gmac-mortgage-customer-service-so-bad-its-criminal.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.10</id>

    <published>2010-11-03T17:26:10Z</published>
    <updated>2010-11-03T17:48:10Z</updated>

    <summary><![CDATA[First, the back-story.Back in August, GMAC received a bill for our flood insurance from our insurance company.&nbsp; They didn't pay it.&nbsp; September rolled around and it still hadn't been paid.&nbsp; Facing a loss of flood insurance if we didn't pay...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="gmac" label="GMAC" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="assholes" label="assholes" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="customerdisservice" label="customer disservice" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[First, the back-story.<br /><br />Back in August, GMAC received a bill for our flood insurance from our insurance company.&nbsp; They didn't pay it.&nbsp; September rolled around and it still hadn't been paid.&nbsp; Facing a loss of flood insurance if we didn't pay up, I paid it by credit card on September 24.&nbsp; GMAC had also finally paid it on September 21.&nbsp; My payment got to the insurance company first.<br /><br />On October 13, our insurance company sent a refund check back to GMAC for overpayment.&nbsp; This check has subsequently disappeared completely.&nbsp; I've made multiple calls to GMAC's "customer service" in an effort to track it down so we can get the surplus back.&nbsp; The first time they transferred me quite literally in circles for almost an hour.&nbsp; The second time I spoke to someone who was a blithering imbecile who wouldn't listen to a word I said.&nbsp; The third time, the representative just disconnected my call.&nbsp; Someone did call me back hours later, but his accent was so thick I couldn't understand a word he said.<br /><br />I also emailed them once, explaining the problem in detail, and some moron wrote me back telling me that my homeowners insurance had been paid.&nbsp; (This is true, but it wasn't what I was writing about.&nbsp; I was writing about our flood insurance in the amount of $556, not our homeowners insurance in a completely different amount, but the brainless fecalbrain who received my email couldn't be bothered with these silly "details.")<br /><br />On no occasion did anyone at GMAC take ownership of the problem and resolve to find the right person or persons to deal with the issue.&nbsp; The best they could do is tell me that they didn't know where the money was.<br /><br />I wonder how many of these people, if someone they knew had misplaced a check for $556 while visiting their home, would just throw up their hands immediately and say, "oh well, I don't know where it is" and think that was a satisfactory resolution.&nbsp; No decent human being in his or her right mind would do that.&nbsp; They'd tear the house apart looking for it, starting with the most likely locations first.<br /><br />Not so with GMAC.&nbsp; They're not even remotely interested in helping.&nbsp; They're certainly not interested in finding the $556 we're owed... I would imagine because they quite like holding on to our money and not giving it back.<br /><br />Yesterday I'd finally had enough of their crap.&nbsp; Rather than spend another moment talking to yet another mindless drone in Russia, I mailed a complaint to the California Department of Corporations, the entity that regulates mortgage lenders in the state.&nbsp; Perhaps that will finally get the attention of someone with the ability and willingness to resolve the problem.<br />]]>
        
    </content>
</entry>

<entry>
    <title>Why Does Eclipse WTP Still Suck So Much?</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/10/why-does-eclipse-wtp-still-suck-so-much.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.9</id>

    <published>2010-10-22T00:07:35Z</published>
    <updated>2010-10-22T00:24:48Z</updated>

    <summary>Much as I hate it as a language for its performance and its tendency of its code to rapidly degrade into a haystack of unreadable crap, PHP has one tremendous development advantage over Java, still: you can change a line...</summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="shitwareeclipsewtpjboss" label="shitware eclipse wtp jboss" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Much as I hate it as a language for its performance and its tendency of its code to rapidly degrade into a haystack of unreadable crap, PHP has one tremendous development advantage over Java, still: you can change a line of code, ALT-TAB to your browser, hit Reload, and see the effect, instantaneously.&nbsp; This does wonders for the development cycle.&nbsp; Of course eventually it bites you in the ass, because PHP is so unmaintainable and hideous.&nbsp; But the quick cycle is fantastic.<br /><br />Eclipse began a sort-of half-assed attempt at integrating development with deployment half a dozen years ago, with the first release of WTP back in 2005.&nbsp; And since then, it hasn't gotten any better.&nbsp; It may have even gotten worse.<br /><br />In a perfect world, when I change a line of code in Eclipse and save the file, the class would be recompiled, hot-swapped into the running server, and I could go see the effect of my change in my browser.&nbsp; This does not happen.&nbsp; Or rather, sometimes it can happen, maybe.&nbsp; Maybe if you install JavaRebel, it will work.&nbsp; Maybe it won't.&nbsp; Who knows?<br /><br />What really happens, most of the time, is that Eclipse will compile the class, then, for reasons I can't imagine anyone understands, it rebuilds the entire .war file for your whole project, then copies the war to the deployment directory of the server.&nbsp; Then the server reloads completely, exploding the war, and restarting everything.&nbsp; The entire process is maddening and can take several minutes, for every change, no matter how insignificant.<br /><br />I say "most of the time" because a lot of the time, for no apparent reason, things just don't work.&nbsp; Something won't get included in the war file, despite no changes to the configuration for your project.&nbsp; Some dependency gets left out.&nbsp; Some resource file doesn't get copied.&nbsp; Sometimes the war file gets rebuilt, but not redeployed, or not reloaded.<br /><br />When any of these things happen, you find yourself going through this stupid litany of things to try to get the damn tool to do its job.&nbsp; Clean the server.&nbsp; Clean all projects.&nbsp; Restart the server.&nbsp; Update Maven dependencies.&nbsp; Restart Eclipse.&nbsp;&nbsp; A single-line code change can turn into a 20-minute ordeal trying to get the damn server to reflect your change so you can see its results in a browser.<br /><br />Most infuriating about having to go through all these insane steps is that there's no definite action that causes WTP to fail; there's nothing one can avoid doing to avoid going through all of these things.&nbsp; As far as I can tell, the bed-shitting is completely random and utterly nondeterministic.<br /><br />No doubt some of the trouble comes from the m2eclipse plug-in.&nbsp; In fact, I suspect that a good 60% of the problems I experience overall in Eclipse are a direct consequence of something stupid in m2eclipse.&nbsp; Of course we wouldn't need m2eclipse if Eclipse had acceptable Maven support built-in.&nbsp; But it doesn't.<br /><br />What's so baffling about this whole situation is that it hasn't improved!&nbsp; In the 5 years since WTP was initially released, the user experience has not improved one iota.&nbsp; The cycle time with JBoss can still easily be several minutes per change (when WTP isn't completely going batshit as outlined above).<br /><br />Surely in 5 years' time, this piece of braised crap could have been made some small degree more stable so as to be actually useful, and a time-saver rather than a time-suck.<br /><br />I can't believe we're still writing web applications like this and it's almost 2011. <br />]]>
        
    </content>
</entry>

<entry>
    <title>Everything Conservatives Need to Know they Learned in Kindergarten</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/10/everything-conservatives-need-to-know-they-learned-in-kindergarten.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.8</id>

    <published>2010-10-14T18:49:30Z</published>
    <updated>2010-10-15T03:55:26Z</updated>

    <summary><![CDATA[Many of us learned many important life lessons in Kindergarten: don't fight, take your turn, share, be polite, etc.&nbsp; Some kids inadvertently learned the wrong lessons, however, and grew up to become right-wing conservatives.&nbsp; Here are some of the lessons...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Many of us learned many important life lessons in Kindergarten: don't fight, take your turn, share, be polite, etc.&nbsp; Some kids inadvertently learned the wrong lessons, however, and grew up to become right-wing conservatives.&nbsp; Here are some of the lessons they learned:<br /><br /><ul><li>If someone looks or sounds different from you, pick on them.&nbsp; Get your friends to pick on them too.</li><li>In a disagreement, whoever shouts the loudest wins.</li><li>Often times, you can break the rules and not get caught.</li><li>If you do get caught, you can always blame someone else.</li><li>Name-calling is funny, and your friends will laugh with you.</li><li>If name-calling and shouting don't get you what you want, try pushing, shoving, or hitting.</li><li>It's better for people to give you what you want because they're afraid of you than because they're your friends.</li><li>Hoard all the best toys for yourself.</li><li>Cut in line.&nbsp; You need to get there before anyone else.&nbsp; Make alliances with people who will let you cut.</li><li>If the teacher catches you doing something wrong and you're punished, blame the teacher and say bad things about her.</li><li>Prove it?&nbsp; You don't have to!</li><li>Milk, cookies, and naps are the best things in the world.</li><li>If at first you don't succeed, keep doing the same thing over and over again, and scream until it works.<br /></li><li>Speaking of which, you can take an extra cookie; why should you care if that means someone else can't have one?</li><li>If you pee on the floor, someone else will clean it up.</li><li>Girls are yucky!&nbsp; They're not as good as boys.&nbsp; Boys are better.</li><li>If a classmate has something you like, wait til he's not looking, and then steal it.</li><li>When you lie convincingly, it's your word against someone else's, and you can get away with it.<br /></li><li>You can show other boys your wee-wee in the restroom.</li><li>When all else fails: temper tantrum!<br /></li></ul>]]>
        
    </content>
</entry>

<entry>
    <title>What Kitty Will Eat When She Won&apos;t Even Eat Tuna</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/09/what-kitty-will-eat-when-she-wont-even-eat-tuna.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.7</id>

    <published>2010-09-29T03:48:51Z</published>
    <updated>2010-09-29T04:05:23Z</updated>

    <summary><![CDATA[Ace kitty's medicine tends to make her lose her appetite, so much so that sometimes she wouldn't even eat tuna.We discovered something that she *would* eat, even when she didn't want tuna though: Vietnamese meatloaf.&nbsp; Really.&nbsp; You can find it...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="cat" label="Cat" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="giòlụa" label="Giò Lụa" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="appetite" label="appetite" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="feline" label="feline" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Ace kitty's medicine tends to make her lose her appetite, so much so that sometimes she wouldn't even eat tuna.<br /><br />We discovered something that she *would* eat, even when she didn't want tuna though: Vietnamese meatloaf.&nbsp; Really.&nbsp; You can find it at most Asian grocery stores.&nbsp; It comes in a big dark-green tube-shaped package and says "Giò Lụa" on it.&nbsp; We slice it up into a very thin slice (maybe 1/8" thick) and then dice it and put it on the edge of a paper plate for her.&nbsp; (She likes to step on the plate to hold it down while she munches.)<br /><br />Hope this suggestion helps someone out there who is having trouble getting their cat to eat when she doesn't want to.<br />

<div style="margin-top: 10px; height: 15px;" class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://www.zemanta.com/" title="Enhanced by Zemanta"><img style="border: medium none; float: right;" class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_e.png?x-id=6e173d1e-73ce-4dc0-827b-35bf9349a90b" alt="Enhanced by Zemanta" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>]]>
        
    </content>
</entry>

<entry>
    <title>How to Give a Pill to a &quot;Difficult&quot; Cat</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/08/how-to-give-a-pill-to-a-difficult-cat.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.6</id>

    <published>2010-08-24T00:20:13Z</published>
    <updated>2010-08-24T00:52:43Z</updated>

    <summary><![CDATA[My cat was once diplomatically called "difficult" by her vet. "Difficult," of course, is code for "seriously bitchy."&nbsp; We suspect that Ace Kitty is some part feral/working kitty; I seem to recall being told when I got her that her...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="catfelinepillhowto" label="cat feline pill how-to" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[My cat was once diplomatically called "difficult" by her vet. "Difficult," of course, is code for "seriously bitchy."&nbsp; We suspect that Ace Kitty is some part feral/working kitty; I seem to recall being told when I got her that her mother was a farm cat.&nbsp; What this ends up meaning is that Ace will stop at nothing to defend herself if she feels threatened, up to and including clawing your arm off and eating your soul for breakfast.<br /><br />It does no good to explain to a "difficult" cat that what you're doing to her is for her own good.&nbsp; The difficult cat is not interested in your explanations.&nbsp; Yet, you love her, and she loves you when it serves her purposes, so you've got to get this damn pill in her.<br /><br /><b>Step 1:</b> Get a "pet piller" or "pill gun" that has a soft rubber tip and puts your hand at a considerable distance from the end.&nbsp; I was advised by Ace's oncologist that the solid plastic ones are worthless, and I believe her.&nbsp; You can find the soft rubber ones on Amazon and probably not in any pet store on earth.&nbsp; I checked every single last one of them in San Mateo and ended up having to order online.&nbsp; <b>Do not attempt to give the difficult cat her pill by hand</b>, at least not if you value your hand.<br /><br /><b>Step 2: </b>prepare the area where you will give your cat her pill.&nbsp; You don't want her to have a lot of space to run around and hide under things.&nbsp; Walk-in closets work well.&nbsp; You want a space that is quiet where there's room enough for you to sit comfortably, cross-legged on the floor.&nbsp; Lay out a large bath towel directly in front of where you plan to sit.<br /><br /><b>Step 3: </b>get everything ready, but <b>make sure the cat doesn't notice</b>.&nbsp; This is critical.&nbsp; Cats are smart, and will quickly associate sounds and behaviours with what happens next.&nbsp; Therefore either distract the cat with something, have your spouse/partner distract the cat, or just be really stealthy.&nbsp; Do not let on what you are about to do.&nbsp; If you need gloves to handle the pill, put them on now.&nbsp; Put the pill in the pill gun, and prepare a small syringe (no needle obviously) of 2-3cc of water.&nbsp; Place the pill gun and the syringe to the right or left side of where you will sit, depending on whether you are right or left handed.<br /><br /><b>Step 4: </b>retrieve and prepare cat.&nbsp; The quicker you complete this step, the better.&nbsp; Take her into the space.&nbsp; Sit on the floor with your ankles crossed in front of you.&nbsp; Throw the bath towel across your legs.&nbsp; Put cat between your abdomen and ankles on top of the towel.&nbsp; Flip the edges of the towel over the top of the cat so that you get a kitty burrito with her head exposed.&nbsp; If you do this step right, the cat can't back up, because she'll run into you, and she can't jump forward because your ankles are there and she's wrapped in a towel.<br /><br /><b>Step 5: </b>everybody get calm. This includes you.&nbsp; This is perhaps the hardest step, but don't skip it.&nbsp; Scratch your kitty's ears, rub her chin, give her a kiss.&nbsp; Take a deep breath.&nbsp; Talk to her sweetly.&nbsp; She'll appreciate the tone of your voice, and the more calm <i>you</i> are, the more calm she will be... for a difficult cat.<br /><br /><b>Step 6: </b>position the cat's head.&nbsp; You can use two hands to get the initial positioning, but eventually you're going to hold her head with your non-dominant hand's thumb and index finger.&nbsp; Using your non-dominant hand, grab the sturdy cheek bones just under the beastie's eyes.&nbsp; <i><b>Rotate</b></i> her head away from your hand- if you're right handed, you're using your left hand, and rotating kitty's head to the right.&nbsp; As you rotate, turn her nose toward the ceiling.&nbsp; Try to get her looking as far up as you can, but looking straight up isn't essential.&nbsp; Rotating to have her look up is essential.&nbsp; You want to be able to see the teeth along one side of her mouth, and she isn't going to like being yanked straight back.<br /><br /><b>Step 7: </b>get the pill into the cat's mouth and clamp it shut.&nbsp; This is hard, but you can do it.&nbsp; Using the soft rubber tip of the pet piller, part kitty's cheeks so you can see the gap in her teeth directly behind her sharp, menacing canine tooth.&nbsp; This is your target. &nbsp; If you can get the piller to go through this space, she will automatically open her mouth.&nbsp; When she does, <i>work quickly!</i>&nbsp; Get the piller tip back into her mouth, push the plunger <i>swiftly</i> with your thumb, withdraw the piller and with the middle and/or ring finger of the hand you're using to hold the cat's head, clamp her jaw shut and hold it.&nbsp; Whew!<br /><br /><b>Step 8: </b>along the same spot where you got the piller in her mouth, slowly and steadily drizzle 2-3 cc of water from the syringe to make her swallow.&nbsp; Some sites say blowing in the cat's nose will make her swallow, but do you really want your nose that close to the difficult kitty's sharp teeth right after you stuck a pill in her mouth?&nbsp; I don't think so.&nbsp; It doesn't work anyway.&nbsp; But swallowing water does.<br /><br />If at this point, the cat spits out the pill, go back to Step <b>5</b>, and try to get the pill further back in her mouth next time by getting the piller in more deeply or pushing the plunger harder/faster so it pops back in there deeper.&nbsp; <br /><br /><b>Step 9:</b> begin saying the name of your cat's favorite treat, and take her to have some.&nbsp; Don't skip this step!&nbsp; The more consistently you reward your beastie for taking her pill, the easier it becomes (gradually).&nbsp; The key here is to begin saying "treat!" or "tuna!" or whatever, right away, so the cat builds an association between taking her pill and getting a treat.<br /><br />Through trial and error, I've figured out what works for Ace Kitty.&nbsp; That is not to say that it's become <i>easy</i> or <i>simple.</i>&nbsp; It's still difficult, just like her, but it's not impossible.&nbsp; We still have an occasional frustrating experience.&nbsp; She still manages to spit out her $4-a-pop pill half the time.&nbsp; But we do manage to get it in her each time.&nbsp; You may have to adapt these suggestions to get something that works for your critter.&nbsp; Good luck!<br />]]>
        
    </content>
</entry>

<entry>
    <title>Flood Insurance: A Most Annoying Gamble</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/07/flood-insurance-a-most-annoying-gamble.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.5</id>

    <published>2010-07-21T15:20:32Z</published>
    <updated>2010-07-21T15:54:51Z</updated>

    <summary><![CDATA[Like a large number of homes in the San Francisco Bay Area, the home I share with my partner lies in a 100-year flood plain.&nbsp; This doesn't mean it floods every 100 years.&nbsp; It means that every year there's a...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="fema" label="FEMA" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nfip" label="NFIP" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flood_insurance" label="flood_insurance" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="national_flood_insurance_program" label="national_flood_insurance_program" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Like a large number of homes in the San Francisco Bay Area, the home I share with my partner lies in a 100-year flood plain.&nbsp; This doesn't mean it floods every 100 years.&nbsp; It means that every year there's a 1% chance of a flood.<br /><br />To get a mortgage in an area that could flood, it's mandatory to carry flood insurance, and with the best of intentions to help people with flood insurance rates that would otherwise be cost-prohibitive, the federal government established the National Flood Insurance Program, which falls under the FEMA umbrella.<br /><br />One doesn't purchase insurance directly from NFIP; you still buy it from an insurance broker, but they're all reselling NFIP policies, so they will all quote exactly the same rates.&nbsp; Presumably they get some commission out of the deal.<br /><br />I say "rates" because there's actually magic behind the insurance rates that ordinary mortals such as myself cannot understand, and there are no tools available to make the rates easier to comprehend and more practical to predict.&nbsp; When you first ask for flood insurance, you are quoted the maximum possible rate.&nbsp; This is because NFIP defaults to automatically assuming the worst about your situation. That's probably a reasonable default posture.&nbsp; The problem is that very little detail is provided about how the rate is derived and no detail at all is provided regarding how it could be improved.<br /><br />If you're lucky, they'll tell you about Elevation Certificates.&nbsp; Elevation Certificates "might" lower your rate, they'll say.&nbsp; An Elevation Certificate basically certifies the elevation of the bottom floor of your house and whether that floor is above the flood elevation for your area on the map.&nbsp; So if, for example, the flood elevation is 7 feet (that is to say, the level water might reach is 7 feet above sea level), you'd want the bottom floor of your house to be above 7 feet.<br /><br />Oh, but there are caveats.&nbsp; Most homes in the area have crawlspaces beneath them.&nbsp; And to NFIP, your crawlspace, if it is below the flood elevation, is a basement until proven otherwise.&nbsp; They don't tell you this at first.&nbsp; No, first you spend $500 to have a surveyor or civil engineer come to your property, take measurements and mail you an elevation certificate. <b>Then</b> they tell you that for your crawlspace to be a crawlspace (and not a basement), you need to have as many square inches of vent space as you have square feet of crawlspace.&nbsp; In other words, if your crawlspace is 1600 square feet, you must have 1600 square inches of venting (and they can't all be in the same wall of course).<br /><br />The other thing they don't tell you is about attached garages.&nbsp; If your garage is attached to your house, there's a chance you might use your garage for something other than merely storing your vehicle.&nbsp; And this is probably true for the vast majority of people, so it is not an unreasonable assumption.&nbsp; Your garage, too, must contain as many square inches of venting as it has square feet of space.&nbsp; Luckily the venting can be in the garage door(s), but it must be there.&nbsp; 500 square feet of garage?&nbsp; 500 square inches of vent openings.<br /><br />Now let's suppose you got burned on your first elevation certificate which you were told could make your rate as low as $556 but instead you were stuck with the $1983 price because your crawlspace, unbeknownst to you is actually a basement, even though you spent $500 to have a civil engineer take the measurements and issue the certificate.&nbsp; And let's suppose that you made the upgrades to your home, adding vents to the crawlspace and the attached garage.&nbsp; The upgrades themselves are cheap-- vent covers are inexpensive, and if you have the tools you can make the adjustments yourself fairly easily in a weekend or two.<br /><br />Then comes the moment of truth- do you spend $200 more to have the civil engineer come back out, count the new square inches of vents and issue a new certificate to give to the NFIP people?&nbsp; Before you did this, you might want to verify with your insurance company that this time, Charlie Brown, this time you'll get to kick that football and save a lot of money ($1400!) each year on your flood policy.&nbsp; The flip-side is that you might spend $200 and have absolutely no change, miss the football, and land flat on your back, having wasted $200 and still having the default worst-case-scenario rate.<br /><br />You might think, "hey, I'll give my insurance company a call and ask them to run the numbers for me."&nbsp; That's a reasonable thing to think.&nbsp; After all, when you're car shopping, you can have the insurance company run numbers for you for hypothetical scenarios-- different makes and models of car, different levels of coverage, etc.&nbsp; You can even do this for other types of home coverage, such as fire damage, checking different deductibles, coverage for personal items, etc.<br /><br />Not so with flood insurance.&nbsp; It's a black box.&nbsp; It's opaque.&nbsp; The answer you get back is "your rate could be as low as $556 with an elevation certificate."&nbsp; It's the same answer you got the first time, before you wasted that first $500.&nbsp; You cannot get a hypothetical rate based on values you intend to update on your elevation certificate or values you might have already updated.&nbsp; You have no way of knowing if that $200 might lower your rate $1400 a year, or if it might do absolutely nothing.<br /><br />Neither the NFIP nor the insurance carrier has any motivation at all to 
help you lower your premiums.&nbsp; It cuts into the program's income and the
 insurance broker's commission.&nbsp; The end result is that, ironically, 
you're punished for doing the responsible, right thing-- trying to 
upgrade your home to make it less likely to incur damage in the event of
 a flood.<br /><br />It's a gamble.&nbsp; A most annoying gamble.&nbsp; If you're like me, you'd gladly spend $200 to save $1400... but you hesitate when there's no assurance whatsoever that your $200 might end up saving you $0.<br /><br />Which brings me to where I am this morning-- trying to get some answer out of my insurance carrier.&nbsp; All I want is for them to tell me that with the new numbers, my premiums would come down (versus the generic answer about having an elevation certificate that I know now to be only half the truth).&nbsp; They won't do it.&nbsp; It's eternally frustrating.&nbsp; Now I must decide if I'm going to ante up again.<br />]]>
        
    </content>
</entry>

<entry>
    <title>HTC Evo 4G</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/06/htc-evo-4g.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.4</id>

    <published>2010-06-21T15:09:34Z</published>
    <updated>2010-06-21T17:20:21Z</updated>

    <summary><![CDATA[When my trusty Nokia 6650 Flip phone started giving trouble, I knew I was going to be in the market for a new phone soon.&nbsp; And since the service I'd been receiving from AT&amp;T had progressively worsened almost the entire...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="sprinthtcevoandroid" label="sprint htc evo android" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[When my trusty Nokia 6650 Flip phone started giving trouble, I knew I was going to be in the market for a new phone soon.&nbsp; And since the service I'd been receiving from AT&amp;T had progressively worsened almost the entire duration of my contract with them, I knew I was also going to be in the market for a new cellular provider.&nbsp; AT&amp;T represents the worst possible corporate attitude I can imagine, having <a href="http://gizmodo.com/5428717/att-has-spent-less-on-network-construction-every-quarter-since-the-iphones-launch">spent <b>less</b> on their network infrastructure in each quarter</a> following the introduction of the wildly-popular iPhone 3G.&nbsp; Rather than, oh I don't know, <i>fixing</i> their damn network, they opted instead to adopt policies to discourage usage, eliminating the "unlimited" plans, and going so far as to introduce a femtocell product to help offload traffic from their network onto customers' own Internet connections <b>yet charging them for the privilege</b>.&nbsp; Of all the confounded arrogance...<br /><br />I decided I'd get a cheap, crappy 3G phone from eBay to limp myself along until I could get something better, so I ended up using an LG Shine for a while.&nbsp; While the LG had decent acoustics, it really sucked as a "smart" phone.&nbsp; It wasn't even able to sync the calendar or contact list with a PC (let alone a Mac) or even browse the file system on the SD card.&nbsp; AT&amp;T had never updated its firmware, in typical AT&amp;T "yeah, it sucks, but you'll take it" fashion.<br /><br />Along about this time I heard about the upcoming HTC Evo 4G phone from Sprint, the first 4G phone to major marketing in the US.&nbsp; Many years ago I had Sprint Broadband service in the Bay Area, which Sprint horribly oversubscribed to the point that it became effectively unusable during peak periods.&nbsp; To their credit, Sprint stopped accepting new subscribers and announced it was investigating other technologies for delivering wireless broadband, and we're finally now seeing the results of that effort.&nbsp; Though I hesitated to do any business with a company based in goddamn Kansas, Sprint also has scored a <a href="http://www.hrc.org/issues/workplace/organization_profile.asp?organization_id=1427&amp;search_id=1&amp;search_type=Quick">100% on the HRC Corporate Equality index</a> , perhaps making them a good influence in an otherwise horrible place.&nbsp; I decided to limp along with AT&amp;T until the Evo came out.<br /><br />Now mind you, I'd still have another 6 months on my AT&amp;T contract at the time of the Evo's introduction, but by this point I hated AT&amp;T Wireless <i>so much</i> that I was only too willing to pay their early termination fee <i>just to be rid of them, permanently.</i><br /><br />I found that I could get a discount via work on a pair of Evos for myself and my partner, which almost made up for Sprint's bullshit "premium data add-on" fee.&nbsp; Sprint has caused quite a bit of commotion over this $10 monthly charge.&nbsp; I suspect the reason is that their CEO, Dan Hesse, told an audience that Sprint would not be charging extra for 4G access, and in fact that it was actually cheaper for the company to provide 4G than 3G.&nbsp; Also, Sprint does not have 4G access in all its markets yet, and won't for some time.&nbsp; So they can't come out and say that the $10 fee is for 4G speed.&nbsp; They also have a problem in that the plan they're marketing already provides "unlimited" data.&nbsp; So they can't really say the $10 is for unlimited data either.&nbsp; So they decided to call this fee a "premium data" fee, which is ambiguous enough of terminology that nobody can really say what the fee is for or what it provides.&nbsp; Look for a class-action lawsuit regarding this fee at some point in the not-too-distant future.&nbsp; I'm fairly sure at some point, Sprint is going to have to eat crow on this one.&nbsp; But even with the $10 "because we can" fee, the plan is still cheaper than AT&amp;T, so for the time being I'm thinking of this as the $10 "because we're not AT&amp;T" surcharge.<br /><br />The phone arrived while I was out of town participating in AIDS/Lifecycle 9.&nbsp; Funnily enough, during the ride my LG phone decided that it just wasn't going to charge the battery anymore, and I ended up having to fork over a little more money to AT&amp;T on the cheapest possible pay-go phone so I could be available to other ride volunteers and stay in touch with people back in the "real world" with whom I needed to stay in touch.<br /><br />When my partner picked me up at the airport after the ride, he brought my Evo along so I could play with it on the way home.&nbsp; He was also using his Evo at the time, operating as a speaker phone, plugged into his car stereo.&nbsp; Cool!&nbsp; <br /><br />The Evo's user interface is mostly intuitive, especially if you've ever handled an iPod Touch or an iPhone.&nbsp; Many of the same concepts are repeated.&nbsp; Many are improved upon.&nbsp; I particularly like the Evo's ability to fully configure each of the phone's primary screens for the tasks you perform most often and applications you use most frequently.&nbsp; There is also support for "widgets" on the screens, for stuff like clocks, weather, enabling/disabling features on the phone, etc.&nbsp; I haven't had any other Android phones to know, but I suspect these are standard Android features.<br /><br />The OS gets into a bit of trouble when it comes to the things you use less frequently.&nbsp; The applications installed on the phone are all in one giant pile, which is perhaps OK if you know the name of the application you're looking for and don't have a great many applications installed.&nbsp; It becomes a bit more cumbersome if you have to scroll through the list and can't remember if that app is called "Google Voice" or just "Voice."&nbsp; Some kind of hierarchical representation would be really nice to have.&nbsp; At least then I could separate "Communication" apps from "Entertainment" apps from "Games."<br /><br />There are also some glaring omissions from the apps that come with the phone by default.&nbsp; For example, there's no file manager.&nbsp; Fortunately, there is no shortage of apps in the Android Market (called just "Market" in the giant pile of applications) to perform this task admirably.<br /><br />The touch-screen interface mostly does what I want it to do.&nbsp; I haven't had the sensitivity problems a few people have complained about when the phone is not being held in a hand.&nbsp; Nor have I experienced any "separation" of the glass.&nbsp; (I'm beginning to suspect that these problems are much ado about nothing, and curiously they are mostly gleefully spouted by Apple fanboys.&nbsp; More on that later.)&nbsp; I have experienced a few times, especially in the contact list, that the phone will "click" something when what I really wanted it to do was to scroll.&nbsp; I'm not sure if the iPhone and iPod Touch do this, but one thing available in addition to the traditional tap and double-tap is the "tap and hold", which often behaves analogously to a "right click", giving you contextually-appropriate options for a particular item, or on the main screen, giving you the option of adding an item.&nbsp; Again, these may be Android things and not specific to the Evo.<br /><br />The only real "bug" I've noticed so far is in adding custom ringtones for contacts.&nbsp; Some hints here-- enter the phone number for your contact without any punctuation or spaces, and if it still doesn't "take", hard-boot the phone.&nbsp; There may be some bad cache management or failure to refresh a data structure happening under the hood here.&nbsp; Hopefully that's fixed in the next release of code?<br /><br />Call quality is excellent, especially compared to AT&amp;T.&nbsp; HTC's acoustics are perhaps some of the best I've experienced on a cellular phone, rivaling and perhaps even besting Nokia.&nbsp; The codecs used by Sprint's CDMA (EVRC by default) just sound better than AT&amp;T's implementation of GSM too.&nbsp; People sound a bit less robotic and the dynamic range is much better.&nbsp; I have experienced a little choppiness from short (5-10ms) repeating dropouts in some calls, but it wasn't bad enough that I've had to ask the other person to repeat what was said.&nbsp; Vocal nuance is important to communication, and I always felt that AT&amp;T's GSM codec (rumoured to be AMR Half Rate) lost a lot of nuance and made it more difficult to mentally process a caller's voice.<br /><br />Image quality from the 8 megapixel rear-facing camera is excellent, far better than other phones I've owned.&nbsp; Though the flash comes from two white LEDs, these LEDs flash <i>brightly</i>, and the camera software seems to know how to compensate for the slightly blue tint that white LEDs invariably have (something I could never say for my Nokia 6650).&nbsp; HD video is smooth and clear.&nbsp; The rear camera also seems to have real focus, rather than the fixed focus found on many phones.&nbsp; The quality from the tiny front-facing camera isn't as good, though it is likely one would ordinarily only use this camera for video calls, which are likely to be scaled down and compressed so much that it won't be the camera that's the limiting factor but rather the codec and the bandwidth.&nbsp; Video on the phone's large display is bright, clean and clear. <br /><br />Battery life is... satisfactory, but your mileage may vary, quite a lot.&nbsp; If you're keeping the phone in your pocket much of the time, pulling it out to check your calendar, look things up on the web, and make the occasional phone call, then no sweat.&nbsp; The battery may last you a couple days between charges.&nbsp; If, however, you're making heavier use of the phone, using the GPS, a number of applications, email, YouTube, porn, watching or recording videos, taking a lot of photos, etc., then you're going to want to buy yourself a car charger; you will find yourself needing to charge the phone at night and probably once during the day.&nbsp; Keep in mind that what you're carrying around with you is effectively a handheld <i>computer</i> that has phone capability.&nbsp; The more you play with it, the more it is going to drain the battery.&nbsp; Fortunately, the Evo is only too happy to charge itself from any USB port, and the charge time is relatively quick.&nbsp; It also seems to hold a charge for longer after the battery has cycled a few times.<br /><br />By far the <i>best</i> feature of the HTC Evo 4G is how steaming <i>mad</i> it makes Apple fanboys, specifically the cult of the iPhone.&nbsp; The iPhone 4G is only just now starting to ship, and it is already lacking in terms of features and capabilities relative to the Evo, and it is still encumbered by AT&amp;T's crappy network.&nbsp; If you get an Evo, be prepared for all the Apple fanboys you know to blither on about the few-and-far-between problems of the Evo, 4G, or Sprint while ignoring the failings of Apple, the iPhone, and AT&amp;T.&nbsp; Honestly, you could paint a goat turd glossy white, stamp an Apple logo on it, and they'd line up at 4AM for the first chance to own one.&nbsp; I sincerely enjoy owning a phone that runs circles around the iPhone and does it on a network other than AT&amp;T's, if for no other reason than knocking down the fanboys a peg or two.<br /><br />Overall, this is a great phone, the best I've ever had in all the phones I've owned since my first crappy analog bag phone with a giant camcorder battery circa 1994.&nbsp; Well done, Sprint, HTC, and Google.<br />]]>
        
    </content>
</entry>

<entry>
    <title>AIDS/Lifecycle 9 Day 1</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/06/aidslifecycle-9-day-1.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.3</id>

    <published>2010-06-07T04:38:37Z</published>
    <updated>2010-06-07T04:50:46Z</updated>

    <summary><![CDATA[Today I woke up at 4:40 AM after having slept perhaps an hour or two, grabbed a 5-hour energy shot, and staggered to the shower.&nbsp; The plan was to get out of the house by 5, but an alarm clock...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Today I woke up at 4:40 AM after having slept perhaps an hour or two, grabbed a 5-hour energy shot, and staggered to the shower.&nbsp; The plan was to get out of the house by 5, but an alarm clock malfunction on the part of my teammate delayed our departure slightly (he was blissfully asleep when it was time to get up, but scrambled really well).<br /><br />We arrived at the Cow Palace around a quarter to six, did the opening ceremonies thing, and then the real fun began.&nbsp; The massage team enhanced ride-out with 24 small bottles of "celebration bubbles"... the kind given as party favors at weddings.&nbsp; I think those cost me about $5 at Big Lots, but they brought so many smiles to so many faces that it was perhaps the best $5 I've ever spent.&nbsp; It's amazing what soap bubbles do to grown adults.<br /><br />It was Fiesta day in the massage tent, and it was boiling hot all day.&nbsp; Day 1 is a slow day for us; since participants get only one massage for the week, most choose not to get it on the first day.&nbsp; This is okay, actually, since it gives our team a little time to settle in.<br /><br />I got some great body work from Patrick (and dozed off during it), and a nice sacro-iliac joint tweak from Chiropractic.&nbsp; I'll probably be seeing them again on Day 3.&nbsp; Every year my left SI joint locks down, and it seems like this year will be no exception.&nbsp; Maybe it's the fire line method of loading and unloading our truck that does it to me.<br /><br />Here's a picture from the massage tent.&nbsp; I'll try to get more/better pictures tomorrow.<br /><br /><a href="http://spatula.net/mt/blog/assets_c/2010/06/IMG_0755-1.html" onclick="window.open('http://spatula.net/mt/blog/assets_c/2010/06/IMG_0755-1.html','popup','width=1024,height=768,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://spatula.net/mt/blog/assets_c/2010/06/IMG_0755-thumb-640x480-1.jpg" alt="IMG_0755.JPG" class="mt-image-none" style="" width="640" height="480" /></a><br /> <div><br /></div><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>I&apos;m so not ready for this</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/06/im-so-not-ready-for-this.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.2</id>

    <published>2010-06-04T06:36:47Z</published>
    <updated>2010-06-04T06:46:05Z</updated>

    <summary><![CDATA[AIDS/Lifecycle 9 is a mere 3 days away now, and for all intents and purposes it begins Saturday with orientation day (aka "Day Zero").&nbsp; I haven't even started packing yet.Fortunately I took tomorrow off, figuring I'd need to run around...]]></summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    <category term="aidslifecycle" label="AIDS/Lifecycle" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[AIDS/Lifecycle 9 is a mere 3 days away now, and for all intents and purposes it begins Saturday with orientation day (aka "Day Zero").&nbsp; I haven't even started packing yet.<br /><br />Fortunately I took tomorrow off, figuring I'd need to run around some, and I made pretty good headway tonight getting the schedules for the tent and the individual team schedules set up in OpenOffice.&nbsp; This year I'm <b>not</b> laminating the tent schedules, because it just takes too long and we immediately throw them away after one use.&nbsp; Instead, I'll print them on card stock and we'll put them in sheet covers.&nbsp; The individual team schedules get printed on business cards and I will laminate those.<br /><br />Tomorrow I have to find my lotion bottle and holster, wash sheets, pack sheets, begin packing all my other goodies, set up my netbook to tether to my phone, go thrift store shopping with my friends and teammates Tom and Chokae for costume bits that we still need for our theme days, deal with some last-minute AIDS/Lifecycle Captain business at the Cow Palace, pack everything... and maybe find time in there somewhere to eat and drink.<br /><br />Saturday it's up bright and early to pick up Tom and head to Day 0 early so we can get our roadie-on.&nbsp; We have to watch a safety video, handle tentmating, check in, visit the camp store for any exciting new swag... then there's a Captains' Meeting, followed by an all-roadies Meeting, followed by the massage team meeting... which will be the first time my whole crew will be together in one place.<br /><br />Then we scatter, go home, finish packing, and Sunday morning, we get up around 4:30 to be at the Cow Palace by 5:30 to start this crazy week...<br /><br />...and I'm soooo not ready for this... but excited nonetheless.<br />]]>
        
    </content>
</entry>

<entry>
    <title>Moving to Movable Type</title>
    <link rel="alternate" type="text/html" href="http://spatula.net/mt/blog/2010/06/moving-to-movable-type.html" />
    <id>tag:spatula.net,2010:/mt/blog//2.1</id>

    <published>2010-06-01T23:30:07Z</published>
    <updated>2010-06-03T23:32:10Z</updated>

    <summary>Since Blogger decided they&apos;d stop supporting remote publishing via sftp, I&apos;ve decided to stop using blogger and start using MT. Huzzah....</summary>
    <author>
        <name>spatula</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-us" xml:base="http://spatula.net/mt/blog/">
        <![CDATA[Since Blogger decided they'd stop supporting remote publishing via sftp, I've decided to stop using blogger and start using MT. Huzzah.<br />]]>
        
    </content>
</entry>

</feed>
