Re: [Python-ideas] New function to add into the "random" module

2017-02-02 Thread Paul Moore
On 2 February 2017 at 12:01,  wrote:

> P.P.S.: The function is tested, it’s working 😊
>

First of all, thanks for your suggestion, and for taking the time to help
improve Python. As noted, random.uniform probably does what you want, so we
don't really need this function.

But in case it's of interest to you, there's some additional considerations
around proposed additions to the stdlib that we'd normally look at with a
suggestion like this. If you find any other improvements you'd be
interested in proposing, it might be helpful to you to be aware of them.

The first thing that struck me was the performance of your approach. With
multiple number<->string conversions it is likely to be extremely slow,
making this function completely unsuitable for things like simulations,
where the ability to generate many millions of results fast is critical.
Python stdlib functions typically get used in a wide range of situations,
and we need to make sure they are suitable for as large a range of
applications as we can.

Also, I'd be curious to know how you tested your function. Random number
generators are notoriously difficult to get right, and you are here
combining the results of multiple calls to the underlying PRNG. By doing
so, you might (as far as I know, it's unlikely, but it's possible) have
degraded the randomness of the result. Did your function pass the standard
tests for randomness? Note: I don't know what those tests are, but I do
know that such things exist, and I'd expect anything in the stdlib to have
been validated by people who *do* know such things. Again, stdlib functions
get used in a wide range of applications, and the authors typically rely on
the Python developers to have "got the details right" on their behalf.

Anyway, these are just a couple of thoughts for you. I hope they were of
interest, and thanks again for contributing.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] New function to add into the "random" module

2017-02-02 Thread Franklin? Lee
On Thu, Feb 2, 2017 at 7:01 AM,  wrote:

> from random import *
>
>
>
> def randfloat(x , y , maxfloatpt=None):
>
> if x > y:
>
> x , y = y , x
>
> lenx = len(str(x))
>
> leny = len(str(y))
>
> intx = int(x)
>
> inty = int(y)
>
> bigger = max(lenx,leny)
>
> if maxfloatpt == None:
>
> if bigger == lenx:
>
> intxlen = len(str(intx))
>
> maxfloatpt = len(str(x)[intxlen:])
>
> elif bigger == leny:
>
> intylen = len(str(inty))
>
> maxfloatpt = len(str(y)[intylen:])
>
> else:
>
> pass
>
>else:
>
> pass
>
> num = randint(intx , inty)
>
> num = str(num)
>
> num = '%s.' % num
>
> for i in range(0 , maxfloatpt):
>
> flnum = randint(0 , 9)
>
> str(flnum)
>
> num = '%s%s' % (num , flnum)
>
> return float(num)
>
>
>
> P.S.: If the indent has anything wrong, just correct me, thx!
>
>
>
> P.P.S.: The function is tested, it’s working 😊
>

It looks like this is generating a random float one digit at a time.
Instead, consider the following:

Say you have a function which generates a number between 0 and n. You want
to generate a number between floats x and y, as fairly as you can. So
stretch the range 0...n onto the range x...y, linearly. That means 0 goes
to x, n goes to y, things close to 0 go to things close to x, etc.

If x is 0, then it's simple:

def stretch(num):
return num / n * y

We just need to make x = 0 temporarily, shifting y down as well:

def stretch(num):
return (num / n * (y - x)) + x

Really, we care about the _length_ of the interval [x,y], relative to the
length of [0,n].

Since we want to reach as many numbers as possible in [x,y], we just need n
to be really big. The limit of n depends on how randint is implemented. I'm
not sure whether Python uses extra randoms in the case of long ints, but
let's say that 2^15 is both big enough for us and small enough for Python's
randints to be pretty random.

import random
def randfloat(x, y):
r = random.randint(0, 2**15) #our random int
length = y - x #length of the interval
f = (r / 2**15 * length) + x
return f

(Python 2 will do truncating division up there, so you'd need to make it do
floating point division with a __future__ import or a cast.)

To be responsible, we should probably up the limit to around 2^54 (which is
the limit of precision for the 64-bit floats used by Python), and we'd need
to learn about how random randint can be with large numbers, then generate
larger random numbers using smaller ones.

To be really responsible, we would not assume that floats are 64-bit.

(Fortunately, we don't have to be responsible, because Daniel pointed out
that this function exists in Python's random.)

The idea of linearly mapping one range to another is useful, so please
remember it. In fact, the stretch works even if x is bigger than y.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] New function to add into the "random" module

2017-02-02 Thread Daniel Moisset
Hi Terry, the functionality you have provided is already covered by the
random.uniform function

On 2 February 2017 at 12:01,  wrote:

> Hi, my name is Terry, and I’d like to propose a small function that could
> be added into the Python’s “random” module.
>
>
>
> This function is for generating a random float/decimal number. I would
> like to know if there’s such function that does the same thing, if there
> is, please point out to me. If not, I would like to ask you developers to
> add this function into future Python versions.
>
>
>
> The function code is as follow:
>
>
>
> from random import *
>
>
>
> def randfloat(x , y , maxfloatpt=None):
>
> if x > y:
>
> x , y = y , x
>
> lenx = len(str(x))
>
> leny = len(str(y))
>
> intx = int(x)
>
> inty = int(y)
>
> bigger = max(lenx,leny)
>
> if maxfloatpt == None:
>
> if bigger == lenx:
>
> intxlen = len(str(intx))
>
> maxfloatpt = len(str(x)[intxlen:])
>
> elif bigger == leny:
>
> intylen = len(str(inty))
>
> maxfloatpt = len(str(y)[intylen:])
>
> else:
>
> pass
>
>else:
>
> pass
>
> num = randint(intx , inty)
>
> num = str(num)
>
> num = '%s.' % num
>
> for i in range(0 , maxfloatpt):
>
> flnum = randint(0 , 9)
>
> str(flnum)
>
> num = '%s%s' % (num , flnum)
>
> return float(num)
>
>
>
> P.S.: If the indent has anything wrong, just correct me, thx!
>
>
>
> P.P.S.: The function is tested, it’s working 😊
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Daniel F. Moisset - UK Country Manager
www.machinalis.com
Skype: @dmoisset
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/