Django Views Incrementing Variables - python

When I increment one of my variables, it only goes up to 2 instead of 3. The default value is 1. I am not sure what I am missing. Any help is appreciated.
def unanswered(request, template ='unanswered.html'):
phone_number = Pool.objects.order_by('?')[0]
pool = Pool.objects.order_by('?')[0]
pool_list = Pool.objects.all()
number_attempts = Pool.objects.filter(phone_number=phone_number).count()
# unanswer number action
if pool_list:
if number_attempts > 3:
return number_attempts
else:
x = number_attempts
x += 1
print x 'returns 2'
store = Pool(id=phone_number.id,
phone_number = phone_number.phone_number,
un_answered=x, answered=0)
store.save()
payload = {'pool':pool,}
return render_to_response(template, payload, context_instance=RequestContext(request))

There is no any for loop or while loop in your code, so if initial number_attempts is 1, it will incremented to 2 and complete the flow.
I see you want to store attempts in the DB, but the way you are doing is not correct. You are passing id=phone_number.id to Store(...), which will try to update existing record if exists with given id. So Pool.objects.filter(phone_number=phone_number).count() always returns 1.
You may want to change it to
store = Pool(phone_number = phone_number.phone_number,
un_answered=x, answered=0)
So for the next request, Pool.objects.filter(phone_number=phone_number).count() will give you 2.
Update after the comment:
All I want is to update the un_answered field from 1,2,3.
In that case, don't use .count() to get number of failed attempts use the field from object that has that counter.
So instead of
number_attempts = Pool.objects.filter(phone_number=phone_number).count()
you can do this
try:
store = Pool.objects.get(phone_number=phone_number)
number_attempts = store.un_answered
# FIX : the original code used a bare except clause.
# Bare except clauses are EVIL. DONT use bare except clauses. NEVER.
# Or thou shall burn in the flames of hell for your eternal death....
except Pool.DoesNotExist:
store = Pool(phone_number = phone_number.phone_number,
un_answered=1, answered=0)
store.save()
number_attempts = 1
...
if pool_list:
if number_attempts > 3:
return number_attempts
else:
x = number_attempts
x += 1
print x 'returns 2'
store.un_answered = x
store.save()

Related

Why is my dictionary not updating in this while loop?

Running: Python 3.9.9 and Django 4
I'm trying to put together a loop that waits for a users input and then appends that input to an existing dictionary. See code below:
def calculator(request):
loop_int = 1
numbers = [str(x) for x in range(0,10)]
i = "1"
current_nums = {'1':[],'2':[]}
if request.GET: #wait for request.GET to return True before starting while loop
while loop_int < 10:
r = request.GET #store request.GET object as r
if r: #this is here to stop the loop and wait for request.GET to return True
print(r)
if list(r.values())[0] in numbers:
digit = list(r.values())[0] #grab the value from request.GET
current_nums[i].append(digit) #append that value to the list at "1" in current_nums dictionary
print(f'digit = {digit}')
print(f'current_nums = {current_nums}')
loop_int += 1 #increment the loop_int
request.GET = None
return render(request, 'calculator/calculator.html')
The last print statement print(f'current_nums={current_nums}') displays the updated dictionary that I expect, but the appended digits don't persist through the next iteration of the loop. Code output below:
<QueryDict: {'1': ['1']}>
digit = 1
current_nums = {'1': ['1'], '2': []}
<QueryDict: {'2': ['2']}>
digit = 2
current_nums = {'1': ['2'], '2': []}
This file is a views.py file for a Django project. I'm having no issues (as far as I can tell) getting the information from the front end using request.GET.
One odd thing I discovered is that if I remove the statement request.GET = None at the end of the loop, which allows the loop to run uninterrupted with the same value for request.GET, then the program works as intended for the next 9 iterations and the dictionary updates persist. However, as soon as I try to set request.GET = None to pause the loop and wait for a legitimate user input, the dictionary updates stop persisting.
Am I making a simple scope error? Or is there a nuance to request.GET that I'm missing?
Your problem is that you put current_nums in the view function, and every time a request comes in, it will be initialized.
You can put it outside the view function, like below, and it will save the data added with each request.
class Data:
loop_int = 1
current_nums = {'1':[],'2':[]}
numbers = [str(x) for x in range(0,10)]
def calculator(request):
i = "1"
if request.GET and Data.loop_int < 10: #wait for request.GET to return True before starting while loop
r = request.GET #store request.GET object as r
print(r)
if list(r.values())[0] in Data.numbers:
digit = list(r.values())[0] #grab the value from request.GET
Data.current_nums[i].append(digit) #append that value to the list at "1" in current_nums dictionary
print(f'digit = {digit}')
print(f'current_nums = {Data.current_nums}')
Data.loop_int += 1 #increment the loop_int
return render(request, 'calculator/calculator.html')
You can still use it for a single person to test locally. If it involves multiple concurrency, you need to lock it.

