Why doesn't None put in variable? - python

Why doesn't None put in variable?
I wrote in code like
def check(request):
if len(request.POST.get('access_key')) >= 25:
return HttpResponse('<h1>Hello</h1>')
elif request.POST.get('access_key', None) == None:
id_json = {}
return JsonResponse(id_json, safe=False)
else:
return HttpResponse('<h1>Good</h1>')
Now I put anything to access_key in POSTMAN like
I think in this case the program goes into elif request.POST.get('access_key', None) == None:,but now it goes into else:.
I really cannot understand why the null value is not recognized as None. I wrote print(type(request.POST.get('access_key'))) and blank is printed out.
I wanna make a system if no value is put, and the program should go into elif request.POST.get('access_key', None) == None:.
How should I fix this?

The return value of request.POST.get('access_key') is '', which is not None.
Try to check for elif not request.POST.get('foo'), this will catch both cases, because both, `` and None will evaluate to False.
Actually, all three values ('', None, and False) as value will fulfill the if condition if not value:.
Have a look at this wiki page: https://en.wikipedia.org/wiki/Empty_string
In most programming languages, the empty string is distinct from a null reference (or null pointer) because a null reference does not point to any string at all..
And more precisely for Python: https://docs.python.org/2/library/constants.html
The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function.

your request.POST.get('access_key') is equal ''
so instead of
elif request.POST.get('access_key', None) == None:
try simple
elif not request.POST.get('access_key'):

Related

Is it better to use 'elif' or consecutive 'if' statements alongside return statements?

