Tuesday, April 29, 2008

On Scripts

I spent pretty much the entire day today onsite at a company for whom I've been working on custom software in my off hours for the last few months. When I had reached the point where I was ready to import all their data (which is currently kept in a series of excel spreadsheets) into my application, they told me that they were unable to get all of it ready in time. They had most of it ready, the only column that was missing in their spreadsheets was the "county" column, which (of course) held the county for each record in the spreadsheet. Currently they had somebody manually looking up the zip code of each one of the 4000 records in the spreadsheet and filling in it's county appropriately.

Wow, you couldn't ask for a better opportunity to show off.

I asked them to give me an hour with an Internet connection, and here's what I came up with (code is in C#.NET):


static void Main(string[] args)
{
Excel.Application excel = new Excel.Application();
excel.Visible = true;
Workbook excelWorkbook =
excel.Workbooks.Open("store.xls",
0, false, 5, "", "", false,
Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);

Worksheet frontSheet =
(Worksheet)excelWorkbook.Sheets.get_Item("Sheet1");

for (int i = 2; i < 4124; i++)
{
try
{
Range zip = frontSheet.get_Range(("J" + i.ToString()),
Type.Missing);

string builder = "http://ws.fraudlabs.com/ZIPCodeWorldUS_WebService.asmx/ZIPCodeWorld_US?";

builder += "ZIPCODE=" + zip.Text.ToString().Trim();
builder += "&LICENSE=05-Y34L-X86F";

WebClient web_client = new WebClient();
byte[] x_response =
web_client.DownloadData(builder.ToString());

string response = Encoding.Default.GetString(x_response);

string strParam = "";
int indexOpen = response.IndexOf(strParam) + strParam.Length;
int indexClose = response.IndexOf("
");
string countyName = response.Substring(indexOpen, indexClose - indexOpen);

Range county = frontSheet.get_Range(("I" + i.ToString()),
Type.Missing);
county.Value2 = countyName;
Thread.Sleep(500);
}
catch (Exception e)
{
Console.WriteLine("" + i.ToString() + ": " + e.Message);
}
}
}


No big thing. It's about 60 lines of code, and for some reason it's one of the most satisfying things I've ever written. Notice the following things about the code: -

-It's not well abstracted
-I did not package it into a library for reuse
-There are many hard-coded values
-file paths are hard-coded relative paths
-it's not particularly efficient (I could have cached repeated results, for example, and applied them without making the webservice call).
-it doesn't follow good naming conventions.
-the exception handling is minimal
-it is not "flexible" by any definition of the word.

Each one of the above points is in direct violation of the all the software principals that I am a very strong advocate of. But the fact of the matter is that this little chunk of code turned a 40 hour project for one of the client's office staff into about 15 minutes of wait time. It took a need, and provided a solution, as quickly as possible.

I think it's possible to get lost in the ideals of "good" software. Believe me, I'm all for sound architecture and the Best-Practices. But honestly, the best measure of any piece of software is how much it helps the person who is using it, and sometimes what you really need is a script.

Saturday, April 26, 2008

Fixing tendinitis

My arm has been hurting really badly this week. So badly, that I've even begun to question my career. I've had some problems my wrist and forearm from time to time, and usually a valid rest it goes away. But that pattern isn't sustainable for somebody who makes a living with their hands. I know you should never work through pain, but I can't just drop everything for a month and wait for my arm to heal. Luckily, I found an elegant solution. This blog post is not being written with my hands, it's being dictated by my voice. It turns out, unbeknownst to me, my copy of windows Vista shipped with speech recognition built in; all that I had to bring to the table was a microphone. All evening I have been working: writing emails, writing code, pretty much doing everything that I usually do on the computer without having to abuse my arms any further. I can't tell you how ecstatic that makes me, I feel like I have a new lease on my future! True, the vocal commands needed to navigate the computer are little unfamiliar a first; but really it's no more difficult than learning anything else new. It just takes a little practice, and a little patience (and perhaps a spouse who doesn't mind listening to you talking to yourself). If this ends up working out really well, I'll be posting a tutorial soon about how to set this up for yourself and about some of the difficulties of working on software without your hands.

Friday, April 25, 2008

