Question: I'm 2 hours into my reading of *diveintopython* and I implemented a naive version of quicksort. 

```
import operator

def even(num):
    return operator.mod(num,2) == 0

def last(list):
    return len(list)-1

def median(list):
    if even(len(list)):
        return len(list)/2 - 1
    else:
        return len(list)/2

def sort(list, pivot_selector):
    if len(list) <= 1:
        return list
    else:
        i = pivot_selector(list)
        pivot = list[i]
        less, greater, equal = [], [], []
        for x in list:
            if x < pivot:
                less.append( x )
            elif x == pivot:
                equal.append( x )
            else:
                greater.append( x )

    return sort(less, pivot_selector) + equal + sort(greater, pivot_selector)

if __name__ == "__main__":
    print sort([5,4,3,2],median)
    print sort([],median)
    print sort([2],median)
    print sort([3,2],median)
    print sort([3,2,3],median)
    print sort([1,3,2],median)
    print sort([1,'a',0],median)
    print sort([None,1,0],median)

```

5 questions:

1. This code resides in a file called quicksort.py. How does one hide the method *even* from being exported to the public.
2. Is it pythonic to pass in a \*pivot\_selector\* as a parameter ?
3. Anything wrong or suboptimal with my quicksort implementation ?
4. How would you allow the user to specify a comparator that will enforce a custom ordering on the list elements ?
5. Is there a pythonic way to enforce a constraint that the list parameter must contain homogeneous types ?

Answer: 
Some semi-random notes on your code:

* Why the explicit `operator.mod` in `even` and not just `%` ?
* Is `len(list)/2 - 1` really important in `median`? If you have a list of length 4, why is index 2 any less a median than index 1? Also, `middle` would be a more suitable name, because the function doesn't really compute a *median*. Finding the real median in a list for quicksort is quite a complex issue and is usually approximated.
* Passing a selector as a function is quite Pythonic. You can use the same method to pass a comparison function and use it in `sort`.
* Your question (5) smells non-Pythonic - don't do that. Python is all about duck typing - if your user thinks he wants to compare integers to `class UserID` and provides the appropriate methods/operators, let him.
> 
> 2: Yes. But using a default value could be better.
> 
> 
> 5: isinstance. But not a good choice. To make sure they
> all have necessary interface is just fine, you don't
> have to monitor their types.
> 
> 
>