Ten states do not split into three equal piles.
EastRiver SourceControl starts with a common shortcut. Draw a uniform integer, then use value % choices to select an item. If the source has ten possible values and the destination has three choices, one choice receives four source values. The others receive three each. The result is 40, 30, and 30 percent instead of equal thirds.[1]
The random generator did its job. The mapping changed the distribution. The bug sits between a low-level number API and the job the application meant to perform.
A random number is raw stock. A random choice is the finished part.
Reject the tail or use the library.
One unbiased mapping accepts the largest prefix of source states that divides evenly by the choice count. It rejects any states left in the tail and draws again. In the ten-state example, values zero through eight form three equal groups. Value nine returns to the hopper.
Application code should usually call the language's range or choice function instead. Python documents uniform integer selection with randrange() and uniform sequence selection with choice(). It also provides choices() when relative weights are intentional.[2] Rust's rand crate provides random_range for one sample and Uniform for repeated sampling between bounds.[3]
Name the distribution in the review.
A reviewer should not have to infer intent from arithmetic. Write whether the selection is uniform or weighted. Name the source API, the destination count, and the test that would expose a heavy bucket. If repeatability matters, record the generator and seed too. A seed can replay the same biased mapping perfectly.
The distributor below makes the mapping visible. It is a finite teaching model. It does not test an actual random generator, prove statistical quality, or select a security-safe API.