Wednesday, August 09, 2006

I learned something new!

I learned something new today. It is extremely rare for me to learn something that I either don't completely know already or have a general idea about. Today I received a HP LaserJet 1020 black&white laser printer. I did my homework on this printer in advance of getting it and so far it is everything I've read about. I've generally been dismayed with printers, mostly because they are inkjets and modern inkjets take forever and a day to warm up the ink to print the first page. My favorite inkjet was the HP DeskJet 500. If you ever wanted a rock-solid printer, that thing simply refused to die. A good, solid piece of engineering. The only reason we got rid of it was because no one carried ink cartridges for it 10 years after HP stopped making them.

Until today, I've never actually owned a printer. Fixed plenty of other people's printer problems and used their printers to print stuff off. You'd be surprised what people will let you mooch :) I'm probably the biggest moocher ever.

Anyway, you're probably wondering what it is I learned that deserves a blog entry. I'll get to that in a moment. I set up the printer exactly the way the directions stated. There was a CD with cool animations designed for people who have never touched a laser printer before. However, the instructions said to insert the CD before connectiong the printer to the computer. It said nothing about an instructional, animated tutorial on the CD. Since I've worked with printers before, it was no big deal, but from the "first time laser printer owner" perspective, there are a number of people out there who probably wonder how to set the printer up and never insert the CD to figure out that the instructions are there. The end result is a perfectly good printer stuck in a box in a corner and another task goes on the ever growing "to-do" list. Someone at HP needs a refresher course on usability testing (or they can simply send me free product and I'll tell them everything wrong with it long before they ever ship it).

Anywho, I got it all connected up, cartridge inserted (BTW, this was the easiest-to-insert toner cartridge I've ever used). But then the strangest thing happened. I got this really cool error message from Windows saying something about "bad or corrupted hardware".

Now, it may be important to note that I have some pretty extensive experience with USB hardware. USB was designed to replace PCI (and PCI was designed to replace ISA and EISA - boy does that date me). However, my experience with USB has been such that USB devices are incredibly finicky and ultra flaky. They have this annoying tendency to randomly stop working - usually when you want to do something important and the fix is to pull the device from one USB slot and plop it into another.

So, I did what I normally do when USB devices don't work on the first go - I pulled the plug out of one slot and put it into another. Bam! Windows recognized the device as a printer. Good job Windows. Go eat a steak as a reward. Or print out a test page. Whichever.

Now that I had my test page in hand, I went to print something real. That printed real fine too (this printer apparently chews ink, but it prints really sharp images). I then went on to do other tasks that I normally do in the evenings and eventually came back to programming.

Now I have, on a USB thumbdrive (USBTD), an experimental environment where I put all of my current working source code. I compile object files and executables on the local hard drive and source code is on the USBTD. So, I went to fire up a project and work on it some more (USBTD still attached) and, lo and behold, the drive was blank. At this point, most people would panic. I, however, know that panic does no one any good. So, instead, I opted for a short 2 second virtual heart attack and then quickly switched into my "deductive reasoning" mode of thinking.

I have this uncanny ability to notice things when it comes to software. I can spot fatal interactions a mile away. Most of you have already figured out the connection since I've already made it for you, but put yourself in the shoes of your average user for a moment. At this point, the average user will panic and then shut down the computer or reboot it and hope the problem will go away and simply fix itself.

Anyway, I then ran a special program I have that forces the OS to flush data to removeable drives and forcefully eject the drive (you, as a user, don't have this program and it isn't for the feint of heart - it does hardcore OS manipulation). Then, I pulled the USBTD, waited for a second, then plugged it back into the same port.

What came as the surprise was the same cool error message stating "bad or corrupted hardware". Now I got interested because something clicked that I had read about a long time ago but had never encountered before. I'm an information nut. I store all sorts of crazy tidbits of information that form general premises that I use to determine a course of action. In this case, I remembered reading an article on USB thumbdrives and unpowered hubs. Everything attached to a computer has power requirements. So, I decided to run a test. I turned off the printer and disconnected the USBTD. Then I connected the USBTD. It worked fine (and, no big surprise, no data loss occurred). Then I disconnected the USBTD and turned on the printer. It worked fine. Then I connected the USBTD while the printer was on. Bam! Error message. So I determined that I could use one or the other, but not both at the same time. To me, this is unsatisfactory.

I'm from the good ol' ISA and EISA days of computing (actually, I've been around longer than that). During the ISA/EISA days, there were things known as IRQs (Interrupt ReQuest lines). Every device plugged into the computer used an IRQ and the user had to set little black pins called "jumpers" on all the hardware they put into their computers. Nowadays, the only jumpers users might mess with are on hard drives and CD/DVD drives for master/slave configurations. Anyway, some users had multiple devices and had to get creative with the pin settings and software settings to get their hardware to not have conflicts with each other. If two devices had the same IRQ, they either didn't work or didn't work right.

So, how does this relate to USB? Well, inside every USB-capable computer (pretty much every computer these days) has a bunch of ports that the user sees that they plug their USB devices into and expect them to work. These ports connect to the motherboard. On the motherboard is a powered USB hub that supplies 500mA (milliamps) of power to ports attached to the hub. A USB hub has multiple ports that can, in theory, handle multiple devices up to the hub's power limits. My USBTD uses 200mA while doing nothing. The printer uses 98mA while doing nothing. Assume both have power spikes while doing something. An example might be simply plugging in the device and interfacing with Windows. Now, you are wondering how I got this information.

Here is where I actually learned something today (I didn't learn anything up to this point). I went on Google and searched for something relating to USB and power consumption. In the process, I discovered that I can find out exactly how much power my USB devices are using from right inside Windows itself. You can follow these simple steps to do the same thing on your computer:

1) Right-click on "My Computer".
2) Select "Properties".
3) Select the "Hardware" tab.
4) Click "Device Manager".
5) Open the "Universal Serial Bus controllers" tree.
6) Double-click on each "USB Root Hub" item in the list.
7) Click the "Power" tab in each dialog.

