Need help understanding a short python code
<p>I want to emphasis that this is not a ask for completing my homework or job: I am studying the LZW algorithm for gif file compression by reading someone's code on <a href="https://github.com/j-s-n/mazes/blob/master/python2/GIF_maze.py" rel="nofollow">github</a>, and got confused by a code block here:</p>

<pre><code>class DataBlock(object):

    def __init__ (self):
        self.bitstream = bytearray()
        self.pos = 0

    def encode_bits (self, num, size):
        """
        Given a number *num* and a length in bits *size*, encode *num* 
        as a *size* length bitstring at the current position in the bitstream.
        """
        string = bin(num)[2:]
        string = '0'*(size - len(string)) + string
        for digit in reversed(string):
            if len(self.bitstream) * 8 &lt;= self.pos:
                self.bitstream.append(0)
            if digit == '1':
                self.bitstream[-1] |= 1 &lt;&lt; self.pos % 8
            self.pos += 1
</code></pre>

<p>What I cannot understand is the <code>for</code> loop in the function <code>encode_bits()</code>:</p>

<pre><code>for digit in reversed(string):
    if len(self.bitstream) * 8 &lt;= self.pos:
        self.bitstream.append(0)
    if digit == '1':
        self.bitstream[-1] |= 1 &lt;&lt; self.pos % 8
    self.pos += 1
</code></pre>

<p>Here is my guess (depend on his comment):</p>

<p>The function <code>encode_bits()</code> will turn an input integer <code>num</code> into a binary string of length <code>size</code> (padding zeroes at left if needed) and reverse the string, and append the digits to <code>bitstream</code> one by one. Hence
suppose <code>s=DataBlock()</code>, then <code>s.encode_bits(3, 3)</code> would firstly turn 3 into <code>011</code> (padding a zero at left to make it length 3) and reverse it to <code>110</code>, and then append <code>110</code> to <code>self.bitstream</code>, hence the result should be <code>bytearray('110').</code> But as I run the code the result gives <code>bytearray(b'\x03')</code>, not as expected. Further more, <code>\x03</code> is one byte, not 3 bits, conflicts with his comment, I cannot understand why? </p>

<p>I forgot to add that his code runs and gives correct output hence there's something wrong in my understanding.</p>

<p>Try looking at it this way:</p>

<ul>
<li>You will be given a <code>bytearray</code> object (call it <code>x</code> for the moment).</li>
<li>How many bytes are in the object?  (Obviously, it's just <code>len(x)</code>.)</li>
<li>How many <em>bits</em> are in the object?  (This is an exercise; please calculate the answer.)</li>
</ul>

<p>Once you've done that, suppose we start with no (zero) bytes in <code>x</code>, i.e., <code>x</code> is a <code>bytearray(b'')</code>.  How many <em>bytes</em> do we need to add (<code>x.append(...)</code>) in order to store three <em>bits</em>?  What if we want to store eight bits?  What if we want to store ten bits?</p>

<p>Again, these are exercises.  Calculate the answers and you should be enlightened.</p>

<p>(Incidentally, this technique, of compressing some number of sub-objects into some larger space, is called <em>packing</em>.  In mathematics the problem is <a href="https://en.wikipedia.org/wiki/Packing_problems" rel="nofollow">generalized</a>, while in computers it is <a href="https://en.wikipedia.org/wiki/Data_structure_alignment" rel="nofollow">often more limited</a>.)</p>

python