Archive by Author

Dropbox is saving my bacon

About a month and change ago a Japanese coworker asked me “Hey, Patrick, have you ever heard of Dropbox?”  All I knew is that they were some vaguely storage-in-the-clooooooooooooooooooooooud startup, but not really the specifics.  But since he and another coworker were interested in it I did some checking to tell them what they would need to press to sign up & etc.  And, yep, storage in the cloud, painless backup, blah blah.  So I grabbed an account for the heck of it and decided I would get around to backing up my files one of these days.

Sigh.  You think we would know by now, right?  “I’m going to start a backup any day now” ranks right up there with “Hmm, well, we haven’t heard from that freaky serial killer in a while.  I think I’ll stay in the house.”

This is despite Benji and Andy Brice both having recent hard drive failures.  (Andy’s, which was a year ago so I suppose not so recent, even came with the title “Your harddrive *will* fail”.  Yeah yeah, sure, and I bet you think there is a machete-wielding maniac over in the next room.  Bah, I think I’ll take a bath.)

Thankfully I was sufficiently moved by their advice to start keeping backups of my servers at Slicehost, which has the added benefit of protecting my source code (since I have my repositories on those servers).  Most of my critical business data is already off of my laptop — its at a Google server farm, or chilling on a Slicehost server, or over at Paypal, but there is still quite a bit of sentimental value in my photos and nuisance in having to reconfigure, e.g., Eclipse to match my personal setup again when I reinstall it.

Anyhow, today the inevitable happened: my Vista-using laptop decided to start the sputter and die deathspiral.  Thankfully, after an hour of fruitless restarts, I was able to boot into safe mode, where I am right now.  I think the hard disk covering some of the code loaded by all the bells&whistles that autoload when the machine boots is toast.  Luckily untoasted is my ability to read the rest of the disk and run Dropbox.

Which is currently streaming my last few folders of Really Don’t Want To Lose That to safer pastures.  Here’s $100, Dropbox — thanks a million.

Fun tip for Vista users: mklink /D name-of-your-symlink C:\Users\blahblah\Documents\whatever will create a symlink between two places on a Vista OS.  If you have a symlink pointing out of your Dropbox folder, dropbox will perceive the stuff outside (say, a full Cygwin installation) as being inside of the Dropbox, and automatically sync it for you.  I really appreciate that trick, as it meant I didn’t have to copy/paste the files I need to update and risk more harddrive activity at the moment.

2 hours until the last of the files are off the disk.  Go Dropbox, go!

Yay for A Productive Hour

I finally killed that little permissions error (protip: if you symlink a to b, and are wondering why you can’t access a/c, a/d, and a/e despite the preferences on a, c, d, and e all being right, check to make sure you’ve chmod-ed b/. properly.)

I also did my very first push out to github, which was slightly on the painful side (Windows user — I’m used to Rails programming having its share of pain) but cleared up fairly fast. I think I’m really going to like git for source control, although since I already have a SVN repository I’ll probably keep that as my main method.

Here’s what I did: took (a particular version of) Delayed::Job and extended it so that it can accommodate multiple workers at once. You can see the details here.

That too ENTIRELY too long

Well, on the plus side, the last three days have probably been my most productive programming spring ever.  On the minus side, a lot of it was spinning my wheels fighting against problems rather than making forward progress.  I blame fatigue.

What I Have Done:

Bingo Card Creator 3.0.  Whee.  It can interact with the server to save user’s word lists in the cloooooooooooud.  Which is apparently the $10 buzzword for a client-server application these days.  For extra bonus points I threw in PDF generation on the server — How hard can it be? – and then got to rediscover the joys of heavy duty fat client Java application development.  Did you know that there is no way in Java’s standard library to copy a file from point A to point B?  Or that if you open the desktop in a Java open/save window it will show you some GUIDs as possible folders?  Fun stuff.

What I Have Mostly Working

Delayed Job integration.  If somebody tries to generate a thousand bingo cards on Prawn, that essentially takes one of my Mongrels and ties it up for a minute.  Behind that, requests start piling up and not getting executed.  Plus, should they have a connection hiccup, well, guess I lose.  So rather than generating PDFs in the request/response cycle, they get queued up for execution in the near future, using Delayed Job.  

