473,569 Members | 2,634 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why UnboundLocalErr or?

I'm trying to define a function that prints fields of given widths
with specified alignments; to do so, I wrote some helper functions
nested inside of the print function itself. I'm getting an
UnboundLocalErr or, and after reading the Naming and binding section in
the Python docs, I don't see why.

Here's the error:
fieldprint([5, 4], 'rl', ['Ae', 'Lau'])

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "fieldprint.py" , line 35, in fieldprint
str += cutbits()
File "fieldprint.py" , line 11, in cutbits
for i in range(0, len(fields)):
UnboundLocalErr or: local variable 'fields' referenced before assignment

This is the code:
def fieldprint(widt hs,align,fields ):

def measure():
totallen = 0
for i in range(0, len(fields)):
totallen += len(fields[i])
return totallen

def cutbits():
cutbit = []
for i in range(0, len(fields)):
if len(fields[i]) >= widths[i]:
cutbit.append(f ields[i][:widths[i]])
fields = fields[widths[i]:]
elif len(fields[i]) > 0:
leftover = widths[i] - len(fields[i])
if align[i] == 'r':
cutbit.append(' '*leftover + fields[i])
elif align[i] == 'l':
cutbit.append(f ields[i] + ' '*leftover)
else:
raise 'Unsupported alignment option'
fields[i] = ''
else:
cutbit.append(' '*widths[i])
return cutbit.join('')

if len(widths) != len(fields) or len(widths)!=le n(align) or
len(align)!=len (fields):
raise 'Argument mismatch'

str = ''
while measure()!=0:
str += cutbits()

What's causing the error?

Thanks,
Alex
--
ChapterZero: http://tangentspace.net/cz/
Jul 21 '05 #1
6 9214
Alex Gittens wrote:
I'm trying to define a function that prints fields of given widths
with specified alignments; to do so, I wrote some helper functions
nested inside of the print function itself. I'm getting an
UnboundLocalErr or, and after reading the Naming and binding section in
the Python docs, I don't see why.

Here's the error:
fieldprin t([5, 4], 'rl', ['Ae', 'Lau'])


Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "fieldprint.py" , line 35, in fieldprint
str += cutbits()
File "fieldprint.py" , line 11, in cutbits
for i in range(0, len(fields)):
UnboundLocalErr or: local variable 'fields' referenced before assignment

This is the code:
def fieldprint(widt hs,align,fields ):
[snip]
def cutbits():
cutbit = []
for i in range(0, len(fields)):
if len(fields[i]) >= widths[i]:
cutbit.append(f ields[i][:widths[i]])
fields = fields[widths[i]:]

What's causing the error?


While I don't know the "correct" fix, the immediate cause is that you
are assigning to "fields" in the final line above, and there is no
"global fields" statement, so the compiler thinks it must be a local,
but you access it (as the error says) before it is assigned-to locally.

"A" fix would be to use a different name locally, and if you really want
it to reference the externally defined "fields", just do something like
"lfields = fields" at the top of cutbits() (where "lfields" means
"local fields", though you can pick any name you like).

-Peter
Jul 21 '05 #2
On Fri, 08 Jul 2005 21:21:36 -0500, Alex Gittens wrote:
str = ''
while measure()!=0:
str += cutbits()
It is considered poor practice to use the names of built-ins like str
or list as variable names.
What's causing the error?


Did you actually copy all of the code? It seems to me that once your code
has assembled the string, it doesn't actually do anything with it. Not
even return it.

Also, you seem to be calling a join method on lists. Lists don't have join
methods.

The rest of your code is very hard for me to follow, especially as you
have not put any comments in and seem to spend a lot of time re-inventing
the wheel. I would do something like this to handle fixed-width printing.

(Untested.)

def fieldprint(widt hs,alignments,f ields):
"""Given a list of widths, alignments and fields (text) representing
a single row of text formatted in columns, returns an aligned version.
Text is never truncated to fit, and is padded with spaces.

Examples:
fieldprint([5, 5, 5], "lcr", ["cat", "12345", "12345"])
=> "cat 1234512345"
fieldprint([5, 5, 5], "rcl", ["cat", "dog", "12345"])
=> " cat dog 12345"
fieldprint([5, 5, 5], "rcl", ["cat", "dog", "mice"])
=> " cat dog mice "

"""

