# hospitality.recipe-scale Scales a recipe from the number of portions it makes to the number wanted, and writes each quantity the way a kitchen would weigh it. ## The rules The scaling itself is exact: the quantity is decimal text, multiplied by `toPortions / fromPortions` as a fraction. Then each quantity is rounded **once**, half-up: | unit | rounded to | written in | |---|---|---| | mg, g, kg | whole grams from 10 g, 0.1 g from 1 to 10 g, 0.01 g below 1 g | g, or kg from 1000 g | | mL, L | the same steps in millilitres | mL, or L from 1000 mL | | each | always **up** to a whole number: half an egg short is short | each | | anything else (oz, lb, cup_us, tbsp, sprig...) | 2 decimal places | unchanged | So 500 g for 4 is 1.25 kg for 10, 1.2 kg for 4 is 600 g for 2, and 666.4 g scaled by 1.5 is 999.6 g, which rounds to 1000 g and is written `1` kg. Metric amounts are converted with `units.convert`; the kilogram and litre forms keep up to 3 decimal places, which is whole grams and millilitres. Imperial and cup measures stay in their unit rather than being converted to metric, because a cook reading a cup recipe expects cups back. Units the registry does not know (tbsp, sprig, pinch) are scaled as written. ## Limits and errors - Portions are whole numbers from 1 to 10000. - A quantity is non-negative decimal text (`"0.5"`, not `"1/2"`), at most 15 significant digits and 15 decimal places. Trailing zeros are ignored. - The unit must not be empty. ## Not covered Scaling is linear. Real kitchens don't always scale linearly: seasoning, leavening, and cooking times and pan sizes often need adjusting by hand when a recipe is multiplied many times over. 1.0.1 fixes Python accepting a trailing newline in quantity; adds tests.