Technicasts’ Grand Opening

January 10th, 2010

I’ve been a busy bee.  I’m about to release the 20th FOSSCast on Friday and I’m also starting another screencasting site this week – Technicasts.com.

Technicasts is part me wanting to try and do some longer screencasts about topics that are too big for a 5-10 minute screencast, and part needing to find a way to pay for the increasing cost of  hosting, bandwidth, and all the time I’ve been putting into it.  So, Technicasts are not free – I’m looking at $9 USD per screencast.

The first episode is on the ZFS file system, and I just finished it up today.  It was a blast to put together, so if you have $9 and a mild interest in ZFS, give it a watch – I think you’ll enjoy it.

2009 in review

December 26th, 2009

Again a year has passed, and what an eventful year it has been.

  1. Found out we are having a baby!
  2. Moved to the Chicago burbs.
  3. Took job at Follett Digital Resources
  4. Was moved to Follett Software Company from Follett Digital Resources
  5. Rented our first (whole) house
  6. Bought our first new car (well, almost new)
  7. Started FOSSCasts.com
  8. Turned 26.
  9. loved my wife even more

Looking back, it has been a very eventful year.  Seems that every year is more eventful than the last… although I think 2010 will be the year of “Yerhot Jr.”

Lessons learned from 11 screencasts

November 13th, 2009

I’ve now completed 11 screencasts for FOSSCasts.com, and I must say it has been a great learning experience.  I’d like to share the workflow that I’ve settled on.

Getting Started

First, the equipment:

  • recorded on a Mac using Snapz Pro to record the desktop.  Lots of other Mac screencasters will recommend iShowU, but I already had a Snapz Pro license and it works well enough for me.
  • Shure SM55S Mic
  • Tascom USB Audio interface.
  • Final Cut Pro to edit the video, add transitions, and overdub audio.  The first couple episodes were edited with iMovie.
  • Keynote to create slides.
  • Sun VirtualBox for virtualization
  • Levelator to normalize the audio.  Levelator is a great piece of software.

Now, I actually got some advice from Ryan Bates  of RailsCasts fame as to actually recording the screencasts.  For the Quicktime videos I use the Animation codec.  One thing that Ryan pointed out is that the fewer pixels that change, the smaller the file size.  You many notice I don’t do a lot of moving my mouse and try to not use arrows when scrolling.  Just jumping to a section of a document is much better with the Animation codec.  Scrolling text, fades, or anything with lots of movement will make your file size grow quickly.

Now, the Ogg Theora codec is a different story. It is much closer to H264 than Quicktime Animation.  Generally I get smaller files with Ogg Theora, but they tend to have slightly less accurate color and detail.

For both I usually set the frame rate to 15 frames per second and keyframe every 160 frames with Quicktime animation and 24 frames with Ogg Theora.  I hear that Ryan has set this as high as 600.  Geoffery Grosenbach of PeepCode uses a lower value and has now started using H264 for many of his screencasts.  I may switch, but for the time being, Animation has given me better results, though a slightly higher file size.  I record at 800×600, same as Ryan Bates does for RailsCasts.

I thought about whether to upload the screencasts to something like Vimeo or YouTube, but in the end decided against it.  One thing I want FOSSCasts to be is well produced and high quality.  Once you convert them to Flash, the quality drops considerably, thus I decided against it.

Now, when it comes down to actually putting the screencast together, my workflow is as follows:

  1. Research the topic.
  2. run through what I want to do.
  3. re-run through it while recording the desktop and talking into the mic.  The talking is just so I can roughly gauge myself and get a feel for what I need to say.
  4. watch what I just recorded, keep what works, and re-record what doesn’t.
  5. Load everything into Final Cut.
  6. Go through slicing everything into sections so I can overdub the audio.
  7. Go through, overdubbing audio, extending parts that should be longer, shortening others.
  8. Create the slides in Keynote, exporting them to PNGs.
  9. Import the slide PNGs, putting them into whatever order I need.
  10. Record over them, shortening and extending as necessary.
  11. Finally, add transitions, the ending slide, and recording over the ending.
  12. Create the title slides, export it, and add to Final Cut.
  13. Add the into and outro music clips.
  14. Export only the audio to an AIFF and use Levelator to normalize it.
  15. Import the normalized audio into Final Cut and export the entire movie to Quicktime and Ogg Theora!

