Archive for the ‘General’ Category

The Price of (Dev) Happiness: Part One

August 9th, 2011 by Rich Armstrong

Okay, let’s just assume that you’ve bought into the idea that a happy developer requires a clean, attractive, comfortable workplace that encourages healthy, sustainable productivity.

You don’t want to do this piecemeal. You asked for a big monitor and you got it. Now, you ask for a sit-stand desk, and you’re suddenly the guy who always needs another “toy.”

You just want to know what a top-notch work station costs so you can tell your boss.

We use these products every day and have for years, and we love them. (Disclosure: None of the following links are affiliate links. We get nothing from recommending these products.) Here’s what our offices contain:

  • Fully-loaded Aeron chair, fully assembled  - $988 from Sit4Less.com
  • AirTouch Adjustable sit/stand desk  and non-moving side desk –  $1738 from Steelcase - Excellent for pranks.
  • Optional anti-fatigue or bouncy Kybun mat for those folks who choose to stand all day – $68 from Amazon or $335 from Steelcase, respectively.
  • 30″ monitor for work and a side monitor for your bug tracker – $1520 from Dell
  • Beefy workstation so you can’t pull this move – also $1520 from Dell
  • Whatever keyboard you want (because we’re all snowflakes) – up to $270 for a Kinesis keyboard
  • Whatever mouse you want (beautiful, fragile snowflakes) -up to $70 for an Apple Magic TrackPad or a fancy trackball.

That’s a cool $6,174.00 maximum. (Yes, I know, we’re paying for a chair for people who stand all day, but we’re talking maximums here.)  All of these except maybe the computer have a depreciation schedule of  about five years. So that comes out to $102.90 a month. But, that’s not $102.90 per month extra; it’s the total cost of everything we use in our offices except the phones. (Which, for a dev, who cares as long as it never rings.)

We could do some research on OfficeDepot.com and come up with some depressingly small number representing the minimum you could spend on a dev to get them nominally productive, but we really don’t want to go there.

Good luck!

Next: the real cost of private offices.

Making an internship great

June 2nd, 2011 by Dan Ostlund

It’s intern season; at least it is here at Fog Creek.

A fresh batch of talented and eager interns started yesterday, and although they missed the fiercely contested Fog Creek/Stack Overflow ping pong tournament, they are already working on important and top secret projects. We’ve got exciting stuff planned, and if all goes well, we’ll be showing off some of it before the leaves start to turn colors, and some of it even sooner than that!

The internship program has been going each summer since the early days of Fog Creek and it’s one of the ways we identify talented new people to come work here. They get a couple of months to see if we’re as great as people say we are, and we get to see them in action, hacking away and showing their chops on real shipping code.

We’ve made the internship program better over time, and Ben Pollack, one of the creators of Kiln, and frequent intern mentor, has written a guide on how to make internships great that covers what he (and we) learned about giving interns a great experience.

Interested in following along or suggesting topics for the conversation?

  • Keep an eye on Building Great Software Companies, a collection of excellent articles on running your software company which we add to when we have good new stuff!.

The very most basic things your company needs to know about sales (part 3 of 4)

May 5th, 2011 by Dan Ostlund

This is part three of a four part series, click here for part one, and here for part two.

Part four appears tomorrow.

Closing

Closing scares the hell out of people. It may be the biggest fear in sales. It feels pushy. It evokes the haunting image of the sales stereotype. If you haven’t done it, it can feel mentally crushing.

But I have good news; it’s no big deal. Easy to say, I know, but it’s true. As you do it more it’ll get easier and this will become more obvious to you.

Remember that people expect to be closed. They entered into a sales situation. There is no mystery about what you guys are doing together; they’re looking at a product, and you’re trying to help them figure out if yours is the right one. Everyone knows this. At some point you’re going to move on from the investigation phase and they will make a decision. This is a surprise to no one.

Even better, there are ways to soften the process of asking for the close.

I’m going to tell you the simplest, most stress-free way to close that you will ever learn, and I want you to commit to trying it. Here it is: “So, what do you think?”

Ta-da! You’ve tried to close a sale, and you didn’t break out in hives.

There are probably thousands of ways to close, and you can find many dozens of books with advice on this topic.

I am a fan of softer closes; they just feel less jarring to me, and they fit with the sales culture at Fog Creek better, but there are certainly harder closes you can employ, and there are times when these make sense. “Harder” in this context means more direct, not aggressive and obnoxious, by the way.

Here are some other soft closes you might try.

“When should we talk next?”

“What’s your deadline for making this decision?”

“Is there anything at this point that would stop you from proceeding?”

“Have you heard enough from me to make a decision?”

I don’t think any of those are too terrifying to try.

To employ a slightly harder close you might say, “If I’ve answered all of your questions about the product, can we discuss pricing and how to proceed with the purchase?”

In the sales books you will probably run across something called the “presumptive close.” The presumptive close assumes the sale, and usually goes something like this, “So, who should I address the invoice to?”

Please do not ever do this. It’s terrible, it reeks of the sales stereotype, and it will tend to generate stiff resistance because you’ve just become the guy with plaid jacket, toothy overbite, and dual gun fingers.