Self-employment

So here it is, day one of working full-time on my business instead of cranking away at a day job. You know what my most profound observation is? It's pretty much like working any other day: I got some code written, made some phone calls, responded to a few emails, and made my product a little better.

The difference? It feels like it means something. My livelihood depends on me writing software WELL, rather than my salary depending on me writing software AT ALL. I'm not sure that feeling is directly related to being self-employed, I think that anybody working in a very small group (one of the first employees in a small business, for example) would be in the same situation: feeling like their actions have purpose and value. Regardless, it feels good. I think I'll keep it up.

Thursday, April 24, 2008

Community Mind Control

OK, I finally broke down and joined Twitter. It still seems a little silly, but the more interesting thing is that here I am signing up ANYWAY. I have an unnatural and deep-seated feeling that if I DON'T sign up then I'm actually missing out on something great that the rest of the technology community is tuned in to, and I just can't bear to be left out of the loop. So here I am, ready to tweet my heart out on a regular basis, and I'm actually enjoying the very thing I've been making fun of.

I think I've been brainwashed.

Wednesday, April 23, 2008

code-coverage in the rails environment

I picked up my todo list for the startup (name to be revealed) tonight, and didn't really have anything that could be done in less than the two-hour time window I had available, so I decided to install RCov (code coverage gem for ruby on rails) and see how I was doing on my test coverage. Now I'll be the first one to say that a good score on a coverage tool does not mean that your tests are testing the RIGHT THINGS, but a bad score does indicate that some things aren't being tested AT ALL. So I've decided to post the results today to publicly show just how well I'm doing, and maybe I'll do that again every month or so to keep myself motivated to keep the coverage level as close to 100% as possible.

It turns out this RCOV is pretty easy to use. I just installed the gem:

gem install rcov


then I created some rake tasks to actually run the coverage scenarios:


namespace :test do

task :prepare_rcov do
rm_f "coverage"
rm_f "coverage.data"
Rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib"
end

desc 'Measures unit test coverage'
task :unit_coverage => :prepare_rcov do
system("#{Rcov} --html test/unit/*_test.rb")
end

desc 'Measures functional test coverage'
task :functional_coverage => :prepare_rcov do
system("#{Rcov} --html test/functional/*_test.rb")
end

desc 'Measures integration test coverage'
task :integration_coverage => :prepare_rcov do
system("#{Rcov} --html test/integration/*_test.rb")
end
end


then I fired up the command line, and here are my results:

UNIT TESTS:

76.3% 14 file(s) 440 Lines 358 LOC


FUNCTIONAL TESTS:

85.6% 17 file(s) 879 Lines 736 LOC


INTEGRATION TESTS:

I have no integration tests written


So, that's a pretty embarrassing level to start at. Luckily there's nowhere to go but up. If you have a rails project you're working on, I recommend giving yourself a reality check on just how well you're testing your code: it only took 15 minutes for me to realize I've got a lot of work ahead of me. ; )

Monday, April 21, 2008

One Step Forward

There will always be more things to do than you're able to get done. Period. Although we steep ourselves in the myth of perfection, this principal applies to pretty much anything worth doing: learning a language, organizing your house, and especially running your company. Who hasn't speculated about the things they would accomplish if they "had more time"? Yes, time is a resource more scarce and precious than most of us know. The painful fact is that of all the resources at our disposal time is the only one that spends itself. You can save your money for when you need it, allocate your space as necessary (and you can always change it later), but it's all against the backdrop of time, which marches on without mercy. It's being spent right now, as you're reading this, and it continues to slip away as you sleep.

Ultimately the knowledge of the nature of time can be very valuable. Given the right outlook, you can learn to manage time (or more accurately, the things you do as time passes) better and the efficiency gains you can achieve within your life are astounding. But it can also be very damaging. In the same way that knowledge of one's own mortality can sometimes lead to an irrational fear of death, the acute awareness of time's unyielding progress can cause what is best described as an irrational amount of stress in a person's work-life. You know you have more things to do than can get done, so you cram as much of it as you can into your workday, then decide to work a little extra because there were a few other things you wanted to wrap up, and when bedtime comes you still aren't satisfied so you stay up a little later than you meant to (finally falling asleep at an ungodly hour), only to awake to the unpleasant realization that your backlog of tasks has still managed to grow and the things you finished yesterday really weren't done all that well because you were too busy worried about the quantity of work in front of you. Ultimately the stress of the unabating todo-list is so much that you slow your progress to practically nothing, since all of it seems so futile anyway.

