简体   繁体   English

嵌套的 while 循环未按预期工作

[英]Nested while loops not working as expected

Created a simple maths calc:创建了一个简单的数学计算:

After user does their first calc they are asked 3 questions.在用户进行第一次计算后,他们会被问到 3 个问题。

  1. Do more math with the final answer.用最终答案做更多的数学运算。
  2. Restart fresh重新开始
  3. Quit completely.彻底戒掉。

Used nest while loops to achieve this.使用嵌套 while 循环来实现这一点。

Picture below shows下图显示

  1. Success at doing a calc.计算成功。
  2. User was then asked if they wanted to do more with the final answer.然后询问用户他们是否想对最终答案做更多的事情。 Answer was 'n'.答案是'n'。
  3. They were then asked if they wanted to start fresh or quit completely.然后他们被问到是想重新开始还是完全退出。 Answer was quit: 'n'.答案是退出:'n'。
  4. So program ended successfully.所以程序成功结束。

Successful end to code代码成功结束

However on retest然而在重新测试

  1. Calc successful.计算成功。
  2. Do want to continue with final answer = no.确实要继续最终答案=否。
  3. Do you want to start fresh?你想重新开始吗? = yes. = 是的。
  4. Program restarts.程序重新启动。 Great!伟大的!
  5. Calc successful.计算成功。
  6. Do want to continue with final answer = no.确实要继续最终答案=否。
  7. Do you want to start fresh?你想重新开始吗? = no. = 没有。
  8. At this point the program should end (as it did above) BUT it continued as if the user in step 2 above had said 'yes'.此时程序应该结束(如上面所做的那样)但它会继续,就好像用户在上面的步骤 2 中说“是”一样。

Keeps looping and it shouldn't保持循环,它不应该

Cannot work out why.无法弄清楚为什么。 Tried using breakpoints to see what is happening but still too inexperienced on how to correctly used this tool.尝试使用断点查看发生了什么,但对于如何正确使用此工具仍然缺乏经验。 Used Thonny as well.也用过Thonny。 Thonny shows that it acknowledges the 'break' command (so it should slip out of the while loop) however it then skips ahead to the next coded line and the calc continues. Thonny 表明它确认了“break”命令(因此它应该滑出 while 循环)但是它然后跳到下一个编码行并继续计算。

enter code here
    more_calc = user_continue_check(data=math_question)

    if more_calc == 3:
        break

    elif more_calc == 2:
        main()

    print("Error checking: When do we get to here?")
    start_calc += 1

Is the problem in the nested while loops below?问题出在下面的嵌套 while 循环中吗? Just don't know.只是不知道。 Been hacking away at this for hours.已经为此苦苦挣扎了好几个小时。 Using Thonny this nested loop works fine.使用 Thonny 这个嵌套循环可以正常工作。 It breaks out correctly returning the correct variable int result.它正确返回正确的变量 int 结果。 So confused.如此迷茫。

enter code here
     def user_continue_check(data):

         user_answer = False
         ans = True

         while not user_answer:

             more_calc = str(input("\n\tDo you want to do more math with the calculated result of "
                          + fg.orange + "{0}".format(data['result']) + fg.rs + "?" + fg.blue + " y/n: "
                          + fg.rs)).strip().lower()

             if more_calc == "n":
                final_check = True

                while final_check:

                   final_user_check = str(input("You you want to start a new calculation: y/n: ")).strip().lower()

                   if final_user_check == "n":
                        ans = 3
                        break
                   elif not final_user_check == "y":
                        print(fg.red + "\t\tYou need to enter y or n" + fg.rs)
                   else:
                        ans = 2
                        break
               break
    
             elif not more_calc == "y":
                print(fg.red + "\t\tYou need to enter y or n" + fg.rs)
             else:
                ans = 1
                break


         return ans

Below is a link to the whole script.下面是整个脚本的链接。 I just don't know where to look for the answer.我只是不知道在哪里寻找答案。 Cannot work out why it does work then doesn't.无法弄清楚为什么它起作用然后不起作用。

enter link description here 在此处输入链接描述

The reason is because your break does indeed break all three loops, but you are using recursive calls on your main, so you are getting back to a lower recursive call of your main.原因是你的 break 确实打破了所有三个循环,但是你在 main 上使用递归调用,所以你又回到了 main 的较低递归调用。

So to explain:所以解释一下:

main => enter loop => enter main => enter loop => enter loop => enter loop => exit all three last loops => exit main main => 进入循环 => 进入 main => 进入循环 => 进入循环 => 进入循环 => 退出所有最后三个循环 =>退出 main

You are still in the first loop in the first main, which called the second main which you just terminated.您仍处于第一个主循环的第一个循环中,该循环调用了您刚刚终止的第二个主循环。

When a function calls itself using recursion, it is not terminated, once the inner call is finished, the function continues its execution right after the call.当函数使用递归调用自身时,它不会终止,一旦内部调用完成,函数会在调用后立即继续执行。

But generally, I would work a little bit on improving the quality of the code first, you might find it easier to debug in the future, here are some suggestions:但一般来说,我会先努力提高代码的质量,你以后可能会发现它更容易调试,这里有一些建议:

  • Use explicit, non ambiguous names (no "ans" "fg" "final_check/final_user_check")使用明确、明确的名称(没有“ans”“fg”“final_check/final_user_check”)
  • don't use break if it can be avoided (and it can here in most cases)如果可以避免就不要使用 break (并且在大多数情况下都可以)
  • don't repeat code不要重复代码
  • don't reassign different types to your variable (ex: ans starts as True, but then becomes a number)不要为您的变量重新分配不同的类型(例如:ans 以 True 开头,但随后变为数字)
  • don't use recursion, it is almost never worth it.不要使用递归,它几乎不值得。 <= in this case this will fix the issue <= 在这种情况下,这将解决问题

That will be a decent start.这将是一个不错的开始。

Your code does something extremely simple yet it's hard to understand and that is a bad sign.你的代码做了一些非常简单但很难理解的事情,这是一个不好的迹象。 It's great that you are trying to incorporate all these concepts into it, but you need to keep your code tidy in order to be able to continue working on it, and understand the problems with it很高兴您尝试将所有这些概念融入其中,但您需要保持代码整洁,以便能够继续处理它并了解它的问题

@jeekiii has explained the problem, that you recurse into main in if more_calc == 2: , which does restart the calculation, but once the inner main exits, control returns to the outer main and just picks up where it left off (repeating the calculation). @jeekiii 已经解释了这个问题,你在if more_calc == 2:中递归到main ,这确实会重新开始计算,但是一旦内部main退出,控制就会返回到外部main并从它停止的地方继续(重复计算)。 What you probably should do here is instead of calling main() there, just clear the state variables by doing:您可能应该在这里做的不是在那里调用main() ,而是通过执行以下操作清除状态变量:

if more_calc == 2:    
    num_used_list = []
    math_question = {}
    start_calc = 0

like you do at the top of main .就像你在main顶部做的那样。

You already have a new_calc variable you check at the top of your loop so you can additionally avoid having to use break at all by just setting new_calc = False under if more_calc == 3: .您已经在循环顶部检查了一个new_calc变量,因此您还可以通过在if more_calc == 3:下设置new_calc = False来避免使用break

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

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