name 'times' is used prior to global declaration – But IT IS declared

Question:

I’m coding a small program to time and show, in a ordered fashion, my Rubik’s cube solvings. But Python (3) keeps bothering me about times being used prior to global declaration. But what’s strange is that IT IS declared, right on the beggining, as times = [] (yes, it’s a list) and then again, on the function (that’s where he complains) as times = [some, weird, list] and "globaling" it with global times. Here is my code, so you may analyse it as you want:

import time

times = []

def timeit():
    input("Press ENTER to start: ")
    start_time = time.time()
    input("Press ENTER to stop: ")
    end_time = time.time()
    the_time = round(end_time - start_time, 2)
    print(str(the_time))
    times.append(the_time)
    global times
    main()
        
def main():
    print ("Do you want to...")
    print ("1. Time your solving")
    print ("2. See your solvings")
    dothis = input(":: ")
    if dothis == "1":
        timeit()
    elif dothis == "2":
        sorte_times = times.sort()
        sorted_times = sorte_times.reverse()
        for curr_time in sorted_times:
            print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
    else:
        print ("WTF? Please enter a valid number...")
        main()

main()

Any help would be very appreciated as I’m new in the world of Python.

Asked By: AntonioPT

||

Answers:

The global declaration is when you declare that times is global

def timeit():
    global times # <- global declaration
    # ...

If a variable is declared global, it can’t be used before the declaration.

In this case, I don’t think you need the declaration at all, because you’re not assigning to times, just modifying it.

Answered By: John Millikin

From the Python documentation:

Names listed in a global statement must not be used in the same code block
textually preceding that global statement.

https://docs.python.org/reference/simple_stmts.html#global

So moving global times to the top of the function should fix it.

But, you should try not to use global in this situation. Consider using a class.

Answered By: carl

From the Python Docs

Names listed in a global statement must not be used in the same code block textually preceding that global statement.

Answered By: randlet

This program should work but may not work exactly as you intended. Please take note of the changes.

import time

times = []

def timeit():
    input("Press ENTER to start: ")
    start_time = time.time()
    input("Press ENTER to stop: ")
    end_time = time.time()
    the_time = round(end_time - start_time, 2)
    print(str(the_time))
    times.append(the_time)

def main():
    while True:
        print ("Do you want to...")
        print ("1. Time your solving")
        print ("2. See your solvings")
        dothis = input(":: ")
        if dothis == "1":
            timeit()
        elif dothis == "2":
            sorted_times = sorted(times)
            sorted_times.reverse()
            for curr_time in sorted_times:
                print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
            break
        else:
            print ("WTF? Please enter a valid number...")

main()
Answered By: Noctis Skytower

For the main program, you can declare it on the top. Ther will be no warning. But, as said, the global mention is not useful here. Each variable put in the main program is in the global space. In functions, you must declare that you want use the global space for it with this keyword.

Answered By: Mih Zam
import time

times = []

def timeit():
    global times
    input("Press ENTER to start: ")
    start_time = time.time()
    input("Press ENTER to stop: ")
    end_time = time.time()
    the_time = round(end_time - start_time, 2)
    print(str(the_time))
    times.append(the_time)
    main()

def main():
    print ("Do you want to...")
    print ("1. Time your solving")
    print ("2. See your solvings")
    dothis = input(":: ")
    if dothis == "1":
        timeit()
    elif dothis == "2":
        sorte_times = times.sort()
        sorted_times = sorte_times.reverse()
        for curr_time in sorted_times:
            print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
    else:
        print ("WTF? Please enter a valid number...")
        main()

main()

that should work. The "global[varname]" have to be at start from definition 😉

Answered By: thePythonNoob

I got the same error below:

SyntaxError: name ‘x’ is used prior to global declaration

When trying to use the local and global variables x in inner() as shown below:

x = 0
def outer():
    x = 5
    def inner():        
        x = 10 # Local variable
        x += 1
        print(x)
        
        global x # Global variable
        x += 1
        print(x)
    inner()
outer()

And, when trying to use the non-local and global variables x in inner() as shown below:

x = 0
def outer():
    x = 5
    def inner():
        nonlocal x # Non-local variable
        x += 1
        print(x)
        
        global x # Global variable
        x += 1
        print(x)
    inner()
outer()

So, I renamed x to y for the local variable as shown below:

x = 0
def outer():
    x = 5
    def inner():        
        y = 10 # Here
        y += 1 # Here
        print(y) # Here
        
        global x        
        x += 1
        print(x)
    inner()
outer()

Then, the error was solved as shown below:

11
1

And, I renamedx to y for the non-local variable as shown below:

x = 0
def outer():
    y = 5 # Here
    def inner():
        nonlocal y # Here
        y += 1 # Here
        print(y) # Here
        
        global x
        x += 1
        print(x)
    inner()
outer()

Then, the error was solved as shown below:

6
1
Answered By: Kai – Kazuya Ito