简体   繁体   English

Python 中的 Else 语句无法正常工作

[英]Else statement in Python not working properly

Was wondering if anyone could help me fix the last else statement with the error message.想知道是否有人可以帮助我修复带有错误消息的最后一个 else 语句。 It works if I type in anything else that's not YyNn, however, the error message still does show up if I type in YyNn.如果我输入任何不是 YyNn 的内容,它会起作用,但是,如果我输入 YyNn,错误消息仍然会出现。 I've been at it all night, and I feel like I'm missing the obvious answer - but it's been driving me crazy.我整晚都在研究它,我觉得我错过了明显的答案 - 但它让我发疯了。 Would appreciate an solution for this.将不胜感激对此的解决方案。 Thanks very much.非常感谢。

import random
score = 0

def rollAllDice():
   values=random.randint(1,6), random.randint(1,6), random.randint(1,6), random.randint(1,6), random.randint(1,6)
   print("You rolled 5 dice. The values are:")
   print("Die 1:", values[0]) 
   print("Die 2:", values[1]) 
   print("Die 3:", values[2]) 
   print("Die 4:", values[3]) 
   print("Die 5:", values[4])
   return values
myDice=rollAllDice()

def allSame(myDice):
    result = myDice[0] == myDice[1] and myDice[0] == myDice[2] and myDice[0] == myDice[3] and myDice[0] == myDice[4]
    len(set(myDice)) == 1
    return result

def diceReroll(myDice):
   if allSame(myDice):
      if keepDie1[0] in 'YyNn':
         die1 = random.randint(1,6)
      elif keepDie2[1] in 'YyNn':
         die2 = random.randint(1,6)
      elif keepDie3[2] in 'YyNn':
         die3 = random.randint(1,6)
      elif keepDie4[3] in 'YyNn':
         die4 = random.randint(1,6)
      elif keepDie5[4] in 'YyNn':
         die5 = random.randint(1,6)
   else: # < ---- the else statement I need help on.
      print("I'm sorry. Please only enter Y or N.")

keepDie1=input("\nWould you like to reroll die 1? [Y/N]: ")
keepDie2=input("Would you like to reroll die 2? [Y/N]: ")
keepDie3=input("Would you like to reroll die 3? [Y/N]: ")
keepDie4=input("Would you like to reroll die 4? [Y/N]: ")
keepDie5=input("Would you like to reroll die 5? [Y/N]: ")
diceReroll(myDice)

I took the liberty to make a few assumptions about your code.我冒昧地对您的代码进行了一些假设。 If you think I went too far, let me know in the comments and I will refractor the answer according to your needs.如果你觉得我走得太远,请在评论中告诉我,我会根据你的需要折射答案。

The base issue with the if/else loop is indentation (as already mentioned by others in the comments). if/else 循环的基本问题是缩进(正如其他人在评论中已经提到的)。 But I think the real reason why you have this issue lies with the structure of your code.但我认为您遇到此问题的真正原因在于您的代码结构。 Thus I would suggest you make two changes that would isolate the user input and remove the problematic if/else clause.因此,我建议您进行两项更改,以隔离用户输入并删除有问题的 if/else 子句。

First, you are validating the input in your dice rolling logic, hence having your if/else loop:首先,您正在验证骰子滚动逻辑中的输入,因此具有 if/else 循环:

if allSame(myDice):
      if keepDie1[0] in 'YyNn':
         die1 = random.randint(1,6)
      elif keepDie2[1] in 'YyNn':
         die2 = random.randint(1,6)
      elif keepDie3[2] in 'YyNn':
         die3 = random.randint(1,6)
      elif keepDie4[3] in 'YyNn':
         die4 = random.randint(1,6)
      elif keepDie5[4] in 'YyNn':
         die5 = random.randint(1,6)
   else: # < ---- the else statement I need help on.
      print("I'm sorry. Please only enter Y or N.")

The else part here, as @Selcuk has noted is badly indented, resulting in you getting that error message.正如@Selcuk 所指出的,这里的 else 部分缩进严重,导致您收到该错误消息。 This function already contains your application logic and it should not be dealing with user input validation at all.此函数已经包含您的应用程序逻辑,它根本不应该处理用户输入验证。

