Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of compares in indices in Python?

I encountered the following:

r = random.randint(1,6)
C = "o "
s = '-----\n|' + C[r<1] + ' ' + C[r<3] + '|\n|' + C[r<5]
print(s + C[r&1] + s[::-1])

When executed in IDLE, this outputs an ASCII die with a random value.

How does it work,and more specifically, what do the compare symbols (< and &) accomplish inside the indices?

like image 614
Joseph Bosco Avatar asked Mar 16 '16 12:03

Joseph Bosco


1 Answers

Someone is code-golfing here, and using hacky tricks to minimise the amount of code used.

  • < is a regular comparison operator; it returns True or False based on the two operands. The Python bool type is a subclass of int and True is 1, False is 0 when interpreted as integers. As such C[r<1] either picks C[0] or C[1].

  • & is a bit-wise operator, not a comparison operator; & 1 is masking the number to the last bit, effectively testing if a number is odd or even (the last bit is set or not). So if r is odd, C[1] is used, otherwise C[0] is.

Breaking this down:

  • C is a string with the o and space characters
  • C[r<1] picks either o or a space based on wether it is smaller than 1. It never is (random.randint(1,6) ensures this), so that is always an o. This appears to be a bug or oversight in the code.
  • C[r<3] picks a space for 1 and 2, an o otherwise.
  • C[r<5] picks an o for 5 or 6, a space otherwise.
  • C[r&1] picks an o for 2, 4 and 6, a space otherwise.

In all, it prints r plus one as a die. r = 1 gives you two pips, while r = 6 results in seven pips, perhaps as a stylised one?

Fixing the code for that requires incrementing all r tests and inverting the odd/even test:

s = '-----\n|' + C[r<2] + ' ' + C[r<4] + '|\n|' + C[r<6]
print(s + C[1-r&1] + s[::-1])

Demo (wrapping the string building in a function):

>>> import random
>>> def dice(r, C='o '):
...     s = '-----\n|' + C[r<2] + ' ' + C[r<4] + '|\n|' + C[r<6]
...     print(s + C[1-r&1] + s[::-1])
...
>>> for i in range(1, 7):
...     dice(i)
...
-----
|   |
| o |
|   |
-----
-----
|o  |
|   |
|  o|
-----
-----
|o  |
| o |
|  o|
-----
-----
|o o|
|   |
|o o|
-----
-----
|o o|
| o |
|o o|
-----
-----
|o o|
|o o|
|o o|
-----
like image 62
Martijn Pieters Avatar answered Sep 28 '22 21:09

Martijn Pieters