Looking back at that list,  it is quite a bit and there is some room for improvement in my workflow.  I can usually get through the whole thing in 3-4 hours if I’m aiming for a 5-6 minute FOSSCast.

The hard part

Initially it was dealing with all the strange things I would say or noises I would make while recording the audio that I didn’t realize I was making.  For example, I would make this clicking noise between sentences.  Go listen the first episode and I’m sure you’ll hear some.  I also tend to do a lot of “umms” and “so’s”.  I’m still working those :)

Of course, you have to get over listening to yourself talk.  I found that after the first two weeks this was no longer an issue.  Learning how to talk into a microphone is also fun and something I’m still perfecting.

Also getting over “putting yourself out there” takes some time.

Thoughts

I might have to write a version 2 of this post in a year and see what changes in my work flow and how I feel about FOSSCasts then.  In the mean time, I’m having a blast.

Drive Failure

October 26th, 2009

I had a hard drive go out on my server at home a lost a couple months worth of posts.  Not fun. Back up your data kids.

Used Car Shopping

July 12th, 2009

We just bought a used 2007 Hyundai Elantra.  It’s a great car, but I completely hate the car buying experience.  Something learned this round.

  1. They (used car salesmen) will try to keep you there as long as possible.  This is to wear you down.  If you’re like me, after a while you’re ready to say yes to anything just to get the hell out of there.  Don’t let them.  
  2. You’re actually the one in control.  They’ll make you feel like you’re not, but you are.  Remember, they’re desperate to sell cars right now.
  3. You don’t need to buy ANY maintenance plans, and extra warranty, or other crap.  Just say no to it all.
  4. Don’t pay for any other extra fees.  The guy we bought ours from tried to tell me that there was a “online” fee since I first saw the car online.  I actually laughed when he tried to tell me that one.
  5. Don’t buy the car on the first visit.  Go in, look at it, take it for a test drive and tell them you’ll think about it.  That’s it. Come back in a couple days and then negotiate a price.  They’ll try to get you to buy it right then and there.  Do not do that – you’ll buy something out of emotion and probably regret it.
  6. Pull your credit score ahead of time if you’re financing.
  7. Speaking of financing, when it comes time to sit down with the financing guy, he’ll give you every reason in the world why they had a hard time getting financing and give you two or three choices. Usually one is the low interest rate that requires you to buy a big extended warranty and the other are higher interest rates.  You can get the lower one with no extended warranty.  Tell him the deal is off unless you get it without the strings attached and begin to get up.  He’ll probably stop you and give you some more reasons he can’t do it, but stick to your guns and you’ll get it. 
  8. Don’t ever be afraid to walk out.  We did at one place.  
  9. Remember, they need to sell cars and you can get a good deal if you’re prepared.  Check out http://edmunds.com and know what you should be paying and don’t go above it. 

Zip Code Distance Searching in Ruby on Rails

June 23rd, 2009

In my last entry we looked at using scopes to dynamically build scopes for searching in your Ruby on Rails application.  In Tryst, we needed to let our uses search for other singles that were xxx miles from their location.  We require that new users enter their zip code, so that is what we had to go off of.

When I was researching the best way to do this, I did a quick Twitter poll – most of my friend thought I should just use Google’s GeoCoding API, which will let you preform these types of searches.  I really didn’t want to go this route for a couple reasons.

  1. It’s an external dependency.  Yes, Google’s uptime is impeccable, but I don’t want to rely on them
  2. Google’s TOS requires that the site/app/service be free.  Tryst may end up with paid features down the road and I didn’t want to have to rewrite a substantial amount of code 1 year from now.
  3. It’s a challenge.

So, we decided to do our own thing.

Our workflow for a search would work like this – we get a distance and a zip code as search parameters, feed both of these into something that returns all the zip codes within the specified distance, and then find all the uses in those zip codes.  Easy enough.

PS. I’m using MySQL here.

