Pages

Wednesday, April 22, 2009

YAML to the Rescue

I needed to create and import product data into an SQL database, but the information I had been given was scattered through various email messages from the client. There was no structure, no CSV file, and no time -- as usual.

It was shaping up to be a real bother to create a CSV file from the information I had and CSV wasn't exactly the friendliest format to look at with poor human eyes.

So I created a YAML file with an entry representing each product. Since the project was mostly written in PHP, I used spyc to parse the file and convert it to SQL insert statements. YAML was much easier to look at than CSV and allowed me to quickly organize the product data without mistakes (such as putting a piece of data in the wrong column).

Writing the parse was easy because each product was already generated as an object, so one could say something like:

foreach ($Yaml as $Product) { print "INSERT INTO product VALUES ('$Product->title', ...); }

I've used YAML for meta data and other applications, but this quick and dirty use saved a lot of time and frustration.

Using Image Magick in a Crunch

So you just got a bunch of images from a client and you need them converted tonight before you can go to sleep. You really don't want to prep each image manually. Whatever shall you do?

Think Image Magick. It's a potent package of image processing goodness with an antiquated name, but I promise you'll get over the name.

This situation happened to me last night. I had a bunch of TIFF files and no time to process them in to Web-ready JPGs. So I created the following shell script:

# Create web versions of product labels and 
# copy them into the appropriate directory.
list=`ls --color=never *.tiff`;
for image in $list
do
    product_id="`echo $image | awk -F "." '{print $1}'`";
    echo "convert $image -resize \"50%\" label.jpg;";
    convert $image -resize "50%" label.jpg;
    mv label.jpg /path/to/products/$product_id/;
done

The convert command is part of the Image Magick package. All of the images were named in the form of product_id.tiff, so that helped. Also, there many other options you could investigate with the convert command, so some experimentation might be required. However, since you've just scripted it, the experimentation becomes very easy.

I observe that even a trivial number of images might be worth scripting in this manner; this script took just a few minutes to write (even looking at the man page for convert). Plus, I knew I would be getting more images later. Plus, plus, I later had to resize the images which was easy using the script.

This Code Goes Up to 11

Some people, when confronted with a problem, think “I know, I'll use regular expressions.”

Now they have two problems.

-- Generally attributed to Jamie Zawinski, an early Netscape engineer.

I was working with HTML strings yesterday, trying to create a teaser from a a block of HTML with predictable structure. My first thought was to use regex and parse the first paragraph and I happily set about doing the work. I mean, I can do regex, that means I'm cool, right? A bit later I realized that there was a much easier way:

$tokens = split('\<\/p\>');
$teaser = strip_tags($tokens[0)];

I've been coding for a while and I am mindful of simplicity in engineering, but this just goes to show that we often use more complicated tools than necessary, just because they are there.

So when you're coding on ten and you need that extra umph, consider turning it down to five instead of up to eleven.

Friday, April 17, 2009

Checking PHP Syntax from VIM

I use vim/gvim for my text editor and I found a handy way to quickly check PHP syntax using a couple of keystrokes from within the editor. Add this to your vimrc file:

" Check php syntax on the current file with CTRL+L
autocmd FileType php noremap <C-L> :!/usr/bin/php -l %<CR>

As an added bonus, you can also use a key mapping to run the execute the PHP file as well, though I find this less useful on a daily basis.

" Run php cli on the current file with CTRL+M
autocmd FileType php noremap <C-M> :w!<CR>:!/usr/bin/php %<CR>

You can change the key used to trigger the command, but you have to be careful not to interfere with pre-existing key combinations.

Shorten Your Ifs

Here’s a PHP example for shortening your conditionals and parameter checking. (There is probably a design pattern for this, but I haven’t found a name for it yet. Submit a comment if you know the name.)

This is a typical PHP example.

/* A useful function.

@param $arg1 First parameter.
@param $arg2 An optional array.

@return Returns a useful string.

*/
public function doSomethingUseful($arg1,$arg2=array())
{
    if (isset($arg2))
    {
        foreach ($arg2 as $v) { /* ... */ }
    }
    else
    {
        return '';
    }
}

Here’s a way to shorten and simplify.

/* A useful function.

@param $arg1 First parameter.
@param $arg2 An optional array.

@return Returns a useful string.

*/
public function doSomethingUseful($arg1,$arg2=NULL)
{
    if (is_array($arg2)) { return ''; }
    foreach ($arg2 as $v)
    {
        /* ... */
    }
}

Friday, April 3, 2009

When MySQL Saved the Day

Although I must grudgingly admit that MySQL has improved over the years, I still think it is a toy database. Rants (both valid and unreasonable) on the vagaries of MySQL abound, so I won't duplicate any of those comments here. Instead, I will relate a recent experience on when MySQL "saved the day".

Once upon a time there was an orders database storing order data and ordered items in MySQL without InnoDb. Someone deleted a really large order and all seemed lost. The order itself could be easily recreated but the list of ordered items was extensive.

But MySQL's lack of referential integrity meant that the ordered items were still present in a separate table. A quick query or two and all of the ordered items were available again.

Message to Elancers

I recently placed a project up for bid on elance.com. As guy involved in sales, marketing, and programming, it's hard for me to give up control of a project. But I needed someone else's time and skill and was willing to trade some money for both.

When the bidding had run its course I selected a winning bidder and since I am involved in the same business as the Elance bidders, and I am not the typical project owner on elance.com, I thought I would send those that didn't win a note on how to do better at sales. I am sharing it here in case it has any useful nuggets on sales and bidding in the world of software and websites.

All,

Thank you for your participation. This project is now closed and I have selected a winning bidder. As you may know, I am a software developer running a family-owned shop. My focus is Web development. I do sales, marketing, and most of the development work. It is important that I do all of these things well if I want to pay my bills and take care of my family.

It is important for you as well, and I wanted to take a moment to offer some unsolicited advice for those of you that did not win the job, so that you might be able to win the next job you bid.

1. I have lots of experience in bidding on sites like elance. The typical employer is unorganized, unprepared, and unaware of the complexity and cost of software development. They are also not qualified to know whether you are a good programmer or not. I am NOT the typical employer. But for most prospects (myself included) it simply boils down to this: Which provider presents the least amount of risk to my business? As both an employer and a contractor, I believe I gave you better and more complete information than you are likely to receive from most employers. Yet

- Many of you submitted a standard "proposal" and had obviously not read any of the information I had provided.

- Some of you said you would follow up after reviewing the information and that was the last contact I saw.

- Some of you bid the maximum bid. Keep in mind that when employers select a budget, it is a range of numbers. Bidding the maximum may put you out of the running immediately.

2. Like most employers, I had a limited amount of time to review your bids. So, I was only interested in those providers that:

- contacted me early,

- had obviously read the information I provided,

- asked meaningful questions,

- offered real advice.

3. Lastly, I view sales as a means of helping people rather than making money. "Sales" for me is matching the right solution for the client. It is the Biblical principal of "doing unto others as you would have them do unto you." Clients feel vulnerable in many ways. Show them that you are trying to help and not just trying to make money. I know that bidding on a site like elance is hectic and hard to manage. It's easy to submit some boiler plate text, some examples of your work, and then move on to the next bid. My advice is the "three B's":

- Be helpful. Ask questions and offer advice.

- Be available. For client questions, advice, etc., but take care not to leave everything up to the client. Following up is important.

- Become a partner. Show that you are interested in mutual benefit and relationship.

Been There Developer Selected

I have selected a winning bidder for the location aware application I'm calling Been There. It was a tough decision as there were lots of good bids and developers. It was also interesting to be the customer for once!