2

i have this code:

class Check(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()

    be = "SELECT * FROM Benutzer ORDER BY date "
    c = db.GqlQuery(be)

    for x in c:
      if x.benutzer == user:
        s=1
        break
      else:
        s=2
    if s is 0:
      self.redirect('/')

to check whether the user is registered or not. but it gives me an error:

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 511, in __call__
    handler.get(*groups)
  File "/Users/zainab_alhaidary/Desktop/الحمد لله/check.py", line 23, in get
    if s is 0:
UnboundLocalError: local variable 's' referenced before assignment

what should i do???

simplyharsh
  • 35,488
  • 12
  • 65
  • 73
zozo
  • 31
  • 1

7 Answers7

6

Define s before to assign it a value (also, change the test on s):

user = users.get_current_user()

be = "SELECT * FROM Benutzer ORDER BY date "

c = db.GqlQuery(be)

s=0    # <- init s here

for x in c:
  if x.benutzer == user:
    s=1
    break
  else:
    s=2
if s == 0:    # <- change test on s
  self.redirect('/')
Studer
  • 611
  • 2
  • 8
  • 21
4

Why exactly are you loading all users, then looping through them, just to find one? Use a where clause:

be = "SELECT * FROM Benutzer WHERE benutzer=:1"
c = db.GqlQuery(be, user)
user_from_db = c.get()
if user_from_db is not None: # found someone
    dostuff()
else:
    self.redirect('/')
Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
2

You want to set s to 0 before the for loop starts. If the query returns zero items, your for loop doesn't loop even once, so s is undefined.

Also, you should use if s == 0: instead of if s is 0:. In CPython, they are both equivalent, but you shouldn't rely on the fact. See: the documentation for PyInt_FromLong and "is" operator behaves unexpectedly with integers.

Community
  • 1
  • 1
Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
  • Why shouldn't he rely on that fact? – reconbot Aug 11 '10 at 13:55
  • `is` tests that the variables refer to the same object in memory, `==` tests that their values are equal. CPython caches small `int`s (<265 I think) for optimisation, so all references to them point to the same place in memory. This is not true of large `int`s, or guaranteed by the specification. – Katriel Aug 11 '10 at 14:00
  • 2
    @wizard, because it's an implementation detail of one implementation of python. there is jython, pypy, ironpython, unladenswallow... any of those might decide not to cache the small ints. besides the code should **say what you mean** – John La Rooy Aug 11 '10 at 14:06
  • I understand what you mean now, I've spent 30 minutes trying to find the docs on "is". – reconbot Aug 12 '10 at 00:10
2

You're using 's' before you assign something to it. Add an 's = 0' in the appropriate location.

signine
  • 2,985
  • 1
  • 18
  • 9
1

Your problem is that if c is an empty list then the code in the for loop is never run and s never gets set, hence the error:

UnboundLocalError: local variable 's' referenced before assignment

What the error is telling you that you're referencing - i.e. using - s before it has any value - i.e. before a value has been assigned to it.

To fix this you just ensure s always is assigned a value:

s = 0

for x in c:
    if x.benutzer == user:
        s = 1
        break
    else:
        s = 2
David Webb
  • 190,537
  • 57
  • 313
  • 299
  • the `else` clause of the `for` loop gets executed if the for loop isn't terminated by a `break`, so this won't work – John La Rooy Aug 11 '10 at 13:56
  • @gnibbler - you're right; shouldn't have suggested something I don't use myself. Have changed to suggested solution. – David Webb Aug 11 '10 at 13:59
0

In the case that c is empty the if statement in the loop never gets executed

you should set s=0 before the for loop

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
0

I don't know why you are doing this, but if I understand your code correctly, you have s=1 when x.benutzer == user, and s=2 otherwise (shouldn't this be s=0 if you are going to check against 0?).

for x in c:
   if x.benutzer == user:
      s=1
      break
   else:
      s=2
if s is 0:
   self.redirect('/')

Anyway, here's my solution:

if not any(x.benutzer == user for x in c):
   self.redirect('/')
satoru
  • 31,822
  • 31
  • 91
  • 141