Wherein I occasionally rant on various topics including, but not limited to, PHP, Music, and whatever other Topics I find interesting at the moment, including my brain tumor surgery of August 2010.

Wednesday, October 24, 2012

Using Visioneer 7300 USB scanner with Mac OSX

Using Visioneer 7300 USB scanner with Mac OSX

So I have this Visioneer 7300 USB scanner that was acquired from a firing from a former job, since the owner didn't even want it back.

It's kind of a nice scanner, lightweight, with five programmable buttons on the front, such as scan and print with one click.

The UI for the button programming is about as bad as I've seen. I refuse to provide instructions because I basically click around semi-randomly when I try to program a button until it works. Kind of like Windows.

Anyway, I wanted to hook it up to my MacBook Pro, but it never seemed to work.

Then an upgrade to Windows made it not work there either because there was no driver allegedly, but I found that gimp could use something to make it work.

Actually, I think the driver for the PaperPort software was at fault, but I like gimp interface better anyway. Though gimp does take a long time to start up. Oh well.

So then I tried gimp on the Mac. With a bit of effort, I made it work.

  1. Starting on the sane homepage I found a supported devices link.
  2. I clicked through to the vendor-ordered devices and found my device.
  3. I then did the usual "sudo port search" to find sane stuff.
  4. I then did my usual "install everything that looks useful":
    • sudo port install sane-backends sane-frontends twain-sane xsane
    • You may not be that indiscriminate however. Good luck.
  5. I tried gimp in a terminal, and it wouldn't start.
  6. So I did "sudo port install gimp" to re-install that.
  7. Again typing "gimp" in a terminal seemed to work...
  8. However, while I had an Xsane dialog... in my gimp "Create" menu...
    • It couldn't find my device.
    • The console log in the terminal said:
      • Couldn't open firmware file (`/opt/local/share/sane/gt68xx/Cis3r5b1.fw'): No such file or directory
    • So I went on a hunt for Cis3r5b1.fw
    • I found a download on a Polish (?) site: Despite my complete lack of understanding of Polish, the download button was rather obvious.
      • Anybody remember when the internet was almost all English, and the Russian site 'demos" opened up and everybody and their brother sent them "welcome" emails and wanted to know what kind of demos they were working on and it was "Demos" the moon of Mars... I think they were astronomers or something. Sorry. I digress. 
  9. I created the gt86xx director in /opt/local/share/sane/ and downloaded the file there.
  10. A restart of X11 and gimp and Bob's your uncle.
  11. I made a test scan, and it took forever, and the white/black/grey scale was all whack.
  12. But the next scan seemed to go faster, and I assume I can tweak settings more or less at random until the colors/grays come out right.
Anyway, that's how I did it, and it might work for you, or not. And it even might be helpful for a different scanner. Or not.

Or even a different platform that can use sane. Or not.

I may have left out a minor step here or there. I'm horrible at taking notes because I usually figure I won't get it to work anyway.

Friday, July 27, 2012

The Cost of Connectivity

The Cost of Connectivity

synopsis: The US Sucks

Public interest and consumer advocates have cited the U.S.’s recent decline in global competitiveness as evidence of the need for policy reforms that will spur greater competition and investment from the nation’s Internet providers. Meanwhile, opponents of this view have dismissed these international rankings as deeply flawed and akin to comparing apples and oranges. They cite the United States' significantly lower population density and larger geographic size relative to other nations at the top of the rankings,which tend to have smaller land areas and greater population densities. emphasis mine

Are the opponents of fair competition seriously suggesting that a survey of major cities around the world is biased to a great effect by population density?

Yes, USA has a serious "urban sprawl" effect. One has to only look at L.A., New York Metro and Chicago to see that.

But, really, is it any easier in Hong Kong, Tokyo, Seoul, Paris, Berlin, London or Amsterdam to tear up streets and install fiber?

Actually, if you think about it, the "urban sprawl" makes it easier

Sure, buying the fiber and running it a longer distance is more expensive.

But they've got more "elbow" room in those cities.

