Tim Harvey :: Blog

Icon

I help organizations who feel stuck

PPL: Day 13 – Unit Tests

This is part of the Peer Pressure Learning 30 series. Get a handle on this PPL thing with my introduction to the experiment.

It’s the weekend, so I’m back to the evening groove. The morning was relaxed and the whole family and I went to visit the Amish farm that we buy all our meat, eggs, and chicken from. But that’s another blog post.

Today’s posts is on unit tests. I’m trying not to be a snob as the Ruby community seems to really have testing nailed. Between Rspec and Cucumber, I’m in heaven. I have to remind myself that there’s a lot to learn from the Java community and especially about writing good tests.

Today’s reading: pg 121 – pg 134

Uncle Bob seems to nail me with every chapter. I have been, for the most part, a self-taught programmer. The programming courses I took in college were a joke that I dominated in my sleep, so I jumped over to a business degree so I could learn something I didn’t know. But therein lies the problem. Until now, I’ve never had a systematic approach to polishing my craft. This line from the text describes me to a T:

…in the mad rush to add testing to our discipline, many programmers have missed some of the more subtle, and important, points of writing good tests.

Some really good points come out of the chapter:

  • Test code should match the code quality of production code – I can relate here…test code changes all the time as the requirements change. If your tests are crap, you’ll pay for it every time you have to rewrite tests. Changing over to using Factories has been a perfect example. The tests stay DRY and have been much easier to maintain since the change. Uncle Bob (the author) correctly says: “Test code is just as important as production code.”
  • Tests give you courage – That’s a weird thing to say, and it’s definitely my interpretation of the text. But…it really is true. I have tremendous faith in the test suites I use in each of my apps. Because of the safety net they provide, I can rename large models, change big chunks of logic, or refactor sections of tricky code without fear. My tests tell me when I’m done! I couldn’t go back to a non-TDD (test driven development) language ever again (or one with sucky TDD tools). I really mean that. I’d be hard as hell.
  • One assert per test…probably – I like that Uncle Bob feels free to break the rules. While it’s a good goal to shoot for one assert per test, the added code and duplication may negate the benefit. I find that I frequently pair a record count assert with an assertion about what’s in the record. The better guideline is to test one behavior (the text says, “concept”) per test.

All in all, I feel pretty good about where I stand with test code. I definitely need to hone my comfort level with the tools I use, particularly to reduce duplication.

I’m totally pumped about tomorrows reading which begins a journey into the depths of classes and their proper composition.

If you’re ready to melt your brain on some wild code stuff, read Miles’ post on Factor, a crazy weird stack language that’s unlike anything you’ve even seen.

PPL: Day 11 – Error handling

This is part of the Peer Pressure Learning 30 series. Read my my introduction to the experiment to learn more.

After two days on Objects and Data Structures, I felt like I was beginning to get a better handle on the concepts. I’m pumped about today’s topic as I’ve just been pondering how to handle bad inputs (to libraries) and thinking about alerting (to me) of recoverable error conditions.

Today’s reading: pg 103 – pg 112

This statement kicks off the chapter on the right foot for me, setting the stage:

Error handling is important, but if it obscures the logic, it’s wrong.

Nice. Definitely not playing around on this topic! This was particularly valuable as the discussion turned to null values in arguments and return values.

Two critical sections were particularly timely for me, titled “Don’t return null” and “Don’t pass null”. I had really been struggling with this and as a result, been adding .nil? checks all over my code. I just had a conversation about it yesterday and was at a loss about what to do.

Now, it’s funny because I failed to take several things into account:

  • Rails already has some great error handling, so if a null creeps in somewhere, the user gets a nice error message and Hoptoad helpfully kicks me in the mouth with a nice shiny stack trace.
  • While it’s definitely worth coding defensively, my code is the only code that calls the methods I’m worried about, so I can trap for bad user input long before it gets into the libraries.
  • Throwing exceptions is not a bad practice. I read a blog post talking about bad usage of exceptions to control program flow and have since stayed away from them. Dumb. In several cases, I’d been returning nil as a flag that something had gone wrong and allowed the caller to deal with it. That’s pretty lame. Thinking now, I realize that I could define some sensible exceptions and allow the caller to handle each differently depending on the situation.

Chances are good that most of my .nil? checks are pointless and only satisfy test cases that I created in rspec. Boo. Time to rip some stuff out because as they say, “No code is better than no code.”

So…all that to say, there’s some tremendous wisdom in what author Uncle Bob shares. He sums it up nicely by saying:

