By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,968 Members | 1,691 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,968 IT Pros & Developers. It's quick & easy.

returning True, False or None

P: n/a
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?

STeVe
Jul 18 '05 #1
Share this Question
Share on Google+
35 Replies


P: n/a
Steven Bethard <st************@gmail.com> wrote:
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?


What about...:

for val in lst:
if val is not None:
return val
return None

or the somewhat fancy/clever:

for val in (x for x in lst if x is not None):
return val
return None
Alex
Jul 18 '05 #2

P: n/a
"Steven Bethard"
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False. . . . Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?

return max(lst)
Raymond Hettinger
Jul 18 '05 #3

P: n/a
On Fri, 04 Feb 2005 10:48:44 -0700, Steven Bethard wrote:
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None


Yes, I see the smell, you are searching the list multiple times. You
could bail out when you can:

seenFalse = False
for item in list:
if item: return True
if item is False: seenFalse = True
if seenFalse:
return False
return None

But I'd submit that if four item lists are your common case, that your
original code is significantly easier to understand what it is doing. This
can be alleviated with an appropriate comment on the chunk of code I gave
you, though.

Jul 18 '05 #4

P: n/a
Steven Bethard wrote:
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?

STeVe


That code looks like a pretty solid implementation of the spec to me.
There isn't a strict need for the last else, of course, which may be the
smell you detect.

If you wanted to get clever you could write something like

for i in True, False:
if i in lst:
return i
return False

but frankly I think that's more obscure, and saves you pretty much nothing.

regards
Steve
--
Meet the Python developers and your c.l.py favorites March 23-25
Come to PyCon DC 2005 http://www.pycon.org/
Steve Holden http://www.holdenweb.com/
Jul 18 '05 #5

P: n/a
Steven Bethard wrote:
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?

STeVe


max(lst) ;-)

Michael
Jul 18 '05 #6

P: n/a
Raymond Hettinger wrote:
"Steven Bethard"
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.


. . .
Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?

return max(lst)


Very clever! Thanks!

Steve
Jul 18 '05 #7

P: n/a
Steven Bethard wrote:
I have lists containing values that are all either True, False or
None, e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.


Try:
max(lst)


Mick.
Jul 18 '05 #8

P: n/a
Alex Martelli said unto the world upon 2005-02-04 13:02:
Steven Bethard <st************@gmail.com> wrote:

I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:
<SNIP OP's code>
This has a light code smell for me though -- can anyone see a simpler
way of writing this?

What about...:

for val in lst:
if val is not None:
return val
return None

or the somewhat fancy/clever:

for val in (x for x in lst if x is not None):
return val
return None
Alex


These don't do what the OP desired.

..>>> test_case = [False, True, True, True ]
..>>> def alexs_funct(lst):
.. for val in lst:
.. if val is not None:
.. return val
.. return None
alexs_funct(test_case)

False

But, by the 'spec', it ought return True.

Best,

Brian vdB
A mere newbie, quite pleased with himself for finding a problem with
'bot code -- next scheduled to occur mid 2011 :-)

Jul 18 '05 #9

P: n/a
Steven Bethard wrote:
return max(lst)


Very clever! Thanks!


too clever. boolean > None isn't guaranteed by the language specification:

http://docs.python.org/ref/comparisons.html

"... objects of different types always compare unequal, and are ordered consistently
but arbitrarily. /.../ In the future, the comparison rules for objects of different types are
likely to change. ..."

</F>

Jul 18 '05 #10

P: n/a
Steven Bethard wrote:
I have lists containing values that are all either True, False or None,
e.g.:

[True, None, None, False]
[None, False, False, None ]
[False, True, True, True ]
etc.

For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

Right now, my code looks like:

if True in lst:
return True
elif False in lst:
return False
else:
return None

This has a light code smell for me though -- can anyone see a simpler
way of writing this?


An attempt to short-circuit if possible:

def tristate(iterable):
it = iter(iterable)
for item in it:
if item is not None:
return item or True in it