Why is it only “mostly” working?  Well, following standard Linux best practices, the user that is supposed to execute the jobs has very little in the way of privileges.  Apparently too little to actually touch his directory.  I have tried everything I can think of to fix this, with no dice, so its time to walk away and come back fresh later.

What Isn’t Even Started Yet

The web version of the software.  (Well, OK, technically the PDF-ification and most of the existing infrastructure will get reused, but I still have to actually make the screens for it, and then tie them into the purchasing pathway.)

I hope to get the web stuff mostly working this weekend and then open 3.0 up for beta testing.  If you’re interested in helping out, please drop a comment, particularly you Mac freaks out there.  

You can see the newly redone PDFs and GIFs for most cards at http://staging.bingocardcreator.com .  Still got some bugs to iron out of that, though…  (Prawn + Imagemagick is literally fifty times faster than rendering through the Windows printer and then screenscraping Adobe Acrobat reader then pasting into Paint — automated, naturally — for cropping out a GIF screenshot, incidentally.)

572 day uptime…

11:59:49 up 572 days, 20:07, 1 user, load average: 0.00, 0.00, 0.00

Sadly, I just had to resize the slice that has been running bingocardcreator.com for the last 572 days. This requires about a minute of downtime. Drats, my perfect record!

Hard to get motivated some days

I’m wrapping up day two out of the five-day vacation I have for Golden Week, and have not quite gotten as much accomplished on getting the new version out as I had hoped.

Task list to embarass myself into working hard tomorrow:

Bingo Card Creator 3.0

  • Client connects to server, validates license key
  • Server accepts connection from client, validates and if necessary reissuses license key
  • Client contacts server, server saves word list to database
  • Client-side GUI for saving word list to server
  • Client contacts server, server responds with word list
  • Client-side GUI for loading word list from server
  • Client contacts server, server responds with list of client’s word lists
  • Client-side GUI for loading word list from server
  • Client contacts server, server responds with PDF of specified word list
  • Client-side GUI for configuring PDF
  • Client-side GUI for saving PDF
  • Update license agreement to clarify usage of server
  • Client requires acceptance of updated agreement to use server
  • Set e-junkie to use automatically generated license keys instead of saved ones to stop reissuing the same key (sidenote: my fault, not theirs — I used the same key list for the CD version and download version)
  • Update PAD file to reflect Bingo Card Creator 3.0
  • Recruit Mac testers for BCC 3.0

Bingo Card Creator.net (my internal name for the web app version)

  • Set up staging.bingocardcreator.com for testing
  • User account page — edit name, email, password, Registration Key, etc
  • User dashboard — display existing lists, printouts
  • Word list editing workflow
  • Printing workflow
  • Generation of bingo cards PDFs
  • Cache saved PDFs to disk
  • Rewrite content publication to use Prawn & ImageMagick instead of laptop automation
  • DelayedJob integration to remove PDF generation from HTTP request/response cycle
  • Lightbox to present download BCC or sign up for BCC.net choice
  • Lazy logins (no login for guest mode, upsell to free trial)
  • Free trial upsells to $$$

Random tasks

  • Integrate signup with MailChimp API to do autoresponder series for hints & tricks
  • Set up mailing list for newsletter
  • Resize Slicehost slice to 512MB to accomodate anticipated need for DelayedJob instances and extra Mongrels
  • Blog about why I’m finally spending time to make a web version

Major Progress on BCC Web Application

I did some more work on the upcoming BCC 3.0 this weekend, which is going to coexist on the desktop and the Internet.  (Feel the power of Web 2.0… several years late!)  

The biggest challenge with BCC coding-wise has always been laying out the bleeping cards.  Mostly, this is because Java has very primitive printing facilities.  I render everything to a Swing canvas and then essentially print the canvas, and Swing is most definitely not designed as a printable format.  This exacerbates some issues which are always going to be hard, such as “How do I automatically size text so that it looks visually appealing without requiring user input?”

Since printing in a web application is sort of hard to control (CSS and usability issues galore), I’ve opted to generate PDFs, which is a quite common choice.  The Prawn library (a new-ish alpha-quality Ruby library for PDF printing) is an absolute lifesaver — I’ve got better behavior out of it in 8 hours of playing around then I’ve been able to coax out of BCC in 2 years.  There is still some ugly spaghetti code hiding in the bowels of it, but its literally a quarter of the size of the stuff in BCC itself, and much, much more comprehensible.  