How to prevent printing from previous function in current function?

I'm currently writing a test function for class to test provided cases on provided solution code. However I'm running into an issue where a print statement is executing when I don't want it to.
This is the provided solution that I'm testing:
def alphapinDecode(tone):
phone_num = ''
if checkTone(tone): #or checkTone2
while len(tone) > 0:
# retrieve the first tone
next_tone = tone[0:2]
tone = tone[2:]
# find its position
cons = next_tone[0]
vow = next_tone[1]
num1 = consonants.find(cons)
num2 = vowels.find(vow)
# reconstruct this part of the number -
# multiply (was divided) and add back
# the remainder from the encryption division.
phone = (num1 * 5) + num2
# recreate the number
# by treating it as a string
phone = str(phone)
# if single digit, not leading digit, add 0
if len(phone) == 1 and phone_num != '':
phone = '0' + phone
phone_num = phone_num + phone
# but return in original format
phone_num = int(phone_num)
else:
print('Tone is not in correct format.')
phone_num = -1
return phone_num
Here's the (partially done) code for the test function I have written:
def test_decode(f):
testCases = (
('lo', 43),
('hi', 27),
('bomelela', 3464140),
('bomeluco', 3464408),
('', -1),
('abcd', -1),
('diju', 1234),
)
for i in range(len(testCases)):
if f(testCases[i][0]) == testCases[i][1] and testCases[i][1] == -1:
print('Checking '+ f.__name__ + '(' + testCases[i][0] + ')...Tone is not in correct format.')
print('Its value -1 is correct!')
return None
When executing test_decode(alphapinDecode), I get this:
Tone is not in correct format.
Checking alphapinDecode()...Tone is not in correct format.
Its value -1 is correct!
Tone is not in correct format.
Checking alphapinDecode(abcd)...Tone is not in correct format.
Its value -1 is correct!
As you can see, because of the print statement in alphapinDecode(I think), it is printing an extra "Tone is not in correct format." above the print statement I have written.
How would I prevent this print statement from executing, and why is it printing if the print statement I wrote in my test function doesn't ask for the result of alphapinDecode?
We are not allowed to alter the code of the given solution.
I'm fairly new to stackOverflow, so sorry for any formatting issues. Thank you!
Edit: Fixed the idents of the test_decode function
One easy solution would be to pass an extra parameter say, a boolean variable debug to the function. That would go something like this.
def func1(var1, debug):
if debug:
print("Printing from func1")
# Do additional stuff
Now when you call it. You now have the option of setting the debug variable.
func1("hello", debug=True) # will print the statement
func1("hello", debug=False) # will not print statement.
If you cannot modify the called function. Then you can follow this method. explained by #FakeRainBrigand here.
import sys, os
# Disable
def blockPrint():
sys.stdout = open(os.devnull, 'w')
# Restore
def enablePrint():
sys.stdout = sys.__stdout__
print 'This will print'
blockPrint()
print "This won't"
enablePrint()
print "This will too"

Look up salary information by name from a list