Not as elegant as max(), but makes me wonder whether a max() that accepts an
additional upper_bound argument and returns upper_bound as soon as it
encounters a value >= upper_bound would be worth the effort.

Peter

Jul 18 '05 #11

P: n/a
Fredrik Lundh wrote:
Steven Bethard wrote:
Raymond Hettinger wrote:

return max(lst)


Very clever! Thanks!


too clever. boolean > None isn't guaranteed by the language specification:


Yup. I thought about mentioning that for anyone who wasn't involved in
the previous thread discussing this behavior, but I was too lazy. ;)
Thanks for pointing it out again.

This implementation detail was added in Python 2.1a1, with the following
note[1]:

"The outcome of comparing non-numeric objects of different types is
not defined by the language, other than that it's arbitrary but
consistent (see the Reference Manual). An implementation detail changed
in 2.1a1 such that None now compares less than any other object. Code
relying on this new behavior (like code that relied on the previous
behavior) does so at its own risk."

Steve

[1] http://www.python.org/2.1/NEWS.txt
Jul 18 '05 #12

P: n/a
Jeremy Bowers wrote:
On Fri, 04 Feb 2005 10:48:44 -0700, Steven Bethard wrote:
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.


Yes, I see the smell, you are searching the list multiple times. You
could bail out when you can:

seenFalse = False
for item in list:
if item: return True
if item is False: seenFalse = True
if seenFalse:
return False
return None


I'd modify this approach slightly...

def tfn(lst):
answer = None
for item in lst:
if item is True: return True
if item is False: answer = False
return answer

But yeah, the original, straightforward way is probably enough clearer
that I wouldn't bother with anything else unless lists might be long
enough for performance to matter.

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #13

P: n/a
"Steven Bethard"
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.


One more approach, just for grins:

s = set(lst)
return True in s or s == set([None]) and None
Raymond Hettinger
Jul 18 '05 #14

P: n/a
I'm seeing a consistent problem in most of these approaches.
Verbalized, the logic of the OP's original code reads as such:

If True is in the list *at all*, return True.
Otherwise, if False is in the list *at all*, return False.
Otherwise, return None.

So if we used Alex Martelli's code:
for val in lst:
if val is not None:
return val
return None


and the list was:

[ False , False , True , None ]

False would be returned upon inspection of the first index, even
though True was in fact in the list. The same is true of the code of
Jeremy Bowers, Steve Juranich, and Jeff Shannon. As for Raymond
Hettinger, I can't even be sure ;)

The original OP's code, on the other hand, inadvertently searches
through the list twice where once would have sufficed, causing a
needless performance pitfall. The following applies the OP's initial
logic while only iterating once:
def boolhunt( items ): falseExists = False
for item in items:
if item is True:
return True
elif item is False and not falseExists:
falseExists = True
if falseExists:
return False l1 = [ True , None , None , False ]
l2 = [ None , False , False , None ]
l3 = [ False , True , True , True ]
boolhunt( l1 ) True boolhunt( l2 ) False boolhunt( l3 )

True

It isn't elegant or clever, but it gets the job done :)

--
Daniel Bickett
dbickett at gmail.com
http://heureusement.org/
Jul 18 '05 #15

P: n/a
On Fri, 04 Feb 2005 16:44:48 -0500, Daniel Bickett wrote:
[ False , False , True , None ]

False would be returned upon inspection of the first index, even
though True was in fact in the list. The same is true of the code of
Jeremy Bowers, Steve Juranich, and Jeff Shannon. As for Raymond
Hettinger, I can't even be sure ;)


Nope. To recall, my code was:

seenFalse = False
for item in list:
if item: return True
if item is False: seenFalse = True
if seenFalse:
return False
return None

So, turning that into a real function and not a sketch:

