可変長数値のエンコードとデコードを実装します。
この演習の目標は、VLQのエンコード/デコードを実装することです。
要するに、このエンコードの目的は、バイト数を節約できるように整数値をエンコードすることです。各バイトで意味を持つのは下位7ビットだけです(右詰めで、いわばASCIIバイトのようなものです)。つまり、32ビットの値がある場合、それを7ビットのバイトの並びに分解する必要があります。もちろん、整数によってバイト数は変わります。一連のバイトのうちどれが最後のバイトかを示すには、最上位ビットを0のままにします。それより前のすべてのバイトでは、最上位ビットを1にします。
したがって、整数が0-127の範囲にある場合、それは1バイトで表せます。VLQは任意の大きさの数を扱えますが、この演習では32ビット符号なし整数に収まる数だけを対象にします。以下は、32ビット値としての整数と、それが変換される可変長数値の例です。
NUMBER VARIABLE QUANTITY
00000000 00
00000040 40
0000007F 7F
00000080 81 00
00002000 C0 00
00003FFF FF 7F
00004000 81 80 00
00100000 C0 80 00
001FFFFF FF FF 7F
00200000 81 80 80 00
08000000 C0 80 80 00
0FFFFFFF FF FF FF 7F
ときには例外を送出する必要があります。そのときは、エラーの原因が何であるかを示す意味のあるエラーメッセージを必ず含めましょう。そうするとコードが読みやすくなり、デバッグもぐっと楽になります。エラーの原因がある決まった種類になるとわかっている場合は、組み込みのエラータイプの中から1つを選んで送出してもかまいませんが、その場合も意味のあるメッセージを含めるようにしましょう。
この演習では、デコードまたはエンコードするシーケンスが不完全な場合に、raise文を使ってValueErrorを「投げる」必要があります。テストに合格するのは、exceptionをraiseし、メッセージも添えたときだけです。
メッセージ付きでValueErrorを送出するには、そのメッセージをexception型の引数として書きます。
# if the sequence is incomplete
raise ValueError("incomplete sequence")