Feast your eyes: 

(I know, Roald Dahl’s name is screwed up due to some sort of encoding issue.)

Here’s the same card printed in Bingo Card Creator:

I really prefer the Prawn version to the Java version for out of the box behavior:

  • prettier autosizing (particularly for the column headers)
  • better line breaking logic
  • better centering of the words in the squares
  • capability to add titles (often requested by customers, never implemented in Java because it would essentially require a rewrite of code that I scarce dare to tread in)
  • capability to add watermarks/footers (often requested by, erm, me)

Printing is, by my estimation, about 90% accomplished.  (I still need to work out some internationalization kinks and then figure out how I’m going to generate the PDFs and store them outside of the web request/response cycle — I don’t want someone printing 800 cards for a Fortune 500 retreat to lock up the server accidentally, but I do want to support that use case.)

After I get printing done I still need to:

  • Code GUIs for word entry, loading/saving lists, etc.
  • Figure out user management (usernames/passwords, forgot password, restricting access appropriately, etc)
  • Extend my admin interface so that I can address issues that people have, should they have any.
  • Figure out how to integrate the web app into my site without confusing the heck out of people.
  • Rewrite a whole lot of copy.  (See the above point.)
  • Sprinkle my pages with copious sign-up-for-webapp-now calls to action.
  • Adjusting the BCC client for close-to-seemless integration with the website (save to/load from Internet)

Now that printing is mostly working the technical issues are all downhill from here.  My biggest worry is the perinneal one for web applications: can I convince non-technical users that “web sites” are worth paying money for?  This is one of the main reasons I’m not planning on deprecating the downloadable version anytime soon.

Bad Places To Have Bugs: Pricing Logic

About a week ago I noticed a deficiency in my understanding of how my shopping cart actually worked for purchases of 2+ units: specifically, e-junkie thought they were mispriced and was bouncing the transactions, resulting in a customer getting charged but not getting their key automatically. I only get about one of these orders a year, so I hadn’t seen the behavior yet. *sigh* So I did something I thought I would fix it: turn on variable pricing, then set prices manually through my cart. Done, right?

Wrong. The next day, I started getting orders at $20.00, the new price floor. I looked around for the possible cause and figured that if you had Javascript disabled or clicked through my cart before its Javascript could load, you’d get taken to e-junkie’s fallback hosted cart, where you’d be given the option of modifying the price. For some reason it defaulted to $20, despite $29.95 being set as the default price. Not quite sure why. So I fixed it, by making the default item be a single copy at $29.95 and only having the pricing logic apply when buying through my cart.

But still the $20.00 units kept coming. Then it hit me — it wasn’t actually that edge case, it was a different edge case — involving an ugly mess of Google Checkout, e-junkie, and my code. Grr. So I went back to Plan A: reverted to the cart which charges 1,499 customers a year correctly and causes 1 guy to wait a bit while I decide how to address this in a more long-term fashion, rather than having half of the purchases this week get screwy behavior.

I lost about $120 that I know about in arbitrary discounts, plus more if anyone was scared off by the weird inconsistency between my site’s pricing and the pricing at Paypal/Google Checkout. Not that I blame them. Grr.

Memo to self: self, you’ve said it before, but avoid doing 5 minute changes at midnight.

Working on Bingo Card Creator 3.0

Well, I spent 1.5 hours today working on the newest version of Bingo Card Creator, after hoping to spend 6 or so.  Drats.  What’s on the agenda:

  • Fixing a display bug when editing the Free Space! under certain conditions.  (Done already.)
  • Moving the default Save/Open directory to the OS-dependent default save directory (i.e. My Documents) rather than the BCC program directory.  This is mostly for Vista compatibility and general ease of use.
  • Moving the location of the license file to the user’s home directory, rather than the BCC program directory.  This is for Vista compatibility and, as an added bonus, it will eliminate the “reenter your license key” headache for upgrading Mac users from here on out.
  • Big feature: Bingo Card Creator is going all web 2.0 and storing its information in the clooooooooooooud.  Just kidding.  Tentatively labeled “Save to Internet” and “Open from Internet”, this lets BCC users work on files at home, work, school, or wherever without having to drag the files along with them.  It also paves the way for an upcoming new product I’m going to launch.  (Three guesses as to what.)
  • Import: While BCC can technically import from a plain text file already, I’d like to give users an easy cut/paste option to get words into it.