Python 2.3.4 (#1, Jan 25 2005, 21:29:33)
[GCC 3.4.3 (Gentoo Linux 3.4.3, ssp-3.4.3-0, pie-8.7.6.6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
def thingy(l): .... seenFalse = False
.... for item in l:
.... if item: return True
.... if item is False: seenFalse = True
.... if seenFalse:
.... return False
.... return None
.... thingy([ False , False , True , None ]) True


The defense rests, your honor. :-)

(I like the later use of "returnValue" and the reduce solution was cute
and quite educational (very appropriate here). I deliberately eschewed
fanciness, though.)
Jul 18 '05 #16

P: n/a
Jeremy Bowers wrote:
The defense rests, your honor. :-)


I stand corrected :-) My apologies.

--
Daniel Bickett
dbickett at gmail.com
http://heureusement.org/
Jul 18 '05 #17

P: n/a
Fredrik Lundh wrote:
Steven Bethard wrote:
Raymond Hettinger wrote:

return max(lst)


Very clever! Thanks!


too clever. boolean > None isn't guaranteed by the language
specification:

http://docs.python.org/ref/comparisons.html

"... objects of different types always compare unequal, and are
ordered consistently but arbitrarily. /.../ In the future, the
comparison rules for objects of different types are likely to
change. ..."


Then maybe like this:
def max_of_two_with_None_less_than_any_other_object(e1 , e2): ... if e1 == None:
... return e2
... elif e2 == None:
... return e1
... else:
... return max(e1, e2)
reduce(max_of_two_with_None_less_than_any_other_ob ject, lst)


Mick.
Jul 18 '05 #18

P: n/a
Jeremy Bowers wrote:
On Fri, 04 Feb 2005 16:44:48 -0500, Daniel Bickett wrote:
[ False , False , True , None ]

False would be returned upon inspection of the first index, even
though True was in fact in the list. The same is true of the code of
Jeremy Bowers, Steve Juranich, and Jeff Shannon. As for Raymond
Hettinger, I can't even be sure ;)


Nope.


Indeed. Similarly for mine, which was really just a slight transform
of Jeremy's (setting a return variable directly, instead of setting a
flag that's later used to decide what to return):
def tfn(lst): .... answer = None
.... for item in lst:
.... if item is True: return True
.... if item is False: answer = False
.... return answer
.... list = [False, False, True, None]
tfn(list) 1 list = [None, False, False, None]
tfn(list) 0 list = [None, None, None, None]
print tfn(list) None >>>


The noted logical flaw *has* been present in a number of proposed
solutions, however.

The key point to note is that one *must* examine the entire list
*unless* you find a True; short-circuiting on False means that you may
miss a later True.

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #19

P: n/a
Daniel Bickett wrote:
def boolhunt( items ): ... falseExists = False
... for item in items:
... if item is True:
... return True
... elif item is False and not falseExists:
... falseExists = True
... if falseExists:
... return False


Or even shorter:
def boolhunt(items): ... result = None
... for item in items:
... if item:
... return True
... elif result is None and item is False:
... result = False
... return result
Or like the Melmacians would do it:
def boolgen(items): ... result = None
... for item in items:
... if result:
... raise StopIteration
... elif item is not None:
... result = item
... yield result
[item for item in boolgen(a_list)][-1]

Mick.
Jul 18 '05 #20

P: n/a
Is it cheating to use a Set?

py>>def doit(thelist):
.... s = sets.Set(thelist)
.... if s == sets.Set([None]):
.... return None
.... else:
.... return max(s)
....
py>>print doit([ True , None , None , False ] )
True
py>>print doit([ None , False , False , None ] )
False
py>>print doit([ False , True , True , True ] )
True
py>>print doit( [None, None, None, None] )
None

Jul 18 '05 #21

P: n/a
reduce(lambda x, y: x or y, lst)

works but when I tried

import operator
reduce(operator.or_, lst)

this did not work. It pukes

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

Any comments?

Fahri
Jul 18 '05 #22

P: n/a
sorry, that should have been:

py>>import sets
py>>def doit(thelist):
.... s = sets.Set(thelist)
.... if s == sets.Set([None]):
.... return None
.... else:
.... return max(s - sets.Set([None]))

Jul 18 '05 #23

P: n/a
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)

works but when I tried

import operator
reduce(operator.or_, lst)

this did not work. It pukes

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

Any comments?

Fahri

TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

