1

I'm trying to simulate a lottery and have a little problem with my functions. Here's what I'm trying to do:

  1. run window1()
  2. window1() --> destroy_window1() --> window2()
  3. window2() --> destroy window2 or retry() --> window1()

The error occurs when I reach destroy_window1(), where i get the following message: "NameError: name 'e1' is not defined". How can I solve this problem?

I've read that you should pre-define the variables outside the functions. So, I tried to just put e1 = 1 etc., but then i get the message: "AttributeError: 'int' object has no attribute 'get'". Since it's an entry, I don't know how to pre-define it.

from tkinter import*
import random

Part1 = list(range(1,51))
Part2 = list(range(1,11))

Numbers = [0]*7

for n in range (5):
    Number = random.choice(Part1)

    Position = Part1.index(Number)
    del Part1[Position]

    Numbers[n] = Number


for i in range (2):
    Number = random.choice(Part2)

    Position = Part2.index(Number)
    del Part2[Position]

    Numbers[5+i] = Number

print (Numbers)


def destroy_window1():
    global Guess
    Guess = [e1.get(), e2.get(), e3.get(), e4.get(), e5.get(), e6.get(), e7.get()]
    master1.destroy()
    window2()

def retry():
    master2.destroy()
    window1()

def window1():

    master1 = Tk()
    master1.title('Lottery')
    Label(master1, text="Guess numbers:").grid(row=0)

    e1 = Entry(master1, width=2)
    e2 = Entry(master1, width=2)
    e3 = Entry(master1, width=2)
    e4 = Entry(master1, width=2)
    e5 = Entry(master1, width=2)
    e6 = Entry(master1, width=2)
    e7 = Entry(master1, width=2)


    e1.grid(row=0, column=1, padx=5)
    e2.grid(row=0, column=2, padx=5)
    e3.grid(row=0, column=3, padx=5)
    e4.grid(row=0, column=4, padx=5)
    e5.grid(row=0, column=5, padx=5)
    e6.grid(row=0, column=7, padx=5)
    e7.grid(row=0, column=8, padx=5)

    master1.grid_columnconfigure(6, minsize=20) # Creates an empty column (nr. 6) with width 20

    Button(master1, text='OK', command=destroy_window1).grid(row=3, column=3, sticky=W, pady=5)



    master1.mainloop()


def window2():

    master2 = Tk()
    master2.title('Check results')
    Label(master2, text="Drawn numbers:").grid(row=0, column=0, sticky=W)
    Label(master2, text="Your numbers:").grid(row=1, column=0, sticky=W)

    for n in range (7):
        Label(master2, text=Numbers[n]).grid(row=0, column=n+1, sticky=W, padx=5)

        if str(Numbers[n]) == Guess[n]:
            Label(master2, text=Guess[n], bg="green").grid(row=1, column=n+1, sticky=W, padx=5)
        else:
            Label(master2, text=Guess[n], bg="red").grid(row=1, column=n+1, sticky=W, padx=5)

    Button(master2, text='Quit', command=master2.destroy).grid(row=3, column=3, sticky=W, pady=5)
    Button(master2, text='Retry', command=retry).grid(row=3, column=4, sticky=W, pady=5)

    master2.mainloop ()

window1()

I can't vote up yet, thanks in advance!

1
  • 1
    It is because local variables in a function cannot be accessed by another function. For your case, just add global master1, e1, e2, e3, e4, e5, e6, e7 as the first statement in window1() to make those variables global variables. Also add global master2 in window2(). However using global variables is not a good practice, try refactor your code using class. Commented Jun 3, 2019 at 7:54

1 Answer 1

1

The error occurs when I reach destroy_window1(), where i get the following message: "NameError: name 'e1' is not defined". How can I solve this problem?

The problem is that the destroy_window1() function doesn't know about the e1 variable, because e1 is defined within the window1() function (and its not global).

A simple fix is to put all the e variables into a list and pass that list as an argument to the destroy_window1() function. Make the list with a simple for loop, this not only solves your problem, but it also makes your code cleaner, easier to read, and easier to change it's functionality in future.

Like so:

def destroy_window1(e_list):
    global Guess
    Guess = []

    for e_item in e_list:
        Guess.append(e_item.get())

    master1.destroy()
    window2()

def window1():

    master1 = Tk()
    master1.title('Lottery')
    Label(master1, text="Guess numbers:").grid(row=0)

    e_list = []

    for i in range(7):
        temp_e = e1 = Entry(master1, width=2)
        temp_e.grid(row=0, column=i, padx=5)
        e_list.append(temp_e)

    master1.grid_columnconfigure(6, minsize=20) # Creates an empty column (nr. 6) with width 20

    Button(master1, text='OK', command=lambda :destroy_window1(e_list)).grid(row=3, column=3, sticky=W, pady=5)

    master1.mainloop()

Part of this solution involves a lambda function. This is because (as you may have noticed) the command option normally can't take arguments for the functions. The use of a lambda functions makes this possible. (Read up on Lambda Functions Here)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.