Skip to content


Scotchel.com teaser page launched!

37signals is the company behind a number of web-based applications that (intentionally) have fewer features that their competition. “Less is more” would be an apt way to describe them. They wrote a really excellent book called Getting Real that outlines their approach to their products, business, process, marketing, and more. They have a free copy of it online.

I read their book recently and one piece of their advice that really stuck with me is to solicit early. They say that one of the best things you can do for yourself is to start collecting email addresses and get a base of people going that will become your early adopters.

With that thought in mind I created a teaser page for scotchel.com. You should take a look at it and add your email address here.

teaser

Posted in development.

Tagged with .



Where do you place ads?

Sometimes when I’m building something I’ll get the feeling that what I’m doing is wrong. It’s one of those “you have a ‘gut feeling’ but you have no idea why” moments. I felt it quite distinctly when putting together my most recent set of search mockups. I had ads at the top of the search results and it felt wrong. I couldn’t figure out why though. Google has ads at the top of their search results and that works out fine.

After a couple days the answer came to me. I’d read in in the Adsense Blog:

Tip #2: Use ads as potential exit paths, not interruptions.

Ads should complement your site, not distract from it. The most natural place for a user to evaluate an advertisement is after they’ve completed their goals on your site. Instead of interrupting your user’s main tasks, try to offer ads as potential exit path for users who were probably ready to leave anyway by placing them at the end of completed tasks.

Ads work on Google’s search results page because you’re at the end of your task by the time you have your search results. Your goal is to go to a different site. So ads, which by default take you to a different site, are not a distraction.

But in my case the search results aren’t the final destination. The goal is to find someone and contact them (or at the very least take a look at their profile). Thus, the best place for ads would be the “you’ve successfully sent a message” page.

This is a great tip for applying some logic to the placement your ads. If a user has accomplished what they wanted to on your site, show an ad. Otherwise, don’t.

Posted in design.

Tagged with .


Searching for love 2

About a month and a half ago I created mockups for the search results page. The version I ended up using had a filtering panel on the left side, ads on the right side, and rows of search results in the middle. I laid it out and after looking at it for days on end while building out more and more of it I started to wonder if it was really the right approach. The inner Maximizer in me just can’t let things go; I’m constantly trying to go from good to great. Which, let me tell you, is a dangerous habit when you want to launch something (and it drives Rachel absolutely nuts). Thankfully with Balsamiq Mockups I can try out new ideas without investing in any coding time. I use it when I have enough time to be productive but not enough to get into “the zone” and program.

So with my fourth search page mockup I set out to try something a bit different and I came up with panels or “cards” for each person. The same information as before, just rearranged a bit. And I also replaced the stars with “I like them”/”I don’t like them” buttons because that seemed a bit more intuitive (how do you rate person on a 5-point scale?).

Fourth search page mockup

Fourth search page mockup

While I was in the process of drawing up these mockups I ran across a page on Google which shows a heatmap for the best locations to place ads. Ads on the top right side have weak performance and ads on the bottom right side have (apparently) no performance. With that in mind I decided to ax the ads on the right side to free up some space there and instead place ads intermixed with the search results. I’m still not sure that’s the best idea or the best location, but it seems better than wasting a bunch of space on the right side.

Fifth search page mockup

Fifth search page mockup

Further reading about the usage of dating sites led me to realize that the majority of people place a lot of importance on photos (as superficial as that may seem). I thought about various ways to make people’s photos take up the majority of the space rather than a bunch of text, and I think I was successful with this mockup. Something about layout out results in columns and rows freaks me out a little though. And I can’t quite figure out why because reading left to right and row after row is how we read text (in most languages, anyway).

Sixth search page mockup

Sixth search page mockup

Finally I decided to return back to the row layout and see what would change if I added some space on the right by removing ads. I also took out the “profile” and “message” links because a) profile seemed worthless when you could just click on their name/photo and b) message seemed a little premature if you hadn’t looked at their full profile yet. With these few changes I was able to add a lot more space for the description text… and not much else. It is a better layout, just not by much.

Seventh search page mockup

Seventh search page mockup

What did I learn from all of this?

  • Photos are king, and should take up the most space
  • The row based layout isn’t an ideal format for showing profiles
  • I can kill the profile/message links without any (foreseeable) adverse effects
  • The ads on the right side need to go

Some good learning going on there. Not a bad investment of time at all.

Posted in development.

Tagged with , .


