2011-01-18

Holding back features on the web

If I were to say there's a CSS 3 feature that all major browsers support except one, which browser would you guess is lacking?

The answer for today is Mozilla Firefox.

It has come up several times on my current project where we've needed to take a variable amount of information and stuff it into a limited space, where aesthetics demand we truncate the data instead of allowing an overflow or a word wrap. The typical way to do this is with an ellipsis, but at what point one should truncate the message is usually the result of guesswork. Checking to see if a string is over, say, 35 characters and cutting it off if it is may work in most cases; but because in a proportional font, the same number of characters can be different sizes depending on which actual characters are used, any fixed number will result in some data elements appearing too short, and a few appearing too long and wrapping or overflowing anyway.

Enter the text-overflow style. In a fixed div or span, setting style="text-overflow: ellipsis;" will cause the browser to truncate the contents with an ellipsis if, when, and where it is needed.

Except for Firefox. Since CSS 3 is still technically in "draft", the coders behind Firefox have decided not to implement text-overflow, despite it being on the bug list since 2005. Mozilla's own developer forum shows that Firefox is the only browser to not implement this to date.

Oddly enough, this is the second time Firefox has failed me recently (the first being a misbehaving feature that plays havoc with AJAX queries).

I found two solutions on the web. One is to use something called XUL binding. The procedure (described here) involves creating an XML document that describes the requested behavior, and then using a Mozilla-specific CSS directive to bind it to the element. Unfortunately, not only does this require another document, but it may conflict with the text-overflow style such that only one or the other will work, but not both. Also, following the comments in the bug, XUL appears to be going away with Firefox 4, and with text-overflow still not implemented, this workaround will work no longer.