Yeah, I've been there, and I have news for you: you're ruining your life. Brute force rarely is the best solution to any problem, and it certainly isn't the way to go with regard to timely software development. We need some sort of milestones to remind us that we ARE making progress, and that the product IS getting better, because if we don't have them it's like riding a stationary bike.

Maybe that analogy doesn't make any sense, so let me dive into it for a second:

Picture a stationary bike with no monitor; just the pedals, the wheels, and the handlebars. There's nothing else in the room (no clock, nothing). You climb on and start pedaling. After a little while you're kind of bored. How far have you gone? How long have you been pedaling? How many calories have you burned? You don't really know, so you'll probably just get off and go do something else.

Now what if the bike has data streaming to you from it? One display shows how long you've been pedaling, one let's you know the distance you've covered, etc. Now you'll get into a rhythm; As you get tired, you'll look at your timer and tell yourself "5 more minutes! You can do it". Or you might say "I know I can make it to 10 miles". Having concrete goals extends your motivation by leaps and bounds.

Now take that and apply it to developing a product. Sure, you have a task list with 100 things on it, but the worst thing you can do for your motivation is chip away at 50 of them over the course of the day. You'll have hours of work and nothing to show for it. Pick one, and knock it out. Pick one bug, and fix it (and include some tests so that it won't ever happen again; Or pick one feature, and implement it decisively, refactoring as much as you can as you go. Now you've taken one concrete step forward, and you can see that your product is improving. Even if that's the only thing you got done today, it's one step better than it was yesterday, and you're still moving forward.

There's a kind of magic that starts to take place with this approach (at least in my experience), because it seems like you're traveling twice as fast as you're used to. At the end of every day, you have something to show for your work, and you're encouraged enough to be excited about getting something done tomorrow (and so are your teammates, if you have any). As the saying goes, a journey of 1000 miles begins with the first step; so just open the damn code editor and take one.

Friday, April 18, 2008

Let there be change

What is the most common complaint during the execution of a software project?

Software Developer: How am I supposed to ever finish this $@#&ing project if the $@#&ing customer changes their $@#&ing mind every $@#&ing day?...$@#&!

I'm no stranger to that, believe me, I understand completely. There is nothing so frustrating as working on something for a long time and struggling to perfect it, only to be told that this wasn't really what they were asking for and to be handed another checklist of modifications ("you'll be fine, really, there isn't that much to it").

So how do should we mitigate it? Make the customer commit before hand to their feature list? Demand a salary increase for every late change? Make them sign the spec at the start? In blood?

Hold on, hold on, those are great ideas (note: those are not great ideas), but I think what this problem is really asking for is a perspective change. Yes, we need to keep the change list under control, but there are plenty of tools, techniques, and methodologies that already address that issue. What I want to talk about is the attitude. We shouldn't get angry when the change list starts to grow, we should get excited.

Reader: Bullshit. You are pandering to the customers, possibly to increase the frequency of your consulting offers, and I am not reading any more of this drivel.

Man, I'm glad that guy's gone. If you're still here, you're probably a reasonable reader who wants to hear me out and won't send me hate mail.

If you're getting requests for changes, it's usually not because you've done bad work (unless you've done bad work, and then you have no-one to blame but yourself). It's usually because the customer has seen the current system in action, and has an idea for a way to make it even better, and if this project is going to be anything that is going to be distributed outside your office, if this is going to be a public-facing piece of software that people will pay you to use, you're going to want that end result to be as close to "freakin' amazing" as you can possibly push it.

That's why you should be excited at the proposition of improvements; it means that the people on your team are still having ideas about how to get better, and as long as you can keep that fire-hose of new concepts going you're moving forward. So by all means release early and often, certainly prioritize those changes and work the most important ones first, definitely be on guard against making the system any more complicated than it needs to be, but for God's sake be happy that people are asking you to do more; you'll be reaping the benefits when the subscribers start rolling in.

