Page 1 of 1

why are these numbers random and these a repeated sequence?

Posted: Fri Dec 14, 2018 4:34 am
by rhubarbdog
I have 2 programs. I think they are pretty much identical in their calls to `random.randrange()`. The first produces 2 different lines of random numbers as expected. The second produces a repeated sequence of 32 random numbers.

Code: Select all

from microbit import *
import random

def unique(select, total):
    chosen = []
    for _ in range(select):
        while True:
            pick = random.randrange(total)
            if not pick in chosen:
                chosen.append(pick)
                break

    return chosen

one = unique(8, 10)
two = unique(4, 7)

for _ in range(2):
    for i in range(32):
        print('%d' % random.randrange(7), end = " ")
    print('')
produces output

Code: Select all

6 6 5 4 2 1 3 1 3 1 6 0 1 3 4 0 2 2 1 5 1 5 4 6 6 4 6 5 2 4 2 5 
4 2 5 2 4 3 2 5 4 1 5 4 5 0 3 1 0 3 3 2 1 4 0 2 1 2 1 6 1 4 2 1 
where as program

Code: Select all

import microbit
import random
import neopixel

BUTTON = { 'up' : microbit.pin8,
           'down' : microbit.pin14,
           'left' : microbit.pin12,
           'right' : microbit.pin13,
           1 : microbit.pin15,
           2 : microbit.pin16 }

IMAGE_BASE = (microbit.Image.HEART, microbit.Image.HAPPY,
              microbit.Image.SAD, microbit.Image.DIAMOND,
              microbit.Image.SQUARE, microbit.Image.SQUARE_SMALL,
              microbit.Image.MUSIC_CROTCHET, microbit.Image.MUSIC_QUAVERS,
              microbit.Image.UMBRELLA, microbit.Image.ARROW_N)

COLOURS = ((20, 0, 0), (0, 20, 0),      # red green
           (0, 0, 20), (20, 20, 0),     # blue yellow
           (0, 20, 20), (20, 0, 20),    # cyan purple
           (40, 20, 0) )                # orange

zip_led = neopixel.NeoPixel(microbit.pin0, 64)
board = []
cur_x = 4
cur_y = 3

def unique(select, total):
    chosen = []
    for _ in range(select):
        while True:
            pick = random.randrange(total)
            if not pick in chosen:
                chosen.append(pick)
                break

    return chosen

def main():
    global board
    global cur_x
    global cur_y
    
    symbols = unique(8, len(IMAGE_BASE))
    colours = unique(4, len(COLOURS))

    for s in symbols:
        for c in colours:
            board.append([0, s, c])
            
    board += board
        
    for i in range(len(board)):
        item = board[i]
        item[0] = random.randrange(len(COLOURS))
        board[i] = item

    for i in range(len(board)):
        b , s, c = board[i]
        print("%d" % b, end = " ")
        if (i + 1) % 32 == 0:
            print("")
            

main()
produces output

Code: Select all

1 2 1 3 5 5 0 3 3 2 5 0 3 0 0 2 6 4 0 2 2 3 0 5 6 6 5 1 3 5 5 0 
1 2 1 3 5 5 0 3 3 2 5 0 3 0 0 2 6 4 0 2 2 3 0 5 6 6 5 1 3 5 5 0 

Re: why are these numbers random and these a repeated sequence?

Posted: Fri Dec 14, 2018 8:07 am
by pythoncoder
It's because board is a list of lists. When you issue

Code: Select all

board += board
board[0] now points to the same list as board[32].
So if you assign to board[0][0] you will see the same number in board[32][0].

Re: why are these numbers random and these a repeated sequence?

Posted: Fri Dec 14, 2018 8:54 am
by rhubarbdog
Yes i see setting board[32][0] also sets board[0][0].

What's the solution. I want my list to be 32 items twice. I'm making a pairs game
I could

Code: Select all

for _ in range(2):
    for s in symbols:
        for c in colours:
            board.append([0, s, c])
 
But what's the pythonic way to make the `board` in one itteration and double it with + or *

Re: why are these numbers random and these a repeated sequence?

Posted: Sat Dec 15, 2018 9:21 am
by pythoncoder
This is a query about the Python language rather than MicroPython and would perhaps be better directed to another forum. You need to read up on copy.deepcopy: there are many tutorials on the web, this one was the first to yield to DuckDuckGo.

You will probably need to install the copy module from the library.

A shallow copy of a list may be made using this syntax:

Code: Select all

a = [1,2,3]
copy_of_a = a[:]
So, rather than using copy.deepcopy you could explicitly code the copy of the compound list.