Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [SUMMARY] Price ranges (#164)

Thread Tools

[SUMMARY] Price ranges (#164)

Matthew Moss
Posts: n/a
In this quiz, James presented us with a practical problem that is
quite common in everyday life. Sometimes we make such decisions
implicitly and "fuzzily", when we shop at a particular store since
another shop "is too expensive." Other times it is a more explicit
search, such as when filtering online listings for products, rentals,
or other services.

The quiz boils down to determining which providers' price ranges
overlap that of the consumer's desired range. To test whether range A
and B overlap requires that at least one of the following hold:

* At least one endpoint (i.e. low or high price) of range A falls
within range B.
* At least one endpoint of range B falls within range A.

A pretty simple task with a good amount of repetitive behavior, which
suggests that these behaviors should be consolidated.

We'll take a look at _Chris Shea_'s solution: it's simple, well-
documented and easy code to read in use. Chris defines a new class,
`PriceRange`, rather than use the built-in `Range` class. This seems
appropriate, as the class is not intended to be reused in the same
manner as `Range`. Let's first look at the initializer:

def initialize(opts={})
@low = opts[:low] || 0
@high = opts[:high] || 1.0 / 0.0

The use of a hash as the initialization parameter allows Chris to make
use of `PriceRange` like this:

customer = => 2_500, :high => 5_000)

And in fact, one or both of `:low` and `:high` could be left out to
create open-ended or empty ranges. Even reordering them is fine, as
they are no longer parameters but rather a single hash.

The initializer remembers the low and high values, providing defaults
if necessary: zero for the low end of the range, and `1.0 / 0.0` --
that is, Infinity, with a capital *I*. Infinity is a constant of class
Float that is greater than all other numbers. So it serves as a valid,
and quite convenient, high value for an open-ended range.

To check for basic overlap, Chris defines these methods:

def includes_price?(price)
price >= @low and price <= @high

def includes_edge_of?(other)
includes_price?(other.low) or includes_price?(other.high)

Very straightforward. As mentioned above, determining if two ranges
overlap involves two parts, where `includes_edge_of?` satisfies one of
those parts (here, *a* and *b* are `PriceRange` instances):


To perform the whole overlap check, then, is simply a matter of also
doing the reverse check, and using the logical-or operator to combine:

a.includes_edge_of?(b) or b.includes_edge_of?(a)

And that is exactly what we see in the last method of the `PriceRange`
class, `select`, but checking over all provided `PriceRange`

def select(*ranges) { |range|
self.includes_edge_of?(range) or range.includes_edge_of?

I like the simplicity of the code as well as the readability (as shown
by example in the code's comments). My only possible complaint is a
preference to use a named constant for infinity in the code, though it
would seem that inserting `(1.0 / 0.0)` is the easiest way to get such

Reply With Quote

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
[QUIZ] Price Ranges (#164) Matthew Moss Ruby 14 06-07-2008 06:43 PM
Online price vs retail store price? Squiggle NZ Computing 74 12-07-2007 03:44 AM
computer spares price list | newly added Canada country price list| Nandhu Python 0 12-04-2007 02:56 PM
US price v Uk price /\\BratMan/\\ Digital Photography 19 11-23-2007 05:18 AM
Vista Ultimate: NZ price vs US Price whome NZ Computing 61 02-03-2007 12:11 PM