Objections

Understanding the sales process (outlined in part one) makes objections seem a lot less daunting. Recall that you are figuring out what the problem is (by asking questions), you’re making your presentation (using lots of vivid stories, and talking about benefits), and you’re explicitly asking for the sale. Good. But at any point you may meet resistance in the form of objections.

I’ve got news: I love objections. No seriously. Sure, I’d much rather have the mere sound of my dulcet voice induce people to say, “How much can I get and how fast?” but, on the evidence, my voice isn’t quite that dulcet. Barring that, I want to hear all of the objections.  I want them to come up early. I want them to be forcefully expressed.

Why do I love objections? Because they give me a very clear sense of what I need to do.

If I’ve done my questioning correctly I probably already know what most of the objections are anyway, and I’ve had time to think about how to deal with them.

An objection is a map. Sure, it’s a map of rough water, but I’d much rather know the rapids are coming instead of finding out after I’m sucking on gallons of water.

Even with your map, objections will still come up that you haven’t uncovered—it’s inevitable, and it’s totally OK. Objections are easy to deal with if you think about them in the right way.

Frank McNair has the answer when he writes, “An objection is simply a request for more information.” Oh my god, yes! That’s another one of those simple yet profound statements. It should completely alter how you look at objections.

Objections shouldn’t make you wilt; objections should make you ask more questions.

Let’s look at an example.

“I don’t think I can use FogBugz because it doesn’t have both severity and priority.”

I could launch into my speech about why having both makes no sense, but that’s too combative. A question is the answer.

Instead, you might say, “So can you describe for me how you use severity and priority now?” And they’ll tell you. And then you may have some more questions, or you might move gently into your severity/priority speech.

For sales technique-combining bonus points, you would tie this speech to some benefits: how using only one of the two saves time, how it reduces case entry overhead, how it increases adoption. Then, if you had a story about another company who stopped using severity and lived to tell about it, well then, you just did a triple axle. Take a bow. The persuasive content of this exchange would be very high.

That conversation is an example of reframing, and it’s something you’ll be doing a lot. People frequently have very specific notions of what they “need”, but you will often find that these requirements, when you scratch at them a bit, are not requirements at all, and if you can show them a better way to get where they want to go, not only will they agree to go that way, they’ll be very enthusiastic about it.

But what if reframing fails? In the example above, we could actually just kill the objection because you can have severity and priority in FogBugz; we just think it’s a bad idea.

If you can’t just kill the objection, then you’re back to asking questions.  Always go back to asking questions. Probe. Feel around. Try to find out why this is a concern. Try to figure out as much useful information around the issue as you can. Ask them how important that concern is; after all, not all objections are equally serious. Almost always you’ll find some grounds to defeat the objection. Every conversation is different, but this process really works.

Once you have the information you need, deal with the objection. Get a tech person on the call. Explore workarounds. Look for reframing opportunities. Relate how others dealt with this issue. Weigh it next to other benefits. You may even have to simply admit a deficiency in your product, which is always preferable to dissembling about it.

You can also sometimes get in front of a common objection by just bringing it up first. If you have a really expensive product you might say, “We’re not the cheapest, but…”

Also, never, ever, ever argue with your prospects. It’s a losing proposition every time.

The basic thing you need to know is that objections fall on you. They are a simple indication that you have not yet given the prospect everything he needs in order to make the decision. You just need to find out what that information is and give it to him. That’s all.

A couple of last semi-random thoughts about quality

  • Don’t interrupt your prospect when she is talking. Rude. Annoying. You miss good information.
  • Don’t ask about the weather. It’s a cliché, and it’s so painfully artificial. Feel free to get down to business quickly. That’s why you’re all on the phone.
  • Do everything for your prospects. For god’s sake don’t ever tell them the documentation is on the website and they can search for it. Are you serious? Find what they need and send it to them. Take care of everything. Everything you don’t take care of is a thing they probably won’t do even if they say they will.

Next we’re going to shift over to the second large area I said sales people need to be concerned with: how you spend your day.

Process

Operations

If you’re a small shop, or a technical founder, or have technical resources available to you, then look around for things to automate. This is all about saving time and creating efficiencies so that you have more time for the squishy, but very valuable, person-to-person stuff.

New trials of FogBugz and Kiln at Fog Creek get turned into cases in our internal FogBugz install. Cases are assigned to a salesperson based on criteria we’ve set, and then the prospect is marked as belonging to the salesperson in our CRM system.

For over a year I did this manually, and it took me about 2.5 hours per week. What a total waste of time. We got a bit of (incredibly useful) spare tech time and now this all happens automatically, and I only know about it when it breaks, which it never does.

These sorts of internal process automations often get neglected because they’re not a new feature or a new product and don’t bring in new money in obvious ways. But never forget that operations efficiencies made Michael Dell a rich man. It’s one of the primary competitive advantages that a company can go for, and even if it isn’t one of yours, make absolutely sure operations inefficiencies are not an active drag.

You always have to do the cost-benefit-analysis, but it’s a pretty safe assumption that operations automations will save you time and money. Just make sure you don’t get overzealous—it’s this kind of thinking that has given the world the Acherontic automated phone tree.

