Unable to run the following Python code - python

This program is basically a script to scan each host in a subnet by actually pinging each ip.
This is my code:
#!/usr/bin/python
import os
global lis
print("Scanning the Subnet : ")
subnet_input = '192.168.1.0'
subnet_input = subnet_input.split('.')
for x in range(0,255):
subnet_input[3] = x
str(subnet_input)
new_sub = str(subnet_input[0])+'.'+str(subnet_input[1])+'.'+str(subnet_input[2])+'.'+str(subnet_input[3])
res = os.system("ping -c 4 {}".format(new_sub))
if res==0:
print("{} is Alive".format(new_sub))
str(new_sub)
lis = lis + " " + new_sub
else:
continue
print("[*] ALL ALIVE HOSTS ARE : ")
for i in lis:
print(i)
Error is :
Traceback (most recent call last):
File "./Ping.py", line 16, in <module>
lis = lis + " " + new_sub
NameError: global name 'lis' is not defined
Even though i have declared a global variable it gives me an error saying that the variable is not defined

You misunderstand how the global statement works.
When you declare a variable global, you tell python that it should be accessible everywhere. However, you still need to give it a value.
In your code, you do:
global lis
But you never assign lis a value. Therefore, when you attempt to access it here:
lis = lis + " " + new_sub
You of course get a NameError. lis does not have a value for you to access.
To fix this, replace global lis with lis = "". Doing global lis and then assigning a value to it will also work. However, since everything seems to be in the global namespace in your example, this is unnecessary.

Related

Python NameError: name is not defined (variable names already defined but I get error)

I am trying to run the following codes. I get the error NameError: name 'XXXXX' is not defined.
if __name__ == '__main__':
land_dir = "C:/Users/mb/Documents/Land"
MOD_dir = "C:/Users/mb/Documents/MOD"
def search_land_name(path):
"""to get the land list file name"""
output_list =[]
pt=os.listdir(path)
for item in pt:
if str.find(item,'B3.TIF') != -1: #satisfied conditions
output_list.append(item[:-6])
return np.unique(output_list)
for item in land_file_list:
print(item)
LD_QA_name = item + "QA.TIF"
LD_B1_name = item + "B1.TIF"
LD_B2_name = item + "B2.TIF"
LD_B3_name = item + "B3.TIF"
LD_B4_name = item + "B4.TIF"
LD_B5_name = item + "B5.TIF"
LD_B6_name = item + "B6.TIF"
LD_B7_name = item + "B7.TIF"
print(LD_B3_name)
NameError Traceback (most recent call last)
Cell In [8], line 1
----> 1 print(LD_B3_name)
NameError: name 'LD_B3_name' is not defined
Any suggestion please.
LD_B3_name is locally defined inside your function search_landsat_name.
That means that the variable only exists inside your function.
If you want to access the variable outside of search_landsat_name you can simply return the variable:
def search_landsat_name(path):
# some code
return LD_B3_name
LD_B3_name = search_landsat_name(path)
print(LD_B3_name)
But keep in mind that LD_B3_name = search_landsat_name(path) creates an independent variable. If you change the value it doesn't affect LD_B3_name inside your function.
Check out global vs local variables to help you understand this more.

Name is local and global syntax error in python

I am getting error while executing below statement
a = 10
def test_method(a):
global a
print("Old value of local a = " + str(a)) #this is returning "a = 10"
a = 2
print("New value of local a = " + str(a))
test_method(a)
print("Value of global a = " + str(a))
Output
SyntaxError: name 'a' is local and global
How to change value of a globally in this proc where name is same for function argument and actual parameter
I really think the correct answer is to just pick a different name for the function argument as I commented, but if you cannot for some reason, you can access the global a via globals():
>>> a = 10
>>> def test_method(a):
... print('global:', globals()['a'])
... print('local: ', a)
...
>>> test_method(42)
global: 10
local: 42
Although this is somewhat hacky and I would strongly recommend simply changing the variable names to avoid the error instead.

KeyError: global not accessible through imported class

I am trying to calculate the number of elements in a chemical equation. The debugger that I have created somehow doesn't have access to the globals within my program. Specifically, I am trying to access carrots but left is not being added to the stack. Any ideas?
Debug.py
class Debugger(object):
def __init__(self,objs):
assert type(objs)==list, 'Not a list of strings'
self.objs = objs
def __repr__(self):
return '<class Debugger>'
def show(self):
for o in self.objs:
print o,globals()[o] #EDIT
Chemical_Balancer.py
from Debug import Debugger
def directions():
print 'Welcome to the chem Balancer.'
print 'Use the following example to guide your work:'
global left #LEFT IS GLOBAL
left = 'B^6 + C^2 + B^3 + C^3 + H^9 + O^4 + Na^1'
print left
print "#Please note to use a 'hat' when entering all elements"
print '#use only one letter elements for now'
# left = raw_input('enter formula:') #enter formula to count
directions()
chem_stats = {}
chem_names = []
chem_names = []
chem_indy = []
for c in range(len(left)):
if left[c].isalpha() and left[c].isupper():
chars = ''
if left[c+1].islower():
chars += left[c]+left[c+1]
else:
chars += left[c]
#print chars
chem_indy.append(c)
chem_names.append(chars)
carrots = [x for x in range(len(left)) if left[x]=='^']
debug = Debugger(['carrots','chem_names','chem_indy','chem_stats']) # WITHOUT LEFT
debug.show()
Error message:
Traceback (most recent call last):
File "C:\Python27\#Files\repair\Chemical_Balancer.py", line 38, in <module>
debug.show()
File "C:\Python27\lib\site-packages\Debug.py", line 12, in show
print o,globals()[o]
File "<string>", line 1, in <module>
KeyError: 'carrots'
About the specific error on the left variable:
when you say a variable is global, python knows it has to look it up in the global namespace when its name is used. But in the code left hasn't been assigned in such namespace.
As you can see, left is commented out
#left = raw_input('enter formula:') #enter formula to count
Uncomment it by removing the # at the beginning of the line, so the line inside the directions function
global left
can find it and the instructions that follow can work.
About the implementation:
one solution to allow the debugger to know where to look for the variables, i.e. in which module, can be to provide the name of the module to it when it is created. Then the debugger object can reach the global variables of the module that created it via sys.modules[module_name].__dict__
debugger.py
import sys
class Debugger(object):
def __init__(self, module_name, objs):
assert type(objs)==list,'Not a list of strings'
self.objs = objs
self.module_name = module_name
def __repr__(self):
return '<class Debugger>'
def show(self):
for o in self.objs:
print o, sys.modules[self.module_name].__dict__[o]
chemical_balancer.py
import debugger as deb
a = 1
b = 2
d = deb.Debugger(__name__, ['a', 'b'])
print(d.objs)
d.show()
a = 10
b = 20
d.show()
which produces
['a', 'b']
a 1
b 2
a 10
b 20
As you can see, the debugger prints the current value of the variables each time its show method is called
I have found this SO Q&A informative and helpful.

