re: the Phase_1/2/3 block of the settings family -- mostly per stage, not per phase
72 records, 94 distinct field names, 31 in every one (post-processing core, five Fog*, three ScreenColor*, SpaceSize, five Supply*, UnderCommandSquadron, the first BGOperate slot). Optional families sit in clean tiers: Nebura_* and ColorLayer* in 69/72, DOF_*/UnsharpMask_*/ExposureKey_* in 15/72, FinalPass* in 3/72. REFUTED: BGOperateFrameCount is NOT the number of BGOperateFrameName_i slots -- 36 of 72. What holds is Count <= slots, 72/72: a fixed slot array with a live count, the same shape as MessageCount under the 32-slot clamp. 68 of the fields common to all three phases NEVER differ in any of the 24 objects. The phase block is a per-stage environment block copied three times; what a phase change is actually for is the backdrop animation (BGOperate*) and the supply/command squadron assignment. MapPath is not in this family -- its 87 records per pack are 29 x 3, the resource manifest's Phase_N. Also fixed a non-determinism the verify loop caught: most_common() over a set iteration ordered ties differently per run; now sorted by (-count, name). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
@@ -4623,3 +4623,50 @@ in one object: once for scoring, once for damage.
|
|||||||
`UnderCommandSquadron`, `MapPath`) is the largest remaining piece and was not
|
`UnderCommandSquadron`, `MapPath`) is the largest remaining piece and was not
|
||||||
read. Which object is which stage, beyond `IsBoss16Enable`. `SplinterCell Count
|
read. Which object is which stage, beyond `IsBoss16Enable`. `SplinterCell Count
|
||||||
5` is a name and a value only.
|
5` is a name and a value only.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅🔴 2026-08-27 — the `Phase_1/2/3` block of the settings family
|
||||||
|
|
||||||
|
The largest remaining piece of the stage-settings table, now read.
|
||||||
|
`stage-settings-table.md` extended; `mission_scoring.py` extended; artefact
|
||||||
|
`data/mission-scoring.txt` grows. Still twelve artefacts.
|
||||||
|
|
||||||
|
**Docs checked first.** `stage-definition-table.md` owns `MapPath`/`MapMesh` — in
|
||||||
|
the **`Stage_SNN`** records, naming `.rgn`/`.col` MiscBin objects; `regn-map-grid.md`
|
||||||
|
and `stage-mission-tables.md` also carry `MapPath`. `UnderCommandSquadron`,
|
||||||
|
`BGOperateFrameName`, `SupplyMovie*`, `FinalPassVinetting`, `Nebura_*` and
|
||||||
|
`ScreenColor*` are owned by **nothing**.
|
||||||
|
|
||||||
|
✅ **72 records, 94 distinct field names, 31 in every one** — the post-processing
|
||||||
|
core, five `Fog*`, three `ScreenColor*`, `SpaceSize`, five `Supply*`,
|
||||||
|
`UnderCommandSquadron`, and the first `BGOperate` slot. Optional families sit in
|
||||||
|
clean tiers: `Nebura_*` (12) + `ColorLayer*` + `BGRotateScale` in **69/72**;
|
||||||
|
`DOF_*` (7), `UnsharpMask_*` (7), `ExposureKey_*` (4) in **15/72**;
|
||||||
|
`FinalPass*` (11) in **3/72**.
|
||||||
|
|
||||||
|
🔴 **Refuted: `BGOperateFrameCount` is NOT the number of `BGOperateFrameName_i`
|
||||||
|
slots — 36 of 72.** I expected the `Count·k` pattern that pinned the chatter pairs
|
||||||
|
and the cutscene pages, and it does not hold. What holds is
|
||||||
|
**`Count ≤ slots` in 72/72**: the slot array is fixed (1, 4 or 5 present) and
|
||||||
|
`Count` says how many are live — the same shape as `MessageCount` under the
|
||||||
|
32-slot clamp. Recorded as a refutation because the strong form is the one a port
|
||||||
|
would naively implement.
|
||||||
|
|
||||||
|
✅ **68 of the fields common to all three phases NEVER differ, in any of the 24
|
||||||
|
objects.** The whole `Nebura_*`, `DOF_*`, `UnsharpMask_*`, `FinalPass*` families,
|
||||||
|
most fog/colour settings, `SupplySquadron2` and `SupplyRange` are **per stage,
|
||||||
|
duplicated into all three phase records**. What moves — never in more than 6 of 24
|
||||||
|
— is `BGOperateFrameName_0` (6), `SupplySquadron1` (5), then `Brightness`,
|
||||||
|
`BrightPass*`, `ColorLayerA`, `BGOperateFrameCount`, `UnderCommandSquadron`,
|
||||||
|
`FirstAdaptedLuminance`, `BGOperateFrameName_2` (3 each). **The phase block is a
|
||||||
|
per-stage environment block copied three times**, and what a phase change is
|
||||||
|
actually for is the backdrop animation and the supply/command squadron.
|
||||||
|
|
||||||
|
⚠️ **`MapPath` is not in this family.** Its 87 records per pack are 29 × 3 — the
|
||||||
|
**resource** manifest's `Phase_N`, not the settings'. Arithmetic, not assumption:
|
||||||
|
the settings family is 24 objects, the resource family 29.
|
||||||
|
|
||||||
|
🟡 Still open: which settings object is which stage beyond `IsBoss16Enable`;
|
||||||
|
`SplinterCell Count 5`; what `SpaceSize`, `GlareType` and `Nebura_*` mean
|
||||||
|
numerically.
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ files, which is how the same ground got covered twice.
|
|||||||
| [`structures/cutscene-message-table.md`](structures/cutscene-message-table.md) | Cutscene dialogue — speaker, portrait, on-screen seconds, audio cue per page | ✅ CONFIRMED, field count = 9·PageCount+2 for all 7 PageCounts, 1 252/1 252 caption keys match, 138 ids close both ways |
|
| [`structures/cutscene-message-table.md`](structures/cutscene-message-table.md) | Cutscene dialogue — speaker, portrait, on-screen seconds, audio cue per page | ✅ CONFIRMED, field count = 9·PageCount+2 for all 7 PageCounts, 1 252/1 252 caption keys match, 138 ids close both ways |
|
||||||
| [`structures/preset-message-rules.md`](structures/preset-message-rules.md) | The reactive-chatter rule table — 64 events, the (message, Yes/No) pair payload, the `Sperkers` roster | ✅ CONFIRMED, the seven fields read off `sub_82213980`, phase tables merge non-additively (224 variants discarded); 8 firing sites share one entry, Probability is a per-cent roll against rand*100.0; Yes = one-shot line; queue is Priority-ordered and capped at 128; the cooldown is Interval + Fluctuation*rand held in the lingering queue node; the 14 player-facing events are voiced by the player set alone (13/15 Katana tables, 0/129 others) (three are seconds ×60, the Yes/No element is a u32 mask, hence the 32 clamp); MessageCount·2 == positional count in 9 216/9 216; five naming routes union to 144/144 (six names predicted from the speaker roster before hashing, control 0/4); 2 388/2 405 message ids bind to a cue |
|
| [`structures/preset-message-rules.md`](structures/preset-message-rules.md) | The reactive-chatter rule table — 64 events, the (message, Yes/No) pair payload, the `Sperkers` roster | ✅ CONFIRMED, the seven fields read off `sub_82213980`, phase tables merge non-additively (224 variants discarded); 8 firing sites share one entry, Probability is a per-cent roll against rand*100.0; Yes = one-shot line; queue is Priority-ordered and capped at 128; the cooldown is Interval + Fluctuation*rand held in the lingering queue node; the 14 player-facing events are voiced by the player set alone (13/15 Katana tables, 0/129 others) (three are seconds ×60, the Yes/No element is a u32 mask, hence the 32 clamp); MessageCount·2 == positional count in 9 216/9 216; five naming routes union to 144/144 (six names predicted from the speaker roster before hashing, control 0/4); 2 388/2 405 message ids bind to a cue |
|
||||||
| [`structures/mission-scoring.md`](structures/mission-scoring.md) | Mission scoring and the S/A/B/C/D rank thresholds — 24 tables x 3 difficulties | ✅ CONFIRMED, one 22-field schema over 72 records; difficulty moves 10 of 22 fields and never the RankScore thresholds; 🔴 which object is which stage unresolved (0/28 names under 19 prefixes) |
|
| [`structures/mission-scoring.md`](structures/mission-scoring.md) | Mission scoring and the S/A/B/C/D rank thresholds — 24 tables x 3 difficulties | ✅ CONFIRMED, one 22-field schema over 72 records; difficulty moves 10 of 22 fields and never the RankScore thresholds; 🔴 which object is which stage unresolved (0/28 names under 19 prefixes) |
|
||||||
| [`structures/stage-settings-table.md`](structures/stage-settings-table.md) | The per-stage settings object — Camera rigs, Player limits, Difficulty_* damage record | ✅ CONFIRMED, 24 settings objects vs 29 resource objects both using Phase_1/2/3; Camera is 13/14 fields constant; GravityFactor non-zero in 4 stages; IsBoss16Enable identifies one object |
|
| [`structures/stage-settings-table.md`](structures/stage-settings-table.md) | The per-stage settings object — Camera rigs, Player limits, Difficulty_* damage record | ✅ CONFIRMED, 24 settings objects vs 29 resource objects both using Phase_1/2/3; Camera is 13/14 fields constant; GravityFactor non-zero in 4 stages; IsBoss16Enable identifies one object; the Phase block is 94 fields of which 68 never vary between phases |
|
||||||
| [`structures/isl-mission-timer.md`](structures/isl-mission-timer.md) | The mission timer — two sequential countdowns, not a limit and a warning | ✅ CONFIRMED — read from `sub_822639B8`; the threshold reading is |
|
| [`structures/isl-mission-timer.md`](structures/isl-mission-timer.md) | The mission timer — two sequential countdowns, not a limit and a warning | ✅ CONFIRMED — read from `sub_822639B8`; the threshold reading is |
|
||||||
| [`structures/archive-naming.md`](structures/archive-naming.md) | Which archives the disc can name — 100% for menu paks, **0.0%** for the six 2D paks and `GP_READY_ROOM` | ✅ CONFIRMED — 6027 names × 16 prefixes, bimodal |
|
| [`structures/archive-naming.md`](structures/archive-naming.md) | Which archives the disc can name — 100% for menu paks, **0.0%** for the six 2D paks and `GP_READY_ROOM` | ✅ CONFIRMED — 6027 names × 16 prefixes, bimodal |
|
||||||
| [`structures/hud-config.md`](structures/hud-config.md) | The in-game HUD configuration — 16 records, 419 asset paths, and a per-stage `ResourceTable` | ✅ CONFIRMED — 0 of 419 config paths resolve as pak entries |
|
| [`structures/hud-config.md`](structures/hud-config.md) | The in-game HUD configuration — 16 records, 419 asset paths, and a per-stage `ResourceTable` | ✅ CONFIRMED — 0 of 419 config paths resolve as pak entries |
|
||||||
|
|||||||
@@ -124,6 +124,41 @@ the rest of the settings object (24 objects):
|
|||||||
PlayerShieldDamageAdjustment 1 distinct 1.0=24
|
PlayerShieldDamageAdjustment 1 distinct 1.0=24
|
||||||
ShieldDamageAdjustment 2 distinct 0.5=23 1.0=1
|
ShieldDamageAdjustment 2 distinct 0.5=23 1.0=1
|
||||||
|
|
||||||
|
the Phase_1/2/3 block (72 records over 24 objects):
|
||||||
|
distinct field names : 94
|
||||||
|
present in EVERY record : 31
|
||||||
|
BGOperateFrameCount BGOperateFrameName_0 BGOperateScale_0 BloomScale BrightPassOffset BrightPassThreshold Brightness Contrast ExposureKeyValue FirstAdaptedLuminance FogLinear FogMaxAmount FogMaxDistance FogMinAmount FogMinDistance GlareType Hue LuminanceMax LuminanceMin Saturation ScreenColorB ScreenColorG ScreenColorR SpaceSize StarScale SupplyMovie1ID SupplyMovie2ID SupplyRange SupplySquadron1 SupplySquadron2 UnderCommandSquadron
|
||||||
|
field-count histogram : {31: 3, 58: 28, 59: 24, 61: 1, 62: 1, 77: 6, 78: 6, 90: 3}
|
||||||
|
BGOperateFrameCount == slots: 36/72 (REFUTED)
|
||||||
|
BGOperateFrameCount <= slots: 72/72
|
||||||
|
slot histogram {1: 3, 4: 67, 5: 2} ; Count histogram {1: 9, 2: 14, 3: 16, 4: 31, 5: 2}
|
||||||
|
fields that DIFFER between phases (of 24 objects):
|
||||||
|
BGOperateFrameName_0 6
|
||||||
|
SupplySquadron1 5
|
||||||
|
BGOperateFrameCount 3
|
||||||
|
BGOperateFrameName_2 3
|
||||||
|
BrightPassOffset 3
|
||||||
|
BrightPassThreshold 3
|
||||||
|
Brightness 3
|
||||||
|
ColorLayerA 3
|
||||||
|
FirstAdaptedLuminance 3
|
||||||
|
UnderCommandSquadron 3
|
||||||
|
BGOperateScale_2 2
|
||||||
|
BloomScale 2
|
||||||
|
ColorLayerG 2
|
||||||
|
ColorLayerR 2
|
||||||
|
Contrast 2
|
||||||
|
GlareType 2
|
||||||
|
LuminanceMax 2
|
||||||
|
StarScale 2
|
||||||
|
SupplyMovie1ID 2
|
||||||
|
BGRotateScale_2 1
|
||||||
|
FogMaxAmount 1
|
||||||
|
SpaceSize 1
|
||||||
|
SupplyMovie2ID 1
|
||||||
|
fields that NEVER differ between phases: 68
|
||||||
|
AfterimageScale BGAnimation_0 BGAnimation_3 BGOperateFrameName_1 BGOperateFrameName_3 BGOperateScale_0 BGOperateScale_1 BGOperateScale_3 BGRotateScale_0 BGRotateScale_1 BGRotateScale_3 CCDLuminance ColorLayerB ContrailFirstCullingOff DOF_Enable DOF_FarAmount DOF_FarClip DOF_FarFocal DOF_NearAmount DOF_NearClip DOF_NearFocal ExposureKeyValue ExposureKey_BeginTime ExposureKey_BeginValue ExposureKey_EndTime ExposureKey_EndValue FinalPassBB FinalPassBG FinalPassBR FinalPassDB FinalPassDG FinalPassDR FinalPassDesaturation FinalPassToneRatio FinalPassType FinalPassVinetting FinalPassVinettingSharpness FogLinear FogMaxDistance FogMinAmount FogMinDistance Hue LuminanceMin Nebura_Count Nebura_EmitterRadius Nebura_EmitterRadiusJitter Nebura_MiddleAmount Nebura_MiddleFar Nebura_MiddleNear Nebura_NearAmount Nebura_NearClip Nebura_ResourceName Nebura_Size Nebura_SpeedLimit Nebura_SpeedScale Saturation ScreenColorB ScreenColorG ScreenColorR SupplyRange SupplySquadron2 UnsharpMask_B UnsharpMask_Far UnsharpMask_G UnsharpMask_Luminance UnsharpMask_Near UnsharpMask_Offset UnsharpMask_R
|
||||||
|
|
||||||
the commonest Normal record:
|
the commonest Normal record:
|
||||||
CraftScore_Adjustment 1.0
|
CraftScore_Adjustment 1.0
|
||||||
FFPenalty_Craft_Basis 1.0
|
FFPenalty_Craft_Basis 1.0
|
||||||
|
|||||||
@@ -77,11 +77,51 @@ almost everything is `1.0`, with `CollisionDamageRatio 0.8` and
|
|||||||
is expressed **twice** in the same object — once for *scoring*
|
is expressed **twice** in the same object — once for *scoring*
|
||||||
(`Score_{Easy,Normal,Hard}`) and once for *damage* (`Difficulty_*`).
|
(`Score_{Easy,Normal,Hard}`) and once for *damage* (`Difficulty_*`).
|
||||||
|
|
||||||
## 🟡 Not settled
|
## ✅ The `Phase_1/2/3` block — mostly per stage, not per phase
|
||||||
|
|
||||||
* The `Phase_1/2/3` block of the settings family (31–90 named fields:
|
**Settled 2026-08-27.** 72 records (24 objects × 3), **94 distinct field names**,
|
||||||
post-processing, fog, DOF, unsharp mask, supply squadrons and movies,
|
of which **31 appear in every one**: the post-processing core
|
||||||
`UnderCommandSquadron`, `MapPath`) is **not read here** — it is the largest
|
(`ExposureKeyValue`, `LuminanceMin/Max`, `FirstAdaptedLuminance`,
|
||||||
remaining piece of this table.
|
`BrightPassThreshold/Offset`, `BloomScale`, `StarScale`, `GlareType`,
|
||||||
|
`Brightness`, `Contrast`, `Saturation`, `Hue`), the five `Fog*` fields, the three
|
||||||
|
`ScreenColor*`, `SpaceSize`, the five `Supply*` (`SupplySquadron1/2`,
|
||||||
|
`SupplyMovie1/2ID`, `SupplyRange`), `UnderCommandSquadron`, and the first
|
||||||
|
`BGOperate` slot. Optional families come in fixed frequency tiers:
|
||||||
|
`Nebura_*` (12 fields) and `ColorLayer*`/`BGRotateScale`/`AfterimageScale` in
|
||||||
|
**69/72**, `DOF_*` (7) and `UnsharpMask_*` (7) and the four `ExposureKey_*` in
|
||||||
|
**15/72**, `FinalPass*` (11) in **3/72**.
|
||||||
|
|
||||||
|
### 🔴 Refuted: `BGOperateFrameCount` is not the number of name slots
|
||||||
|
|
||||||
|
The obvious reading — a `Count` naming its indexed group, the pattern that pinned
|
||||||
|
the chatter pairs and the cutscene pages — **fails here: 36 of 72**. What holds is
|
||||||
|
the weaker statement, **`BGOperateFrameCount ≤ slot count` in 72/72**: the slot
|
||||||
|
array is fixed (1, 4 or 5 `BGOperateFrameName_i` present) and `Count` says how
|
||||||
|
many are live, exactly as `MessageCount` sits under the 32-slot clamp in
|
||||||
|
[`preset-message-rules.md`](preset-message-rules.md). `Count` runs 1…5.
|
||||||
|
|
||||||
|
### ✅ What actually changes between phases
|
||||||
|
|
||||||
|
Of the fields common to all three phase records of an object, **68 never differ
|
||||||
|
in any of the 24 objects**. The entire `Nebura_*`, `DOF_*`, `UnsharpMask_*` and
|
||||||
|
`FinalPass*` families, most of the fog and colour settings, `SupplySquadron2` and
|
||||||
|
`SupplyRange` are **per stage, duplicated into all three phases**.
|
||||||
|
|
||||||
|
The short list that *does* move — and never in more than 6 of 24 objects — is:
|
||||||
|
`BGOperateFrameName_0` (6), `SupplySquadron1` (5), then `Brightness`,
|
||||||
|
`BrightPassOffset`/`Threshold`, `ColorLayerA`, `BGOperateFrameCount`,
|
||||||
|
`UnderCommandSquadron`, `FirstAdaptedLuminance`, `BGOperateFrameName_2` (3 each),
|
||||||
|
and a tail of bloom/glare/contrast/colour knobs at 2.
|
||||||
|
|
||||||
|
So the phase block is best read as **a per-stage environment block copied three
|
||||||
|
times**, with the backdrop animation (`BGOperate*`) and the supply/command
|
||||||
|
squadron assignment as the parts a phase change is actually for.
|
||||||
|
|
||||||
|
⚠️ **`MapPath` is not in this family.** Its 87 records per pack are 29 × 3 — the
|
||||||
|
**resource** manifest's `Phase_N`, not the settings'. `stage-definition-table.md`
|
||||||
|
owns `MapPath`/`MapMesh` in the `Stage_SNN` records; what it does not say is that
|
||||||
|
the name recurs in the resource manifest's per-phase records.
|
||||||
|
|
||||||
|
## 🟡 Not settled
|
||||||
* Which object is which stage, beyond the single `IsBoss16Enable` hook.
|
* Which object is which stage, beyond the single `IsBoss16Enable` hook.
|
||||||
* `SplinterCell Count 5` — name and value only.
|
* `SplinterCell Count 5` — name and value only.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ language pack, each holding Score_Easy / Score_Normal / Score_Hard with one
|
|||||||
|
|
||||||
Run: python3 mission_scoring.py > ../../docs/re/data/mission-scoring.txt
|
Run: python3 mission_scoring.py > ../../docs/re/data/mission-scoring.txt
|
||||||
"""
|
"""
|
||||||
import sys, os, glob, collections
|
import sys, os, re, glob, collections
|
||||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
from unit_substructures import pak_entries
|
from unit_substructures import pak_entries
|
||||||
import unitgroup as U
|
import unitgroup as U
|
||||||
@@ -120,6 +120,54 @@ def main():
|
|||||||
print(' %-36s %2d distinct %s' % (
|
print(' %-36s %2d distinct %s' % (
|
||||||
k, len(c), ' '.join('%s=%d' % (a, b) for a, b in c.most_common(5))[:70]))
|
k, len(c), ' '.join('%s=%d' % (a, b) for a, b in c.most_common(5))[:70]))
|
||||||
|
|
||||||
|
# the Phase_1/2/3 block of the settings family
|
||||||
|
prec = [(h, i, U.named(d['Phase_%d' % i])) for h, d in full for i in (1, 2, 3)
|
||||||
|
if 'Phase_%d' % i in d]
|
||||||
|
allf = collections.Counter()
|
||||||
|
for _, _, n in prec:
|
||||||
|
for f in n:
|
||||||
|
allf[f] += 1
|
||||||
|
core = sorted(f for f, c in allf.items() if c == len(prec))
|
||||||
|
print()
|
||||||
|
print('the Phase_1/2/3 block (%d records over %d objects):' % (len(prec), len(full)))
|
||||||
|
print(' distinct field names : %d' % len(allf))
|
||||||
|
print(' present in EVERY record : %d' % len(core))
|
||||||
|
print(' %s' % ' '.join(core))
|
||||||
|
print(' field-count histogram : %s' % dict(sorted(
|
||||||
|
collections.Counter(len(n) for _, _, n in prec).items())))
|
||||||
|
|
||||||
|
le = 0
|
||||||
|
slots = collections.Counter()
|
||||||
|
cnts = collections.Counter()
|
||||||
|
for _, _, n in prec:
|
||||||
|
c = int(n['BGOperateFrameCount'])
|
||||||
|
k = sum(1 for f in n if re.fullmatch(r'BGOperateFrameName_\d+', f))
|
||||||
|
slots[k] += 1
|
||||||
|
cnts[c] += 1
|
||||||
|
le += (c <= k)
|
||||||
|
eq = sum(1 for _, _, n in prec
|
||||||
|
if int(n['BGOperateFrameCount'])
|
||||||
|
== sum(1 for f in n if re.fullmatch(r'BGOperateFrameName_\d+', f)))
|
||||||
|
print(' BGOperateFrameCount == slots: %d/%d (REFUTED)' % (eq, len(prec)))
|
||||||
|
print(' BGOperateFrameCount <= slots: %d/%d' % (le, len(prec)))
|
||||||
|
print(' slot histogram %s ; Count histogram %s' % (
|
||||||
|
dict(sorted(slots.items())), dict(sorted(cnts.items()))))
|
||||||
|
|
||||||
|
moved = collections.Counter()
|
||||||
|
same = collections.Counter()
|
||||||
|
for h, d in full:
|
||||||
|
ns = [U.named(d['Phase_%d' % i]) for i in (1, 2, 3) if 'Phase_%d' % i in d]
|
||||||
|
if len(ns) != 3:
|
||||||
|
continue
|
||||||
|
for f in set(ns[0]) & set(ns[1]) & set(ns[2]):
|
||||||
|
(moved if len({n[f] for n in ns}) > 1 else same)[f] += 1
|
||||||
|
never = sorted(f for f in same if f not in moved)
|
||||||
|
print(' fields that DIFFER between phases (of %d objects):' % len(full))
|
||||||
|
for f, c in sorted(moved.items(), key=lambda kv: (-kv[1], kv[0])):
|
||||||
|
print(' %-28s %2d' % (f, c))
|
||||||
|
print(' fields that NEVER differ between phases: %d' % len(never))
|
||||||
|
print(' %s' % ' '.join(never))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print('the commonest Normal record:')
|
print('the commonest Normal record:')
|
||||||
for k, v in sorted(dict(base).items()):
|
for k, v in sorted(dict(base).items()):
|
||||||
|
|||||||
Reference in New Issue
Block a user