Conditions and If-Statement

Question:

I created a small script for generating password in python:

# LIBRARY IMPORTS
from datetime import datetime
import random

# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
lowerCase = "abcdefghijklmnopqrstuvwxyz"
upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
symbols = "!?%&@#+*/()=<>-_"
passwordConstructor = lowerCase + upperCase + numbers + symbols
minPasswordLength: int = 8
maxPasswordLength: int = 20


# FUNCTIONS
def getUsername():
    global userName
    userName = str(input("Enter Username:"))


def getPasswordLength():
    global passwordLength
    passwordLength = input("Enter the length of password: ")


def generatePassword():
    global password
    password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
    print("1." + password)
    password = ''.join(random.sample(password,len(password)))
    print("2." + password)
    password = ''.join(random.sample(password, len(password)))
    print("3." + password)


def generateTextFile():
    if userName != "":
        f = open(userName.upper() + " - " + dateFormat + ".txt", "w+")
        f.write("USERNAME: " + userName + "nPASSWORD: " + password + "nnGENERATED ON: " + dateFormat)
    else:
        f = open("Password generated on " + dateFormat + ".txt", "w+")
        f.write("PASSWORD: " + password + "nnGENERATED ON: " + dateFormat)
    f.close()


def printPassword():
    generatePassword()
    print(password)


if getPasswordLength() == '':
        print("Please enter a value. This cannot be empty.")
else:
    if not getPasswordLength().isdigit():
        print("Length of password must be a number.")
    else:
        if getPasswordLength() > maxPasswordLength:
            print('Length of password is limited to ' + maxPasswordLength)
        elif getPasswordLength() < minPasswordLength:
            print('Length of password must be grater than ' + minPasswordLength)
        else:
            generatePassword()

But condition doesn’t work and end up in an error. What I am doing wrong?

Conditions for User Input which should be covered:

  1. Cannot be empty.
  2. Must be number.
  3. Greater than minPasswordLength (8).
  4. Smaller than maxPasswordLength (20).
Asked By: Stephan Koenig

||

Answers:

When you add the max and min password length to the string at the end you must declare them to be a string. It should look like this:

print('Length of password is limited to ' + str(maxPasswordLength))

That’s the only immediate issue that I can see, however from my experience I know that it has to be done every time an integer or numeric value is added to a string so you will have to amend any other instances where this happens.

Hope this works 🙂

Answered By: gingerninja412

There are a couple issues here in your code, as others have mentioned, including issues of comparisons between different types, namely comparing the input provided by the user and the min and max password lengths.

You also do not have a loop to re-prompt the user to enter a password length again if it does not satisfy the constraints, which I am not sure was your intended aim. I have adapted your existing code below and enclosed the modified logic in a while loop so that the user will continue to be prompted to enter a password length that satisfies the constraints.

# LIBRARY IMPORTS
from datetime import datetime
import random

# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
lowerCase = "abcdefghijklmnopqrstuvwxyz"
upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
symbols = "!?%&@#+*/()=<>-_"
passwordConstructor = lowerCase + upperCase + numbers + symbols
minPasswordLength: int = 8
maxPasswordLength: int = 20


# FUNCTIONS
def getUsername():
    global userName
    userName = str(input("Enter Username:"))


def getPasswordLength():
    global passwordLength
    passwordLength = input("Enter the length of password: ")


def generatePassword():
    global password
    password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
    print("1." + password)
    password = ''.join(random.sample(password,len(password)))
    print("2." + password)
    password = ''.join(random.sample(password, len(password)))
    print("3." + password)


def generateTextFile():
    if userName != "":
        f = open(userName.upper() + " - " + dateFormat + ".txt", "w+")
        f.write("USERNAME: " + userName + "nPASSWORD: " + password + "nnGENERATED ON: " + dateFormat)
    else:
        f = open("Password generated on " + dateFormat + ".txt", "w+")
        f.write("PASSWORD: " + password + "nnGENERATED ON: " + dateFormat)
    f.close()


def printPassword():
    generatePassword()
    print(password)

while True:

    getPasswordLength()

    if passwordLength == "":
        print("Please enter a value. This cannot be empty.")
        continue

    try:
        passwordLength = int(passwordLength)
    
    except ValueError:
        print("Length of password must be an integer.")
        continue

    if passwordLength > maxPasswordLength:
        print(f"Length of password is limited to {maxPasswordLength}")
        
    elif passwordLength < minPasswordLength:
        print(f'Length of password must be grater than {minPasswordLength}')
        
    else:
        generatePassword()
        break

As mentioned by other users, global variables should be avoided if possible, and for your code the same result can be achieved in perhaps a more "pythonic" way without using global variables. I have not changed it in my answer but could be something to think about.

Answered By: H_Boofer

I switched from global variable to return and ended up with:

# Simple password generator created by akatsuki

# LIBRARY IMPORTS
from datetime import datetime
import random

# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
lowerCase = "abcdefghijklmnopqrstuvwxyz"
upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
symbols = "!?%&@#+*/()=<>-_"
passwordConstructor = lowerCase + upperCase + numbers + symbols
minPasswordLength: int = 8
maxPasswordLength: int = 20


# FUNCTIONS
def getUsername():
    userName = str(input("Enter Username:"))
    return userName


def getPasswordLength():
    passwordLength: str = input("Enter the length of password: ")
    return passwordLength


def generatePassword():
    password = "".join([random.choice(passwordConstructor) for i in range(getPasswordLength())])
    print("1." + password)
    password = ''.join(random.sample(password,len(password)))
    print("2." + password)
    password = ''.join(random.sample(password, len(password)))
    print("3." + password)
    return password


def generateTextFile():
    if getUsername() != "":
        f = open(getUsername().upper() + " - " + dateFormat + ".txt", "w+")
        f.write("USERNAME: " + getUsername() + "nPASSWORD: " + generatePassword() + "nnGENERATED ON: " + dateFormat)
    else:
        f = open("Password generated on " + dateFormat + ".txt", "w+")
        f.write("PASSWORD: " + generatePassword() + "nnGENERATED ON: " + dateFormat)
    f.close()


def printPassword():
    generatePassword()
    print(generatePassword())


while True:
    getUsername()
    getPasswordLength()

    if getPasswordLength() == "":
        print("Please enter a value. This cannot be empty.")
        continue

    try:
        getPasswordLength() = int(getPasswordLength())

    except ValueError:
        print("Length of password must be an integer.")
        continue

    if getPasswordLength() > maxPasswordLength:
        print(f"Length of password is limited to {maxPasswordLength}")

    elif getPasswordLength() < minPasswordLength:
        print(f'Length of password must be grater than {minPasswordLength}')

    else:
        generatePassword()
        generateTextFile()
        break

But in line:

    try:
        getPasswordLength() = int(getPasswordLength())

I got following error:
"Cannot assign to function call"

How this can be solved?

Answered By: Stephan Koenig