First, we need a reference for zip codes.  I found this great free CSV that has all zip codes, major cities, longitude, latitude, area codes, and even metropolitan codes. Import it into your database and remove any rows that were not in the US.  I actually had a ‘Location’ model in my Rails application that I imported this into.

After some digging around the webs, I found some crazy algorithms for generating distance between different locations based on their longitude and latitude.  I’m not going to pretend to understand everything that is happening here, but after some playing around I ended up with this:

SELECT o.zip_code
FROM locations z, locations o, locations a

WHERE z.zip_code = #{zip_code}
AND	z.zip_code = a.zip_code
AND	(3956 * (2 * ASIN(SQRT(
		POWER(SIN(((z.latitude-o.latitude)*0.017453293)/2),2) +
		COS(z.latitude*0.017453293) *
		COS(o.latitude*0.017453293) *
		POWER(SIN(((z.longitude-o.longitude)*0.017453293)/2),2)
	)))) <= #{distance}

I’ll let you guess which part does the calculation. :)
zip_code and distance you’ll need to pipe into the SQL, but you’ll get back all the zip codes with in your specification. We just thew the returned array of zip odes into a scope like this:

# models/users.rb
def search(params)
    scope = User.scoped({})
    ...
    scope = scope.conditions "users.zip_code in (?)", zip_codes unless zip_codes.blank?
    ...
end

Now, this query is fairly slow. By slow, I mean about 25-30ms correctly indexed on my development box. For us it’s just fine.

I hope that helped someone out – I had a hell of a time finding a solution I liked and I really think this is the best one.

Smart Searching Using Anonymous Scopes

June 21st, 2009

I really like how Lovetastic’s search works.  Instead of a plethora of select boxes, users can simply use expressions to create searches.  We did something similar with Tryst’s searching.  One text field and you enter stuff like age ranges (30-45), things like smoke-yes or smoke-no, cities, zipcodes, etc.

Tryst.com Search

To make this whole thing more Rails like, I did not want to just use Regex to parse out search terms and plug them into a complicated SQL query.  That would be soooooo PHP.

Named Scopes are awesome.  You can use them to built decently formatted and fairly complicated SQL queries in a nice, no bullshit, manner. You can do cool stuff like this:

@users = User.active.males.in_zipcode(params[:zip_code]).nonsmokers.top_ten

Just keep stacking scopes on.  Rails generates the query and it usually doesn’t suck.

Go read the API docs for the basics on Named Scopes. We’re gonna do some not basic stuff. Check out Ryan Bate’s Anonymous Scopes Railscast, which introduced me to this method of generating Scopes.

We wanted to add a Class Method called search and have it define the Scopes. We pass in the params hash, anything else we need (like the current user), and let it handle the Scoping and determining what we’re looking for from the search params.

To start, here is our search class method.

# app/models/user.rb
 def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]
end

Yeah, using Will Paginate and assigning my search terms to a local variable. I’ve also written another Class Method that does the parsing of the params.

# app/models/user.r.b
def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]
   #parse params
    max_age, min_age, zip_codes, gender, smoke, drink = self.get_parameters(search_terms.to_s, current_user)
  end

Now, we’re going to define some dynamic scopes. This is awesome. For it to work, we’ll add an initializer.

#config/initializers/scopes.rb

class ActiveRecord::Base
  named_scope :conditions, lambda { |*args| {:conditions => args} }
end

Now, lets make the scopes.

def self.search(params, current_user)
    page = params[:page] || 1
    search_terms = params[:search]

    max_age, min_age, zip_codes, gender, smoke, drink = self.get_parameters(search_terms.to_s, current_user)

    scope = User.scoped({})
    scope = scope.conditions "users.age >= ? and users.age <= ?", min_age, max_age unless min_age.blank?
    scope = scope.conditions "users.zip_code in (?)", zip_codes unless zip_codes.blank?
    scope = scope.conditions "users.smoker = ?", smoke unless smoke.blank?
    scope = scope.conditions "users.drink = ?", drink unless drink.blank?
    scope = scope.conditions "users.gender = ?", gender unless gender.blank?
    scope.paginate :page => page, :order => "created_at DESC"
  end