If you are tempted to return null from a method, consider throwing an exception or returning a special case object instead.

* Note: A special case object would be one that looks and acts like the typically returned object. For example, Rails ActiveRecord #all method typically returns an enumerated list of model instances. When no records exist, it returns an empty array instead of nil. That plays nicely with a .each loop, saving us from trapping for nil.

PPL: Day 2 – Functions

This is part of the Peer Pressure Learning 30 series. Take a gander at my introduction to the experiment.

Today began with the first portion of Chapter 3: Functions from Clean Code. I stopped just before getting into function arguments.

Today’s reading: pg 31 – pg 40

The first section followed a consistent theme, pounding away at making your functions short, focused, and one-dimensional. My key takeaways were:

  • Keep ‘em REALLY short – This usually isn’t much of a problem for me, right up until it is. At times, I get lazy (usually when not doing TDD) and let a function get out of hand. It’s crazy, as a longer function is a pain in the ass to test, and confuses the hell out of your future self. While the authors don’t give a hard and fast rule (which would be stupid), it appears that anything over 5-10 lines is likely a code smell.
  • Do only one thing – Again, I feel like I generally do well with this, perhaps erring on the side of creating too many functions. I’m consistently challenged for creating too many rabbit-holes to dig through. I need to really keep any eye on this and put in the rabbit-holes where needed.
  • Only one level of abstraction per function – I’m really excited about this one. While I’ve read Clean Code several times, this hasn’t sunk in until now. The idea is not to do string manipulation in the same function that’s doing SQL calls and building an HTML template string. It’s a somewhat nebulous concept for me to explain, but the book did a good job. I think it’s something you’ll recognize when you see it.

Tomorrow, more functions! It goes into argument counts and structure. Woot!

UPDATE: I got a bit too rowdy posting source code from a private project, so I pulled the exercise code. Definitely my bad. I may come back and do another exercise to post from one of my public repositories. More than likely, I’ll forget tomorrow. :)

30 technologies in 30 days

I’m feeling inspired by the recent Smashing Magazine tribute to _Why and a tweet from Ray Hightower about another developer who blogged about his month of new technology. I want to challenge myself to do the same. It’s time to get back to creative exploration.

The last 3 months have seen almost every spare moment at home given to wrapping up open projects from the consulting business I closed down early this year so I could focus on my new job. It’s been a tough road, making sure that my leftover client work didn’t intrude on the workday.

I have 4 projects about 95% complete and a small site that’s 60% done. It looks likely that I can wrap them all up, Lord willing, by the middle of June. In that time, I will also give away what’s left of my hosting clients and may be done managing servers! That will finally leave time for fun and exploratory coding as well as putting in extra time at work now that we are hitting crunch time. I’m SO looking forward to no longer being pulled in a dozen directions.

Unlike my previous mode of building new web apps that could become subscription services, I’m planning to release all my stuff on GitHub (I just open sourced the code to Am I Down and will probably release my filtering Twitter Proxy this week). The practice and fun of creation are what i want most. The idea of adding a new business that im responsible for sounds awful.

The next few months will be great!

Determining employee compensation

Since none of us exist as completely self-sufficient agrarians, we will all accept some form of compensation for the work we do. For most of us, that will come in the form of a check from our employer while some will pursue self-employment. Put simply, compensation represents the price tag for the work a person does.

After looking back on conversations I’ve had over the last several years, it’s clear to me that employees generally misunderstand compensation. I think that’s understandable as few have ever been in a position to set someone’s pay.

I think we have a responsibility to ourselves to build a strong understanding of compensation. I’m convinced that it will help us establish contentment and apply our effort properly towards accomplishing our goals. Be honest, you’d be happy if you knew you were paid exactly right. And you’d love knowing how your compensation was set so you could do something about it.

Summary

Not sure you can make it through this whole article? I’ve summarized the critical bits:

  • Business owners hire employees to make profit for them
  • Compensation has nothing to do with a person’s worth
  • Two things determine how much an owner will pay an employee: The market and the company’s financial situation.
  • The market decides how much an employer will have to pay for certain work. It’s the economics of supply and demand.
  • When the number of people who can do certain work goes up, the price employers will pay goes down.
  • If there are fewer people available to do certain work, the employer will have to pay more.
  • If the company cannot afford the market rate, it must offer less to employees. Special circumstances may encourage an employee to accept less than the market rate. Otherwise, the business will live with an unfilled positon until the market rate comes down, or finances improve.
  • A business owner is free to ignore the market and pay whatever they want (more or less). It’s their business and they can do whatever they want with it.

