【问题标题】:How can I tell the difference between a user-input blank string and one I created?如何区分用户输入的空白​​字符串和我创建的空白字符串?
【发布时间】:2012-02-29 05:12:07
【问题描述】:

任务是让用户输入密码,然后使用递归确保密码中没有元音。如果是,则让用户重新输入密码。这是我到目前为止所拥有的:

def passwordCheck(pwd):
    """checks if pwd has any vowels in it."""#doc string
    vowels = 'aeiou'#specifies the characters that aren't allowed
    if pwd == '':
        return 0
    elif pwd == None:
        return None#Shouldn't be necessary but just in case
    elif pwd[0] not in vowels:#checks that the 1st(0th) character is not a vowel
        return passwordCheck(pwd[1:])#gets rid of the 1st(0th) character and starts again
    elif pwd[0] in vowels:#checks if the 1st(0th) character is a vowel
        return 1#if it is, stops the function calls and returns a value

password = str(input('Please enter a password with no vowels in it: '))#asks user to input their new password
x = passwordCheck(password)#checks the password is valid, i.e. no vowels

while x == 1:#when the password entered contains a vowel
    print('\nSorry, that is not a valid password.\nYour password cannot contain any vowels.')#tells the user why their password is invalid
    password = str(input('\nPlease enter a different password: '))#gives the user a chance to re-enter their password
    x = passwordCheck(password)#checks to make sure the new password is valid

print('\nCongratulations, you have entered a valid password!')#tells the user if their desired password is valid
print('\nYou are now able to log on to the system with these credentials.')#could've been included on the previous line but looks neater here

我知道这可能不是最 Pythonic 的方式,但在大多数情况下它对我有用。我很想听听更好的方法,但理想情况下有人可以以同样的方式提供帮助。我不想只是复制别人的代码而不理解它。

我的问题是处理用户根本不输入密码的情况。第一个 if 语句:

if pwd == '':
    return 0

我认为它只是处理字符串完全递归的情况,即没有元音,但经过几分钟的检查,很明显这也适用于没有密码。 我也尝试过使用:

if pwd == None:
    return something

现在我在想问题可能是因为我说:

password = str(input('######'))

但我也对此进行了修改,但似乎仍然无法让它发挥作用!我试过谷歌和搜索stackoverflow,但没有运气,所以如果有人有任何他们认为可能有帮助的想法/解决方案,我会非常感激听到他们的声音。非常感谢。

我的主要问题是:

我如何区分一个空字符串,因为它已经被递归了,而用户什么也没输入?

已解决。

最终使用

def passwordValid(pwd):
if len(pwd)>0 and passwordCheck(pwd)==0:
    return pwd
else: return 'Fail'

password = str(input('Please enter a password with no vowels in it: '))#asks user to input their new password
y = passwordValid(password)#checks the password is valid, i.e. no vowels

while y == 'Fail':#when the password entered contains a vowel
    print('\nSorry, that is not a valid password.\nYour password cannot contain any vowels or be empty.')#tells the user why their password is invalid
    password = str(input('\nPlease enter a different password: '))#gives the user a chance to re-enter their password
    y = passwordValid(password)#checks to make sure the new password is valid


print('\nCongratulations, you have entered a valid password!')#tells the user if their desired password is valid
print('\nYou are now able to log on to the system with these credentials.')#could've been included on the previous line but looks neater here

感谢 Wayne Werner 修正了标题和主要问题。

【问题讨论】:

  • 这是一个可怕的递归作业问题。 (不是你的错,我知道;只是评论。)
  • 但是,有趣的是,我最初使用/学习递归的方式(尽管它是实际验证,并不能确保它没有元音)。它使在以后的生活中使用递归变得更加容易。
  • @cheeken 明确为check_password(pwd)可以定义为return not any(~pwd.find(vowel) for vowel in 'aeiou')
  • @cheeken:在函数式语言中,您当然可以为此使用递归。恕我直言,虽然 Python 并不真正支持尾递归,但 Python 的功能“足够”使其相当现实,你当然应该在这里使用像 any 这样的帮助器。
  • @NiklasB。许多学生在递归和理解何时以及为什么需要递归方面存在困难。像这样的问题,很容易用循环解决,我觉得只会进一步混淆他们的理解。

标签: python recursion python-3.x


【解决方案1】:

不要试图用一种方法解决这两个问题。你有两个不同的标准:没有元音;最小长度。

def isPasswordValid(pwd):
    return len(pwd) > 4 and not passwordCheck(password)

x = isPasswordValid(password)

...

可以通过添加另一个参数来解决这个问题,该参数指示循环了多少个字符,但这很笨拙并且没有真正的好处。