What to do with your day

I don’t like to be rigid about this because autonomy is an important element of job satisfaction.

But I have found that sometimes people just need some guidance here. I’ve made the mistake of assuming that everyone would figure out a way that works for them, but they often don’t, so what follows is some advice on being better at the process side of sales.

First, have a sales tool of some kind that you use. I don’t care what it is; Fogbugz, Highrise, Salesforce, SugarCRM—it doesn’t really matter as long as you use it consistently and you don’t lose things in it. This system is the center of your day and gives you confidence that you’re not missing anything. It’s where you schedule your activities. It’s the tool you rely on to set your daily agenda.

In a perfect world someone will be able to pull lots of different kinds of data from it to do interesting analysis, like how long it takes to convert someone, which are the highest value prospects, and many other nuggets of useful business analysis.

How you spend your day will vary a lot depending on your business.  Do you do a lot of outbound, cold calls? Do you make $100,000 sales or do you tend to hover in the $2,000 range?  There will be many factors determining how your sales team operates. It might be that you’re the only sales person and also the technical lead (and bookkeeper, and hiring manager, and wastebasket cleaner).

There is at least one thing that is common to all of these situations: The need to set aside some time for uninterrupted planning each day. Sales people are interrupted a lot, and this can be mentally taxing. Take some time every day to calmly think about what you need to get done for the next day. Turn your phone off and let calls go to voicemail—there is no sales call that can’t wait an hour if necessary.

Whether you plan the night before or in the morning is a matter of taste, but this I know from lots of observation and experience: if you get to work and dive in without some semblance of a plan your day will be much more chaotic and reactive than it needs to be. All day will feel like you’re playing catch-up and you’ll likely go home with the nagging sense that you didn’t get to something important.

Do this: Just commit to one week of planning your sales day before you jump into the actual work and see if it makes a difference.

Next: How to get the best return for your time doing sales

The very most basic things your company needs to know about sales (part 2 of 4)

May 4th, 2011 by Dan Ostlund

This is part two of a four part series, click here for part one.

Part three and four coming tomorrow and Friday.

Questions

The most important skill you can develop in sales is the ability to ask good questions. Work on this first, and work on it relentlessly. Other important skills will follow more naturally when you’ve gained some skill here.

Questions give you information and help you understand what the problem or the need is. It’s by far the most powerful tool you have and is the prerequisite to everything else in the sales process outside of saying “hello.”

People generally like to talk about what they’re involved in. A few well placed questions can get the conversation rolling, and as it unfolds you get amazingly valuable information that will help you focus on the things that matter to the prospect.

Also, questions are like magic. You ask one question and suddenly the prospect is telling you other things that you never even asked about.  They’ll tell you things about their business, their processes, the other tools they use, how their teams work, when they can spend money…

I promise when you get good at asking questions you’ll be amazed at their power.  In the early stages of a call with good questions, you’ll find the prospect talking a lot more than you. This is good. This focuses your conversation.

Six rules about questions

1) They must sound natural. Everyone can hear it when you’re reading from a list or a script. It just sounds awful. This makes me feel like I’m on the world’s worst sales call, which is damn close to the world’s worst fate. You make things sound natural through repetition. Practice your questions all the time. Practice them in your head, practice while you’re driving. Think about a call from yesterday and ask where you missed good questions. Play it over in your head, and then revise those sections mentally until they are perfect.

2) No salesy questions. I’ve banned any question that sound like canned “salesy” questions. If any slip through on our team I strangle them, drown them, and bury them in the desert. And then I turn my attention to the question.

I never want to lose sight of the fact that this is a conversation about how to solve a problem, and I want my questions to further that conversation, not make my prospect roll his eyes.

An example of a salesy question is what the sales books call a “tie down” question. It goes like this: “Having a secure house is important, isn’t it?” Barf. Everyone sees right through this manipulative question.

3) Actually ask the questions. You would be stunned at how often question asking is neglected, or how little time is spent on it. Paul Kenny, sales consultant and owner of Ocean Learning, says that the average time that elapses between the end of the initial chit chat and the launch of the pitch is about forty-nine seconds. Forty-nine!  You couldn’t get much more than my name in forty-nine seconds. It’s the biggest missed opportunity in sales.

4) Ask open questions.

There are three types of questions:

  • A selection question: “Do you want the red pill or the blue pill?”
  • A closed question: “Oh my god. Was that the dog?”
  • An open question: “How did you end up down there?”

Open questions are the ones you want to favor. These expand the conversation and receive fuller answers. Closed questions are necessary, but when relied upon too much they invite short, clipped answers.  “Do you want pizza?” invites one kind of answer, and “What are you in the mood to eat?” invites a completely different kind.

Open questions that get a sales call going could be, “What prompted you to look at FogBugz?” or “Since you’re using Bugzilla but looking at FogBugz, can you tell me a bit about what’s not working for you now?” Sometimes you’ll get a short answer to an open question, but that’s fine; just ask another open question.