You cannot determine how much to compensate a person for a given position without careful evaluation of what the market will bear. Anything else would be guessing.

Market rate for a position can generally be determined by a careful analysis of:

  • How much would I have to pay a replacement to fill a position
  • What would a non-competitor pay one of my employees currently in the position

    Read the rest of this entry »

Take your workspace seriously

I’ve always been fascinated with creating a proper and efficient working environment. I’ve taken a fair bit of inspiration from the terrific writeup and gallery put together by Mitch Haile on his setup. Key takeaways:

  • Have separate coding and administrative areas
  • For coding, screen real estate is king
  • Bush Series C office furniture rocks
  • Ergotron makes fantastic monitor/laptop mounts
  • I’m not a freak for owning/buying tons of books (in paper form, either)

BookshelfDuring my 5-year stint at a local cabinet shop, I had enjoyed the opportunity to design and install two completely different office setups; one standing-height workstation and the other a traditional L. When I started Literacy5 a year and a half ago, I went through a variety of setups before I settled on something I really liked (some through necessity, and others out of a need to experiment).

Separate coding and administrative spaces

Original layoutOne of the most valuable lessons from reading Mitch’s office FAQ was the way he created different spaces for his coding and administrative/non-computer work. In my original office layout, I used the corner section to setup my Mac Pro and three 22″ screens. The large bowed section functioned as my admin area. This worked REALLY well. My computer workstation area stayed immaculately organized while the admin area was always strewn with papers. That gave me the ability to keep extremely focused on the work at hand while coding, with zero distractions. When working on the business side of things, I could multi-task and juggle whatever I needed. My Macbook accompanied my to the admin area whenever I did my bookkeeping.

I eventually swapped the admin/computer spaces to support pair programming. Two of us could easily sit side-by-side at the large bow-shaped desk and each have our laptops out. While I didn’t use it that way very often, it worked out great!

At work, I keep my desk space as sparse as possible, still maintaining as much screen real estate as possible. As an aside, the Kinesis Advantage Pro has made a huge difference in the trouble I was having with my wrists. It’s a topic for another post, but switching to Dvorak at the same time worked out nicely.

I really like having the two Dell 2209WA monitors on their side…it’s perfect for terminal windows, chat sessions, and Basecamp. The Macbook Pro runs the monitor on the left with the iMac 27″ handling the one on the right. With a little creative SSH action, the left 22″ can tail the Rails logs and it feels like you have three screens natively on the iMac.

New layoutNow that I spend the days at a shared office, my home office needs have changed dramatically. We are selling our 6,000 sq/ft home/office and will share office space with our friends John and Betsy at a converted warehouse. The office will primarily support managing our home, helping out with the non-profit we do accounting for, and my side projects. I may not even keep a computer there full-time, instead relying on my Macbook Pro. The new layout will still have two separate workspaces, but they will likely be split between my wife and I. I may even setup a dedicated podcast/screencast recording area so that I can leave my mic setup and ready to go.

Get a decent chair, please

One of the lessons I learned early was that a crappy chair can ruin your productivity (not to mention your back) by the end of the day. I’m a young guy, so I don’t care to complain about my back for at least another 20-30 years. The office I worked in before starting Literacy5 spent the bare minimum on chairs, so I’ve sat in some doozies. I never thought much of it since I was doing primarily IT support work with some programming sprinkled in. At most, I might be seated for 2 hours at a time with frequent breaks.

After a few more people were added to my staff, I spent considerably more time at my desk managing projects, coding, and handling server support. By this time, I was sitting in my chair for 7+ hours each day with only the occasional break. I realized just how important a decent chair (and having the sense to get up regularly to stretch) was.

So after launching out on my own, one of my major goals was to make sure that I got some decent seating. Like any new business, I didn’t have the stability to drop $1k on a chair right away, so I opted for a standing height work area…no chair needed! I build the desk myself and it worked great for quite some time. About six months in, I found that I was doing fewer meetings to attract new clients and had a lot more long stretches at my desk coding. While I really love a standing desk, I found that I couldn’t be comfortable more than 5-6 hours a day.

When I built a new office, I finally had the client work to justify a decent chair. I got a terrific deal on a top of the line Herman Miller Mirra through eBay, spending about $500. The Mirra is the follow on to the tremendous Aeron (I’ve tried both and prefer the Mirra). That has been the best $500 I ever spent. I’m sitting in it now and a year later it looks new, works perfect and still gives me 9-10 hours a day in perfect comfort.

