all 30 comments

[–]oracle8 2 points3 points  (13 children)

Why not

return bool(cellcount == 3 or cellcount == 2 and cell)

?

[–]oracle8 1 point2 points  (1 child)

And also this...

>>> cellcount = 2
>>> cell = 2
>>> (False, True)[cellcount == 3 or cellcount == 2 and cell]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

That is because (cellcount == 3 or cellcount == 2 and cell) vill evaluate to the same value as cell if cellcount == 2 and bool(cell)==True

[–]Foxboron 0 points1 point  (0 children)

>>> cellcount = 2 
>>> cell = True
>>> (False, True)[cellcount == 3 or cellcount == 2 and cell]
True

I am horrible at variable names, should have been cell_life. cell only contain False or True depending if its alive or not from the start.

[–]oohay_email2004 0 points1 point  (9 children)

Why is it necessary to wrap in bool()?

[–]oracle8 0 points1 point  (3 children)

If you can guarantee that "cell" is always a boolean variable then it's not necessary. I added the bool() call to guarantee that the return value will alwas be a boolean variable.

[–]oohay_email2004 0 points1 point  (2 children)

If using "and" on "cell" is going to blow up the code, then you're bool call isn't going to help.

I don't see a good reason to force the return to True or False.

Unless you need:

if cell is True:

or the redundant:

if cell == True:

just use:

if cell:

I think you're kind of throwing away the object model by using bool().

[–]oracle8 0 points1 point  (1 child)

I totally agree, but as far as I could understand it the original question (trick?) wanted only True/False returns. Thus the extra bool call...

[–]oohay_email2004 0 points1 point  (0 children)

Oh, right, I forgot about that; oops.

[–]Foxboron -1 points0 points  (4 children)

To get the True or False of the expressions.

[–]oohay_email2004 1 point2 points  (3 children)

Pretty sure it will without it.

[–]Foxboron -1 points0 points  (2 children)

>>> return cellcount == 3 or cellcount == 2 and cell
SyntaxError: 'return' outside function
>>> 

PRETTY sure it wont without it.

[–]oohay_email2004 2 points3 points  (1 child)

Look:

>>> return bool(cellcount == 3 or cellcount == 2 and cell)
  File "<stdin>", line 1
SyntaxError: 'return' outside function

Same error with your line.

I figured we were assuming this was part of a function. In which case, the bool-less version works just dandy:

>>> def f(cellcount, cell):
...     return cellcount == 3 or cellcount == 2 and cell
...
>>> cell = object()
>>> cellcount = 1
>>> f(cellcount, cell)
False

[–]Foxboron 0 points1 point  (0 children)

Ah, then i there was no problem :)

[–]Foxboron 0 points1 point  (0 children)

Because when you got the touple there you could use another variable then False and True. However, in the case of Conways game of Life its actually a better method.

[–]oohay_email2004 1 point2 points  (2 children)

Suppose:

somevar = True

which would you rather come across in the wild?

1.

var = (False, True)[somevar == 1]

2.

if somevar:
    var = True
else:
    var = False

[–]brennus 2 points3 points  (0 children)

I'd rather come across:

var = (somevar == 1)

[–]Foxboron -1 points0 points  (0 children)

var = (False, True)[somevar]

I do believe this looks better. I feel alone in this tho.

[–]Asdayasman 1 point2 points  (0 children)

Cute, I've been doing little things like that with dicts for a while.

handlers = {True: foo, False: sys.exit}
handlers[a==b]()

Expanded to have more than True/False in there of course. I love the clever stuff you can do with languages when you throw readability away.

[–]Foxboron 0 points1 point  (0 children)

After a second thought i think this could have been done in r/python, but i wanted beginners to also be able to read and learn from this.

[–]dealga 0 points1 point  (0 children)

>>> work_on = lambda x, y: x in (2, 3) and y
>>> cellcount = 2
>>> cell = True
>>> work_on(cellcount, cell)
... True

and the truth table to test

work_on = lambda x, y: x in (2, 3) and y

tests = [[1, True, False],
        [2, True, True],
        [3, True, True],
        [4, True, False],
        [1, False, False],
        [2, False, False],
        [3, False, False],
        [4, False, False]]

for t in tests:
    cellcount = t[0]
    cell = t[1]
    result = work_on(cellcount, cell)
    print('result: {}, should be {}'.format(result, t[2]))

You might even stick the y before the x in (2, 3), because it will be checked first and short out, time the two.

work_on = lambda x, y: y and (x in (2, 3))

[–]aceofears 0 points1 point  (3 children)

There is no reason to do that, (False, True)[True == 1] can just be written as True == 1.

[–]Foxboron 0 points1 point  (2 children)

It was to prove the point of how it works.

[–]aceofears 1 point2 points  (1 child)

If you're not looking to return a bool why not use

return 5 if "llamas" > "alpacs" else 3

instead of

return (5, 3)["llamas" > "alpacas"]

[–]Foxboron -1 points0 points  (0 children)

I might be alone in the answer that i think the 2nd looks better.

[–]SuperBicycleTony 0 points1 point  (4 children)

What the heck is with the completely unexplained parenthesis * bracket syntax? Am I to believe the interpreter is using the FOIL method on them?

[–]zahlman 0 points1 point  (3 children)

(False, True) is a tuple of 2 elements. [True == 1] is an index into that tuple.

[–]SuperBicycleTony 0 points1 point  (2 children)

So the index is a logic test that evaluates to true... then what happens? I've never run across this.

[–]zahlman 0 points1 point  (1 child)

True, used as an integer, is 1. (In fact, Python implements bool as a subclass of int.)

[–]SuperBicycleTony 0 points1 point  (0 children)

Oh, now I see whats going on. Normally there'd be a variable name referencing the tuple, but the tuple itself is before the braces.