5) Ask questions until you understand everything you need to. I’ve seen reticence on the part of some sales people around asking repeated questions. They feel like the questions are intrusive and bothersome, and anyway, they’re straining like greyhounds waiting to start their product demo. This is a mistake.

If your prospect describes an internal process you don’t understand, uses an acronym or jargon that’s foreign to you, or simply says something in an unclear way, keep asking questions until you understand properly.

6) Take notes. You think you are going to remember that conversation you had, but you’re wrong. Write your notes as soon as you get off the phone. Just make it part of your habit.

Stories

We’re wired for stories.  Take advantage of this. Stories don’t have to be long and elaborate; a story can be simple and short. A story can be a sentence long.  It can be a side comment thrown in as you’re talking about something else.

Stories make your presentation more memorable.  They add vividness. They show benefits. They offer social proof.

Here is a story: “When we decided to dump Subversion and use Mercurial we saved six weeks on our merge time before launches.”

One sentence, but a powerful story anyway. It implies a bunch of things: we used SVN, but had issues with it (likely the same ones they are having); we successfully switched off it; we save time with Mercurial; we can actually do merges now; the prospect could do the same thing; we could probably help them do it.

Most good stories have a villain (or an obstacle) and a solution. In my one sentence story above, SVN is the villain, and its nefarious henchmen are the ridiculous tribulations of merge week month(s). The solution is Mercurial. Just think obstacle-solution, that’s the basic formula.

The single-sentence SVN story is vastly more memorable than any list of features you could spew out. Will our prospect remember the cool electric DAG we built for Kiln?  I don’t know, but I can almost guarantee he will remember that we used to use SVN, that we got off it, and that we made life better for ourselves.

Constantly keep an eye out for stories you can use, whether they come from your company, or the people you talk to. “I was just talking to someone last week who had their year’s supply of ice cream ooze all over the basement floor because the power went out. He bought a generator from me yesterday!”

Of course, don’t make stuff up. It’s never OK to lie to your prospects.

Features and Benefits

This is the most repeated sales advice on the planet: sell benefits not features.

It’s important.

I like to think about the persuasive content of what I say, and benefits are simply more persuasive than features. Despite being so widely suggested, emphasizing benefits over features is something that most sales people are terrible at, and that’s when they even try, which is not very often. Why is this neglected so much?

Because it’s just easier to talk about features, that’s why. It’s the first thing you learn at a new job. And if you happen to have built the product, you can cite every feature backwards, and give a lengthy report on every technology choice you made.  You have the power to make eyes glaze.

Talking about benefits requires empathy and imagination and a fair amount of mental work. Talking about features is safe, and most people never venture out of the fort. But it’s weak. It has low persuasive content.

Here is another story: I was shopping recently for a new mattress since my ten-year-old inner-spring futon had actually enrolled in night courses in torture. I was considering one option and read everything on the manufacturer’s website and did research for a couple of days. I knew the dimensions, and the difference between a pillow top and a plush top, how many coils it had, how likely it was to sag, and that it was branded for various upscale hotels. I was still thinking all this over when a friend told me, “I slept on one of those for a week.  Best bed I ever slept in.  Best sleep I ever got.”

I bought it the next day. Done. All I needed was a trusted voice to tell me how I was going to benefit from it.

I definitely needed to know about the features to satisfy certain minimal concerns, but by themselves features allay fears, they do not persuade. Features get you to zero, benefits move you beyond.

Features and benefits, however, are very tightly entwined, and so if you’re talking about a benefit, it’s usually not off by itself divorced from an actual feature conversation.

Just the other day a client on an old version of FogBugz said, “I’m required to send these reports to my executives.  I have to query the database to get the data I want, then put it into Excel, add some commentary, and then send it along. It’s a painful process.” A “features” answer to this statement would be, “You should upgrade your FogBugz version since they now export to Excel.”

That’s an OK answer as far as it goes, but it’s not nearly as good as a benefits answer which might go like this, “FogBugz now has an Excel export feature, so you can just do a search for the data you want, quickly add any additional columns of data you want to see from the drop-down menu, and then export that to Excel. You save that search for re-use of course. You can stop all of this manual querying and exporting, and you’ll save time. But you can take this further. Since you have to do this all the time, let’s skip the manual stuff altogether. Why not use the API to generate the reports you want and then have them automatically emailed to the people that need them each week? You can use these tools to take this job off your plate forever.”

I talked about features all over the place in that answer, but I also helped him to see a picture of how his problem could go away if he used those features.  That’s a benefit.

For a sales technique-combining bonus, if you responded to his original statement with the question, “How many hours a week do you spend on this report?” you could quantify his time savings for him over the course of a year–a substantial benefit.

Or, imagine for a moment that you sell shark cages for divers. There are a bunch of features you could talk about.  The color is a beautiful silver. The hook system to get it in the water is easy to use. It can be folded up for easy storage. It’s welded by the world’s best welders. Good features.

But what you really care about is that you won’t get eaten by that sinister black-eyed bastard.  That’s what really matters. That’s a benefit.

Next: The most pain-free way to close a sale

 

The very most basic things your company needs to know about sales (part 1 of 4)

May 3rd, 2011 by Dan Ostlund