How in the world did they find any room in Tokyo to run fiber? The whole city is a spire with tiny apartments/condos crammed on top of each other like a Jenga game.

Have you ever seen the traffic in Paris or London?

Hong Kong? You can't even breathe without invading somebody's personal space.

The US doesn't even have a single city in the top 50. You have to scan down to top 90 to hit Los Angeles.

Does that prove their point? Or does that population density make it much more expensive to run fiber?

In fact, if you Google for prices of laying fiber, you will find the same answer everywhere: Population density is the #1 cost factor. They're running fiber inside sewers just to avoid dealing with tearing up streets!

Monday, June 04, 2012

[Bleep]y Error Messages

[Bleep]y Error Messages.
(My daughters might read this blog, so I need to keep it G audience.)

I encountered yet another useless error message today.

Not that I've blogged before about this, but any developer, any user has experienced this, so I mean yet another useless error message from the corpus of all useless error messages inflicted upon any user anywhere, any time.

And they are legion.

So I won't point out the specific vendor/software/whatever.  I'll just rant about what makes a GOOD error message.

Are you smarter than a 5th grader?

Maybe it was just my school, but we learned the basic Journalism/Essay rules in 5th grade:

  • Who
  • What
  • Where
  • When
  • Why

5th Grade. Five Ws.

Let's apply this to Error Messages:


Exactly WHO is throwing this error message at me?
For some kind of device, like coffee maker, router, car, ok, this should be obvious.
Some routers have mini-web-servers built in, so maybe not...
Maybe the coffee-maker has different components.
Certainly today's cars are complicated enough.
At any rate, all the software/hardware involved should identify WHO they are in the error message:
  • OS Error: Permission Denied.
  • MySQL  Error: Permission Denied.
  • PHP Error: Permission Denied.
  • XYZ (application) Error: Permission Denied.
Every one of those would require radically different approaches to diagnose and correct.

If you, the software/hardware developer are bubbling up or passing on error messages, or to be kosher to an end user, suppressing the error message in favor of a "Something Went Wrong" error message, and logging the real message somewhere for Developers to look at, you still can at least tell the end user WHO is throwing the error message.

Even if you want to hide the inner implementation (E.g. particular Database vendor), at least tell me it's a database error that went wrong!

As a user, I can make an educated guess what course of action to take, or whom to contact within your/my/our organization.

And if the error message is for a Developer or needn't be masked for Security, I need to know who is throwing the error message.

Today's systems are too complex and too many error messages are being passed through, with all context lost.


What exactly went wrong? I need context. I'm not knee-deep into your code, hardware, architecture. I need enough context that I can figure out what actually happened, from Square One of knowledge.

All too often you find an error message that makes zero sense to anybody not intimately familiar with the software.


I don't need just filename, I need the line number.
I don't need just filename, I need the full path.
In all probability, whatever you choose for a filename is going to be used by somebody else as well.
Let me know exactly where the error originates.
Is it configuration?  Business logic? Resources?


I can read the calendar and a clock, so if the error is in real-time, I don't mean that.
Even for an asynchronous error  generated/read, I still need...
When did this error occur relative to what the software was trying to do.
Was it reading the disk, writing to RAM, reading an RSS feed, or trying to feed the pigeons.
I can't begin to diagnose what went wrong with whatever you were doing if I don't know when it happened, relative to your workflow.


Why are we here? Not in a philosophical sense,  but why is this an error in the first place? Why do you need whatever you need to carry on what you are doing? Maybe your idea of the one true source of what you need doesn't match mine. Perhaps I can provide an alternate source.

And a bonus one:


If you're going to tell me something went wrong, you probably have a pretty good idea what I should do to correct it. So why not tell me what to do next, or at least list some actions that will probably be useful.
Whether I have to sacrifice a rubber chicken or poke a voodoo doll or tighten the wing nut, let me know.  Odds are you already know what I need to do.  Tell me. Don't make me spend an hour googling and researching all about your software/hardware/whatever to find out I only have to turn the amp up to 11.
Give me very specific instructions. If it's really long and complicated, give me the references I need to get the instructions.  Preferably multiple references.  I may not have the user manual.  I may not have Internet access. Don't tell me of only one of the two resources. List both.

