
# Python uses the value None to indicate a nonexistent value. 
# It is similar to other languages’ null:

x = None
print x == None 	# prints True, but is not Pythonic
print x is None 	# prints True, and is Pythonic

# Python lets you use any value where it expects a Boolean!!

#  The following are all “Falsy”:

False	# Boolean constant
None	# "null"
[] 	# (an empty list)
{} 	# (an empty dict)
""	# empty string
set()	# empty set
0 	# int
0.0	# float

# Except the "falsy" things, pretty much anything else evaluates to True.

# This fact can be used to write interesting assignments....

########################################################################
# Trick 1:
#
#   Given a string s:
#     if s != empty string, assign the first character to first_char 
#     else assign "" to first_char

# Solution 1a: (traditional programming language)

if s:
    first_char = s[0]	# non-empty string s is True
else:
    first_char = ""


# Solution 1b: take advantage that:   s = "" is False
#
#    if s is "", then:   s and s[0] === False and s[0] === False
#                        s and s[0] will RETURN the FIRST value !!!
#
#    if s is "?..", then:   s and s[0] === True and s[0] === s[0]
#                           s and s[0] will RETURN s[0] !!!

first_char = s and s[0]


########################################################################
# Trick 2:
#
#   Given a numeric variable s (which can contain None !!!)
#   If s is None, we want to use 0 instead (so computation will succeed)
#

# Solution: 2a:

if s:
    safe_s = s
else:
    safe_s = 0

# Solution 2b: take advantage that:   s = None is False
#
#    if s is None, then:   s or 0 === False or 0 === 0
#                          s or 0  will RETURN 0
#
#    if s != None, then:   s or 0 === True or 0 === True
#                          s or 0 will RETURN s !!!

safe_s = s or 0


# ########################################################################
# all( )  and any( )
# 
#   all( list-of-values ) = True if all items in list-of-values are truthy
#                           (Better: no falsy element in list)
#
#   any( list-of-values ) = True if at least 1 items in list-of-values is
#                           truthy

all([True, 1, { 3 }]) 	# True
all([True, 1, {}]) 	# False, {} is falsy
any([True, 1, {}]) 	# True, True is truthy
all([]) 		# True, no falsy elements in the list
any([]) 		# False, no truthy elements in the list
