[Python-ideas] Pre-PEP Adding A Secrets Module To The Standard Library

Tim Peters tim.peters at gmail.com
Tue Sep 22 00:08:42 CEST 2015

>>> When would somebody use randbelow(n) rather than randrange(n)?

>> 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 at yahoo.com>]
> Anyone who gets confused by randrange(3) also gets
> confused by range(3),


> 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

> 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.

More information about the Python-ideas mailing list