Thursday, April 17, 2008

The Short-Timer

In a recent post I announced that I am leaving my job to pursue a start-up full time. Now that I'm half-way through my final two-weeks, I can feel the presence of an unwanted companion: Short-Timer Syndrome.

I think everybody feels it to a certain extent when they're ready to move on. You're more easily distracted, your productivity begins to fall off, people come to your desk with issues that need to be solved and all you can think of is "Why is this MY problem?". It's a pretty disturbing feeling, actually, because if you're anything like me it goes directly against your core ethics. I'm being paid to provide my skills and experience, and that means that I should be providing the best that I have to offer or else I'm not giving my employer the value they're supposedly getting in exchange for that cash. However, now that I'm leaving, part of me feels listless and wants to just slack-off and do nothing until my time here is up.

It's tempting to justify this with an internal monologue that says something like "they never appreciated me anyway", or "I've already done more than my fair share", but if we're honest with ourselves we know those sentiments don't stand up to scrutiny. It's equally tempting to be "productive" and to spend my time during these last few days getting things done that need to be taken care of for my startup, but that's equally wrong since it would mean that my ex-employer was paying me a salary (for however short a time period) to work on my outside project that does not benefit them in anyway whatsoever.

I'll tell you what I've found that helps: transition-based tasks. Things that I'm working on in order to ease my transition out of this building seem to not suck as much as the same development work I was doing before I turned in my two weeks. Tying up loose ends in libraries I wrote, documenting areas of the code that others haven't been exposed to very much, training other developers in my responsibility area to minimize the impact of my absence, anything like that, and I think I know what the reason is. When I'm doing things that are designed to help the transition, I feel like I'm moving forward towards my perceived freedom; when I'm doing regular development, the fact that I'm leaving in a week makes it seem kind of pointless, so I tend to be less involved and more unhappy.

It's a simple trick, but it's been working wonders for me. Every hour or so I take a few minutes to do something in preparation for my departure next Thursday (document a class or two, maybe refactor some of my "private" code to be more readable for a new developer), and that boost gives me another stretch of productivity on normal day-to-day tasks, which is really important to me because I don't want to lose my professionalism here in the last few days of my employment.

As an added benefit, this kind of house cleaning could keep your co-workers from blaming everything that goes wrong in the first 30 days of your absence on you and your "abominable" code. ; )

Monday, April 14, 2008

"All I need is a Programmer"

I was contacted this week by an old acquaintance, and he had a proposition for me.

"Hey, I hear you're a programmer! That's great, because my buddy and I have
this idea for a business. We have everything important figured out, and all we need is a programmer to throw it together."


On the surface there isn't really anything unreasonable about that statement. These guys know what they want for an application, they "just" need the technical know-how to implement it. So, quelling my urge to say something flippant, I penned a reasonable response.


"Well, I have some other projects I'm involved in right now, but I'm always happy to take a look at something new and see if it's a good fit. If you want to do this as a strictly cash-for-labor exchange, it would probably take $X-per-hour to get me interested in spending time on it. If, on the other hand, you don't have any startup capital and are interested in trading equity for this work, I would probably have to see at least an X% cut of the company (and this option would, of course, be predicated on whether I felt the business was a viable one that I'd be interested in being invested in)"


Although I really didn't expect him to be interested in meeting me at those terms, I expected maybe a counter offer or an indication that he was expecting Y instead of X. What I actually got as a reply surprised me a little.

Hey, so, we aren't really prepared to pay. I mean there isn't that much to it, it's just a PHP website with a MySql database, I was hoping you could just throw it together as a favor. Oh well, thanks anyway

I thought about this for a minute, and realized that implicit in the conversation are several assumptions (or perhaps more accurately, conventionally perceived "truths") with regard to the craft of software development.

1)"there isn't that much to it" = "software is really easy to write"

2)"We have everything important figured out" = "in a business, the actual software is just icing on the cake"

3)"All we need is a programmer" = "software developers are cogs in a machine, or interchangeable components of an assembly line"

So then my question is this: Are these common assumptions within the software industry, and more importantly are they accurate?

Assumption 1: software development is easy

