[Tutor] [spoiler] Re: Shifting arrays as though they are a 'word'

Chip Wachob wachobc at gmail.com
Tue Oct 9 09:38:35 EDT 2018


Peter,

Thank you for taking the time to create the example.

I'm new to Python, and, as a result, about a quarter of your example
makes sense to me.  The remainder I will have to start googling to see
if I can get my head around it.


On 10/9/18, Peter Otten <__peter__ at web.de> wrote:
> Chip Wachob wrote:
>
>> All,
>>
>> Sorry for not being more clear.  I think I was nearing my fill of
>> Python for the day when I wrote.
>>
>> Now, refreshed, let me see if I can fill in the blanks a bit more.
>
> You have posted code sprinkled with prints and irrelevant details.
> Please rewrite the relevant part into a simple function,
>
> def bitshift_right(data, nshift):
>    ...
>
> just the pure algorithm without any prints. Then find input data that
> produces an AssertionError in the snippet below:
>
> input = ...
> rshift = ...
> wanted_output = ...
> assert bitshift_right(input, rshift) == wanted_output
>
> I'm sure then someone is able and willing to point out the error in your
> implementation.
>
> In the mean time here's my effort which also provides an idea on how to wrap
>
> the shifting into a simple class:
>
> $ cat bitshift_oo.py
> format_bits = "{:08b}".format
> try:
>     format_bits(42)
> except ValueError:
>     # python 2
>     def format_bits(b):
>         return bin(b)[2:].zfill(8)
>
>
> def to_bits(s, sep=""):
>     return sep.join(map(format_bits, s))
>
>
> def bitshift_right(b, n):
>     nbytes, nbits = divmod(n, 8)
>     length = len(b)
>     if nbits:
>         nbits = 8 - nbits
>         a = [0]
>         for bb in reversed(b):
>             hi, lo = divmod(bb << nbits, 256)
>             a[-1] |= lo
>             a.append(hi)
>         b = bytearray(a[::-1])
>     return (bytearray(nbytes) + b)[:length]
>
>
> class Bytes(bytearray):
>     def __rshift__(self, n):
>         return Bytes(bitshift_right(self, n))
>
>     def __str__(self):
>         return to_bits(self, " ")
>
>
> if __name__ == "__main__":
>     SAMPLE = Bytes(b"\xaa\xbb")
>     for i in range(12):
>         print(SAMPLE >> i)
> $ python bitshift_oo.py
> 10101010 10111011
> 01010101 01011101
> 00101010 10101110
> 00010101 01010111
> 00001010 10101011
> 00000101 01010101
> 00000010 10101010
> 00000001 01010101
> 00000000 10101010
> 00000000 01010101
> 00000000 00101010
> 00000000 00010101
> $
>
> PS: An easier approach would be to match the to_bits() function with a
> to_bytes() function. Then you can implement the shift as a simple string
> manipulation:
>
> def bitshift_right(b, n):
>     bits = to_bits(b)
>     shifted = ("0" * n + bits)[:len(bits)]
>     return to_bytes(shifted)
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>


More information about the Tutor mailing list