레코드 블로킹 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.

"""레코드 블로킹 (Stallings 12.6절). 블록 B바이트, 레코드 R바이트.
고정 블로킹: 블록당 레코드 floor(B/R)개, 블록 끝에 B mod R바이트 낭비.
가변·걸치기(spanned): 낭비 없이 채우고 남는 부분은 다음 블록으로 넘긴다.
가변·안 걸치기(unspanned): 다음 레코드가 남은 공간보다 크면 그 공간을 버린다."""


def fixed(B, R, n):
    bf = B // R
    blocks = -(-n // bf)
    return bf, blocks, B - bf * R          # 블록당 레코드, 필요한 블록 수, 블록당 낭비


def spanned(B, sizes):
    return -(-sum(sizes) // B)


def unspanned(B, sizes):
    blocks, left = 0, 0
    for s in sizes:
        assert s <= B, "안 걸치기는 블록보다 큰 레코드를 담을 수 없다"
        if s > left:
            blocks += 1; left = B
        left -= s
    return blocks


if __name__ == "__main__":
    # 카드·예: 블록 1,024바이트, 레코드 100바이트, 레코드 1,000개
    assert fixed(1024, 100, 1000) == (10, 100, 24)
    # 가변 길이 레코드 300, 500, 400, 200, 600, 100 (합 2,100) 블록 1,024
    sizes = [300, 500, 400, 200, 600, 100]
    assert spanned(1024, sizes) == 3                 # 2100 / 1024 올림
    assert unspanned(1024, sizes) == 3               # [300,500] [400,200] [600,100]
    sizes2 = [600, 600, 600]
    assert spanned(1024, sizes2) == 2 and unspanned(1024, sizes2) == 3
    assert fixed(1024, 300, 1)[0] == 3 and fixed(1024, 300, 1)[2] == 124
    print("ALL CHECKS PASSED")