This is certainly an opinion I'm used to dealing with, and I'm sure most of you have experienced it as well: "This isn't rocket science, all we need is a program that does [insert complicated feature here]". Unfortunately it's all too common to be under the illusion that software is about 1/10th as tough to build as it actually is. Now we could say that's not unreasonable to assume, because to a non-technical user the User Interface IS the software, so they only can perceive 1/10th of the full application anyway. Based on that fact it wouldn't be illogical to conclude that it's no big deal to just add another button there at the bottom that completely changes the work-flow of the application. This is one misconception of the software industry that in my opinion can be 100% debunked: Software development is hard. We have tools to mitigate that; there are good development methodologies that can keep us focused on what's important, and good tools that can amplify our productivity, but at the end of the day it's difficult to produce good and simple software.

Assumption 2: software is just fluff compared to the business

This is another attitude I've encountered more than a few times, and again the surface value of the argument seems reasonable. After all, software can be made to do anything (within reason), so it isn't really the software that we're selling, it's the business concept. It's the product or the service that's making us them money, not the code. Now in a way, that's very true: great software that has no utility is perhaps not great software after all. However, it would be wrong to take that statement and turn it around to say that a great business idea will succeed regardless of the software that acts as it's delivery medium. Whether you are a product or a service company, the software is telling your story and your business WILL be judged on whether it is easy to use and doesn't break down. The greatest business in the world would not be able to overcome a millstone of bad software around it's neck. This misconception is, in my opinion, false and getting falser.

Assumption 3: programmers are interchangeable pluggable components

FULL DISCLOSURE: I'm a programmer, I have a vested interest in this not being true.

Nevertheless, I have experienced this opinion many times during various job-searches. A company is experiencing time-line problems, and the "obvious" solution is to get 5 more programmers. More manpower = more progress, right? Now of course this is a biased opinion, but I don't think all programmers are created equal. Plenty of other bloggers have written on the subject of the "Rockstar" programmer, that mythical super-productive hero who can carry a project on his back, and I'm not entirely convinced that he exists. That being said, I do think that the right people in the software developer roles on a project can make a difference of at least an order of magnitude. What might take one average-joe-coder 10 hours might be done in 1 if you have the right guy for the job, and if that's true I think I can safely throw the above assumption right out the window.

What do you think? Has the software industry changed to the point where the above assumptions are becoming more viable? Or is it just that the things potential customers believe about software are changing because of the pervasiveness of technology today?

Sunday, April 13, 2008

Burning the midnight oil

So I just finished up my last piece of development for today, and it's now 1:18 in the morning (last night I was up to 2:30). After roughly a day and a half of solid coding, I have come up for air momentarily to consider an issue of interest to me: Why am I so freakin' productive at night?

Here in the wee hours of the morning, I seem to accomplish things at 3 times the pace I do during the day, and with fewer bugs to boot. You might think to yourself, "Who cares why? If it works so much better for you, just work at night instead of during the day!". Well if that's you, than you either aren't married or you are and you don't want to stay that way.

Seriously though, I can't be staying up into the middle of the night all the time, and I already have a good 8 hour block every day set aside for development, so I'd really be excited about being able to capture that productivity boost at will. With that in mind, here are a couple of my ideas as to just what makes the night such a great programming environment:

Zero Interruptions

This may be the biggest part of it, honestly. When the sun is down, nobody is calling you, texting you, IM-ing you, or sending you emails (and if they are, you can safely ignore them without offense because, hey, you were in bed, right?). For me, that's a big deal-maker that I've noticed even in my old day job's environment; days when I was left alone for a while were days when I was able to do serious damage to those endless defect lists.

The world slows down

I don't know about you, but in the middle of the night my RSS client doesn't grow at the same feverish rate that it does during the day, and that means that there's less of a chance of me seeing something cool but unrelated and taking 30 minutes to try out a tutorial that has no bearing on my current project (What?!? They're running Ruby on Javascript now?!?! I must play....).

Open schedule

Tell me if this sounds familiar:

"OK, I've got a few things I need
to get done here, but I also
need to be leaving in half an
hour to get to that meeting on time,
so I need to work on something I
can knock-out quick.
Hmm......I'm hungry."