【讨论】:

    【解决方案2】:

    这个问题可以分解为(至少)三个不同的子问题:

    • 检查字符串是否包含元音
    • 检查字符串是否为有效密码(长度> X 有元音)
    • 从用户那里获取密码

    您的代码应该反映这种结构。因此,您可以使用以下函数布局:

    def has_vowels(string):
      if not string:  # check for empty string
        return False  # empty strings never have vowels
      # TODO we have a non-empty string at this point and can use recursion
    
    def is_valid_password(string):
      return len(string) > 0 and not has_vowels(string)
    
    def request_password():
      while True:   # use an endless loop here, we don't won't to repeat
                    # the "input" statement. We could also change this to
                    # something like `for i in range(3)` to allow only a limited
                    # number of tries.
        passwd = input('Please enter a password with no vowels in it: ')
        # TODO check if input is valid, if yes, return, if no, print an error
    

    【讨论】:

    • 哇......也许不要发布完整的代码作为家庭作业问题的答案。
    • @dusktreader:是的,你是对的。我剥了一点,也许没人注意到:)
    • 我做了一点点不同,但它主要基于你和@cheeken 的答案。不过,我不太明白 has_vowels() 的第一行。非常感谢您的帮助,对不起,我无法为您的答案投票,因为我没有声誉。
    • @RLoftus:很高兴我能帮上忙。空字符串在 if 语句中的计算结果为 False,因此这与 if len(string) == 0 相同。
    • 现在更有意义了,看起来也更干净了。非常感谢大家的帮助。
    【解决方案3】:

    您无法区分空字符串和空字符串。但是,您可以将变量设置为 None,或设置为“__no_string_entered_yet”之类的字符串。也就是说,我不明白您为什么需要,请参阅其他答案。

    【讨论】:

      【解决方案4】:

      我相信这可以满足您的问题:

      • 不允许空密码(不同于“空白”密码?)
      • 密码中不允许使用元音

      我选择不使用 if/elif/else 来支持它的结构,以便有效字符“通过”

      def pwd_check(s):
          vowels = 'aeiou'
          if len(s) == 0: return False     # This is only valid in the first iteration
          if s[0] in vowels: return False
          if len(s) == 1: return True      # Success: a 1 character pwd with no vowels
          return pwd_check(s[1:])
      

      我考虑过检查以确保没有传入像 ' ' 这样的字符串,但我没有看到明确要求。 pwd_check(password.strip()) 解决了这个问题。

      【讨论】:

        【解决方案5】:

        这就是我喜欢做的事情。
        为了好玩,我添加了密码的最小和最大长度条件:

        def passwordCheck(pwd,vowels = 'aeiou',minimum=5,maximum=12):
            if pwd == '':
                return 0,None,None
            elif pwd[0] in vowels:
                return -1,None,None
            else:
                y = passwordCheck(pwd[1:])[0]
                if y==-1:
                    return -1,None,None
                else:
                    return y + 1,minimum,maximum
        
        
        
        mess = 'Please enter a password with no vowels in it: '
        while True:
            x,miin,maax = passwordCheckstr(input(mess))
        
            if x==-1:
                mess = ('\nSorry, that is not a valid password.\n'
                        'Your password cannot contain any vowels.\n'
                        'Please enter a different password: ')
        
            elif x==0:
                mess = ('\nSorry, you must enter a password.\n'
                        'Please do enter a password: ')
        
            elif x<miin:
                mess = ('\nSorry, the password must have at least %d characters.\n'
                        'The string you entered has %d characters.\n'
                        'Please, enter a new longer password: ' % (miin,x))
        
            elif x>maax:
                mess = ('\nSorry, the password must have at most %d characters.\n'
                        'The string you entered has %d characters.\n'
                        'Please, enter a new shorter password: ' % (maax,x))
        
            else:
                print ('\nCongratulations, you have entered a valid password!\n'
                       '\nYou are now able to log on to the system with these '
                         'credentials.') 
                break
        

        编辑

        另一种算法。
        我不满意返回 -1,None,None 这样的元组

        def check_password(forbidden,minimum,maximum):
        
            def passwordCheck(pwd,cnt=0,forbid = forbidden,
                              miin=minimum,maax = maximum):
                # cnt is the number of preceding turns of recursion
                # that have been already executed.
                if pwd == '':
                    if cnt==0:
                        # cnt==0 means that it's the first turn of recursion
                        # since pwd is '', it means no entry has been done
                        return 0
                    elif cnt<miin:
                        return -3
                    elif cnt>maax:
                        return -2
                elif pwd[0] in forbid:
                    return -1
                else:
                    if cnt in (-3,-2,-1):
                        return cnt
                    else:
                        return passwordCheck( pwd[1:] , cnt+1 )
        
        
            mess = 'Please enter a password with no vowels in it: '
            while True:
                x = str(raw_input(mess)).strip()
                y = passwordCheck(x)
        
                if y==0:    # inexistent string
                    mess = ('\nSorry, you must enter a password.\n'
                            'Please do enter a password: ')
        
                elif y==-1: # string contains a vowel
                    mess = ('\nSorry, that is not a valid password.\n'
                            'Your password cannot contain any vowels.\n'
                            'Please enter a different password: ')
        
                elif y==-2: # string too long
                    mess = ('\nSorry, the password must have at most %d characters.\n'
                            'The string you entered has %d characters.\n'
                            'Please, enter a new shorter password: ' % (maximum,len(x)))
        
                elif y==-3: # string too short
                    mess = ('\nSorry, the password must have at least %d characters.\n'
                            'The string you entered has %d characters.\n'
                            'Please, enter a new longer password: ' % (minimum,len(x)))
        
                else:       # success
                    print ('\nCongratulations, you have entered a valid password!\n'
                           'You are now able to log on to the system with these credentials.')
                    break
        
        # EXECUTION
        check_password('aeiou',5,12)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-08
          • 2023-03-12
          • 2015-01-23
          相关资源
          最近更新 更多