Update: April 2010

l-shaped-deskI’ve had the opportunity to change my desk around, changing out a long 6ft table arrangement for an L-shaped workstation. It fits my monitor setup significantly better and affords a lot more space. I still stick to a clear work area, although it’s nice to have room for notebooks and printouts as needed.

I’m testing out the setup with only one 22″ Dell screen and thus far, it’s working fine. That will leave me with an extra monitor to leave at the other office where I was using only the Macbook. Having a second screen there will make a big impact.

Can you be friends with your clients? I think so.

Over the years, talking heads have told us that one should keep your business and personal life carefully separated. While I’ve generally agreed with that approach, recent shifts in my client base towards more ideal clients has given me opportunities to head in a new direction.

Getting our families together

Working with John King from Metta Audio has been my first experience with a truly ideal client. The work we do together has been extremely interesting and engaging, as well as being a joy to build.

20100120 MilesWe enjoy working together so much, and appreciate each other as fun people, that it’s been natural to connect outside of work. Our families have gotten together several times for dinner and play time. I have to admit, it helped a lot that John and his wife Betsy (who is a stellar photographer) are really open and genuine people. Just reading their blogs made me feel like I knew them. Reading about their experiences made it pretty obvious that we had a lot in common.

Building solid foundations

The really amazing thing I’ve found is that as we’ve become friends in addition to business associates, our relationship has strengthened. I suppose that sounds obvious, but it has rather significant implications for the long-term success of any business. While I don’t seek to be friends with John to manipulate him, there are several tangible business outcomes as a result of our growing friendship:

  • Loyalty – Because the business relationship is not based on some fleeting detail like price, I feel more comfortable than ever that John would come to me first when he needs help. I get to spend more time doing the work I love and less time building up my client base. Plus, I’m more loyal to John! I work hard to take care of his needs and have gladly learned some new tools to fit his requests.
  • Profitability – I’ve found that every new client needs some level of training on how you do business and how your services can best meet their needs. By fostering long-term clients, you reduce this non-billable time and effort. Plus, when a client really values what you offer (both in terms of who you are as well as what you do), you can both arrive at a mutually agreeable rate for your services that’s almost sure to be more than what you might feel comfortable asking when doing the first project for a new customer.
  • Fun – Don’t underestimate this one! I’ve had more fun the last six months working for my ideal clients that I ever have before. That’s resulted in me doing some of my best work, feeling less stress, and growing my skills tremendously. I think you’ll find that this does have a measurable financial impact. Clients can tell when you love what you do and they’ll want to be a part of it with you.

Hitting the museum

Spending time with your clients doesn’t have to involve dinner at your home (although the intimacy of that can be powerful). For our latest excursion, my wife Sara and I invited John’s family to join us for a trip to the fabulous Indianapolis Children’s museum.

20100120 JennaA brief side note is in order…spending time with my family is the most important thing on my list when I’m away from work. So the last thing I would do is drag my wife and kids along to some boring business get-together with a client. Instead, we planned something that the family would love and invited John and his family to join us! This is important, too. While your clients will appreciate you for taking care of them, they will adore you when you do special things with their kids. But remember, this all needs to be something you do because you want to and love it, not some cheap to do list to curry favor with a client.

20100120 Miles and John

So we spent several hours at the museum cruising around and playing with the kids. Afterwards, we introduced John to Skyline Chili for lunch. It was a terrific day and everyone had a great time. I think we talked shop for less than 5 minutes the whole day (Which is good! No shop talk would have been fine.).

Getting several clients together

I’m looking forward to going again when John’s wife Betsy can come. Plus, it didn’t work out this time, but for our next trip, I hope that Matt Outten from Squaremouth can bring his family. Matt is my latest ideal client and has been really enthusiastic about getting our families together. He’s even been gracious enough to invite our family to come have lunch at his office each week when his family comes!

If you haven’t picked up the message yet, the critical theme is to share, share, share what you have, whether it’s a fun trip, a friendship, or knowledge. Give it away, you won’t be sorry.

When building web apps, utilize proper indexing

Rails does a lot of crazy wonderful stuff. The downside is that all that awesome power gives you the ability to make some pretty dumb moves. Just because I can get the URL for one of the sites my Am I Down? users get alerts for by using…

current_user.sites[0].host.url