On my computer, I have 5 "USB Root Hub" entries. I then confirmed that the ports I used for the printer and the USBTD are part of the same "USB Root Hub". In essence, to solve this problem (a power usage problem) so that I can have the printer on and my USBTD attached and powered up at the same time, I'm going to have to play the "IRQ jumping game" that I used to play in the old ISA/EISA days. One thing to note is that I have a USB mouse and it shows up on a completely different "USB Root Hub" and it occupies only 2mA when not in use - which is very cool because it is an optical mouse. However, only two ports are available for the hub that the mouse is on while 8 ports are available for the "USB Root Hub" that the USBTD and printer currently connect to.

Now how many users are even going to figure any of that out? Of those, how many will even make the connection to power consumption as the problem? You'd have to be a hardware guru to even think the phrase "power consumption" and, even then, you'd probably doubt that as a cause and simply assume Windows actually discovered bad hardware (because Windows error messages are never wrong).

BTW, from first glance, the HP LaserJet 1020 is a terrific entry-level laser printer. It prints fast, occupies very little space, seems quite robust, and has a classic look-and-feel that reminds me of the old HP DeskJet 500. PC World has a review of it on their website and, well, their opinion of it is simply wrong. It doesn't have bells-and-whistles - it does what a printer is supposed to do and just prints. User reviews of this printer are quite positive and, even though I don't do much printing, I can tell quality workmanship a mile away.

Speaking of which, Arrow Corp. still makes the same exact staple gun they made 25 years ago. It was quality then and someone in the company clearly understands that and it is the same identical product today (and still made in the U.S.). I expect the staple gun I recently replaced to last another 25 years. Most U.S. companies cut corners to reduce cost and, as a direct result, shoddy products come out. It should be no big surprise, therefore, that the same (or worse) shoddy work can be done more cheaply overseas. When money, not quality, are at the forefront, you as a consumer suffer as a result. The same thing applies to all appliances made these days: Washers, dryers, vaccuum cleaners, refridgerators, microwaves, etc. all used to last 15-20 years before needing new parts or being replaced. Now you are lucky to get 3 years out of them for only a slightly lower price (accounting for inflation). Even clothing used to last forever (excellent stitching, solid cutting, even seams, good material, etc.). Now clothing falls apart in a year. I've gotten into the habit of ripping out buttons on shirts and sewing them back in myself when I buy them...my button sewing jobs (which suck, BTW*) outlast the shirts they are on.

