Python list variable scope issues - python

I have the following code:
def myFunction(param, param):
myList = ["",[],[],[]]
#code to fill up myList
for q,d in enumerate(detailCollection):
#all the fun stuff here
yield{
"var1":myList[0],
"var2":myList[1],
#and so on
}
The error I am getting is as follows:
NameError: name 'myList' is not defined
Coming from the lines in the yield statement
For privacy purposes I haven't included actual code, but this is identical situation of what is happening. Why is it saying that myList is not defined when it is clearly in the same function scope, and how can I fix this problem? I would rather not move the myList variable all the way out and call it a global variable, to keep the code clean and concise is there a way to do this without moving myList declaration/definition?

So I didn't realize I had an extra _ laying around in my yield statement. No biggy :) Problem solved.

Related

Python variable declared in 'for' loop not seen outside of loop

I know there are quite a few "python scope questions" here but I am VERY rusty with python and I am really confused about a "UnboundLocalError" problem I keep getting. I have read that 'for' loops do not have a contained scope yet my code seems to be acting in that way... My code looks like this:
`
...
for b in blocks[:]:
if b.contains(CONSTANT_NUM):
r = b.split(CONSTANT_NUM+2)
if r: blocks.append(r)
Foo= struct.unpack('<H', b.data)[0]
Bar = Foo
...
print("Foo: 0x%x" % (Foo))
`
Whenever I run this, I get the error "UnboundLocalError: local variable 'Foo' referenced before assignment". When I instead try and print Bar I get the same error. Why is the assignment not being carried outside of the 'for' loop?
It could be very likely that your loop never went into the if statement and hence Foo was never initialized.
You need to initialize it before the loop just to make sure that if that conditional is never met, you have something to print.
In your case, if the 1st if condition is failing, then the compiler won't reach the Foo = ... statement. Which will result in the error you are getting now.
The error indicates that at the time of checking the variable foo you have not yet initialized.
you should initialize it before the loop.

Module with text files

I am very new to python, and am writing a code with multiple modules.
Each of my modules manipulates the same list that I have named "myList", however, I am having trouble understanding how to get the list into each module.
For example, one module called reverseList.py needs to take the list and reverse it, but when it is run in my main function, I get an error that the list does not exist.
Import reverseList
def main():
with open('list3.txt', 'r') as f:
data = f.read()
data = data.split("\n")
myList = [row.split(",") for row in data]
reverseList.reverse()
NameError: name 'myList' is not defined
The reverseList.py module is as follows:
def reverse()
myList1 = myList[::-1]
print(myList1)
return
It is unclear where exactly the error comes out since you didn't include your entire main function - there is no place myList is used before/after its definition. But I can think of a couple of reasons for the error.
The error shows up when a variable is used before it is defined. So, you might have the variable myList before you define it in line 4 of your current code.
In python, indentation is the matter of correctness of your code. Meaning, line 2~4 should be indented if you didn't do so.
I might be able to come up with a better answer if you present the rest part of the code.
Your update reveals where the problem is happening; that is from your reverseList, not your main.
You are loading myList in reverseList, but it has never been defined. myList defined in main is not accessible from reverseList. To fix this problem, you should pass myList as an argument to the function reverse when it is called and use that in your reverse function.
main:
reverseList.reverse(myList)
reverseList:
def reverse(myList):
myList1 = myList[::-1]
print(myList1)
return
Note that the argument name of the function reverse can be different from the one in main. In other words, it doesn't matter if you do follow;
def reverse(myList2):
myList1 = myList2[::-1]
print(myList1)
return
This might be better:
def reverse(myList2):
print(myList2[::-1])

Scoping with Nested Functions in Python