When the moon is up, there are no meetings or conference calls, or really anything scheduled in the near future, so you don't have to keep surfacing to check the time. Theoretically, it takes very little effort to look at the clock, but for me (and maybe this is ONLY me) if I'm looking at the clock it means I've momentarily stopped thinking about what I was working on, and even though it's for only a very brief time I've still lost some momentum.

It feels pretty badass

Perhaps not everyone feels this way, but to me there seems to be a sort of "badge of honor" that comes with working on something late into the night. It's something that resonates with other hackers; we like telling stories about how late we were up hacking as much as we do about cracking some bug we were after for 3 days, or about crashing a production application with a bit of untested code, or about losing weeks of work in a hard-drive failure. We can all say "yeah, I've been there", and that makes it a common bond in this psuedo-sub-culture of hackerdom. So maybe I'm more productive at night for the same reason that I can work-out harder and for longer when I'm listening to high-energy music: the attributes of my environment unconciously cause me to more closely conform to a strong personal narrative.

Extracting the essence

So based on my possible reasons above, here are some ways you could recapture some of that midnight-power for the daylight hours.

1. Minimize interruptions during hacking time. Maybe even turn off your cell phone and close your email client, it'll all still be there when you resurface.

2. Keeping up to date with industry news is important, but probably not as important as actually contributing to the industry. That's right, close the news reader, it too will be around when you are ready to take a break.

3. Find the next thing on your schedule for the day (hopefully a few hours off) and set a timer or an alarm that will go off in time for you to prepare for whatever it is. Hopefully by knowing that the alarm will go off before you need to do anything you'll be able to leave the time management up to the device and focus all your brain-cycles on the task at hand.

4. Not sure about this one. I guess I could say that the more attributes of your environment that remind you of awesome hackerness, the more awesome of a hacker you will be (my english prof would probably cringe at that sentence). Maybe you should grow a beard and take off your shoes? ; )

Saturday, April 12, 2008

Taking the Plunge

So here's the official public announcement: I quit my day job as of last thursday, and will be working full time on the startup I've been talking about from the 24th onward. This was a pretty big step, you see, because I was bringing in a lot of income from my software consulting job at an insurance company, and now that's over. In a way that's kind of scary, but at the same time it's also motivating: nothing breeds competancy like necessity. So those of you who are regular readers, expect to see more posts on the care-and-feeding-of-startups in the near future. Wish me luck.

Thursday, April 10, 2008

Clickatell's Redemption

Recently, I wrote a post regarding a bad experience I had with the SMS Gateway provider Clickatell.

I just wanted to put out an update now to let those of you who are considering Clickatell for your SMS needs know the resolution of the matter. On 04/10/2008, a manager at Clickatell contacted me directly by phone to apologize for the problems I'd had while working with them, and to make sure my refund was provided as requested. In return, I retracted my complaint with the Better Business Bureau, so everything has turned out fine, and I appreciate the fact they were willing to do that.

That being said, I do want to give a quick plug to Upside-Wireless. This is the service I'm working with right now, and their customer service has been much better than what I experienced with Clickatell overall. When I had a latency problem about a week after I'd switched to them (messages were suddenly taking 20 minutes to deliver), they were quick to respond and got it fixed with no extraneous pleading or cajoling on my part. This could, of course be due to chance: Perhaps I was just unfortunate enough to be paired with clickatell's WORST customer service rep when I was working with them, while simultaneously being lucky enough to get helped by Upside-Wireless's star performer. I certainly don't think that Clickatell could have the kind of customer service that I experienced with them be very common or else they'd be out of business by now, so I probably just fell through the cracks to some disgruntled employee. Nevertheless, the anecdotal evidence shown thus far means that I will stick with Upside-Wireless for now.

Wednesday, April 9, 2008

date_select functional testing (another gotcha)

Here's a quick sympathy post for those who are relatively new to the Rails framework.

Situation:

You're trying to test a form post that uses the "date_select" helper tag and you've noticed that rails is somehow automagically transforming the three fields in the form into one attribute in the request, and you don't know how to write a functional test that has everything formatted correctly in order to produce a valid date on the other side. You've googled for help and found not many people have addressed this.