operator.or_ is "|" i.e., bitwise, not logical or

Michael

Jul 18 '05 #24

P: n/a

"Michael Spencer" <ma**@telcopartners.com> wrote in message
news:ma***************************************@pyt hon.org...
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)

works but when I tried

import operator
reduce(operator.or_, lst)

this did not work. It pukes

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

Any comments?

Fahri

TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

operator.or_ is "|" i.e., bitwise, not logical or

Michael


That explains it. Is there a logical or we can use with reduce?

Fahri
Jul 18 '05 #25

P: n/a
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)


This doesn't solve the OPs problem since
reduce(lambda x, y: x or y, [False, None])


returns None instead of False.

Mick.

Jul 18 '05 #26

P: n/a
Fahri Basegmez wrote:
"Michael Spencer" <ma**@telcopartners.com> wrote in message
news:ma***************************************@pyt hon.org...
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)

works but when I tried

import operator
reduce(operator.or_, lst)

this did not work. It pukes

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

Any comments?

Fahri


TypeError: unsupported operand type(s) for |: 'NoneType' and 'bool'

operator.or_ is "|" i.e., bitwise, not logical or

Michael

That explains it. Is there a logical or we can use with reduce?

Fahri

Yes, but it's not quite the same as the 'or' operator
bool.__or__(True, False) True bool.__or__(False, False) False bool.__or__(False, None) NotImplemented


this may not be intentional...

Michael

Jul 18 '05 #27

P: n/a

"Mick Krippendorf" <ma******@gmx.de> wrote in message
news:36*************@individual.net...
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)


This doesn't solve the OPs problem since
reduce(lambda x, y: x or y, [False, None])


returns None instead of False.

Mick.


You are right.
I tested None or False and it worked. I assumed order did not matter for or
operator.

None or False returns False
False or None returns None

You know what they say about assumptions. Live and learn.

Fahri
Jul 18 '05 #28

P: n/a
Fahri Basegmez said unto the world upon 2005-02-04 23:14:
"Mick Krippendorf" <ma******@gmx.de> wrote in message
news:36*************@individual.net...
Fahri Basegmez wrote:
reduce(lambda x, y: x or y, lst)


This doesn't solve the OPs problem since

>reduce(lambda x, y: x or y, [False, None])


returns None instead of False.

Mick.

You are right.
I tested None or False and it worked. I assumed order did not matter for or
operator.

None or False returns False
False or None returns None

You know what they say about assumptions. Live and learn.

Fahri


Hi Fahri,

I don't have a reference at hand, but you might want to check the
docs' index or do a google for short circuit python or something similar.

or works by evaluating the first value and returning it if it
evaluates to True. Otherwise it returns the second.
0 or 42 42
Likewsie, and returns the first if it evaluates to False, otherwise it
returns the second. [] and 42 []


The idea is that the evaluation breaks out as soon as it has seen
enough to determine the result. Hence, short circuit. And, instead of
returning a Boolean, it returns the actual object flanking the
operator. Hence, the behaviour observed.

HTH,

Brian vdB

Jul 18 '05 #29

P: n/a
On Fri, 04 Feb 2005 13:04:16 -0500, rumours say that Steve Holden
<st***@holdenweb.com> might have written:

[STeVe]
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

[Stevbe]If you wanted to get clever you could write something like

for i in True, False:
if i in lst:
return i
return False


[!Steve]

You mistyped None as False in the last line. Your typos are getting worse every
day :)
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #30

P: n/a
Brian van den Broek <bv****@po-box.mcgill.ca> wrote:
...
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.
... for val in (x for x in lst if x is not None):
return val
return None
... These don't do what the OP desired.


Ah, you're right, True should take precedence, point 2 of the specs.
OK, let's take advantage of the fact that None < False < True:

return max(lst)
This fails when lst is empty (the specs presumably imply a None should
be returned then). More robust:

return max(lst or [None])
Alex
Jul 18 '05 #31

P: n/a
Christos TZOTZIOY Georgiou wrote:
On Fri, 04 Feb 2005 13:04:16 -0500, rumours say that Steve Holden
<st***@holdenweb.com> might have written:

