I'm trying to generate a random number in a range - MicroPython

I’m trying to generate a random number in a range (between 4 and 96), I’ve used import urandom at the beginning of my code and tried the code listed below - it’s not working, this seems to be the usual syntax for most Python and MicroPython versions I’ve used before.

ix = urandom.randint(4, 96)



Here is the answer. So the parameter is the number of bits. getrandbits(8) would give a random value between 0-255.

I needed a range, this seems to work:

# (screen <4-96> or 92 pixels, 5 bits = rnd # 0 to 31, * 3 = 93, -1 = 92 + 4 for left edge (or + 3))
            ix = (urandom.getrandbits(5) * 3) + 3 
1 Like

Here is an implementation of randint(start, stop) I wrote based on the code in Javitto Random:

def randint(start, stop):
    bound = stop - start
    mask = bound
    mask |= mask >> 16
    mask |= mask >> 8
    mask |= mask >> 4
    mask |= mask >> 2
    mask |= mask >> 1
    ret = urandom.getrandbits(30) & mask
    while ret > bound:
        ret = urandom.getrandbits(30) & mask
    return start + ret

Thanks! this looks interesting, I’ll have to see if I can implement it into my code.

Too complicated, normally you if you have a random integer N you get it to range <A,B> as A + N mod (B - A + 1). I.e. a + urandom.getrandbits(32) % (b - a + 1).

1 Like

I don’t know about the mask business, but the while ret > bound part likely gets rid of modulo bias.

Not that it’s necessarily an issue, depending on the use case.

1 Like

Yep, it doesn’t have modulo bias, but I’m guessing it doesn’t matter in this case. So better use the version drummyfish posted.

Just change getrandbits(32) to getrandbits(30). Otherwise it gives following error: OverflowError: small int overflow.

The mask business reduces the amount of retries in the while loop without incurring modulo bias.