Solution:

The reason most people haven't addressed this problem is that the solution is so very simple that most people haven't even run into it as a "problem" per se. But if you found this post because you haven't solved the "problem" yet, than you might be a little like me; you might have decided to think about the problem so long that you've convinced yourself that you don't know how you'll accomplish it. So I have two solutions for you, one for your immediate problem of how to set up a post parameter representing a date in a functional test, and another for your (my) problem with overthinking things to death. First, the code:


class some_controller_test < ActionController::TestCase
def test_post_form_with_date
post :action_name, {:model_name=>{:date_field => 5.days.since.utc.to_s}}
assert #...anything you need to check....#
end
end



Yes, that's right, all it really took was just setting up a date object and calling "to_s" (this solution worked for me, if anyone else has anything slicker they'd like to post feel free to do so below). It was really the obvious thing to do in the first place, but I was so sure I was going to have to work around the 3-field nature of the date_select helper method, that I didn't even try it out first; and therin lies the second solution. Try it out. Just try SOMETHING and you'll be one step closer than nowhere, which is were you were before. ;-)

Tuesday, April 8, 2008

Mac = Awesome Dev Machine

This one will be short, but to the point. Two weeks ago my trusty Toshiba Satellite decided it didn't like starting up anymore (it would crash halfway through the boot). I'm still not sure why that happened, but being in the middle of a development push for my startup I didn't feel like spending time trying to nurse it back to health. So, I formatted the hard drive and started with a fresh install of Windows Vista, and steeled myself for the lengthy task of getting my machine back into the development state it had been in before this catastrophe. Thinking ahead, I realized that this could happen again in the future, and decided to get out my wife's MacBook Pro and prepare it as a development environment as well so that I would have a machine to work on in case mine died again during a critical time period. Now I've never been a Mac user; I've been a windows hacker for many years, and have worked on *nix systems for some projects, but I'd always considered a Mac to be a way-too-expensive media machine.

I don't have time this morning to go into the gory details, but here's the summary: The Mac took about 1/4th of the time to get development-ready for a rails project (mostly because all the necessary Ruby and Rails stuff comes pre-installed), so I started working on my next few development items (using textmate) and was pleasently suprised to find that I truly enjoyed working on that machine.

For one thing, the tests ran super-fast. You almost can't test-drive your work on Windows at all because the tests take at least 30 seconds to run which means that you just can't afford the time to run your tests before and after making each incremental change. Running my automated tests on the Mac was like a small taste of heaven, and having that experience just serves to make me more disappointed in my windows environment when I'm using it. Additionally, TextMate was like a dream come true. On windows, I'm using RadRails, which works OK, but all the built in macros in TextMate are really cool, and it's intellisense (autocompletion) seems to be much better. Oh, and one more thing, Windows Developers are second class citizens on the Ruby-On-Rails help forums. This isn't necessarily because nobody likes them; it's more due to the fact that there just aren't that many people developing rails apps on windows (for obvious reasons, I now see). On the other hand, if you're driving a Mac, you will find all the help you need and more.

For all these reasons, I will proudly purchase a Mac for my next development machine. And now, my farewell letter to windows:


Dear Windows,


We've had a good run, you and I.
So many games, so many hours...it
all seems so empty now.
Remember when I first started learning Java?
We would spend hours together,
sure that we could continue on that path
forever. How naive we were.
It's nothing about you, really, it's
just that we've started to grow in
different directions. I've changed,
and I don't think it would be healthy
for me to cling to you when we really
are starting to have
less and less in common.
I don't want us to lose touch, now.
I'll be back to hang out for a
while whenever I need some C# support,
but I think it would be best
for both of us if we took a break and
really took some time to focus
on ourselves. I'll miss you, windows;
and I'm sincere when I say
"Have a great life".


Your friend,


~Ethan Vizitei

Monday, April 7, 2008

The Hive

A friend showed me the website of a very interesting group today (can they be called a company?), and I had to put up a post to share it. Their website is "http://www.thehive.com", and to be honest it sounds too good to be true. According to their website, they are one big distributed group of hackers who work in some of my favorite technologies building cool projects for competative salaries with full benefits living wherever they want. Additionally, it sounds like as a developer for The Hive you are provided with high-end Mac hardware as your development environment, which means I'm drooling off the side of my keyboard right now. Rephrased: "Work from home on a sweet development machine using your favorite technology stack"; if I weren't working on a startup project myself, my resume would already be in the mail.

