Saturday, December 29, 2007

Luigi Colani, Twisted by Design

CNET columnist Rich Trenholm recently wrote a short history of digital photography titled "Photos: The history of the digital camera."

This is composed of 14 short pages (short but cute pages, and page flipping keeps us distracted from all the ads). Each page has one image of equipment from digital photography's short history, along with some appropriate text. Sadly for me it wasn't always clear where the information or the images originated. It would have been fun to dig a bit deeper, though it was certainly a good read overall, and I did manage to dig up some more info.

The opening page shows Kodak's original prototype digital camera from 1975. It was the size of a counter top kitchen appliance, said to have weighed around nine pounds, and had an image resolution in the range of 10 kilopixels. The image was recorded on tape after capture.

But for me the most interesting information came later in the piece, accompanying photos of a bunch of mocked-up Canon canons from 1984. They came from Luigi Colani, who had earlier had a hand in designing the ground breaking Canon T-90 camera. Fortunately or otherwise, the designs he mocked up never made it to market.

Mr. Colani describes himself as "the unabashed agent provocateur of the design world." Which seems about right. He also seems to like letting his prose off the leash: "He thinks in terms of grand utopias, creating ingenious drafts for designs that preempt much of what is not yet technically feasible."

Etcetera. Anyway, it's his specialty, designing is. He has more words at "The official Website of Colani Trading AG."

The Colani story starts with the Canon T-90 camera. You can see it at Canon's very own online camera museum. Canon seemed to like Colani's contribution to the T-90 design. They say that "Canon's unique 'bio-form,' which is now widely recognized, was created in the design work for the T90," so that must be why they asked Mr. Colani back for round two after this was done.

In fact, in the T-90 process, he even changed their way of designing cameras. Originally he had approached the company with an idea for an optional hand grip for the F1 body. They apparently passed on that but instead sucked him into the design process for the T-90, putting him in charge of a team. But they also kept their own team, and then had the two complete.

Colani didn't win. But neither did Canon's original team.

The better parts of the two designs were eventually melded into a single semi-organic design that led to the smooth curves of the EOS 1 series. It isn't surprising that Colani's T-90 design wasn't used outright. You should see it. His original design looked something but not quite like a demented black gourd.

On the other hand the Canon engineers' design looked like something would look if designed by engineers, and if you see that sort of thing once you remember it. First the engineers designed the guts of the camera and then wrapped some plastic around it and sprinkled a few control buttons here and there.

Colani's influence helped a lot. As a designer he thinks first about how to hold and control something, in this case a camera, and then goes on from there, leaving the internals undefined, for the people with scary degrees to deal with. He doesn't know that end of it anyway. He just does the wrapper, so to speak, but that is his area of expertise.

As with most pure designers though he seems to have the occasional uncontrollable fit of fancy. Almost seems like he may need a hovering assistant or two to hold him down if he gets too frantic, but his car designs look good. Some other things not quite so, like these cameras maybe.

Neither Colani's nor the engineers' approach could have worked as well as their synthesis, which resulted in the distinctive, usable canonical look that we have seen in every Canon SLR since then.

That was 1984, and Canon wanted to play with some ideas from the "near future" (the 1990s), so it asked Colani to come by again and poke at the future for them. The result was his "5 Systems" mockups, which when done were exhibited at the 1984 Photokina exposition.

These were the:

Super C. Bio:
An SLR camera with a 35-70 mm power operated zoom lens, and a couple of stray horns, one of which looks like a hand grip. The other looks like a stalk hiding a built-in flash tube.

Lady: A small white camera intended to fit the hand, and resembling a soft bar of soap that someone has squeezed into shape with his fingers.

Hy-Pro: A professional SLR system camera. Has "different combinations of bumps and hollows" to facilitate holding it at either eye or waist level, though you could say that it looks a little like it has too many horns.

Frog: An underwater camera with two horns on the back, ostensibly hand grips, but which could give you a really good poke in the eye if need be. Two flash units are built in. And the lens shade covers the sides of the lens but not the top, where most of the glare would be from (i.e., the "surface", where day light is, and so on).

HOMIC (HOrizontal Memorychip Integral storobo Camera): Well, Canon ought to know, and if they say "storobo" they may mean it, but then again maybe not. Canon says its "A still video camera. It uses solid-state memory. It is characterized by the objective lens and viewfinder being on the same axis. The flash unit fires through the objective lens." This could have been fun to play with, flash on a video camera and all, firing through the taking lens, giving you intermittent, blinding lightning flashes all over your scene, instead of a nice, even flood light (not bouncing around inside the taking lens). Then again, they know more about making cameras than I do. Then again, what the hell is a "still video camera?"

Anyway, good piece by Rich Trenholm, and interesting work by Canon (still in business) and Luigi Colani, also still in business, at work on lots of fancifully twisted things, some of which are good-looking cars, and some others of which are fancifully twisted things.

Friday, November 30, 2007

Sigma Corporation reannounces the DP1

I've looked at this camera before and found the front of my shirt getting wet (whatever is causing this seems to be coming from my lips). And then fretting over details like a lot of others seem to be doing.

Personally speaking I'd like a few interchangeable prime lenses, or something like a difocal (maybe 24mm and 40mm equivalents), or a shortish zoom (maybe 24mm to 48mm equivalent), or as a last resort a slightly longer fixed focal length lens (say 35mm equivalent). I think about this and then gnaw on the carpet some more, and then go back to looking at the photos of the camera and wondering if I could live with it as-is. And so on.

Sound familiar, anyone?