I hope to have something to show you guys by, oh, say next weekend, and am aiming to release this by my birthday.  (April 16th)  Funny trivia: 3.0 raised to the 3.0 power is 27, which will be my age on my birthday.

オープンソース・ソフトウェアとうまく勝負するにはどうするか

[Editor’s note: this is the Japanese translation of “How To Successfully Compete With OSS“, which I prepared because some Japanese blogs were apparently interested in the topic.]

[備考:自分が書いたHow to Successfully Compete With OSSがいくつかの日本のブログからリンクされましたので、和訳してみました。母国語ではないですから、おかしい言い方があれば教えてください。仕事外あんまり書かないので練習しないと行けないですけどね。]

時々、Business of Software (ソフト業界の掲示板)で「オープンソースソフトウェア(以下、OSS)に勝負するに意味あるか?ただだから勝ち目はないだろう?」との意見が出ます。もちろん、Joel Spolskyさんなどが説明したように、OSSにでも勝てるのです。特にHacker News (他のソフト業界の掲示板)で書かれた「Enterprise系ソフトで当然に勝てる」とのコメントが気に入りました。ただ、B2Cに関する議論がほとんどなかったです。無理無理無理と言われたことは少なくないが、B2C(Bussiness To Consumer,つまり、企業が素人に売ること)でも、値段が0円であるOSSに勝てます。

資格とは言いえないが、少し経験あり:両親や先生のためにビンゴカードを作成するソフト Bingo Card Creatorをやっています。B2C中のB2Cです。去年度の売上は2百万円程度で、今年は増加して、4月末まで給料を超えるだろうと思います。始めた2006年7月に、同じ問題を解決しようとする二つのOSSがもう存在しました: BingoCardMaker とbingo-cards.  (相変わらず、我らプロぐラマー達は意味深い名前を付けるのに上手でしょう。)

よって、下記のOSSに関する議論はFirefoxなどの一流なプロジェクトではなくて、OSSの残りの99%です。人が使っているのに、一度も聞いたことのないソフトです。すべての有料ソフトはMicrosoft Officeじゃあないと同じように、OSSはFirefoxには限らないのです。

OSSも好きですからあんまり怒らないでください!:私的活動でも仕事でもOSSを使っています。コードを共有したり、自分のプロジェクトを時々開封したり(私のshopping cart を使えますよ)します。OSSが好きです。OSSか有料ソフトかどちらかが生き残るなんて思えません。

したがって、「OSSにするのに、こうすればいい」とアドバイスを書くとき、残忍冷酷戦略会議なんてないですよ。ユーザのニーズに応じて相応しいツールを見つけてほしいのみです。(時々それによって儲かったら、まあ、いいでしょう。)

OSSよりうまくできるものと言いえば

1)  マーケティング

ユーザには問題があります。ソフトは問題を解決するツールです。と言っても、ユーザは「ソフト不足」との問題を意識していません。

1%以下のユーザが「問題はソフトが足りない」と意識している:あなたのソフトがビンゴカードの作成のためであろうか何のためであろうか、ユーザにすでにあった問題を解決するものしかすぎません。もう解決しようとしたはずです。失敗を繰り返して、イライラして、検索エンジンでソフトを示さない「how do I make bingo cards」とか単純な質問を聞いたでしょう。数学的にいうと、去年度検索してくれた14.5万人のお客さんの中、800人しかソフトを検索しなかったです。「ダウンロード」などの専門用語を使った人を入れても、97%以上はソフトを問題としなかったのです。

OSS活動はソフトに注目し、ソフトでできることを無視する:OSSのサイトを開いてみてください。どれでもいいです。うちのソフトはどのこの、ソフトの実装方法、ソフトのバグトラカー、ソフトのML、ソフトなんてうんざりほど書かれているでしょう。problem domain (ユーザが苦しんでいる問題範囲)に関してなにひとつも書いていないでしょう。「このサイトを見ているなら、もうソフトが要としている」という非常識のせいです。

もし、あなたのプロジェクトのユーザがソフトが要としているとのスタンスでマーケティングすれば、problem domain向けのSEOを行わないでしょう。ソフトが好きなオタク同士ではなしていて、ソフトがただ家電商品に近いと思う一般人には広報しないでしょう。(自分のソフトを好評してくださったお客さんはソフトがイヤです。パソコンに興味があるから使うひとではなくて、ご家族と再会するのにパソコンが一番はやいという人なんです。)

2)  デザイン

[翻訳は思ったより時間かかったので明日終わらせます。よろしくお願いします。]

Socks, Software, and the "Stupid" Questions Costing You Sales

In response to my recent article about OSS vs. proprietary software, which stressed the need to perform handholding of non-technical users, some comments said something to the effect that they don’t want idiots using their software anyway.  I think it is important that we treat non-technical users with humility and respect, because just because they are not experts at our field that does not mean we can afford to ignore them.  (Plus, their money is as green as anyone else’s.)  In the spirit of promoting humility, I’m going to share a humiliating experience with you: I failed this Sunday at buying socks.

The Setup

I live in central Japan and work as a sometimes-programmer, sometimes-manager, sometimes-technical translator.  I am also an inveterate skinflint (a handy attribute for one to have when starting a business with $60), which means I only buy clothes when they go on sale.  My trigger line for socks is at 300 yen, which is about $3 or so.  

The missing bit of information in that sentence, which is so ingrained into us we have never questioned it, is that I just quoted the price of socks in the unit of “a pair of socks”.  Because that is the way we always think of socks: (temporarily) matched sets that are indivisible until the washer gremlins get to them.  This is so obvious to us that we probably don’t remember when we learned it, much like we technically inclined people don’t remember when we started using the word “license” to mean a copy of software and don’t remember when “open the folder” was an instruction requiring thought to follow.

The Sale

While at my local mall buying food on Sunday, I noticed a sign claiming that they were having a big sale on men and ladies footwear, including socks.  Specifically, the socks were priced as follows: 

Pretty easy, right.  You probably don’t know how to pronounce it, but its clearly 4 x (something) = 1,000 yen.  I’ll fill in the something for you: it says -soku.  (Or, together with the 4, yonsoku.)  The character literally means “foot”, and its also a classifier.  A classifier is a feature of Japanese that gets appended to a number when you are using numbers to count things, as opposed to using them as mathematical abstractions.  English uses classifiers, too, but a lot less frequently: think of someone saying “The rancher owns 47 head of cattle” or “Today I bought three pairs of pants.”

Thus my dilemma: exactly how many socks does yonsoku represent?  Does -soku mean “pair of socks” or “socks”?  If it means “pair of socks”, then that is 4 pairs for 1,000 yen, 250 yen per pair, so I should stock up on the screaming deal on socks.  If it means “socks”, then that is 500 yen per pair, so I should buy my stocks some other day when they offer a better discount.

It is not immediately obvious, by the way — I had never specifically been taught it, classifiers are wily beasts (there are something like six different ways to count a PDF file, trust me), and I know at least one other way to say “pair” which I was not sure exhausted the number of ways to describing “a matching set of footwear items”.  For all I knew, unbeknownst to me common knowledge in Japan was that socks are counted as individual discrete items, just like pants are.  (Try explaining to a Japanese person that you are wearing a pair of jeans some time.  They start muttering about crazy Americans and how we feel the need to pluralize something which any idiot can see is one flat garment.)

Hating To Ask A Stupid Question

 I stared at that sign for, I kid you not, ten minutes.  I was well aware of the fact that the entire situation was absurd, mind you: I’m a college-educated professional who has been speaking Japanese for about eight years now, I do technical translation for engineering specs on Big Freaking Enterprise Software, I am generally not a stupid person: and yet here I am, able to read the words right in front of me but unable to make sense of their import.  (Doubly embarrassing: the character soku is dirt-simple, is probably about first-grade level, and I can use it in at least two dozen words that I would actually understand, from “satisfaction” to “the condition of not getting enough exercise”.)

What I didn’t do

There was a store employee standing right next to the sign, and I’m perfectly capable of asking her to clear up my confusion.  But I didn’t.  Because who wants to admit they’re so stupid as to be unable to count socks right?  

Similarly, when customers are on your site, they hate to ask you the stupid questions.  Oh, you’ll still get your fair share of questions which might make you go hmm.  Here are a couple real ones I’ve had:

 

  • I want to buy this for my mother, but she doesn’t have a computer or the Internet.  Can she still use it on her TV or something?
  • Can your software (editor’s note: Bingo Card Creator) make bingo cards?
  • I clicked the picture in your instruction manual where it said Enter Your Name Here and it vanished!  What’s up?!

 

