Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I gave a +1 to Kugel, but another leaner option is</p> <pre><code>dirUp, dirDown, dirLeft, dirRight = range(4) </code></pre> <ul> <li><ul> <li><ul> <li>(Some time passes)</li> </ul></li> </ul></li> </ul> <p>So I was thinking...we have an obvious DRY violation here in that we already specify four items on the LHS, and then again specify four on the RHS. What happens if we add items in the future? What happens when someone else adds them, and maybe they are more sloppy than ourselves? One obvious way to remove the DRY violation is to use the list of enums themselves to assign their values:</p> <pre><code>&gt;&gt;&gt; enums = ['dirUp', 'dirDown'] &gt;&gt;&gt; for v, k in enumerate(enums): ... exec(k + '=' + str(v)) ... &gt;&gt;&gt; print dirDown 1 &gt;&gt;&gt; print dirUp 0 </code></pre> <p>If you can stomach using <code>exec()</code> for this, then fine. If not, then use the other approach. This current discussion is all academic anyway. However, there is still a problem here. What if the enums are used throughout a great body of source code, and some other programmer comes along and inserts a new value between <code>dirUp</code> and <code>dirDown</code>? This will cause misery because the mapping between the names of the enums and the enums themselves will be wrong. Bear in mind that that remains a problem even in the original simple solution.</p> <p>Here, we have the novel idea of using the builtin <code>hash()</code> function to determine our enum value as an int, and we use the text name of the enum itself to determine the hash:</p> <pre><code>&gt;&gt;&gt; for k in enums: ... exec(k + '=' + str(hash(k))) ... &gt;&gt;&gt; dirUp -1147857581 &gt;&gt;&gt; dirDown 453592598 &gt;&gt;&gt; enums = ['dirUp', 'dirLeft', 'dirDown'] &gt;&gt;&gt; for k in enums: ... exec(k + '=' + str(hash(k))) ... &gt;&gt;&gt; dirUp -1147857581 &gt;&gt;&gt; dirDown 453592598 &gt;&gt;&gt; dirLeft -300839747 &gt;&gt;&gt; </code></pre> <p>Notice that we inserted a new value between <code>dirUp</code> and <code>dirDown</code>, i.e. <code>dirLeft</code>, and our original mapping values for the first two <em>did not change</em>.</p> <p>I may actually use this in my own code. Thanks to the OP for posting the question.</p> <ul> <li><ul> <li><ul> <li>(Some more time passes)</li> </ul></li> </ul></li> </ul> <p>Beni Cherniavsky-Paskin made some very good comments:</p> <ul> <li>Python's default <code>hash()</code> is not stable across platforms (dangerous for persistence applications)</li> <li>The possibility of collisions is always present.</li> </ul> <p>I tend to agree with both observations. His suggestion is to use the strings themselves (I really like the self-documenting behaviour of using the values) as the hash, and so the code becomes the following (note we use a set instead of a list, to enforce uniqueness):</p> <pre><code>&gt;&gt;&gt; items=('dirUp','dirDown','dirLeft','dirRight') &gt;&gt;&gt; for i in items: exec('{}="{}"'.format(i,i)) &gt;&gt;&gt; dirDown 'dirDown' </code></pre> <p>It is also trivial to put these in a namespace, so as to avoid collisions with other code:</p> <pre><code>&gt;&gt;&gt; class Direction(): for i in ('dirUp','dirDown','dirLeft','dirRight'): exec('{}="{}"'.format(i,i)) &gt;&gt;&gt; Direction.dirUp 'dirUp' </code></pre> <p>The length of the cryptographic hash he mentions can be seen here:</p> <pre><code>&gt;&gt;&gt; from hashlib import md5 &gt;&gt;&gt; crypthash = md5('dirDown'.encode('utf8')) &gt;&gt;&gt; crypthash.hexdigest() '6a65fd3cd318166a1cc30b3e5e666d8f' </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload