0

I am using python 2.7. I wrote a code to generate passwords. For doing this, I used the random module to generate how many characters of different types(uppercase, lowercase, special and numbers) to be used to generate a password of a given length. When a wrote a function for this, it was supposed to return a tuple, but it returns None. Why is it happening?

I tried the casual debugging method of putting print statements in between and figuring out where it went wrong. Everything works just fine, except it returns None.

def passlen(a):
    """Gives length of different characters to be put into passwords"""
    uplen=random.randrange(0, a)
    lwlen=random.randrange(0, a)
    speclen=random.randrange(0, a)
    nmbrlen=random.randrange(0, a)
    if uplen+lwlen+speclen+nmbrlen==a:
        print (uplen, lwlen, speclen, nmbrlen)
        return(uplen, lwlen, speclen, nmbrlen)
    else:
        passlen(a)

x=input("how many characters in the password?")

print(passlen(x))

Expected results are 4-tuples, but it gives None instead.

HansHirse
  • 18,010
  • 10
  • 38
  • 67
Phnx Drm
  • 1
  • 2
  • where is Your `return` statement? o_0 – Kamiccolo Apr 25 '19 at 10:07
  • right above the `else` statement – Phnx Drm Apr 25 '19 at 10:09
  • So... most of the time it's not being executed, wherefore the function returns `None`. – Kamiccolo Apr 25 '19 at 10:10
  • But isn't a function only supposed to return at the end of a `return` statement? And it returns `None` if no `return` statement is found. – Phnx Drm Apr 25 '19 at 10:15
  • So, most of the time Your function does not reach the end statement. Only if the sum is equal to `a`. You have None when the function exits without explicit return statement. It's sounds better then just guessing what did You actually wanted to return. – Kamiccolo Apr 25 '19 at 10:19
  • My apologies. I do not understand what you are saying. I am using recursion here . And as I see in most recursive functions, the results work just fine. – Phnx Drm Apr 25 '19 at 10:22

2 Answers2

1

So you want four random numbers that add to a? Of course you can try choosing four random numbers until you find a set that adds up to a, but that might take a while for large values of a (and you definitely don't want to do this recursively).

Much better to choose three split points between 0 and a:

def passlen(a):
    splits = sorted([random.randrange(0,a) for _ in range(3)])
    uplen = splits[0]
    lwlen = splits[1] - uplen
    speclen = splits[2] - uplen - lwlen
    nmbrlen = a - uplen - lwlen - speclen
    return uplen, lwlen, speclen, nmbrlen
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
0

Thanks to Kamiccolo for trying to help out.

The function should look like this:

def passlen(a):
    """Gives length of different characters to be put into passwords"""
    uplen=int(random.randrange(0, a))
    lwlen=int(random.randrange(0, a))
    speclen=int(random.randrange(0, a))
    nmbrlen=int(random.randrange(0, a))
    bab=(uplen, lwlen, speclen, nmbrlen)
    if uplen+lwlen+speclen+nmbrlen==a:
        return bab
    else:
        return passlen(a)

A duplicate thread also helped me in this.

Phnx Drm
  • 1
  • 2
  • 1
    This is problematic. You can expect a StackOverflowError with this code for large enough values of `a` because instead of simply looping until you get a suitable result, you keep calling the same function recursively. And you don't actually need a loop at all. – Tim Pietzcker Apr 29 '19 at 06:35