The following function and usage examples illustrate exactly what I need with this usage:
test([{True | False}]):
>>> def test(arg=True):
... if arg:
... print "argument is true"
... else:
... print "argument is false"
...
>>> test()
argument is true
>>> test(True)
argument is true
>>> test(False)
argument is false
>>> test(1)
argument is true
>>> test(0)
argument is false
>>> test("foo")
argument is true
>>> test("")
argument is false
>>>
Now I want exactly the same usage and behaviour but with command-line parsing, i.e. with this usage:
python test [{True | False}]
So I am trying to sort out how to do it with something like this:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-arg",
help="I want the usage to be [{True | False}] (defaults to True)")
arg = parser.parse_args().arg
if arg:
print "argument is true"
else:
print "argument is false"
But I can't figure it out. I tried all sorts of options and combinations of options among which action="store_true", default=True, choices=[True, False], type=bool but nothing works as I would like, e.g.:
$ python test.py -h
usage: test.py [-h] [-arg ARG]
optional arguments:
-h, --help show this help message and exit
-arg ARG I want the usage to be [{True | False}] (defaults to True)
$ python test.py
argument is true
$ python test.py True
usage: test.py [-h] [-arg ARG]
test.py: error: unrecognized arguments: True
etc.
Thanks for any help.
Find or write a function that parses strings like 'True', 'False'. For example
http://www.noah.org/wiki/Python_notes#Parse_Boolean_strings
def ParseBoolean (b):
# ...
if len(b) < 1:
raise ValueError ('Cannot parse empty string into boolean.')
b = b[0].lower()
if b == 't' or b == 'y' or b == '1':
return True
if b == 'f' or b == 'n' or b == '0':
return False
raise ValueError ('Cannot parse string into boolean.')
Think of this as the boolean equivalent of int() and float() Then just use it as the argument type
p.add_argument('foo',type=ParseBoolean)
bool() doesn't work because the only string it interprets as False is ''.
If you give the parameter a name that starts with "-" it will become a flag parameter. As you can see from the "usage" it excepts it to be called test.py -arg True
If you do not want to put -arg before the argument itself you should name it just arg, so it will become a positional argument.
Reference: http://docs.python.org/dev/library/argparse.html#name-or-flags
Also it by default will convert the parameters into strings. So if arg: does not work. The result would be the same as if you called if "foo":.
If you want to be able to type True or False on the command line you will probably want to keep them as strings and use if arg == "True". Argparse supports boolean arguments, but as far as I know they only support the form: test.py --arg results in arg=true, while just test.py will result in arg=false
Reference: http://docs.python.org/dev/library/argparse.html#type
Thanks to varesa who put me on the way I could find this solution:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("arg",
nargs="?",
default="True",
help="I want the usage to be [{True | False}] (defaults to True)")
arg = parser.parse_args().arg
if arg == "True":
arg = True
elif arg == "False":
arg = False
else:
try:
arg = float(arg)
if arg == 0.:
arg = True
else:
arg = False
except:
if len(arg) > 0:
arg = True
else:
arg = False
if arg:
print "argument is true"
else:
print "argument is false"
However it seems to me quite complicated. Am I dumb (I am new to Python) or could there be a more simple, more straightforward, more elegant way of doing this? A way that would be close to the very straightforward way that a function handles it, as shown in the original posting.
Related
I have below code gives me ValueError when input is left blank
U = find_lastuid() # Return variable from other function
uidnum = int(raw_input("What is uid number? (default is: %s)" % U))
if not uidnum:
print("defualt uid is used: %s" % uidnum)
else:
print("UID is %s" % uidnum)
uidnum = int(raw_input("What is uid number? (default is: %s)" % U))
ValueError: invalid literal for int() with base 10: ''
Can someone tell what is wrong with this code?
I can see similar code works in REPL
>>> id = 234
>>> a = raw_input("Enter id")
Enter id
>>> if not id:
... print(id is blank)
... else:
... print(id)
...
234
This is because you cannot convert an empty string to an int, what you could do, however is use a try and except block to handle this:
try:
uidnum = int(raw_input("Enter uid:"))
except ValueError:
print("Please enter a number!")
I have to write a function that validates a password and returns true or false. It is only true if it is 8 characters, contains a number, a upper case letter, and a symbol.
This is what I have for my function file.
def validatepassword(pswd):
for char in pswd:
if char in '01234567890':
containsnumber = True
I have no idea how to incorporate the other variables, any help is appreciated.
Thanks
def validatepassword(pswd):
## Declare the flags and set them to False
containsNumber = False
containsUpper = False
containsSymbol = False
for char in pswd: ## Loop through the characters of the password
if char in '0123456789': ## Check if the character's a number
containsNumber = True
elif char in "ABCEDFGHIJKLMNOPQRSTUVWXYZ": ## Otherwise check if the character's an uppercase letter
containsUpper = True
elif char not in "0123456789ABCEDFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz": ## Otherwise check if the letter isn't an alphanumeric character (i.e. a symbol)
containsSymbol = True
if containsNumber and containsUpper and containsSymbol and len(pswd) == 8: ## Were all of the checks passed?
return True
return False ## No need for an 'else' as the program will only reach this stage if it hasn't returned anything yet
Use regular expression and check the password matching as below in python.
Check python documentation for more help https://docs.python.org/2/howto/regex.html
import re
def validatePassword(pswd):
P=re.compile('[\d\D]')
if(P.match(pswd)):
print('TRUE')
else:
print('FALSE')
validatePassword('super')
def earlier_semester(w1,w2):
if w1[1]<w2[1] or w1[0]=="Fall":
print "True"
else:
print "False"
A = ('spring',2015)
B = ('spring',2014)
C = ('Fall',2015)
D = ('Fall',2014)
print earlier_semester(A,B)
print earlier_semester(D,A)
print earlier_semester(A,C)
Getting answer and then None on the next line like:
False
None
True
None
The command print earlier_semester(A,B) calls the function earlier_semester with the arguments A,B and prints what that function returns. It returns, by default, None. Therefore None prints.
Let's demonstrate this. First, let's define a very simple function:
>>> def somefn():
... print "Hi"
...
Let's run the function:
>>> somefn2()
'Hi'
Now, let's print the function:
>>> print somefn()
Hi
None
The problem is that somefn has no explicit return statement. That means, by default, it returns None.
Let's try this again with a return statment:
>>> def somefn2():
... return "Hi"
...
>>> somefn2()
'Hi'
>>> print somefn2()
Hi
It no longer prints None.
You should use return inside the function instead of print. something like the below:
def earlier_semester(w1,w2):
if w1[1]<w2[1] or w1[0]=="Fall":
return "True"
else:
return "False"
If you no return at the end of function, you got None default value!
You don't need to type print("True") or print("False") for python to print out True/False.
Just type:
return True
return False
Python will automatically print out 'True' and 'False' values.
If you use your method, you're not defining what the function returns when the condition evaluates. The reason for this is because Python Functions work in a way so that it has to return "something".
So it does what you tell it to it:
Print "True" or Print "False"
Then prints out "None" after each function call.
Refer to amended code below:
def earlier_semester(w1,w2):
if w1[1]<w2[1] or w1[0]=="Fall":
return True
else:
return False
A = ('spring',2015)
B = ('spring',2014)
C = ('Fall',2015)
D = ('Fall',2014)
print(earlier_semester(A,B))
print(earlier_semester(D,A))
print(earlier_semester(A,C))
I would like
to check if a string can be a float before I attempt to convert it to a float. This way, if the
string is not float, we can print an error message and exit instead of crashing the
program.
so when the user inputs something, I wanna see if its a float so it will print "true" if its not then it will print"false" rather than crashing. I don't want to use built in functions for this. I need to make my own function for this.
I tried :
import types
def isFloat():
x = raw_input("Enter: ")
if(x) == float:
print("true")
if(x) == str:
print("false")
isFloat()
I don't know if its true or not but it wont work it wont print anything either
The recommended thing to do here is to try it:
try:
f = float(x)
print("true")
except ValueError:
# handle error here
print("false")
This underscores the Python philosophy "It's better to ask for forgiveness than for permission".
The only reliable way to figure out whether a string represents a float is to try to convert it. You could check first and convert then, but why should you? You'd do it twice, without need.
Consider this code:
def read_float():
"""
return a floating-point number, or None
"""
while True:
s = raw_input('Enter a float: ').strip()
if not s:
return None
try:
return float(s)
except ValueError:
print 'Not a valid number: %r' % s
num = read_float()
while num is not None:
... do something ...
print 'Try again?'
num = read_float()
def myFunc( str ):
print "str=", str
if str == None:
print "str is None"
else:
print "str is not None, value is:", str
This function is called multiple times in my app with str being None. However sometimes, although str is None, the test fails and it prints:
str=None
str is not None, value is None
How can this happen ?
The string 'None' and the bytestring b'None' will both print out None, but not actually be none. Also, you can have custom classes which override their __str__ methods to return 'None', although they're actually not None.
Some aesthetic notes: Python guarantees that there'll only ever be one instance of None, so you should use is instead of ==. Also, you should not name your variable str, as that's the name of a built-in.
Try this definition:
def myFunc(s):
if s is None:
print('str is None')
else:
print('str is not None, it is %r of type %s' % (s, type(s).__name__))
Check the value of str again. If your test fails then str is not the special None object. Presumably str is in fact the string 'None'.
>>> str = None
>>> str == None
True
>>> str = 'None'
>>> str == None
False
>>> print str
None
Judging from your comments, str is actually u'None' which is a string of type unicode. You can test for that like this:
>>> s = unicode('None')
>>> s
u'None'
>>> print s
None
>>> s == 'None'
True
Now, whilst you could do that, I suspect that your problem lies elsewhere. The calling code must be converting this object to a string, for example with unicode(None). It would most likely be better is the calling code only converted to string if the object is not None.
Is it possible that str is bound to the string object "None" by any chance?
I would recommend using if str is None instead of ==. Not to mention, you really shouldn't be using str as a variable name.
You could also use the __repr__ method to show the value:
>>> x = None
>>> print 'the value of x is', x.__repr__()
the value of x is None
>>> x = "None"
>>> print 'the value of x is', x.__repr__()
the value of x is 'None'