codexinteger-interval-and-batch-counts.py
integer-interval-and-batch-counts.py
"""Exact integer counts, contrasted with ceiling capacity requirements."""
from pathlib import Path
import math
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np
def main():
plt.rcParams.update({"font.size": 11, "figure.facecolor": "white"})
fig, (interval, batch) = plt.subplots(1, 2, figsize=(11.6, 5.8),
layout="constrained")
cases = [(-2.7, 1.1), (-2, 2), (.2, 4.7), (.2, .8)]
lattice = np.arange(-3, 6)
for row, (a, b) in enumerate(cases):
y = 3 - row
selected = lattice[(lattice >= a) & (lattice <= b)]
count = max(0, math.floor(b) - math.ceil(a) + 1)
assert len(selected) == count
interval.plot(lattice, np.full_like(lattice, y), color="#d4dde1", lw=.8)
interval.plot([a, b], [y, y], color="#c26030", lw=4,
solid_capstyle="butt", alpha=.7)
interval.scatter(lattice, np.full_like(lattice, y), color="#b6c2c9",
s=30, zorder=3)
interval.scatter(selected, np.full_like(selected, y), color="#167e8d",
s=48, zorder=4)
endpoint_colors = ["#167e8d" if float(value).is_integer() else "#c26030"
for value in (a, b)]
interval.scatter([a, b], [y, y], facecolors=endpoint_colors,
edgecolors="#c26030", s=43, linewidths=1.3, zorder=5)
interval.text(-3.35, y + .30, f"[{a:g}, {b:g}]: {count} integer points",
fontsize=11)
interval.set(title="Real endpoints choose the allowed integers",
xlabel="Real number line", xlim=(-3.5, 5.3), ylim=(-.5, 3.75),
xticks=lattice, yticks=[])
interval.spines[["top", "right", "left"]].set_visible(False)
interval.text(-3.35, -.33, "Blue points are counted; orange bars show closed intervals.",
fontsize=9)
items, capacity = 102, 20
batches = math.ceil(items / capacity)
assert batches == 6 and (batches - 1) * capacity < items <= batches * capacity
for index in range(batches):
x, y = index % 3 * 1.42, 1 - index // 3 * 1.18
used = min(capacity, max(0, items - index * capacity))
batch.add_patch(Rectangle((x - .08, y - .08), 1.12, .92,
facecolor="white", edgecolor="#8396a2", lw=1.2))
for place in range(capacity):
px, py = place % 5, place // 5
batch.add_patch(Rectangle((x + .2 * px, y + .2 * py), .16, .16,
facecolor="#167e8d" if place < used else "#e4ebee",
edgecolor="white", lw=.4))
batch.text(x + .46, y - .27, f"Batch {index + 1}: {used}/20",
ha="center", fontsize=10)
batch.text(1.85, 2.02, r"$\lceil102/20\rceil=6$", ha="center", fontsize=17)
batch.text(1.85, -.93, "5 full batches + 1 with two items\n18 unused places",
ha="center", fontsize=12, linespacing=1.5)
batch.set(title="A partly filled batch still counts as one",
xlim=(-.26, 4.2), ylim=(-1.27, 2.35))
batch.set_aspect("equal")
batch.set_axis_off()
fig.suptitle("Floor and ceiling turn boundaries into exact discrete counts", fontsize=17)
fig.get_layout_engine().set(rect=(0, .065, 1, .90))
fig.text(.5, .017, "Interval length differs from its integer-point count; complete groups differ from sufficient capacity.",
ha="center", fontsize=10)
fig.savefig(Path(__file__).with_suffix(".png").name, dpi=100, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()