views:

116

answers:

7

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???

+6  A: 

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
How do I correctly format the code block (with colour, ...) ?
Studer
Don't use `<pre>`, just indent 4 space. The syntax highlighting is automatic.
Fred Larson
Indent it by 4 spaces, or mark it and use the code button to do it.
chryss
Thank you very much !
Studer
+2  A: 

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 http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers.

Alok
Why shouldn't he rely on that fact?
wizard
`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.
katrielalex
@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**
gnibbler
I understand what you mean now, I've spent 30 minutes trying to find the docs on "is".
wizard
+2  A: 

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

signine
A: 

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

gnibbler
+1  A: 

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
Dave Webb
the `else` clause of the `for` loop gets executed if the for loop isn't terminated by a `break`, so this won't work
gnibbler
@gnibbler - you're right; shouldn't have suggested something I don't use myself. Have changed to suggested solution.
Dave Webb
+4  A: 

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('/')
THC4k
I'd vote you up twice if I could, this wasn't his question but it should be his answer.
wizard
Wooble: Ok, I've never used AppEngine so I didn't know.
THC4k
A: 

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.Logic