0

So I am trying to declare the variable "checks" as a global variable because I get the following issue:

  File "C:\Python27\Projects\Automatic Installer\autoinstall.py", line 11, in installFunc
    if checks[0] == 1:
NameError: global name 'checks' is not defined

Here's my code, I've tried to add global checks to both the main body of the program as well as the installFunc function. Is there another location I should be adding it/some other way to indicate that checks should contain the information in the program?

import urllib
import subprocess
from Tkinter import *

global checks

def installFunc():
    global checks
    subprocess.call("md c:\MGInstall", shell=True)
    subprocess.call (u"net use w: \\it01\files")
    if checks[0] == 1:
        subprocess.call(u"w:\\software\\snagitup.exe")
    if checks[1] == 1:
        subprocess.call(u"w:\\software\\camtasia.exe")
    if checks[2] == 1:
        urllib.urlretrieve(u"SUPERLONGURLLOLOLOL", u"c:\\MGinstall\\gotomeeting.exe")
        subprocess.call (u"c:\\MGinstall\\gotomeeting.exe")
    urllib.urlretrieve(u"http://ninite.com/.net-7zip-air-chrome-cutepdf-dropbox-essentials-firefox-flash-flashie-java-klitecodecs-quicktime-reader-safari-shockwave-silverlight-vlc/ninite.exe", u"c:\\MGinstall\\MGinstall.exe")
    subprocess.call (u"c:\\MGinstall\\MGinstall.exe")
    subprocess.call (u"w:\\printers\\installer\\printer.exe")

app = Tk()

w = Label(app, text="CompanyName IT Automatic Installer")
w.pack()

text = ["Snagit", "Camtasia", "GotoMeeting"]
variables = []
for name in text:
    variables.append(IntVar())
    Checkbutton(text=name, variable=variables[-1]).pack()

b = Button(text="OK", command=installFunc)
b.pack()

app.mainloop()
checks = [variable.get() for variable in variables]
Steven Matthews
  • 9,705
  • 45
  • 126
  • 232
  • 2
    `global checks` doesn't define the name `checks`, it just allows you to modify the global. (It's completely unnecessary in your use case anyway, since you're not even trying to modify it) – Wooble May 23 '12 at 14:43

4 Answers4

3

I think this is because checks gets set after the mainloop (the last line of the posted code). the function installFunc gets called from the mainloop via a button press, but checks hasn't been defined yet.

Using the global data in this case isn't a good idea anyway. You should probably do something like:

def installFunc(checks):
    ...

checks = [variable.get() for variable in variables]
b = Button(text="OK", command=lambda : installFunc(checks))

Or, even better, wrap all this up in a class... that way you can do:

self.b=Button(..., command=self.installFunc)
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • No, `checks` is never defined on the module level, only marked as a global there.. – Martijn Pieters May 23 '12 at 14:45
  • @MartijnPieters -- I think we're saying the same thing. saying `global checks` doesn't define the variable. the last line of the script `checks=[ ... ]` does define the variable. However, it is defined too late (after it has been referenced in the `installFunc` function) ... Am I wrong about this? – mgilson May 23 '12 at 14:48
  • @MartijnPieters: Look at the code again. Last line after mainloop is `checks = [variable.get() for variable in variables]`. That is at module level. – Steven Rumbalski May 23 '12 at 14:51
  • I haven't yet done much OOO programming in Python! I'm going to try your lambda method (which I'm not sure exactly what is going on) but I'll eventually try to switch to writing a class. – Steven Matthews May 23 '12 at 14:57
  • @AndrewAlexander : the lambda is essentially the same thing as doing `def func(): return installFunc(checks)` and then putting `command=func` in the `Button` constructor. I hope that helps explain it. – mgilson May 23 '12 at 15:01
  • Oh, nice! Sorta in reverse order, then. – Steven Matthews May 23 '12 at 17:07
0

Replace the first 'global checks' (the one at the global level) with 'global = ...', initializing it appropriately. Using 'global' is really relevant only within a function/method. Per the Python docs: The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global. You may want to read this as well - has lots of relevant info: Using global variables in a function other than the one that created them

Community
  • 1
  • 1
Art Swri
  • 2,799
  • 3
  • 25
  • 36
0

The problem is not the first 'global checks'. What causes the error is that checks is accessed before it is initialized.

You must initialize checks before calling the main loop of the application.

betabandido
  • 18,946
  • 11
  • 62
  • 76
0

First of all, Python is not PHP.

You need to use keyword global if an only if, you're going to assign to global variable within scope of a function.

global checks at top level makes no sense at all, and more importantly does not define that variable.

global checks in your installFunc() does not make sense, as you do not assign anything to that variable, in fact you don't even modify it.

In Python variables from outer scope are visible in local scope, unless of course you try to assign something, which would be interpreted as redefining that variable within local scope.

Problem with your code is that you only define checks after exiting main loop. Correct code would look like this

import urllib
import subprocess
from Tkinter import *

#no global definition here...

def installFunc():
    #no global definition here...
    subprocess.call("md c:\MGInstall", shell=True)
    ...

...

#define checks before starting main loop
checks = [variable.get() for variable in variables]
app.mainloop()
vartec
  • 131,205
  • 36
  • 218
  • 244