NOTE: You can get this entire series as a pdf if you prefer: The Most Basic Things Your Company Needs to Know About Sales

I’m the first sales manager Fog Creek has had. I’m not a salesman by profession. Before I came to Fog Creek I was working as a sys admin at JibJab where I tried not to break things. What on Earth did I know about software sales? Wasn’t that done at a golf course, and please can I get directions?

Well, I learned. I learned a lot, and in the process we’ve built a sales team to be proud of. We made some mistakes along the way, and had to fire a few people, but month by month we got better and now we feel good about where we are, and we know where we need to go to be exceptional.

If I can learn this, than you can too. In fact, I am about to save you time, and prevent mistakes. What follows, in four parts, is what we learned and how we did it at Fog Creek.

I realize now that I started selling a long time ago. See, I used to work as a waiter, and we were supposed to up-sell various things like top-shelf margaritas and seasoned sour cream for the french fries. I sucked at it. Like, I was dead last every shift. You could have taken a long snooze and done better than me.

One day the manager wanted to know what was up, and I said something like, “Man, if they want top-shelf margaritas they’ll ask. I don’t need to push it on them.”

I was putting on a little front. Sure, I believed that, but…

My manager said, “That’s true, they are likely to ask if they want something, but what if they don’t know we have it?”

Wow… Hang on, that could be true… In fact, it probably was true fairly often. It was a simple and yet profound thing to say.

I think he knew what my real problem was: fear. I was afraid. I was afraid of sales. I feared that it insulted my customers and I even feared the anticipated rejection. It felt incredibly awkward to make these suggestions. I had developed a revulsion to the whole thing, and I hated doing it, so basically I didn’t.

But my manager helped me reframe it. Suddenly I was informing my customers about something rather than pushing things on them. They still made their own choice; but now they had more information with which to make it.

Doing sales can often generate fear in new sales people—even, sometimes, in veterans.

I’m guessing sales is scary for you in some ways—maybe all of them.

But read on, I think we can get a start on making this a tolerable, and maybe even an enjoyable thing to do.

When do you start sales?

If you’re a founder you’re probably already doing sales even if you don’t really understand exactly what you’re doing. Your passion and domain understanding can translate remarkably well into enthusiastic product pitches and demos. You probably built your software to solve a problem, perhaps one you suffered from yourself, so you know all about it. This has pushed you well into the sales sphere.

You might be doing a lot of “low-touch” sales, in which case it may be that you don’t even need a sales force—for years Fog Creek didn’t have one, and most of our sales still happen without any human intervention.

These low-touch sales are driven by marketing. You make a great website, you test how it’s doing, you change what’s failing.  You send out automatic emails, you try different copy—you dump the one that started, “I am the prince regent of a great and wealthy country…”

The line between sales and marketing is not clearly drawn, and the functions have huge overlap.  I almost think we need a new word for this.  Smarketing? Smales?

OK, smales.  This is the world of Patrick MacKenzie of Bingo Card Creator fame (and Avinash Kaushik, and Rob Walling, and Darmesh Shah, and so on). Smales is hugely important. It’s a low-cost way to increase sales, and especially if you’re technical, you should do this first. Do it frequently and do it always. You’ll want to start a sales team after you think you’ve squeezed everything you can out of smales. Remember, though, at some level, sales is always going on.

For now I only want to talk about the sales that human beings conduct with other human beings.

Even though the internet has radically changed sales channels, the basics of selling person-to-person haven’t changed at all.

 

What is Sales?

Many technical people tend to have a rather, shall we say, uncharitable view of sales people.  They think something like the following: Sales is full of charlatans and hucksters who lie and inveigle and pressure; no one wants to talk to them and the thought of actually being one makes a root canal sound like a vacation.

That’s not so good.

But this is just a stereotype—not without some cause, for sure, but it doesn’t really deserve the weight it once did. Mature and responsible salespeople don’t act like that because they don’t need to, and because they understand that such behavior is classic win-lose.  The sales people of the stereotype are trying to force you into something you are unsure about and they make the whole thing feel like a battle where you have a lot to lose.  You don’t have to be that kind of salesperson, or have that kind of sales culture, and in fact, if you do, then you’re taking a very short-term view of your business.

So let’s try that again.

Sales is a conversation.

Ah! That’s it. That’s the most basic thing you need to know in order to demystify sales.  You’ve all had conversations, so you’re off to a good start. Sales conversations just tend to be a specific kind of conversation, one that you can become better at, and one that tends to take a particular form.

There is one other part to this sales demystification process that deserves top billing before we move on.

Sales is problem solving.

There are people in the world with a problem of some kind.  Some subset of those people need this problem fixed and is seeking a solution. You’re one of the people who can fix that problem, and you need to show them that your fix is the best one for them.  Again, that’s it.

Sales is a mindset as much as it is a set of skills.  If you believe that sales is hard, scary, underhanded, and manipulative, then that’s what it will be, and you’ll hate it, and fear it.

Let’s put these ideas together into one sales demystifying sentence: Sales is a conversation about how to solve a problem.

At its core it really is that simple. If you can learn the truth of that, sales will become radically less frightening.