# helper function
def align(width, alignment, text):
"""Give a width, an alignment, and some text, returns a string
containing that text aligned correctly in columns.
"""
if alignment in "Ll":
# left-justify
return text.ljust(widt h)
elif alignment in "Rr":
# right-justify
return text.rjust(widt h)
elif alignment in "Cc":
# centered
return text.center(wid th)
else:
raise ValueError("Uns upported alignment '%s'" % alignment)

if not len(widths) == len(alignments) == len(fields):
raise 'Argument mismatch'
columns = zip(widths, alignments, fields)
# builds a list of tuple of (width, alignment, field)
L = [] # hold each formatted column as it is built
for column in columns:
L.append(align( *column))
# equivalent to:
# L.append(align( column[0], column[1], column[2]))
return ''.join(L)
Hope this is helpful to you.
--
Steven.

Jul 21 '05 #3
On Fri, 8 Jul 2005 21:21:36 -0500, Alex Gittens <sw******@gmail .com> wrote:
I'm trying to define a function that prints fields of given widths
with specified alignments; to do so, I wrote some helper functions
nested inside of the print function itself. I'm getting an
UnboundLocalEr ror, and after reading the Naming and binding section in
the Python docs, I don't see why.

Here's the error:
fieldprint([5, 4], 'rl', ['Ae', 'Lau'])Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "fieldprint.py" , line 35, in fieldprint
str +=3D cutbits()
File "fieldprint.py" , line 11, in cutbits
for i in range(0, len(fields)):
UnboundLocalEr ror: local variable 'fields' referenced before assignment

This is the code:
def fieldprint(widt hs,align,fields ):

def measure():
totallen =3D 0
for i in range(0, len(fields)):
totallen +=3D len(fields[i])
return totallen

def cutbits():
cutbit =3D []
for i in range(0, len(fields)):
if len(fields[i]) >=3D widths[i]:
cutbit.append(f ields[i][:widths[i]])
fields =3D fields[widths[i]:] fields[i] = fields[i][widths[i]:] # did you mean this, analogous to [1] below?
elif len(fields[i]) > 0:
leftover =3D widths[i] - len(fields[i])
if align[i] =3D=3D 'r':
cutbit.append(' '*leftover + fields=
[i])
elif align[i] =3D=3D 'l':
cutbit.append(f ields[i] + ' '*lefto=
ver)
else:
raise 'Unsupported alignment option=
'
fields[i] =3D '' ^^^^^^^^^-- [1] else:
cutbit.append(' '*widths[i])
return cutbit.join('')

if len(widths) !=3D len(fields) or len(widths)!=3D len(align) or
len(align)!=3D len(fields):
raise 'Argument mismatch'

str =3D ''
while measure()!=3D0:
str +=3D cutbits()

What's causing the error?

Maybe the missing [i]'s ?

It's not clear what you are trying to do with a field string that's
wider than the specified width. Do you want to keep printing lines that
have all blank fields except for where there is left-over too-wide remnants? E.g.,
if the fields were ['left','left123 45','right','12 345right'] and the widths were [5,5,6,6] and align 'llrr'

should the printout be (first two lines below just for ruler reference)
123451234512345 6123456
LLLLLLLLLLRRRRR RRRRRRR
left left1 right12345r
2345 ight