The second solution uses the JavaScript library jQuery. The function (which I found at Devon Govett's blog), when applied to a web element, takes the text, recreates it in a clone of the element, starts truncating text as necessary until it finds text that fits in the element, and replaces the text in that element. It's not terribly efficient as it iteratively tests the text on each element, and if the element can change size you either have to update it manually or tell the script to constantly check the element and recompute; but it does do the job that Mozilla won't. Fortunately, we're already using jQuery, so adding an extension was a trivial task.

I don't know if it's some higher ground they're trying to take by not implementing "draft" features, but the fact remains, as an end user of browsers, to me, they appear to be stubbornly behind the curve.

2011-01-14

ASP.Net, Dynamic Controls, and ViewState, revisited

At my current job, we are encouraged to share tips and ideas with other developers. I thought it could be useful to demonstrate the problem of dynamic controls and ViewState and my solution (posted three years ago here), since it not only is a problem that could come up in our web development, but it provides a useful opportunity to review the page life cycle.

So I grabbed my sample code and opened it in Visual Studio 2010. The good news is, it still works as advertised. However, I wanted to demonstrate the problem along with the solution; so I removed all my "extra" code. I was rather startled to find that the old problem didn't manifest itself. When I typed in data to one control and clicked a button to add another, the first control retained all its data.

It seems that the .Net Framework got some improvements over the years. The first improvement is that it seems ASP.Net is far more consistent in naming controls that are added to the page at run-time. (Part of the original problem was, when a control was loaded on page load vs. later in an event handler, the dynamically-assigned ID would be different.) The second is, if a control is loaded later in the life cycle, it does actually go back to the ViewState and re-load any applicable data. (It used to be very unreliable in this regard.)

I did find that things were not all roses. If you add a bunch of controls and start removing controls from the middle of the list, control data would get lost. Also, if you delete controls in the middle of your list and re-add controls, the controls may get added in the middle of the list instead of the end.

The solution is much easier than it used to be:

  • Create a member variable to hold the list of IDs (or whatever data is required to recreate the control and its ID) — in this example, I'm using private List<string> _childControlIds to just store the IDs, since the control type and location is always the same constant.
  • Create a Page Load event handler that looks like this:
    private void Page_Load(object sender, EventArgs e) {
     if (!IsPostBack) {
      _childControlIds = new List<string>();
      addAField(null).InitializeNewControl(); //Optional - create a new control, and initialize its data
     } else {
      if (ViewState["ControlCount"] as string[] != null) {
       _childControlIds.AddRange((ViewState["ControlCount"]) as string[]);
      }
      foreach (string controlId in _childControlIds) {
       addAField(controlId); //Create an existing control with its already-established ID
      }
     }
    }
  • The addAField method looks like this:
    private CustomChildControl addAField(string fieldId) {
     CustomChildControl cc = (CustomChildControl)LoadControl("CustomChildControl.ascx");
     if (String.IsNullOrEmpty(fieldId)) {
      cc.ID = String.Format("CUST{0}", DateTime.Now.Ticks); //new control; create a unique ID
      _childControlIds.Add(cc.ID);
     } else {
      cc.ID = fieldId; //existing control; reuse ID
     } 
     this.CustomControlsPlaceHolder.Controls.Add(cc);
     cc.DeleteControlClick += new EventHandler(DeleteCustomControl);
     return cc;
    }
    Notes:
    1. It no longer appears to be necessary to add the control before setting its ID — the ViewState manager seems to pick it up just fine either way.
    2. The custom control in my example has its own delete control and fires an event, that this page subscribes to. Your implementation may vary.
  • The DeleteCustomControl method looks like this:
    private void DeleteCustomControl(object sender, EventArgs e) {
     CustomChildControl cc = sender as CustomChildControl;
     if (cc != null) {
      _childControlIds.Remove(cc.ID);
      this.CustomControlsPlaceHolder.Controls.Remove(cc);
     }
    }
  • The method to add a control (in my case, a button on the page) is simply:
    private void AddButton_Click(object sender, EventArgs e) {
     addAField(null).InitializeNewControl(); //Create a new control, and initialize its data
    }
  • And finally, a Page PreRenderComplete event handler (because it's late enough in the page lifecycle; PreRender itself may be sufficient for your needs) that sticks the control ID list in ViewState:
    private void Page_PreRenderComplete(object sender, EventArgs e) {
     ViewState["ControlCount"] = _childControlIds.ToArray();
    }

And that's it. Surprisingly simple.

I don't know at what point this changed (or if I even over-architected the original solution — a distinct possibility). This could be an improvement in .Net 3.5, or it could be something "fixed" in a service pack along the way. The only thing I can say for certain is this much simpler method works quite well in my admittedly simple example.

2011-01-01

2010 Bandwidth

I haven't been posting monthly bandwidth numbers, mostly to distract from the fact that the majority of my posts lately were the monthly bandwidth numbers, and that's just boring. But I haven't stopped keeping track.

2010 proved out what I expected. Since we got rid of paid TV, we have been relying on Netflix for the majority of our video entertainment. The use of this has increased over the year, as we've not only become more comfortable using the service, but the number of offerings of the service has increased as well. Add to this the fact that more videos are available in HD, and it's no wonder that my monthly data usage has only been going up.

There are also other items that account for the increase. A large number of file transfers to support our website design business accounts for some of this. Also, we bought a Blu-ray player that has the capability to stream YouTube videos, of which the kids have taken advantage as a substitute for more traditional Saturday morning cartoons.

The year-over-year view is rather dramatic:

The largest-use month in 2009 was surpassed by 75% of the months in 2010, and the second-highest month of 2009 was exceeded by all of them. Comcast's measurement was consistently lower than mine, although they were only 8% off in December. It was November when, finally, we reached the halfway point of a monthly cap.

The numbers are likely to only go further up. I don't see any change in this trend. Content providers are continuing to innovate and use the bandwidth we have. Netflix's increase in HD offerings is one example. Microsoft recently updated the Xbox to use a higher quality encoding for voice communication, which, although only provides a modest increase in bandwidth, is just another example.

All this still leaves me wondering, when will general use and content innovation use up this arbitrary data cap, and turn the number of "excessive" users from what was once claimed to be "a single percent" into the majority? I also wonder if Comcast's policy of punishing those who go over their monthly number will change before or after that happens — or, more cynically, how much revenue they'll collect from fines before they consider changing their policy.

2010-10-28

Thoughts on document reader software

A document reader program should be unobtrusive. When you get a document on your computer that it is supposed to handle, you should just have to double-click on the document, and your operating system should open the associated program. It should do this quickly, without a lot of fanfare. The document is the focus of the user's attention, not the program. There should be nearly no need to open the reader program on its own, without a document; although, a link to the program in an appropriate folder on the Start Menu isn't uncalled for, should such a need arise (e.g., if the user wants to manually check for updates or change default settings for the program, he shouldn't have to find an irrelevant document to open first).

To these points, I say:

Adobe, quit installing an icon to Acrobat Reader on my desktop, without asking, every time you do an update; get rid of the bloat that causes Reader to take half a minute to open a document (running a service or pre-loading half your program into memory when I haven't even opened a document yet is not an acceptable option); and when I say "disable the splash screen", do not ignore that setting or re-enable it and think I won't notice.

Yes, I'm aware of alternatives, such as Foxit Reader, that aren't nearly as bad; unfortunately, I have to keep Acrobat around for those forms and bills that alternatives aren't able to process.

2010-10-24

IntelliMouse Explorer 1.0 in Windows 7

I have an old IntelliMouse Explorer. It's the original version, wired, but still works great. Alongside my Natural Keyboard Pro, it's an old, functional, comfortable piece of hardware that I refuse to get rid of. The replacements that have come along since often fall short in various ways. And, much like the Natural Keyboard Pro and other strong Microsoft hardware input devices from years gone by, Microsoft's software drivers have stopped supporting them.

There's no real reason for them not to work today. The keyboards haven't changed much, except to add or change the extra control keys sprinkled around the standard 121. Mice, even less so; they have the same X-Y directional input, five buttons, and a scroll wheel they've had for over a decade. But if you install the current version of IntelliType or IntelliPoint, they will refuse to detect your older keyboard and mouse; and even though the operating system will use them just fine for standard functions, all the fancy buttons and the ability to remap them (that used to work on older versions of the software) won't be available.

I came across this blog post on Blogfeld.com that describes in detail how to get a Natural Keyboard Pro to have full functionality in Vista and Windows 7. I followed these instructions earlier this month, and I can verify that they work flawlessly with the current version of IntelliType software (currently version 8). I thought maybe the same technique could be applied to get my old IntelliMouse Explorer to work with IntelliPoint 8 as well.

I won't post the details here — Blogfeld already does an excellent job at describing everything — I'll just indicate what I did to apply his technique to IntelliPoint.

I searched for an old version of IntelliPoint off of Microsoft's download site. You can still download IntelliPoint 5.2 from their site (link as of the time of this post is here, but you can search for "IntelliPoint 5" on download.microsoft.com to find it) and installed it on a Windows XP workstation in order to get the old files.

On the Windows 7 machine, I opened up the point64.inf file (IntelliPoint's version of IntelliType's type64.inf — and yes, I'm using 64-bit; the 32-bit version would naturally be point32.inf), and in the [MsMfg…] section, I added the following string to the block of IDs listed:

%HID\Vid_045E&Pid_001E.DeviceDesc%=HID_Filtr_Inst, HID\Vid_045E&Pid_001E

Further down in the [Strings] section, I added:

HID\VID_045E&PID_001E.DeviceDesc="Microsoft USB IntelliMouse Explorer (IntelliPoint)"

The next step was to modify the IPointDevices.xml file. This one required a little more thought, as IntelliPoint 5 did not have an IPointDevices.xml file to copy from. I noticed, however, that the IntelliMouse Explorer 3, which is supported in IntelliPoint 8, has the exact same configuration as the IntelliMouse Explorer 1. So, I found the <Device> section that describes the IntelliMouse 3, copied it, and pasted it to the end of IPointDevices.xml. I changed the <Name> node to read, simply, "IntelliMouse Explorer", changed the <OemAbbreviation> node to "IME", and changed the value under <HWID Type='PID'> to read "0x001E" (the last four characters of the USB ID, used in the point64.inf file above). I also had to change the ID in the <Device> node itself to something that was not used elsewhere in the file — '10' was good enough.

I followed the rest of the instructions from Blogfeld, and sure enough, it worked great. The configuration screen in IntelliPoint uses the images of the IntelliMouse Explorer 3, and it allows configuration of all five buttons and the scroll wheel, including per-application settings, like any other mouse it "officially" supports.

2010-10-20

Firefox + Ajax + Refresh = Disaster

Usually, when coding a web page that's targeting users of IE and Firefox, the browser that's going to cause the lesser amount of problems is Firefox. So I was genuinely surprised when I came across a bug reported for Firefox only that came down to what I consider the browser misbehaving.

The requirements for our app included a series of dropdown boxes, where the selection a user makes in one dropdown drives the choices that appear in the next one (what's commonly referred to as a "cascading dropdown"). For a nicer user experience, this is typically done with AJAX, so that the request/response that generates the second dropdown upon selection of the first doesn't require an entire page refresh. ASP.Net makes this really easy with the UpdatePanel control. Controls inside of an UpdatePanel can be refreshed without reloading the entire page. It's not as lean as a pure AJAX call could be, since the server reprocesses the whole page, but the coding time is greatly reduced.

Our environment includes a standard master page that includes a ScriptManager component (required for using UpdatePanels) and the following script:


<script language="javascript" type="text/javascript"> 
    function onEndRequest(sender, args) {  
        ajaxPostBackButton.disabled = false;  
        var error = args.get_error();  
        if (error != null) {  
            window.location = "../errorPage.aspx";  
        }  
        var updateProgressPanel = $get("<%=this.UpdateProgressPanel.ClientID %>");  
        updateProgressPanel.className = "HideObject";  
    }  
    function onBeginRequest(sender, args) {  
        var ajaxPostBackButtonId = args.get_postBackElement().id;  
        ajaxPostBackButton = document.getElementById(ajaxPostBackButtonId);  
        ajaxPostBackButton.disabled = true;  
        var updateProgressPanel = $get("<%=this.UpdateProgressPanel.ClientID %>");  
        updateProgressPanel.className = "DisplayProgressLayer";  
    }  
    var ajaxPostBackButton;  
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onBeginRequest);  
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);  
</script> 

The script, in essence, binds a couple of functions to the AJAX start and stop methods that do this:

  • On start:
    • Disable the control used to trigger the AJAX call (this helps guard against double-posting)
    • Show a div that contains a "loading" animated gif to let the user know something's happening
  • On end:
    • Enable the control used to trigger the AJAX call
    • Check for an error, and if found, redirect the browser to the standard error page
    • Hide the div with the "loading" gif

Now, if the user makes a selection in the first dropdown, everything runs normally, and the second dropdown appears. If the user then presses F5 to refresh their browser, the browser reloads the page from its initial load state, i.e., with the first dropdown with the initial "Please select…" option selected, and no second dropdown.

At least, that's the way it works in IE. In Firefox, what I was seeing was, the first dropdown was getting selected to the option I had selected before I hit refresh, it was disabled, and there was no second dropdown.

Finding out why was no easy task. With the help of Firebug, I was able to show that, on refresh, neither the onBeginRequest nor the onEndRequest methods were being called, and those were the only places the dropdown's enabled state was being tinkered with. I could only conclude that Firefox itself was setting this state. But why, and how do I stop it?

A couple hours of internet searching on why a dropdown in an UpdatePanel would be disabled failed to yield any useful information. I did find one user complaining about Firefox repopulating form values with prior input on refresh; unfortunately, that user's request for how to get around it was met with a snarky response about how it was a useful feature of Firefox and how the user was mentally deficient for not appreciating it. Sorry, but when you're coding a web application that is trying to control the content of form values and states and react to changes, and the browser breaks all rules and changes those states without raising any events to react to, I'll have to go with the feature being deficient and buggy.

Coming at the problem the next day with a fresh set of search terms, I came across this blog post: Firefox refresh viewstate updatepanel bug hell!!! The post describes a more serious error that can occur with Firefox's mucking about with a form after refresh that got updated with AJAX. The solution, renaming the form's ID on every refresh, seemed a little more of a brute-force hack than I wanted, and he mentions it doesn't work well in a master page scenario anyway (which we're in).

The comments on that post, however, point to an article on developer.mozilla.org that describes the feature in more detail and, more importantly, how to turn it off. By adding the nonstandard attribute autocomplete="off" to the page's <FORM> tag, it suppresses this bothersome behavior and lets the page work as expected.

We're now determining if this action is something that should be done site-wide (add it in the master page's markup), as it could be an uncaught bug on other pages; or if it's something that should be done on a page-by-page basis, by adding this.Page.Form.Attributes["autocomplete"] = "off"; to the prerender event of any affected page.

2010-08-31

Raingutter Regatta racetrack

Regatta side viewAlthough I am not the Cubmaster anymore, I wanted to share this project. In the past, the Raingutter Regatta was a troublesome event. The kids enjoyed it well enough, but for raingutters, all we had were vinyl gutters. It was always a trick to get them elevated, so that the kids could stand and walk beside them, but keep them supported enough so they wouldn't collapse when filled with water. Also, the end caps just snapped onto the gutters, and they never formed a perfect seal; so someone had to be volunteered to keep a bucket filled so the gutters could be refilled as needed. While the kids deal with it well enough, you definitely notice a drop in enthusiasm when they have to wait for the adults to figure out how to shore up a gutter and refill it with water every couple races.

Last summer, I was the Cubmaster, and I got to the church early to start setting up the gutters. I thought I had a bit of an advantage over years past in that we had a new building that had a pavilion with picnic tables. The tables, I figured, would support the length of the gutters and keep them from folding. All I needed to do was support the sides.

As I was filling the gutters with water and trying to figure things out, however, I was blindsided by nothing short of a miracle. Our newly-called Webelos den leader had taken it upon himself to build the project you see in the picture above. (Click the picture to see a couple more images — unfortunately taken from my outdated cell phone.) He pulled up in his truck and asked me to help him unload this large boat from the back. He said he didn't want to say anything before, because he wasn't sure he could finish it in time. Indeed, he had just put some of the finishing touches on it that afternoon.

It was, to say the least, amazing. A length of PVC pipe, cut in half, formed the tracks, which were wide enough to accommodate the hulls of the boat kits we were using (which were simple styrofoam blocks — much lower tech than the Pinewood Derby cars, but much easier for the boys to cut and form on their own). The half-pipes were laid in the top of the wooden form of a large boat. (Last year, the boat did not have the sail; that was something he added for this year.) A drain hole was drilled in the bottom of one end of each track, with a standard rubber drain stopper plugging it up, so the tracks could be easily drained at the end of the night.

We had some minor problems with leaks — because he caulked it earlier that day, it didn't have time to completely dry and seal — but it wasn't anything we weren't used to. There was no worrying about gutters buckling or collapsing, and the legs were sturdy enough to keep it from going anywhere when it got bumped.

It certainly made my day. And the boys', too. That event was easily one of the most successful we had all year.

2010-08-25

I found Microsoft Phone!

Following up to this post, where I ponder what happened to a certain Microsoft software product that seemed way ahead of its time hit the market and disappeared with almost no fanfare.

At my new job, I just got my phone configured. It's an IP phone that plugs into an ethernet jack (and apparently draws power from that jack as well, as there is no other power cord), and once it connected and downloaded all its necessary updates, the IT guy walked me through some of the features.

He directed me to set up my voicemail account. He pressed the voicemail button, and a friendly-sounding, female, synthesized voice announced, "Welcome to Microsoft Exchange." He then gave me a quick overview of the features available, which included the ability to access my email from my phone.

It would appear that Microsoft Phone grew up, moved out of the house, and got a job in the corporate world.

It certainly has come a long way. One of the "cool" features he demonstrated was the voice-activated directory. He pushed "Directory", and the voice prompt asked for the name of the person to call. In his moderate southeast Asian accent, and in a relatively soft voice, he spoke the name of the coworker in a neighboring cubicle. Within a second, the computer repeated the name (which it got exactly right on the first try), asked for confirmation, and then proceeded to dial.

Later, when I set up my voicemail account (setting my own PIN, greeting message, etc.), I experimented a bit. One of the options presented to me was "Calendar". I chose that option, specified "Today" (at which point the computer told me I could just say "Calendar for today" at the main menu to get straight to this point), and the computer proceeded to read to me my appointments for the day.

The voice synthesis was very clear. While it could never compare to seeing the information on the screen where you could glance at any piece of information at will instead of waiting for it to be read to you, it was no different than, say, the difference between reading a book and listening to an audiobook version of the same. All of the commands were done by voice. At no time did I have to repeat a command that the computer didn't hear, nor did it misinterpret any command I gave it; and I didn't speak any louder or exaggerate my pronounciation when I gave my commands. Although, the whole interchange was a little slow, considering I had to wait at the end of each operation for the computer to give me a list of all the things I was "allowed" to say. (I would imagine that accuracy goes way up when the number of possible inputs is constrained.) It was still far easier than the laughable experience I had trying to use voice controls in Windows Vista.

I am a little disappointed that this product does not appear to be available for the home anymore. More than once, I've been away from home and wished I could have easy access to an email when all I had was my phone. However, I think they're probaby dead on in their target market. It seems like people are using their cell phones more than their home computers as their address books and calendars, so the need to "phone home" just isn't there. Those who do access email on the road tend to pay for a data plan for their cell phones, so they can scan through email visually instead of having it read to them linearly — a huge advantage on a home email account that may get email from hundreds of sources, most of it spam that gets through filters. On the flip side, business email accounts tend to be more business-focused (in my experience; YMMV), so hearing unread email can be less of an exercise in "sifting through junk". Also, providing a phone access path to check information means that all employees can access their personal accounts without providing or provisioning VPN accounts, company cell phones, data plans, etc.

2010-08-16

In B4 Unemployment

When I was "downsized", I got some severance pay in addition to my unused vacation time. Because of this, my unemployment benefits were due to not start until a few weeks after my actual termination date.

Today, I started my new job.

I had a few interviews that came down to a couple solid possibilities. Both were very good jobs, and I thought it would come down to a choice between them. While I was waiting to hear a final decision, I spent some time in prayer that I would be guided to the right job. Sure enough, I only got an offer from one company; the other told me my qualifications were perfect, but they decided to go with another candidate who they just "felt was a better fit".

I supposed I should be used to this by now, but I'm still impressed, and thankful, with how Heavenly Father provides a very clear path to what He has provided for me. The path may not always be the smoothest or the shortest, but it's always gotten me where I've needed to be.

2010-08-13

Friday the Thirteeneth Strikes Again

I got a notice in the mail a while back about a recall Toyota is doing on vehicles, including my Prius, for a possibility of floor mats jamming accelerator pedals. Now, I'm more inclined to believe this is more media hype than any actual problem, but as long as it's free, I have free time, and especially since they were promising a free floor vacuuming with the service, I might as well take the car in. So I made an appointment.

I left for the dealer this morning, and my wife promised to leave shortly thereafter in the minivan to pick me up. On my way in, though, I got a call from an upset wife. The van wouldn't start. The battery didn't have enough of a charge to turn it over. This was a new battery, one we bought earlier this year. It should not be dead. Unfortunately, it didn't agree.

Now, fortunately, we have a plug-in battery charger that we got many years ago, so she began charging it while I dropped off my car. Since she was going to be leaving a lot later, I walked over to our next stop, the FedEx center, to pick up a package from my former employer that had apparently already forgotten my correct address. A healthy dose of exercise and still a ten minute wait, and my wife drove by to pick me up.

We were going to get family pictures today, so we went to the shopping center. My wife wanted to stop by the shoe store to get new shoes for a couple of the kids first, so we pulled up there. The baby was still asleep, so I was going to wait in the van. She rolled down the windows and shut off the minivan. While we were unloading, though, the baby woke up. I went to start the car to roll the windows up, but all I got in response was "click click click click click". Despite the 40-minute round trip to pick me up from FedEx and come back to the shopping center, the battery had no charge. And now, we were stranded on the wrong side of the shopping center.

We hiked across the shopping center to get to our picture appointment. Fortunately, it was still morning, so it was not too warm yet; but it was still a decent hike with four kids, slightly uphill, passing a distance that included a full-size Wal-Mart and a Sam's Club (these are not small stores).

Once we got to our picture appointment (on time, even), we started trying to call the phone numbers of anyone we had in our cell phones to see who might be home and who might be able to shuttle one of us home to get jumper cables and to my mother's to pick up her truck.

Getting pictures done, we then went to get lunch at one of the nearby restaurants. While we were there, one of our church friends showed up to drive me to my house and my mother's. At my house, I got my mother's house keys, and then we went to my mother's house. Problem, the house key does not work on the storm door on her front door. It would've let me in from the garage, but I didn't have her garage door opener. We had one in the minivan, but she didn't pick me up from the minivan; she picked me up from the restaurant. (I'm not sure I would've thought to grab the garage door opener anyway.)

Fortunately, she was willing to let us try jump-starting off of her truck. We just had to go back to my house to pick up the jumper cables I forgot to grab. (I was going to pick them up after I got my mother's truck.) And, fortunately more, we weren't inconveniencing her much; through all the driving around, her daughters in the car were lulled into a nap they don't usually get, so she was getting a nice bonus.

Jump-starting the minivan was fairly uneventful, except for the usual problems of trying to get the clamps secured on the terminals and finding a good ground. Rant time: Why don't they make battery terminals longer, so that jumper cables aren't constantly in danger of slipping off the things? And, why don't they make an obvious grounding post for clamping the negative cable? The first place I clamped it was secure, but obviously not a decent ground, as it completely failed to start the car; as soon as I clamped it to a less secure but more obviously metal bolt, the minivan started right up on the first try. Rant over.

We thanked our friend profusely for the ride and vowed not to turn off the minivan for as long as we could. My wife followed me to my mother's, so we could grab her truck. (If we needed to leave the minivan behind while it got its battery replaced, we would need the extra vehicle to get home.) With the garage door opener in the minivan, this was a much easier trip.

We made a long drive to Sears, where we bought the battery, so they could check it out and replace it. Long story short, they were able to replace it while we wandered the store, so we were able to take the minivan home. They said it was in fact a bad battery, and everything else checked out ok. Unfortunately, this not only made the truck unnecessary, having the extra vehicle meant we were unable to simply stop by and pick up my car, which was already done and will now require another extra trip out to go get.

I'm not usually one to consider the 13th of a month falling on a Friday as being anything but a statistical curiosity, but it certainly seemed unlucky today.

Still, it all worked out in the end, and the worst of it was just inconvenience. Annoying, exhausting inconvenience, but just inconvenience.

2010-08-07

Land lines (and their owners) don't deserve to die

Cell phone "elitists" bug me. These are the people who insist that land lines or home phones are relics of a bygone era, and anyone who has a home phone are either simply wasting their money, or refusing to change with the times, or are somehow mentally deficient for not ridding themselves of a land line and going exclusively with cellular phones.

We know a handful of families that have ditched the land line and gone entirely with cell phones. (To their credit, they have been far from "elitist" about it.) Unfortunately, we have encountered some common problems trying to call our cellphone-only friends. These are based on actual, real-life experiences.

  • You have to double (or more) the number of phone numbers you have to know to call the family. You can't just call one number for the family, you have to know the number for the husband, and the one for the wife, and possibly the numbers for any children.

    • Published phone directories will likely not be set up for this and list only one number, which at best will be a 50:50 chance of belonging to the specific family member you wanted to contact; so unless you make a point of getting down everyone's number, you'll consistenly call one family member just to ask for the number of another family member. (While the first family member could simply hand their phone to the second, I've found it's more common they will request you call the second number, so the first phone is still free for calls that are actually for the first person.)

  • You don't know if they are home when you call, and you will end up reaching them at an otherwise inconvenient time (i.e., when they are out shopping, at work, running some other errand, away on vacation).

  • If you don't care whom you contact (i.e., you want to call the family to set up a visit, invite them to dinner, pass them some information about a community event, etc.), you end up having to decide whom you're going to contact.

    • The person you decide to contact will end up being the least convenient person, as they will end up being the one who is out of the house (as above), greatly raising the chance any information you wanted to convey to the family will be long forgotten by the time said person returns home.

  • The cell coverage in the neighborhood isn't great, and the call will end up sounding like tin cans and string (when it's not dropped). This seems to be especially true in our "outer suburbian" neighborhoods, and even more so near certain schools.

  • Even when the desired person is at home, and assuming their phone is getting enough reception, it is not uncommon for someone to misplace their pocket-sized device, or not hear the single ringing phone from elsewhere in the house; and they can easily miss the call for being unable to hear or find their phone in time.

While I could possibly see this working more for singles or couples, it just doesn't make sense to me for families. In order to allow your children to make or receive phone calls at all, you either have to yield "your" cell phone, or shell out the money for their own.

I understand why some people do it. The families we know that have gone to cell phones have done so to save money, and to get away from endless telemarketing calls. Those are certainly appealing reasons — we easily get three times as many unwanted calls on our land line as calls we actually want to take. But in practice, it just makes calling a family unnecessarily complicated, and they are just problems we'd rather avoid. It's not a waste of money, and we're not stupid or living in the past.

2010-07-15

On the Job Hunt

At my place of employment, once a month, we had a "one-on-one" with our boss, a scheduled time where we could talk about how work was going and such. In my most recent one this month, I expressed my concern that the work I was doing was not being recognized or appreciated. The project I had originally been hired on to work on was basically shelved seven months ago (despite the new feature release I had built last year, the special on-site trip I made to a client's site on its behalf, and my work in getting it through Microsoft Certification), and all the work I had been doing on the company's flagship product since then was going unmentioned and undemonstrated at trade shows and in press releases. My boss assured me that my work was important, that it was bringing the product and the company further than it had ever been in years.

Turns out, I was right. Yesterday, very suddenly, I was told I was being let go. The Powers That Be had decided, as a cost-cutting measure, to completely eliminate the project I was hired on for, and, since I was tied to that project (despite the fact that I hadn't worked on it this entire year, except to get it the aforementioned Microsoft Certification, which was done as a cost-savings measure since it would get the company free OS/software licenses), my position was also being cut.

There were so many things I wanted to say, so many arguments I wanted to make, but the decision had already been made without discussion. My boss, who told me the decision was not his, had in his hands my final check and the termination agreement dated for that day. I knew nothing I would say would make the least bit of difference one way or the other. All I could think was that I have a wife and four kids at home, and attempting to say anything would only lead to a useless discussion that would delay my inevitable departure and keep me from finding my next job so I could make sure my family was provided for.

I am tempted to write more, to rant about how I think it's unfair or how I think it was a bad decision (not just because of how it affects me personally); or I could pine for the things that have been taken away from me, the conveniences I had working there; but really, what would be the point? Nothing changes the fact that I need to get my résumé up-to-date and off to recruiters so I can find my next job.

2010-06-24

Installing software: Linux vs. Windows

I wanted to install the MySql Workbench on my Linux development box. My experience only reaffirmed my position that, despite the many advances made over the years, Linux still isn't quite ready for the masses. I list these steps and problems here, not as a list of what could happen, but as a list of things that actually happened to me at least once during this process.

Although MySql Workbench is the product in question here, this could really apply to any piece of software (and, as noted, did apply to more than one of the libraries I had to try to install in the process).

  • First, I went to the download page for MySql Workbench. They had several packages available, but none that corresponded to my particular version of Linux (CentOS 5.5, roughly equivalent to Red Hat Enterprise Linux 5.5). So, it seemed I was bound to compile from source.
  • I downloaded the source package, unzipped it, and ran ./configure. It proceeded to run a bunch of checks on my system, ultimately stopping when it could not find a certain library it considered critical. I checked the package repository (using whatever GUI front-end to "yum" that comes with CentOS), and found it. Although I did have the library installed, I didn't have the library-devel package installed, which I guess is required for compiling programs against it.
  • Development package installed, I ran ./configure again. And the check immediately after the previous library, it failed to find another critical library. Ok, go back to the software installer and… oh dear, it's not there. Search the internet, find a package for RHEL5, and install it.
  • Run ./configure again. Another library missing. Not in the package installer. Search the internet. No pre-compiled package this time; download the source code. Install library from source. (n.b.: This, and any other time I have to "install from source", means going through this whole series of steps/possibilities for that library. And yes, a library can have a dependency on yet another library [or series of libraries] that I have to go find and install, etc.)
  • Run ./configure. Wait, it says the library I just installed isn't installed. locate library; it's in /usr/local/lib instead of /usr/lib. Figure out how to configure pkg-config to include the other directory.
  • Run ./configure again. Another library problem — the version I have installed is too old. Newer version not in the package installer. Search the internet. No pre-compiled package. Download source. Install library from source. Run ./configure again. Still reporting library is too old. Attempt to remove old library from software manager; decide against it when software manager decides it wants to remove a host of other packages that depend on the existing one (as it is unaware of the newer version I just installed). Find the files that tell pkg-config what's installed, and remove the entries for the older version, so it won't see those before it sees the newer version. (n.b.: I discovered I could do this more easily by telling pkg-config to look in /usr/local/lib first, and /usr/lib second.)
  • Run ./configure again. Another missing library. Not in the package installer. Search the internet. No pre-compiled package. Download source. Attempt to compile library from source code, get an error. Search the internet. Find that someone has submitted a patch for that problem. Apply patch. Compile and install library.
  • Run ./configure again. Configuration completes. Attempt to compile. Get errors about missing symbols. Go online, find a reference to the problem and an invitation to join an irc chat room for support.
  • Install irc client and join chat room. Told that the version of Workbench is out of date, and given a link to the next version.
  • Go to link. Binary package is available — for RHEL6, not 5. Download the source. Run ./configure. Find another library that's too old. Download updated library, and updates of the libraries it depends on. Compile and install.
  • Run ./configure. pkg-config finds the updated version of the libraries, but the next check finds the old version, and demands that I uninstall the old version. Decide against it when I see that attempting to uninstall it from the package manager will uninstall over half of the packages on my system.
  • Decide to throw caution to the wind and download the RHEL6 binary package. Software installer complains that it depends on libraries I don't have and/or have old versions of, and it can't automatically find (including an updated version of some of the MySql database files themselves, which I could not accept, as I have to develop against a specific version of the database to provide accurate support); and it refuses to install.
  • Go to MySql download site. Download Windows version of Workbench to Windows workstation. Double-click installer. Enter connection credentials to database running on Linux. Connect successfully.

I like the idea of Linux; I really do. There are limitless possibilities with it. And I am reasonably confident that, if I ever did get this software installed, I wouldn't need to worry about it again. I have a Linux server at home that took me several days to set up, but once I got it running, I've rarely had to touch it. And on the occasions when I do decide to update it, it works pretty magically.

But when it takes two days of my time to attempt to install a utility — and ultimately failing — when I can do the same task (and succeed) on Windows in less than ten minutes (with most of that time spent downloading the file I want), sometimes I wonder if it'll ever make a viable replacement for an OS that, despite all its problems, most of the time "just works".

2010-06-15

A 400-Pound Doorstop

I woke up Sunday morning to my wife asking me for the password to my laptop, so she could put on a DVD for the toddler; and said toddler explaining in great detail how the TV doesn't turn on when you press the button. The TV had served pretty well for 9 years, but lately it had been showing signs of decay — the lower-left corner was perpetually out of focus, the image would very slightly and very occasionally "fuzz" for just a second), but it had finally given up the ghost.

On the one hand, I had hoped it would survive long enough for 3D technology to mature and become the "standard". On the other, if it's going to die, the week leading up to Father's Day, with the corresponding retail sales, isn't a bad time to do it.

Yesterday, we went out to a certain big electronics store known for blue and yellow polo shirts and compared TVs. Because of where we were putting the TV, we had a fixed size limit. A 50" might have barely fit the space, with a fraction of an inch to spare, but we didn't really want to cut it that close — the kids would be bumping it into the walls with reckless abandon. LED screens did provide a sharper, higher-contrast picture than the plain LCDs, but the technology is still new enough that the price difference was pretty large. In the end, our eyes were drawn to the Samsung models, especially since the quality of the LCD model was quite comparable to the LED (and both models seemed to outshine other brands, both LED and LCD).

Long story short, we brought home the reasonably-on-sale TV and the not-on-sale mount, and paid for Best Buy to come and recycle the old TV. I had figured we would wait for them to remove the old behemoth before we installed the new one, but my wife was insistent on installing it immediately. (Excited for the new TV, or desperate to entertain the kids — you make the call.) We were less than gentle in rolling the old TV out of place (what are we going to do, break it?) and managed to get the new one set up with a minimum of finger-smashing incidents.

We hooked it up to the DVD player and the Xbox, and I spent a little bit of time viewing the videos from E3 and playing the game that happened to be in the disc drive before going to bed. I have to say, it was like getting a new pair of glasses. Everything is much brighter, sharper, clearer, easier to see. I used to complain about the Xbox dashboard and being unable to read the dark-grey-on-light-grey 6-point text (especially since it fell in the out-of-focus area on the old TV), but now, even though I still think it's a less-than-optimal color scheme, I have to say it's insanely easy to read when the letters actually have edges. The game, too, was exceptionally clear and sharp.

The only down side? (Well, besides the knowledge that 3D is coming, and it probably won't be too long that I'll find myself a generation behind again.) My wife wants a blu-ray player to go with it now.

2010-06-05

AT&T showing how data caps stifle services

AT&T is making news for announcing the end of its unlimited 3G wireless data plan. While those who are currently on such a plan can keep it, no one getting a new plan will have "unlimited" even as an option. The reason this is such big news, of course, is because Apple has an exclusive contract with AT&T to provide service for all iPhones and iPads.

I'm not going to debate the popularity of Apple's products, mainly because I don't understand it. I've owned a Tablet PC, and the iPad does less, by design. The iPhone doesn't do any more than a lot of other phones out there. Both devices are locked into Apple's closed and tightly-controlled environment and its single, exclusive service provider. Despite all that, the fact is, the devices are very popular and very hyped. And because of that, people take notice.

Because of the iPad's popularity, media companies are actively looking at streaming more data to these devices. Major media companies have apps for the devices, Netflix can stream movies to them, and more are coming.

And now, AT&T has essentially put a limit on these new services, saying you can only use 200MB or 2GB (depending on your plan) a month.

That number seems extremely low, but how much is it really? There's an article on Clicker.com, titled How Much Video Can You Actually Stream With AT&T’s New Data Plans? that calculates the numbers with real-world data.

Unfortunately, I can't tell if it's high or low. I don't have a data plan personally, as I find them too expensive to deal with and am usually close enough to a PC with a "real" internet connection throughout most of my day. There have been times, though, that I've wished I've had it, but for the most part, it's been a convenience I've been happy enough to live without. (As an aside, I have a Zune with me often, and it can use Wi-Fi when available. However, I have almost never found a convenient open Wi-Fi access point when I need one. So, I find the claims that these new limits won't affect anyone because "open Wi-Fi is everywhere" to be laughable at best, and downright insulting at worst.)

If I were in a position where I had more roaming downtime, such as when I worked downtown and took the bus or train in to work every morning, I could see making a lot of use of 3G services. However, because I drive myself to work, and I work on a computer all day, I think I might end up being one of the "unaffected" lot, finding that my actual usage was well below the cap.

Interestingly enough, though, the measurements only take into account active usage. Sometime soon, the next iPhone OS will be released, and it will allow for multitasking, so that services can be running in the background. What happens when people suddenly have the ability to stream music over 3G in the background while they're doing other things? Data usage will no longer be active, but it'll be racking up passively in the background. Will 200MB be enough then?

2010-06-01

May Bandwidth

In84.90 GB
Out6.38 GB
Total91.29 GB
Comcast's measurement75 GB (-16.29)

Another exciting post in my most consistent blog posting to date. I've noticed that, although SpeedTest.net seems to still report a fairly consistent rate, things in general don't seem quite as fast as they used to be. Netflix movies have a tendency to go "blocky" a little more frequently; YouTube videos don't always download faster than they play back; even Xbox Live updates, which used to download in a couple seconds, seem to take close to a minute to download now; and games don't always report my network status as "green". Not sure what the problem is, or if it's just my perception — from the accounts I've read, even though it took me a couple hours to download the Halo Reach beta from overloaded servers, I still got a better connection than most.

Not that I wouldn't welcome a little competition around here to help keep Comcast on their toes. O FiOS, where art thou?

2010-05-04

Road Rage Murder in Aurora

There's an urban legend that, if you see a car at night with their lights off and you flash your brights at them, you may be triggering a gang initiation where they will hunt you down and kill you.

It's the first thing I thought of when I heard the story of what happened to a young man who lived in our town. He was riding home with some friends, when an SUV came up behind them on the highway, tailgating them, and started flashing their brights. The driver flashed his brake lights at the SUV, at which point the SUV moved over to the right, pulled alongside, and fired shots into their car, fatally wounding the man.

NBC 9 News · KDVR Fox 31 · Denver Channel ABC 7

I can't imagine what they must be going through. To have such a random and senseless act of violence inflicted on them, and then to know that the murderer is still out there; I know it makes me angry and scared just thinking about it, and I never met this young man.

2010-05-02

April Bandwidth

In70.19 GB
Out7.45 GB
Total77.64 GB
Comcast's measurement67 GB (-10.64)

While not quite falling back to the "cable-era" numbers, it's still quite a drop from last month. I have noticed the older kids seem to pick out a DVD off the shelf more often than hitting the Netflix queue lately, and even during the day at work I haven't seen my Xbox account signed in watching Netflix as often as it did last month. Definitely not to say that it's not getting used, just that it's starting to balance out between our other entertainment options a bit.

2010-04-26

Provident Lending? More like Provident Annoying

So, we were closing on a house on behalf of my mother, who is moving nearby. The terms of this are fairly amusing and will be the subject of another blog post, but this one is just a rant to say:

Never, under any circumstances, use Provident Lending.

Last week was the first scheduled closing date. My wife had scheduled to do the closing at 5pm, so she could come by work and leave the kids with me and I'd only have to leave work a little early. As I got home, I found a series of messages on the answering machine. The messages were asking my wife to get to the office in ten minutes, because the lending company, Provident Lending, had decided they did not want to do the closing at 5pm and wanted to do it immediately, and if she did not get there in 10 minutes, it would be a few days before closing could happen again. (Apparently, when a lender does a "funding", it is for a specific date and time, and if it does not happen, the funding must be reissued.)

While it is true that the call should have gone to my wife's cell phone instead of just left at home (the realtor said she seemed to have lost my wife's cell phone at that moment), it wouldn't have helped. The Denver area is quite large, and even if my wife had been home to receive the phone call, and even if she would've been able to instantly get in the car and start driving as soon as the call came in (an unrealistic expectation with a toddler and an infant), it would've been physically impossible for her to reach the office in 10 minutes or less. Add this to the complication that, at the time the calls came in, she was on her way to pick the two older boys up from school, and it's hardly any surprise closing did not happen that day.

The closing today ran a little long, because Provident Lending is extremely picky in what they accept for documents. The power of attorney form had to be their own, because they require extra information that is not present on a "standard" form. They rejected two signatures from my wife where she left out the word "by" between her name and my mother's. And they rejected one signature from the representative from the title company because "it appeared to be crossed out" — there was an extraneous horizontal mark on one of the letters that no one else could even see. (According to those who have worked with Provident Lending before, they will also reject signatures if you write sevens with an extra horizontal line on the same grounds, that they "appear crossed out".)

To quote my wife:

They were completly ridiculous in their demands, delayed the closing a week due to them not getting documents ready (they had everything they needed), and wanted to reject closing documents because the notary's signature had a small mark inside a single letter and it "looked like a cross-out" We couldn't see this mark. And we were informed by the Title Company that this is their normal practice.

It's as if they didn't really want our business. Which is fine. The broker who set us up with the realtor has apologized for this (he is covering the $50/day cost their last-minute deadline and refunding delay would've cost us out of his own pocket) and swears he will never use them again; and the next time we do any financing, you'd better believe we will not be doing business with Provident Lending.

2010-04-19

Last time, on General Highschool

Remember the story of the Lower Merion School District (just northwest of Philadelphia, PA) and the complaint that they busted a student while they were remotely using his camera to spy on him in his own home? Naturally, an investigation was launched, at which time the Philadelphia Federal Court ordered the school not to remove or destroy any evidence, to which the school agreed.

Remember, too, at the time, the school district insisted that it only activated those cameras when there was reason to believe the laptop was stolen (which they insist they had cause to believe in this case), and that they have only done this a total of 42 times.

A new motion filed last week alleges that, after investigating the evidence stored on the school district's computers, there were over 400 pictures taken alone of the student in his room, along with "thousands" of pictures of other students. The investigation also turned up screenshots of IM conversations and — perhaps the most damning evidence of all — emails commenting on the pictures, with one of the staff saying it was "like a little soap opera", with an administrator's response, "I know. I love it!"

Whether the spokesman for the school district believed what he was saying about the laptops being activated only in cases of stolen laptops and only being activated less than four dozen times, I don't know. But it's becoming increasingly obvious that this is not true.

This should, at the very least, serve as a warning. This kind of monitoring power is bad, mm'kay? Honestly, I don't think I would trust myself to have that kind of power and be able to resist the temptation of turning it into my own personal little soap opera; and honestly, I wouldn't expect anyone to trust me with that power, even if I were behaving responsibly.