* I'm a programmer, what do you expect? However, if I can sew a button on better than the manufacturer, there is something clearly wrong with the industry as a whole.

I suspect I'll eat my words about the printer after the first toner cartridge gets used up. However, my paper output is generally low so a single cartridge could take 2-3 years to go through and the printer might last for a very long time past that.

Friday, August 04, 2006

esnips.com: We ruin Google search results!

First, visit here:

http://www.esnips.com/web/MyCPrograms

And view the source code to the two programs that were uploaded by the creator Parul Goyal - or is it Goyal Parul? Whoever it is, they clearly don't know how to write code. Everyone who doesn't know how to write code should not be allowed to post their source code to any place but private, unsearchable forums until they get halfway decent. That way, people like me aren't annoyed. I suspect that websites such as these are the reason MSDN Library search results are dropping off the map.

The first program (reversing a string) simply doesn't work. Well, it displays a string in reverse, but it doesn't actually reverse it. If he gets hired by Cisco, be afraid...very afraid. Here's how I would reverse a string:

1) Not use C. C is such a weak language. I would use C++ instead.
2) Not use C++'s basic stuff. ANSI Standard C++ is such a weak language. I would use Safe C++ instead.
3) To reverse a string, I would use BString*:

#include "Base.h"

int main()
{
printf("%s\n", *BString("parulgoyal").Reverse());

return 0;
}


Does the same thing except it actually reverses the string and THEN prints it. Done and done. I used fewer lines of code, the code is readable and more maintainable, and I know it works without even testing it.

* BString is, in my professional opinion, a cleaner design than STL string and it offers a ton of functionality that is simply missing from STL string. The class is distributed with the "Safe C++ Design Principles" book. 50% of all homework problems given to students are easily solved with this class. By "easily solved", I mean little programs like the above.

It is interesting to note that the same comment lines are used in both programs. The person is clearly copying and pasting the code from a sample named 'laernCode.c' (they really spelled it 'laern' instead of 'learn').

For the second program, it simply won't even work properly. The for-loop conditional is wrong such that the if-statement after the loop will never fire. The person also didn't bother skipping even numbers (2, 4, 6, 8, etc.) and the n/2 limit is wrong (the actual limit is (integer)sqrt(num)). I won't even bother going into the whole mess of carelessly mixing integer data types.

What is sad is that I found the code in question from a quick search on the keyword 'programming' on the esnips website (esnips.com was recommended by someone on a mailing list I moderate) and that a half-dozen people had viewed the source before I did...most likely they assumed that the answers were good and thus committed them to memory. Disseminating information while still being a beginning programmer should get you shot by a firing squad.

The only thing good about esnips is that illegal e-books of some of the better C++ books to learn from are at the top of the list of the search results. Not that I'm advocating the use of illegal materials, I'm just saying that if esnips is going to have publicly available source code that sucks, that source code should come after materials that are actually good sources for learning the language. Koenig & Moo "Accelerated C++" is an infinitely better starting point followed by the e-book "Safe C++ Design Principles" to bring you up to speed on modern programming practices. Between the two, the most useful parts of C++ are covered.

On a more interesting note, my brake line cracked yesterday and dumped brake fluid all over the road. I limped the car home, patched up one part of the crack that I could see, dumped a container of brake fluid into the resevoir, and took it to the shop today. There was a trail of brake fluid the whole way - which was entertaining. I also probably annoyed every driver behind me (sorry about that) because I limited my speed to 30 mph in a 45 mph zone. That, and I was in 2nd gear the whole way to utilize engine drag to add some traction. I'll find out later today if the crack was intentional or if the lines were just worn out from old age (the vehicle does have 56,000 miles on it). Braking the vehicle consisted of alternating between pumping the parking brake and pumping the power brakes and using the engine drag (and having LOTS of space to stop the vehicle). I thought about putting on my hazard lights, but I think most people figured out I had something wrong with my vehicle what with all the squeaky sounds from the parking brakes and the fact that I was going painfully slow down the road. Thusly I was given a fairly wide latitude to drive in. The hazard lights would have just been embarrassing. (I had my hand on it just in case I actually lost control of the vehicle).