Blog

Mmm, Qualified job leads.

I am… aquiver with excitement over this position. It’s just what I’ve always wanted to do, particularly at this point in my career!

Date: Fri, 5 Sep 2008 10:17:50 -0400 (EDT)
From: Peter@REDACTED.com
Subject: $15.00/hr - 1 Day (Sept 10th Wed) Worcester PC TECH
Hi Dave,
      My name is Peter REDACTED and I'm a recruiter at REDACTED Computer Corporation.
Our records show that you have expertisereflecting  work that I have available at my direct
client. 
The details are: 
WED SEPT 10TH IN WORCESTER
PC IMAGE DEPLOYMENT (SYMANTEC GHOST)
$15.00/PER HOUR W2
MUST BE ABLE TO PASS A BACKGROUND CHECK.
If you are still available, interested, and/or planning to make a change, or know of a friend who
might have the required qualifications and interest, please PLEASE EMAIL ME YOUR MS
WORD RESUME TO peter@REDACTED.com  even if we have spoken recently about a
different position.
When you respond, please include a daytime phone number so that I can reach you.  In
considering candidates, time is of the essence, so please respond ASAP.  Thank you.
Sincerely yours,
Peter REDACTED
REDACTED Computer Corp, Inc.
Note: Please allow me to reiterate that I chose to contact you either because your resume had
been posted to one of the internet job sites to which we subscribe, or you had previously
submitted your resume to RMS. I assumed that you are either looking for a new employment
opportunity, or you are interested in investigating the current job market.
If you are not currently seeking employment, or if you would prefer I contact you at some later
date, please indicate your date of availability so that I may honor your request. In any event, I
respectfully recommend you continue to avail yourself to the employment options and job
market information we provide with our e-mail notices.
Thanks again.
Peter REDACTED
New York, NY 10036

Perl GRRRR.

Warning. I’m ranting. I’m annoyed. I’m frustrated. You might want to put on your rant-proof galoshes before proceeding.
Ready?
Perl should be considered a Write-Only Language.
Code that is written in it is generally incomprehensible by anyone but the person who wrote it. It’s great for one-offs, quick simple jobs, and low-scope tools. But anyone who says it’s appropriate for an enterprise level application (and I mean anything over about a thousand lines) should be strung up, draw, quartered, glued back together, and shot into space.
The main problem is Perl is so weakly typed, it should be considered not to have any. That means that parameters passed to methods are not type-checked, and therefore there’s no way to tell if you’re calling a method correctly, except to see if the app blows up when you run it. Editors and IDE’s cannot magically determine that “such and such a method requires an integer, a string, and a hashmap containing such and such values. You’re doing it wrong.”
Because of this weak typing and lack of structure, Perl libraries become worthless. Let’s leave aside the fact that Perl OOP implementations are complete and total trash (OOP is designed to organize your data into object form, and stabilize how components are used, defining a rigid structure so that when you use the component, you must use it correctly). In the case of libraries, it’s impossible to use a library unless you understand how it works. Libraries are not self documenting, they don’t even have a standard method of organization. They’re just loose collections of Perl code, again, with very little defined structure.
Therefore, people who come along to maintain code after the first person has suffered the above fate has no clue how a method is supposed to work, unless the original coder documented it, or built in type checking in their code. I have seen NO Perl code that actively makes sure the parameters being passed in are of the correct type. At best, they make sure the parameter are not null. And if they’re super-advanced, they even use prototypes.
And yes. I am in the unenviable position of maintaining thousands upon thousands of lines of undocumented, badly maintained, incomprehensible Perl code. Yes, the developers could have documented, formatted, and put the code into a form that’s easier to maintain. But they didn’t, and to me that’s the languages fault, not the developers. A language should have some element of maintainability, and not require the programmer to make up for it’s inherent ambiguity. If it does, it’s doubling the burden on the programmer. They not only have to write the code, they have to document it, and make it maintainable.
In my opinion… Perl by its very nature encourages sloppy organization and unmaintainable code.
And now, back to the trenches.

My iPhone – 2 weeks on.

