[Генератор случайных строк] Застрял в al oop при условии else - PullRequest
0 голосов
/ 12 июля 2020

Итак (как вы, вероятно, увидите из моего кода) я новичок в Python (версия 3.8.3) и до сих пор наслаждаюсь этим, и я испытал себя в нескольких разных проектах для начинающих. В настоящее время я создаю генератор случайных строк (т.е. генератор паролей, отсюда и использование модуля секретов).

# Password Generator
import secrets, string

print("Welcome to the generator. Please specify your requirements")
print("A. All Characters;\nB. No Numbers;\nC. No Punctuation\nPlease choose the appropriate letter for your needs.")
userInput = input()
def userWelcome():

  if userInput.lower() == "a":
      generatePass = string.ascii_letters + string.digits + string.punctuation
      print("How long do you want your string to be?")
      stringRange = int(input())
      print( "".join(secrets.choice(generatePass) for _ in range(stringRange)) )


  elif userInput.lower() == "b":
      generatePass = string.ascii_letters + string.punctuation
      print("How long do you want your string to be?")
      stringRange = int(input())
      print("".join(secrets.choice(generatePass) for _ in range(stringRange)))


  elif userInput.lower() == "c":
      generatePass = string.ascii_letters + string.digits
      print("How long do you want your string to be?")
      stringRange = int(input())
      print("".join(secrets.choice(generatePass) for _ in range(stringRange)))


  else:
      print("Not an option! Let's try again.")
      userWelcome()

userWelcome()

Однако моя проблема в том, что делать, если пользователь вводит неверный параметр . Как вы можете видеть, с оператором else я предполагаю, что то, что они заполнили, не соответствует ни одной из предыдущих опций, и поэтому я хочу снова попытаться перезапустить генератор (поэтому я пытаюсь снова вызвать userWelcome в операторе else).

Однако, когда я ввожу, например, 12 в качестве входных данных, моя оболочка начинает выводить мою строку (не вариант, давайте попробуем еще раз) буквально тысячу раз, как будто она застряла в al oop. Мне интересно, что именно я делаю неправильно.

Что я пробовал:

(1) Итак, я сначала попытался решить эту проблему ввода с помощью попробуйте и за исключением , запустив, за исключением случаев, когда есть ValueError, но это работает только для чисел, и мне не удалось повторно запустить userWelcome ()

(2) Я попытался создать elif оператор , в котором я проверяю ввод целых чисел, однако он также застревает в al oop. Код:

elif userInput.isalpha() == False:
    print("Not an option! Let's try again.")
    userWelcome()

В любом случае, я надеюсь, что это хорошо объясняет. Я был занят этим несколько часов и подумал, что спрошу об этом. Может быть, это очень глупый вопрос, но для меня это сложно :)

TL; DR: Хотите проверить правильность ввода пользователем, снова запустив мою функцию, застряли в странном l oop

Спасибо за ваше время и усилия!

1 Ответ

0 голосов
/ 12 июля 2020

Код вызывает userWelcome() рекурсивно, без изменения глобальной переменной userInput. Та же неправильная строка обрабатывается снова, вызывая тот же результат, который снова вызывает userWelcome() - навсегда (по крайней мере, до максимальной глубины вызова).

Вы должны прочитать новую строку в начале userWelcome вместо использования глобальной переменной. Кроме того, рекурсия здесь является излишним, что сбивает вас с толку. Лучше использовать простое while l oop:

while True:
  userInput = ....
  if ....
     do something
     return
  elif ...
     do something else
     return  # exit the function - breaking out of the loop
  else:
     print(error message)
     # No return here, means the loop will continue to loop
  

Если вы хотите вызвать функцию вместо l oop внутри, вы можете вместо этого сделать так, чтобы функция возвращала успех (True) против неудачи (False ), и l oop что в вызывающем:

while not userWelcome(inputString):
    inputString = read the string

def userWelcome(inputString):
   if inputString == ....:
      something
      return True # To mark OK
   elif inputString == .....:
      something else
      return True # To mark OK
   else:
      print an error
      return False # To mark failure

Просто избегайте глобальных переменных, это плохая практика. Передайте значение через параметры, как в приведенном выше коде.

...