I just want to check if my elif statement is correct to check for content composed entirely of white-spaces. Thanks.
def post(self):
wall_name = self.request.get('wall_name',DEFAULT_WALL)
comment_container = CommentContainer(parent = wall_key(wall_name))
comment_container.name = self.request.get('name')
comment_container.content = self.request.get('content')
if comment_container.content == '':
self.redirect("/error")
elif comment_container.content == str.isspace:
self.redirect("/error")
else:
comment_container.put()
self.redirect('/#comment_section')
The isspace() function is an instance function and also a class function -- meaning you can call it on an existing string or by passing it an argument.
For example:
>>> 'foo' == str.isspace
False
>>> 'foo' == str.isspace()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor 'isspace' of 'str' object needs an argument
>>> str.isspace(' ')
True
The first line there appears to work correctly because str.isspace does indeed not equal the string 'foo', but this is because 'foo' is a string and str.isspace is a function. We never called isspace()!
>>> str.isspace
<method 'isspace' of 'str' objects>
See? That's its actual identity.
But we can call it over an existing string:
>>> 'foo'.isspace()
False
>>> ' foo '.isspace()
False
>>> ' '.isspace()
True
>>> foo = ' '
>>> bar = ' blahblah '
>>> foo.isspace()
True
>>> bar.isspace()
False
So you need to assign the thing you want to test first (you can reference it directly, but that will be annoying to read a few months from now when you want to maintain this code):
def post(self):
content = self.request.get('content')
if content == '' or content.isspace():
self.redirect('/error')
else:
wall_name = self.request.get('wall_name',DEFAULT_WALL)
comment_container = CommentContainer(parent = wall_key(wall_name))
comment_container.name = self.request.get('name')
comment_container.content = self.request.get('content')
comment_container.put()
self.redirect('/#comment_section')
Now we've saved the work you were throwing away and checked for blank comments.
One note, you could also call change the if check to this:
if self.request.get('content') == '' or content.isspace(self.request.get('content')):
But again, I find this less obvious and clear.
str.isspace() is a method, so you would probably want to use:
elif str.isspace(comment_container.content):
or
elif isspace(comment_container.content.isspace():
Related
Im looking to create something that I can use to check if a string meets a condition like so:
var = "hello"
check = var.checkconditions()
Im just curious as to if its possible as I have never seen it done before.
How would the function/whatever I need to use be set out?
String is a build in class/object and can not be changed. However you can make a personal new class:
class str_class:
def __init__ (self, str):
self.str = str
def checkconditions(self):
# Enter your conditions
var = str_class('hello')
check = var.checkconditions()
Or you could simply make a funtion that takes the string as input and outputs if the condition is met or not:
def checkconditions(str):
# Enter conditions
var = 'Hello'
check = checkconditions(var)
Edit: From other comments it seems as though it is possible but not recommended.
You can use a Class and then use the method check_conditions.
class Check:
def __init__(self):
pass
def check_conditions(string):
#Do whatever you need in here
print(string)
c = Check
c.check_conditions("hello")
This should hopefully do what you need!
You can't directly add the method to the original type.what you can do is subclass the type like
class mystring(str):
def checkconditions(self):
#condition
and then you can instantiate your new class
var = mystring('hello')
var.checkcondition()
but that's still no too practical, if you want to make it more proper you can do this
import __builtin__
__builtin__.str = mystring
var = str("hello")
check = var.checkconditions()
which achieves most of the effect desired.
Unfortunately, objects created by literal syntax will continue to be of the vanilla type and won't have your new methods/attributes.
var = 'hello'
var.checkconditions()
# Output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'checkconditions'
"""
I m trying to filter out only valid emails addresses,but I getting the below error.
Traceback (most recent call last):
File "C:/Python27/ghhs.py", line 20, in <module>
valid=list(filter(a,email)) TypeError: 'bool' object is not callable
Here is the code:
def fun(email):
for i in email:
if ('#'and'.') in i:
user,url=i.split('#')
web,domain=url.split(".")
if user.replace('-','').replace('_','').isalnum() is False:
return False
elif web.isalnum() is False:
return False
elif len(domain)>3:
return False
else:
return True
else:
return True
if __name__=="__main__":
n=int(input())
email=[raw_input() for i in range(n)]
a=fun(email)
valid=list(filter(a,email))
valid.sort()
print (valid)
The first argument to filter should be a function that will get called for each item in the second argument, but you are calling the function first and passing in the return value. Change your filter call to something like this:
valid=list(filter(fun, email))
ETA
As pointed out in the comments below fun has some other problems. From one, since the function passed to filter gets called for each item, it shouldn't been attempting to loop over its input but just accept a single email address and not a list of addresses.
Also your initial test for characters in the address is broken. Something like this will work better:
def fun(email):
if ('#' in email) and ('.' in email):
user, url = i.split('#')
web, domain = url.split(".")
if user.replace('-','').replace('_','').isalnum() is False:
return False
elif web.isalnum() is False:
return False
elif len(domain)>3:
return False
else:
return True
But better yet, don't reinvent the wheel:
from validate_email import validate_email
valid = list(filter(validate_email, email))
I want to be able to print "hello harry" from a module. This is my module (called test23):
class tool:
def handle(self,name):
self.name = "hello " + name
This is my script:
import test23
harry= test23.tool().handle(" harry")
print harry.name
I can't seem to print "hello harry" inside my script idle. How would I go about doing this?
handle doesn't return anything, so harry will be NoneType.
Do it in two times: first assign the instance, then call the method:
>>> class tool:
... def hello(self,name):
... self.name="hello "+name
...
>>> a=tool()
>>> a.hello('i')
>>> a.name
'hello i'
>>> b=tool().hello('b')
>>> b.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'name'
>>> type(b)
<type 'NoneType'>
I think this will do it.
from test23 import tool
harry = tool()
harry.handle("harry")
print harry.name
tool.handle() doesn't return an object, so you need to store the object before you call the method:
import test23
harry = test23.tool()
harry.handle("harry")
print harry.name
What you wanted to do is:
harry = test23.tool() # Ok harry is a tool object
harry.handle(" harry") # Ok harry.name has been set to " harry"
print harry.name # Ok print successfully "hello harry"
But what you did is: harry= test23.tool().handle(" harry")
Let's look one pass at a time:
test23.tool() : builds a new (temporary) tool object
test23.tool().handle(" harry") : sets the attribute name of the temporary and returns... None!
harry= test23.tool().handle(" harry") : sets the attribute name of a temporary tool object, set harry to the return value of the handle method which is None => same as harry = None
Alternatively, you should change handle to return the tool object:
class tool:
def handle(self,name):
self.name = "hello " + name
return self
I keep getting this error
TypeError: object of type 'NoneType' has no len()
here is the code:
def main():
myList = [ ]
myList = read_csv()
## myList = showList(myList)
searchList = searchQueryForm(myList)
if len(searchList) == 0:
print("I have nothing to print")
else:
showList(searchList)
searchQueryForm apparently returns a None if it finds nothing. Since you can't apply len to None, you'll have to check for that explicitly:
if searchList is None or len(searchList) == 0:
The object which you want to get the len() from is obviously a None object.
It is the searchList, returned from searchQueryForm(myList).
So this is None when it shouldn't be.
Either fix that function or live with the fact that it can return None:
if len(searchlist or ()) == 0:
or
if not searchlist:
The searchQueryForm() function return None value and len() in-build function not accept None type argument. So Raise TypeError exception.
Demo:
>>> searchList = None
>>> print type(searchList)
<type 'NoneType'>
>>> len(searchList)
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: object of type 'NoneType' has no len()
Add one more condition in if loop to check searchList is None or not
Demo:
>>> if searchList==None or len(searchList) == 0:
... print "nNothing"
...
nNothing
return statement is missing in the searchQueryForm() function when code is not go into last if loop. By default None value is return when we not return any specific value from function.
def searchQueryForm(alist):
noforms = int(input(" how many forms do you want to search for? "))
for i in range(noforms):
searchQuery = [ ]
nofound = 0 ## no found set at 0
formname = input("pls enter a formname >> ") ## asks user for formname
formname = formname.lower() ## converts to lower case
for row in alist:
if row[1].lower() == formname: ## formname appears in row2
searchQuery.append(row) ## appends results
nofound = nofound + 1 ## increments variable
if nofound == 0:
print("there were no matches")
return searchQuery
return []
# ^^^^^^^ This was missing
I'm learning Python. I'm reading some code containing something like this:
class Menu:
'''Display a menu and respond to choices when run.'''
def __init__(self):
self.notebook = Notebook()
self.choices = {
"1": self.show_notes,
"2": self.search_notes,
"3": self.add_note,
"4": self.modify_note,
"5": self.quit
}
def display_menu(self):
print("""
Notebook Menu
1. Show all Notes
2. Search Notes
3. Add Note
4. Modify Note
5. Quit
""")
def run(self):
"""Display the menu and respond to choices."""
while True:
self.display_menu()
choice = input("Enter an option: ")
action = self.choice.get(choice)
if action:
action()
else:
print("{0} is not a valid choice".format(choice))
def show_notes(self):
pass
def search_notes(self):
pass
def add_note(self):
pass
def modify_note(self):
pass
def quit(self):
pass
There are some lines very interesting:
action = self.choice.get(choice)
if action:
action()
Seems it's creating a temporary name for a specific function.
So I did the following test for it to learn more:
>>> def show_notes():
print("show notes")
>>> def search_notes():
print("search notes")
>>> choice = {"1": show_notes, "2": search_notes}
>>> action = choice.get(1)
>>> action()
But I get the following error:
Traceback (most recent call last):
File "<pyshell#64>", line 1, in <module>
action()
TypeError: 'NoneType' object is not callable
Can someone tell me what the technique is and what principle is behind?
Functions are first class objects, and you can create additional references to them. These are just as temporary as you need to them to be, but they can be permanent too.
Your own attempt confused strings and integers however; you used 1 (an integer) where the actual key is '1' (a string). Because you used the wrong key, the dict.get() method returned a default instead, None. None is not a function object and the call fails.
Had you used the right key your code would have worked too:
>>> def show_notes():
... print("show notes")
...
>>> def search_notes():
... print("search notes")
...
>>> choice = {"1": show_notes, "2": search_notes}
>>> choice['1']
<function show_notes at 0x10b1fae18>
>>> choice['1']()
show notes
You can make use of dict.get() returning a default here too, by giving the method a better default to return:
>>> choice.get('none-such-key', search_notes)()
search notes
It seems there's an error in your test. You should be getting "1" and not 1. Getting 1 is returning None because there's nothing defined for key 1. Therefore when you call it like a function it's not valid.
To clarify, "1" is a string and 1 is an integer, which are different keys.
Example:
>>> a = {"1": "yes"}
>>> a.get(1)
>>> a.get("1")
'yes'
Example II (using function):
>>> def hello():
... print "hello"
...
>>> hello()
hello
>>> a = {"1": hello}
>>> b = a.get(1)
>>> b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
>>> b = a.get("1")
>>> b()
hello
It's not creating a random name for a function. The class method choice is selecting a function and returning it, and it is subsequently being assigned to the variable action. The function is then called by calling action, like you would any function.
Here's an example:
def foo():
print(5)
def getFunction():
return foo
x = getFunction()
x()
The output from this will be 5.
Taking a step back from all of this, you can assign any object to any variable. So consider the following example (I think this will help you understand a little bit more):
def foo():
print(5)
bar = foo
foo = 5
foo()
This will produce an error along the lines of integer objects are not callable. The way this works is that the function object contained in foo is being assigned to variable bar, and the integer 5 is being assigned to foo. The function hasn't changed, but the variable containing it has.
The very first part of defining a function def foo is letting the interpreter know that you are defining a function object and storing in the variable foo. The name and the mechanics of the function are separate.
Does this make sense?