Ovoid
Ovoid

Reputation: 33

Bingo card generating duplicate numbers

I created a simple Bingo card generator that generates 4 numbers between n and n+15. However, I noticed that numbers are sometimes generated twice despite an if statement I wrote that was supposed to find duplicates and rerun the random generation for that cell. My code is below:

import random

ballCount = 75  # Max value of cell
gridWidth = 4
gridHeight = 5
numPerCard = 20  # Numbers generated per card
minimum = 1
maximum = 15


def generate_number(stored, small_num, big_num):
    random.seed(a=None, version=2)
    random_number = str(random.randint(small_num, big_num))
    if "| "+random_number+" |" in stored:
        generate_number(stored, small_num, big_num)
    return random_number


for row in range(gridHeight):
    string = ""
    for Number in range(gridWidth):
        number = generate_number(string, minimum, maximum)
        string += " | " + number
    string += " |"
    print(string)
    maximum += 15
    minimum += 15

And here is an example of output with duplicates (23 appears 2 times):

 | 2 | 5 | 9 | 12 |
 | 25 | 23 | 19 | 23 |
 | 37 | 42 | 30 | 37 |
 | 60 | 49 | 50 | 55 |
 | 73 | 71 | 69 | 67 |

Upvotes: 3

Views: 477

Answers (4)

fwoosh
fwoosh

Reputation: 184

There are two problems I can see here. The first problem is, when your program retries the random number generation, it doesn't do anything with the result. You should add a return before generate_number(stored, small_num, big_num), making it return generate_number(stored, small_num, big_num). Secondly, you should remove the " |" in the "| "+random_number+" |". It can be possible that the repetition is at the last cell you generated, and therefore does not have a " |" after it. Hope this answers your question.

Upvotes: 1

Rodrigo Eggea
Rodrigo Eggea

Reputation: 124

Problems found in your code:

1) Your 'stored' variable in generate_number is missing the vertical bar "|" in the end, so number doesn't match.

2) The return of your recursive function must be assigned to "random_number".

Follow the corrected code:

import random

ballCount = 75  # Max value of cell
gridWidth = 4
gridHeight = 5
numPerCard = 20  # Numbers generated per card
cards = 6  # Number of cards
minimum = 1
maximum = 15

def generate_number(stored, small_num, big_num):
    random.seed(a=None, version=2)    
    random_number = str(random.randint(small_num, big_num))
    if "| " + random_number + " |" in stored +" |":
        random_number = generate_number(stored, small_num, big_num)
    return random_number

for row in range(gridHeight):
    string = ""
    for Number in range(gridWidth):
        number = generate_number(string, minimum, maximum)
        string += " | " + number
    string += " |"
    print(string)
    maximum += 15
    minimum += 15

Hope this helps

Upvotes: 1

Samwise
Samwise

Reputation: 71512

    if "| "+random_number+" |" in stored:
        generate_number(stored, small_num, big_num)
    return random_number

If you already have the number, you call generate_number again, but you still return the original number (the duplicate).

You may be interested in random.sample as an alternative way of getting a random selection of unique numbers within a range. E.g.:

>>> [random.sample(range(n, n+15), 4) for n in range(15, 75, 15)]
[[20, 26, 15, 23], [37, 44, 32, 40], [48, 45, 47, 50], [63, 62, 68, 71]]

or, with pretty-printing:

>>> for row in [random.sample(range(n, n+15), 4) for n in range(15, 75, 15)]:
...     print(f"| {' | '.join(map(str, row))} |")
...
| 17 | 15 | 27 | 22 |
| 34 | 33 | 42 | 36 |
| 54 | 51 | 55 | 48 |
| 68 | 73 | 61 | 72 |

Upvotes: 2

Pete
Pete

Reputation: 569

Inside the if statement you need to return the result from generate_number. Right now it will do the if statement and then discard that result and then return the original number.

Upvotes: 1

Related Questions