exception handling with NameError - python

I want to append new input to list SESSION_U without erasing its content. I try this:
...
try:
SESSION_U.append(UNIQUES)
except NameError:
SESSION_U = []
SESSION_U.append(UNIQUES)
...
I would think that at first try I would get the NameError and SESSION_U list would be created and appended; the second time try would work. But it does not. Do you know why? If this is not clear let me know and I will post the script. Thanks.
Edit
# save string s submitted from form to list K:
K = []
s = self.request.get('sentence')
K.append(s)
# clean up K and create 2 new lists with unique items only and find their frequency
K = K[0].split('\r\n')
UNIQUES = f2(K)
COUNTS = lcount(K, UNIQUES)
# append UNIQUES and COUNTS TO session lists.
# Session lists should not be initialized with each new submission
SESSION_U.append(UNIQUES)
SESSION_C.append(COUNTS)
If I put SESSION_U and SESSION_C after K = [] their content is erased with each submission; if not; I get NameError. I am looking for help about the standard way to handle this situation. Thank you. (I am working Google App Engine)

It appears that the code you posted is probably contained within a request handler. What are your requirements regarding this SESSION_U list? Clearly you want it to be preserved across requests, but there are several ways to do this and the best choice depends on your requirements.
I suspect you want to store SESSION_U in the datastore. You will need to use a transaction to atomically update the list (since multiple requests may try to simultaneously update it). Storing SESSION_U in the datastore makes it durable (i.e., it will persist across requests).
Alternatively, you could use memcache if you aren't worried about losing the list periodically. You could even store the list in a global variable (due to app caching, it will be maintained between requests to a particular instance and will be lost when the instance terminates).

Related

how to compare two lists in different functions in Python?

I am making a Django web Application and i am facing a problem in comparing two different lists in different functions
def test(request,slug):
n=request.user
choice=TestOptions.objects.filter(choice=slug).first()
que=questions.objects.filter(Subject=choice)
question=[]
un=['a','b','c','d','e']
for q in que:
if q not in question:
question.append(q)
else:
continue
sampling = random.sample(question, 5)
print("--------------SamPLING111")
print(sampling)
print("--------------SamPLING111")
correctAnswers=[]
for j in sampling:
correctAnswers.append(j.answer)
marks(correctAnswers)
d = dict(zip(un,sampling))
return render(request,"code/test.html",{'questions':d})
def acceptAnswer(request):
answers=[]
if request.method=="POST":
answers.append(request.POST['a'])
answers.append(request.POST['b'])
answers.append(request.POST['c'])
answers.append(request.POST['d'])
answers.append(request.POST['e'])
score(answers)
return render(request,"code/dub.html")
def marks(correct):
list1=[]
l1=correct
def score(and):
list2=[]
l2=ans
function test is passing a list and function acceptAnswer is passing another list my job is to compare those two lists
how can I compare l1 and l2?
I am not 100 percent what you are trying to do with these lists, but in order to compare them I would just return them. Here is a quick example:
def marks(correct):
list1 = []
l1 = correct
return l1
def score(answer):
list2 = []
l2 = answer
return l2
numbers = [1,2,3]
numbers2 = [1,2,3]
numbers3 = [3,4,5]
print(marks(numbers) == score(numbers2)) # True
print(marks(numbers2) == score(numbers3)) # False
Hopefully this helps!
Rather than continue with comments I figured I'd elaborate in an answer though it isn't an exact answer to your question I think it is the real answer.
You really have two issues. One is a design issue ie how to make your program work correctly and the other is an implementation issue about the scope of variables and how to deal with it.
I can see in your profile you're a university student and given the nature of the code it seems very likely you're writing your web app for the purposes of learning maybe even an assignment.
If you were doing this outside of a university I'd expect you were seeking practitioner type skills in which case I'd suggest the answer would be to design your application the way Django expects you to, which I would say would translate into storing state information in a database.
If this is a lab however you may not have covered databases yet. Labs sometimes have students doing silly things because they can't teach everything at the same time. So your Prof may not expect you to use a database yet.
Inside a web application you have to consider that the web is request response and that you can get requests from a lot of different sources so you have state management concerns that classical desktop applications don't have. Who is supposed to see these tests and who is supposed to see the marks and what is the order these things happen? Should anyone be able to create a test? Should anyone be able to take a test? You might not care yet, eventually you'll want to care about sessions. If people are taking their own tests you could store data in a user session but then other people wouldn't see those tests. Generally the correct way to store this sort of state is in a database where you can access it according to what you know about the current request. If this is some sort of basic intro app your Prof may be happy with you doing something kludgy for now.

Mis-arranged dictionary pairs when host on Flask

