The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
Run the corner procedure ISO 16283 makes mandatory under 25 m3 (#652)
* Run the corner procedure ISO 16283 makes mandatory under 25 m3
The field entry point of the package promised the core 100 Hz to 3150 Hz range
and nothing else, which was neither what the code did nor what a field engineer
needs. ISO 16283 makes the corner procedure mandatory, not optional, for the
50 Hz, 63 Hz and 80 Hz bands whenever the room volume, calculated to the
nearest cubic metre, is smaller than 25 m3, and that is most bedrooms and every
bathroom. Handed nineteen bands, airborne_insulation answered at 50, 63 and
80 Hz from the default procedure alone, which in a room that small is not the
ISO 16283 quantity.
The three parts state one procedure, so building/measurement/low_frequency.py
writes it once. L_Corner is the highest of the measured corners band by band,
which may be three different corners, energy-averaged over the source positions
(Part 1 Formula (12), Part 2 Formula (15); the q = 1 case is all Part 3 prints,
in its Clause 7.3.4 prose). L_LF weighs it one third against two thirds of the
default level, Formulae (13), (16) and (5) being identical but for the
subscripts. Airborne, impact and facade all reach that code through a
LowFrequencyProcedure, and a conformance row says so rather than a test alone.
Clause 10.4 comes with it: under the same trigger one 63 Hz octave reverberation
time replaces the three one-third-octave ones. It is a receiving-room clause in
all three parts, including the one whose corner procedure also admits the source
room, so a small source room beside a large receiving room moves L1 and leaves T
as measured. Part 3 confines the whole procedure to the loudspeaker methods and
now refuses to answer with road traffic.
Two boundaries are printed numbers and are pinned as such. The trigger rounds
half away from zero the way the rest of the tree rounds a printed quantity, so
24,5 m3 becomes 25 m3 and does not trigger where Python's own round would say 24
and would; and "smaller than" is strict, so 25 m3 exactly takes the default
procedure. Above the line the procedure is refused rather than answered, because
no part of the standard says what a corner measurement means there.
None of this has a numeric oracle. Annex B of Part 1 and Annex C of Part 2 are
blank recording forms and the Annex D and E "Examples" are loudspeaker-position
drawings, so the eight new conformance rows judge the printed trigger, the
printed band set and the closed forms of Formula (13): it degenerates to L when
the corner level equals it, rises with the corner level, and cannot fall below
10 lg(2/3) + L. The reason Clause 10.4 gives for the octave band is measured
rather than asserted, by putting a known single-sloped decay through the
reverberation machinery already here and seeing the 63 Hz octave recover it
better than the three one-third-octave bands do.
Two defects of ISO 16283-2 join the errata registry, both confirmed in the
published and the draft print. Clause 8.3 sends the reader to calculate the
low-frequency level "for the source and/or receiving room" of an impact
measurement, which has no source-room level, and Clause 10.3 prints "larger than
25 m3" where Parts 1 and 3 print "or equal to", leaving a receiving room of
exactly 25 m3 with no frequency range at all.
The impact docstrings were still citing the draft's numbering while the module
implements the 2020 edition: L'n is Clause 3.15 Formula (3) there, the Sabine
area is Formula (2), and the energy average of levels is Formula (11).
* Give the corner procedure a page, and show what it costs the rating
The low-frequency procedure arrived as code with a section inside the field
guide, and that was the wrong shape for it. It is mandatory in most of the
rooms this library gets pointed at, its trigger has a boundary worth spelling
out one word at a time, it differs between the three parts in ways that change
the answer, and no part of ISO 16283 publishes a worked example of it. That is
a page, not a section of somebody else's.
buildings/insulation/low-frequency-procedure gathers the whole of it: the 25 m3
trigger with its rounding and its strict comparison, the corner level of
Formula (12) and what the energy mean over source positions does to it (the
reported corner level is not the loudest corner of the campaign, and the figure
shows a corner above it), the closed forms of Formula (13), the 63 Hz octave
reverberation time of Clause 10.4 with the two NOTES that justify it, and a
table of which room and which source each part states the procedure for. What
the standard asks of the corner measurement is set out beside what the library
actually checks, which is one requirement of six. The field guide keeps a short
version and sends the reader on; the facade guide's cross-reference follows,
and so do both Spanish twins.
The figure is one field measurement in a bedroom of 3.6 m by 2.7 m by 2.4 m,
23 m3 to the nearest cubic metre. The left panel draws the eight corner
measurements the maximum is picked out of, in two columns per band so that no
marker is buried under the reported one, and shades what Formula (13) adds.
The right panel answers the question a field engineer actually has: DnT,w does
not move, because ISO 717-1 reads it over 100 Hz to 3150 Hz and never sees
these bands, while C50-3150, which does see them, moves a whole decibel. Both
readings are chips over clear ground, and the divider stops short of one rather
than vanishing behind it.
The oracle problem gets a section rather than a footnote. Annex B of Part 1 and
Annex C of Part 2 are blank recording forms and the Annex D and E "Examples"
are loudspeaker-position drawings, so the page names what stands in for a
published result: the printed numbers, the three closed forms of Formula (13),
the reason Clause 10.4 gives measured rather than asserted, and the conformance
row that makes "one implementation" a checked fact.
No new errata. Two candidates were read from the rendered page and both fall
below the bar the registry keeps: ISO 16283-3 Clause 8.4 prints a stray comma
inside the last subscript of its quantity list, which is typography nothing
reads, and ISO 16283-1 Clause 8.3 sends the reader to "Formula (1) and
Formula (4)" for R' without naming Formula (5) for the absorption area, which
the reverberation-time clause supplies anyway. The two ISO 16283-2 defects this
procedure does run into are already recorded.
* Say so when a small room is answered without the corner procedure
Implementing the procedure did not stop the library giving the wrong answer to
the caller who has not heard of it. The bedroom the guide page works through,
3.6 m by 2.7 m by 2.4 m, is 23 m3 to the nearest cubic metre, and
airborne_insulation handed its volume and its nineteen band centres still
returned DnT of 35.6, 33.9 and 36.9 dB where ISO 16283 says 31.7, 29.7 and
33.3 dB. Nearly 4 dB in each of the three bands, C50-3150 moving from -1 dB to
-2 dB, and not a word. Clause 8.1 (Clause 7.3.1 in Part 3) is a shall, and the
volume and the band centres were both in hand already for other reasons: the
volume sizes the Sabine absorption area and the band centres label the
spectrum. Between them they are enough to know the procedure was owed.
So all three entry points now raise LowFrequencyWarning on that call. Warning
rather than refusing, deliberately: the corners may genuinely not have been
measured, and the default-procedure spectrum is what the ISO 16283 one gets
compared against, which is exactly what the guide page's own figure does. It
cannot fire when the caller ran the procedure, when no volume was given, when
the room does not trigger, when the band centres were not given, when the
optional low range of Clause 5 was not measured, or on a road-traffic facade,
which ISO 16283-3 Clause 6 gives the default procedure and nothing else. Only
the receiving room, because only its volume is an argument. The message names
the rounded volume, the clause and the argument to pass, and says what to do
instead; the two conditions the class now covers are told apart by message,
since the corner-count one does not move a number and this one moves several.
ISO 16283-1 Clause 6 joins the errata registry. It asks for the
reverberation-time low-frequency procedure "in the source and/or receiving
room", and ISO 16283-1 measures no source-room reverberation time: the same
clause says so three paragraphs earlier, and Clause 10 says it four times more,
in its heading, in 10.1, in 10.3 and in 10.4. Parts 2 and 3 print that sentence
with one room, so Part 1 is the outlier of the three. It is the same shape as
the ISO 16283-2 Clause 8.3 entry already recorded, and the phrase is correct
one paragraph above, where the sound pressure level really is measured in both
rooms. The ISO 16283-2 Clause 10.3 entry gains a witness: UNE-EN ISO 16283-2,
the Spanish translation of the 2015 edition, already prints "superior a 25 m3"
without the "o igual a", so that boundary gap has stood across two editions and
a revision rather than being a slip of the 2020 print.
Four survivors of a mutation audit are closed, three of them real gaps. The
facade path's use of the combined level was asserted nowhere, so deleting the
line that feeds it back left the suite green while the facade came out up to
4.4 dB better insulated than the standard says. The band lookup was only ever
exercised with 50, 63 and 80 Hz in the leading three columns, so reading the
leading three passed; a sheet that starts at 31.5 Hz now says otherwise. The
copies that protect the caller's own level and reverberation-time arrays were
untested, one of them killed only by accident through cross-test contamination.
And nothing pinned four corners as the quiet side of the printed minimum. The
array test builds its inputs from literals rather than the module fixtures,
because an implementation that wrote in place would have corrupted those long
before the comparison ran.
Three docstring claims were not true of the code. The entry points listed a
raise for a room that does not round below 25 m3, which LowFrequencyProcedure
makes at construction and they cannot reach. The module docstring named a
low_frequency argument the airborne pair does not have. And it gave the 16 core
bands to the ISO 717 rating, which also takes the 5 octave bands from 125 Hz to
2000 Hz; only the report fiche needs exactly the 16.
Two citations were wrong on the guide page and in the module. ISO 16283-2
Clause 9.1 does carry the per-corner background-noise requirement, word for
word as Part 1 prints it, so the asymmetry the comment implied does not exist.
And ISO 16283-3 Clause 7.3.2 prints "a minimum of four corners" without the
per-source-position qualifier its two siblings carry, and has no second
position to repeat them at.
The monotonicity of Formula (13) was listed among the closed forms standing in
for an oracle and nothing checked it; it is a conformance row now, sweeping the
corner level over 80 dB in 0.2 dB steps. That makes nine rows for the module,
and the five anchored in a closed form say "closed form" in their
expected-value cell, which is the phrase the guide page tells a reader to look
for. The page stops attributing the 63 Hz octave decay comparison to the
report, where it never was, and the ratings page gains the back-link the
enlarged-range section was missing: a reader computing C50-3150 lands there,
and that term is the one the corner procedure moves.
README_PYPI.md is regenerated. The guide row added to README.md was not carried
over, which left tests/test_packaging.py red.
* Warn on a low range measured in part, and count the paragraphs right
Three follow-ups from the last read of this branch.
The new warning required all three of 50, 63 and 80 Hz to be present before it
would fire, so a room under 25 m3 reporting only two of them still answered in
silence. A partially measured low range is as far outside ISO 16283 as a fully
measured one, and requiring the whole set left a hole in the check that exists
to close exactly this. Any one of the three is now enough; a band axis naming
none of them describes a measurement the clause does not reach, and that is
the only case that stays quiet.
The Clause 6 errata entry counted paragraphs wrong in both directions. Read
off the rendered page, that clause runs six paragraphs and a NOTE, so the
first is five paragraphs and a NOTE back rather than three, and the
sound-pressure-level paragraph is two above rather than one, one of those two
being the NOTE. The substance of the entry is untouched.
And the guide's worked example calls the library the way that now warns,
without saying so, which left a reader copying the block to wonder what they
had done wrong. It says so, in all three editions. The figure generator beside
it already caught the warning with a comment explaining why; the page should
teach its own instrument rather than trip over it.
* Count the guide the low-frequency procedure added
The guides index states its own total three ways, as a number in the
frontmatter description and as words in the body, in each language. Adding the
ISO 16283 page moved the total to 109 and left all four statements at 108, so
`check:guides` was red on this branch.
The check is worth having for exactly this reason: the index links all 109
correctly, so nothing was missing from the map. What drifted was the sentence
that counts them, which no reader would have doubted.
* Give Clause 10.4's substitution its own function
Two things, both narrow.
The 63 Hz octave substitution was an if/else inside the determination, and it
is a self-contained rule: Clause 10.4 of ISO 16283-1 and -2, and Clause 8.4 of
ISO 16283-3, put the octave time in place of the three one-third-octave values,
in the receiving room and nowhere else. It is now one function, so every
refusal on either side sits beside the clause it comes from and the source
room simply has nothing to substitute. Cognitive complexity of the entry point
goes from 16 to under 8.
And six pytest.raises blocks built their procedure inside the block. If
building it ever raised, the test would pass without the call it exists to
check ever running.
* Test the refusals that had none
Six guards raised without a single test reaching them: an empty corner sheet,
empty level and corner arrays, a non-finite value on either side of the
combination, reverberation times that cover a different band axis than the
levels, and a level array with more than one dimension. Each states a real
contract, and an untested raise is a raise that can stop working quietly.
low_frequency.py goes from 94% to 100% line coverage.
* Say what warns, cite what the standard prints, and refuse a rank on arrival
Three corrections and a changelog entry.
"All three warn when you forget" was not true. A road-traffic facade is
exempt: Clause 6 of ISO 16283-3 gives those methods the default procedure and
nothing else, so there is nothing to have forgotten, which is a different
thing from the library choosing to stay quiet. Measured rather than read: with
a 23 m3 room and the three bands on the axis, the loudspeaker facade raises
the warning and the road-traffic one is silent.
Two ISO 16283-2 citations named the wrong clause. The standard puts the
equivalent absorption area A in Clause 3.14 with Formula (2), and the
normalized impact sound pressure level L_n in Clause 3.15 with Formula (3);
A_0 has no clause of its own, being a term of that formula. The module
docstring gave A_0 the L_n citation and the l_n attribute gave L_n the area
one. Every other ISO 16283 citation in the file was checked against the three
printed parts and holds.
LowFrequencyProcedure accepted corner sheets of any rank and left the refusal
to corner_level, so a one-dimensional or four-dimensional sheet built fine and
failed later, in a function the caller never named. It refuses on arrival now.
And a Spanish agreement error, in both places it appeared: demasiado is
invariable before an adjective.
* Give the changelog the trigger the code actually has
The entry said the procedure is mandatory below 25 m3, which is the shape of
the rule but not its edges. The volume is rounded to the nearest cubic metre
with halves going up, so 24.4 triggers and 24.5 does not, and a road-traffic
facade never triggers at any volume because Clause 6 of ISO 16283-3 gives
those methods the default procedure and nothing else.
Both numbers are measured against the implementation rather than reasoned
from the rounding rule: 24.5 reads as the boundary going the other way than
it looks.
* Name the clause each part actually prints, and the work frequencies still does
Two guide paragraphs describing all three measurement entry points said
Clause 8.1 had come into force, which is true of Parts 1 and 2 and not of the
loudspeaker facade, whose trigger is Clause 7.3.1 of Part 3. The module and
the conformance registry already made that distinction; the prose now makes
it too, in the six editions that carried the sentence.
The parameter tables said frequencies was ignored without a low-frequency
argument, and it is not: naming the three bands beside a small volume is
exactly what tells the function the procedure was owed and makes it warn.
Fixed in the two docstrings the tables are generated from, and regenerated.
Two prose occurrences of facade in the field guide take the cedilla the rest
of the page uses; identifiers keep their ASCII.
* Say which low bands were named, and refuse an axis that names none of them truthfully
The missing-procedure warning fired on any of the three low-frequency bands,
deliberately, and then claimed all three had been named. Worse than the false
sentence was the advice: a caller with a partial low range who followed it
into passing a LowFrequencyProcedure ran straight into the band-axis check,
which runs on the three together. The warning now names the bands actually
found and, when the set is incomplete, says to complete the low range first
or leave it out. The guides described the same trigger as requiring all
three; they say any of the three now, in the six editions.
The frequencies vector was read even without a procedure, to decide whether
to warn, and nothing checked it against the measured bands on that path: a
three-entry vector against five measured bands would have keyed the warning
on columns the data does not have. All three entry points now refuse a
vector that is not one band centre per measured band, on entry, with the
counts named. The facade entry point had its own later version of that check
with its own wording; there is one now. A test that pinned the old silence
for a (1, bands) axis pins the refusal instead.
The changelog described airborne_insulation as taking a low_frequency
argument it does not have; it takes one procedure per room of the pair. The
printed 25 m3 limit in the reference data was defined and never read; the
trigger case for the limit itself is built from it now. Three lines that
broke their files' hard-wrap convention are rewrapped.
* Hold the narrative to the trigger it describes, and the band axis to finite centres
Two docstring paragraphs still said the warning needed the three bands named
when the trigger fires on any of them, contradicting the parameter tables
generated two sections below from the same file. They read as the code
behaves now, and the API pages are regenerated from them.
A NaN band centre answered False to every band comparison and slipped past
the warning's band test in silence, which is exactly the failure mode the
entry check exists to close, and a facade result would have carried it as a
plot coordinate. The axis check refuses non-finite centres by name, with a
test pinning the NaN case.
* Walk the band lister's rank guard where the entry points no longer can
The entry points now refuse a two-dimensional band axis before
_named_low_frequency_bands runs, which left the helper's own rank guard
unreachable from them and uncovered. The guard stays, because the helper is
the module's answer to which low bands an axis names and a future caller
must get the same empty answer; a direct test walks it and says why.
* Refuse the volumes that are not volumes, and say only what the corners must do
A NaN receiving-room volume sailed through every entry point's positivity
check, because NaN answers False to <= as readily as to >, and the facade
result then carried NaN levels; a test even pinned that behaviour as a known
separate defect. All three entry points now refuse NaN through the NaN-safe
comparison and infinity by name, and the test pins the refusal.
The prose overstated in four places what this branch delivers. The corner
procedure can move the three low bands by several decibels and the adaptation
term with them, but Formula (13) leaves a band untouched when the corner
level equals the default one, so the ratings guide no longer promises
movement unconditionally. The insulation index now carries the road-traffic
exception and the rounded-volume boundary the linked guide states, and its
pointer cites Clause 8.4 beside 10.4 for the facade. The reverberation
substitution paragraph names the receiving room as the trigger's owner, since
a small source room never substitutes anything. A dangling "unchanged" in the
module docstring reads as the adverb it was meant to be, and the API page is
regenerated from it.
* Give R' a gatekeeper of its own, and a test to every refusal
Sonar counted airborne_insulation past the cognitive-complexity gate, and the
weight was the apparent sound reduction index: the paired-geometry check, the
positivity and finiteness gates and Formula (4) all sat inline under the
low-frequency branching. _apparent_reduction_index() now owns that block, the
messages unchanged, and the function reads as the three quantities it returns.
The refusals themselves were asserted nowhere: a zero, negative, NaN or
infinite geometry raised the right message with no test holding it, in the
airborne, impact and facade entry points alike. Each refusal now has one,
NaN grouped with the non-positives because that is what the `not x > 0`
spelling is for, and infinity on its own because it passes that gate and is
refused by name.
The stand-aside guard of the low-frequency warning helper is reachable only
by calling the helper directly, since every entry point complains about a
broken volume before the helper runs; a direct test now pins that silence
instead of leaving the line as dead weight in the coverage report.
Rate a lining and a floor covering on their reference elements, and measure the sound of rain on a roof, by ISO 10140-1:2021 (#906)
A lining measured without and with it now gives its improvement band by band and its single numbers on the standard basic element of ISO 717-1:2020 Annex D, a floor covering gives its reduction of impact level on the heavyweight reference floor or on any of the three lightweight ones, and the sound of artificial rain on a roof, a roof window or a rooflight comes out as its intensity level, its A-weighted value and its normalized level against the reference glass pane. The reference curves of ISO 717-1 Table E.1 and ISO 717-2 Table 4, and the rain tables of ISO 10140-1 and ISO 10140-5, are published read-only tables, every result has a plot in English and Spanish, and a new guide walks the three annexes through a worked lining, a vinyl on a timber floor and a rooflight under heavy rain.
Run the corner procedure ISO 16283 makes mandatory under 25 m3 (#652)
* Run the corner procedure ISO 16283 makes mandatory under 25 m3
The field entry point of the package promised the core 100 Hz to 3150 Hz range
and nothing else, which was neither what the code did nor what a field engineer
needs. ISO 16283 makes the corner procedure mandatory, not optional, for the
50 Hz, 63 Hz and 80 Hz bands whenever the room volume, calculated to the
nearest cubic metre, is smaller than 25 m3, and that is most bedrooms and every
bathroom. Handed nineteen bands, airborne_insulation answered at 50, 63 and
80 Hz from the default procedure alone, which in a room that small is not the
ISO 16283 quantity.
The three parts state one procedure, so building/measurement/low_frequency.py
writes it once. L_Corner is the highest of the measured corners band by band,
which may be three different corners, energy-averaged over the source positions
(Part 1 Formula (12), Part 2 Formula (15); the q = 1 case is all Part 3 prints,
in its Clause 7.3.4 prose). L_LF weighs it one third against two thirds of the
default level, Formulae (13), (16) and (5) being identical but for the
subscripts. Airborne, impact and facade all reach that code through a
LowFrequencyProcedure, and a conformance row says so rather than a test alone.
Clause 10.4 comes with it: under the same trigger one 63 Hz octave reverberation
time replaces the three one-third-octave ones. It is a receiving-room clause in
all three parts, including the one whose corner procedure also admits the source
room, so a small source room beside a large receiving room moves L1 and leaves T
as measured. Part 3 confines the whole procedure to the loudspeaker methods and
now refuses to answer with road traffic.
Two boundaries are printed numbers and are pinned as such. The trigger rounds
half away from zero the way the rest of the tree rounds a printed quantity, so
24,5 m3 becomes 25 m3 and does not trigger where Python's own round would say 24
and would; and "smaller than" is strict, so 25 m3 exactly takes the default
procedure. Above the line the procedure is refused rather than answered, because
no part of the standard says what a corner measurement means there.
None of this has a numeric oracle. Annex B of Part 1 and Annex C of Part 2 are
blank recording forms and the Annex D and E "Examples" are loudspeaker-position
drawings, so the eight new conformance rows judge the printed trigger, the
printed band set and the closed forms of Formula (13): it degenerates to L when
the corner level equals it, rises with the corner level, and cannot fall below
10 lg(2/3) + L. The reason Clause 10.4 gives for the octave band is measured
rather than asserted, by putting a known single-sloped decay through the
reverberation machinery already here and seeing the 63 Hz octave recover it
better than the three one-third-octave bands do.
Two defects of ISO 16283-2 join the errata registry, both confirmed in the
published and the draft print. Clause 8.3 sends the reader to calculate the
low-frequency level "for the source and/or receiving room" of an impact
measurement, which has no source-room level, and Clause 10.3 prints "larger than
25 m3" where Parts 1 and 3 print "or equal to", leaving a receiving room of
exactly 25 m3 with no frequency range at all.
The impact docstrings were still citing the draft's numbering while the module
implements the 2020 edition: L'n is Clause 3.15 Formula (3) there, the Sabine
area is Formula (2), and the energy average of levels is Formula (11).
* Give the corner procedure a page, and show what it costs the rating
The low-frequency procedure arrived as code with a section inside the field
guide, and that was the wrong shape for it. It is mandatory in most of the
rooms this library gets pointed at, its trigger has a boundary worth spelling
out one word at a time, it differs between the three parts in ways that change
the answer, and no part of ISO 16283 publishes a worked example of it. That is
a page, not a section of somebody else's.
buildings/insulation/low-frequency-procedure gathers the whole of it: the 25 m3
trigger with its rounding and its strict comparison, the corner level of
Formula (12) and what the energy mean over source positions does to it (the
reported corner level is not the loudest corner of the campaign, and the figure
shows a corner above it), the closed forms of Formula (13), the 63 Hz octave
reverberation time of Clause 10.4 with the two NOTES that justify it, and a
table of which room and which source each part states the procedure for. What
the standard asks of the corner measurement is set out beside what the library
actually checks, which is one requirement of six. The field guide keeps a short
version and sends the reader on; the facade guide's cross-reference follows,
and so do both Spanish twins.
The figure is one field measurement in a bedroom of 3.6 m by 2.7 m by 2.4 m,
23 m3 to the nearest cubic metre. The left panel draws the eight corner
measurements the maximum is picked out of, in two columns per band so that no
marker is buried under the reported one, and shades what Formula (13) adds.
The right panel answers the question a field engineer actually has: DnT,w does
not move, because ISO 717-1 reads it over 100 Hz to 3150 Hz and never sees
these bands, while C50-3150, which does see them, moves a whole decibel. Both
readings are chips over clear ground, and the divider stops short of one rather
than vanishing behind it.
The oracle problem gets a section rather than a footnote. Annex B of Part 1 and
Annex C of Part 2 are blank recording forms and the Annex D and E "Examples"
are loudspeaker-position drawings, so the page names what stands in for a
published result: the printed numbers, the three closed forms of Formula (13),
the reason Clause 10.4 gives measured rather than asserted, and the conformance
row that makes "one implementation" a checked fact.
No new errata. Two candidates were read from the rendered page and both fall
below the bar the registry keeps: ISO 16283-3 Clause 8.4 prints a stray comma
inside the last subscript of its quantity list, which is typography nothing
reads, and ISO 16283-1 Clause 8.3 sends the reader to "Formula (1) and
Formula (4)" for R' without naming Formula (5) for the absorption area, which
the reverberation-time clause supplies anyway. The two ISO 16283-2 defects this
procedure does run into are already recorded.
* Say so when a small room is answered without the corner procedure
Implementing the procedure did not stop the library giving the wrong answer to
the caller who has not heard of it. The bedroom the guide page works through,
3.6 m by 2.7 m by 2.4 m, is 23 m3 to the nearest cubic metre, and
airborne_insulation handed its volume and its nineteen band centres still
returned DnT of 35.6, 33.9 and 36.9 dB where ISO 16283 says 31.7, 29.7 and
33.3 dB. Nearly 4 dB in each of the three bands, C50-3150 moving from -1 dB to
-2 dB, and not a word. Clause 8.1 (Clause 7.3.1 in Part 3) is a shall, and the
volume and the band centres were both in hand already for other reasons: the
volume sizes the Sabine absorption area and the band centres label the
spectrum. Between them they are enough to know the procedure was owed.
So all three entry points now raise LowFrequencyWarning on that call. Warning
rather than refusing, deliberately: the corners may genuinely not have been
measured, and the default-procedure spectrum is what the ISO 16283 one gets
compared against, which is exactly what the guide page's own figure does. It
cannot fire when the caller ran the procedure, when no volume was given, when
the room does not trigger, when the band centres were not given, when the
optional low range of Clause 5 was not measured, or on a road-traffic facade,
which ISO 16283-3 Clause 6 gives the default procedure and nothing else. Only
the receiving room, because only its volume is an argument. The message names
the rounded volume, the clause and the argument to pass, and says what to do
instead; the two conditions the class now covers are told apart by message,
since the corner-count one does not move a number and this one moves several.
ISO 16283-1 Clause 6 joins the errata registry. It asks for the
reverberation-time low-frequency procedure "in the source and/or receiving
room", and ISO 16283-1 measures no source-room reverberation time: the same
clause says so three paragraphs earlier, and Clause 10 says it four times more,
in its heading, in 10.1, in 10.3 and in 10.4. Parts 2 and 3 print that sentence
with one room, so Part 1 is the outlier of the three. It is the same shape as
the ISO 16283-2 Clause 8.3 entry already recorded, and the phrase is correct
one paragraph above, where the sound pressure level really is measured in both
rooms. The ISO 16283-2 Clause 10.3 entry gains a witness: UNE-EN ISO 16283-2,
the Spanish translation of the 2015 edition, already prints "superior a 25 m3"
without the "o igual a", so that boundary gap has stood across two editions and
a revision rather than being a slip of the 2020 print.
Four survivors of a mutation audit are closed, three of them real gaps. The
facade path's use of the combined level was asserted nowhere, so deleting the
line that feeds it back left the suite green while the facade came out up to
4.4 dB better insulated than the standard says. The band lookup was only ever
exercised with 50, 63 and 80 Hz in the leading three columns, so reading the
leading three passed; a sheet that starts at 31.5 Hz now says otherwise. The
copies that protect the caller's own level and reverberation-time arrays were
untested, one of them killed only by accident through cross-test contamination.
And nothing pinned four corners as the quiet side of the printed minimum. The
array test builds its inputs from literals rather than the module fixtures,
because an implementation that wrote in place would have corrupted those long
before the comparison ran.
Three docstring claims were not true of the code. The entry points listed a
raise for a room that does not round below 25 m3, which LowFrequencyProcedure
makes at construction and they cannot reach. The module docstring named a
low_frequency argument the airborne pair does not have. And it gave the 16 core
bands to the ISO 717 rating, which also takes the 5 octave bands from 125 Hz to
2000 Hz; only the report fiche needs exactly the 16.
Two citations were wrong on the guide page and in the module. ISO 16283-2
Clause 9.1 does carry the per-corner background-noise requirement, word for
word as Part 1 prints it, so the asymmetry the comment implied does not exist.
And ISO 16283-3 Clause 7.3.2 prints "a minimum of four corners" without the
per-source-position qualifier its two siblings carry, and has no second
position to repeat them at.
The monotonicity of Formula (13) was listed among the closed forms standing in
for an oracle and nothing checked it; it is a conformance row now, sweeping the
corner level over 80 dB in 0.2 dB steps. That makes nine rows for the module,
and the five anchored in a closed form say "closed form" in their
expected-value cell, which is the phrase the guide page tells a reader to look
for. The page stops attributing the 63 Hz octave decay comparison to the
report, where it never was, and the ratings page gains the back-link the
enlarged-range section was missing: a reader computing C50-3150 lands there,
and that term is the one the corner procedure moves.
README_PYPI.md is regenerated. The guide row added to README.md was not carried
over, which left tests/test_packaging.py red.
* Warn on a low range measured in part, and count the paragraphs right
Three follow-ups from the last read of this branch.
The new warning required all three of 50, 63 and 80 Hz to be present before it
would fire, so a room under 25 m3 reporting only two of them still answered in
silence. A partially measured low range is as far outside ISO 16283 as a fully
measured one, and requiring the whole set left a hole in the check that exists
to close exactly this. Any one of the three is now enough; a band axis naming
none of them describes a measurement the clause does not reach, and that is
the only case that stays quiet.
The Clause 6 errata entry counted paragraphs wrong in both directions. Read
off the rendered page, that clause runs six paragraphs and a NOTE, so the
first is five paragraphs and a NOTE back rather than three, and the
sound-pressure-level paragraph is two above rather than one, one of those two
being the NOTE. The substance of the entry is untouched.
And the guide's worked example calls the library the way that now warns,
without saying so, which left a reader copying the block to wonder what they
had done wrong. It says so, in all three editions. The figure generator beside
it already caught the warning with a comment explaining why; the page should
teach its own instrument rather than trip over it.
* Count the guide the low-frequency procedure added
The guides index states its own total three ways, as a number in the
frontmatter description and as words in the body, in each language. Adding the
ISO 16283 page moved the total to 109 and left all four statements at 108, so
`check:guides` was red on this branch.
The check is worth having for exactly this reason: the index links all 109
correctly, so nothing was missing from the map. What drifted was the sentence
that counts them, which no reader would have doubted.
* Give Clause 10.4's substitution its own function
Two things, both narrow.
The 63 Hz octave substitution was an if/else inside the determination, and it
is a self-contained rule: Clause 10.4 of ISO 16283-1 and -2, and Clause 8.4 of
ISO 16283-3, put the octave time in place of the three one-third-octave values,
in the receiving room and nowhere else. It is now one function, so every
refusal on either side sits beside the clause it comes from and the source
room simply has nothing to substitute. Cognitive complexity of the entry point
goes from 16 to under 8.
And six pytest.raises blocks built their procedure inside the block. If
building it ever raised, the test would pass without the call it exists to
check ever running.
* Test the refusals that had none
Six guards raised without a single test reaching them: an empty corner sheet,
empty level and corner arrays, a non-finite value on either side of the
combination, reverberation times that cover a different band axis than the
levels, and a level array with more than one dimension. Each states a real
contract, and an untested raise is a raise that can stop working quietly.
low_frequency.py goes from 94% to 100% line coverage.
* Say what warns, cite what the standard prints, and refuse a rank on arrival
Three corrections and a changelog entry.
"All three warn when you forget" was not true. A road-traffic facade is
exempt: Clause 6 of ISO 16283-3 gives those methods the default procedure and
nothing else, so there is nothing to have forgotten, which is a different
thing from the library choosing to stay quiet. Measured rather than read: with
a 23 m3 room and the three bands on the axis, the loudspeaker facade raises
the warning and the road-traffic one is silent.
Two ISO 16283-2 citations named the wrong clause. The standard puts the
equivalent absorption area A in Clause 3.14 with Formula (2), and the
normalized impact sound pressure level L_n in Clause 3.15 with Formula (3);
A_0 has no clause of its own, being a term of that formula. The module
docstring gave A_0 the L_n citation and the l_n attribute gave L_n the area
one. Every other ISO 16283 citation in the file was checked against the three
printed parts and holds.
LowFrequencyProcedure accepted corner sheets of any rank and left the refusal
to corner_level, so a one-dimensional or four-dimensional sheet built fine and
failed later, in a function the caller never named. It refuses on arrival now.
And a Spanish agreement error, in both places it appeared: demasiado is
invariable before an adjective.
* Give the changelog the trigger the code actually has
The entry said the procedure is mandatory below 25 m3, which is the shape of
the rule but not its edges. The volume is rounded to the nearest cubic metre
with halves going up, so 24.4 triggers and 24.5 does not, and a road-traffic
facade never triggers at any volume because Clause 6 of ISO 16283-3 gives
those methods the default procedure and nothing else.
Both numbers are measured against the implementation rather than reasoned
from the rounding rule: 24.5 reads as the boundary going the other way than
it looks.
* Name the clause each part actually prints, and the work frequencies still does
Two guide paragraphs describing all three measurement entry points said
Clause 8.1 had come into force, which is true of Parts 1 and 2 and not of the
loudspeaker facade, whose trigger is Clause 7.3.1 of Part 3. The module and
the conformance registry already made that distinction; the prose now makes
it too, in the six editions that carried the sentence.
The parameter tables said frequencies was ignored without a low-frequency
argument, and it is not: naming the three bands beside a small volume is
exactly what tells the function the procedure was owed and makes it warn.
Fixed in the two docstrings the tables are generated from, and regenerated.
Two prose occurrences of facade in the field guide take the cedilla the rest
of the page uses; identifiers keep their ASCII.
* Say which low bands were named, and refuse an axis that names none of them truthfully
The missing-procedure warning fired on any of the three low-frequency bands,
deliberately, and then claimed all three had been named. Worse than the false
sentence was the advice: a caller with a partial low range who followed it
into passing a LowFrequencyProcedure ran straight into the band-axis check,
which runs on the three together. The warning now names the bands actually
found and, when the set is incomplete, says to complete the low range first
or leave it out. The guides described the same trigger as requiring all
three; they say any of the three now, in the six editions.
The frequencies vector was read even without a procedure, to decide whether
to warn, and nothing checked it against the measured bands on that path: a
three-entry vector against five measured bands would have keyed the warning
on columns the data does not have. All three entry points now refuse a
vector that is not one band centre per measured band, on entry, with the
counts named. The facade entry point had its own later version of that check
with its own wording; there is one now. A test that pinned the old silence
for a (1, bands) axis pins the refusal instead.
The changelog described airborne_insulation as taking a low_frequency
argument it does not have; it takes one procedure per room of the pair. The
printed 25 m3 limit in the reference data was defined and never read; the
trigger case for the limit itself is built from it now. Three lines that
broke their files' hard-wrap convention are rewrapped.
* Hold the narrative to the trigger it describes, and the band axis to finite centres
Two docstring paragraphs still said the warning needed the three bands named
when the trigger fires on any of them, contradicting the parameter tables
generated two sections below from the same file. They read as the code
behaves now, and the API pages are regenerated from them.
A NaN band centre answered False to every band comparison and slipped past
the warning's band test in silence, which is exactly the failure mode the
entry check exists to close, and a facade result would have carried it as a
plot coordinate. The axis check refuses non-finite centres by name, with a
test pinning the NaN case.
* Walk the band lister's rank guard where the entry points no longer can
The entry points now refuse a two-dimensional band axis before
_named_low_frequency_bands runs, which left the helper's own rank guard
unreachable from them and uncovered. The guard stays, because the helper is
the module's answer to which low bands an axis names and a future caller
must get the same empty answer; a direct test walks it and says why.
* Refuse the volumes that are not volumes, and say only what the corners must do
A NaN receiving-room volume sailed through every entry point's positivity
check, because NaN answers False to <= as readily as to >, and the facade
result then carried NaN levels; a test even pinned that behaviour as a known
separate defect. All three entry points now refuse NaN through the NaN-safe
comparison and infinity by name, and the test pins the refusal.
The prose overstated in four places what this branch delivers. The corner
procedure can move the three low bands by several decibels and the adaptation
term with them, but Formula (13) leaves a band untouched when the corner
level equals the default one, so the ratings guide no longer promises
movement unconditionally. The insulation index now carries the road-traffic
exception and the rounded-volume boundary the linked guide states, and its
pointer cites Clause 8.4 beside 10.4 for the facade. The reverberation
substitution paragraph names the receiving room as the trigger's owner, since
a small source room never substitutes anything. A dangling "unchanged" in the
module docstring reads as the adverb it was meant to be, and the API page is
regenerated from it.
* Give R' a gatekeeper of its own, and a test to every refusal
Sonar counted airborne_insulation past the cognitive-complexity gate, and the
weight was the apparent sound reduction index: the paired-geometry check, the
positivity and finiteness gates and Formula (4) all sat inline under the
low-frequency branching. _apparent_reduction_index() now owns that block, the
messages unchanged, and the function reads as the three quantities it returns.
The refusals themselves were asserted nowhere: a zero, negative, NaN or
infinite geometry raised the right message with no test holding it, in the
airborne, impact and facade entry points alike. Each refusal now has one,
NaN grouped with the non-positives because that is what the `not x > 0`
spelling is for, and infinity on its own because it passes that gate and is
refused by name.
The stand-aside guard of the low-frequency warning helper is reachable only
by calling the helper directly, since every entry point complains about a
broken volume before the helper runs; a direct test now pins that silence
instead of leaving the line as dead weight in the coverage report.
Rate a lining and a floor covering on their reference elements, and measure the sound of rain on a roof, by ISO 10140-1:2021 (#906)
A lining measured without and with it now gives its improvement band by band and its single numbers on the standard basic element of ISO 717-1:2020 Annex D, a floor covering gives its reduction of impact level on the heavyweight reference floor or on any of the three lightweight ones, and the sound of artificial rain on a roof, a roof window or a rooflight comes out as its intensity level, its A-weighted value and its normalized level against the reference glass pane. The reference curves of ISO 717-1 Table E.1 and ISO 717-2 Table 4, and the rain tables of ISO 10140-1 and ISO 10140-5, are published read-only tables, every result has a plot in English and Spanish, and a new guide walks the three annexes through a worked lining, a vinyl on a timber floor and a rooflight under heavy rain.
Every verdict reads its pass and fail flags, grades and classes from the values it holds (#949)
A result no longer stores a verdict beside the readings it came from. Sixty-two result classes used to keep the flag, grade or class their function had worked out (`passes`, `complies`, `qualified`, the `*_met` and `*_ok` flags, the advisories, the per-band classes of the IEC 61260-1, IEC 61672-1 and IEC 61043 verdicts, the ISO 9614-2 grade, the ISO/PAS 1996-3 category, the IEC TS 61400-11-2 block status and the rest), so a result built by hand or rewritten with `dataclasses.replace` could hold readings that fail and a flag that says they pass. Each of them is now a read-only property, read from the values the result keeps and the limit the standard prints, and so is any figure that only fed it, such as the rounded level of an RD 1367/2007 period or the acceptance region of a trend test.
The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
Every verdict reads its pass and fail flags, grades and classes from the values it holds (#949)
A result no longer stores a verdict beside the readings it came from. Sixty-two result classes used to keep the flag, grade or class their function had worked out (`passes`, `complies`, `qualified`, the `*_met` and `*_ok` flags, the advisories, the per-band classes of the IEC 61260-1, IEC 61672-1 and IEC 61043 verdicts, the ISO 9614-2 grade, the ISO/PAS 1996-3 category, the IEC TS 61400-11-2 block status and the rest), so a result built by hand or rewritten with `dataclasses.replace` could hold readings that fail and a flag that says they pass. Each of them is now a read-only property, read from the values the result keeps and the limit the standard prints, and so is any figure that only fed it, such as the rounded level of an RD 1367/2007 period or the acceptance region of a trend test.
The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
A Spanish figure writes its decimal comma on every panel it draws, and two guards keep it that way (#777)
Every helper that writes text takes a language and defaults to English, so a call that forgets to pass it on raises nothing and puts an English decimal point into a Spanish figure. The plotting modules, the figure generators and the fiches now hand the caller's language to every helper that takes one, and localize_axes is called once per axes a plot builds rather than once per figure: a twin axis, a colorbar and the z of a 3-D panel each carry a formatter of their own, and each was shipping in English beside a panel already in Spanish. What decides whether an axis is localised is its formatter and not its scale, so a log axis of distances still writing its own numbers is reached and a pinned frequency axis is left to format_frequency_axis. A zoom inset and a contour colorbar, which the save-time pass of the figure generators cannot reach, are localised where they are built. The band column of the room criterion sheet and of the whole sound-power fiche family is written in the sheet's language too.
scripts/check_language_forwarding.py fails on any call to a helper that takes a language, made from anywhere a language is in scope, that does not pass it on. It reads module and class bodies as well as functions, follows a helper through a local alias and a functools.partial, names the shapes it cannot reach, keys an exemption by its line so one approved call cannot cover another, and reports a method name only some of whose namesakes take the language, which silently switched the untyped-receiver check off.
scripts/check_figure_decimal_point.py reads the committed Spanish figures and fails on a tick label that is a number with a point in it, whichever pass was meant to write the comma. It found six figures, regenerated here. Both run from the Makefile and in CI.
Rate a lining and a floor covering on their reference elements, and measure the sound of rain on a roof, by ISO 10140-1:2021 (#906)
A lining measured without and with it now gives its improvement band by band and its single numbers on the standard basic element of ISO 717-1:2020 Annex D, a floor covering gives its reduction of impact level on the heavyweight reference floor or on any of the three lightweight ones, and the sound of artificial rain on a roof, a roof window or a rooflight comes out as its intensity level, its A-weighted value and its normalized level against the reference glass pane. The reference curves of ISO 717-1 Table E.1 and ISO 717-2 Table 4, and the rain tables of ISO 10140-1 and ISO 10140-5, are published read-only tables, every result has a plot in English and Spanish, and a new guide walks the three annexes through a worked lining, a vinyl on a timber floor and a rooflight under heavy rain.
Rate a lining and a floor covering on their reference elements, and measure the sound of rain on a roof, by ISO 10140-1:2021 (#906)
A lining measured without and with it now gives its improvement band by band and its single numbers on the standard basic element of ISO 717-1:2020 Annex D, a floor covering gives its reduction of impact level on the heavyweight reference floor or on any of the three lightweight ones, and the sound of artificial rain on a roof, a roof window or a rooflight comes out as its intensity level, its A-weighted value and its normalized level against the reference glass pane. The reference curves of ISO 717-1 Table E.1 and ISO 717-2 Table 4, and the rain tables of ISO 10140-1 and ISO 10140-5, are published read-only tables, every result has a plot in English and Spanish, and a new guide walks the three annexes through a worked lining, a vinyl on a timber floor and a rooflight under heavy rain.
Rate a lining and a floor covering on their reference elements, and measure the sound of rain on a roof, by ISO 10140-1:2021 (#906)
A lining measured without and with it now gives its improvement band by band and its single numbers on the standard basic element of ISO 717-1:2020 Annex D, a floor covering gives its reduction of impact level on the heavyweight reference floor or on any of the three lightweight ones, and the sound of artificial rain on a roof, a roof window or a rooflight comes out as its intensity level, its A-weighted value and its normalized level against the reference glass pane. The reference curves of ISO 717-1 Table E.1 and ISO 717-2 Table 4, and the rain tables of ISO 10140-1 and ISO 10140-5, are published read-only tables, every result has a plot in English and Spanish, and a new guide walks the three annexes through a worked lining, a vinyl on a timber floor and a rooflight under heavy rain.
KB italic, Euler's number upright, and the subscripts of the guides, figures and diagrams set as their standards print them (#952)
The weighted vibration severity KB is italic in every diagram, figure, guide, docstring and errata entry, as DIN 4150-2 and DIN 45672 print it, and Euler's number is upright in every formula, as ISO 80000-2:2019 prints the mathematical constants. `make subscripts` fails on an upright KB or an upright running index and `scripts/check_euler_number.py` fails on an italic e, and both checks now read the row breaks, wrapped inline math and escaped strings they used to skip. Where a standard prints every subscript in one slope, as EN 15657, EN 12354-5 and RD 1367/2007 do, ISO 80000-2 decides: a running index is italic and a descriptive abbreviation upright, so the position levels of EN 15657 are L_{v,i} with an italic i. The standardized levels with their italic T, the ISO 7235 diagram with its sign put right, and the noise control, in-situ, exposure, aircraft and theory symbols follow their printed pages. No public name, signature or return value changes.