But mostly, when customers have a “stupid” question, they don’t spend time searching for your contact information.  They just bounce.  They:

  • don’t want to wait for an answer
  • don’t want to be seen as idiots (they have had that happen a lot with their computers and geeks)
  • don’t want to impose on someone’s time

What We Can Do About It

Luckily, since we have near-total control of the environment our customer is in when they start thinking of “stupid” questions, we can help them get answers:

  • Judicious use of web formatting.  Internet users generally don’t read, they scan.  Call out important points in bold, put them in bullet points, distinguish them with size or color, what have you.  Don’t overuse this technique or it can become somewhat difficult to identify what is really important.
  • Repetition of key points or concepts which are difficult.  Trust the teacher on this one: the basic pattern of every lesson is tell the student what they’re going to learn, teach them, have them mimic it, tell them what they have just learned.  We repeat the main ideas constantly because it helps them stick.
  • Avoid use of inappropriate jargon.  If you are selling to customers who are not professional buyers of software (hint: most B2C customers are not), don’t use words like “license” or “SaaS” or “support contract”.  Explain what those mean in simple English: you can one copy of Bingo Card Creator for $30, you pay for World of Warcraft every month, if you want us to be available for questions via phone it costs $100 per year, paid when you buy the software and renewable every year until you decide to stop.
  • Make appropriate use of analogies.  People will reach into their previous experience to answer their own questions.  For example, when I was (not) buying the socks, I figured “Maybe Japanese people count socks like they count pants” (analogy fail).  My customers have, multiple times, come to the conclusion that “A free trial for software is like a free trial for a magazine — I have to send something in to cancel it or else they will bill me”.  Rather than letting your customers find their own analogies, you should when appropriate guide them to things in their experience that will make sense.  (SaaS Our software is like a gym membership: you pay money for membership now and once a month hereafter, as long as you’re a member it costs the same no matter how much you use it, and you can cancel at any time and no owe any more money than you have already paid.)
  • Have a FAQ: You probably don’t want to call it a FAQ in a non-technical niche, but a nice inviting label like “Answers to questions you might have” or “Got any questions?” works just as well.  (Pro-tips: put the most important stuff at the top, have lots of questions visible at once, and consider what your mix of questions says to someone who is not actually asking a question at all.  For instance, “Q: My screen died after installing your software.  What happened?” is not a confidence builder, even if the answer is “A: This is totally not our fault!”)
  • Be the warm, inviting guy who welcomes questions:  Even if it secretly galls you that you have to answer questions, you should always put a welcoming, concerned, and patient face on, including in your copy around the contact method.  For instance, “Please make sure you have read the FAQ before answering a question so you don’t want our time” is distressingly common, and it is both off-putting to people (those with questions and those just browsing your site) and ineffective at reducing support volumes.  On the other hand, “We love talking to customers!  Feel free to send us an email if you have a question, a comment, or just want to say hi.” says “You may not have a problem today, but if you ever do have a problem, I will not make you feel stupid about it.”
  • Blame yourself, and only yourself.  No matter what your customer asks you, no matter what went wrong, no matter what they did: it is your fault.  Even if you don’t feel like this is true, learn to fake it.  Its not hard.  Say the word “you” more, the word “I” less (except when parceling out blame), and the word “sorry” when your customer hits something that in any way inconveniences them.  Twice.  And don’t do the cop-out “I am sorry that you didn’t see where I wrote …”  That assigns fault to them.  Who’s at fault here?  That’s right, you are.  “I am sorry that I didn’t write the instructions more clearly.  You can …  Sorry again for the inconvenience.”  

Useful Things To Know About Socks

So it turns out that -soku actually does mean pair of socks.  Drats, I let a bargain go by and the store lost a sale.  

Your customers are probably not failing to purchase from you because they can’t read (well, in the globalized 2000s it is certainly possible that you have less proficient readers of English trying to make sense of your site), but they’re also being tripped up by their “stupid” questions today.  If you can intercept these before they happen and answer them well when they slip through the net (some always will), then you’ll see an increase in sales.  Like anything else: measure, test, and seek continuous improvement on it.