or what? I think you can get the above with more concise code :-)
but a minor mod to yours seems to do it:
def fieldprint(widt hs,align,fields ): ... def measure():
... totallen = 0
... for i in range(0, len(fields)):
... totallen += len(fields[i])
... return totallen
... def cutbits():
... cutbit = []
... for i in range(0, len(fields)):
... if len(fields[i]) >= widths[i]:
... cutbit.append(f ields[i][:widths[i]])
... #fields = fields[widths[i]:]
... fields[i] = fields[i][widths[i]:] # did you mean this, analogous to [1] below?
... elif len(fields[i]) > 0:
... leftover = widths[i] - len(fields[i])
... if align[i] == 'r':
... cutbit.append(' '*leftover + fields[i])
... elif align[i] == 'l':
... cutbit.append(f ields[i] + ' '*leftover)
... else:
... raise 'Unsupported alignment option'
... fields[i] = '' # <-- [1]
... else:
... cutbit.append(' '*widths[i])
... # XXX return cutbit.join('')
... return ''.join(cutbit)
... if len(widths) != len(fields) or len(widths)!=le n(align) or len(align)!=len (fields):
... raise 'Argument mismatch'
... # str = ''
... result_lines = []
... while measure()!=0:
... result_lines.ap pend(cutbits())
... #str += cutbits()
... return '\n'.join(resul t_lines)
... fieldprint([5,5,6,6], 'llrr', ['left', 'left12345', 'right', '12345right']) 'left left1 right12345r\n 2345 ight' print fieldprint([5,5,6,6], 'llrr', ['left', 'left12345', 'right', '12345right'])

left left1 right12345r
2345 ight

Note that
for i in xrange(len(item s)):
item = items[i]
# mess with item
just to walk through items one item at a time is more concisely written
for item in items:
# mess with item
and if you really need the index i as well,
for i, item in enumerate(items ):
# use item and i here

Also, if you are going to raise 'Argument mismatch' it would be better to do it at the beginning
and use a standard exception. String exceptions are frowned upon these days, so probably raise
ValueError or TypeError with the string as an argument instead, unless you have a more informative thing to do.
BTW, measure above can be defined with current builtins as (untested)
def measure(): return sum([len(field) for field in fields])
I'll leave a few things ...

HTH

Regards,
Bengt Richter
Jul 21 '05 #4
Alex Gittens wrote:
I'm getting an UnboundLocalErr or def fieldprint(widt hs,align,fields ): [...]
def cutbits(): [...]
fields = fields[widths[i]:]


There's your problem. You are assigning 'fields' a completely new
value. Python doesn't allow you to rebind a variable from an outer
scope in an inner scope (except for the special case where you
explicitly use the 'global' directive, which is no use for the nested
scopes you are using here).

So when you assign an identifier in a function Python assumes that you
want that identifier to be a completely new local variable, *not* a
reference to the variable in the outer scope. By writing 'fields= ...'
in cutbits you are telling Python that fields is now a local variable
to cutbits. So when the function is entered, fields is a new variable
with no value yet, and when you first try to read it without writing to
it first you'll get an error.

What you probably want to do is keep 'fields' pointing to the same
list, but just change the contents of the list. So replace the assign
operation with a slicing one:

del fields[:widths[i]]

--
Andrew Clover
mailto:an*@doxd esk.com
http://www.doxdesk.com/

Jul 21 '05 #5
On 9 Jul 2005 05:26:46 -0700, an********@doxd esk.com wrote:
Alex Gittens wrote:
I'm getting an UnboundLocalErr or

def fieldprint(widt hs,align,fields ): [...]
def cutbits(): [...]
fields = fields[widths[i]:]


There's your problem. You are assigning 'fields' a completely new
value. Python doesn't allow you to rebind a variable from an outer
scope in an inner scope (except for the special case where you
explicitly use the 'global' directive, which is no use for the nested
scopes you are using here).

So when you assign an identifier in a function Python assumes that you
want that identifier to be a completely new local variable, *not* a
reference to the variable in the outer scope. By writing 'fields= ...'
in cutbits you are telling Python that fields is now a local variable
to cutbits. So when the function is entered, fields is a new variable
with no value yet, and when you first try to read it without writing to
it first you'll get an error.

What you probably want to do is keep 'fields' pointing to the same
list, but just change the contents of the list. So replace the assign
operation with a slicing one:

del fields[:widths[i]]


Except the OP probably had two errors in that line, and doesn't want to slice
out fields from the field list, but rather slice characters from the i-th field,
and strings are immutable, so he can't do
del fields[i][:widths[i]] # slice deletion illegal if fields[i] is a string
and so
fields[i] = fields[i][:widths[i]]
would be the way to go (see my other post).

