how compare a str object with None - python-3.x

I have meet a problem, when I develop a web use python3+flask, when name has no in put, I am confused, the result is True in print
name = request.args.get('name')
if name is not None:
print('True')
else:
print('False')
I refer to python documents, "A is not B" means A and B is not same object.
And I make the following test:
print(name) #None
print(type(name)) #<class "str">
print(type(None)) #<class "NoneType">
I found the answer, but when I use the following format
if name:
print('True')
else:
print('False')
it prints True and print(name) I get None
I have to write like the following:
if name != str(None):
print('True')
else:
print('False')
I feel it a little uncomfortable when use it like this, how I can compare it in a elegant way.

Getting a string "None" as part of a request commonly happens when you return a None value as part of a previous response.
Example:
# given a variable that is passed to a jinja template as None
# instead of as an empty string
name = None
Will result in a link with "None" as a string.
<a href="/some/link?name={{ name }}>click here</a>
Instead of trying to handle for a string "None" in any given request where you expect a string, you should output the original variable as an empty string:
name = None
...
# convert Nones to empty strings right before sending to jinja
if not name:
name = ''

print(True if "None" not in name else False)
I think that's more elegant way of printing out in your case.

Related

local variable 'type' referenced before assignment

Why I'm getting this error?
local variable 'type' referenced before assignment
Code:
try:
if type(meeting.modified_date) != bool:
//code
except Exception as e:
raise ValidationError(_(str(e)))
finally:
type = None
if 1:
type = 'auto'
else:
type = 'manual'
I was think some local variable creating this error but after debugging I come to know that this if condition creating an error because of this type().
Empty values on record attributes in Odoo recordsets will always be falsy, except for number fields like float or integer. They will have the value zero and this also is falsy, but zero values can have a meaning in some contexts, so you should always think about the if conditions when checking number values.
Anyways, you can just change your if condition to
if meeting.modified_date:
, because non set date fields are falsy and set date fields are truthy.
One way to get that error.
def _something(self, meeting):
if type(meeting.modified_date) != bool:
pass
#rename it
type = "small"
Edit:
try:
if type(meeting.modified_date) != bool:
//code
except Exception as e:
raise ValidationError(_(str(e)))
finally:
#this is local variable and the fix is
record_type = None
if 1:
record_type = 'auto'
else:
record_type = 'manual'
#and later where type is used it should renamed aswell
The reason you are getting this error is because you assign the global function type to a value in your code. If you do this, then the global function type will be overwritten to be a variable even before the actual assignment in the scope of the name space. Because the python interpreter now treats type as a local variable instead of the global function it is not assigned when you try to call the global function (which is treated as a local variable).
Solution: do not assign names of global functions to variables and rename the variable "type" to something else e.g., object_type.
I mean the code example is basically provided by #Paxmees in the replies. His explanation is a bit difficult to understand. But if you want to see one:
def example_error(var):
if type(var) == bool:
pass
#this produces the error, because you overwrite global function type
type = "string"
def example_fixed(var):
if type(var) == bool:
pass
#fixed do not overwrite global function type:
type_of_var = "string"

How to print class variables in a list

