Legend Rylex
Legend Rylex

Reputation: 3

While loop in function not working (Python 3.5.0)

I am doing a piece of code for a school with 7-10 year old students which will test their basic arithmetic skills. The program is fully functional and should allows the teacher to see the scores in text files afterwards. However, it's currently 556 lines long. I have shortened it as much as possible but I can't seem to get this one piece of code to work:

def Repeat(repeat_q, option_right, t_class_right):
    repeat_q = input("\n\nWould you like to see any other class details? ")
    if repeat_q == "Yes" or repeat_q == "yes":
        option_right = False
        t_class_right = False
        repeat_question = True
        repeat_q = " "
    elif repeat_q == "No" or repeat_q == "no":
        print("Okay...")
        repeat = False
        T_Exit()
    else:
        print("Please only write 'yes' or 'no'")
    return repeat_question

This function is called later on like this:

elif test == 2:
    OP_2(list_counter, repeat_question)    
    while repeat_question != True:
        Repeat(repeat_q, option_right, t_class_right)

All it does like this is repeat the 'repeat_q' variable. I have tried changing the value of the variable after it but nothing seems to work.I can get it to work if I take it out of the function, like this:

elif test == 3:
    OP_3(list_counter, repeat_question)
    while repeat_question != True:
        repeat_q = input("\n\nWould you like to see any other class details? ")
        if repeat_q == "Yes" or repeat_q == "yes":
            option_right = False
            t_class_right = False
            repeat_question = True
        elif repeat_q == "No" or repeat_q == "no":
            print("Okay...")
            repeat = False
            T_Exit()
        else:
            print("Please only write 'yes' or 'no'")

This is what happens to the code:

Hello and welcome to my quiz.
Please write your name: teacher

Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1

 _________________________________________
|                                         |
| 1) Alphabetical  with  highest  score   |
| 2) Highest score, highest  to  lowest   |
| 3) Average score, highest  to  lowest   |
|_________________________________________|

Choose one of the options above (1, 2 or 3): 2
Sorting by highest score, from highest to lowest

['Lol: 10', 'Zaid: 9', 'Abdul: 8', 'Hello: 5', 'Bruno: 5']


Would you like to see any other class details? yes


Would you like to see any other class details? yes


Would you like to see any other class details? yes


Would you like to see any other class details? yes


Would you like to see any other class details? no
Okay...

You have now finished viewing class details
Thank you for using this program
>>>  # Exits the program

As opposed to this (The working but inefficient version):

Hello and welcome to my quiz.
Please write your name: teacher

Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1

 _________________________________________
|                                         |
| 1) Alphabetical  with  highest  score   |
| 2) Highest score, highest  to  lowest   |
| 3) Average score, highest  to  lowest   |
|_________________________________________|

Choose one of the options above (1, 2 or 3): 1
Sorting alphabetically...

['Abdul: 8', 'Bruno: 5', 'Hello: 5', 'Lol: 10', 'Zaid: 9']


Would you like to see any other class details? yes

Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1

 _________________________________________
|                                         |
| 1) Alphabetical  with  highest  score   |
| 2) Highest score, highest  to  lowest   |
| 3) Average score, highest  to  lowest   |
|_________________________________________|

Choose one of the options above (1, 2 or 3): 3
Sorting by average score, from highest to lowest

['Lol: 10.0', 'Zaid: 8.333333333333334', 'Abdul: 5.333333333333333', 'Hello: 3.3333333333333335', 'Bruno: 3.0']


Would you like to see any other class details? no
Okay...

You have now finished viewing class details
Thank you for using this program
>>> 

Can anyone please help me. A full version of my code is available if anyone wants to check that out: http://www.filedropper.com/teacherprogramtask3-annotated

Upvotes: 0

Views: 550

Answers (1)

Charlton Lane
Charlton Lane

Reputation: 438

When you have the chunk of code inside of the Repeat() function, repeat_question = True is creating a local variable called repeat_question. This variable is a different variable to the one outside of the function that the while loop is checking.

This issue is to do with variable scope, this website explains it quite well: http://gettingstartedwithpython.blogspot.com.au/2012/05/variable-scope.html

There is a simple solution however, you just need to use the return repeat_question at the end of your function by setting repeat_question to the result of the function:

    while repeat_question != True:
        repeat_question = Repeat(repeat_q, option_right, t_class_right)

Also inside the function's elif...: and else: statements you may have to set repeat_question to False.

That should fix it.


EDIT: I think that it isn't working as when it is inside the function, the option_right and t_class_right variables are also only local variables and don't affect the option_right and t_class_right that are outside of the function.

It's a bit of a messy workaround but it should work.


OK I got it working! Repeat function:

def Repeat(repeat_q, option_right, t_class_right):
    repeat_q = input("\n\nWould you like to see any other class details? ")
    if repeat_q == "Yes" or repeat_q == "yes":
        option_right = False
        t_class_right = False
        repeat_question = True
        repeat_q = " "
    elif repeat_q == "No" or repeat_q == "no":
        print("Okay...")
        repeat = False
        t_class_right = True
        repeat_question = False
        T_Exit()
    else:
        print("Please only write 'yes' or 'no'")
    return repeat_question, t_class_right, repeat_question

And in the code:

    if test == 1:                               
        OP_1(list_counter, repeat_question)  
        while repeat_question != True:    
            repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
    elif test == 2:
        OP_2(list_counter, repeat_question)
        while repeat_question != True:
            repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
    elif test == 3:
        OP_3(list_counter, repeat_question)
        while repeat_question != True:
            repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
    else:
        T_Broke()

You have to name repeat_q to repeat_question in the function call, as it is in the above code. That may have caused it to crash and stop working or it could have closed since option_right and t_class_right weren't being updated, or a combination of the two.

Upvotes: 2

Related Questions