There is more to it of course, but when you strip away all the advice contained in all the vast number of books on sales, this is what it’s all about.

Let’s talk specifics.

 

Breaking Sales Down to Two Things

The success of salespeople hinges on two factors: 1) The quality of the things that come out of their mouths, and 2) the discipline they develop for their sales day.

The first one, quality, tends to be a bit softer—a sort of “I know it when I see it” thing—but it’s still exceptionally important.  You certainly know a good movie when you see one.  You might not be able to explain what makes the movie good, but you still know it. The same will hold for good sales people, and when you educate yourself about what to look for, you’ll become very good at figuring out what actually separates good sales people from bad ones.

The second part, discipline, focuses on process and more readily yields to data analysis. We’ll get to that in a later section.

When talking about the quality of things emerging from your mouth, there are again two main parts to consider, a) your sales and presentation skills, and b) your product and market knowledge.

Product knowledge

I am assuming that you make a great effort to understand everything you can about your product and your market. Study. Memorize. Practice. I don’t have much to add here, except to say, that the better your domain knowledge, the better your conversations will go. Neglect this and you’re crippling yourself as a sales person.

You’ll often find that sales people frequently have a fear of sounding dumb, especially if there is a large difference between the technical skills of the salesperson and the people they normally talk to.  This tends to lead to timid and boring presentations.  It also involves a lot of mumbling and low-talking while the sales person desperately prays for a change of topic from the one they only dimly grasp. Sometimes they will just blurt out, “Java!” and hope the whole thing goes away.

There are two fixes for this, the first I already mentioned, which is to crush your areas of ignorance.  If you plan to be a top performer in your field, then this is part of the cost. Just accept it.

The other way to mitigate this worry is to never pretend to know things you don’t know. Learn to say, “I don’t know” with total ease.  If you start to get into tricky terrain, don’t guess, and don’t speculate, just say, “I don’t know, but I’ll find out for you.”

Always be fearless with “I don’t know,” but also do a bit of self-analysis. Recognize that if you find yourself saying this so often that it would just be easier to have someone else handle the call, then you’ve got ignorance crushing to do and you better get to it!

Sales Skills

The buying process

Understanding the buying process is important because it gives you a framework for understanding and analyzing what you’re doing.  Good sales books all have some view about how the sales process unfolds. I think the clearest and most useful articulation of this is in Frank McNair’s book, How You Make the Sale. It’s a short and readable book which will give you a nice foundation in the sales process. In an abbreviated form the sales process looks like this: You find out what problems the prospect is having, you present your solution, you deal with objections, you close, and usually you follow up.

Each of these can be exhaustively discussed and dissected (plus I left a couple out), but remember, we’re doing the basics.

Next: The most important sales skill you can learn.

 

How to do AB Testing using Google Website Optimizer

September 3rd, 2010 by Michael Pryor

Every week we do a 10-15 presentation internally where someone from the office gives a quick how-to or instruction on some tech related topic.  Last week Ben Kamens talked about how we do AB Testing for FogBugz and Kiln using Google's Website Optimizer.  I edited it a bit to keep all our secret stuff secret, but I've included it below so you can learn how to do it yourself.
 

Cheeky Python: A Redis CLI

July 21st, 2010 by Tyler Hicks-Wright

Recently, at work, we started using MiniRedis as a lightweight store for some job queuing on Kiln's backend. We had originally planned on using the full Redis, but because we have to deploy licensed Kiln on Windows, we had to come up with our own solution.

So far, it's been working very well for us. The Redis command set is pretty small and very straightforward, which makes it easy to clone. The only annoyance we've run into is that the stable command line interface (CLI) for Redis only speaks the 1.x protocol, while MiniRedis only speaks the 2.0 version. The redis CLI also does not run on Windows. This is a bit of a problem, since we're still working on our queuing system and we need to do testing.

To get around not having a client to use, Ben would telnet in to the MiniRedis port and type out the commands manually. It ended up looking a bit like this:

I, on the other hand, would fire up Python and, using the redis-py library (which is a very nice client library), issue commands directly from there. Neither option was very convenient.

So one day, tired of having to do all the imports and set up the connection, I decided to put together a CLI using Python.

import cmd

class RedisCli(cmd.Cmd, object):
    pass

if __name__ == '__main__':
    RedisCli().cmdloop()

The basic CLI is very simple. Python's cmd module takes care of all the hard parts for you. If you run this script, you'll get a prompt (Cmd) that supports one command: help. Unfortunately, that's all you have. You can't even exit gracefully. So that's the first thing I added:

class RedisCli(cmd.Cmd, object):
    def do_exit(self, line):
        return True
    do_EOF = do_exit

The cmd module lets you define commands by writing a do_foo() method which takes the line the user typed in. The above code gives you the exit command, and also makes EOF (Unix: Ctrl-D, Windows: Ctrl-Z) exit for you. That's helpful, but it doesn't really add much in terms of actual functionality. For that, we import the Redis client libraries

from redis import Redis

initialize the connection

class RedisCli(cmd.Cmd, object):
    def __init__(self, host, port):
        self.redis = Redis(host=host, port=port)