I'm writing some python code that works out a person's total pay.
I am able to do this by getting the user to input their pay, however I would like them just to be able to enter their name and then the name is searched in position 0 of a list (Eg. 0,1 0,2 0,2 etc).
I have tried using a tuple but it is not callable and the dictionary and list would not work for me either.
counter = 0
valid = 0
employeelist = [["thomas","2","500"], ["jake","1","750"]]
while True:
while True:
try:
name = str(input("Name:"))
except ValueError:
print("Error")
continue
else:
break
while True:
if name == employeelist[counter,0]:
print(employeelist[counter])
break
valid = 1
elif counter = 3:
print("invalid name")
break
else:
counter = counter + 1
if valid == 1:
break
months = employeelist[counter,1]
pay = employeelist[counter,1]
totalpay = int(months) * int(pay)
Edit:
I do no longer have the code with the dictionary, however I just edited the code from [counter,1] and [0,1] to [counter][1] and is working fine thank you :D
The code below is for your inner loop
employeelist = [["thomas","2","500"], ["jake","1","750"]]
name = ""
while True:
try:
name = input("Name:")
break
except:
print "Error"
position = -1
for i, element in enumerate(employeelist):
if element[0] == name:
position = i
break
if position == -1:
print "Invalid Name"
else:
totalpay = int(employeelist[position][1]) * int(employeelist[position][2])
Your code have multiple bugs. First, valid=1, is set after breaking the loop -meaning valid=1,is never set. You also are checking elif counter = 3 this way, you should rather use two equality signs, like this: elif counter == 3
The error you are getting, that list indices must be integers or slices, not tuple, you are having because you are accessing a multidimensional array the wrong way. Instead of name == employeelist[counter, 0], it should be name == employeelist[counter][0].
Your way of iterating through the array is possible, but its rather simpler using a for loop.
Try this way.
for employees in employeelist:
if name == employees[0]:
print(employee)
valid = 1
break
If it iterated through the hole employeelist, without the if-block running, valid = 1, would never been set.
Working code:
counter = 0
valid = 0
employeelist = [["thomas","2","500"], ["jake","1","750"]]
while True:
while True:
try:
name = str(input("Name: "))
except ValueError:
print("Error")
continue
else:
break
for employees in employeelist:
if name == employees[0]:
print(employees)
valid = 1
break
if valid == 1:
break
months = employeelist[counter][1]
pay = employeelist[counter][2]
totalpay = int(months) * int(pay)
print(totalpay)

My file has no length? Even though it does

def file_contents():
global file_encrypt
encryption_file = input("What is the name of the file?")
file_encrypt = open(encryption_file, 'r')
contents = file_encrypt.read()
print (contents)
ask_sure = input("Is this the file you would like to encrypt?")
if ask_sure == "no":
the_menu()
This part of the code opens the file the user enters, right? There are no real problems here.
def key_offset():
key_word = ''
count = 0
total = 0
while count < 8:
num = random.randint (33, 126)
letter = chr(num)
key_word = key_word + letter
count = count + 1
offset = ord(letter)
total = total + offset
print("Make sure you copy the key for decryption.")
if count == 8:
total = total/8
total = math.floor(total)
total = total - 32
print(key_word)
return total
This is the part where it calculates the offset and etc etc. Once again no problems here.
def encrypting():
file = file_contents()
total = key_offset()
encrypted = ''
character_number = 0
length = len(file_encrypt)
And then this is where the problem appears, I have made the variable file_encrypt global in the first block of code, so therefore it should work. I have tried calling it under another variable like file_en = file_encrypt and used file_en in the length calculating, but it keeps saying it has no length... I have tried asking friends and my teacher, but they seem clueless. The problem is that every time i get to this part it says that file_encrypt has no length or the other way I tried it, file_en has no length, something to do with TextWrapper.io.
file_encrypt is a file pointer, which does indeed not have a length. The contents of your file are in contents, but that is a variable local to the file_contents function.
Really you should not be using global variables; there isn't any reason to here. Instead, return the actual data - contents - from file_contents, then you can use it in the calling function.
There are a few issues with your code, but ignoring those for now, I think your main problems are:
1) The function "file_contents" doesn't return anything, I suspect you want to return "contents". Hard to say without knowing what you want to do with the "file" variable.
def encrypting():
file = file_contents() # <--
2) As others have said, "file_encrypt" is a pointer to a file, although in this function you didn't declare it as global, so it's probably None.
def encrypting():
file = file_contents()
total = key_offset()
encrypted = ''
character_number = 0
length = len(file_encrypt) # <--
So, these modifications should give you what you need:
def file_contents():
global file_encrypt
encryption_file = input("What is the name of the file?")
file_encrypt = open(encryption_file, 'r')
contents = file_encrypt.read()
print (contents)
ask_sure = input("Is this the file you would like to encrypt?")
if ask_sure == "no":
the_menu()
return contents # <-- ADDED
def encrypting():
contents = file_contents() # <-- MODIFIED
total = key_offset()
encrypted = ''
character_number = 0
length = len(contents) # <-- MODIFIED

python code problem

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???
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('/')
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('/')
You're using 's' before you assign something to it. Add an 's = 0' in the appropriate location.
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.
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
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
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('/')

Categories