Pythonのビッグ/リトルエンディアン

バイトを受け取り、リトルエンディアンとして解釈して数値を返す関数

def little_endian_to_int(b):

    return int.from_bytes(b, 'little')

数字を受け取り、リトルエンディアンとしてバイトを返却

def int_to_little_endian(n, length):

    return n.to_bytes(length, 'little')

バイト数も256とか指定するのではなく、引数lengthとして受け付ける。また、数字はiよりnの方がベター

pythonのdigest()とhexdigest()

digest()はバイト列、hexdigest()は16進数を返却する

import hashlib 

print(hashlib.sha256(b'test').digest())
print(hashlib.sha256(b'test').hexdigest())

$ python3 test.py
b’\x9f\x86\xd0\x81\x88L}e\x9a/\xea\xa0\xc5Z\xd0\x15\xa3\xbfO\x1b+\x0b\x82,\xd1]l\x15\xb0\xf0\n\x08′
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

pythonでdivmod

Pythonでは //で商、%で余りだが、divmodで両方を出力する。

q = 13 // 4
mod = 13 % 4
print(q, mod)

q, mod = divmod(17, 7)
print(q, mod)

$ python3 test.py
3 1
2 3

pythonのbytes型

bytesはバイナリデータを扱うバイト型

str1 = "高島屋"
enc_str1 = str1.encode()

print(f"{str1}:{enc_str1}")
print(f"type: {type(enc_str1)}")

print(f"高: {hex(ord('高'))}")
print(f"島: {hex(ord('島'))}")
print(f"屋: {hex(ord('屋'))}")

$ python3 test.py
高島屋:b’\xe9\xab\x98\xe5\xb3\xb6\xe5\xb1\x8b’
type:
高: 0x9ad8
島: 0x5cf6
屋: 0x5c4b

バイト型はb’で囲まれる
\xは続く文字列

Pythonのクラスメソッド(@classmethod)

クラスにくっついている関数のようなもので、インスタンス化していないクラスのものから呼び出せる。
メソッドに@classmethodと付けることでクラスメソッドにできる。

class A:

    def test_method():
        print("test")

    @classmethod
    def my_cls_method(cls):
        print("hello")

A.my_cls_method()
A.test_method()

– 第一引数でクラスが取得できる(インスタンスメソッドは第一引数が必ずselfになる)
– クラスの中にあるので、クラスをインポートすれば使える
– クラスメソッドを使わずに関数として書くこともできるが、クラスメソッドの場合は、インポートできて、まとめて管理できる

class Item:
    def __init__(self, id, name):
        self.id = id
        self.name = name

    @classmethod
    def retrieve_from_api(cls, id):
        res = requests.get(f"https://api.example.com/items/{id}")
        data = res.json()
        return cls(id, data["name"])

Pythonのビッグエンディアンとリトルエンディアン

import binascii

hex_b = 'f0148c'
bytes_be = binascii.unhexlify(hex_b)
bytes_le = bytes_be[::-1]
hex_le = binascii.hexlify(bytes_le).decode()
print(hex_le)
import sys

def dump(data):
    print(data)

    a = int.from_bytes(data, byteorder='big')
    b = int.from_bytes(data, byteorder='little')
    c = int.from_bytes(data, byteorder=sys.byteorder)
    print(a, hex(a))
    print(b, hex(b))
    print(c, hex(c))

dump(b'\x01\x02')
dump(b'\x11\x12\x13\x14\x15\x16\x17\x18\x19')

$ python3 test.py
b’\x01\x02′
258 0x102
513 0x201
513 0x201
b’\x11\x12\x13\x14\x15\x16\x17\x18\x19′
314897056051100063769 0x111213141516171819
462904482303900324369 0x191817161514131211
462904482303900324369 0x191817161514131211

Python super().__init__()の使い方

継承元のコンストラクタをオーバラーライドする

class Parent:
    def __init__(self, a, b):
        self.a = a 
        self.b = b
    
    def w(self):
        print(self.b)

class Child(Parent):
    def w(self):
        return super().w()

child = Child(0, 'hello')
child.w()

サブクラスで__init__を定義すると親クラスの上書きされてしまう。

class A:
    def __init__(self, name):
        self.name = name 

class B(A):
    def __init__(self, name, mail):
        super().__init__(name)
        self.mail = mail

b = B("yamada", "gmail")
b.name
class Parent:
    def __init__(self, name, age):
        self.name = name 
        self.age = age 

    def my_name(self):
        print("名前は" + self.name + "。年齢は" + str(self.age) + "歳。")

class Child(Parent):
    def __init__(self, name, age):
        super().__init__(name, age)

yamada = Child("yamada", 20)
yamada.my_name()

Python unittestのTextTestRunner().runを理解する

$ sudo apt install tree
$ tree
.
├── other.py
├── suite.py
└── test.py

test.py

import unittest

class MyTest(unittest.TestCase):
    def test_mytest_01(self):
        print("test_mytest_01 is called")
        one = 1
        self.assertEqual(one, 1, "one is 1")

other.py

import unittest

class OhterTest(unittest.TestCase):
    def test_other_01(self):
        print("test_mytest_01 is called")
        two = 2
        self.assertEqual(two, 2, "two is 2")

suite.py

import unittest

import test
import other

def suite():
    test_suite = unittest.TestSuite()
    test_suite.addTest(unittest.makeSuite(test.MyTest))
    test_suite.addTest(unittest.makeSuite(other.OhterTest))
    return test_suite

if __name__ == "__main__":
    mySuite = suite()
    unittest.TextTestRunner().run(mySuite)

$ python3 suite.py
test_mytest_01 is called
.test_mytest_01 is called
.
———————————————————————-
Ran 2 tests in 0.000s

OK

addTestとして、unittest.TextTestRunner().run() でテストを実行する