[STeVe]
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.

[Stevbe]
If you wanted to get clever you could write something like

for i in True, False:
if i in lst:
return i
return False

[!Steve]

You mistyped None as False in the last line. Your typos are getting worse every
day :)


That wasn't a *type*, it was a *thinko*

regards
Steve
--
Meet the Python developers and your c.l.py favorites March 23-25
Come to PyCon DC 2005 http://www.pycon.org/
Steve Holden http://www.holdenweb.com/
Jul 18 '05 #32

P: n/a
Steve Holden wrote:
Christos TZOTZIOY Georgiou wrote:
On Fri, 04 Feb 2005 13:04:16 -0500, rumours say that Steve Holden
<st***@holdenweb.com> might have written:

[STeVe]
For a given list:
* If all values are None, the function should return None.
* If at least one value is True, the function should return True.
* Otherwise, the function should return False.


[Stevbe]
If you wanted to get clever you could write something like

for i in True, False:
if i in lst:
return i
return False


[!Steve]

You mistyped None as False in the last line. Your typos are getting
worse every
day :)

That wasn't a *type*, it was a *thinko*

regards
Steve


Sheesh, now I even make typos typing about typos ...

giving-up-on-the-spill-chocker-ly y'rs - steve
--
Meet the Python developers and your c.l.py favorites March 23-25
Come to PyCon DC 2005 http://www.pycon.org/
Steve Holden http://www.holdenweb.com/
Jul 18 '05 #33

P: n/a
I think it is evil to do something "at your own risk" ; I will certainly not
embark some roller coaster at my own risk.

I also think it is evil to scan the whole list (as "max" ought to do) when
only scanning the first few elements would suffice most of the time.

Regards

Francis Girard

Le vendredi 4 Février 2005 21:13, Steven Bethard a écrit*:
Fredrik Lundh wrote:
Steven Bethard wrote:
Raymond Hettinger wrote:
return max(lst)

Very clever! Thanks!


too clever. boolean > None isn't guaranteed by the language
specification:


Yup. I thought about mentioning that for anyone who wasn't involved in
the previous thread discussing this behavior, but I was too lazy. ;)
Thanks for pointing it out again.

This implementation detail was added in Python 2.1a1, with the following
note[1]:

"The outcome of comparing non-numeric objects of different types is
not defined by the language, other than that it's arbitrary but
consistent (see the Reference Manual). An implementation detail changed
in 2.1a1 such that None now compares less than any other object. Code
relying on this new behavior (like code that relied on the previous
behavior) does so at its own risk."

Steve

[1] http://www.python.org/2.1/NEWS.txt


Jul 18 '05 #34

P: n/a
nghoffma wrote:
sorry, that should have been:

py>>import sets
py>>def doit(thelist):
... s = sets.Set(thelist)
... if s == sets.Set([None]):
... return None
... else:
... return max(s - sets.Set([None]))


Since a function that doesn't return is equivalent to one that returns
None, you can write it as:
def doit(lst):

.... s = set(lst) - set([None])
.... if s: return max(s)

that looks to me as the most elegant so far, but this is just because
it's mine :-)

You can also filter out Nones with a list/generator comprehension, but
sets are just more elegant...

--
Ciao,
Matteo
Jul 18 '05 #35

P: n/a
Matteo Dell'Amico wrote:
Since a function that doesn't return is equivalent to one that returns
None, you can write it as:
>>> def doit(lst):

... s = set(lst) - set([None])
... if s: return max(s)

that looks to me as the most elegant so far, but this is just because
it's mine :-)


Cool. I prefer to be explicit about returns (e.g. not counting on the
automatic return None), and I'd rather not create the unnecessary None
set, so I would probably write this like:

py> def f(lst):
.... s = set(lst)
.... s.discard(None)
.... if s:
.... return max(s)
.... else:
.... return None
....

But it's definitely a very elegant solution. Thanks!

Steve
Jul 18 '05 #36

This discussion thread is closed

Replies have been disabled for this discussion.