…doesn’t mean that I necessarily should. That command generates some heavy SQL, running a join across several tables (after running a separate query to get the current user):

SELECT "subscriptions"."id" AS t0_r0, "subscriptions"."user_id" AS t0_r1, "subscriptions"."host_id" AS t0_r2, "subscriptions"."alert_id" AS t0_r3, "subscriptions"."created_at" AS t0_r4, "subscriptions"."updated_at" AS t0_r5, "hosts"."id" AS t1_r0, "hosts"."url" AS t1_r1, "hosts"."created_at" AS t1_r2, "hosts"."updated_at" AS t1_r3 FROM "subscriptions" LEFT OUTER JOIN "hosts" ON "hosts".id = "subscriptions".host_id WHERE ("subscriptions".user_id = 35) ORDER BY subscriptions.updated_at DESC, hosts.url ASC

That’s going to take 21ms to run, just for a lookup. Is that a big deal? Perhaps not. Indexes (in the right situations) may make that SQL query run at an acceptable level.

Real world problems

In the case of Am I Down?, my service that alerts you when your web sites go down, I run some pretty slick lookups back through the logs for a web site to see if the change we see in a sites’ status is significant enough to warrant an alert. Since there are thousands of web site checks going on every hour (currently over 20,000 each day), a 21ms SQL statement is seriously bad. You can see the result below:

20100119-db-indexing-screenshot

The solution

The logging table didn’t have an index on the host_id, so it took forever (20ms or so) to find only the log entries for the current host, which for various reasons happens 8-10 times per check. So almost a 1/4 second is taken up by SQL checks every time I checked a site. You do the math and that means you can only sustain about 1,200 sites (240 checks per minute, every 5 min) for each checking worker. Not good.

You’ll see that the there’s a vertical bar towards the right of the graph, after which the bars drop off considerably. That would be the point I added an index for the host_id. Suddenly the time drops to about 3ms. That’s more like 3,600 sites for each checking worker. Much better!

Improving your Rails app

For a Rails app, the Rails_Indexes plugin offers a great way to track down any obvious indexes you may be missing. To speed up queries and reduce the number of queries you make, take a look at Bullet.

Client stats for 2009

As we begin the new year, I would encourage you to review your business and see what unexpected insights you might find. I’m not talking about another look at your products or services, but rather at your processes, finances, and customers.

Starting to work ON your business, not just IN it

It’s easy for me to spend the whole year thinking about code, forgetting that it’s just as important to work on the business as it is in the business (check out the terrific book, The E-Myth for more on this subject).

For me, a major revelation came when I looked at my top customers as a percentage of sales a few months back:

Google Chart

Tail wagging the dog

Wowzers! While it felt like I had a bunch of customer jobs going, the reality was that 3 clients kept everything going. Worst of all, my top client of 2009 was my least profitable and most demanding (It’s worth noting that they had some very good qualities as well: very consistent work and they always paid on-time).

Based on some thoughtful review of these stats, I made a few changes:

Putting long-term relationships first

I saw that too much of my work was provided by clients that needed the services I offered, but had little need for the “Tim-ness” I bring. Partially, that’s because I initially pursued the marketing and design agency niche. Unfortunately, their margins are very tight and for many of the players, web is an afterthought. There’s very little really innovative development going on locally. Clients aren’t asking for it yet.

More than anything else, my work needs to come from organizations that find me irreplaceable. Not in that lame, “I’m the only one who knows how it all works” sort of way. Rather, it’s about finding and working with people who really appreciate the unique talent, perspective, caring, and personality you bring to every project. It’s about brining so much enthusiasm and productivity that the client can’t believe their luck in finding you. Those are things that cannot easily be replaced by anyone else.

My work with John King from Metta Audio has this feel. We both really appreciate what we bring to the relationship. He’s been kind enough to tell me that the chemistry we have as we work together is as much or more valuable than my coding. Plus, I’m always thrilled to work with him on something new!

Demoting the tough client

My favorite book for self-employed consultants, Book Yourself Solid, reminds us that we have to drop our worst clients. They sap our energy and we end up doing poorer work for everyone. I’m not one to fire a client unless there’s something drastically wrong, I’d rather have them fire me. If the work isn’t worth it, I may have to raise my rates significantly to maintain profitability. That way, the client can still get help and I don’t need to complain. If the rate becomes unreasonable for the work they need, the client can replace me. Along those lines…

