[Tutor] I don't quite understand bitwise

dn PyTutor at DancesWithMice.info
Tue Dec 15 17:29:52 EST 2020


On 16/12/2020 08:11, nathan tech wrote:
...

> An example of this is:
> self.RegisterHotKey(self.kid6, win32con.MOD_ALT|win32con.MOD_SHIFT, 0x46)
> 
...

> So I started to research how the x|y format works and came across 
> bitwise operators which is apparrently what is meant when x|y|z is used.
> 
> But to me they look like ints/
> 
> I am just... Completely lost on how this eeven works.


You are correct in saying that they look like ints. However, the next 
question is to ask, 'what do ints look like?'

Aside: At $work we are very concerned by, and often debate, the options 
of learning Python on its own, eg the 'boot camp' idea (no one who has 
suffered a military Boot Camp would ever put the two in the same 
category!). The comparisons come down to the time it takes to complete a 
traditional degree program[me] and its (crushing!) costs; versus the 
thinness of depth and narrowness of coverage that characterises a 
'fast-course'. Perhaps a separate "Friday Finking" discussion...

Apparently you have learned Python, perhaps even taught yourself, 
without the traditional backing of a ComSc degree. For which I praise 
you, and any implied-criticism is for the approach.

In a 'full-fat' ComSc course there would be coverage of 
computer-hardware and how it works, including the use of binary code and 
boolean algebra; and perhaps even some exposure to machine code and/or 
assembler languages. All of which gives (me at least) a great 
appreciation for Python, its idea of a "virtual machine", and how it 
saves us from so much 'pain'!

So, after all that mumbling-and-grumbling, here's a short-version (with 
the assumption that you'll read-up about the parts you don't 
already/immediately understand):-


We talk about using a "64-bit computer" (or perhaps a slightly older 
machine might be 32-bit). What is a "bit"? We used to think of a 
"binary-digit" as the smallest unit of information in a computer. The 
analog was a light-switch, which can either turn the lamp "on" or "off".

However, computer-storage is usually "addressed" at the level of 
"bytes". What is a byte? Eight bits! Just as a bit can only assume one 
of only two possible "states", a byte has exactly 2⁸ unique states, ie 
256. [in case it doesn't come-through the email, that's two superscript 
8, ie two to the eighth power] "Two" is quite a small number, and 256 is 
still not very large. So, bytes are often grouped-together for strength.

Back to our computer's 'size', those "64-bits" could also be considered 
a collection of eight bytes! In the ?good, old, days we might have 
referred to this grouping of bits/bytes as a "word".

At this point we could 'disappear' into computer architecture, but 
Python's interpreter abstracts us away from such detail. Let's spare 
ourselves and move-on.


If we have a series of bits (or bytes), some of which are turned 'on' 
and some of which are 'off', eg

     0110 0001

what does this mean? The opaque answer is that it can mean anything that 
you want it to mean! For example, you mentioned ints. This succession of 
bits could be said to mean the integer "97" (and it does!).

What about learning our (Latin) alphabet? These (same) bits could 
represent the letter "a" (again, it does!).

How about if we have a set called "fruit"? The first four bits (I'm too 
lazy to do more*) could indicate that we have some combination of an 
apple, a banana, a clementine, a durian... in which case:

     0110 ~ a banana and a clementine

So, it's all about "encoding"! Thus, how do we use the binary-digits 
and/or what do they represent. Until you apply *your* meaning to the 
bits, we can't be more specific amongst the choices:

     0110 0001 ~ 97 ~ "a" ~ a banana and a clementine (etc)


Let's 'cheat' for a moment, and stay with my abbreviated four-element 
sets of fruit.

Cast your mind back to the school-yard. Perhaps your Mum/Mom gave you 
some food to eat at school, and perhaps mine also for me. Being kids we 
always thought that what the other had was somehow better than our own. 
So, being clever, little, nascent-coder, problem-solvers, we would 
compare and contrast before making deals to trade/swap.

Let's say I turn-up with a a banana and a clementine, and you've been 
given a durian. As a first step, lets add or 'pool' them together. Now 
we have a pile (set) of fruit consisting of a banana, a clementine, and 
a durian. With that knowledge we can start 'trading', and because you're 
bigger (stronger, and can leap more buildings at a single bound) than 
me, you take the lot - throwing-down the banana peal for me to slip on 
(no, you wouldn't do that to me. Would you?)

Let's use the same system as above to represent the two sets of fruit, 
and what happens when we create a 'pool':

     mine:     { banana, clementine }
     yours:    { durian }
     the pool: { banana, clementine, durian }

Applying the 'encoding' method, this could be expressed, in bits, as:

     mine:     0110
     yours:    0001
     the pool: 0111

Are we agreed that 0110₂ represents or 'equals' a banana, a clementine, 
and a durian?
(in case it doesn't come-through the email, that's 0110 subscript two, 
ie 0110 in base-2)

Did you notice the columnar relationship? If there is a 1 from either 
(or both) rows, then the column position representing the pool will be 
one. If neither is one (or both 'mine' and 'yours' is zero) then the 
pool's column or bit will be zero!

Thus, taking the calculation one bit at a time ("bit-wise"!), if 'my' 
bit is one *or* 'your' bit is one, then the answer-bit is set to one. 
Conversely, if neither bit is one, then the answer-bit is set to zero.

This is the binary OR operation!
NB there are variants, but they're irrelevant to the stated application. 
(fortunately!)


Finally, we reach 'the point'!

In the (above) explanation, combining the two sets was referred to as 
"adding" or "pooling". In Boolean Algebra, bitwise 'adding' is called 
"or", ie if either you *or* I had a piece of that type of fruit to 
contribute to the pool, it would appear in the pool.

NB The analogy breaks-down if we both contribute an apple, because sets 
don't 'count' how many of each item. To account for that, we need to 
represent our 'pool' using integers (unless I've already eaten part of 
my apple on the way to school - not an unheard-of event! Now, we're 
talking "floats" or "real numbers" and we're not going there...) ie 
different encoding systems!

In the wxPython context, we are discussing modifier-keys, of which there 
is a finite set, and there's no such thing as two 'flag'/'Windows' keys 
(and the two shift-keys can be separately-identified). Accordingly, a 
key-combination is a set, a pooling, of multiple keys; which presumably 
will lead to a particular choice/function.

So, whilst the wxPython-people are content to use Boolean Algebra and 
bitwise-or functions to express a key-combination; apparently you would 
prefer a 'higher-level abstraction'. Hey, I'm with you on this!

Perhaps then use a Python set rather than a list, and you'll be off 
laughing.
(and with a belly full of good, healthy, fruit - but if you're going to 
cut-open that durian, I'm heading a long way away, up-wind!)


* and yes, just to leave anyone who has read this far with a smile, 
those four bits (half a byte) could be referred to as a "nibble" or 
"nybble". Actually, this not just a joke. The first single-chip CPUs 
were four-bit computers. These are still available, and applied in 
numerous situations.

Furthermore, it seems likely that the use (and understanding) of 
Python's bit-wise operations will become more important with the 
increasing use of Raspberry Pi-s and other SBCs, MicroPython, etc!
-- 
Regards =dn


More information about the Tutor mailing list