0

I made a simple program in Python to generate a random string with 5 numbers in it:

import random

numcount = 5
fstring = ""

for num in range(19): #strings are 19 characters long
    if random.randint(0, 1) == 1:
        x = random.randint(1, 26)
        x += 96
        fstring += (chr(x).upper())
    elif not numcount == 0:
        x = random.randint(0, 9)
        fstring += str(x)
        numcount -= 1

print(fstring)

Not too hard, right? Except for one incredibly strange thing: the strings it returns are of a random length. I have run the code several times, and here are some of my results:

>>> ================================ RESTART ================================
>>> 
VQZ99HA5DER0CES4
>>> ================================ RESTART ================================
>>> 
05PS0T86LOZS
>>> ================================ RESTART ================================
>>> 
E2QX8296XK
>>> ================================ RESTART ================================
>>> 
M5X9K457QDNBPX

I can't figure out what's going on... Can anyone point me in the right direction?

2
  • 1
    Without doing any deep-level analysis, you can see that sometimes both ifs will fail (leading to a shorter fstring) and sometimes, randomly, they won't. Commented Jun 19, 2014 at 22:02
  • Sometimes, very rarely, they won't. On average you'd get 9.5 iterations in the numeric branch, and only 5 will do anything. Pretty unlikely you'd only get 5 or fewer iterations. Commented Jun 19, 2014 at 22:05

2 Answers 2

8

You flip a coin 19 times; 50 percent of the time you pick a letter, the other 50 percent you pick a digit, but only up to 5 times. If you hit the number option more often, you do not add anything.

So you build a string up to 19 characters, but it can be shorter. On average it'll be 9.5 letters, and 5 digits.

Only pick numbers if you still have numbers to pick:

import string
import random

numcount = 5
chars = []

for num in range(19): #strings are 19 characters long
    if numcount and random.random() < 0.5:
        chars.append(str(random.randint(0, 9)))
        numcount -= 1
    else:
        chars.append(random.choice(string.ascii_uppercase))

fchars = ''.join(chars)

Demo:

>>> import string
>>> import random
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> numcount = 5
>>> chars = []
>>> for num in range(19): #strings are 19 characters long
...     if numcount and random.random() < 0.5:
...         chars.append(str(random.randint(0, 9)))
...         numcount -= 1
...     else:
...         chars.append(random.choice(string.ascii_uppercase))
... 
>>> ''.join(chars)
'3M6G97OEHP6TGYRONPV'
>>> len(chars)
19
Sign up to request clarification or add additional context in comments.

Comments

0
import random

numcount = 5
fstring = ""


while numcount > 0:
    if random.randint(0, 1) == 1:
        x = random.randint(1, 26)
        x += 96
        fstring += (chr(x).upper())
    elif not numcount == 0:
        x = random.randint(0, 9)
        fstring += str(x)
    numcount -= 1

print(fstring)

2 Comments

This can generate strings as short as 5 characters, i dont think he wants that
This produces only 5 characters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.