Implement chunks(items, size) returning a list of lists of at most size items each, in order. The last chunk may be shorter. Raise ValueError if size < 1.
Also implement chunk_evenly(items, n): split into exactly n chunks whose lengths differ by at most one, with longer chunks first (like np.array_split).