I would suggest you rewrite the user input part as a separate function (the change to the user prompt message is called an f-string. You can look it up in case you don't understand it):我建议您将用户输入部分重写为一个单独的函数(对用户提示消息的更改称为 f 字符串。如果您不明白,可以查找它):

def diceRerollPrompt(diceNumber):
    while True:
        prompt = input(f'Would you like to reroll die {diceNumber}? [Y/N]: ').upper()
        if prompt in 'YN':
            return prompt
        else:
            print("I'm sorry. Please only enter Y or N.")

keepDie1=diceRerollPrompt(1)
keepDie2=diceRerollPrompt(2)
keepDie3=diceRerollPrompt(3)
keepDie4=diceRerollPrompt(4)
keepDie5=diceRerollPrompt(5)

This piece of code would repeatedly ask the user to input characters until our user enters yYn or N. It ensures that if the user makes a mistake, the user is immediately telegraphed that his/her input is wrong.这段代码会反复要求用户输入字符,直到我们的用户输入 yYn 或 N。它确保如果用户输入错误,则立即通知用户他/她的输入是错误的。 You also isolate your code from bad input very early on and not need to write heavy validation in the business logic greatly simplifying your allSame() function.您还可以allSame()代码与错误输入隔离,无需在业务逻辑中编写大量验证,从而大大简化了allSame()函数。 Win-win for you and the user.您和用户的双赢。

Afterwards, you can simply delete the problematic if/else loop at all and change your diceReroll function like this:之后,您可以简单地删除有问题的 if/else 循环并像这样更改您的diceReroll函数:

def diceReroll(myDice):
   if allSame(myDice):
      if keepDie is 'Y':
         die1 = random.randint(1,6)
      elif keepDie2 is 'Y':
         die2 = random.randint(1,6)
      elif keepDie3 is 'Y':
         die3 = random.randint(1,6)
      elif keepDie4 is 'Y':
         die4 = random.randint(1,6)
      elif keepDie5 is 'Y':
         die5 = random.randint(1,6)

Note that I took the liberty to change the YyNn to just Y as you would not want to reroll the dice if the user said NO, right?请注意,我冒昧地将YyNn更改为Y因为如果用户说不,您不想重新掷骰子,对吗?

Full solution below完整解决方案如下

import random
score = 0

def rollAllDice():
   values=random.randint(1,6), random.randint(1,6), random.randint(1,6), random.randint(1,6), random.randint(1,6)
   print("You rolled 5 dice. The values are:")
   print("Die 1:", values[0]) 
   print("Die 2:", values[1]) 
   print("Die 3:", values[2]) 
   print("Die 4:", values[3]) 
   print("Die 5:", values[4])
   return values
myDice=rollAllDice()

def allSame(myDice):
    result = myDice[0] == myDice[1] and myDice[0] == myDice[2] and myDice[0] == myDice[3] and myDice[0] == myDice[4]
    len(set(myDice)) == 1
    return result

def diceReroll(myDice):
   if allSame(myDice):
      if keepDie1 is 'Y':
         die1 = random.randint(1,6)
      elif keepDie2 is 'Y':
         die2 = random.randint(1,6)
      elif keepDie3 is 'Y':
         die3 = random.randint(1,6)
      elif keepDie4 is 'Y':
         die4 = random.randint(1,6)
      elif keepDie5 is 'Y':
         die5 = random.randint(1,6)

def diceRerollPrompt(diceNumber):
    while True:
        # if you want to use the simple string concatenation:
        # prompt = input('Would you like to reroll die ' + diceNumber +'? [Y/N]: ').upper()
        prompt = input(f'Would you like to reroll die {diceNumber}? [Y/N]: ').upper()
        if prompt in 'YN':
            return prompt
        else:
            print("I'm sorry. Please only enter Y or N.")

keepDie1=diceRerollPrompt(1)
keepDie2=diceRerollPrompt(2)
keepDie3=diceRerollPrompt(3)
keepDie4=diceRerollPrompt(4)
keepDie5=diceRerollPrompt(5)
diceReroll(myDice)

'''

Excellent response by @Simas. @Simas 的出色回应。

I would just like point out that you will never be able to re-roll anything unless all 5 dice are the same.我只想指出,除非所有 5 个骰子都相同,否则您将永远无法重新掷骰子。 The reason is that in allSame you are using the logical and operator.原因是在allSame您使用的是逻辑and运算符。 By definition, all conditions must be true in order for it to return true.根据定义,所有条件都必须为真,才能返回真。 Therefore, if you get even 1 false, it returns false.因此,即使得到 1 个 false,它也会返回 false。 So in diceReroll , the first if condition is always going to evaluate to false .所以在diceReroll ,第一个if条件总是会评估为false And maybe this is what you want, however you shouldn't be asking if the user wants to re-roll anything if that's the case.也许这就是您想要的,但是如果是这种情况,您不应该询问用户是否想要重新滚动任何内容。 By changing the and s to or s you then get the behavior that the dice re-roll will only work if the first dice is equal to at least one other die.通过将and s 更改为or s,您将得到这样的行为,即只有第一个骰子等于至少一个其他骰子时,骰子重新滚动才会起作用。 (Not sure what the len(set(mydice)) == 1 is for...it seems to be a boolean statement but isn't connected to the previous statement by an and or or ) (不确定len(set(mydice)) == 1是什么...它似乎是一个布尔语句,但没有通过and or or连接到前一个语句)

And with the current if-elif structure, only the first dice to have a 'Y' will be re-rolled because after it evaluates it, it ignores the rest.并且使用当前的if-elif结构,只有第一个具有“Y”的骰子才会被重新掷骰子,因为在评估它之后,它会忽略其余的骰子。 So, this may be better suited as a series of if statements.因此,这可能更适合作为一系列if语句。 Also, all the keepDie x needs to have 0 in the brackets, otherwise you get an index out of bounds.此外,所有keepDie x 都需要在括号中包含 0,否则您会得到一个越界的索引。

def diceReroll(myDice):
    if allSame(myDice):
        if keepDie1[0] is 'Y':
            die1 = random.randint(1, 6)
            print(die1)
        if keepDie2[0] is 'Y':
            die2 = random.randint(1, 6)
            print(die2)
       if keepDie3[0]is 'Y':
            die3 = random.randint(1, 6)
            print(die3)
       if keepDie4[0] is 'Y':
            die4 = random.randint(1, 6)
            print(die4)
       if keepDie5[0] is 'Y':
            die5 = random.randint(1, 6)
            print(die5)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM