FAILURE MAP
← Case archive

FA-69266 / Tide and marine navigation tables / Open access

Light characteristic abbreviation: Height and range suffixes are matched case-insensitively · case 01

A range such as 20M is read as a 20 m elevation when no height is given.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The pattern is compiled with re.I so the metre suffix m also matches nautical miles M.

VERIFIED REPAIR

Match m and M case-sensitively.

Unsuccessful approach: Lower-casing the whole string first breaks class and colour matching.

Case contract

Input a chart light abbreviation such as "Fl(3)WR.10s15m20M". Return [class, groups, colours, period_s, height_m, range_nm]: class includes an "Al." prefix; groups is a list (composite "2+1" -> [2,1], default [1]); colours default "W"; missing numbers are None. Unparseable strings return None.

Why this case matters

Tide tables and passage plans turn published predictions into go/no-go decisions about depth, clearance and timing.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(x):
    m=re.match(r"^(Al\.|)(LFl|Fl|VQ|Q|Iso|Oc|F)(?:\(([0-9+]+)\))?\.?([WRGY]*)\.?(?:(\d+(?:\.\d+)?)s)?(?:(\d+)m)?(?:(\d+)M)?$",x,re.I)
    if not m: return None
    cls=m.group(1)+m.group(2)
    grp=[int(p) for p in m.group(3).split('+')] if m.group(3) else [1]
    col=m.group(4) or 'W'
    per=float(m.group(5)) if m.group(5) else None
    return [cls,grp,col,per,int(m.group(6)) if m.group(6) else None,int(m.group(7)) if m.group(7) else None]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None]), ('light characteristic abbreviation "Q(9)15s"', 'Q(9)15s', ['Q', [9], 'W', 15.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None]), ('light characteristic abbreviation "Fl(4)Y.20s8m5M"', 'Fl(4)Y.20s8m5M', ['Fl', [4], 'Y', 20.0, 8, 5]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None]), ('light characteristic abbreviation "Q.1.2s"', 'Q.1.2s', ['Q', [1], 'W', 1.2, None, None]), ('light characteristic abbreviation "Mo(A)10s"', 'Mo(A)10s', None), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
light characteristic abbreviation "Fl.10s20M"['Fl', [1], 'W', 10.0, 20, None]['Fl', [1], 'W', 10.0, None, 20]Failed
light characteristic abbreviation "Fl(3)WR.10s15m20M"['Fl', [3], 'WR', 10.0, 15, 20]['Fl', [3], 'WR', 10.0, 15, 20]Passed
light characteristic abbreviation "LFl.10s"['LFl', [1], 'W', 10.0, None, None]['LFl', [1], 'W', 10.0, None, None]Passed
light characteristic abbreviation "Q"['Q', [1], 'W', None, None, None]['Q', [1], 'W', None, None, None]Passed
light characteristic abbreviation "VQ(6)10s"['VQ', [6], 'W', 10.0, None, None]['VQ', [6], 'W', 10.0, None, None]Passed
light characteristic abbreviation "Iso.WRG.4s"['Iso', [1], 'WRG', 4.0, None, None]['Iso', [1], 'WRG', 4.0, None, None]Passed
light characteristic abbreviation "Oc(2)R.8s12m9M"['Oc', [2], 'R', 8.0, 12, 9]['Oc', [2], 'R', 8.0, 12, 9]Passed

SHA-256 / 9621e406e779f579f11cb0847c4b1efad8987f2ae26303dd8348780c28780b1b

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(x):
    m=re.match(r"^(Al\.|)(LFl|Fl|VQ|Q|Iso|Oc|F)(?:\(([0-9+]+)\))?\.?([WRGY]*)\.?(?:(\d+(?:\.\d+)?)s)?(?:(\d+)m)?(?:(\d+)M)?$",x.lower())
    if not m: return None
    cls=m.group(1)+m.group(2)
    grp=[int(p) for p in m.group(3).split('+')] if m.group(3) else [1]
    col=m.group(4) or 'W'
    per=float(m.group(5)) if m.group(5) else None
    return [cls,grp,col,per,int(m.group(6)) if m.group(6) else None,int(m.group(7)) if m.group(7) else None]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None]), ('light characteristic abbreviation "Q(9)15s"', 'Q(9)15s', ['Q', [9], 'W', 15.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None]), ('light characteristic abbreviation "Fl(4)Y.20s8m5M"', 'Fl(4)Y.20s8m5M', ['Fl', [4], 'Y', 20.0, 8, 5]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None]), ('light characteristic abbreviation "Q.1.2s"', 'Q.1.2s', ['Q', [1], 'W', 1.2, None, None]), ('light characteristic abbreviation "Mo(A)10s"', 'Mo(A)10s', None), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
light characteristic abbreviation "Fl.10s20M"None['Fl', [1], 'W', 10.0, None, 20]Failed
light characteristic abbreviation "Fl(3)WR.10s15m20M"None['Fl', [3], 'WR', 10.0, 15, 20]Failed
light characteristic abbreviation "LFl.10s"None['LFl', [1], 'W', 10.0, None, None]Failed
light characteristic abbreviation "Q"None['Q', [1], 'W', None, None, None]Failed
light characteristic abbreviation "VQ(6)10s"None['VQ', [6], 'W', 10.0, None, None]Failed
light characteristic abbreviation "Iso.WRG.4s"None['Iso', [1], 'WRG', 4.0, None, None]Failed
light characteristic abbreviation "Oc(2)R.8s12m9M"None['Oc', [2], 'R', 8.0, 12, 9]Failed