Sorting records by distance using PHP & MySQL

I recently got to the point in my project where I was ready to implement sorting for the search results.  I wanted to sort by the distance between two zip codes. However, I quickly realized I had a major problem on my hands. I had a (potentially) large number of search results that I needed to sort. Too many to sort using PHP; I needed a way to sort them in MySQL. But the method I’d planned to use to calculate the distance between zip codes, Micah Carrick’s distance calculation class, was implemented entirely in PHP. I needed some way for the distance to end up in the SQL query so that I could sort on it.

After searching around for a bit I came across this nice bit of code which creates a MySQL query using PHP variables to calculate the distance. By combining the two methods I was able to create a very workable solution for sorting by distance. Here’s what I did:

First, download the zipcode SQL from Micah’s page and run each SQL file. That should give you a new shiny table called zip_code filled to the brim with (what else?) zip codes.

Second, you’ll need the get_zip_point function from Micah’s code:

/**
 * This function pulls just the latitude and longitude from the
 * database for a given zip code.
 */
function get_zip_point($zip)
{
	$sql = "SELECT lat, lon from zip_code WHERE zip_code='$zip'";
	$r = mysql_query($sql);
	if (!$r)
	{
		$this->last_error = mysql_error();
		return FALSE;
	}
	else
	{
		$row = mysql_fetch_array($r);
		mysql_free_result($r);
		return $row;
	}
}

Third, you’ll want a function to generate the SQL you’ll use in your query:

/**
 * Returns the SQL to calculate distance based on latitude and longitude
 */
function get_distance_SQL($lat, $lon)
{
	$sql = "
	3957 * 2 *
	atan2(
		sqrt(
			pow((sin(0.0174*(lat-$lat)/2)),2) +
			cos(0.0174*$lat) * cos(0.0174*lat) *
			pow((sin(0.0174*(lon-$lon)/2)),2)
		)
		,
		sqrt(1-
			(
				pow((sin(0.0174*(lat-$lat)/2)),2) +
				cos(0.0174*$lat) * cos(0.0174*lat) *
				pow((sin(0.0174*(lon-$lon)/2)),2)
			)
		)
	)
	as distance";
 
	return $sql;
}

Fourth, you wrap it all together with a few lines of PHP. I’m using CodeIgniter to handle the SQL call, so your mileage may vary a bit on the exact implementation details.

list($lat, $lon) = $this->get_zip_point($user_zip_code);
 
$this->db->select("users.username, zip_code.city, zip_code.state_prefix," . $this->get_distance_SQL($lat, $lon), FALSE)
		->from('users')
		->join('zip_code',"users.zip_code = zip_code.zip_code")
		->order_by('distance', 'asc');
 
$search_results = $this->db->get();

And shazam, you now have a way to sort a set of SQL results by distance.

Posted in development.

Tagged with , , , .


Merging data can make things easier

Scotchel.com has options for users to select information about themselves (e.g. age, relationship status, etc.) Originally I kept two of those fields, gender and orientation, as separate entities. That was working fine until I wanted to start searching for certain types of people.

Let’s assume there’s a straight girl that wants to find guys that would be interested in her. Obviously her pool of candidates includes straight guys. However, it’s also entirely possible that it would include bisexual guys. After all, they’re interested in girls too.

It gets even more complicated with bisexual folks. If you’re a bisexual guy you may be interested in gay guys, bisexual guys, straight girls, and bisexual girls. If you have gender and orientation as separate fields in your database you’re suddenly searching on 8 different elements:

  • gender = “male” AND orientation = “gay” OR
  • gender = “male” AND orientation = “bisexual” OR
  • gender = “female” AND orientation = “straight” OR
  • gender = “female” AND orientation = “bisexual”

Yikes. I came to realize that the easier way to do this would be to merge gender and orientation into one über field (gender+orientation). In effect this allows you to always halve the number of elements you have to search on.

I created a quick logic table to figure out how I could get it to work:

Straight Guys (1) Gay Guys (3)
Bisexual Guys (5)
Straight Girls (2)
Gay Girls (4)
Bisexual Girls (6)
Straight Guys (1)
xmark xmark xmark checkmark xmark checkmark
Gay Guys (3) xmark checkmark checkmark xmark xmark xmark
Bisexual Guys (5) xmark checkmark checkmark checkmark xmark checkmark
Straight Girls (2) checkmark xmark checkmark xmark xmark xmark
Gay Girls (4) xmark xmark xmark xmark checkmark checkmark
Bisexual Girls (6) checkmark xmark checkmark xmark checkmark checkmark