This question is specifically regarding coding convention. I know that using if or elif in this case will produce the same results. Just wondering which is the "proper" way to construct this function:
With consecutive if:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
if selectedCourse.getPrereqs() != 'none':
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
With elif:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
elif selectedCourse.getPrereqs() != 'none':
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
If I had to choose between the two, I would probably use two if statements, but that's just a matter of personal preference.
If I had a third choice, I wouldn't have any return statements with Boolean literals. I would write a single return statement that uses and and or.
return (not selected.hasPassed()
and (selected.getPrereqs() == 'none'
or all(x.hasPassed()
for x in selected.getPrereqs()))
This is close to how you would describe this in English: you can take the class if you have not passed it, and if the class either has no prerequisites or if you have passed all the prerequisites.
As John Kugelman points out, if getPrereqs returned an empty list instead of 'none', you could further reduce this to
return (not selected.hasPassed()
or all(x.hasPassed()
for x in selected.getPrereqs())
I love the early return pattern:
Get invalid cases out of the way first, either simply exiting or raising exceptions as appropriate, put a blank line in there, then add the "real" body of the method. I find it easier to read.
Returning early keeps the nesting level down, which is great way to reduce cognitive load. I would take it one step further and flip the second if statement around so it too returns early:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
if selectedCourse.getPrereqs() == 'none':
return True
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
That said, some other improvements I would make:
Avoid stringly typed variables. Switch that 'none' to None.
But then, when a method returns a list don't return None when there are no results. Return an empty list. Then the caller can blindly iterate over the list without checking if it's None or empty.
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
If you're comfortable with generator expressions you could even convert the loop into an all(...) call, removing the need for the final return True.
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
return all(self.courses[prereq].hasPassed()
for prereq in selectedCourse.getPrereqs())
I like this because it's a more direct encoding of the question: "Has the student passed all of the prereqs?"
I think I prefer the first version. Why? When you have an if...elif...elif... thing with returns in each branch, there are two "competing" control structures: the if statement and the returns. Obviously, the returns will "win", so we might as well remove the elif stuff. Either that, or have just one return statement, which returns a value computed by a preceding if...elif...elif...else structure.
We use elif but please understand it depends on your problem statement.
Note: Please do not create a big ladder out of it as then it becomes difficult to maintain and debug the code.

Is it possible to reference a variable for an if statement that may or may not yet be defined?

Trying to program an API trading algorithm- I need to check whether an order has been filled, and if it has been filled, place the new order, and if the order has not been filled or there is no order, do nothing (return). The variable that holds 'Filled' or 'Not filled' is only declared if there is an open order. I want it to basically send the order if the variable is 'Filled', and ALSO send the order if the variable is undefined, but NOT send the order if it is unfilled and undefined (no orders ever sent, ie. initial run through)...
The original problem is that it sends a second order even if the previous order is not filled yet, so I created a variable in the 'openOrders' function that shows the status of the order. But if there are no orders, the variable is undefined. So I want it to send the order if it is undefined (no orders), and send the order if the variable is 'filled'.
I had this code but the first line throws it off because it doesn't recognize none as undefined. Any suggestions?
if self.openOrderStatus == None: #<--
# SELL
elif self.openOrderStatus != 'Filled':
return
else:
# SELL
Just give openOrderStatus an initial value of None when you create the containing object. That represents a non-existent order. Then the code you show us will work as is. For example:
class SomeClass:
def __init__(self):
self.openOrderStatus = None
...
def some_method(self):
if self.openOrderStatus == None: # <-- no throw now
# SELL
...
elif self.openOrderStatus != 'Filled':
return
else:
# SELL
...
If you want to coerce attributes that don't exist to None, an easy way to do that is with getattr() with the default value filled in:
if getattr(self, 'openOrderStatus', None) == None: #<--
pass # SELL
elif getattr(self, 'openOrderStatus', None) != 'Filled':
return
else:
pass # SELL
However, it would be much better practice to initialize your objects such that every attribute you want always has a value, even if that value is None.

Clean way to write IF statements in python to skip on None?

I have a function where sometimes a parameter can be none, and I would like to compare that with another object. However, if I am trying to call an object property, my script will throw an exception on None, even if both objects are None (see example below).
def do_animals_make_same_sound(first_animal, second_animal):
if first_animal.sound = second_animal.sound:
print('Yes they do!')
But if both animals are None, it throws an exception when instead I want it to print('Yes they do!'), but it seems I have to write a really ugly If statement:
def do_animals_make_same_sound(first_animal, second_animal):
if (first_animal is None and second_animal is None) or (first_animal is not None and first_animal.sound == second_animal.sound):
print('Yes they do!')
Is there a better way to do this?
following code is clearer IMHO:
def do_animals_make_same_sound(first_animal, second_animal):
# early return if one of the two animals is missing, ensure both exist
if not (first_animal and second_animal):
return
if first_animal.sound == second_animal.sound:
print('Yes they do!')
ref: Avoid Else, Return Early
It's not great, but one approach can be to use getattr with a default, so None (and anything else without the desired attribute) behaves as if it had the default as the value of its attribute. For example:
if first_animal.sound == second_animal.sound:
can become:
if getattr(first_animal, 'sound', None) == getattr(second_animal, 'sound', None):
I don't actually recommend this, as it silently ignores errors. In real code, I'd almost always let the AttributeError propagate; there is no reasonable scenario in which I'd consider None an acceptable stand-in for "something" where "something" has specific behaviors or attributes; if the caller is passing None, that's almost certainly an error that should not be silently ignored.
I think first you have to understand what's the meaning if one of the objects is None. There are basically three scenarios:
One or both objects are None
One or both objects does not have sound attribute
Both have sound attribute
For #1, I'm assuming it should throw an error as there is really no comparison. What your code does is print "Yes they do" if both objects are None.
For #2, you can use what ShadowRanger suggests, If both objects have None as sound property, and your think it is a normal behavior, then use ShadowRanger's solution.
For #3, just do your normal comparison
def do_animals_make_same_sound(first_animal, second_animal):
if not first_animal or not second_animal:
print("One of the objects is None")
elif getattr(first_animal, 'sound', None) == getattr(second_animal, 'sound', None):
print("Yes, they do!")
If it's a general enough pattern, I'd use a decorator to catch the None case specifically and process it. That keeps the logic out of the function. But you need to define exactly what None means here... it's a little odd that you can pass None for both, but it's not legal to just pass None for one of them. In any case, a decorator is a great way to abstract out some common logic in a clean way...
def NoNone(f):
#functools.wraps(f)
def _no_none_func(*args, **kwargs):
if args[0] == None and args[1] == None:
print('Both are None')
return
return f(*args)
return _no_none_func
#NoNone
def do_animals_make_same_sound(first_animal, second_animal):
if first_animal.sound == second_animal.sound:
print('Yes they do!')
else:
print("No they don't!")

Are booleans mutable in python?

I have the following code in python:
def update(request, id):
success = 0
try:
product = Mattress.objects.get(id=id)
success = 1
except Mattress.DoesNotExist:
pass
if success == 1:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Is this code a valid way to check the "success" boolean. If the code passes through the try statement, will "success" be changed to 1 or is it remaining at 0?
Answering your question:
Are booleans mutable in python?
Yes and no. Variables that are assigned a boolean value are (probably always, and definitely in this case) mutable, yes. They're also not restricted to being assigned boolean values, as variables are not staticly typed.
But the booleans True and False themselves are not mutable. They are singletons that cannot be modified.
Looking at your actual code:
if success = 1:
Is not valid syntax, you want a == there. Also, idiomatically speaking you should not use 0 and 1 for success and failure values you should use True and False. So you should refactor to something like this:
def update(request):
success = False
try:
product = Mattress.objects.get(id=id)
success = True
except Mattress.DoesNotExist:
pass
if success:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Yes. success will be changed to 1 on success.
There are a few things wrong with this snippet.
Firstly, you're not using a boolean type. Python's booleans are True and False.
Second, you're not comparing in your if statement. That line isn't valid in Python 3. What you're looking for is: if success == 1: or if success == True:
You would still be able to assign a boolean value to a variable regardless of boolean immutability. I believe they are stored as a primitive type, so they're as immutable as any other primitive type.
You should consider using an actual boolean and not an integer. You can set success to true or false and Python will interpret them as keywords to the values of 1 and 0. Using numbers can be a bit tricky as some languages interpret things different. In some languages 0 is false but any value besides 0 is considered true. However the answer to your question is yes, it will work just fine.
Probably the question you are asking is not even related with the problem you are trying to solve. I think there is a a Pythonic way to achieve what you want by:
def update(request):
try:
product = Mattress.objects.get(id=id)
except Mattress.DoesNotExist:
template_name = 'failure.html'
else:
template_name = 'success.html'
return render_to_response(template_name)
Basically if the exception is thrown, i.e., the template you will render will be 'failure.html'. On the other hand, if the query is performed successfully, 'success.html' will be rendered.

Python: "return <tuple>" keeps returning None

I have the following code:
def subStringMatchExact(target,key,matches=(),base=0):
if find(target,key) != -1:
matches += (find(target,key)+base,)
base += find(target,key)+len(key)
subStringMatchExact(target[find(target,key)+len(key):],key,matches,base)
else:
print matches
return matches
When I run the function, say for instance subStringMatchExact('abcdabcdababcdedakcdobcdabcd','abc'), the print matches line will have my interpreter print (0,4,10,24), which is correct. However the line return matches returns value None.
Similarly when I call print subStringMatchExact('abcdabcdababcdedakcdobcdabcd','abc'), the interpreter also gives None.
Can anyone help me correct this?
I rather think that you intended to return the recursive value on line 5. As it is, it just calls it and then continues to the end of the method, returning None. So, all you need is the insertion of the return keyword.
def subStringMatchExact(target,key,matches=(),base=0):
if find(target,key) != -1:
matches += (find(target,key)+base,)
base += find(target,key)+len(key)
return subStringMatchExact(target[find(target,key)+len(key):],key,matches,base)
else:
print matches
return matches
I think you mean for the statement at the end of the if clause to say:
return subStringMatchExact(...)
The return statement beneath your print statement is indeed working — it is successfully sending the answer back up the chain to the instance of the function that called it — but then the copy of the calling function is throwing it away. Without a return in the first clause of the if statement, a None gets returned instead.

Categories