Taking a break here to chatter a bit about my iPhone. Catya and I got ours at the same time, and I have to say, it’s been a pretty nifty experience all around. The iPhone is pretty much the first ‘quasi-perfect’ melding of handheld computer, telephone, and portable internet device I’ve ever used.

I’ve named mine ‘speicus’, a reference for you Roger Zelazny fans. It’s really more of a companion than my Treo ever was. I have it hooked to my 2 email accounts (work and home), and viewing / responding / filing mail works perfectly, whether I’m on the 3g network or on a local WiFi connection. I love not having to carry an iPod around around for music. Not to mention having a web browser that is powerful, well supported, and fast, and there are volumes of applications coming through the AppStore that keep things interesting.

However, naturally, it has it’s faults. I wouldn’t be a blogger if I didn’t gripe and groan about things, so here’s my current ‘stuff that is aggravating me’ list…

  • Contacts
    The Contact manager is quite powerful. I was able to sync it against my Google Contacts via Outlook (bleah), and all 400 contacts came into the phone just fine. The problem is that it’s SLOW. Pulling up my Contacts list and scrolling it can take 7+ seconds to get started, that’s just plain too long.

  • SMS
    I text a lot. The SMS interface is good, but it’s hard to get to – it’s just a normal icon in the program listing. You can shortcut the one useable button on the phone to get somewhere quickly with a double tap, and I have that set to go to my favorites in Phone, but to get to an SMS conversation, I have to tap Home, scroll to the first window, tap SMS, and then select which convo I want to participate in. Startup of the SMS app is also quite slow, sometimes taking 4-5 seconds to come up.

  • Buttons
    I applaud the design of the iPhone. The screen is a joy, touch sensitive, multitouch, fast and beautiful. There are 5 external controls (Home, Volume up/down, Silence, and Close (?)). The last 4 have fixed, non-changeable functions,and the Home button is required to always be Home, but has 1 programmable function (double-tap). IMHO, a button on either side of the home button would have been a huge win. They could have been reassignable, and having shortcut access to certain well used applications would be great.

That’s it. For 2 weeks of heavy usage, these are really the only things that have made me go “grr”. If I were pressed for another problem it might be the battery life. But really, the volume of things this device is doing, from internet connections to bluetooth to playing games to playing music, coupled with easy charging via USB cables, I’m okay with having to plug it in once a day to recharge it.

My first store-bought new Apple product, and I’m impressed.

Vacation, Geeking, Code, and MySQL

