2017年12月31日日曜日

誰の役に立つわけでないPythonのTips

フラグが立つまで待つ
 0x20はフラグの位置。
while (readdata(xx) & 0x20 ) :
        continue


2の補数の符号判断
 16ビットの例。ビット数に合わせて0と1の数を増減
def sign16(x):
        return ( -(x & 0b1000000000000000) | (x & 0b0111111111111111) )

バイト・スワップ
def swap16(x):
        return (((x <<8) & 0xff00) | ((x >> 8 ) & 0x00ff))

ビット反転
 16ビット長。長さがわかっているとき。
data ^ 0xffff

ビット反転して、LSBに1を加える
~data ^ 0xffff

数値データを1と0の文字列で得る
 dataの上位が 0のときは0がなくなるので、完全な1,0の文字列にはならない。
bin(data)[2:]
 元に戻す
hex(int(bin(data)[2:],2))

数値の長さの1を得る
len(bin(data)[2:])
マスクを作る
int(("1"*(len(bin(data)[2:]))),2))
任意長の数値のビット反転。ただし、先頭に1がくる数値。
data ^ int(("1"*(len(bin(data)[2:]))),2))

移動平均
 切り出しただけ。

datas=[]
while 1:
                if len(datas)<10 :
                        datas.append(readADC())
                else:
                        del datas[0]
                idou = sum(datas)/len(datas)
                print round((Vref * (sign16(int(hex(idou),16))) / 32767.0),5),"V "

for文
for i  in range(10) 0~9まで

for i in range (1,10) 1~9まで

for i in range (2,10,3) 2~10まで、ステップ3。結果2,5,8

 for (i,x) in enumerate(data)
data='1101'であれば、最初に1を取り出す。(0,1) (1,1),(2,0),(3,1)
data=['Spring', 'Summer', 'Fall', 'Winter'] Springを最初に取り出す。

-----
イテレート(iterator) 反復


イテレーション

イテラブル (iterable) 
イテラブルからリストを生成  list(range(5))

タプル 組 カンマで値を区切ったリストのようなもの。要素を変更ができない?

CRC8-ATM

def crc8atm(data) : #data=0x654321
        data =data <<8
        length = len(bin(data)[2:])
        for i in range(length):
                if int(bin(data)[2:3],2) == 1 : #MSB =1
                        nokori = bin(data)[11:]
                        sentou = (int(bin(data)[2:11],2)) ^ (int('100000111',2))
                        data = int((str(bin(sentou)[2:11])+str(nokori)),2)
                data=int(bin(data),2) #MSB=0
                if len(str(bin(data)[2:]))<9:

                        return(hex(data))


2017年12月29日金曜日

固定小数点形式の

符号1ビット+n桁の整数部+m桁の小数点部
n=12、m=3
n=2、m=13
n=1、m=14
とか変なデータがある。そこで、小数点位置を任意に指定できる10進変換関数はないかと探すが、ないみたい。
 Decimalという関数の説明ページにたどり着いて、穴が開くほど読んでいたが、解決に至らない。

Python で小数点対応の N 進数から 10 進数に変換するプログラムを書いた

というページを見つけた。汎用関数になっているので、2進数を10進に変換するだけなので、小数部分の変換を書いてみた。
from decimal import *

data ='110'
sum0 =Decimal(0)
for (i,x) in enumerate(data) :
    sum0 += Decimal(x)*Decimal(2**(-(i+1)))
print (data,sum0)

内包表現にしてみた。
fractional =sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(data)])
これ1行見たら、翌日にはどうやって変換しているかわからない.

  • 小数点第1位を取り出し、2^-1すると0.5が得られる。それにその数字を乗じる。1なら0.5、0なら0。
  • 小数点第2位を取り出し、2^-2すると0.25が得られる。それにその数字を乗じる。1なら0.25、0なら0。

それを桁数分繰り返す。
floatで実数として取り出す。取り出したのはリスト形式。なのでsumで合計を求める。
永久に1を超えられない数値が求まる。

 関数にした。16ビット限定だと。16進のデータdatahex(ex。0xb3f9)と、整数部分のビット数integer(ex。12)を引数に呼び出す。

def kotei(datahex,integer) :
        if (datahex & 0b1000000000000000 ) :
                I1=(~datahex ^ 0xffff)
                I0=bin(datahex)[3:(3+integer)]
                Integer=-(int(I0,2) ^ int(("1"*integer),2))
                F0= bin(I1)[(2+integer):]
                Fractional =-sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(F0)])
        else:
                Integer=(datahex & 0b0111111111111111 )>> (15-integer)
                fdata3=str(bin((datahex & 0b0111111111111111 ) & int( '1' * (15-integer),2)))[2:]
                Fractional =sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(fdata3)])
        #print Integer,Fractional,(Integer+Fractional)
        return(Integer+Fractional)

まちがっている。。。。 修正しました。
Integerは整数部分。負のときは反転し、LSBに1ビット足す。正のときは小数部分の桁分右にシフトするだけ。
fdata3は小数部の1,0を文字列で切り出す。
Fractionalは、小数点の演算。
整数部と小数部を加算して終了。