and add some of the Redis commands

    def do_get(self, line):
        print self.redis.get(line)

    def do_set(self, line):
        key, value = line.split()
        print self.redis.set(key, value)

This is nice, because help will now list get and set. But Redis has many more commands available. One option would be to continue adding all the Redis commands until you had the full set specified and properly parsing the command line. That's pretty time consuming, brittle, and just plain boring. Personally, I don't have the patience.

Fortunately, the cmd module has a default() method which is called for any unrecognized functions. That means we can get rid of do_get and do_set and replace them with:

    def default(self, line):
        parts = line.split()
        print getattr(self.redis, parts[0])(*parts[1:])

Huh? Let me explain: getattr() takes an object and an attribute name, and returns that attribute if it exists. To illustrate, calling getattr(obj, 'foo') is the same as calling obj.foo. In this case, we're assuming the user typed in one of the functions defined in the Redis object. We use getattr to get that function, and then we pass the rest of the arguments to it using Python's *args syntax. This sidesteps the problem of not knowing how many arguments the commands take.

Unfortunately, this approach is prone to errors. For example, the user can type in __init__, which will call the Redis object's constructor again, overwriting our connection. Someone could also try to call foobarbazbat, which does not exist in the Redis object and will throw an error. Lastly, we've also lost our list of commands when you type help.

To fix this, we're going to have to do some spelunking in the Redis object. Fortunately, Python's dir() function returns all of the Redis object's attributes. We can then iterate over them, filter out any that start with an underscore (Python's convention for private attributes) and make sure they're callable. We then use setattr to create a function in our own class that calls into the Redis object and prints the result.

    def __init__(self, host, port):
        super(RedisCli, self).__init__()
        self.redis = Redis(host=host, port=port)
        for name in dir(self.redis):
            if not name.startswith('_'):
                attr = getattr(self.redis, name)
                if callable(attr):
                    setattr(self.__class__, 'do_' + name, self._make_cmd(name))

    @staticmethod
    def _make_cmd(name):
        def handler(self, line):
            parts = line.split()
            print getattr(self.redis, name)(*parts)
        return handler

Notice here that _make_cmd is creating a new function inside of it, and returning that function so we can set the do_foo of our own class to the function that calls self.redis.foo(). Likewise for any callable function in the Redis class.

Now if we type help on our command line, we'll get a list of all functions in the Redis object. Also, if we try to access anything private, like __init__, we'll be told that syntax is unknown. This also means that our default() method is no longer necessary, since we've already enumerated everything that we could possibly call on the Redis object.

You'll notice, however, that help lists all of the functions as "Undocumented". It would be really nice if we could also get documentation for each of these commands. Now that we can easily list all of the available commands, we could write the documentation ourselves by specifying a help_foo() function for each command. However, this is boring and like I said before, I don't have that kind of patience. It also turns out that writing our own documentation would be redundant, as the authors of our Redis client library have done a good job documenting each function in the form of docstrings:

def get(self, name):
    """
    Return the value at key ``name``, or None of the key doesn't exist
    """

Python takes these docstrings pretty seriously. In fact, they become an attribute of the function itself, called __doc__. This is great for us, because it means we can pull those docstrings into our CLI and make them documentation for our commands. We use the same method as before to dynamically add help_foo() methods to our own class for every function that has a docstring:

    doc = (getattr(func, '__doc__', '') or '').strip()
    if doc:  # Not everything has a docstring
        setattr(self.__class__, 'help_' + name, self._make_help(doc))

    @staticmethod
    def _make_help(self, doc):
        def help(self):
            print doc
        return help

So now if we type help, we'll get a list of "Documented" and "Undocumented" commands. If we type help get, it'll tell us "Return the value at key “name“, or None of the key doesn't exist." Awesome!