I’ve known for a while that I needed to change the relationship my top client. 90% of their work was supporting an existing environment, and that’s not really my strength. And because the work is support-related, it’s almost always urgent and interrupts scheduled projects for other clients. My frustration was a clear indication that my rate did not reflect the cost of doing business with this client.

As I mentioned in a previous blog post, I began the transition in October. I completed several open projects and started discussions about eliminating the retainer I was on and associated minimum hours. Since their budget had tightened, it turned out to be a natural move for them, shifting me over to a higher rate that allowed them to only call when I’m urgently needed.

I work hard to protect my time on scheduled client projects, so we also agreed on a minimum billable time when they call. This ensures that I’m compensated for time lost to the interruptions and ensures that they don’t call frivolously. With over a month under our belt with the new agreement, I think it’s been a real success. I’m pleased to take their calls and help when they need it, and they’re spending less. Best of all, I’m freed up to do more of the work that I love.

Increasing the apps available

In addition to client work, I want to add to and continue growing the subscription services I’ve created:

Focusing on larger projects

My business thrives on doing ongoing work for a small number of stellar clients. Part of that is due to my personality. I can really do effective work on one or two projects a day. If I’m pulled away to make calls and juggle 8 projects, trying to move each forward in the course of a day, it feels like a disaster. I enjoy the larger development projects more. They offer a more significant sense of accomplishment that designing lots of little marketing sites.

It looks like I’ll be able to transition over to just a few clients with ongoing needs in 2010. If everything goes as I suspect it will, I’m already completely booked through March, and likely into mid-year. That’s tremendously encouraging. I also had to start a waiting list for a couple potential clients that want some work done and were comfortable waiting for me to free up. It’s a pretty wonderful spot to be in.

Many of the relationships I worked hard to build in 2009 have resulted in requests for work. I’ve been pleased to refer many of these to other independent developers and designers in the area, helping them keep busy while taking care of my contacts. It’s always hard for me to turn down a project as I love to help people, but it’s what I have to do for my current clients.

It’s going to be a stellar 2010!

Finding my ideal clients

I am constantly on the lookout for ideal clients. I yearn to surround myself with them. The people I look for:

  • Possess an enthusiastic attitude and enjoy coming to work every day
  • Want to delight their customers with excellent service and fantastic products
  • Love to learn, looking to improve themselves and their craft
  • Focus on building lasting value at the expense of immediate gratification
  • Value quality time with family and friends, avoiding the workaholic trend

Literacy 5 - LogoIf that’s you, I expect you to contact me in the next 2 minutes. You’ll find a wealth of contact details on my company web site.

But what do you do?

“But Tim,” I hear you say, “You didn’t say anything about the work you do.” That’s true, and very intentional. While most of my work ends up being technology-related, and specifically web site development, what separates my from any other developer sits outside the technology realm.

It’s about giving my customers peace of mind. I’m the guy who my clients (and previous employers) turn to when the game is on the line and they need to score (pardon the sports analogy, it’s all I could come up with). While it may sound cliche, I make things happen.

Ruby on Rails LogoYes, I build killer web sites and online software. They’re perfect for my clients not because the technology is great. It’s that they do what no one else could figure out how to do: accomplish my client’s goals of more revenue, more customers, fewer errors, etc.

The people I work with have problems they need solved, and never enough time to take care of everything. They’re frustrated when working with people who need to be told what to do, or how to do it. There just isn’t enough time in the day.

I’m the guy who comes in and wants to know, “Where do you want to be in 6-12 months?” and “What issues plague your organization?” I sniff out the solutions to those problems, present my plan of action, and then get it done. My clients rest easy at night knowing that I’m sweating the details and taking responsibility for delivering success.

You did what?

Some of the quirky projects my clients (and previous employers) have put me up against include:

  • Managing the planning and execution of a national trade show exhibit — Increased dealer network by 20% within 9 months
  • Revamping a manual, fax-based ordering system — In less than a year, over 90% of customers chose to use the web-based system I created
  • Writing a “For Dummies” book — Researched and wrote over half of “Developing eBay Business Tools For Dummies“, a beginners guide to API connectivity for eBay, PayPal, FedEx, and UPS.
  • Completely rebranded a confused, aging company — Within months, salespeople were jumping for joy over the new materials and focus on a single consistent message
  • Building online shipping software service ShipperTools.com — Designed, developed, and implemented ShipperTools, recommended in a bunch of online selling books
  • Running operations for three retail stores while the owners sought outside financing — Launched their first online marketing and promotion tools with e-coupons still in use 5 years later