Regards,
Bengt Richter
Jul 21 '05 #6
On Sat, 09 Jul 2005 06:17:20 GMT, bo**@oz.net (Bengt Richter) wrote:
On Fri, 8 Jul 2005 21:21:36 -0500, Alex Gittens <sw******@gmail .com> wrote:
I'm trying to define a function that prints fields of given widths
with specified alignments; to do so, I wrote some helper functions
nested inside of the print function itself. I'm getting an
UnboundLocalE rror, and after reading the Naming and binding section in
the Python docs, I don't see why.

It's not clear what you are trying to do with a field string that's
wider than the specified width. Do you want to keep printing lines that
have all blank fields except for where there is left-over too-wide remnants? E.g.,
if the fields were ['left','left123 45','right','12 345right'] and the widths were [5,5,6,6] and align 'llrr'

should the printout be (first two lines below just for ruler reference)
123451234512345 6123456
LLLLLLLLLLRRRRR RRRRRRR
left left1 right12345r
2345 ight

or what? I think you can get the above with more concise code :-)
but a minor mod to yours seems to do it:

[...]

Not very tested, but you may enjoy puzzling out a more concise version
(and writing a proper test for it, since it might have bugs ;-)
def fieldprint(widt hs, align, fields): ... if len(widths) != len(fields) or len(widths)!=le n(align):
... raise ValueError, 'fieldprint argument mismatch'
... align = [getattr(str, j+'just') for j in align]
... results = []
... while ''.join(fields) :
... for i, (fld, wid, alg) in enumerate(zip(f ields, widths, align)):
... results.append( alg(fld[:wid], wid))
... fields[i] = fld[wid:]
... results.append( '\n')
... return ''.join(results )
... print fieldprint([5,5,6,6], 'llrr', ['left', 'left12345', 'right', '12345right'])

left left1 right12345r
2345 ight

BTW, since this destroys the fields list, you might want to operate on a copy
(e.g., remaining_field s = fields[:]) internally, or pass a copy to the routine.
Of course, you could put "print" instead of "return" in fieldprint and just call it
instead of printing what it returns as above, but you didn't show that part in your
original example. BTW2, note that "str" above is the built in string type, and it's
not a good idea to use a built in name for a variable the way your original code did.

Regards,
Bengt Richter
Jul 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2590
by: Brad Clements | last post by:
I was going to file this as a bug in the tracker, but maybe it's not really a bug. Poor Python code does what I consider to be unexpected. What's your opinion? With Python 2.3.2 (but also happens with 2.2) An import within a function that shadows a global import can raise UnboundLocalError. I think the real problem is that the the local...
2
5019
by: silverburgh.meryl | last post by:
Can you please tell me what is the meaning this error in general? UnboundLocalError: local variable 'colorIndex' referenced before assignment In my python script, I have a variable define and init to 0, like this colorIndex = 0 and in one of my functions, I increment it by 1
8
1602
by: David Bear | last post by:
I'm attempting to use the cgi module with code like this: import cgi fo = cgi.FieldStorage() # form field names are in the form if 'name:part' keys = fo.keys() for i in keys: try: item,value=i.split(':') except NameError, UnboundLocalError:
15
2312
by: Paddy | last post by:
Hi, I am trying to work out why I get UnboundLocalError when accessing an int from a function where the int is at the global scope, without explicitly declaring it as global but not when accessing a list in similar circumstances. The documentation: http://docs.python.org/ref/naming.html does not give me enough info to determine why the...
9
2414
by: Camellia | last post by:
hi all why it generates an "UnboundLocalError" when I do the following: <code> .... def main(): number = number() number_user = user_guess() while number_user != number:
2
2049
by: Konstantinos Pachopoulos | last post by:
Hi, i have a problem, the source of which is probably the fact, that i have not understood how to declare global variables - I use the Jython compiler, but i think this is a Python issue... First of all, i don not use any classes in this module. The problem is, that i declare and instantiate some vars outside the functions (global ones),...
8
1712
by: defn noob | last post by:
isPrime works when just calling a nbr but not when iterating on a list, why? adding x=1 makes it work though but why do I have to add it? Is there a cleaner way to do it? def isPrime(nbr): for x in range(2, nbr + 1): if nbr % x == 0: break
0
7701
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8130
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7677
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6284
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5219
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2115
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1223
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
940
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.