Why is Python compiling this code without throwing errors? - python

I'm new to Python, so please bear with me.
Why isn't Python throwing an error when it compiles the following code.
def b_search(left, right):
while left <= right:
mid = left + (right-left)//2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = whatever
else:
right = mid-1
return -1
Wondering how there's no error even though 'nums' isn't defined, and neither is 'whatever', nor 'target'.
Thanks!

Global variables are looked up at runtime, when the function tries to access their value, not when the function is defined. If there's still no nums variable when the function tries to actually use it, you'll get a NameError at that point, but not at function definition time.
The process here isn't "look up nums and compile bytecode using the information we found"; it's "compile bytecode that, if run, might look up nums then".

From the code you provided, looks like you're not running the function, therefore the code is not being executed and it doesn't use the non-existing variables.
Once you declared the function, if you try to call it, you'll find this errors:
>>> b_search(3,9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in b_search
NameError: name 'nums' is not defined

Related

Create dynamic function in python?

I got NameError for calling test_gobject, but the funny thing is I never called this function name. I called test_gobjectpy()
Can you explain it to me why Python decide to call the wrong function name (see error output)
Maybe it has some problems because I have a string with the same name as function?!
file name test_dyn_fun.py
second_path = ['test_gobject.py', 'st1.py', 'test_show_desktop.py', 'download_img.py', 'test_dump.py']
print("second_path", second_path)
print()
for i in second_path:
#func = create_dyn_func(i)
tmp = i.replace(".", "") #rm dot for function name
print("tmp =", tmp)
exec(f"def {tmp}(): print({i})")
print()
print(dir(test_gobjectpy))
print()
print(locals())
test_gobjectpy()
Error output:
Traceback (most recent call last):
File "/home/manta/Coding/test_dyn_fun.py", line 13, in <module>
test_gobjectpy()
File "<string>", line 1, in test_gobjectpy
NameError: name 'test_gobject' is not defined
In your loop you create functions, the first one created is effectively created like this:
i = 'test_gobject.py'
tmp = 'test_gobjectpy'
exec(f"def {tmp}(): print({i})")
So, it's as if you ran:
exec("def test_gobjectpy(): print(test_gobject.py)")
For Python to print test_gobject.py, it tries to access an object called test_gobject and its attribute .py.
That's what is causing the error. The fact that test_gobject.py looks like a filename to you doesn't matter, it's just names of variables to Python, the way you wrote it.
What would you expect to happen if you called this function?
def test_gobjectpy():
print(test_gobject.py)
More in general, as a beginning programmer, it's generally best to stay away from stuff like exec() and eval(). It's very common for new Python programmers to think they need this, or that it somehow solves a problem they have, but it's generally the worst solution to the problem and rarely actually a good solution at all. (not never, just rarely)

Input function interpreted as variable for some reason

Been looking around and can't find an answer.
So I call either raw_input() or input() to fill out a simple variable. But instead of running the function, I get
UnboundLocalError: local variable 'input' referenced before assignment
My code doesn't have 'input()' anywhere before that first call, and never makes a variable sharing the name. Same happens for 'raw_input()'. I'm confused here, as calls to the functions work fine in other code, and also on the console, but for some reason throw errors on this. No previous calls. Funny enough, it worked on my first run of the code, but now doesn't. What am I looking for?
Edit: Someone asked for the code. Not much to show.
end = False
lightsoff = []
lightson = []
bias = []
i = 0
while not end:
print "Set #" + str(i + 1) +", LED off: ",
offFile = input()
EDIT: To correct here, a variable named 'input' is referred to much later in the code (it's long). I wrote a couple of references backwards. I didn't know Python made a list (or something) of what's going to be a local variable before running, thus throwing up problems like this.
I suspect your code looks a bit like:
>>> def x():
... input = input()
... print(input)
...
>>> x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in x
UnboundLocalError: local variable 'input' referenced before assignment
>>>
The problem is that you've created a variable called 'input', and then trying to get something from it before it exists.
>>> def y():
... val = input()
... print(val)
...
>>> y()
Would work a bit better. In python (and most dynamic languages) functions are kind of values too - so you can use the name of a function just like you would any other variable.
So a good idea is to not name a variable the same as a function.
Does that help?

__class_ data member in python, how it is different from static data member in java

i am trying to execute following code to understand Class data member in python, but it is throwing StopIteration error,
class PizzaShop():
pizza_stock = 10
def get_pizza(self):
while not PizzaShop.pizza_stock:
PizzaShop.pizza_stock -= 1
yield "take yours pizza order, total pizzas left {}".format(PizzaShop.pizza_stock)
mypizza_shop = PizzaShop()
pizza_order = mypizza_shop.get_pizza()
print "{}".format(repr(pizza_order.next()))
i am expecting that it should first print some message and then any exception
i am using python 2.7, ubuntu 32bits os
output:
Traceback (most recent call last):
File "/home/scott/pythonfiles/core_python/pizza.py", line 10, in <module>
print "{}".format(repr(pizza_order.next()))
StopIteration
The problem is this line
while not PizzaShop.pizza_stock:
This will stop immediately if pizza_stock is nonzero. Which it always is. You probably intended to write
while PizzaShop.pizza_stock:
Anyway, if you want to find the details on how values, classes, etc. behave in Python, you should check the docs. It's very different from Java.
P.S. The following is unnecessary as str.format has a shorthand for calling repr. Also, you shouldn't call magic methods like .next directly. Use the builtin next() instead.
print "{}".format(repr(pizza_order.next()))
Should be
print "{!r}".format(next(pizza_order))

Is it possible to print the actual name of a variable, rather than the value it contains? [duplicate]

This question already has answers here:
How to retrieve a variable's name in python at runtime?
(9 answers)
Closed 9 years ago.
When using ctypes with libraries I'm not familiar with (in this specific case, Windows API), I tend to be really aggressive with checking each little step for failures since the Windows API simply returns Null, rather than throwing any kind of error.
So, I have tons of lines that look like this:
myVariableName = windll.user32.SomeWinAPIFuncThatReturnsZeroIfItFails()
if not myVariableName: print "Failed to create myVariableName"
And I repeat that a kazzilion times while figuring out the code.
It would be really nice if I could wrap the above check into a checkSuccess() function, which would simply take the name of the variable to check.
Something along the lines of
def check_success(var_name):
if not var_name:
print "failed to create %s" % var_name # <-- but the actual variable name; not the value
sys.exit()
return True
Of course, I could just manually pass in a string of the variable name, but for cleanliness and boilerplate's sake, it'd be cool it I could just pass in the single variable name.
Hopefully that makes sense!
Are tracebacks enough for you here?
myVariableName = windll.user32.SomeWinAPIFuncThatReturnsZeroIfItFails()
if not myVariableName: raise ValueError
When that gets raised, you see:
Traceback (most recent call last):
File "main.py", line 1, in <module>
my_function()
File "main.py", line 3, in my_function
if not myVariableName: raise ValueError
ValueError
You could write a function to help you this:
def verify_non_zero(x):
if x == 0: raise ValueError
return x
And then:
myVariableName = verify_non_zero(windll.user32.SomeWinAPIFunc())
Which would give you the traceback:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
myVariableName = verify_non_zero(windll.user32.SomeWinAPIFunc())
File "<pyshell#6>", line 2, in verify_non_zero
if x == 0: raise ValueError
The short and sweet is: you can't (really) pass variables, only values. To pass a variable, you'd have to pass its name and its context.
This usually means that you already know the name, so you can just pass the name, or refer to the variable directly.
In your actual usecase, you're actually just checking the value, as far as I can tell. You can pass that value to a function, no problem (and pass the name as well, if you want - you know the name statically).

len(array) works from interpreter, fails when called within function

I have a simple function that works when I enter it in my Jython interpreter manually, but the call to len() fails when I try to run the code as a function.
def calculateChecksum(self, command):
sum = 0
for b in range(len(command)):
sum = sum + command[b-1]
mod = sum % 64
checkbyte = mod & (0xFF)
checksum = checkbyte | 0x80
where command is a jarray.array of bytes (Why am I not using the built-in array type? I ask you: Does it matter? jarray.array is working for everything else, and it clearly works on some occasions, see below)
>>> testarray
array([55, 57, 51], byte)
>>> len(testarray)
3
>>> stage.calculateChecksum(stage, testarray)
Traceback (innermost last):
File "<console>", line 1, in ?
File "....py", line 75, in calculateChecksum
AttributeError: __len__
So I think it's safe to say that this array implements len(), but I don't know why that doesn't always seem to be true. Any idea what's going on here?
Call the method like this:
stage.calculateChecksum(testarray)
Notice that you don't have to explicitly pass stage for the self parameter, that's passed implicitly when you invoke a method over an object (stage in this case.)
You defined def calculateChecksum(self, command): into a class, and when you call a class-method, you do not need to add the self variable. Python adds it for you.

Categories

Resources