I think I just made up for my lack of productivity toward the end of last week.
Database Fixes
I had been totally stymied by a problem in the CONGO rewrite – how to handle state of a registrant in a way that didn’t involve scanning history logs and essentially replaying an audit each time. The real stumbling block was defining exactly what states a registrant could be in.
Going by a recent event, it appears there really is a situation where someone may have signed up to work up to attending an event, but hadn’t actually completed the registration yet. In early version of CONGO, we called this ‘subscribed’. It caused all sorts of havoc in the larger events, because there should never have been a situation where someone was subscribed, but not registered.
Cept, it kept happening. The counts of people subscribed compared to the counts of people registered would drift, but in weird ways, and also in ways that were hard to source, due to the funky way CONGO v1 was calculating state of the registrant.
All of this is going away now, with a directly updated and maintained reg_state table that underwent some major surgery tonight. I introduced reg_state to help with this ‘what is the current situation of this person’ question that arises constantly. Apparently, though, I never quite completed tuning it. To wit:
o The table was a MyISAM table, rather than InnoDB
o It had no foreign key indexes at all
o It was not tracking subscription status at all (the logic was ‘if they were in the table, they were subscribed’
Etc etc. That’s all fixed now, and logic was introduced to automatically toss the registrant into the reg_state table whenever they were looked up in the current event. So they’re added, but NOT subscribed, that can be done later, but their state is no longer non-deterministic.
Layout Schmayout. Just show it
Well, not so much. The ShowRegistrants.jsp file may be my number-one edited file in the whole project. It’s the one that determines what the ‘registrant zoom’ screen looks like – probably the most viewed page in CONGO. And I keep fiddling with it. I’m currently trying to cut down the number of pushbuttons on it, and organize them in a useful way. It’s frustrating work, because I’m not really a UI designer. I’m sure I’ll good solid feedback from the CONGO power users out there. I hope ya’ll like it. *worry*.
The next step is attaching the reworked status display with functions (like ‘subscribe’ ‘register’ and ‘print badge’). These new hooks really change the workflow of the application, but I think it’ll be for the better.
Unfortunately, I’ve just gotten a poke that the next major event to use CONGO may be going live in about 10 weeks with pre-registration, so I have a hard deadline now for when v2 really needs to at least be in basic useful form. I really don’t want to deploy the old version again, so maybe this is a good kick in the pants to work toward a functional version in a reasonable timeframe.
Yeah, but… Vacation?
So, I did mention vacation up there. This weekend I’ve been up at the house in Maine with the family and the water and the woods. I suppose it helped to get away from the code for a few days, because sitting down tonight definitely got things rolling again. It’s the last ‘official’ day of the summer-vacation-house season, so we did things like pull the sailboat and power boat out of the water, put the docks away for the winter, and cleaned out the freezer. There’s always some meloncholy associated with labor day because of this. The weekends spent up here during the summer are great, and we had a wonderful time this summer. On the flipside, we’ll start having weekends back at home, which will primarily be taken up with packing for the move to Mosaic in a month or two, but I’ll still miss the mornings waking up to loons calling and the calm still lake out our windows.

Weekblog: Day 3 – Baby steps!

Another night of hax0ring, with not as much progress as I’d like, again. This time though it was mostly distraction as opposed to actual problems getting in the way. I did finish up the DAO for the Notes, and note creation and updating is working correctly. I’m having a little problem with auto-populating the TIMESTAMP columns, but I’ll figure that out. I’m just glad Struts is playing nice with the DAO and Doing The Right Thing [tm]

Oddly, I’m sort of daunted by the next steps, which are going to really start impacting the workflow in CONGO – making direct changes to how Notes are handled, how registrations are managed, and how history is kept. Up until now, things have been pretty much duplicating functionality (or at least adding to existing limited functionality). But I’m looking at rewriting the Registration page and how history and status are being kept. This is at the core of how CONGO works – the very reason that, with something like 50,000 registrations having been run through the software since it’s first rollout, we haven’t corrupted a single table, or ended up with a mysterious situation where a users status is wrong or lost in a way that was not easily determined.

I’ll get past this, I know, but it still makes me nervous.

On the “face of the future’ front, though, we have the emerging view of what the database will look like. This first image is the old view of CONGO’s tables. No foreign keys whatsoever, that means only programmatically enforced referential integrity.

Here’s what my working v2 table structure looks like. I’ve only been working with address contacts and notes so far, as well as conference master data, but it’s all starting to tie together as it should. By the way, these images are generated via dbVisualizer, an awesome generic SQL database tool that has a free mode that’s extremely useful (and includes ERD diagrams like this 🙂

Bit by bit, I’m moving forward.

Weekblog: Day 3 – The JDBC Whubbidah huh?

Today, durnit, I was going to get some work done. I specifically scheduled time after $dayjob to spend working on CONGO v2, and ya know what? I actually did it!

Tonight’s joy was parking at the Panera in Marlborough, plugging in the iPhone for music, and getting down to coding. With the network being twitchy in the restaurant, I actually had about 2 hours of uninterrupted focus time to code, and I was productive!

I finished up much of the underlying work on the Notes system (the DAO and Data object are done), and was working on wiring up the Notes interface into Coconut (the web front end). One of my goals with this whole project is to upgrade how I’m managing database resources, and doing things ‘properly’. For instance, CONGO v1 had absolutely no referential integrity mechanisms in place. No foreign keys of any sort. This meant I could easily have had orphaned data in many of the tables, there was just no way to tell.

The first step to setting up proper RI is to use foreign keys to link one table to another. The newly formed Notes table now has foreign keys linking to the reg_master table (which holds registrant master information). I did learn a couple basic concepts while doing this though. For instance, if the source of a key reference is null, then the foreign key constraint is not checked (handy!). If it has any other value, it must have a corresponding key in the target table. I found out quickly that specifying source columns as NOT NULL in the database scheme wasn’t going to work, particularly on columns that get populated later.

The other thing I wanted to fix was date handling. I had a mishmash of DATE column types and raw text fields storing dates in the old version. MySQL (and most databases) have a handy column type called TIMESTAMP that can not only store time down to fractions of a second, but also support basic math operations (“Show me all rows that have been modified in ‘now() – 3 HOURS’ is a valid construct).

Here’s the problem though. MySQL DATETIME columns cannot be null. So what if I don’t have a date to put into the column yet? Well, the docs say the schema should say ‘colname TIMESTAMP DEFAULT 0’ – I did this, and it seemed to take. But when I tried to retrieve the row in my DAO, I was getting this error:

java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 6 to TIMESTAMP.

The offending line causing this was (‘where’ is a Note object, postDate is a java.sql.Timestamp, and ‘fromwhat’ is a ResultSet):

where.postDate = fromwhat.getTimestamp("note_postdate");

I completely and totally don’t understand this. I’m wondering if this is a bug in the JDBC driver I’m using, or what, but I should not be trying to load a date in the format 0000-00-00 into the java.sql.Timestamp object. It should be returning NULL, and therefore ‘postDate’ should be null, as it was when it was created.

I ended up having to code logic around it to say basically “Don’t try to load the note_postdate value unless circumstances can guarantee there was a value there.” I tried various approaches for ‘Is this column going to be null?’ – but it really appears as if the JDBC driver is delivering a Timestamp object, even though the source is null.

It gets a little better. In the MySQL docs, they say, as I mentioned above, that the declaration for a TIMESTAMP without a value should be ‘default 0’. But after I create my tables from my schema (using that syntax), and then do a ‘SHOW CREATE TABLE reg_notes’, lo and behold, I see:

CREATE TABLE `reg_notes` (
`note_id` int(8) NOT NULL auto_increment,
`note_rid` int(8) NOT NULL default '0',
`note_cid` int(8) default NULL,
`note_postrid` int(8) default NULL,
`note_ackrid` int(8) default NULL,
`note_postdate` timestamp NOT NULL default '0000-00-00 00:00:00',
`note_ackdate` timestamp NOT NULL default '0000-00-00 00:00:00',
`note_message` varchar(100) default NULL,
KEY `id` (`note_id`),
KEY `rid` (`note_rid`),
KEY `note_cid` (`note_cid`),
KEY `note_postrid` (`note_postrid`),
KEY `note_ackrid` (`note_ackrid`),
CONSTRAINT `reg_notes_ibfk_1` FOREIGN KEY (`note_rid`) REFERENCES `reg_master` (`master_rid`) ON DELETE CASCADE,
CONSTRAINT `reg_notes_ibfk_2` FOREIGN KEY (`note_cid`) REFERENCES `con_detail` (`con_cid`) ON DELETE CASCADE,
CONSTRAINT `reg_notes_ibfk_3` FOREIGN KEY (`note_postrid`) REFERENCES `reg_master` (`master_rid`) ON DELETE CASCADE,
CONSTRAINT `reg_notes_ibfk_4` FOREIGN KEY (`note_ackrid`) REFERENCES `reg_master` (`master_rid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Observant folks may note that the note_postdate and note_ackdate columns now have default values of ‘0000-00-00 00:00:00’. Not what I specified in my creation SQL.

I’m past this now, and it’s working, but if anyone has ideas about why this is behaving this way, I’d love to hear it. It’s damned frustrating.

UPDATE 08/28/2008 – Through the magic of RTFM and some nudges from Imre, my table definition was wrong… Here’s what it should be:

note_postdate TIMESTAMP null DEFAULT null,
note_ackdate TIMESTAMP null DEFAULT null,

This little bit of MySQL fun is in fact documented, it’s just buried in the TIMESTAMP page on dev.mysql.com

Weekblog: Day 2 – or ‘That didn’t go as planned’

As the title says, yesterday hardly went as planned, as evidenced by me just getting around to posting at 9:30 this morning.

The Geekery. It is everywhere!
First, the day was full of IT-related geekiness, trying to get SASL authentication working on the the mail gateway for the Greater Homeport Server Cluster. What should have been an hour long setup and fiddling turned into a 6 hour “Learn what SASL is, learn what TLS is, learn how Postfix manages it, learn how Cyrus implements SASL, learn how to set up standard authentication, and learn how to do this all on an extremely busy mail gateway without killing all inbound mail” process.

In the end, we were only partially successful. The main impetus for this setup was making it so Cat and I could send mail from our iPhones without using Googles SMTP gateway (if you have a gmail account, you can use SASL authentication and send mail from anywhere via smtp.google.com. The drawback? Any mail going through that gateway gets it’s From: line rewritten to the gmail account ID.)

We got most bits working, except for finding out at the end that v2.0.2 firmware on the iPhone has a problem with self-signed certificates on TLS-enabled mail servers (but this is only for SMTP connections – Safari et al has no problem with self signed certs. Annoying). One assumes Apple will be fixing this soon, but it means we can’t have encrypted inbound mail connections from the iPhone. Adam has suggested there is a list of certs that free and Apple certified, I may end up going that route.

Oh yeah, and about the project I’m supposed to be working on…
But that’s not what I came here to talk about.

The point of this week’s blogging was to get focused on CONGO v2 and make some progress on getting toward an Alpha release. To accomplish this, I need to get 2 hours or so a night of fairly focused work time.

Last night I failed.

The main culprit? Lack of sleep. I went out to dinner with my mom last night (mm, steak!), and ended up getting home around 8:30. Not too bad, thought I, I still have a couple hours before bed. Flopped down on the couch, had the laptop out, tossed a movie in, and started work and… fell asleep right on the couch. An hour and a half later, I woke up (now about 10;30), was immensely groggy, and decided “Right, that’s it. Bed.” and flopped right into bed, sleeping like the dead til 8am this morning. Total sleep time? About 10.5 hrs. How I feel today? Stiff, but caught up.

Unfortunately, this meant I got only a minimal amount of work done on CONGO last night. I fixed some of the Notes DAO setups, and started work on modifying the ShowRegistrant functions to enable the notes browsing. I’m trying to decide if the Notes listing should be attached directly to an instance of a Registrant, which means it gets populated whenever a Registrant is instantiated. This really only happens on single views (ala, getting a list of Registrants from a search query doesn’t load the entire Registrant, just an index), so it shouldn’t make things too burdensome. It has the advantage of making everything easily accessible if you have the Registrant at hand. Right now a registrant’s attendance history is attached on instantiation (for Arisia, this is perhaps 20 rows, but that’s somewhat unusual). If I don’t embed the list in the Registrant object, I’ll need a second set of lookups and queries when viewing a registrant, which is a little cumbersome.

For now I think I’ll embed it, and hook up the DAO’s appropriately. It’ll make the display logic a lot easier (data is at hand), and if we end up beating the bejeezus out of the database for largish events, I’ll look at optimizing it.

Conclusion
Onward and forward. Today I need to focus on the paying job and finish up an annoying script, hoping to get it audited and approved by the other engineer. Have I mentioned that Perl is not my favorite language? Oh there is a rant pending…

Weekblog: Day 1

I didn’t get as far as I had hoped to tonight, due to a variety of distractions – it was an impressive list of “things that get in the way of previous plans” (Work actually had work for me to do, then a stop by the Mosaic work site to check on some supplies, then dinner, then home to find the freezer has stopped freezing (due to a broken icemaker), then helping out Cat with some finance stuff so we can get our Mortgage application in. Ung!

Finally I sat down, and with The Time Machine on as background entertainment (not so good a movie – great for background noise – and what the heck is with Jeremy Irons? Is there no movie so bad he won’t act in it? Sheesh) – I got down to work.

There were some great comments from yesterday on how to handle historical triggers on database updates. There’s some challenges to using triggers (such as “who made this update?” – though using a ‘last updated by’ column on every record could fix this, I’m still not sure if it’s a good idea). Jonah pointed out also that using database triggers limits the portability of the database layer. Given that MySQL isn’t going anywhere, and that it’s getting more and more attention as an enterprise-level database system, I’m not that worried about it, but I am taking that into consideration.

Tonight though I needed to find something short term to work through, so I focused on how ‘notes’ are applied to registrants. In the past, I would make a “NOTE” entry in the history table. These NOTEs could be anything from just an informational note by the operator (“This person was nice”) to something important (“Paid by check”). Having NOTEs in history was “okay” but without filtering, it was hard to see operator comments in a meaningful way.

I also had a concept of ‘NOTICE’ records. These are essentially NOTEs to be displayed to the operator whenever a registrant logged in. They would show up as red messages on the registrant detail screen, and the operator would have to acknowledge the NOTICE before proceeding (that’s the theory – in fact there was no logic to enforce this). These NOTICEs were very, er, noticeable to the operator, and were great for things like “DO NOT ADMIT THIS PERSON UNDER ANY CIRCUMSTANCE” (yes, we had a few of them, and I know of one instance where the CONGO ‘NOTICE’ record actually did prevent them from entering the event. Yay!). Generally though they were used for innocuous things like “STILL OWES $25” or the like.

For v2, I’m seperating out the NOTICE / NOTES into a separate table simple called ‘Notes’. The option to making any note entry a ‘notice’ will be on the note creation, and it’ll just be a flag on the record. Also the record will keep track of when the note was created, and by whom, as well as when it was acknowledged, and who acknowledged it.

The basic DAO structure is there, as is the data object, and I’ve created the schema file for it as well. Nothing is wired in yet, but I’m also still noodling around how I want the record to look, so I’m sure there’ll be more work moving forward.

The other bit I did tonight was trying to squash a problem I’m having with the JDBC connection pooling. I’m using the C3PO connection pooling tool, and if CONGO has been idle for a while, I’ll get a connection communications failure. Googling around hasn’t showed me anything immediately obvious, though others have said they’re having the same problem. What I’m trying now is adding some auto reconnection options to the JDBC connection string, so my c3po setup now looks like this:

private void configurePool() {
logger.debug("Empty connection pool, recreating...");
ComboPooledDataSource cpds = new ComboPooledDataSource();
try {
cpds.setDriverClass( "com.mysql.jdbc.Driver" );
} catch (PropertyVetoException e) {
e.printStackTrace();
}
cpds.setJdbcUrl("jdbc:mysql://localhost/congo?autoReconnect=true&autoReconnectForPools=true");
cpds.setUser("root");
logger.debug("Initted.");
applicationMap.put("cpds",cpds);
}

I won’t know if it’s working yet until I idle long enough to force a timeout. I’ll let ya’ll know.

Weekblog: Day 0

Just quick update on this. Last night I did get some coding time in after blog-posting. The fix this time was a problem with Create Registrant that was throwing SQL errors all over the place. Turns out I never actually completed writing the DAO for the Registrant data object, and the create() method was broken in a ton of interesting ways.
There’s still a twitch in restoring the state to the editor after creation – it’s not reloading the new registrant into the sessionspace after creation, so you end up with a sort of ‘blank’ registrant screen. Exiting and coming back shows the new entry, so it is creating it, just isn’t reloading.
I’m sort of worried about keeping history right now. The old code did everything in the history table programmatically – so whenever I made a change to a registrant’s information, I had to make a call to logEntry() to create a new history record. So, naturally, there was some inconsistencies in the logging. It also didn’t help that the history table was critical information. It was part informational, part auditing. In fact, some parts of CONGO used the history table to recalculate statistics and status on registrants. (Note – that is SO not going to be in the rewrite).
Anyway – regarding logging, I’m looking into learning MySQL triggers to have registrant history updated automatically whenever a change happens. That way I don’t have to always remember to put in a logging call. We’ll see if this is viable (for instance, how does the trigger know what the ID of the operator is? The one who is actually making the change?)
Stay tuned. 🙂

A WeekBlog – A Post a Day – CONGOv2

So this week I’m faced with a situation I haven’t had in front of me in, well, as long as I’ve been married… at least as long as I’ve had kids in my life.
This week Cat is up in Maine with Zach. I have my normal work going on during the day, but no commitments for the evenings.
A unique opportunity to be sure.
The Plan [tm]
So here’s what I’m going to do. A few months ago I started work on a complete rewrite of CONGO. The rewrite is underway, and has been getting attention fairly regularly over the last couple weeks, but I need to make the final push to an alpha release.
This week, I will dedicate 2 hours a night every night to continuing work on CONGO v2, with the goal of reaching an alpha-testable version by the end of the week. I will also make a post each night with an idea of where my progress is on the rewrite, and what I’ve accomplished. (I do reserve the right to post the next morning if I’m up until Oh-Dark-Thirty coding and fall asleep in the middle of writing an exception handler.)
Anyone wishing to follow the riveting details of my work, I subscribe to the Commit Early, Commit Often philosophy of source code control, so when I’m working, you’ll see commits firing off pretty quickly. If this sounds interesting, you can sign onto the mailing list, or, if you’re uber-hip, subscribe to the RSS feed.
Yeah? So? Why us?
So why bombard ya’ll with my chattering? Well, I work better with encouragement, or if I know folks care about what I’m doing. Curious about bits of CONGO? Ask! Wanna help out? Give a “wow, kick butt, dude. Go for it” comment or two.
Hopefully I’ll have some work to show for tonight, but if not, stay tuned for truly exciting blow by blow Java coding!

So… shiny…

So, 3 days I’ve had my iPhone now, and I tell ya, it’s hard to put down. So hard I’ve had a hard time finding time to write to the blog about how much I’m enjoying it.

Here’s a couple highlights of my first, realistically, 2.25 days with the phone. It’s a black 16gig iPhone 3G, just to make sure everyone is on board.

  • Within two hours of powering up the phone (20 minutes of which I was driving), I had successfully attached to my SSL IMAP server at home and was reading my inbox, connected to my gmail account, AND attached to the Exchange server at work. All quite seamlessly. The accounts play well with each other, I can set up Fetch or manual updates (so cute having the phone next to me go “chime!” when I get new mail, but for busy inboxes, gets old fast).
  • Getting my Contacts synced from Google Contacts was a little trickier, but iTunes for windows just BARELY had enough functionality to make this possible. But, it sure was nice getting all 400 some odd contacts back into my address book.
  • The iTunes Appstore is wonderful. Many good applications available, and it’s trivial to install them either via iTunes, or directly via the appstore link on the phone.
  • It’s very hard to keep reminding myself this is a 3G, unlimited Data plan unit. Once I got past that mental block I tuned into RadioParadise, hit the streaming 3G feed, and listening to the station all the way home. That’s a 45 minute driving commute, RP didn’t burp once, feeding music to a moving car in Boston at 128kbps. Just too sexy for words.
  • I’ve ordered a simple skin from Gelaskins – I’m constantly afraid of scratching the phone – having some sort of barrier to keep it’s gleaming body away from my pocket change is a must.
  • The keyboard took some getting used to – but with Apple’s smart fingertip placement, AND a very intelligent replacement algorithm that ‘just plain works’ (none of the ‘did you mean This?’ nonsense. 99% of the time it guesses right, and you don’t have to do anything, it just replaces the text for you, after letting you know via a very nice animation that it was doing so).

In short. I love it. I’ve named it Speicus.

More kvelling later.

iPhone over Palm – It has it’s faults, but…

It looks like Cat and I will be getting iPhones. The decision to jump away from PalmOS was pretty much made for my by Palm’s inability to innovate. That article was posted in August, 2007. In response, Ed Colligan, the CEO of Palm, responds with platitudes and vague promises:

Let’s remember that it is very early in the evolution of the smartphone and there is enormous opportunity for us to innovate. We have only just begun to fight!

Well Palm, it’s a year later. And Palm has done nothing with PalmOS. In fact, they have further deepened their relationship with Microsoft, coming out with more and more Windows Mobile devices, and doing nothing to pull focus back to the PalmOS platform.

In the meantime, Apple has gone ballistic with the iPhone.

This posting on PalmAddicts sums it up perfectly for me. The iPhone is not perfect, and I’ve spoken of my concerns before, but Apple is at least addressing the shortcomings in their platform. Unlike Palm, who is simply letting their once beautiful system fade away.

Orson Scott Card – Totally Nucking Futs.

I usually give authors some leeway in their personal lives and opinions. I mean, particularly SF authors are an odd lot, and entitled to their quirks.
I had heard that OSC had some pretty off the wall opinions regarding gay marriage and the like, but this latest rant, published in the July 24th, 2008 “Mormon Times” as an op-ed piece, takes the ‘batshit crazy’ to a new level.
I suggest you sit down and steady yourself with something soothing before reading that piece. There’s hardly a paragraph that doesn’t elicit a “WHAT?!??!” and “That’s a blatant lie” and “You have GOT to be kidding me”, but here’s a taste if you don’t feel like wading through the vitriol. The first paragraph pretty much sets the tone;

The first and greatest threat from court decisions in California and Massachusetts, giving legal recognition to “gay marriage,” is that it marks the end of democracy in America.

Got that? Democracy’s over, kids! Lets head for the caves!
How bout a few more tidbits:

Remember how rapidly gay marriage has become a requirement. When gay rights were being enforced by the courts back in the ’70s and ’80s, we were repeatedly told by all the proponents of gay rights that they would never attempt to legalize gay marriage. It took about 15 minutes for that promise to be broken.

Wait, who? what? Who promised what where? And I hardly remember laws being passed where it was stipulated “We shall not pursue gay marriage!”
It just goes on. Enjoy the humor value of his ravings, and know that in fact there are many people in the world who think this way. Mores the pity.
Thanks to laist.com and Digg for the pointers.

A Way to Kill Some Time – Fantastic Contraption

I don’t recommend going over to FantasticContraption.com unless you have a couple hours you’d care to dispose of.

It’s a puzzle game of sorts, where you can build simple machines consisting of wheels and sticks, then set the machine in motion to accomplish a task. Once the machine starts going, there’s no touching it until it either completes the given task, or you restart.

The game is ‘physics based’, meaning objects behave as you’d expect them to. Balls roll, blocks tumble, and a small vehicle rolling off the edge of a cliff… plummets.

The site also allows you to upload completed machines for each task, and going through other peoples’ solutions to the problem. Some are absolutely fascinating and intricate, involving dozens upon dozens of components.

Thanks (or raspberries, not sure which yet) to blk for pointing this one out to me.

A Quest – Network enabled cheap MP3 player

I’m looking for something, maybe folks can help me out.
I want a small MP3 player that will stream audio over the network. The commercial version is the Roku Soundbridge. I wouldn’t mind building my own, hacking together parts, whatever, but I really haven’t found something that fits the bill.
Here’s the requirements:
* Must stream MP3 from a remote (network) source
* Can be wireless or fixed wire
* Should be small enough to mount on a wall
* Laptop running Linux is POSSIBLE, but only something that could mount / sit in Tablet orientation
* Total cost should be less than $50
* Should have at least a minimal display showing volume, source, and current track
* Line level output (RCA or headphone jack)
* Prefer opensource / linux based, but a commercial solution would work also.
* Should have local controls for pause, next track, volume, but not a requirement
The best configuration I can come up with is a handheld device running Angstrom or the like, but the most baseline iPaq or similar is still $50-$60, and I dont’ have a lot of experience with the current generation of iPaqs.
I’ve also considered picking up a Zaurus SL-5500 or two and using them. They seem to go for a good price on eBay, and certainly are opensource. Good video, touchscreen, and can take an SD card for network.
Anyone else have any ideas? There are zillions of opensource MP3 player boards on the web, but none have network interfaces on them (that I could find). I’m open to suggestions!