SHA-256 / 4d74493ddfd2d917869f57533fe1c5b7cf4b1170437d6d112c0d4694d28a0065

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(x):
    m=re.match(r"^(Al\.|)(LFl|Fl|VQ|Q|Iso|Oc|F)(?:\(([0-9+]+)\))?\.?([WRGY]*)\.?(?:(\d+(?:\.\d+)?)s)?(?:(\d+)m)?(?:(\d+)M)?$",x)
    if not m: return None
    cls=m.group(1)+m.group(2)
    grp=[int(p) for p in m.group(3).split('+')] if m.group(3) else [1]
    col=m.group(4) or 'W'
    per=float(m.group(5)) if m.group(5) else None
    return [cls,grp,col,per,int(m.group(6)) if m.group(6) else None,int(m.group(7)) if m.group(7) else None]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "LFl.10s"', 'LFl.10s', ['LFl', [1], 'W', 10.0, None, None]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "Oc(2)R.8s12m9M"', 'Oc(2)R.8s12m9M', ['Oc', [2], 'R', 8.0, 12, 9]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Q"', 'Q', ['Q', [1], 'W', None, None, None]), ('light characteristic abbreviation "Al.Fl.WR.5s"', 'Al.Fl.WR.5s', ['Al.Fl', [1], 'WR', 5.0, None, None]), ('light characteristic abbreviation "Fl(2+1)G.15s"', 'Fl(2+1)G.15s', ['Fl', [2, 1], 'G', 15.0, None, None]), ('light characteristic abbreviation "Q(9)15s"', 'Q(9)15s', ['Q', [9], 'W', 15.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "VQ(6)10s"', 'VQ(6)10s', ['VQ', [6], 'W', 10.0, None, None]), ('light characteristic abbreviation "F.R"', 'F.R', ['F', [1], 'R', None, None, None]), ('light characteristic abbreviation "Fl.2.5s"', 'Fl.2.5s', ['Fl', [1], 'W', 2.5, None, None]), ('light characteristic abbreviation "Fl(4)Y.20s8m5M"', 'Fl(4)Y.20s8m5M', ['Fl', [4], 'Y', 20.0, 8, 5]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None])], [('light characteristic abbreviation "Fl.10s20M"', 'Fl.10s20M', ['Fl', [1], 'W', 10.0, None, 20]), ('light characteristic abbreviation "Iso.WRG.4s"', 'Iso.WRG.4s', ['Iso', [1], 'WRG', 4.0, None, None]), ('light characteristic abbreviation "LFl.G.12s24m15M"', 'LFl.G.12s24m15M', ['LFl', [1], 'G', 12.0, 24, 15]), ('light characteristic abbreviation "Al.Oc.WG.6s"', 'Al.Oc.WG.6s', ['Al.Oc', [1], 'WG', 6.0, None, None]), ('light characteristic abbreviation "Q.1.2s"', 'Q.1.2s', ['Q', [1], 'W', 1.2, None, None]), ('light characteristic abbreviation "Mo(A)10s"', 'Mo(A)10s', None), ('light characteristic abbreviation "Fl(3)WR.10s15m20M"', 'Fl(3)WR.10s15m20M', ['Fl', [3], 'WR', 10.0, 15, 20])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
light characteristic abbreviation "Fl.10s20M"['Fl', [1], 'W', 10.0, None, 20]['Fl', [1], 'W', 10.0, None, 20]Passed
light characteristic abbreviation "Fl(3)WR.10s15m20M"['Fl', [3], 'WR', 10.0, 15, 20]['Fl', [3], 'WR', 10.0, 15, 20]Passed
light characteristic abbreviation "LFl.10s"['LFl', [1], 'W', 10.0, None, None]['LFl', [1], 'W', 10.0, None, None]Passed
light characteristic abbreviation "Q"['Q', [1], 'W', None, None, None]['Q', [1], 'W', None, None, None]Passed
light characteristic abbreviation "VQ(6)10s"['VQ', [6], 'W', 10.0, None, None]['VQ', [6], 'W', 10.0, None, None]Passed
light characteristic abbreviation "Iso.WRG.4s"['Iso', [1], 'WRG', 4.0, None, None]['Iso', [1], 'WRG', 4.0, None, None]Passed
light characteristic abbreviation "Oc(2)R.8s12m9M"['Oc', [2], 'R', 8.0, 12, 9]['Oc', [2], 'R', 8.0, 12, 9]Passed

SHA-256 / 3fb7020532430bf01d5fb5df133d1c84edc3f075a5194c6e1e97ef6969b31ad4

Verification & scope

A deterministic toy model with stipulated rules and constants; not certified hydrographic software or a substitute for official tide tables. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:48:09.921863+00:00.

Case digest / 17ad1d1a40e9bfdd1e422d76ed13c99f58c1b86074658167ee91b75033e07da0