# BrianHicks/cowboy

It works on ranges.
Python
Fetching latest commitâ€¦
Cannot retrieve the latest commit at this time.
 Failed to load latest commit information. cowboy test .gitignore .travis.yml README.md requirements.txt setup.py

# COWBOY

It works on ranges.

## Installation

`pip install cowboy`

### Installing for development

``````git clone https://github.com/BrianHicks/cowboy.git
pip install -r requirements.txt
python setup.py develop
nosetests
``````

## How to do stuff with Cowboy

Construct a range:

```import datetime
from cowboy import DateRange

first_quarter = DateRange(
start=datetime(2012, 1, 1),
end=datetime(2012, 3, 31)
)```

See if an arbitrary value is within the range, matching on start and end. `O(2)`:

`datetime(2012, 2, 1) in first_quarter # True`

Step through all the values in the range. Generator returns `O(2n+1)` where `n` is the delta of the start and end:

```from cowboy import NumberRange

one_through_ten = NumberRange(1, 10)

one_through_ten.steps(granularity=1) # Generator yielding [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]```

### Working with multiple ranges

You can add two ranges in the obvious manner (takes the lesser of the starts and the greater of the ends):

```fst, snd = NumberRange(1, 2), NumberRange(3, 4)

fst + snd # <NumberRange: 1 to 4>```

In real life, that's not always how you want to combine sets. Take for example, a circus, where we want to quickly see if the circus is showing any particular day:

```from cowboy import MultiRange

circus_schedule = MultiRange(
DateRange(datetime(2012, 1, 1), datetime(2012, 1, 3)),
DateRange(datetime(2012, 1, 8), datetime(2012, 1, 10))
)
datetime(2012, 1, 2) in circus_schedule # True
datetime(2012, 1, 9) in circus_schedule # True```

You can also get the intersection of two ranges. This works a little bit like `set.intersection` but might raise a `InvalidRangeError` if the start is greater than the end. Essentially, this tries to create a new Range with the greater of the starts and the lesser of the ends:

```fst, snd = NumberRange(1, 3), NumberRange(2, 4)
fst.intersection(snd) # <NumberRange: 2 to 3>```

Say you wanted to make your own Range for chars, so that `CharRange('a', 'c')` made sense. That class would look something like this:

```from cowboy.base import Range

class CharRange(Range):
'a range of characters'
def steps(self, granularity=1): # most subclasses will override just granularity
current = ord(self.start)
while current <= ord(self.end):
yield chr(current)
current += granularity```

Now you can use all the methods outlined above to operate on ranges of characters.