Archive for the '/dev/random' Category

TextMate, ImageMagick and “Command not found”

Two days ago I did a clean install of Snow Leopard, TextMate and all the associated goodies. All was going well until I tried running my spec’s that referenced Rmagick from within TextMate. They started returning the following error:

sh: convert: command not found

This was fixed by opening TextMate’s preferences, Advanced -> Shell Variables and adding a new variable:

Variable: PATH
Value: see below.

For the curious, my $PATH is currently:

/usr/local/bin:/usr/local/sbin:/usr/bin:/opt/local/bin:/usr/local/mysql/bin:/opt/local/sbin:/bin:/usr/sbin:/sbin:/usr/X11/bin

No Comments »

chris on September 2nd 2009 in /dev/random

Merb, merb_datamapper gem, and “was no found”

I just killed a bunch of time tracking down the cause of this issue that was occurring while trying to run a merb app:

FATAL: The gem merb_datamapper (>= 0, runtime), [] was not found

This message is in fact incorrect. Merb can find the gem just fine, as running with –verbose indicates, it just can’t load it.

After much mucking about it turns out the problem was the Addressable gem being updated to v2.1. Removing addressable-2.1.0 fixed everything.

(If you run into similar issues and think this might help, please note the date on this post. Version numbers may have changed significantly since this writing.)

No Comments »

chris on June 19th 2009 in /dev/random

How To Make Fake Mars Dust

It amuses me to no end that not only has NASA figured out how to create fake Mars dust (aka: dust on Earth that has the same consistency and texture as the stuff on Mars), but that they actually have a legitimate need to do so:

But now Spirit faces a new and tricky challenge—its wheels have partly sunk into a patch of soft soil. The rover’s controllers have put a halt to driving operations while they try to figure out how to get it unstuck.

“Spirit is in a very difficult situation,” John Callas, project manager for the rovers at the NASA Jet Propulsion Laboratory (JPL) in Pasadena, Calif., said in a statement yesterday. “We are proceeding methodically and cautiously. It may be weeks before we try moving Spirit again.” A JPL spokesperson said today that the rover’s condition had not changed.

Incidentally, the recipe via MarsRovers:

Recipe for rover sandbox testing (to duplicate Spirit’s sandtrap): 1part Diatomaceous Earth + 1part Fire Clay (used for pottery)

No Comments »

chris on June 15th 2009 in /dev/random

Better Range Intersection in Ruby

A little while ago I posted a solution for finding intersections between timespans (“Detecting DateTime Timespan Overlap In Ruby”). It works but, as Dan Kubb pointed out to me, it doesn’t use the most graceful means of determining intersections between Range instances, particularly for very large ranges.

Not content to leave it at that, Dan of course provides a better solution, complete with tests:

#!/usr/bin/env ruby

class Range
  def intersection(other)
    raise ArgumentError, 'value must be a Range' unless other.kind_of?(Range)

    min, max = first, exclude_end? ? max : last
    other_min, other_max = other.first, other.exclude_end? ? other.max : other.last

    new_min = self === other_min ? other_min : other === min ? min : nil
    new_max = self === other_max ? other_max : other === max ? max : nil

    new_min && new_max ? new_min..new_max : nil
  end

  alias_method :&, :intersection
end

if __FILE__ == $0
  range = 5..10

  tests = {
    1..4   => nil,     # before
    11..15 => nil,     # after
    1..6   => 5..6,    # overlap_begin
    9..15  => 9..10,   # overlap_end
    1..5   => 5..5,    # overlap_begin_edge
    10..15 => 10..10,  # overlap_end_edge
    5..10  => 5..10,   # overlap_all
    6..9   => 6..9,    # overlap_inner

    1...5  => nil,     # before       (exclusive range)
    1...7  => 5..6,    # overlap_begin      (exclusive range)
    1...6  => 5..5,    # overlap_begin_edge (exclusive range)
    5...11 => 5..10,   # overlap_all  (exclusive range)
    6...10 => 6..9,    # overlap_inner      (exclusive range)
  }

  tests.each do |other, expected|
    result = range.intersection(other)
    result_status = ( result == expected ) ? "passed" : "failed"
    puts "#{range.inspect} #{other.inspect} result #{result_status}: #{result.inspect} (#{expected.inspect})"
  end