It seems that the most important points here are that the IDEA (cuz there ain't no camera yet) of a camera like this is getting some smart people excited, and that a camera company is actually thinking about a camera like this, perfect or not.

Eventually we'll get some really simple, really small, high-image-quality cameras designed for usability, and built from first principles as digital devices.

If this Sigma camera reaches production then it will be the advance scout of this new breed. There will be others, whether this camera is a success or not, but if we can start now, with this camera, it will bring the future along a bit faster.

Humans aren't changing. Cell phones will not replace real cameras. Eventually (some) cameras will re-evolve to suit the needs of agile and perceptive still photographers, and we will be able to get away from imaging devices designed as mindless add-ons for those goofy twitchy people who just like gadgets and have short attention spans.

I recommend the "Inside Straight" column by Herbert Keppler in the November "Popular Photography" magazine. Go look at it. The column is titled "What today's camera makers can learn from the very first Leica: Keep it simple." It has a photo of the original Leica next to a modern DSLR. You will get the point immediately.

Now for some more carpet gnawing, then lunch.

For the Sigma announcement, see Sigma.

For a discussion, see The Online Photographer.

Wednesday, October 10, 2007

RE: How to Succeed as a Photographer

RE: "How to Succeed as a Photographer" by Mike Johnston, at The Online Photographer.

First I read this post, and then I read Bob Lewis's weekly IT-related column (at www.issurvivor.com/) and then I saw some similarities. True, these two seem unrelated, but that's the fun part. Bob was writing about his recent vacation, and relating it to his IT experience. Mike was writing about people, and relating their questions to his experience in photography. But both write about the intersection of technics, creativity, and business.

From Bob Lewis's main points, as they may relate to developing a photographic style:

1 - "Experts experience a different world."

What you see in a photograph is what you see, but may not tell much about where the final image came from. The vision of a world-class photographer comes from who that person is, what that person has been through, and that person's effort over years if not decades. You (and I) might produce an occasional faint copy of a style but can't do it consistently because we just don't live in the right world. It's someone else's world, and we will always be outside of someone else's world.

2 - "What you like and what you should ask for aren't always the same."

"You don't always get what you want but sometimes you get what you need." We've all heard variations of this. Still, it's hard to both know what we need and to ask for it. Maybe the problem is the asking. Maybe it has too narrow a focus. Maybe it's just too needy. An artist should never think too small, or be too limited, nor should anyone, really. What you want and what gives you real joy can be delightfully at odds, and an artist really needs to be open to the possibilities of the unexpected.

3 - "You can't optimize for everything."

The more you optimize for one dimension, the less optimal your results in all other dimensions. In other words, if you try too hard you'll get something that looks the part. This is especially true if trying to mimic someone else's style, or trying to look like a "professional." If you're really good you'll be unique, and you'll also automatically be optimal for exactly that condition. Relax. Let it happen.

4 - "The outside view tells you little about the inside view."

This is similar to the first point, but still a little different. You could call this "mastery of technique." "First there is a mountain, then there is no mountain, then there is."

When you try too hard, you're focused on the wrong things. The vision comes from who you are and also how well you can handle your tools. If you don't know which end of the hammer does the work you're going to have problems. The hammer is a strange and heavy object with odd curves and inscrutable sharp edges, and it is mute. It takes effort to learn its capabilities.

Likewise, if you know which end of the hammer does the work but you still can't pilot it then you will continue to explore many dead ends. If you are motivated you will look for clues and try emulating an expert carpenter. Eventually, at the point you become proficient a new world opens, and everything you see becomes nail-like. You are an expert yourself.

When you know the hammer so well that you forget it's in your hand, forget what it is, then you are a master. There is no longer a hammer or nails, or a nailer. It is now all process. You and the hammer and the nail and the job are not separate entities but part of a collaborative process, and the concern is no longer with nails and hammering things together with them but about creation.

5 - "Sometimes, what you get is better than what you'd planned."

And being able to recognize this is the core of creativity. "Bad artists copy. Great artists steal." Pablo Picasso didn't mean that a great artist steals from other artists. He wasn't talking about crime, not burglary or robbery. He didn't reference material things.

First you try to color within the lines. Later you learn to draw your own lines and color within them, and later still you ignore the idea of lines. Beginning artists always learn by copying. They have to learn how to do art. The process is one of working from outside in until the artist becomes art.

The fundamental idea of stealing is of making something your own, not of taking from someone else. Crime is a crude, material reflection of something beautiful and profound.

Artists steal. They discover and reform. They take tiny parts of life and remake them again and again until these bits are completely owned, completely a part of the artist. That is the difference between a bad artist and a great artist.

An artist can and will steal from himself, or from a chance encounter with the unexpected, from the sudden flicker of a bird's shadow, from a stray flavor tasted only once, from a stray word, a child's gesture, the rasp of grandmother's ancient voice.

What happens, every instant of every day, is all inspiration. And all unplanned no matter how hard you try to put it into a box. The professional artist, and even more so the great artist, takes ownership by giving the inspiration an unmistakable signature, and setting it free.

Hey, you believe in God? You think God has it all worked out? Maybe so, but do you think God is boring and predictable and you have God figured out? Heh. God is smarter than you, and more fun. And whether or not "God" is a concept close to your thinking (not actually to mine) this world is smarter and wilder than all of us put together. Stay loose. Experience the holy fire. Let it burn your butt whenever it wants to.

Tuesday, October 09, 2007

2007 Wonderland Trail Hike

Last night I finished adding photos of my September hike around Mt Rainier to my web site. Short on closeups and no people, but not bad for grab shots on a 90-mile foot trip.

Luckily rain didn't reach me because I got to the dry side of the mountain the first day, and dodged it, although there was lots of fog and cloud on day two, but still nothing like the predicted 12 hours of rain. Or two following days of gradual clearing. No, not bad for the first day, having started after lunch.

Someone going the way opposite to me had three days of fog and cloudy weather, and some real rain, I got off well. The only real problem for me was my own stupidity, which is a constant companion.

I misread the sign that indicated where I was to get off the trail and take to the highway, avoiding the only impassable part of the trail (still not fixed after last fall's ripping rain and flooding).

So a mile on I got to the washed-out part and decided to take a chance on sliding down 60 feet onto rocks rather than backtracking. It wasn't that bad. Been through worse things at St Helens and hiking off-trail around Mt Adams. And really quiet. Almost anything is better than walking six miles along a highway.

It was an hour or so after missing the turnoff when I got to a place where last year's flooding had cut the trail into bits. The stream had diced it over and over again.

I was standing on a fallen tree mulling which way to go, and then I just began tipping over backward. Nothing to grab, I just went back suddenly, falling over, starting from about three feet up, with my feet on this horizontal tree trunk.

As I fell my feet slipped off the tree and hit the ground first, then my behind, then the pack on my back. The pack stood out like a big hump and acted like a lever. It whipped my head around like the tassel at the end of a whip, toward the ground. My accelerated head hit the ground with a loud thump. Yeah, a loud thump. Loud enough to scare me.

I hit soft sand, my head beside a smooth river rock the size of a watermelon, and I wasn't dead. Or paralyzed with a broken neck, to lie there along a closed section of trail and die in cold rain after sunset. OK by me.

I did have a headache for about an hour, but that was about it. A pretty good deal overall.

I got up, collected my things and brushed off, then started hiking again. For a while I wondered what it would be like to have a brain hemorrhage and have my skull fill with blood, but not feeling much worse than usual I just kept going.

Things worked out. That was day one of eight, and the rest were good. High point, about 7500 feet. Coldest night, about 25 degrees. Most memorable feeling, joy. The weather stayed nice until a few days after I got home, but since then it's been raining. Winter came in mid-September and now it seems to be here for the duration, and the word is that we'll have a wet and stormy winter. Oya, life these days.

See photo slideshow.

I still have some St Helens shots from July to work on, but that gives me something to do with the rest of my life. WooHoo!

Friday, October 05, 2007

RE: It's the Sheepskin, Stupid

Today Mike Johnston of "The Online Photographer", a wildly popular photography blog, posted "It's the Sheepskin, Stupid." He says, in part.
To this day, virtually every job I come across in the photography field that I'd be a good match for lists an MFA degree as a minimum requirement. The irony is that with the depth of my experience and knowledge in the field, I could probably teach at most photography MFA programs. But not being an MFA myself, I can't actually get a job teaching anybody.
There were 25 comments at the time I read it, and here is what I replied:

For better or worse, one has to deal with this as with many other things. That's just the way they are, but not necessarily fun, or right, or the way they will remain. What you have commented on is the result of a culture of scarcity.

In the case of positions in various institutions dealing with art, there is necessarily an elite, who get ensconced and then brick up the doorway into a narrow slit, partly because they need to (not enough demand and therefore very few opportunities on the inside) and because they want to (if it was hell for me to get here, then by damn I won't let just anyone in -- they have to suffer too, just like I did, and should be just like me, because I am obviously a superior being or I wouldn't have gotten here).

Much in the software world used to be like this, and still is in stuffy backwaters, but things are changing there, and in many other aspects of life. With new technologies and global markets we have new opportunities, and this, as we can see by the presence of "The Online Photographer", various forums and online magazines, image publication sites and online galleries, is being felt in the photography world as well.

If one wants to work in a museum with terrazzo floors, marble columns and hushed silences, then there will always be the prerequisite of acceptance by the priesthood. Too bad. Humans are like that. I decided long ago that anyone who didn't have the good sense to hire me was someone I wouldn't want to work with anyway.

Paul Graham, the web startup funder, has a good essay on similar topics in his world. Here are some of his thoughts on degrees and opportunities:
In a big, straight pipe...the force of being measured by one's performance will propagate back through the whole system. Performance is always the ultimate test, but there are so many kinks in the plumbing now that most people are insulated from it most of the time.

So you end up with a world in which high school students think they need to get good grades to get into elite colleges, and college students think they need to get good grades to impress employers, within which the employees waste most of their time in political battles....

Imagine if that sequence became a big, straight pipe. Then the effects of being measured by performance would propagate all the way back to high school, flushing out all the arbitrary stuff people are measured by now. That is the future....

What students do in their classes will change too. Instead of trying to get good grades to impress future employers, students will try to learn things. We're talking about some pretty dramatic changes here.
Mike Johnston and his readers perform. That's OK by me. We can wave politely at the faces behind the glass in the fortresses as we pass by.

(See Paul Graham's essay "The Future of Web Startups"
and Mike Johnston's post "It's the Sheepskin, Stupid".)

Thursday, October 04, 2007

This is pay, sort of...

In a Spanish proverb, "God says, 'Choose what you will and pay for it.'" And things generally work that way. Pay isn't always good, or a benefit, but when we think of work we think of money coming in, and generally see it as a benefit. I work. I get paid. Money. I have salary, insurance benefits, vacation time, and sick leave. Not all money, exactly, but still pay. It's all pay. All coming in. To me. It's good.

Normally we don't include medical and dental insurance, vacation time or sick leave in our thinking of "pay". But consider taking a job that doesn't offer any of these, if you can. Then think of an identical job that does offer them all and tell me which one you'd actually take.

Exactly. Because one pays more. No doubt about which hook to bite. Glad we got that out of the way.

Don't complain when you start seeing your two weeks off show up on your income tax statement as it will one day. I once worked at a place where you were entitled, after one year, to one week off without pay. You could wander off for a week and rest up, and they wouldn't replace you while you were gone. If you could afford to be gone. That was your vacation time. Being down there right at ground level puts things into perspective. No fooling.

Besides the basics some people get stock options, a company car, bonuses, and some non-monetary things like prizes or other material goods, framed certificates, or praise such as being named employee of the (fill-in-the-blank).

So that about wraps it up then, eh?

Nope, and you knew it didn't.

Even if you've never had "a job" you know better. Work is what someone else tells you to do. You have a boss. Usually several. In most places I've worked, we might have 50 people in the office, and five or six levels of supervisors. Talk about your wonderful life there.

"Supervisor" literally means one who views from above. "Overseer" is a direct synonym. Supervisors came into their own in 19th-century factories where the supervisor was actually a person who sat in a high chair and watched everyone work. Made sure that they worked. Oversaw the workers. You could tell that they were workers because they didn't speak, had their heads down, and kept their hands moving. Anyone who spoke, or looked up, or slowed down got clipped by the supervisor.

Which is a little like being told you're unprofessional because you haven't chosen to wear a suit to work. Professionals being the ones wearing the antique, expensive, and painful clothes. Like supervisors wear. Professional supervisors.

Being a supervisor hurts because it's so hard, and so godlike. A supervisor has to be all-knowing, and that is very difficult. Someone who evaluates the work of everyone else has to be all-knowing and infallible, and the wearing of painful clothing shrivels into absolute insignificance other than as a way of making it obvious who's boss. It's a way of intimidating others by proving that nothing, not even a noose around your neck all day, can intrude upon your consciousness, even a tiny bit.

And we all need a boss. Because if we didn't have bosses we wouldn't have people telling us what to do and how and when and how hard and how long. We would run wild in the streets, or maybe nap all day. Because we are not professionals and we do not have all-seeing knowledge and we are lazy and cannot possibly control ourselves.

The boss is not like that, wild in the streets and fun, but no one has ever been able to explain just why it is that the boss does not need supervision by another boss who is supervised by an infinite chain leading right up to, through, and infinitely beyond God. No one has ever explained why it's not supervisors all the way up. They just stop somewhere, and its them versus us. And we are seen as interchangeable and expendable parts and they are not, so limited in their numbers as they are. And to get us to do anything at all they have in one hand a stick, and in the other hand a carrot or a donut or maybe a dime.

Sticks have lately been deprecated in a public relations sort of way, so we hear a lot more about carrots, even from dictators. They've all got the PR religion now. It's always the "Democratic Republic" of somewhere and never Generalissimo Bob's Evil Hell Hole and Rotting Torture Cesspool, even if that's what it is.

And this attitude has infected business and the world of work.

They (the chain of bosses) have decided that a salary (including a few side benefits) is an unavoidable and necessary evil, but only a minimum. If you, Mr/Ms Expendable, want to make it on the job you have to show some flash and be able to snag a bonus. If you do you earn more but also avoid sinking into the bottom ten percent. You know, the ones who just get fired every year to keep the basement nice and clean, and because it's fun to fire people. Whoops! Looks like there's still a stick around after all.

But mostly it's reward time. Some kind of reward. Incentive pay. Gold stars to display at evaluation time. Real pay. Stuff you can use to keep your job.

And oddly enough, rewards don't work. They aren't real pay after all. We'll get to real pay next time, but right now let's talk about the kind of pay that rots your teeth and makes you hate your life and think longingly of how good that smooth, round, cold gun barrel would feel sliding in between your lips as your finger tightens on the trigger.

Hey, how crazy am I? Everyone knows that goosing someone with performance-based pay gets the juices flowing and turns a warehouse stuffed full of slackers into a lean, mean fighting machine. 'Cep'n 'taint so, love. 'Taint so.
To the best of my knowledge, no controlled scientific study has ever found a long-term enhancement of the quality of work as a result of any incentive system. In fact, numerous studies have confirmed that performance on tasks, particularly complex tasks, is generally lower when people are promised a reward for doing them, or for doing them well. As a rule, the more prominent or enticing the reward, the more destructive its effects. (Alfie Kohn, Education Week, September 17, 2003)
He has a good web site (www.alfiekohn.org/) and he's been at it a long time. His book "Punished by Rewards" is also good.

Kohn has found that
  1. Rewards punish. It turns out that rewards and punishment are two sides of the same coin, and that both are naked attempts at manipulation. Rewards don't usually hurt quite as much, though they can be just as humiliating as punishment can be.

  2. Rewards disrupt relationships. Rewards create winners and losers (usually one winner and a roomful of happy losers). Rewards foster enmity. Rewards discourage those who do well but not exactly quite well enough, according to some standard or other, which may be arbitrary. Rewards create pettiness. Rewards encourage people to work separately and not as a team. After all, why in hell should I help you when you're just going to screw me by winning?

    Some say that none of us alone is as stupid as all of us together, but unless you're the boss, or wearing a suit today, none of us alone is as smart as all of us. Can't be. So rewards make the business more stupid. And less competitive. (Irony alert!)

  3. Rewards ignore root causes. Got someone who's not quite doing well enough lately? Whack him with a stick, or if you're feeling really ornery, dangle a shiny trinket in front of his nose.

    Don't ask if his mother died, his kid is now a crack addict, or his wife just ran off with the babysitter. That shiny, twirling thingy will do the trick. And if it doesn't you can always fire his sorry ass. Who cares if he's done a great job for the past 10 years and knows the business better than you ever will?

    Rewards are blunt instruments, do not analyze causes or other messy things, and are simpleminded, and that's what we want, right?

  4. Rewards discourage taking risks. No one wants to screw up the possibility of getting that reward.

    So people will wait to hear what the ground rules are. They will want to be told what to do. And exactly no one will do something completely unexpected. You know, the kind of thing that could move their company into the next century like, oh, 50 years ahead of everyone else.

    Short-term goals, that's the ticket. And with a reward system in place, every activity becomes only another obstacle. There are no longer any opportunities, only hurdles to kick out of the way while you shove your way to the front.

  5. Rewards kill enthusiasm, even for things that people would do just for the fun of it.

    One group of children, told that they had to play with chalk before they could get to the felt markers began to hate drawing with chalk. The other group, told the opposite, began to hate felt markers. Children told nothing at all go nuts having fun with either one, or both at once.

    Any activity seen as a means to a reward becomes distasteful, strange as it sounds. Researchers keep finding this result over and over again, no matter how hard they try to find that rewards work.

    Rewards come to be seen as controlling, and everyone hates being controlled. People feel threatened, watched, constantly judged. As though they're forced to work only to meet deadlines, to be ordered around, and to be competitive toward others when really they want the opposite.

So
The best amount of competition in your company is none at all...competition itself -- which simply means requiring one person or group to fail in order that another can succeed -- is inherently counterproductive. Similarly, I’m not offering a 'soft' argument against competition, basing my objection solely on its destructiveness to us as human beings. I'm saying that competition also makes no sense from the perspective of the bottom line. It holds people back from doing their best. (Alfie Kohn www.alfiekohn.org/managing/nocontest.htm)

Yikes.

Money and goods are only one form of pay. Call it "official" or "external" pay. This is a baseline, a minimum-level compensation that comes with a job. Money is compensation for giving up part of your life and doing what you don't especially want to, what isn't inherently meaningful to you, or for doing things that aren't intrinsically rewarding, or for what is too hard or too frustrating to bother with otherwise.
When people are asked what's most important to them, financial concerns show up well behind such factors as interesting work or good people to work with. For example, in a large survey conducted by the Families and Work Institute, "salary/wage" ranked 16th on a list of 20 reasons for taking a job. (Alfie Kohn www.alfiekohn.org/teaching/edweek/meritpay.htm)
But there is another form of pay. Call it "unofficial" or "internal" pay. We'll look at this next time. This kind of pay is what you get for doing what is worthwhile. To you. As a real person. And not as an office machine.

Tuesday, September 18, 2007

Building a Ruby on Rails Contact Form

------------------------------------------------------------------------------------
CONTENTS
------------------------------------------------------------------------------------

How to build a contact form using ActiveRecord and ActionMailer

Introduction
Background..............................................general information
How To Do It............................................step-by-step instructions
General Notes...........................................programming issues and gotchas
Original Sources.......................................where I found the basic info



------------------------------------------------------------------------------------
INTRODUCTION
------------------------------------------------------------------------------------

Purpose: To create a contact form under Ruby on Rails allowing a site visitor to directly contact you from your web site. Using this form should prevent various automated software thingies from spamming you, as will happen if you go the usual "mailto:foo@bar.com" route.

These notes are based on "Simple Contact Form using a Table-less Model" found at www.bphogan.com/learn/pdf/tableless_contact_form.pdf (See more notes at the bottom of this piece.)

The point is to use the Rails model mechanism to handle error messages, but without having a database (or skipping the database interactions if you do have a database, because we don't really want to muck around with that just for sending email messages).


------------------------------------------------------------------------------------
BACKGROUND
------------------------------------------------------------------------------------

My host is Site5 (www.site5.com), and these notes apply to their system.

Start with a new application so you can play with it and keep it from interfering with any real projects you have. When you're ready you can do it over in production mode on your web site.

My version (what you see here) was developed on Windows. Change your paths and commands as needed to reflect the requirements of your own operating system.

Also, I'm assuming that you're first working in development mode on your local computer. Therefore you'll probably be using Webrick as a server and your copy of the file development.rb (config\environments\development.rb) will include the following setting:
 config.action_mailer.raise_delivery_errors = false

In other words, your application won't care that your email doesn't actually get sent, and in a development environment it probably shouldn't. Other people have managed to jigger their desktop systems to send email from a Rails application out through their home internet service providers. I don't care about that, so I'm sticking with the default setup where we just fake it (a.k.a a development setup).



------------------------------------------------------------------------------------
HOW TO DO IT
------------------------------------------------------------------------------------
  1. Here's a tree view of the directories and files you'll end up having for this toy application. It's a standard Ruby on Rails application but only the relevant directories and files are shown here.

    Note that this is a minimal, bare-bones "application". It has a home page (ix.rhtml), a contact page with a form on it (contact.rhtml), and a page which echoes the message, if it got sent (sent.rhtml).

  2. Mailtome
    |
    \---test
    |
    +---app
    | +---controllers
    | | application.rb
    | | home_controller.rb
    | |
    | +---helpers
    | | application_helper.rb
    | | home_helper.rb
    | |
    | \---views
    | +---home
    | | contact.rhtml
    | | ix.rhtml
    | | sent.rhtml
    | |
    | +---layouts
    | |
    | \---mailtome
    | contact_message.rhtml
    |
    +---config
    | | config.yml
    | | environment.rb
    | | routes.rb
    | |
    | \---environments
    | development.rb
    | production.rb
    | test.rb
    |
    +---log
    | development.log
    |
    +---public
    x_index.html (deleted by renaming; was index.html)

  3. I started in a new directory I called "Mailtome". Use whatever you want -- it doesn't matter (maybe -- see note later on). You'll end up working relative to the application's root. For this document it's called "test". So let's create the application called "test":
     C:\...\Mailtome> rails test

  4. Now switch to the application root (the test directory) and create a controller called "home":
     C:\...\Mailtome\test> ruby script/generate controller home

  5. Start the WEBrick server from the application root:
     C:\...\Mailtome\test> ruby script/server

  6. Open the application's default page in your browser by entering the standard URL (http://localhost:3000/) and verify that things are working. If so, you will get the usual "Welcome aboard You're riding the Rails!" page. You've seen this before. No surprises there.

  7. Now reconfigure your environment to make experimentation a little easier.

    1. Copy public\index.html to app\views\home\ix.rhtml (Note the change in file name and extension from "index.html" to "ix.rhtml".)

    2. Rename public\index.html to hide it from the application, or just delete it. Your choice.

    3. Configure the file config\routes.rb

      1. Open routes.rb

      2. Find this section at the bottom:
         # You can have the root of your site routed by hooking up ''
        # -- just remember to delete public\index.html.
        # map.connect '', :controller => "welcome"

      3. Assuming that your controller is "home", and the desired action is "ix", set the last two lines as shown here:
         # You can have the root of your site routed by hooking up ''
        # -- just remember to delete public\index.html.
        # map.connect '', :controller => "welcome"
        map.connect ':controller/:action'
        map.connect '', :controller => 'home', :action => 'ix'

      4. Now three things will work
        1. Entering "http://localhost:3000/" will take you to the home page (views\home\ix.rhtml) by default.

        2. Entering "http://localhost:3000/home/ix" will also do this. Yay!

        3. If you have a web page named "foo" (known as a "view" in the Rails world) in the view directory (app\views\home\), then entering the URL "http://localhost:3000/home/foo" will take you to that page. You won't need an explicit action for it in the controller.

          If you have a view with some other name, then it will also work, assuming that it exists and is stored with the other views belonging to the "home" controller.

    4. Manually create a file in the models directory called "tableless.rb". This is a file containing a table-less model (i.e., there is no database behind it). It will have the following contents:
       # ...\models\tableless.rb
      class Tableless < ActiveRecord::Base
      #----------------------------------------------------
      # create an array of columns
      #----------------------------------------------------
      def self.columns()
      @columns ||= [];
      end
      #----------------------------------------------------
      # add new column to columns array
      #----------------------------------------------------
      def self.column(name, sql_type = nil, default = nil, null = true)
      columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s,
      default,
      sql_type.to_s,
      null)
      end
      #----------------------------------------------------
      # override the save method to prevent exceptions
      #----------------------------------------------------
      def save(validate = true)
      validate ? valid? : true
      end
      end #class

    5. Create the file "contact.rb" in the models directory to extend the Tableless class that you just created.
       # ...\models\contact.rb
      class Contact < Tableless
      column :name, :string
      column :email_address, :string
      column :message, :text
      validates_presence_of :name, :email_address, :message
      validates_format_of :email_address,
      :with => %r{\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z}i,
      :message => "should be like xxx@yyy.zzz"
      end #class

      The explicit calls to "column" in this file are how you add new attributes to the model. This class works just like an ActiveRecord class, including the mechanism for using the standard validation methods, but the cool part is that you don't need to have a database.

      I chose to use just three items per email message: user name, user email address, and the body of the message. The example I based this on also asked for street address, city, state, zip and phone number. If you want to use those fields as well, just add them wherever the user name, user email address, and the user's message body are referenced throughout this example, and use the right format when you do that (i.e., be consistent).

      The last two lines in the Contact class are validators.

      The "validates_presence_of" line verifies the presence of required data (whichever fields you decide are mandatory) when someone uses your form to contact you.

      The "validates_format_of" line makes sure that whatever the user enters as a return email address, though it may be bogus, will at least have a reasonable format. The regular expression used was lifted straight from the Rails API documentation.


    6. Generate a mailer named "Mailtome" (this is an arbitrary name). The following command will create the file "mailtome.rb" in the models directory and an empty "...\views\mailtome" directory:
       C:\...\Mailtome\test> ruby script/generate mailer Mailtome

      Open the file models\mailtome.rb and you will see:
       class Mailtome < ActionMailer::Base
      end

      Edit this file by adding a delivery handler so it looks like this (the actual text of the subject field is up to you):
       # ...\models\mailtome.rb
      class Mailtome < ActionMailer::Base
      def contact_message(contact)
      recipients CONTACT_RECIPIENT
      from contact.email_address
      subject "Contact from my web site"
      body['name'] = contact.name
      body['email_address'] = contact.email_address
      body['message'] = contact.message
      end
      end #class

      Note: I used the minimum number of fields: name, email address, and message.


    7. Manually create the file "contact_message.rhtml".
       <%# ...\views\mailtome\contact_message.rhtml -%>
      Contact from my web site.
      ========================================
      User: <%=@name -%>
      Email: <%=@email_address -%>
      Message:
      ----------------------------------------
      <%=@message -%>
      ----------------------------------------
      Generated at <%=Time.now.to_s -%>

      This will constitute the body of the email message sent to you.

      Note: In "mailtome.rb" (the Mailtome model class) the values are stored in the @body[] array but are referenced directly here via clever magic behind the scenes somewhere, of whose inner workings I am totally ignorant. You can choose to have the time added, or not, and the wording in the heading line (where it says "Contact from my web site.") as well as the exact format are up to you. (So what else is new?)


    8. Code the controller actions.

      Earlier you created a controller named "home". It is in the file called "app\controllers\home_controller.rb", and it needs at least two actions, but I added a third one to make things clearer for me during development. (I need all the help I can get.) Here is the finished controller:
       # ...\controllers\home_controller.rb
      class HomeController < ApplicationController
      #----------------------------------------------------
      # show contact form
      #----------------------------------------------------
      def contact
      @contact = Contact.new
      end
      #----------------------------------------------------
      # process email
      #----------------------------------------------------
      def send_contact_request
      @contact = Contact.new(params['contact'])
      flash[:notice] = ''
      if @contact.save
      begin
      Mailtome.deliver_contact_message(@contact)
      notify_user
      rescue
      flash[:notice] = 'FLASH/RESCUE: Saved, then problems'
      render :action=>"contact"
      end
      else
      flash[:notice] = 'FLASH: Not saved'
      render :action=>"contact"
      end
      end
      #----------------------------------------------------
      # happens when mail successfully sent
      #----------------------------------------------------
      def notify_user
      flash[:notice] = 'FLASH: Saved and sent via notify_user'
      render :action=> "sent"
      end
      end #class

      This is what the various parts do:

      1. The first action, "contact", displays the input form to the user:
         def contact
        @contact = Contact.new
        end

      2. The second action, "send_contact_request", receives data from the user and turns the crank to validate and send the email.

        The first thing that happens is that it creates an instance of the Contact class just as though we had a database connected to the application.

        Then we call the "save" method on our contact object. The "save" has been overridden so it doesn't actually save anything (because we're not using a database).

        If OK so far, we then invoke "deliver", a class method of Mailtome. This indirectly calls our contact_message method via the call: "Mailtome.deliver_contact_message(@contact)".

        The "validates_presence_of" and "validates_format_of" validators in the Contact class check for problems. But even if all fields are filled you can still have garbage data.

        The email address does need the right format. There is no way to guarantee that it's a real email address, but it should at least look like one (it's the best we can do). If you type something like "jdsflk;sdkj@sd,fmas,.com" or "@.123" it won't work. Those pesky "special" characters or an odd format will cause the sending process to fail.

        The right format is "xxxxx@yyyyy.zzz", with one @ sign and one period, each in the right place. The "xxxxx", "yyyyy", and "zzz" parts just have to be there -- their length is not checked, except for the "zzz" part, which has to be at least two characters long, if I've read this the right way. The regular expression came right out of the Rails framework documentation under "validates_format_of" and it's good enough for me.

        OK, if something does go wrong with the send process, then the rescue clause will kick in and bounce the user back to the contact form. Once there the user can see an error message in the flash buffer.

        In case the "save" didn't work, and we never got to the send step at all, then once again the user is bounced back to the contact form, but this time with a different error message in the flash buffer.

        The "validates_presence_of" and "validates_format_of" routines will provide error messages in a production environment.

      3. Action three, "notify_user" affirms to the user that the email was sent. It does this by redisplaying as confirmation back to the user the user's name, email address, and the body of the message via the "sent.rhtml" page.
        Note on Flash messages: This is a test program in a development environment. I designed these messages to be minimally meaningful for me. Use what's right for you. You may not want flash messages visible in a production environment, so you can comment them out, while leaving them there, in case you need to do some tweaking again later on.


    9. Add the "sent" page: "sent.rhtml". (Nonessential HTML and CSS are excluded here for clarity, but are based on the default public\index.html page.)
       <%# ...\views\home\sent.rhtml -%>
      <body>
      <div id="page">
      <div id="content">
      <div id="header">
      <%= link_to "Home", {:controller => "home", :action => "ix"} -%>
      <br /><br />
      <% if @flash[:notice] -%><div><%= @flash[:notice] -%></div><% end -%>
      <br />
      <h1>Message sent</h1>
      </div>
      <br /><br />
      <p><strong>Your Name: </strong><%=@contact.name -%></p>
      <p><strong>Your Email Address: </strong><%=@contact.email_address -%></p>
      <p><strong>Your Message: </strong></p>
      <p><%=@contact.message -%></p>
      <p><strong>Sent at: </strong> <%=Time.now.to_s -%></p>
      </div>
      <div id="footer"> </div>
      </div>
      </body>

    10. Create a Qwik-N-Dirty (TM) form in "contact.rhtml". (Nonessential HTML and CSS are excluded for clarity, but are based on the default public\index.html page.)
       <%# ...\views\home\contact.rhtml-%>
      <body>
      <div id="page">
      <div id="content">
      <%= link_to "Home", {:controller => "home", :action => "ix"} -%>
      <% if @flash[:notice] -%><div><%= @flash[:notice] -%></div><% end -%>
      <%=error_messages_for "contact" -%>
      <%= form_tag :controller=>"home", :action=>"send_contact_request" do -%>
      <p>Name <%= text_field("contact", "name") -%></p>
      <p>Email <%= text_field("contact", "email_address") -%></p>
      <p>Message<br />
      <%= text_area("contact", "message", {"cols"=>"40", "rows"=>"5"}) -%>
      </p>
      <%= submit_tag "Send" -%>
      <%= end -%>
      </div>
      <div id="footer"> </div>
      </div>
      </body>

      Note: This is the newer form syntax. The "start_form_tag" syntax has been deprecated.


    11. Configure the ActionMailer environment. Note: You can hard-code the values into "...\config\environment.rb", or put them into a "config.yml" file as shown in step "2" here.

      1. Open "...\config\environment.rb" and add the following lines at the bottom of the file (extra whitespace added for clarity). We're assuming that you are using SMTP to send email:
         # ...\config\environment.rb
        ActionMailer::Base.delivery_method = :smtp
        c = YAML::load(File.open("#{RAILS_ROOT}/config/config.yml"))
        ActionMailer::Base.server_settings = {
        :address => c[RAILS_ENV]['email']['server'],
        :port => c[RAILS_ENV]['email']['port'],
        :domain => c[RAILS_ENV]['email']['domain'],
        :authentication => c[RAILS_ENV]['email']['authentication'],
        :user_name => c[RAILS_ENV]['email']['username'],
        :password => c[RAILS_ENV]['email']['password']
        }
        CONTACT_RECIPIENT = c[RAILS_ENV]['email']['contact_recipient']

      2. Create the "...\config\config.yml" file like the following, but with your own values as appropriate for your own needs. The development settings don't really matter. For this example, we'll assume that your:
         domain is "www.foobar.com"
        username is "fred"
        password is "secretpassword"
        send-to email address is "fred@gmail.com"

        # ...\config\config.yml
        development:
        email:
        server: mail.development_foobar.com
        port: 25
        domain: development_foobar.com
        authentication: none
        username:
        password:
        contact_recipient: fred@gmail.com
        production:
        email:
        server: mail.foobar.com
        port: 25
        domain: foobar.com
        authentication: login
        username: fred
        password: secretpassword
        contact_recipient: fred@gmail.com

    12. After each test run you can view the "sent" email on the "sent" page ("...\views\home\sent.rhtml") or by viewing the contents of the development log file "...\log\development.log" (this file is also helpful for debugging).

      For your production environment, use the production log file "...\log\production.log" instead.



------------------------------------------------------------------------------------
GENERAL NOTES
------------------------------------------------------------------------------------

The other ActionMailer examples I've found were all designed to automatically send email out to a customer after some event (i.e., an order is received or filled).

What I wanted was a form that a visitor to my site could fill out and use to send email to ME (i.e., email sent from my own application to my personal email account).

Using the example in "Agile Web Development with Rails" helped a little but not much. That example uses the aforementioned auto-generated email process, and the example is too loose to clearly explain exactly what's happening. Hey, I'm slow but I can't help it. I just didn't have enough info to puzzle it out.

I developed this toy application from a sample published under the name "Simple Contact Form using a Table-less Model". I found it at www.bphogan.com/learn/pdf/tableless_contact_form.pdf (Copyright 2006 by Brian Hogan.)

This helped a bunch but I still had a few problems with the original sample I needed to work through, such as:

  1. Flash messages were not hooked up to anything, which made them invisible and therefore useless (Duh). I realize that this is a minor quibble, but I'm not as smart as everyone else, and can't see invisible things, so I changed that.

  2. In the original example the data item "column :email_address, :string" was referred to in the file "contact_message.rhtml"
     as Email        : <%=@email -%>
    instead of Email: <%=@email_address -%>

    This made the message delivery fail at the line that read
     "Mailtome::deliver_contact_message(@contact)"
    in home_controller.rb.

    This was a major time-waster and took me way too long to work this out. Since I had no idea if the original sample actually worked I wasn't sure if there was a problem with it or with me. (My second Duh moment. And yes, I introduced a lot of my own problems and mistakes along the way -- there's always enough blame to go around.)

  3. The original sample uses a model mailer called "Mailer". This didn't seem to work right for me. Maybe the environment got confused by a mailer called Mailer. Things got better when I renamed it to "Mailtome".
     original  :  ruby script/generate mailer Mailer
    my version: ruby script/generate mailer Mailtome <-- Notice the clever change.

  4. The original sample of "...\models\mailtome.rb" has syntax differences from the example shown at http://api.rubyonrails.org/classes/ActionMailer/Base.html. This also seemed to give me some problems. I originally had so many problems that I can't remember them all, but watch your syntax.

  5. The author of the original sample uses some verbal shortcuts and his code is a little too sparsely commented for my taste. My version should be more obvious.

  6. There was one more thing that I wasn't sure of.
    In the original example, in "home_controller.rb", in the action I call "send_contact_request", there is a line which originally read
     "Mailtome::deliver_contact_message(@contact)"

    Originally I thought this was a problem, but it's not. For clarity though, in keeping with more standard OO notation, I changed it to
     "Mailtome.deliver_contact_message(@contact)".

    Note the original "::" vs the changed ".". In the book "The Ruby Language" by Dave Thomas, these examples are given:
     Foo.Bar()      # method call
    Foo.Bar # method call
    Foo::Bar() # method call
    Foo::Bar # constant access

  7. If you configure "perform_deliveries" or "raise_delivery_errors", (in "...\config\environment.rb", if you set up things there) then remember which settings you want to use:
     ActionMailer::Base.perform_deliveries = true | false
    ActionMailer::Base.raise_delivery_errors = true | false

    You can also set these for production in "...\config\environments\production.rb" as:
     config.action_mailer.raise_delivery_errors = true
    config.action_mailer.perform_deliveries = true

  8. Another thing: At least on Site5, for the "address" or "server" denoted in "environment.rb" (or in "config.yml" if you use that), you need to prefix the server name with "mail.". So assuming your domain name is
     foobar.com
    then this line should be
     mail.foobar.com
    Granted, I'm not as bright as all of you, so this took me a while to figure out, along with all the other odd problems along the way. I kept getting erratic results when I got something wrong. Duh, yet again. The thing would work for several tries, and then stop, and wouldn't restart. I'm still not sure why.

    I've learned the hard way that it doesn't do much good to get something working and then forget how I did it. No point in doing all the research and development work more than once. MUCH easier just to read from a clear set of notes that I made for the benefit of my future (and less intelligent) self. That's why I wrote this up. No doubt you are much smarter, so ignore whatever you don't need to remember.

  9. If suddenly your whole production web site stops working (like you can't even bring up your home page), then carefully review all your config and environment files. It really helps to keep a complete set of versions of each file as you work. I usually do something like the following for each file I change.
     environment.rb
    environment.rb.2007_08_08A
    environment.rb.2007_08_08B
    environment.rb.2007_08_08C
    environment.rb.2007_08_09A
    environment.rb.2007_08_09B
    environment.rb.2007_08_09C
    environment.rb.2007_08_09D

    In this example "environment.rb" is the current file, and the latest copy matches it (in this case "environment.rb" has the same contents as "environment.rb.2007_08_09D"). I keep these versions on my desktop system and upload only the latest version to my web site.

    If I need to backtrack I have the exact version at hand, viewable in an instant, no guessing needed.

    Once I'm sure that I have things nailed down I can archive the changes and/or feed them into my version control system and delete the various intermediate copies.

    Manually-created files take some effort but can be a real godsend if I screw myself up so badly that I have to start over. And it has happened. I have had to go back a week or two (on the job, no less) and rewrite something from memory. It's much easier to roll a file back a version or two than to recreate several hundred lines of original code from memory. Whether or not you have a boss watching. A version control system may not guarantee you know which change you need to go back to either, if you're juggling a lot of files and making quick changes all day.

  10. When you change anything in the config directory tree, it's likely that you'll have to restart your web server. If you are working in development mode on your desktop with Webrick, this is really easy. If you are working on your production site, and you will have to, when you install this, then you need to know how to restart Apache. If
     1 - your logon id is "foobarx", and
    2 - your password is "secretpassword", and
    3 - you are using fastcgi, then the following command will restart your
    production server (at least on a shared server)

    pkill -9 -u foobarx -f dispatch.fcgi

  11. Watch your version of Rails. If it's different on your desktop from what you have at your web site, you can suddenly see things stop dead and have no clue. Make sure that the environment variable "RAILS_GEM_VERSION" in "environment.rb" is correct.

  12. One final thing on sending email to yourself: If your site is www.foobar.com, and your email address for that site is "info@foobar.com", and you have email auto forwarded from "info@foobar.com" to an account like "fred@gmail.com", then use "fred@gmail.com" as the email address inside your form-based system and not "info@foobar.com".

    In other words, don't send email from www.foobar.com through "mail.foobar.com" to "info@foobar.com". Send it from www.foobar.com through "mail.foobar.com" to an outside account.

    I've found through trial and error that sending mail through "mail.foobar.com" to "info@foobar.com", and expecting it to be forwarded to "fred@gmail.com" works sometimes and sometimes it doesn't. It also can work perfectly for a while and then stop dead and not work again.

    I also can't reliably send email from "fred@gmail.com" to "info@foobar.com", if "info@foobar.com" forwards email back to "fred@gmail.com". If I want to test my email system without using the contact form I have to send from another email account to "info@foobar.com", and wait for it to show up at "fred@gmail.com".

    OK, maybe I'm especially dumb and missed all the basics somewhere, and shouldn't have tried half of the stuff I did try, but I believe I now have a reliable system.

    At one time I had it all working and then my ENTIRE site locked up SOLID for no particular reason that I could fathom. Nothing I tried would make it work, so I had to delete everything and rebuild the whole site, including uploading over 700 image files. That is not fun. There seem to be some obscure interactions going on somewhere in the background, and I believe that I've gotten around them all.


------------------------------------------------------------------------------------
ORIGINAL SOURCES
------------------------------------------------------------------------------------

1 - "Simple Contact Form using a Table-less Model", at http://www.bphogan.com/learn/pdf/tableless_contact_form.pdf This is based on the following.

2 - "Tableless model" from Rick Olson - http://rails.technoweenie.net/tip/2005/11/19/validate_your_forms_with_a_table_less_model

Note: This second URL doesn't work for me. You can try to find the original idea at http://weblog.techno-weenie.net/ or http://techno-weenie.net/

Friday, May 04, 2007

Work, part 2: What is pay?

Do you do it for money?

Some say that if you do, that makes you a pro. Some say that being a pro means you do things that are right, even if doing them costs you money. In other words, it's your integrity that's important, not your bank account.

But what is integrity good for? It gets you more business and a higher rate of return. Customers will come to you because they know that they can trust you, and that you will do for them what they can't do for themselves. And they will pay more for your goods or services than for those from someone else because they have a sort of guarantee.

Your integrity removes one more variable from the process. You provide dependability and that can be important, because it means preventing a whole bunch of things.

It means preventing a whole bunch of things from suddenly rising out of the ground like the evil spirits of the dead in one of those horror films. The ones where a nice suburban house has been built on a graveyard by unethical developers. And then the dead get irritated. And then get even. Customers don't like it when they have to deal with armies of the angry dead.

So, because you provide dependability, you also provide simplicity.

Your extra thought, and work, and integrity heads off a lot of bad things and removes the possibility that they can happen. This removes you from competing as a commodity provider. You are no longer working on the basis of providing the lowest price.

Thinking about professionalism just brings us back to pay. But no matter what, pro or no pro, you need to be paid. Money in the business world is like food for an organism. No food, no life. No income, no business.

A business needs to eat, and so do the people who make up the business. You can say that there are two levels of need here, one for the business, which has to make a profit, and one for the employees, each of whom has to earn a living. Profit goes to the business owners, and pay goes to the staff.

Thinking a little deeper you can see it involving three entities: the business, the staff, and the owners of the business, each with their own needs. And customers on the outside looking in.

But it's even a bit more complicated than that.

There is really no business. A business is an abstraction. If we stop thinking about it, it goes away, because a business exists only in our minds.

The reality is that there are just people, and the business is an idea that all of them agree to hold in their minds. The reality is that there are just lots of people linked by relationships to one another, and all of them want something from the relationships that they are in.

A person I once worked with told me that the purpose of business was to provide jobs for people. Not everyone would agree with that. I didn't, at the time. There is a common understanding that the purpose of a corporation is to maximize shareholder value, and there have been many legal rulings that poked at this issue. *

But the more I've thought about what my colleague said the more I agree with it. Not fully, since there are more people involved in any business than just the employees, but taking a broader view, it makes more sense.

The two fundamental ideas to keep in mind are that any business is solely human relationships, and that no one ever makes a profit.

Human relationships: Without humans, there is no business. Of any kind, by any name. The sole value of any business lies in the people who work at it (not just those who "own" it, not just those who "run" it, and not just those who are "employed by" it).

Remove the people and there is nothing left whatsoever. Don't think that you can fire all the staff and keep it going with different "hires". We're talking about permanently removing all the people. It is much clearer when you think of it that way. Remove the people and there is no residue. Only emptiness.

Profit: (A) Everyone dies. (B) You can't take it with you. (C) End of story.

Passing along wealth to others, again, does not count because you no longer exist, therefore you have no profit. Inherit money or other property, or just find a box of hundred dollar bills in an alley, and it may be fun, interesting, confusing or something else entirely, but you still make no profit. As Homer Simpson once said about beer, you can only rent it.

Everything is temporary. This means your profit too.

And this means you.

So that kind of makes money or other property look a little strange. And business as well.

What is pay, after all, then?


* See "The cyclical transformations of the corporate form: A historical perspective on corporate social responsibility" for some background http://www.law.umich.edu/centersandprograms/olin/abstracts/discussionpapers/2005/05-003aviyonah.pdf

Tuesday, April 10, 2007

Work, part 1: What is it?

What is work?

It seemed so easy in physics class. Maybe that's one reason that I majored in physics, after assuming that my first, English degree was not quite the right thing.

"Work: a transfer of energy from one object to another by applying a force over a distance."

Oh, so sweet and simple. And understandable. And quantifiable. Even amenable to use on multiple-choice tests, or to probing by means of electronic calculator. Define the problem using a couple of variables, enter the numbers and get a result. Check your work, and then write down the answer. Problem solved.

There is a lot of discussion every day about what work actually is, for the rest of us, we who have moved outside the classroom and have had it hit us in the face. Some say things like "All paid jobs absorb and degrade the mind." (Aristotle)

That's one point of view, perennially espoused, sagely followed up by another thought: "When a man tells you that he got rich through hard work, ask him: 'Whose?'". (Don Marquis) We've barely gotten started here and we can already cut the cynicism with a knife. Even worse, we have to carry that knife in self-defense.

But soon we begin to drift, if we keep listening, keep thinking, toward sentiments like "Getting fired is nature's way to telling you that you had the wrong job in the first place". (Hal Lancaster, in The Wall Street Journal) Then this: "Nothing is really work unless you would rather be doing something else". (James M. Barrie) Both of these sentiments are also familiar to everyone.

But it goes beyond that.

"Do not hire a man who does your work for money, but him who does it for love of it". (Henry David Thoreau)

"The more I want to get something done, the less I call it work". (Richard Bach)

And one more, out of another famous life: "Far and away the best prize that life offers is the chance to work hard at work worth doing". (Theodore Roosevelt)

And summed up by "Whenever it is in any way possible, every boy and girl should choose as his life work some occupation which he should like to do anyhow, even if he did not need the money". (William Lyon Phelps)

So what is work? We still don't agree. It can be agreeable or not, for pay or not, long, short or in between. It's something or other, but seems to divisible into two entities, sort of related, like second cousins who barely know each other.

One kind of work is forced onto a person's life and the other kind grows out of it. Let's assume that both types are compensated in some way. We can assume that all work is compensated in some way, even if it's only a payment in food and shelter and a cessation of the beatings.

Let's also assume that work is a more or less directed activity that has a tangible result.

Hammer a horseshoe out of a lump of red hot iron and you have a horseshoe. No disagreement there, it's tangible.

But so is a poem, even if unwritten. You know it's been produced because you can encounter it: it's either written or recited.

So work is more than just thought, more than daydreaming, more than idle planning. Albert Einstein produced magnificent thought experiments but they weren't done until he had shared them, and at that point they joined the body of his life's work.

So work has a result, and it generates some kind of compensation.

(Quotations found at http://www.quotationspage.com/subjects/work/)

Friday, March 16, 2007

Corporate HR Marketing, or not

I'm still evolving. I hope you are too. It means you're alive. Possibly troubled, but alive.

I got contacted this week by what appeared to be a good employer. On the surface it appeared to be a good job and a good company. Maybe better than that, even. Maybe great.

The opening words to my reply were: "I thought I'd deleted my resume from every place it was posted, after getting spam for .Net jobs in New York City for about two months, so was surprised to hear from you. But that's OK."

The part of the recruitment announcement that caught my attention was "our development philosophy is to write software correctly the first time, without shortcuts; to build reusable components whenever possible for use across all of our development projects; and to ensure that our existing code base is our biggest asset, rather than a liability."

Yow!

Then they went on to say how one of their people was working on an Ajax tool to generate scaffolds in Ruby on Rails.

Yow! They work with Rails!

Of their 10 requirements, I met nine, but not the first, Ruby on Rails experience in production applications. I've been trying but haven't made it there yet. Possibly due to sloth. To get there, since I have no experience, I'll have to manufacture experience, by going out and finding freelance work, which then may still not qualify, in the eyes of an employer.

But what's a fella gonna do, I ask yers, what then?

I decided not to strain myself by leaping at it. The job is in an isolated city of 30,000, and the person who contacted me, the company's technology manager, has the same name as someone who went to school in that town, and has been active in posting comments about religious subjects hither and thither.

I've been lucky enough to have had lots of fun experiences in life. Among them being trapped in a small town, and working at small companies owned by families who gossip about their employees over lunch, and being approached by my boss and given religious pamphlets to read. And most fun of all, not all at the same place, so it wasn't just one scary black hole in a world full of light and the smell of roses.

Still...

Then, thinking more, several other things about this company began to worry at me with little teeth. They started in 2001 with two employees and had 60 as of a year ago. Why? Why do they need so many, and how does this mesh with precision software development? Wouldn't you expect to find people throwing things around, just to get their work backlogs down? And wouldn't you expect there to be a lot of chaos?

I think you would, no?

Thinking more, a process which may or may not be good for me, but which I can't quit (though I did give up smoking many long years ago), I began wondering what made this company special.

They have a good idea. It's sort of like a social networking site to pre-qualify contractors and bring them together with customers for home improvement work, plus some glass and automotive stuff mixed in as well. Brilliant idea, in fact. Nearly recession-proof.

But they advertise dead plain and simple, just like everyone else. When you read the ideas they lay out and think back, what you imagine is just another business. You don't think fun, quirky, imaginative and welcoming workplace where you can finally fit in and make a difference.

What you think about is all those classified ads you've read over the years that all say exactly the same thing in the same way, some better than others:

CORPORATE
Research & Development


To become a recognized leader in the food industry it takes a successful pattern of constant growth with many new and innovative projects on the horizon. A true phenomenon occurs when brilliant research minds meet the challenge of a technological society. At Star-Kist, makers of 9-Lives cat food, and Jerky Treats dog snacks, we are committed to this through the caliber of our employees. If you would like the opportunity to show what you can do, we have something for you...

Successful candidate must have experience in pet foods or low-acid canned foods...

Right. You can hardly avoid stepping in it.

So back to "my" company:

We reward ambition with a pay-for-performance plan that includes a competitive compensation package, including bonuses for meeting/exceeding performance goals.

Which, as I noted in my reply, could mean that they have a really great place, or it could be all knife fights all the time, winner take all, or it could be so-so yawn time. Can't tell. Can't see anything through the haze of HR bafflegab.

By this time, of course, I'd decided that I didn't want to drive 300 miles for an interview just to be told that they really wanted someone with paid experience, just as they'd said, so I had nothing to lose and was honest.

But I was trying to be helpful. Really. I pointed out some things like this, like how their words were really great but how they nevertheless sounded like just another PR machine. I've been burned before. You can tell, can't you?

More snooping around their web site paid off. They offer six days of vacation the first year, nine the second, and then it shoots up to 12 days and stays there forever. Six days a year? This is a cutting-edge company? I'd rather get more time off instead of a raise, or better yet, get time to do interesting things on the job with a flat two weeks a year. Never mind that Australians and Europeans expect a month, no questions asked.

What happens when a staffer exceeds expectations, say? What if I worked there, and invented a way to shave eight hours a week off the time for my tasks? What would they let me do with that extra day? Would they even think that way? Would they ever assume that the time was then mine?

Hard to say, but I bet not. I bet they grind. Grind through the work. Grind out profits. All of which is OK, but where is the payoff? What do you get for working besides enough pay to keep going? What do you get to feed your soul?

They don't say.

As I said clearly in my resume, I'm a generalist. I do lots of things, most of them well and a few exceedingly well, and am looking for a place where I can make a difference doing interesting things in a supportive environment. (Three things, count 'em.)

I think of Humanized, which I stumbled on recently (http://www.humanized.com/about/). I get the idea that I'd like to send these people money just because they deserve it. It's clear that they're all so smart that they'd never even let me shine their shoes, but if somehow I ran into one of them at a party, I'd probably have a lot of fun, and learn so much that my head would hurt for weeks.

They present themselves as a few people on a mission. It sounds as though they really care about what they do and why they do it, and as though they have at least three or four major interests, each, outside of their work. This message is clear and engaging. They are different.

They aren't recruiting, but if they were, people from everywhere would be climbing all over each other to get there. It's absolutely clear that they are not the same old whatever.

And that's why I'm still unemployed, or, um, er, still in the process of getting my company started.

Yes. That sounds much better.

Damn. Did I just outsmart myself again with all this thinking?

Ahem.

Tuesday, February 13, 2007

Jobster, a thing whose whatever may or may not have come.

"What is the Jobster service?

"Jobster is both a networking site for professionals and an online recruiting service for employers. We work with employers to help them find great people, and we work with professionals and jobseekers to make it easy for them to search jobs from across the web, get the inside scoop on company culture, and get referred for jobs." So they say.

Yay. We got another.

It looks purty, real purty. Folks should like it, maybe. Dunno, but it's trendy. That aint good or bad, it just is. Life is like that.

I've had an ad off and on with Craigslist for several months now. A couple of people contacted me about building social networking sites. They want to do Facebook. And they want someone like me to build it and then they'll pay when the money comes rolling in. Sounds good, damn near foolproof.

Conceptual, you see. Someone gets an idea, puts it on wheels, and watches the money come pouring in through the chute they built just for that purpose. Then everyone else wants to do that too. Easy, once the idea is there. Or the new, shiny, squeaky-clean design. Wow. I want one just like that, and by the way, if you build it, I'll pay when I'm rich.

Maybe, maybe not.

Jobster is fancy, and it's basically a good idea. I'm not sure if it will work, but then I don't have to worry about that one.

Seems kind of sterile, given its purpose, which is what by the way? Oh, yes, bringing employers together with job seekers for mutual satisfaction.

Yes, that was it. But can't employers scan resumes elsewhere? They wouldn't necessarily want to go browsing through pages of embarrassing personal drivel (see below). Maybe Jobster is a or will be a resource for people with compatible skills and like interests to find each other and set up businesses, somehow or other.

That one might work. Maybe that's why I put my info there. Sounds good to say it that way in public, case anyone asks. I should say it like that. Case anyone asks.

Bye.

Q & A with the Jobster robot:

Q - What's your New Year's resolution?
A - Eat more hamsters. It's probably never too late to start, but I'm not sure I have the stomach for it, never having sucked on or even licked a hamster, dead or alive, cooked or raw. Luckily for me and the hamsters, everyone slides on resolutions, and I'm gonna too.

Q - How would your boss describe you?
A - Luckily I don't have one now, which is OK except for the pay. But I've always gotten good performance evaluations. I tend to think that what people put down in writing is the real deal.

Q - How would your co-workers describe you?
A - My sister says I'm weird. This is also something that each person I've ever thought of as a friend has called me. My mother said that whenever she heard of some quiet guy, some polite, good student who was always nice to everyone, who suddenly went nuts and murdered everyone around him, she thought of me. But I've never done that. No, really, I mean it. Not even once. Most of my coworkers have been clock watchers and lifers. The kind of people who know a comfy kennel when the see it, and do a little work between coffee breaks, now and then. The kind of people who get angry when they are expected to work. I've never understood that, or fit into that group, and so have often been considered a jerk. Even though I'm polite, and quiet, and always nice to everyone. I hope I didn't disappoint my mother.

Q - What advice do you have for someone who wants a job like yours?
A - I'll trade ya for it. Positive view: I'm self-employed. Negative view: I'm unemployed. (Though I have so much to learn that I have no spare time.)

Q - What are the most challenging aspects of your job?
A - Problem solving. Being creative. But most of all, not being supported by management, which has happened. When you work with difficult or naive customers, and then your own team cuts you off at the knees, well then you have to wonder just what the point is. Kind of embarrassing to say so at the moment, given that I'm working by myself, but I'm dreaming back in time when I had a salary and health insurance and coworkers, I think. Gets fuzzy sometimes.

Q - What are the most rewarding aspects of your job?
A - Of any job: the chance to crack a problem in a creative way. I've often been ignored because I analyze a problem, come up with a solution, test it, design it, build it, test the completed work, put it into production, and no one ever hears about it again. In the software world, you get credit for creating crap as quickly as possible, and then riding in for several evenings and weekends of hacking until the thing finally works. People get awards for that, but not for doing something right the first time. Go figure.

Q - What are you most passionate about?
A - Backpacking. Mornings. Pussycats. Hamsters. Keeping the pussycats separated from the hamsters. Quiet moments. Forests. Love.

Q - What companies would you most like to work for?
A - The perfect one, the one, the only, if only it would make itself known to me. And yet I wait and wait and it is not yet revealed.

Q - What do you want to do when you grow up?
A - A friend of mine always wished he was an artichoke. He seemed to have a direction. I keep looking. I once knew a woman (a cat lady) who wished she was covered in fur. I'm not so sure about that.

Q - What have your past employers loved about you?
A - None of them have been quite so bold as to express their feelings in such a way. I show up, which is 80% of life. And I work hard, and in good faith, which seems to be about 0.0005% of life. I focus on the work and training myself, and being more efficient this time around than last time, which is about another 0.000016%. Most people seem to like genial idiots. I prefer to be a genial idiot on my own time, but maybe I've been doing it wrong all these years. Could this be?

Q - What kind of job are you looking for?
A - A chance to make a difference at some place that is making a difference. An opportunity to use many of my multiple personalities: thinker, analyst, writer, editor, photographer, generally sane person, designer, developer, project manager, problem solver. A job at a place where people collaborate and work for a common goal, in good faith.

Q - What makes you a great coworker?
A - I try to pull my weight, be good to people, be respectful and tactful, cooperative, and I always seem to get the short end of the stick. The people who get ahead (in places I've worked) have been aggressive, arrogant, and sloppy. Maybe I should have tried harder to hate people and show it, to claim the work of others as my own, to bluff and bluster and browbeat, but instead I've always tried to get work done, to be modest and helpful, and to share credit for work well done. I guess I'm really dumb.

Q - What makes you a great employee?
A - If it isn't what I've said in my answer to "What have your past employers loved about you?", or the opposite (being a genial idiot) then I don't have a clue. Maybe I should be now clueless. Maybe that would work.

Q - What path did you take to your current career?
A - Good will, hard work, constant learning, creativity, inventive solutions. And then they eliminated my job. Go figure.

Q - What profession other than yours would you like to try?
A - I've been a technical writer, a darkroom technician, a museum designer, a newspaper reporter, a formal and informal student. I've driven truck, written a book, finished a B.A. in English and a B.S. in physics and computer science. I've been an analytical chemist, bicycled around Mt Rainier, from Seattle to Portland, and from Seattle to Vancouver (the exotic one). I've spent thousands of dollars of my own money on training for the sake of my job, and have used personal software and equipment when my employer would not provide it. I've been a long-time photographer, and do digital now. Who knows what might be next?

Q - What special qualifications do you have for your dream job?
A - You mean being a hamster rancher? Well, I just can't get enough of the little critters. They're just endlessly fascinating. One of my favorites used to bathe every evening when he got up (which they all do). I kept a deep pan of fine sand in the hamster cage (they go nuts over it), and I once watched him wash himself twice. It took 45 minutes before he was ready to snuffle around all night. I'd love to have a large herd and watch them flowing over the landscape, as far as the eye could see, nothing visible but tiny furry rippling backs.

Q - What was your best business trip experience?
A - Boy, we're scraping the barrel here. Business trip experience? Like I've ever gone anywhere on business? About all I've done is pay my own way to go off and get training. I guess I'd have to qualify that as my trip to Santa Barbara to spend a week learning Eiffel directly from Bertrand Meyer, one of the founders of object orientation. Too bad the world got stuck on C-based languages. Eiffel reached its peak of visibility about the time that Java came out and the ignorant herds abandoned C++ for Java without giving any thought to what was really wrong with C++ or C in the first place. And now we have Java as the world's number one programming language, and people getting itchy and squinting around for something else, without ever having thought things through from first principles. Oh, dear. Here we go again.

Q - What was your best interview experience like?
A - Ordinary life -- no threats, no tears, no diarrhea, no fear. Even some laughter, and not directed at me, for once.

Q - What was your first job?
A - Working for Tom Levi at Northwest Mapping Co. in Bismarck, North Dakota. He was a great guy but somehow or other didn't feel the need to pay me. I mostly ran an Ozalid machine to make blue-line copies of oil lease maps (and architectural drawings, and so on). "Trademarked copying process used to produce positive prints from drawn or printed materials or film, such as printing proofs from film images. The film is placed on top of chemically treated paper and then exposed to ultraviolet light. The image is developed dry using ammonia vapor." I love the smell of ammonia. Tom claimed that even though he smoked constantly and often had two or three cigarettes burning simultaneously, the ammonia fumes protected him. I can't say. All I know is that I still love the smell. Even better than a freshly-washed hamster.

Q - What was your most bizarre interview experience like?
A - I once drove from Bellingham to Olympia (about 150 miles) for an interview with a State of Washington agency, and when I sat down with the interviewers, they asked me if I had any questions. That was the interview.

Q - What's your dream job?
A - Being rich, the same as everyone else's. Barring that, hiking the Continental Divide Trail.

Q - Who are your role models?
A - Now you're cheating. This is the same as the "mentor" question. See that. If you're too lazy, then know that I steal from everyone. Guys are like that. We come in kit form and have to assemble ourselves from the pieces that come our way. Women seem not to need this sort of thing, but most guys are assembled from assorted parts. If I see someone doing something that seems good, I try to do that too. I add it to my act.

Q - Who was your most influential mentor and what did they teach you?
A - Everyone, both the good and the bad. And the others, the ordinary, everyday heroes all around us. I have no personal heroes but I learn constantly, or try to. Sometimes it takes a bit, but things eventually sink in. I've learned much from walking empty trails and watching the night sky, from learning self-reliance, and the value of good friends. As long as life goes on, there is always another chance to improve.

So will you, like, hire me now? Please?

Monday, January 22, 2007

Getting Your Head On Straight

There is a fundamental problem in building software, and that is deciding what to build. It's fundamental because everything else rests on this one decision, and it's often overlooked, or made in the wrong way. Because everything else depends on it, you have to start at ground level, from first principles, if you want to make a sound decision.

Thinking from first principles is simple but hard. Very hard.

The need for a piece of software may come from several directions. It may arise because of a critical need of the business. Then again it may be only a perceived need. It could be an impulse, driven by one strong personality or the tide of politics internal to the business. This would not be good.

You may need software because of new laws to comply with, fear of competition, or just because you're feeling a little behind and want to keep up with trends by copying everyone else.

A good reason will arise from a true need, and if carried through it may result in a real benefit to your business. If you're working from faulty principles, though, you'll not only have a poor foundation but a poor result.

You need to know your business through and through. And your customers. One way or another you're in business to do something for someone else, something they can't do, or don't want to, so they come to you. If you can deliver they'll be glad to pay you what you need to get by. But you do have to keep their needs in sight.

Somewhere along the way you'll have to deal with staff, even if you're self-employed. The people you employ are the experts in running the business. They know how things work, and when, and all of them are acutely aware of exactly everything that doesn't work. They are your surface of contact with customers, the membrane your business breathes through, its nerve endings.

Staying close to your customer's needs is critical, but so is anticipating where they might be going, so you need to make your decisions match the long term interests of the business. With the customers, and your staff, and the long term in mind, go for the greatest gain possible from the minimum investment.

Plan to start small, with something functional, something you can use tomorrow, or the day after, but don't shoot for next year. You need to start small and see how it feels, then let the software evolve and accrete over time while it's being used.

Evolution is a wonderful thing, and it has a proven track record. If you build software that your business really needs, and start small, and keep adding to it, then you'll get to keep testing it every day, starting with the first day, when it's still very small and very simple.

Daily stressing of any living thing is the best way to have it grow up to be strong. The more you use the first parts you create, the more time you'll have to squeeze out all the gaps, and build more and more strength. As time goes by, your foundation will be more than strong enough to support the whole edifice, no matter how big it gets, and the whole structure will have been thoroughly tested by time.

By starting small you'll also be able to stay within your budget, and within your competence, and assess all risks. You can measure small things pretty easily, so when faced with small problems you'll be able to head them off, knowing that they're there, and exactly where they are, and that they're small. You can also measure progress a whole lot better on a small project. Because it's small enough to understand.

By starting small you can also keep an eye on resources. Not just money, but time and the energy of your staff as well. Burning through your money, wasting your time, and flaming out your staff are all bad, and much less likely to happen when your project starts small and grows organically.

Then, with a little success under your belt, and because you've learned to assess risks and measure resources, you can think about going outside your areas of maximum comfort and competence and branch into new areas.

But first, last and always you have to keep your head on straight. There are some deep pits to fall into. Maybe you don't need software at all. If you do, you'll likely be better off buying something rather than building it.

If you do decide to build it, there are two attitudes you especially want to avoid. One is dismissive, and it runs something like "Why should I have to get involved? You're the computer people. You should know what to do."

The other is arrogant, and follows the rule that we all have running around in our heads, no matter who we are, that if I don't understand something, then it can't be important, so I don't have to pay attention to it.

Considering that about 80% of software projects still fail after all these decades, you really want to avoid a losing attitude. If you are going down the route of building software, then you have to be real. You have to be serious about knowing what you want, why you want it, and what it will do.

You need a real plan, you need coordination, and you have to measure everything and make sure you're on track. You need to keep checking your sanity all the way through, and every day you need to wonder if this is really the right thing to be doing.

If you don't treat software development like a real job, it can eat you up and put you right out of business. It's happened.