UnboundLocalError: local variable referenced before assignment in python closure [duplicate]

This question already has answers here:
Is it possible to modify a variable in python that is in an outer (enclosing), but not global, scope?
(9 answers)
Closed 17 days ago.
I implemented two simple closures in Python. To me, they looks the same, but one works and the other doesn't.
The working one is:
def makeInc(x, y):
def inc():
return y + x
return inc
inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)
inc5 () # returns 15
inc10() # returns 15
But the second one doesn't work:
import os
def linker(dest, filename):
print filename
def link():
if os.path.isfile(filename): # line 17
filename = os.path.join(os.getcwd(), filename)
dest = os.path.join(dest, filename)
y = rawinput('[y]/n: ln -sf %s %s' % (dest, filename))
if y == 'n':
return 1
else:
return os.system('ln -sf %s %s' %(dest, filename))
else:
return -1
return link
l = linker('~', '.vimrc')
l() # line 30
It faults at the first line of link() when executing l():
Traceback (most recent call last):
File "test.py", line 30, in <module>
l()
File "test.py", line 17, in link
if os.path.isfile(filename):
UnboundLocalError: local variable 'filename' referenced before assignment
They seem identical to me so I don't understand why the second one doesn't work. Any idea?
You have overwritten the variable with filename = os.path.join(os.getcwd(), filename), if you change the filename = to something other than filename you won't get a local variable 'filename' referenced before assignment error.
Once you set filename = you are no longer referring to the parameter filename that is passed in you are referring to the local filename in the scope of the inner function which you try to use in the if before you have it defined.
You will have the same problem with dest, if you change the two lines and the other variables to something like:
filename_ = os.path.join(os.getcwd(), filename)
dest_ = os.path.join(dest, filename)
You will see the code runs fine as filename now refers to the parameter not to a local variable defined in your inner function.
You will see the exact same behaviour if you try to reassign x in your first function and try to access x before you have defined it:
def makeInc(x, y):
def inc():
print y + x # will cause referenced before assignment error
x = 5 # now x is local to the inner func, the x from the outer function is overridden
return y + x
return inc
If you print the __closure__ attribute you will see what happens:
def makeInc(x, y):
def inc():
return y + x
return inc
inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)
print(inc5.__closure__)
(<cell at 0x7f180df67e50: int object at 0xef00f8>, <cell at 0x7f180df67fa0: int object at 0xef0080>)
Now reassigning x:
def makeInc(x, y):
def inc():
print y + x
x= 5
return y + x
return inc
inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)
print(inc5.__closure__)
(<cell at 0x7fea11889fd8: int object at 0x291e080>,)
After reassigning in the inner function, there is no longer a reference to x.
So basically the fundamental difference between your two original functions is that in one you are reassigning the variable in the local scope and in the other you are not. As you can see from the code above if you do something similar in the first function the outcome is exactly the same.
There is a nice tut here on scopes LEGB etc..

Accessing a variable inside a function from another script

comodin.py
def name():
x = "car"
comodin_1.py
import comodin
print comodin.x
Error:
Traceback (most recent call last):
File "./comodin_2.py", line 4, in <module>
print comodin.x
AttributeError: 'module' object has no attribute 'x'
Is this possible?
In the code you wrote, "x" doesn't exist in "comodin". "x" belongs to the function name() and comodin can't see it.
If you want to access a variable like this, you have to define it at the module scope (not the function scope).
In comodin.py:
x = "car"
def name():
return x
In comodin_1.py:
import comodin
print comodin.name()
print comodin.x
The last 2 lines will print the same thing. The first will execute the name() function and print it's return value, the second just prints the value of x because it's a module variable.
There's a catch: you have to use the 'global' statement if you want to edit the value "x" from a function (add this at the end of comodin.py):
def modify_x_wrong():
x = "nope"
def modify_x():
global x
x = "apple"
And in comodin_1.py:
print comodin.name() # prints "car"
comodin.modify_x_wrong()
print comodin.name() # prints "car", once again
comodin.modify_x()
print comodin.name() # prints "apple"

Categories