<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 "or" operator
This presentation is inspired by
Neil Ludban's use
of the "or" operator in 
Test-Driven Development with Python at 
last month's technical meeting.
split diff view of code on github
view of code on github
Step1:  Python's or
operator has some similarities with C's || operator.
Both always evaluate the first operand.
Both guarantee that the second operand is not evaluated 
if the first operand is true.
C's || operator yields an integer
Step2:  Python's concept of truthiness
Numerical values are false if zero and true if not zero.
None is false.
Sequences and collections are false if empty, and true if not empty.
Step3:  Slowly scroll through the output of the following cell,
predicting the output of each value
before scrolling to reveal the actual output.
Step4:  There was some confusion and disbelief
that True and False are integers,
so that was played with.
Some folks also did not know about
the distinction between the / and // operators in Python 3,
so that was played with also.
Step5:  Now we get to how the "or" operator was used in fizzbuzz().
Step6:  Now we get to a more serious discussion of when it is good to use
the "or" operator
where the operands are not merely
the typical case of False or True.
The short answer is
Step7:  Pete Carswell asked about doing the above long expressions with a lamdba,
hence the following.
Step8:  Note that the reduce() evaluates all the elements of its second operand,
whereas a big long multiple "or" expression
is guaranteed to stop evaluating operands after the first true operand.
Then I thought the operator module should eliminate the need for the lamdba,
so I explored the operator module.
Step9:  Unfortunately, I was not able to find an equivalent to the "or" operator.
Zach brought up another use of the "or" operator
for handling default arguments.
Step10:  It is too bad that there is not an or= operator.
C does not have a ||= operator either.
Step11:  Zach prefers his code above to code below,
with the danger of its mutable default value.
Step12:  The cell above changes the mutable default argument,
as shown below.
Step13:  Zach's version does not suffer from the mutable default argument problem.
Step14:  How can I screw up Zach's version?
It is sensitive to false arguments.
Step15:  That can be fixed with a traditional "is None" test.
Step16:  Maybe a better name for this presentation would be 'this' or 'that'.
Step17:  Zach reported that the "or" operator in Javascript works like Python.
This presentation concentrated on the "or" operator.
The "and"
operator works like you (should) expect.
Explore it on your own.
<ASSISTANT_TASK:>
Python Code:
# meld is a great visual difference program
# http://meldmerge.org/
# the following command relies on the directory structure on my computer
# tdd-demo comes from https://github.com/james-prior/tdd-demo/
!cd ~/projects/tdd-demo;git difftool -t meld -y 389df2a^ 389df2a
Explanation: "or" operator
This presentation is inspired by
Neil Ludban's use
of the "or" operator in 
Test-Driven Development with Python at 
last month's technical meeting.
split diff view of code on github
view of code on github
End of explanation
False or False
0 or False
False or 0
0 or 0
False or True
True or False
True or True
True or 1
1 or True
1 or 1
1 > 2
3 < 4
# This kind of expression using the "or" operator is very typical,
# comprising the vast majority of use.
1 > 2 or 3 < 4
'hello' or 'world'
'' or 'world'
'hello' or ''
'' or ''
'' or None
False or 3.14
'False' or 3.14
bool('False' or 3.14)
[] or {}
'' or []
'' or {}
'' or (1, 3)
'' or 'False'
'' or 'True'
'' or True
'' or False
Explanation: Python's or
operator has some similarities with C's || operator.
Both always evaluate the first operand.
Both guarantee that the second operand is not evaluated 
if the first operand is true.
C's || operator yields an integer: 0 (false) or 1 (true).
Python "or" operator yields one of the operands.
If the first operand is true, it is the result
and the second operand is guaranteed to not be evaluated.
If the first operand if false,
the second operand is evaluated and is the result.
Note that Python returns one of the operands, not merely 0 or 1.
Python's concept of truth
...
Here are most of the built-in objects considered false:
constants defined to be false: None and False.
zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
empty sequences and collections: '', (), [], {}, set(), range(0)
...
Objects that are not false are true.
constants defined to be true: True.
not zero of any numeric type: 1, -1, 0.01, 1j, Decimal(1), Fraction(-1, 1)
non-empty sequences and collections: 'hello', (0,), [0], {0: 0}, set([0]), range(1)
For each of the following cells, predict the output.
During the meeting, there was much disagreement in predictions,
especially in the first four cells below.
That led to real learning.
End of explanation
values = (
    None,
    0,
    0.0,
    0j,
    (),
    [],
    {},
    set(),
    False,
    True,
    True + True,
    (True + True + True) / True,
    1,
    -1,
    1.e-30,
    '',
    'False',
    'True',
    
    [],
    [None], # This fools many people.
    [0],
    [0.0],
    [0j],
    [1],
    [1, 2],
    [[]], # This fools many people.
    [{}],
    [()],
    [],
    
    (),
    (None,),
    (0,),
    (0.0,),
    (0j,),
    (1,),
    (1, 2),
    ([],),
    ({},),
    ((),),
    (),
    
    {},
    {None: None},
    {False: None},
    {'False': None},
    
    set(),
    {None},
    {0},
    {0.0},
    {0j},
    {1},
    {1, 2},
    {()},
)
Explanation: Python's concept of truthiness
Numerical values are false if zero and true if not zero.
None is false.
Sequences and collections are false if empty, and true if not empty.
End of explanation
for value in values:
    print(repr(value), type(value))
    print(bool(value))
    print()