end

I like it.

No Comments »

chris on June 6th 2009 in /dev/random

Amazon S3 Buckets and “Access Denied”

DreamBank uses Amazon S3 as it’s data and media storage backup. Recently I enabled logging on our S3 buckets and was immediately refused access to any of the content contained within; nothing but “403 Access Denied” errors. Bit of a problem, that.

Thanks to some sound guidance from the folks at Cloudberry Lab (who make CloudBerry S3 Explorer – that’s my plug for their freeware Windows S3 app since they were so helpful) I now have full access to our buckets again.

The solution: turns out the permissions on the buckets were munged* when I enabled logging, giving access to no one. Resetting the access to “owner/owner” did the trick. This was accomplished by connecting to S3 through Transmit and tweaking the perms like any other file directory.

(*that’s as close to a technical description as I can get. I have no idea what really went wrong.)

No Comments »

chris on June 6th 2009 in /dev/random

Merb, Safari and “Cannot decode raw data”

Today I was attempting to get Merb to output a comma-delimited file of data dumped from the database. In config/init.rb I’d added:

Merb.add_mime_type( :csv, :to_csv, %w[application/csv], "Content-Encoding" => "gzip")

but I kept getting this error from Safari: cannot decode raw data.

Turns out the gzip encoding was mucking up the data. Using this line instead produced the desired outcome:

Merb.add_mime_type( :csv, :to_csv, %w[application/csv] )

No Comments »

chris on April 30th 2009 in /dev/random

Detecting DateTime timespan overlap in Ruby

The Scenario
Let’s say you have an instance of DateTime that represents a starting time, and you have a duration that, when added to the starting time, represents an ending time.

Let’s say you have two such things and you want to know if they overlap (or intersect, or collide). For instance:

  1. March 29, 2009 @ 10:00am; 120 minutes
  2. March 29, 2009 @ 11:00am; 90 minutes

In this example there’s one hour of overlap in which #1 stretches from 10:00am – 12:00pm and #2 stretches from 11:00am – 12:30pm.

How to detect this? I’m sure there’s many clever ways, this way is mine.

We’re Gonna Need More Monkeys
First, we need to monkey-patch some core classes. Monkey-patching is fun, it makes us feel 31337.

As an aside: it’s patently absurd that DateTime doesn’t have a built-in function for converting to a Time instance (which is layered atop the patently absurd need for Ruby to have three unique Date/Time classes… but that’s another rant)….

Anyhow, let’s monkey-patch DateTime so it can return itself as an instance of Time:

class DateTime
  def to_time
    return Time.mktime( year, month, day, hour, min, sec )
  end
end

Now we need to alter Range to detect intersections with other ranges the way Array does with its & operator. We do this with Bill Siggelkow’s clever intersection() method:

class Range
  def intersection(range)
    res = self.to_a & range.to_a
    res.empty? ? nil : (res.first..res.last)
  end
  alias_method :&, :intersection
end

Ta-da; monkey-patching complete.

DateTime is the VB.Net of Date/Time Classes
You’ve likely inferred from the code above that we won’t be using DateTime for this jaunty action, but rather instances of Time. You’d be correct. DateTime is remarkably unsuited for this sort of thing. But since DateTime is so popular and prevalent that’s where we’ll start.

Our first moment of comparison will start right now to 60 minutes in the future:

a = DateTime.now
a_start = a.to_time
a_end = a_start + ( 60 * 60 )

Our second moment in time will start 30 minutes from now to 120 minutes in the future:

b = DateTime.now
b_start = b.to_time
b_start = b_start + ( 30 * 60 )
b_end = b_start + ( 120 * 60 )

Free-range Comparison
Now that we have our times, let’s convert them into ranges:

# Turn these into ranges
a_range = (a_start.to_i..a_end.to_i)
b_range = (b_start.to_i..b_end.to_i)

and compare them:

puts "Result A-B: #{a_range.intersection( b_range )}"

As of this writing the output is:

Result A-B: 1238340860..1238342660

which indicates an overlap/intersection/collision between the two timespans, displayed as seconds. Had there been no collision, nil would have been returned instead.