This question is similar to others asked on here, but after reading the answers I'm not grasping it and would appreciate further guidance.
While sketching new code I find myself adding a lot of statements like:
print('var=')
pprint(var)
It became tedious always writing that, so I thought I could make it into a function. Since I want to print the variable name on the preceding line, I tried:
def dbp(var):
eval('print(\'{0}=\')'.format(var))
eval('pprint({0})'.format(var))
so then I do do things like:
foo = 'bar'
dbp('foo')
which prints
foo=
'bar'
This is all great, but when I go to use it in a function things get messed up. For example, doing
def f():
a = ['123']
dbp('a')
f()
raises a NameError (NameError: name 'a' is not defined).
My expectation was that dbp() would have read access to anything in f()'s scope, but clearly it doesn't. Can someone explain why?
Also, better ways of printing a variable's name followed by its formatted contents are also appreciated.
You really should look at other ways to doing this.
The logging module is a really good habit to get into, and you can turn off and on debug output.
Python 3.6 has f'' strings so you would simplify this to:
pprint(f'var=\n{var}`)`
However, here's an example (not recommended) using locals():
In []:
def dbp(var, l):
print('{}='.format(var))
pprint(l[var])
def f():
a = 1
dbp('a', locals())
f()
Out[]:
a=
1
first of all, id like to say that eval is a high security risk for whoever is going to be running that code.
However, if you absolutely must, you can do this.
def dbp(var):
env = {'var': var}
# Adding global variables to the enviroment
env.update(globals())
eval("print('{0}=')".format(var))
eval('pprint(var)', env)
def f():
a = ['123']
dbp('a')
you can then do
>>> f()
a=
'a'

Django: "referenced before assignment" but only for some variables

I'm writing a small app in Django and I'm keeping the state saved in a few variables I declare out of the methods in views.py. Here is the important part of this file:
from app.playerlist import fullList
auc_unsold = fullList[:]
auc_teams = []
auc_in_progress = []
auc_current_turn = -1
print(auc_in_progress)
def auc_action(request):
data = json.loads(request.GET["data"])
# ...
elif data[0] == "start":
random.shuffle(auc_teams)
print(auc_unsold)
print(auc_in_progress)
auc_in_progress = [None, 0, None]
print(auc_in_progress)
The auc_unsold and auc_teams variables work fine; the auc_in_progress variable is not seen by this method, though, giving the error in the title. If I take out the print statement and let this code assign a value to it, the exception will be thrown somewhere else in the code as soon as I use that variable again.
I have tried making another variable and this new one seems to suffer from this problem as well.
What is happening?
Edit: I found a solution: if I write global auc_in_progress just before the print statements, then everything works fine. If I try writing that as I declare the variable above it doesn't work, though, for some reason.
I am unsatisfied with this, because I don't know why this happens and because I dislike using global like that, but eh. Someone has an explanation?
You should absolutely not be doing this, either your original code or your proposed solution with global.
Anything at module level will be shared across requests, not only for the current user but for all users for that process. So everyone will see the same auction, etc.
The reason for your error is because you assign to that variable within your function, which automatically makes it a local variable: see this question for more details. But the solution recommended there, which is the same as your workaround - ie use global - is not appropriate here; you should store the data somewhere specifically associated with the user, eg the session.

Python Parameter Confusion

I'm a beginner, writing a Python Blackjack script, and got confused about whether or not a function (dealPlayer) needs a parameter. It works either way, with a parameter or without. I'm not sure if I've had a brain fart, or I've not learned something along the way. Here's the code:
import random
dealer = []
player = []
c = ""
deck = [2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,
9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,11]
def dealPlayer(deck):
cardOne = random.choice(deck)
cardTwo = random.choice(deck)
player.append(cardOne)
player.append(cardTwo)
deck.remove(cardOne)
deck.remove(cardTwo)
The question is, do I need (deck) as a parameter in the function? It works with or without (deck) as a parameter. I've gone back over different tutorials, and other's code, but I'm still confused. Thanks for any help.
The reason your code works with or without deck as a parameter is because there is a global variable named deck, so when you reference deck inside your function, the function will first look for the local variable (the parameter) and then if it doesn't find it, it will look for the global variable.
It's best to refactor your code to not use global variables at all -- define deck initially inside a function and then pass that as a result or argument to other functions as needed. If you don't want to do that, then at least make sure your argument does not shadow (have the same name as) the global variable, to avoid confusion further on. Or remove the argument entirely and use the global variable only, if that's appropriate for your program.
did i get you right that if your function is:
def dealPlayer():
the code still works? this should raise a undefined deck error. EDIT: this was wrong of course its global. And just works without it. but thats a bad practice.
def dealPlayer():
deck = []
this should raise a Index Error.
cardOne = random.choice()
This raises a TypeError.

Categories

Resources