Why this is printing none after every output of print command - python-2.7

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))

Related

Use of conditional function, condition in definition

I have a seemingly trivial problem. I write a definition and I don't know how to introduce conditional functions.
I have a definition that works:
def function_1 (kot):
if kot == True:
print ("Yes:")
else:
print ("NO:")
It wokrs good
function_1 (False)
No:
or
function_1 (True)
Yes:
But I would like to have such a thing in my definition
def function_1 (kot = True):
if kot == True:
print ("Yes:")
else:
print ("NO:")
and it doesn't work any more.
Because you need to call the function as you did in the above example
def function_1 (kot=True):
if kot == True:
print ("Yes:")
else:
print ("NO:")
function_1()
output:
Yes:

python 2.7 - trying to print a string and the (printed) output of function in the same line

I have the following function defined:
def displayHand(hand):
"""
Displays the letters currently in the hand.
For example:
>>> displayHand({'a':1, 'x':2, 'l':3, 'e':1})
Should print out something like:
a x x l l l e
The order of the letters is unimportant.
hand: dictionary (string -> int)
"""
for letter in hand.keys():
for j in range(hand[letter]):
print letter, # print all on the same line
print '' # print an empty line
Now, I want to print the following:
Current hand: a b c
To do this, I try to do:
print "Current hand: ", displayHand({'a':1, 'b':1, 'c':1})
And I get:
Current hand: a b c
None
I know that None is printed cause I am calling the print function on the displayHand(hand) function, which doesn't return anything.
Is there any way to get rid of that "None" without modifying displayHand(hand)?
if you want to use your function in a print statement, it should return a string and not print something itself (and return None) - as you would do in a __str__ method of a class. something like:
def displayHand(hand):
ret = ''
for letter in hand.keys():
for j in range(hand[letter]):
ret += '{} '.format(letter) # print all on the same line
# ret += '\n'
return ret
or even
def displayHand(hand):
return ''.join(n*'{} '.format(k) for k,n in hand.items() )
When you trail a print with a ,, the next print will appear on the same line, so you should just call the two things on separate lines, as in:
def printStuff():
print "Current hand: ",
displayHand({'a':1, 'b':1, 'c':1})
Of course you could just adapt this and create a method like:
def printCurrentHand(hand):
print "Current hand: ",
displayHand(hand)
The only way to do this (or I believe the only way to do this) is to use return instead of print in your displayhand() function. Sorry if I didn't answer your question.
Your function 'displayHand' does not have to print the output,
it has to return a string.
def displayHand(hand):
mystring=''
for letter in hand.keys():
for j in range(hand[letter]):
mystring+= letter # concatenate all on the same line
return mystring
BUT, you have to check the '.keys' command help as the order of the input (a/b/c) may not be respected

python: checking for errors in the users input

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()

how to parse a boolean argument in a script?

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.

Python None if check fails

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'