ok, so this is a bit complex, I'm writing a bit-field function using a template, which can consist of:

``````field( Template, Value )

field( [1,7,15]        ,255 ) #int representation...
field( ['1','3','4']   ,255 ) #bit representation...
#>>> [1,7,15]

field( [1,7,15]        ,[1,7,15] )
field( ['1','3','4']   ,[1,7,15] )
#>>> 255
``````

so what I'm looking for is a way to R-shift `Value` by the binary size of the data field during enumeration in a generator...

here's the unfinished int >>> list method for example:

``````return [(Value>> ? )&(~(~0<<int(t)) if t.__class__==str else t) for t in Template]
``````

what would I have to do to the `?` to get what I'm after??

thanks :)

a way to R-shift Value by the binary size of the data field

I don't understand what you want to do. What is the binary size of the data field ? Can you give examples of input values and expected output values ?

Here is my solution

``````def field(template, value):
res = 0
for t, v in zip(template, value)[::-1]:
if t.__class__ is int:
t = t.bit_length()
else:
t = int(t)
res = (res << t)|v
return res

if __name__ == '__main__':
res = field([0b1,0b111,0b1111], [0,3,9])
print(res, bin(res))
``````

Unfortunately `v is int or long` means

``````(v is int) or long
``````

It is always True because `bool(long`) is True. If you want to test if a value is an int or a long, the valid ways are

``isinstance(v, (int, long)) …``

## All 11 Replies

a way to R-shift Value by the binary size of the data field

I don't understand what you want to do. What is the binary size of the data field ? Can you give examples of input values and expected output values ?

GAH! curse my horrible explainations... lol

what I mean is, [1,7,15] evaluates to [ 0b1, 0b111, 0b1111 ] in which the size of these is specified by ['1','3','4']

so what I need to do is, in the for loop, for each run:

1: (Value>> `0` )&(~(~0<<int(t)) if t.class==str else t)
2: (Value>> `1` )&(~(~0<<int(t)) if t.class==str else t)
3: (Value>> `8` )&(~(~0<<int(t)) if t.class==str else t)

what can I do to incrimint the value-shift like I want??
enumerate() obviousely won't work, unless I use it to gather the sizes from the template and sum() them up... heh :P
isn't there a better way??

Now I don't understand how the 1 3 4 become 0 1 8. Can you explain the connection between the two ?

oops

``````p   = 0
p+1 = 1
p+3 = 4
``````

was looking at 7 instead of 3 and not realizing when I wrote the post, so that's how I got 8

quick solution (probably not the best)

``````sums = [int(v) if v.__class__==str else len(bin(v))-2 for v in Template]
return [(Value>> (sum(sums[:i]) if i else 0) )&(~(~0<<int(t)) if t.__class__==str else t) for i,t in enumerate(Template)]
``````

EDIT: scratch that, it's not working right... heh

EDIT2: fixed

and vice-versa, though again, probably not the best:

``````def field(template, value):
template, value = list(reversed(template)), list(reversed(value))
sums = [int(v) if v.__class__==str else len(bin(v))-2 for v in template]
v = {'':0}; [v.update({'':( v['']<<sums[i])|f }) for i,f in enumerate(value)]; return v['']
``````

testing:

``````>>> field([0b1,0b111,0b1111], [0,3,9])
150
``````

Here is my solution

``````def field(template, value):
res = 0
for t, v in zip(template, value)[::-1]:
if t.__class__ is int:
t = t.bit_length()
else:
t = int(t)
res = (res << t)|v
return res

if __name__ == '__main__':
res = field([0b1,0b111,0b1111], [0,3,9])
print(res, bin(res))
``````
commented: very nice +4

oh yea, I forgot about zip()
that's much better than what I'm currently doing :D

btw NICE reversal method =D
god, I've been using list(reversed( )) for so long... =3=

and .bit_length()
why is this not documented anywhere 9_9
many thanks :)

btw, your for loop, fitting my coding preferences: ;)

``````for t, v in zip(template, value)[::-1]: res = (res << (t.bit_length() if t.__class__ is int else int(t)) )|v
``````

now if only I could do `; for` lol

`bit_length()` is documented in python 3. It has been backported to 2.7.

Edit: it is actually also documented in 2.7.

Edit: in python 2, `t.__class__ in (int, long)` would be better, although a little slower than `t.__class__ is int`.

if it's just 2 types, this is better ;)

``````>>> def f(v): print True if v is int or long else False

>>> f(int())
True
>>> f(long())
True
>>>
``````

truthfully, I'm not entirely sure if it's faster than tuple creation, though logic tells me it should be.
figured that one out a while back, had issues with more than 2 types back when I was triangulating primitives.

EDIT:

Edit: it is actually also documented in 2.7.

huh... in the times I've looked at the docs, I've never seen it.
though I don't look much at those docs anymore...
they're confusing and don't tell you much of what you need to know... heh
I'm literally better off asking for a better example in most cases.

Qt has better documentation, and even their docs suck :P
lol

Unfortunately `v is int or long` means

``````(v is int) or long
``````

It is always True because `bool(long`) is True. If you want to test if a value is an int or a long, the valid ways are

``````isinstance(v, (int, long)) # good programming
type(v) in (int, long) # doesn't work with subtypes
v.__class__ in (int, long) # dirty but faster
``````
commented: oh ok, my mistake :) +4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.