プログラマが学ぶべき最も大切な技能は、コードを書かないですむときを見極めることかもしれない
- 不必要な機能を削除する。過剰な機能は持たせない
- 汎用的なユーティリティを作って使いまわす
- 定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しんでおく
-
問題をなるべく簡単にする
-
プロジェクトに 欠かせない機能 だけを見積もる
-
ありとあらゆる入力を処理できなくても、顧客の要求を満たすプログラムであれば良い
- 要求を詳しく調査し、問題をなるべく簡単にする → 必要なコードも短くて済む
-
例: LRUキャッシュ vs 単項目キャッシュ
- あるプログラムでのディスク読み込み例
read Object A read Object A read Object A read Object B read Object B read Object C read Object D read Object D
-
LRUキャッシュは、保持しているデータのうち参照されていない時間が長いものから削除していく方式
-
単項目キャッシュは、1つのデータしか保持しない方式
- 実装コストは LRUキャッシュ >> 単項目キャッシュ
-
このプログラムでは、必ずオブジェクトは
A, B, C, D
の順番で読み込まれる- つまり、要求は
A, B, C, D
の順で読み込んだときに効果があるキャッシュ
- つまり、要求は
-
古いキャッシュを保持している必要がないので単項目キャッシュで十分な効果が得られる
- 10章 「無関係の下位問題を抽出する」を参照
- 標準ライブラリのすべての関数・モジュール・型の名前を読んでみる
- 覚えなくて良い。「何ができそうか」という感覚だけ掴んでおく
- 使えそうな場面が来たときに「そういえばAPIにあったな」と思い出せれば十分
- 言語にもよるが、標準モジュールで大抵のことはできる
- Dash: https://kapeli.com/dash
- セット、カウンター
array = ['a', 'c', 'a', 'c', 'a', 'a', 'c', 'b', 'a', 'c', 'c', 'b', 'c']
# 重複のない集合
set1 = set(array)
print(set1)
# {'a', 'b', 'c'}
set2 = set(['b', 'c', 'd'])
# 和集合
print(set1 | set2)
# {'a', 'b', 'c', 'd', 'e'}
# 積集合
print(set1 & set2)
# {'b', 'c'}
# 差集合
print(set1 - set2)
# {'a'}
# 要素数のカウンター
import collections
counter = collections.Counter(array)
# 数が多い要素順にソートして出力
print(counter.most_common())
# [('c', 6), ('a', 5), ('b', 2)]
- int型メソッド to_bytes, from_bytes
- pow
- (CTFer暗号やる人向け)
message = 3735928559
# intからバイト列(ビッグエンディアン)
print(message.to_bytes(4, 'big'))
# b'\xde\xad\xbe\xef'
# intからバイト列(リトルエンディアン)
print(message.to_bytes(4, 'little'))
# b'\xef\xbe\xad\xde'
# バイト列からint
payload = b'\xca\xfe\xba\xbe'
print(int.from_bytes(payload, 'big'))
# 3405691582
# RSAの暗号化
# 冪剰余の高速計算(いわゆるmodpow)
n = 941837418740217332989582098539028509238509357747905821937589247582397423094902747107042174721742878417
e = 65537
cipher_text = pow(message, e, n)
最も読みやすいコードは何も書かれていないコードだ
平均的なソフトウェアエンジニアが書く出荷用のコードは一日10行。 この10行というのはよくテストされ文章化されている製品用コードとしてということ。 コードが増えるとプロジェクトが「重く」なり、開発が難しくなっていくので、なるべく新しいコードは短いほうが良い。