
[Steven]
When would somebody use randbelow(n) rather than randrange(n)?
[Tim]
For the same reason they'd use randbits(n) instead of randrange(1 << n) ;-) That is, familiarity and obviousness. randrange() has a complicated signature, with 1 to 3 arguments, and endlessly surprises newbies who _expect_, e.g., randrange(3) to return 3 at times. That's why randint() was created.
[Andrew Barnert <abarnert@yahoo.com>]
Anyone who gets confused by randrange(3) also gets confused by range(3),
True!
and they have to learn pretty quickly.
And they do. And then, in a rush, they slip up.
Also, randint wasn't created to allow people to put off learning that fact. It was created before randrange, because Adrian Baddeley didn't realize that Python consistently used half-open ranges, and Guido didn't notice. After 1.5 was out and someone complained that choice(range(...)) was inefficient, Guido added randrange. See the commit comment (61464037da53) which says "This addresses the problem that randint() was accidentally defined as taking an inclusive range (how unpythonic)".Also, some guy named Tim Peters convinced Guido that randint(0, 2.5) was surprisingly broken, so if he wasn't going to remove it he should reimplement it as randrange(a, b+1), which would give a clear error message.
Goodness - you seem to believe there's virtue in remembering things in the order they actually happened. Hmm. I'll try that sometime, but I'm dubious ;-)
... I suppose randbelow could be implemented as an alias to randrange(a), or it could copy and paste the same type checks as randrange,
randbelow() is already implemented, in current Pythons, although as a class-private method (Random._randbelow()). It's randrange() that's implemented by calling ._randbelow() now. To expose it on its own, it should grow a check that its argument is an integer > 0 (as a private method, it currently assumes it won't be called with an insane argument).
but honestly, I don't think anyone needs it.
Of the four {randbelow, randint, randrange, randbits}, any can be implemented via any of the other three. You chopped what I considered to be "the real" point:
"randbelow(n)" has a dirt-simple signature, and its name makes it hard to mistakenly believe `n` is a possible return value.
That's what gives it value. Indeed, if minimality crusaders are determined to root out redundancy, randbelow is the only one of the four I'd keep.