2 Comments »

chris on March 29th 2009 in /dev/random

Where’d the Comments Go?

After much consideration I’ve decided to close comments on all posts on this blog. I do this for a number of reasons:

  1. Once again dealing with the comment spam has become far too annoying. Akismet has been great but enough spam was slipping through that it had become a chore to manage each morning. Under different circumstances I might continue to put up with it but…
  2. The nature of this blog is such that for the most part the posts don’t generate comments-based discussion. I use it place primarily as a storage device for things I think might be useful later and often, via Google, other people find these posts and find them useful as well. Thus, most of the comments are of the “thank you” nature, which is immensely gratifying and I thoroughly enjoy them but massaging my own ego is not a good enough reason to wade through the spam each morning!
  3. And on the few posts that do warrant discussion or criticism I’m very much on board with reading your responses on your blogs (and thus I’ve left open trackback and pingback). It seems that people do tend to write more thoughtfully when writing from their own pulpit so if you’re so inclined then link back to me and let’s run discussions that way. It’ll be fun!

All that said, whether or not you’ve ever left a comment, thanks for reading!

Comments Off

chris on March 2nd 2009 in /dev/random

Pagination in Merb

Pagination is one of those things that almost every site needs and for which there is absolutely no glory. Boring stuff, pagination, the Edmonton of software development. Which might explain why, when I needed to figure out how to paginate in Merb a little while ago, it was so difficult to find clear instructions on how to do so. When you find yourself in pagination you do what you have to do and then move on, with nary a glance back (apologies to both my readers in Edmonton, but you know I’m right.)

Oh sure, lots of posts on the web say “use Lori Holden’s dm-is-paginated with merb-pagination” but none say quite exactly how. And while I’m fully willing to concede I may be a little thick sometimes I found the examples on her pages somewhat under-enlightening. Hints of light bulbs but no switches, as it were.

So, embarking under the assumption that both dm-is-paginated and merb-pagination are installed on your system, here’s how I got pagination working with Merb. In this example I’ll use my DbAdminLog class as an example.

First, make sure you have the dependencies declared in dependencies.rb. At the time of this writing, these were:

dependency "merb-pagination", "0.0.1"
dependency "dm-is-paginated", "0.0.1"

In the DbAdminLog model, I added this line underneath my property definitions and validations:

is_paginated

This provides the pagination methods to the model necessary elsewhere. If you don’t add this line, no pagination for you, which is funny because it isn’t mentioned anywhere on the example pages linked above ( “…on public display in the local planning department for months, locked in a filing cabinet in the darkened cellar behind a sign that says, ‘Beware of the Leopard’”.)

In the DbAdminLogs controller I added the following to the index() method:

def index
  @current_page = ( params[:page] && ( params[:page].to_i > 0 ) ) ? params[:page].to_i : 1
  @page_count, @db_admin_logs = DbAdminLog.paginated( :o rder => [ :created_at.desc ], :conditions => cond, :page => @current_page, :per_page => 20 )
  display @db_admin_logs
end

The first line figures out which page of results we’re displaying, based on the GET parameter supplied (or not supplied, in the case of the default “1″.) The second line is the pagination magic in which I define the order to be displayed (they’re log files, so LIFO), any filtering conditions via the cond variable (if you want every record unfiltered you can leave :conditions out or replace cond with ["1"]), the page number and the number of entries to be displayed per page.

(For extra credit, swap out the && with andand and be 1337.)

That’s the controller.

The view is pleasantly straightforward. In index.html.haml I added the following at the bottom below the display code:

= paginate( @current_page, @page_count, :inner_window => 5 )

And there you have it: merb pagination.

Comments Off

chris on February 27th 2009 in /dev/random

Brutal But Honest: A Developer’s Code?

I wish I knew the original source for this quote. Anyone?

Duplicate code is the root of all evil in software design. When a system is littered with many snippets of indentical, or nearly identical code, it is indicative of sloppiness, carelessness, and sheer unprofessionalism. It is the guilt-edged responsibility of all software developers to root out and eliminate duplication whenever they find it.

From An Accidental Doppelgänger in Ruby.

Comments Off

chris on February 20th 2009 in /dev/random