Pretty slick, huh? So now, in my controller I just need

# app/controllers/search.rb
def users
    @users = User.search(params, current_user)
end

Assuming your class method for parsing out scope parameters doesn’t suck, you should have very clean, cuddly, and concise searching. No more worrying about breaking some huge crappy SQL query.

You’ll notice I used

users.zip_codes in (?)

This is because I can pass an array of zipcodes and return all the users in those zipcodes. This is because I’ve implemented radial distance searching base on zipcodes. Users can search like ” 60606 25miles” and return all users who are within 25 miles of 60606. We’ll go into how this works in the next post.

Yes, I started a dating site. I’m sorry.

June 14th, 2009

Ok, so five years ago I never would have though that I’d have started a ‘Web 2.0′ dating site.  Hell, I didn’t think I’d be doing a lot of things, but here I am.   There is actually a small story how I got involved with (shamless self promotion) trystme.com.  Wanna hear it?  Good.

Originally, I wanted to become an elementary school teacher and was halfway though getting my elementary eduction BA… until I started to volunteer at a school library.  I hated it.  Plus I realised I had too many tattoos to be a school teacher… never should have been in all those punk bands growing up.

So there went that idea – I quit school and took a year off.

I decided to go for something that is completely different and the opposite of little crazy kids – computer science.  I had always like computers, had some experience with Dreamweaver and the idea of not having my work talk back to me all the time sounded great.  I went back to school and loved CS.

About 3 years ago I graduated and I got a contract job with a small local development shop in Duluth, MN.  After a few months it went under and the guy screwed me out of a pay check or two, but I did walk away with something really cool – I was exposed to Ruby on Rails.  I freakin loved it.  LOVED IT.  I quit wasting my time with PHP and drank the Ruby juice.  I even wrote an article for a Rails magazine.

Eventually I got a job working programming for this educational coop in Norther Minnesota.  It was pretty slick.  I enjoyed the work, had tons of freedom, and actually got paid (unlike the contract gig).  Worked there for a little over a year… until… I got an iPhone January 2nd of 2009.

I had a couple week lapse in my old phone contact, so my old phone was still on but it would get left at home.  One day it rang and my wife answered it.  It was some lady from Chicago who said she worked for some company that was trying to find Rails developers and somewhere they found my resume or something crazy like that.  She even said that she had called before and left messages and that I never called back.  This is true – I rarley call back if I don’t know the caller.  Thanks telemarketers.

So, Jen tells me I should call this lady, Andrea The HR Lady From Chicago.  Jen and I had been talking about moving from Norther MN for sometime now and almost took a job in Milwaukee (thank God we didn’t).  The more I talked to Andrea The HR Lady From Chicago the more it sounded good.

So I got this job, moved to the Chicago Burbs, and met a guy at work named Mike.  Mike had lots of crazy ideas and had this one to start a dating site.  The original idea was to only spend two weeks developing it and whatever we had at the end of two weeks was it.  This sounded great at first, but since two weeks really meant about 40 hours between the two of us (since we’re doing this at night after our real jobs) it got stretched to about a month and a half.

There you have it.  We didn’t exactly build it to make tons of money. That’d be nice – we have ads on it, but really we just wanna see what happens.  I guess we want what every programmer with an entrepenurial spirit wants – to wake up one morning and find that your one lowely server is dying under the load and we have to split into an app server and a database server.  Then add Memcached, another app server, shard the database, another app server, hire a real DBA, and on and on.

Check it out – we launched it today, 14/6/2009 at 7:30pm, and are super proud of it.  If you’re looking for a date sign up and give it a try.  Let us know what you think and have fun.

I’ve pulled a Brett Farve

May 22nd, 2009

That’s right.  I’m pulling this blog from retirement.  It’s still getting quite a bit of traffic and I feel bad for just neglecting it.  Keep checking back for some real content.

blog.john.yerhot.org

November 19th, 2008

I will be moving this weblog to blog.john.yerhot.org in the next couple days.  I will also be moving from Wordpress to my own home brew platform.  johnyerhot.com will still go here, and so will all the posts, but I will not be posting here any longer.

blog.john.yerhot.org