Searching now becomes a lot more straightforward. If you’re a 1, you’re looking for a 4 or 6. If you’re a 3, you want a 3 or 5. And so on and so forth. Another nice part of this system is that you can get the gender by doing a simple modulus operation. Divide gender+orientation by 2, and if the remainder is 1 you’re a guy and if the remainder is 0 you’re a girl.

That got me to thinking, are there other places where I could be merging data together to save myself a headache? I scoured through my database and there were a couple places where I could merge some booleans together into a single field using a truth table, but I wouldn’t gain anything extraordinary from it. Anyhow, it’s a good tool to keep in the back of my head in case I run into similar situations in the future.

Posted in development.

Tagged with , , .


Slowly but surely

With Rachel’s birthday this past weekend I hadn’t had time to touch the site. Ironic considering I had just been talking about how much time I’d put into the site a couple posts ago… That’s how it goes when you’re working on a project in your spare time though; you work with the time you have. Sometimes you get a lot of time, sometimes you get none.

I’ve made some good progress on the infrastructure behind the search results page. While it doesn’t function much differently, it’s set up for the page to work with a default set of search preferences and allow the user to change them on the fly. So far only the results per page dropdown is hooked into it, but I think I should be able to hook all of the other components up with minimal code (always a plus).

Posted in strategy.


About Me

Recently I decided it would be wise to fill in my “about me” page. The page was looking a little sad considering I’ve been blogging here for a few months. Unfortunately I’m quite terrible at writing about myself. The fact that there was enough content on my plentyoffish profile for Rachel to be interested and message me still amazes me to this day.

Anyway, since I’m not good at writing about myself I tried to think of inventive ways that I could write about myself from a different perspective. And then I remembered reading an article on How to Hack Someone’s Mind. And I thought, hey, why can’t I hack my own mind?

And so I did. I started reviewing all of the bookmarks I’d saved to delicious while making notes on the categories and themes of the articles. I came to recognize that:

  • I’m a frugal entrepreneur trying to create a site in an established market (an underdog)
  • I’m a self-starter planning to develop the site myself (programming and design)
  • I’m planning to market the site using primarily social media

Sounds about right to me. Makes me wish I’d been using delicious back when I was dating — it would’ve made creating profiles roughly 27 times easier.

Posted in personal.

Tagged with , .


Making CodeIgniter’s Pagination library play nice with jQuery

I’m back, and despite the fact that I haven’t posted in a bit I’ve been accomplishing quite a bit on the site …or maybe not. You see, I started keeping track of the hours I’ve been spending working on the site. Over the last 6 days I’ve put in 11 hours on the site. That’s a pretty good amount of time I’ve put in, actually, considering that my goal is to put in at least 8 hours (the equivalent of one work day) a week on the site.

On the (perhaps) not so good side, the majority of that time has been spent implementing pagination on the search results page. You would think this would be incredibly easy considering that CodeIgniter has a Pagination class. It shouldn’t take me approximately 8 hours, right? Well, apparently it does when you’re trying to use AJAX to handle your pagination. I was even perfectly willing to accept a complete hack for a solution, but alas, anything I tried to do to cobble together a fix for one issue only introduced another issue somewhere else.

Eventually jQuery came to my rescue. In the configuration for Pagination I set the base_url to ” (an empty string) so that the href on the pagination links would contain only the number for the search results. Then I set up jQuery to find all of the anchor links in my paging div, stop the normal link function, and call my function to load in the search results. The jQuery code came out like this:

1
2
3
4
5
6
7
8
$(document).ready(function(){
  $("div.paging > a").click(function(e){
    // stop normal link click
    e.preventDefault();
 
    $('div#search_results').load("/search/get_results/"+$(this).attr("href"));
  });
});

This is still something of a hack as I’m basically creating fake href values for the anchor tags, but whatever, it works! I can come back later and fix it. At this point hacks are okay. Speed is much more valuable than perfectly elegant code as I want to find out if my idea is solid before investing oodles of time in it.

Posted in development.


Out ’til next week

I’m headed out of town on vacation, so I won’t be updating my blog until sometime next week. Sadly that means my site won’t be getting any attention until then either. I’m going to be completely unplugging and not bringing my laptop with me.

Posted in personal.