When I print the dictionary in the interpreter, it works as desired, but when I use it as Flask API return value the dictionary becomes a mess, all key-value pairs are mis-organized.
Not desired JSON data (got this on Flask API) - https://pastebin.com/jrfLMVNg
Desired JSON data (got this on interpreter) - https://pastebin.com/cDJnah07
Probably the faulty code:
def dataPacker(self,*datas):
for data in datas:
if type(data) == dict:
for key,value in data.items():
self.returnDataJson[key] = value
else:
raise Exception('dict object expected')
def dataCollector(self):
with concurrent.futures.ThreadPoolExecutor() as executor:
details_ = executor.submit(self.dataPacker,self.details)
audiolink_ = executor.submit(self.dataPacker,self.audiolink)
videolink_ = executor.submit(self.dataPacker,self.videolink)
lyrics_ = executor.submit(self.dataPacker,self.lyrics)
return self.returnDataJson
Is this because of threading? But why does it work fine on Interpreter?
So the problem is that the items in the wrong order, but each key has the right value?
You don't say which version of Python this is; older versions didn't keep items in order (it was arbitrary), and Flask may be deliberately making it random as well as arbitrary in order to protect against attacks.
If it comes to that, the order of items in a JSON dictionary (object) is defined to be unimportant, so you shouldn't rely on it if you can at all help it.
Threading will indeed make the order potentially interleaved. If you need to rely on the order, you'll need to put in some mechanism to guarantee it; currently it's just chance whether it ends up in the order you want or in some other order.
I found Cliff Kerr's Answer to this question
helpful. I just added app.config['JSON_SORT_KEYS'] = False to my code and now it doesn't sort it alphabetically and keeps the dict ordered.

How to increment QLineEdit name to access value?

This seems like a really simple question, but has me stumped. I've got a UI that has multiple QLineEdits for names, start, and end times. For example:
clipName1, clipStart1, clipEnd1
clipName2, clipStart2, clipEnd2
clipName2, clipStart3, clipEnd3
These are not dynamically built on the fly. They are static. I wish to access the values from these by going through a loop. I am not sure how I can append an integer onto the variable name and still be able to access the value. I've tried this which I know doesn't work:
clipTotal = 4
for i in range(1, clipTotal+1):
clipName = self.clipName+str(i)+.text()
Answer provided by ekhumoro in comments above:
clipName = getattr(self, 'clipName%d' % i).text()

Idiomatic/fast Django ORM check for existence on mysql/postgres

If I want to check for the existence and if possible retrieve an object, which of the following methods is faster? More idiomatic? And why? If not either of the two examples I list, how else would one go about doing this?
if Object.objects.get(**kwargs).exists():
my_object = Object.objects.get(**kwargs)
my_object = Object.objects.filter(**kwargs)
if my_object:
my_object = my_object[0]
If relevant, I care about mysql and postgres for this.
Why not do this in a try/except block to avoid the multiple queries / query then an if?
try:
obj = Object.objects.get(**kwargs)
except Object.DoesNotExist:
pass
Just add your else logic under the except.
django provides a pretty good overview of exists
Using your first example it will do the query two times, according to the documentation:
if some_queryset has not yet been evaluated, but you
know that it will be at some point, then using some_queryset.exists()
will do more overall work (one query for the existence check plus an
extra one to later retrieve the results) than simply using
bool(some_queryset), which retrieves the results and then checks if
any were returned.
So if you're going to be using the object, after checking for existance, the docs suggest just using it and forcing evaluation 1 time using
if my_object:
pass

Django page hit counter concurrency

Im a django newbie. Im making a crude hit counter as an assignment for a course in web programming at Uni. I made a class HitCount:
from django.db import models
# Create your models here.
class HitCount(models.Model):
count = models.IntegerField()
And then I use this code in the views file:
def index(request):
#try getting a hitcounter, if there is none, create one
try:
hc = HitCount.objects.get(pk=1)
except:
hc = HitCount(count=0)
hc.save()
pass
#get a queryset containing our counter
hc = HitCount.objects.filter(pk=1)
#increment its count and update it in db
hc.update(count=F('count')+1)
#ATM hc is a queryset, so hc.count will just return how many
#counters are in the queryset (1). So we have to get the
#actual counter object
hc = HitCount.objects.get(pk=1)
#and return its count
return render_to_response('hitcount/index.html', {'count': hc.count})
This is my index.html file:
<p>{{count}}</p>
This seems to work just fine, but I wonder:
Is this a reasonable way of doing this? Should the code for incrementation really reside in the views file? Or should I move it into a method in the class?
Is this concurrency safe or do I need to use some kind of lock? Part of the assignment is making the counter concurrency safe. I use SQLite, which uses transactions, so I figured it should be all right, but I may be missing something.
Off topic, but you should be catching HitCount.DoesNotExist in your try/except, since you really only want to execute the code in the except if the HitCount object doesn't exist yet.
If it's possible, you might want to look at something like Redis (or another key/val store) to do your hit counter.
Redis provides a method called INCR that will automatically increment a value by 1. It's super fast and a great solution for a hit counter like this. All you need to do is make a key that is related to the page and you can increment that by +1.
It might also make more sense to use a middleware class to track page hits. Much easier than adding it to every view. If you need to display this count on every page, you can use a context processor (more info) to add the page's hit count into the context. There will be less code repetition this way.
Edit
I initially missed that this was for a Uni project, so this might be heavily over engineering for what you need. However, if you were to ever build a hit counter for a production environment, this is what I'd recommend. You can still use the middleware/context processors to do the hit counts/retrieval in a DRY manner.
Locking is possible in python using the following:
lock = Lock()
lock.acquire()
try:
... access shared resource
finally:
lock.release() # release lock, no matter what
Keep in mind that method is not safe in a multi-server environment though.
You could also create a more extensible 'logging' solution that tracks each hit as a row in the db with associated info, and then be able to count/query even at a particular date range.
You could create a new database row for each hit and call HitCount.objects.count() to get the count.

Categories

Resources