Maybe I'm just getting too old and turning into a grumpy old man. But I'm very weary of spending my time researching your error messages because you can't communicate. For the same effort, word-count, whatever, except possible thought on your part, you can give me a better error message.

Maybe you think I'm being lazy.
Maybe you think I should just shut up and take it, just like everybody else.

Maybe you think I'm asking to be spoon-fed everything.

After 20+ years of software development, I've served my time reading [bleep]y error messages and trying to make some sense of them.

What we have here is a failure to communicate.

It's not me.

Tuesday, May 22, 2012

PHP Caches (APC et al)

I occasionally still see people referencing ancient misinformation that various PHP bytecode caches are giving huge performance boosts by caching the bytecode so the PHP bytecode parser/compiler doesn't have to do the monumental task of reading PHP source and converting it into bytecode to be run by the Zend Engine.

Nothing could be further from the truth.

Okay, there is one tiny bit of truth in there.

The php process/program/runtime, without a bytecode cache, is in fact a JIT parser/compiler to a bytecode, which is then run by the Zend Engine.

Amd. okay, the various caches all cache the bytecode as part of the process of gaining huge performance boosts for most PHP web applications.

So that's two tiny bits of truth in a monumentally flawed statement.

But the significant boost is not from bypassing the parser/compiler.

APC and other caching mechanisms save a great deal of time by not hitting the hard disk to load the script, but keeping it in RAM, if possible. Hard disks are slow.  RAM is fast.

The bytecode is saved in cache instead of source, which does bypass the PHP parser/compiler.

But that's just "gravy"

Compare two following psuedo code samples that describe the difference the APC (or other cache) makes:

Code Listing #1

//save hitting the hard disk
if ( $source_code = in_cache($path) ){
  //got the source code from cache, do nothing
  //file_get_contents = super-duper slow!!!
  $source_code = file_get_contents($path);
$bytecode = zend_parse($source_code);

//Code Listing #2

//save hitting the hard disk
//and a small bonus, cache the bytecode, not source:
if ( $bytecode = in_cache($path) ){
  //got the bytecode from cache, do nothing
  //file_get_contents = super-duper slow!!!
  $source_code = file_get_contents($path);
  $bytecode = zend_parse($source_code);

As you can see, both code listings bypass the hard drive access which is super-duper slow.

But the second one also bypasses the PHP parser/compiler, simply because it's such a trivial difference, just moving one single line of code into the conditional, to cache $bytecode versus $source_code.

The savings from parsing is chump change compared to disk I/O.

It's also trivial chump change to implement.

But every ounce counts, so all the "bytecode caching" (sic) mechanisms do it this way.

They should all really be called "RAM caching, with bytecode gravy" or even "RAM caching" and just ignore the minimal difference between source versus bytecode.

I'm sure this post is going to make all the caching implementers run out and change their documentation etc. :-)

Well, at least you now understand what "bytecode cache" really means. I'll call it a "win".

Monday, February 06, 2012

Rebuild theme registry on every page.

Rebuild theme registry on every page.

During theme development, it can be very useful to continuously rebuild the theme registry. WARNING: this is a huge performance penalty and must be turned off on production websites.

The last couple weeks, I have found out the hard way exactly what this is talking about... :-(

You probably won't really notice it on page load, unless your site is high traffic.

But even a LOW traffic site, with MySQL replication set up, your MASTER hard drive is going to fill up very quickly.

We were generating 4.4G per day on a low-traffic site.

This is because re-building the theme registry on every page deletes all the {variables} and the whole theme registry and then re-INSERTs them all on every page hit.

Just flipping that off on ONE low-traffic site brought disk usage down to 400M per day.

When keeping several days' worth of mysql binary logs, that difference adds up quickly.

Note that only SOME themes even have such a checkbox in their "Configuration" panel. The most notable one (that I know of) is Zen or any theme built on Zen.