The only thing that seems strange about this place is that I can't find any outside information on them. Excluding their website, it's hard to prove that they exist, and the only project they claim on their website is an internet dating application, which is free to use. How is this sustainable (I suppose they could be sailing on ad revenue)? I've done some extensive googling, and haven't turned up much, so I guess they must be flying in stealth mode on other projects, so to speak, using funding to float them until they have something that turns a profit. In any case, on the surface it seems like one hell of an opportunity. They have openings posted for PHP, Ruby on Rails, Qt C++, and Java SWT, all of which would be cool jobs to have, so if you're a hacker in one of those categories and are looking for a fresh opportunity maybe you should go to the link above and find out if these guys are for real.

Friday, April 4, 2008

WTF is 422?

Blogging has been low on my priority list recently, since I've been working hard on my startup prototype, but I had to put in an entry tonight to share a solution to an unexpected problem I just fixed with my application.

So here's the scenario: My app needed to be able to send text messages, and receive texted responses to them for processing. Because I don't have an SMS gateway myself, I contracted to use the services of ipipi.com (see my post on SMS Gateway Providers). They provide an API of RESTful web services you can use for this sort of thing. They have a URL that I post my sent messages to, and I expose an address in my rails App that all incoming messages are forwarded to. Pretty straight-forward. Now, after reading the documentation for the web-service requirements, I quickly threw together some functional tests for my Rails Controller that would be handling incoming messages, and I'll be honest, I tested the bejeezus out of it. Every possible combination of bad parameters I could think of, pretty much anything that could go wrong I had a legitimate response for. So, after making sure my impressive suite of automated tests was passing successfully, I fired up my local server to give it a test run. I walked through the application, and received a text message on my phone, as intended. I couldn't respond to it directly, since my messages were being forwarded to my live application, but I had a mocked up form I could use to replicate the incoming HTTP-POST of a replying message, so I used it to generate a response, and everything behaved as expected. "Hooray", I thought, "I have most verily succeeded!".
Excited to try out the real response sent from my phone to the application, I promoted my code to my production server, and ran the test again. After recieving my text message, I responded, and waited....and waited...and waited. No dice. Apparently it just didn't get through. I went to check out my account with www.ipipi.com, assuming it must be some error in the forwarding settings, but everything checked out. Then I got an email in my gmail inbox: "Unable to forward SMS: Server Response - 422".
"422?", I thought, "What the hell is 422?". Obviously, it was an HTTP status code that was being returned, indicating some sort of error, but it wasn't one I was familiar with. A quick google search was very little help:

422 - Unprocessable Entity
The server understands the media type of the request entity,
but was unable to process the contained instructions.

This didn't really mean anything to me, so I had to operate on the assumption that, since my emulations of the POST were successful, something was wrong with ipipi.com. I wrote their customer service department, and was politely told that there was absolutely nothing wrong with their service and that the example I was using to emulate it was fine, so it was back on my plate.
I'll save you the story of the several hours that followed this. Suffice it to say that I did a lot of research before stumbling on the solution in an obscure message board. So here it is: 422 is returned by the Rails ActionController by default when a POST comes from another website outside your own web application. It's a security feature built in to prevent Cross-Site Request Forgery attacks. That's why my mocked-up emulator form post was working, it was originating from WITHIN my application, thus it had the necessary security key appended to the request, something that could not be done by an external application. So for those of you who are dying to know the solution, here's how you can disable this protection for a single method in a controller:


class CustomerController < ApplicationController

protect_from_forgery :secret => 'any_phrase',
:except => :web_service_method

def web_service_method
#..all your code for handling external post
end

end


the string attached to the "secret" symbol is just a string of your choice that will be used as the SALT for the creation of the security key used by all other controller methods. obviously, the "except" entry takes the name of the method that you wish to exclude from this forgery protection (thus allowing external sites to POST to it successfully. May this post help someone in the future from going through the same experience I had yesterday. ; )