So I am very new to coding and started with python, I am trying to build a class in a program that puts together a DnD party by randomising their attributes. So far I can get the program to initialise instances of the party members and just give the user a prompt on how many of the hero's to choose from they would like in their party. My issue is that after setting the lists up and getting everything in place. I am unable to print any of the attributes of the individual heros. Regardless of whether I am calling them from within the lists or if I am directly trying to print them. I have tried using __str__ to create strings of the attributes but I am clearly missing something. Any help would be greatly appreciated.
import random
class Party:
def __init__(self, name="", race="", alignment="", class_=""):
self.name = name
while name == "":
name = random.choice(names)
# print(name)
self.race = race
while race == "":
race = random.choice(races)
# print(race)
self.alignment = alignment
while alignment == "":
alignment = random.choice(alignments)
# print(alignment)
self.class_ = class_
while class_ == "":
class_ = random.choice(classes)
# print(class_)
def character_stats(self):
return "{} - {} - {} - {}".format(self.name, self.race, self.class_, self.alignment)
Each attribute pulls a random value from a list. My format statement is the latest attempt to get the values of the attributes to print rather than the object/attributes instead.
I apologise if any of the terminology is wrong, very very new to this
You are not assigning anything else but the input, (in this case being an empty string "" to the attribuytes. In your minimal example you have this constructor:
class Party:
def __init__(self, name=""):
self.name = name
while name == "":
name = random.choice(names)
After you randomly assign a new name from names, you should assign it to self, otherwise the local variable just goes out of scope when the __init__ method finishes. This code snippet should work:
class Party:
def __init__(self, name=""):
while name == "":
name = random.choice(names)
# Now we assign the local variable as
# an attribute
self.name = name

Python3 verify if List Items are contained in read() result

I want to verify if Items from a List are contained in what i fetch by using string.read().
How do I do this:
if string.find(lisst):
do_whatever()
elif string.find(lisst2):
do_something_else()
Example is pretty basic, but that's all I want to do. I keep getting invalid syntax error. :(
def verify(text):
lisst = ['awesome','failed','trolling']
lisst2 = ['boring','bad']
s = requests.get(text)
t = s.read()
if t.find(lisst):
print("Someone was awesome, failing or trolling!")
elif t.find(lisst2)
print("Something retarded happened")
error is thrown at elif t.find(lisst2), so I need a workaround.
elif any(n in t for n in lisst2):
^
SyntaxError: invalid syntax
Thank you in advance!
If I understood correctly, you want to do something in an if block if a string contains any the elements of a list.
if any(str in aVeryLongStringData for str in myList):
doStuff()
If you want to check if your data contains all of the elements on your list, you can just change "any" to "all"
if all(str in aVeryLongStringData for str in myList):
doStuff()

How to have two outputs in a def

I can't add two output to def function.
I have tried many ways but it always outputs only one of them if true or false.
loan_True = True
loan_False = False
def message():
if loan_True == True:
print()
message = f"""\
Subject: Loan Application
Hello {Fn} {Ln}, {hurray}
"""
elif loan_False == False:
print()
message = f"""\
Subject: Loan Application
Hello {Fn} {Ln}, {sorry}
"""
return message
message()
Output of code that is correct and exactly what i wantThis is the email the code sends but its wrong. i want the output in the email to be the same exact in the first pic.
I want the output to be what it is assigned.
I would propose something like
def message(loan_allowed):
if loan_allowed:
return "hooray"
else
return "sorry"
I.e. use function parameters instead of global variables. If you want to use a variable in the function I would use
def message(loan_allowed):
text = None
if loan_allowed:
text = "hooray"
else
text = "sorry"
return text
I.e. first set it in function scope. And use a different name than the function.

It asks to give the values but instead of giving an answer. It is giving me None

Here I created a module.
class Employee:
def __init__(self):
self.name = input("Enter your name: ")
self.account_number = int(input("Enter your account number: "))
def withdraw(self): # it receives values from for
if withdraw1 > current_balance:
print ("You have entered a wrong number: ")
else:
print ("The current balance is: ", current_balance - withdraw1)
import TASK2 # I am importing the module I created
c = TASK2.Employee()
def for(self):
c.withdraw1 = int(input("enter number: "))
c.current_balance = int(input("Enter the current balance: "))
d = method(c.withdraw) # here I am trying to pass the values to withdraw
print (d)
The problem I get is that although it asks for the values instead of giving me an answer it gives me None.
Here's my take on your code.
# TASK2.py
class Employee:
def __init__(self):
self.name = input("Enter your name: ")
self.account_number = int(input("Enter your account number: "))
# make sure you initialise your member variables!
self.withdraw_val = 0 # withdraw1 is ambiguous, so I use withdraw_val instead
self.current_balance = 0
# receives values from for ### no it doesn't, right now, it GIVES values TO your "for" function
def withdraw(self):
if self.withdraw_val > self.current_balance: # remember to use "self." to
# access members within the class
print ("You have entered a wrong number: ")
else:
# again, remember "self."
print ("The current balance is: ", self.current_balance - self.withdraw_val)
# TASK2sub.py
import TASK2
c = TASK2.Employee()
def for_employee(employee): # (1) don't use "self" outside a class
# it's contextually unconventional
# (2) "for" is a keyword in Python, don't use it for naming
# variables/functions, it'll mess things up
employee.withdraw_val = int(input("Enter value to withdraw: "))
employee.current_balance = int(input("Enter the current balance: "))
return employee.withdraw_val # not entirely sure what you want to return
# but you should definitely return something
# if you're going to assign it to some variable
d = for_employee(c.withdraw()) # "for_employee" function needs a return statement
# ".withdraw()" method should also require a return statement
print(d)
Note: I'll be referring to your original for function as for_employee from now on. Also note that I'm still hazy about what you're trying to accomplish and that there is most probably a more suitable name for it.
Since your original for_employee function didn't return anything, it returns None by default. (This explains the output you saw.)
I think you're misunderstanding how functions work in general. For example,
d = for_employee(c.withdraw())
print(d)
Your comment for the .withdraw() method is inaccurate.
"it receives values from for"
More accurately, c.withdraw() will first be computed, then whatever it returns is passed into the for_employee function as a parameter. Instead of "receiving values from", the withdraw method "gives values to" the for_employee function.
Something more reasonable would be
c.withdraw() # on a line by itself, since it doesn't return anything
d = for_employee(c) # pass the entire object, since you'll be using self.withdraw_val and whatnot
print(d)
Another issue is with conventional naming. This is what I get from the IDLE (with Python 3.7) when defining a function named for
>>> def for(a): return a
SyntaxError: invalid syntax
Again, for is a keyword in Python, don't use it for naming your variables, functions, or classes.
With self, it's less severe (but I could see that it's confusing you). self is more of a convention used in class methods. But for_employee isn't a class method. So conventionally speaking, the parameter shouldn't be named self.
(I find the code spaghetti-ish, it might benefit if you refactor the code by moving the for_employee method into the class itself. Then it would completely make sense to use self.)

Resources