This is getting to be a useful little CLI. In addition to having a documented list of all commands available, we also get tab completion for our commands, so if we type l<TAB>, we get the list of all list commands. (On Windows, you'll need the pyreadline module installed for this to work.) But what if we could also autocomplete our keys? Some of our keys get pretty long, and typing them out is a pain. We could define a complete_foo() method for each of our functions, but all we're ever going to be completing are the keys, so we can just use the completedefault, which is a catchall completion, to grab our keys for us.

    def completedefault(self, text, line, start, end):
        return self.redis.keys(text + '*').split()

Once we've added this, we can type get bar<TAB> and we'll get all of the keys that start with bar.

We're in the home stretch now. Just to make things a little nicer, let's modify the prompt and the intro message so the user knows they're in the Redis CLI:

    def __init__(self, host, port):
        ...
        self.prompt = '(Redis) '
        self.intro = '\nConnected to Redis on %s:%d' % (host, port)

And finally, because this is a tool we want to be able to use with different servers, let's add the ability to specify a host (-h or --host) and port (-p or --port).

import getopt

if __name__ == '__main__':
    opts = dict(getopt.getopt(sys.argv[1:], 'h:p:', ['host=', 'port='])[0])
    host = opts.get('-h', None) or opts.get('--host', 'localhost')
    port = int(opts.get('-p', None) or opts.get('--port', 12345))
    RedisCli(host=host, port=port).cmdloop()

To finish, we just add some error checking so we don't get bailed out with an exception if we happen to make a typo. Here's the final script:

import cmd
import getopt
import sys

from redis import Redis
from redis.exceptions import ConnectionError, ResponseError

class RedisCli(cmd.Cmd, object):
    def __init__(self, host, port):
        super(RedisCli, self).__init__()
        self.redis = Redis(host=host, port=port)
        self.prompt = '(Redis) '
        self.intro = '\nConnected to Redis on %s:%d' % (host, port)
        for name in dir(self.redis):
            if not name.startswith('_'):
                attr = getattr(self.redis, name)
                if callable(attr):
                    setattr(self.__class__, 'do_' + name, self._make_cmd(name))
                    doc = (getattr(attr, '__doc__', '') or '').strip()
                    if doc:
                        doc = (' ' * 8) + doc  # Fix up the indentation
                        setattr(self.__class__, 'help_' + name, self._make_help(doc))
        try:
            # Test the connection. It doesn't matter if 'a' exists or not.
            self.redis.get('a')
        except ConnectionError, e:
            print e
            sys.exit(1)

    @staticmethod
    def _make_cmd(name):
        def handler(self, line):
            parts = line.split()
            try:
                print getattr(self.redis, name)(*parts)
            except Exception, e:
                print 'Error:', e
        return handler

    @staticmethod
    def _make_help(doc):
        def help(self):
            print doc
        return help

    def completedefault(self, text, line, start, end):
        return self.redis.keys(text + '*').split()

    def do_exit(self, line):
        return True
    do_EOF = do_exit

    def emptyline(self):
        pass  # By default, cmd repeats the command. We don't want to do that.

if __name__ == '__main__':
    opts = dict(getopt.getopt(sys.argv[1:], 'h:p:', ['host=', 'port='])[0])
    host = opts.get('-h', None) or opts.get('--host', 'localhost')
    port = int(opts.get('-p', None) or opts.get('--port', 12345))
    RedisCli(host=host, port=port).cmdloop()

And there we have it. A full-featured, robust, well-documented Redis CLI in about 60 lines of code. For comparison, the C version is over 500 lines of code, and has no help documentation or code completion.

The best part, though, is that this doesn't really know anything about Redis at all. The only parts that are aware of Redis are __init__(), which sets up the Redis object, and completedefault(), which gets our keys. That means that you could easily adapt this script to be a CLI on top of any client library you have.

Cross posted from http://hicks-wright.net/blog/cheeky-python-a-redis-cli/.

SQL Server 2008 Express

June 15th, 2010 by Rich Armstrong

We found out recently that SQL Server 2008 Express, the free edition of SQL Server, has increased its database size limit from 4GB to 10GB!

SQL Server is an enterprise-grade database that runs FogBugz flawlessly and almost never corrupts or crashes. In our experience, for running FogBugz, it's far superior to MySQL or Access.

How much usage can you expect before exceeding 10GB? Well, it depends on how you use the software. If you're using FogBugz for regular email correspondence with your users (with normal size attachments), it would take a few years to hit this limit, and we can help you clear out old stuff when that day comes, extending your free usage by a year or more. If you're not using FogBugz for email, attachments, or large log files, you'll probably be fine until The Singularity.

Placeholders

January 30th, 2009 by Rich Armstrong

Snippets are a powerful feature of FogBugz, but many people don't know about placeholders in snippets.  These allow you to put a tag in your snippet text that will automatically be replaced with a value from the case.

The easiest way to see how these work is to see them in action. To do this, I created a test snippet which shows me all placeholders and the values they're replaced with.  Take the whole of the text below and copy it into a "test" snippet, then use it in a case (preferably one that's been emailed in).

A lot of folks ask us (as I asked when I first joined) why we don't have a snippet for extracting the first name out of the email's From address.  The simple answer is that this is not just a simple database value that we can pop into the text.  This will be one of my big wishes for future versions of FogBugz, but it won't be coming any time very soon.

Note that these placeholders work in outgoing autoreplies as well. Here's the snippet text: 

{case} (case) for the case ID

{sender} (sender) for the sender's email address

{subject} (subject) for the subject of the message

{ticket} (ticket) for the external ticket ID

{url} (url) for the URL of the FogBugz install

{ticketurl} (ticketurl) for an external link to the case

{ticket} (ticket) for the non-URL portion of the link.

{username} (username) for the name of the logged on user

{useremail} (useremail) for the email of the logged on user 

Troubleshooting the FogBugz Screen Shot Tool

November 7th, 2008 by Rich Armstrong

The FogBugz screen shot tool is a pretty simple thing, but you'd be surprised how often people run into difficulty with it.

Luckily, troubleshooting problems is pretty easy.  On Windows, we use the same libraries IE uses, so if you can log onto your FogBugz account with IE, you should be able to use the screen shot tool.

By far the most common mistake happens when people move servers or FogBugz installs. After that, you need to make sure that the FogBugz URL in your screen shot tool points to the right install.  You can find it on the bottom of the screen.