Explanation: Slowly scroll through the output of the following cell,
predicting the output of each value
before scrolling to reveal the actual output.
End of explanation
True + True
True / (True + True)
True // (True + True)
Explanation: There was some confusion and disbelief
that True and False are integers,
so that was played with.
Some folks also did not know about
the distinction between the / and // operators in Python 3,
so that was played with also.
End of explanation
'' or 1
'' or 2
'fizz' or 3
'buzz' or 5
'fizz' or 6
'fizzbuzz' or 15
'' or 16
Explanation: Now we get to how the "or" operator was used in fizzbuzz().
End of explanation
False or 0 or 0j or 0.0 or [] or {} or set() or None or ()
False or 0 or 0j or 0.0 or 'false' or [] or {} or set() or None or ()
Explanation: Now we get to a more serious discussion of when it is good to use
the "or" operator
where the operands are not merely
the typical case of False or True.
The short answer is:
Use the "or" operator when it makes the code more readable.
But that begs the question.
When does using the "or" operator make the code more readable?
This is a question I have been struggling with.
Let's go back to the old code at hand.
if not output:
    return str(n)
return output
It returns either output or str(n).
When said that simply in English,
Neil's refactoring is the most readable code.
It says most simply and directly what we want.
return output or str(n)
The problem may be from the biases of experienced programmers like myself
who expect the "or" operator to yield only a true or false value,
like we expect from other languages
such as but not limited to C.
Inexperienced folks do not bring such baggage from other languages.
For myself,
I have decided to absorb and use the idiom like Neil showed us.
It is part of learning Python.
With a long string of "or"ed stuff,
the result is the first true operand.
If no operands are true, the result is the last operand.
End of explanation
from functools import reduce
a = (
    False,
    0,
    0j,
    0.0,
    [],
    {},
    'look ma no hands',
    set(),
    None,
    (),
)
reduce(lambda x, y: x or y, a)
Explanation: Pete Carswell asked about doing the above long expressions with a lamdba,
hence the following.
End of explanation
import operator
[s for s in dir(operator) if 'or' in s]
Explanation: Note that the reduce() evaluates all the elements of its second operand,
whereas a big long multiple "or" expression
is guaranteed to stop evaluating operands after the first true operand.
Then I thought the operator module should eliminate the need for the lamdba,
so I explored the operator module.
End of explanation
def foo(p=None):
    p = p or [1, 2, 3, 4]
    return p
Explanation: Unfortunately, I was not able to find an equivalent to the "or" operator.
Zach brought up another use of the "or" operator
for handling default arguments.
End of explanation
foo(5)
foo()
Explanation: It is too bad that there is not an or= operator.
C does not have a ||= operator either.
End of explanation
def foo(p=[1, 2, 3, 4]):
    return p
foo(3)
foo()
a = foo()
a[1] = 'hi mom'
a
Explanation: Zach prefers his code above to code below,
with the danger of its mutable default value.
End of explanation
foo()
Explanation: The cell above changes the mutable default argument,
as shown below.
End of explanation
def foo(p=None):
    p = p or [1, 2, 3, 4]
    return p
b = foo()
b
b[2] = 'this'
b
foo()
Explanation: Zach's version does not suffer from the mutable default argument problem.
End of explanation
foo([1])
foo([])
foo(0)
Explanation: How can I screw up Zach's version?
It is sensitive to false arguments.
End of explanation
def foo(p=None):
    if p is None:
        p = [1, 2, 3, 4]
    return p
foo()
foo(None)
foo([1])
foo([])
foo(0)
Explanation: That can be fixed with a traditional "is None" test.
End of explanation
'this' or 'that'
'give me liberty' or 'give me death'
Explanation: Maybe a better name for this presentation would be 'this' or 'that'.
End of explanation
False and 1
'False' and 1
Explanation: Zach reported that the "or" operator in Javascript works like Python.
This presentation concentrated on the "or" operator.
The "and"
operator works like you (should) expect.
Explore it on your own.
End of explanation
<END_TASK>