- Sync references/mahadasha_editorial_bilingual.json (9 lords x 3 paragraphs, zh + en, per-paragraph source locators) and mahadasha_editorial_policy.md, plus the one-line pointers in SKILL.md and vimshottari_dasha_guide.md. - New chapter after 大运解释 in both editions: the three paragraphs side by side (general / traditionally supportive / traditionally strained), never picked by lord or chart, Mahadasha layer only; source labelled as secondary study notes with the original edition pending verification; English only in the English edition. - Coverage contract: the topic moves from NOT_CARRIED to the checked list. No change to the frozen exporter, dates or any scoring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
306 lines
20 KiB
Python
306 lines
20 KiB
Python
"""Coverage contract against the upstream customer export (2026-11-06).
|
|
|
|
Every topic the upstream export prints (`customer-export/registry`, branch
|
|
`codex/customer-export-frozen-20261016`) is mapped to the section in our full
|
|
data report that carries it, in both editions. `audit_report` checks that each
|
|
section is present and carries real content, and that degraded markers
|
|
(「公开报告资料包未带此模块」, 「简化模型」) are gone.
|
|
|
|
Topics deliberately not carried are listed in `NOT_CARRIED` with the reason,
|
|
so a gap is a decision on record, never a silent omission.
|
|
|
|
Command line, on any exported report:
|
|
|
|
python -m scripts.report_render.upstream_coverage report.md [--language en]
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Topic:
|
|
upstream: str # upstream export heading
|
|
zh: str # our Chinese heading (prefix of the heading text)
|
|
en: str # our English heading (prefix)
|
|
kind: str = "table" # "table": needs a real table cell; "text": needs prose; "group": heading only
|
|
# Optional column that must carry real values: (zh header, en header, "any" | "all").
|
|
column: tuple[str, str, str] | None = None
|
|
|
|
|
|
# Upstream topic -> our section. Order follows the upstream export.
|
|
TOPICS: tuple[Topic, ...] = (
|
|
Topic("AI Reading Guide", "阅读说明", "AI Reading Guide", "text"),
|
|
Topic("Key points", "重点", "Focus", "text"),
|
|
Topic("Key points · timeline", "时间线", "Timeline", "text"),
|
|
Topic("Key points · career / finances / relationships", "三个领域的盘面依据", "Domain evidence"),
|
|
Topic("Birth Particulars / Hindu Calendar", "出生资料 / 印度历", "Birth Particulars / Hindu Calendar"),
|
|
Topic("Birth Chart Planetary Raw Positions", "本命盘行星原始位置", "Birth Chart Planetary Raw Positions"),
|
|
Topic("Chandra Chart / Bhava Spashta", "月亮盘 / Sripati 宫位精确表", "Chandra Chart / Bhava Spashta"),
|
|
Topic("Upagraha / Sub-Planets Points", "Upagraha / 副行星 点位", "Upagraha / Sub-Planets Points"),
|
|
Topic("Special Lagnas and Points", "特殊上升与派生点", "Special Lagnas and Points"),
|
|
Topic("Natal and Divisional North Indian Charts", "本命与分盘北印度图盘", "Natal and Divisional North Indian Charts", "group"),
|
|
Topic("Planets, Nakshatras and Houses", "行星、星宿与宫位解释", "Planets, Nakshatras and Houses", "group"),
|
|
Topic("Shadbala / Bhava Bala Summary", "六维力量 / Bhava Bala 摘要", "Shadbala / Bhava Bala Summary"),
|
|
Topic("Declination / Kranti / Speed", "赤纬 / 速度", "Declination / Speed"),
|
|
Topic("Planetary Avasthas", "Avastha 行星状态", "Planetary Avasthas"),
|
|
Topic("Bhava Bala House Strength", "Bhava Bala 十二宫力量", "Bhava Bala of the twelve houses"),
|
|
Topic("Planetary Friendship Matrix", "行星友敌关系矩阵源数据", "Planetary Friendship matrix source"),
|
|
Topic("Aspect Matrix", "相位矩阵", "/ p45-p47 aspect matrix"),
|
|
Topic("Jaimini Karakas, Arudha Padas and Special Lagnas", "Jaimini Karaka、Arudha Pada", "Jaimini Karaka, Arudha Pada"),
|
|
Topic("Ashtakavarga SAV / BAV / Pinda", "Ashtakavarga SAV / BAV / Pinda", "Ashtakavarga SAV / BAV / Pinda"),
|
|
Topic("Ashtakavarga Complete House Scores", "Ashtakavarga 完整宫位分数", "Ashtakavarga Full House Scores"),
|
|
Topic("Vimsopaka / Pushkara / Vargottama", "二十分力量 / Pushkara / Vargottama", "Vimsopaka / Pushkara / Vargottama"),
|
|
Topic("Ashtakavarga Shodhya / Yoga Pinda", "Ashtakavarga Shodhya", "Ashtakavarga Shodhya"),
|
|
Topic("Vimshottari Dasha", "Vimshottari 大运", "Vimshottari Dasha"),
|
|
Topic("Yogini Dasha", "Yogini 大运", "Yogini Dasha"),
|
|
Topic("Kala Chakra Dasha", "Kala Chakra 大运", "Kala Chakra Dasha", column=("主星/星座", "Lord/sign", "all")),
|
|
Topic("Jaimini / Narayana Dasha", "Jaimini / Narayana 大运", "Jaimini / Narayana Dasha"),
|
|
Topic("Sthira Dasha", "Sthira", "Sthira Dasha"),
|
|
Topic("Niryaana Shoola Dasha", "Niryaana Shoola", "Niryaana Shoola Dasha"),
|
|
Topic("Drig Dasha", "Drig", "Drig Dasha"),
|
|
Topic("Navamsha Dasha", "Navamsha", "Navamsha Dasha"),
|
|
Topic("Lagna Kendradi Rashi Dasha", "上升 Kendradi", "Lagna Kendradi Rashi Dasha"),
|
|
Topic("Shoola Dasha", "Shoola", "Shoola Dasha"),
|
|
Topic("Tribhagi Dasha", "Tribhagi 大运", "Tribhagi Dasha"),
|
|
Topic("Tribhagi 40-year Dasha", "Tribhagi 40-year 大运", "Tribhagi 40-year Dasha"),
|
|
Topic("Shattrimshatsama Dasha", "Shattrimshatsama 大运", "Shattrimshatsama Dasha"),
|
|
Topic("Satabdika Dasha", "Satabdika 大运", "Satabdika Dasha"),
|
|
Topic("Sade Sati / Dhayya / Kantaka Saturn", "Sade Sati / Dhayya / Kantaka", "Sade Sati / Dhayya / Kantaka"),
|
|
Topic("KP Chart / Cusps", "KP 星盘 / 宫头", "KP Chart / Cusps"),
|
|
Topic("KP Significators / Planet Lords", "KP 征象星 / 行星主星", "KP Significators / Planet Lords"),
|
|
Topic("Natal / KP Ruling Planets", "本命 / KP 主宰星", "Natal / KP Ruling Planets"),
|
|
Topic("Varshaphala Basic Data and Annual Planets", "Varshaphala 基础资料与年度行星表", "Varshaphala base data"),
|
|
Topic("Mudda Annual Dasha Table", "Mudda 年度大运", "Mudda annual dasha"),
|
|
Topic("Patyayini Main-Period Ending-Date Table", "Patyayini 结束日", "Patyayini ending dates"),
|
|
# A year without a combination says so in one sentence.
|
|
Topic("Tajika Yoga Presence Table", "Tajika 瑜伽呈现对照表", "Tajika Yoga Presence Table", "text"),
|
|
Topic("Saham Points", "Sahams 点位表", "Sahams"),
|
|
Topic("Annual Anchors", "年度锚点", "Annual anchors"),
|
|
Topic("True Solar Return", "真实太阳返照", "True Solar Return"),
|
|
Topic("Panchadhikari", "Panchadhikari", "Panchadhikari"),
|
|
Topic("Tripataki Placement", "Tripataki Chakra 年盘落点", "Tripataki Chakra placements"),
|
|
Topic("Annual Monthly Return Chart Data", "年度月返照图盘数据", "Monthly returns within the year"),
|
|
Topic("Lifetime Annual Return Chart Data", "生命周期年度返照图盘数据", "Lifetime annual return charts"),
|
|
Topic("Eight-Year Birthplace Overview", "出生地八年年度总览", "Eight-year overview at the birthplace"),
|
|
Topic("Bhavesh House-Lord Placements", "宫主(Bhavesh)落宫解释", "House lords (Bhavesh)"),
|
|
Topic("Mangala / Sade Sati / Dosha Results", "火星婚姻煞 / Sade Sati / Dosha 结果", "Mangala / Sade Sati / Dosha Results"),
|
|
Topic("Traditional Supportive Practices / Remedies", "传统辅助建议", "Traditional supportive notes"),
|
|
Topic("Benefic / Mixed / Malefic Yoga Candidates", "可用瑜伽总表", "Applicable Benefic / Mixed / Malefic Yogas"),
|
|
Topic("Dasha Interpretations", "大运解释", "Dasha Interpretation", "group"),
|
|
# Astrologer's bilingual text (yinduzhanxing 058c4f5f), replacing the unpublished upstream prose.
|
|
Topic("Traditional Dasha Reference Alternatives", "大运传统参考", "Traditional Dasha Reference", "text"),
|
|
Topic("Sudarshana Chakra", "Sudarshana Chakra(三参考点盘)", "Sudarshana Chakra", "group"),
|
|
Topic("Divisional Charts Numeric Tables", "分盘数值位置表", "Divisional Charts Numeric Tables", "group"),
|
|
Topic("Shadbala Components", "六维力量细项", "Shadbala Components"),
|
|
Topic("Functional Benefic / Malefic Layer", "功能性吉凶星层", "Functional Benefic / Malefic Layer"),
|
|
Topic("KP House Cusps and Significators", "KP 宫头与征象星", "KP House Cusps and Significators"),
|
|
Topic("Calculation Notes", "计算口径", "Calculation Conventions", "group"),
|
|
Topic("Research High-Division Raw Data", "研究型分盘", "Research divisional charts"),
|
|
Topic("Kala Chakra AD / Pratyantar Boundaries", "Kalachakra", "Kalachakra"),
|
|
Topic("Yoga Participants and Timing Links", "瑜伽参与行星", "Yoga Participants", column=("参与行星", "Participants", "any")),
|
|
Topic("Shadbala Subcomponent Data", "六维力量分项", "Shadbala Subcomponent", column=("Sthana(位置)", "Sthana", "all")),
|
|
Topic("Ashtakavarga Contribution and Reduction Data", "八分法加减", "AV Contribution and Reduction"),
|
|
Topic("House Components and Physical Coordinates", "宫位分量与坐标", "House Components and Physical Coordinates"),
|
|
Topic("Birth Calendar Elements", "出生历法", "Birth Calendar"),
|
|
Topic("Goel Jaimini Strength and Special-Point Evidence", "Goel Jaimini 强度与特殊点", "Goel Jaimini Strength and Special Points"),
|
|
Topic("Dasha Boundary Scan", "大运与小运交界检查", "Dasha Boundary Scan", "text"),
|
|
Topic("Natal Vivah Saham", "本命 Vivah Saham", "Natal Vivah Saham"),
|
|
Topic("Lagna Vargottamamsa", "上升 Vargottamamsa", "Lagna Vargottamamsa"),
|
|
Topic("Natal Tithi Lord Associations", "本命 Tithi 主星", "Natal Tithi Lord"),
|
|
Topic("Dated Pancha Pakshi Schedule", "五鸟活动", "Pancha Pakshi"),
|
|
Topic("Neutral and Compound Planetary Relationships", "行星中性与复合友敌关系", "Neutral and Compound Relationships"),
|
|
Topic("Pushkara Decision Basis", "Pushkara 判断依据", "Pushkara Basis"),
|
|
Topic("Rashi Tulya Navamsa Mapping", "Rashi Tulya Navamsa", "Rashi Tulya Navamsa"),
|
|
Topic("Dispositor Terminals and Cycles", "定位星终点与循环", "Dispositor Terminals"),
|
|
Topic("Natal Saham Formula Basis", "本命特殊点公式依据", "Natal Saham Formula Basis"),
|
|
Topic("Bhrigu Relationship Geometry", "Bhrigu 关系几何", "Bhrigu Relationship Geometry"),
|
|
Topic("Aspect Geometry and Motion Data", "相位几何", "Aspect Geometry"),
|
|
Topic("Avastha Inputs and Method Data", "行星状态输入", "Avastha Inputs"),
|
|
Topic("Vimsopaka Contribution Details", "Vimsopaka 分盘贡献", "Vimsopaka Contribution"),
|
|
Topic("Argala Support and Obstruction Structure", "Argala 支持与阻挡", "Argala"),
|
|
Topic("Nakshatra Reference Data", "星宿参照", "Nakshatra Reference"),
|
|
Topic("Dispositor Chain Data", "定位星链", "Dispositor Chain"),
|
|
Topic("Bhava Chalit Planet Placements", "Bhava Chalit 行星落宫", "Bhava Chalit Planet Placements"),
|
|
Topic("Dated Transit Positions", "注明日期的行运", "Dated Transit", column=("星座", "Sign", "all")),
|
|
Topic("Double Transit PAC Data", "木土双重行运 PAC", "Double Transit PAC"),
|
|
Topic("Lagna and Seventh Lord Transit Checks", "上升主与七宫主行运", "Lagna / 7th Lord Transit"),
|
|
Topic("Planetary Congregation Data", "行星聚集", "Congregation"),
|
|
Topic("D30 Sign-Based Planetary States", "D30 状态", "D30 States"),
|
|
Topic("Bhava Bala Three-Component Alternative", "Bhava Bala 三分量", "Bhava Bala Three-Component"),
|
|
Topic("KP Calculation Conventions", "KP 计算口径", "KP Calculation Conventions"),
|
|
Topic("D9 Dignity and Navamsa Segments", "D9 尊贵", "D9 Dignity"),
|
|
Topic("Divisional Mapping Conventions", "分盘映射", "Divisional Mapping"),
|
|
Topic("Bhava Chalit House Centres and Boundaries", "Bhava Chalit 宫心", "Bhava Chalit Centres"),
|
|
Topic("Conditional Dasha Applicability", "条件大运是否适用", "Conditional Dasha Applicability"),
|
|
Topic("Chara Dasha Period Durations", "Chara 大运时长", "Chara Dasha Period Durations"),
|
|
Topic("Bhrigu Approximate Progression Sequence", "Bhrigu 近似推进序列", "Bhrigu Approximate Progression"),
|
|
Topic("Additional Native Timing Calculations", "补充推运计算数据", "Additional timing calculations", "group"),
|
|
Topic("Yoga Vimshottari natal", "本命 Yoga Vimshottari", "Natal Yoga Vimshottari"),
|
|
Topic("Saptavarga lord relationships", "七分盘星座主", "Saptavarga lords"),
|
|
Topic("Buddhi Gati", "Buddhi Gati", "Buddhi Gati"),
|
|
Topic("Kaala", "Kaala", "Kaala"),
|
|
Topic("Sudasa", "Sudasa 出生周期", "Sudasa birth cycle"),
|
|
Topic("Independent Annual Method Reference", "独立年度方法参考", "Independent Annual Method Reference", "group"),
|
|
Topic("Three-Year Predictive Ephemeris", "三年逐月星历", "Three-Year Predictive Ephemeris"),
|
|
Topic("Narayana Method Comparison", "Narayana 口径对照", "Narayana Method Comparison"),
|
|
Topic("Yogini Dasha Cycle Context", "Yogini 周期", "Yogini Periods"),
|
|
Topic("Tribhagi Dasha Profile", "Tribhagi 适用情况", "Tribhagi Profile"),
|
|
Topic("Jaimini Calculation Details", "Jaimini 计算细节", "Jaimini Calculation Details"),
|
|
Topic("Jaimini Graha Pada Derivation", "Graha Pada", "Graha Pada"),
|
|
Topic("Jaimini Yogi and Ava Yogi", "Jaimini Yogi 与 Ava Yogi", "Jaimini Yogi and Ava Yogi"),
|
|
Topic("Karakamsha Coordinates", "Karakamsha", "Karakamsha"),
|
|
Topic("Darakaraka Chart Coordinates", "Darakaraka", "Darakaraka"),
|
|
Topic("Navamsha Dasha AD Duration Contract", "Navamsha 小运时长", "Navamsha AD Duration"),
|
|
Topic("Bhrigu Cycle Context", "Bhrigu 周期", "Bhrigu Cycle"),
|
|
Topic("Arudha / Upapada / A10 Derivation", "Arudha、Upapada 与 A10", "Arudha / UL / A10"),
|
|
Topic("D30 Source Input Degrees", "D30 输入", "D30 Source Input"),
|
|
Topic("Tara and Chandra Combined Matrix", "Tara 与 Chandra 矩阵", "Tara-Chandra Matrix"),
|
|
Topic("Nakshatra Dasha Timing Context", "星宿大运上下文", "Nakshatra Dasha Context"),
|
|
Topic("Natal Saham Formula Trace", "本命特殊点公式轨迹", "Natal Saham Formula Trace"),
|
|
Topic("Vimshottari Birth-Balance Basis", "Vimshottari 出生余额", "Vimshottari Birth-Balance"),
|
|
Topic("Multi-Reference Transit Positions", "多参考点行运", "Multi-Reference Transit"),
|
|
Topic("Annual Return House Framework", "年运整宫框架", "Annual Return House Framework"),
|
|
Topic("Annual Return Calculation Contract", "年运返照计算约定", "Annual Return Calculation Contract"),
|
|
Topic("Tajika Aspect and Yoga Candidates", "Tajika 相位与瑜伽候选", "Tajika Aspect and Yoga Candidates", "text"),
|
|
Topic("Tripataki Chakra Detail", "Tripataki 轮盘明细", "Tripataki Chakra Detail"),
|
|
Topic("Annual Tajika Strength Detail", "年度 Tajika 力量", "Annual Tajika Strength"),
|
|
Topic("Annual Saham Formula Trace", "年度特殊点公式轨迹", "Annual Saham Formula Trace"),
|
|
Topic("Annual Chart Numeric Data", "年度图盘数值数据", "Annual Chart Numeric Data"),
|
|
Topic("Current Dasha Convergence by Domain", "当前多系统收敛", "Current Dasha Convergence"),
|
|
Topic("Canonical Yoga Candidate Rows", "瑜伽条目", "Canonical Yoga Rows", column=("行星", "Planet", "any")),
|
|
Topic("Ashtakavarga Yoga Pinda Reduction Data", "八分法 Yoga Pinda", "AV Yoga Pinda"),
|
|
Topic("Shadbala Result Summary", "六维力量结果", "Shadbala Result"),
|
|
Topic("Ashtakavarga Sign Assessments", "八分法星座评估", "AV Sign Assessments"),
|
|
Topic("Prastara Ashtakavarga Contribution Totals", "Prastara 合计", "Prastara Totals"),
|
|
)
|
|
|
|
# Upstream topics this report does not carry, each with the decision on record.
|
|
NOT_CARRIED: dict[str, str] = {
|
|
"Tithi Ashtottari — independent MD/AD/PD": "A raw PyJHora external-replay dump (AGPL fields); not shipped to customers (2026-11-06).",
|
|
"Eight-Year Residence Overview": "Needs the user's current residence, which the product does not collect.",
|
|
"Narayana Method Comparison · PyJHora comparison": "Report lines naming PyJHora are removed by product rule; Rath and the source-aware method are both shown.",
|
|
}
|
|
|
|
DEGRADED_MARKERS: dict[str, tuple[str, ...]] = {
|
|
"zh": ("公开报告资料包未带此模块", "(简化模型)"),
|
|
"en": ("This module is not in the public report packet", "(Simplified model)"),
|
|
}
|
|
_UNDETERMINED = {"zh": {"未判定", "—", "-", "", "无"}, "en": {"not determined", "Not determined", "—", "-", "", "None"}}
|
|
_SEPARATOR = re.compile(r"^\|?\s*:?-{2,}")
|
|
|
|
|
|
def _sections(markdown: str) -> list[tuple[str, str]]:
|
|
"""(heading text, body up to the next heading of the same or higher level)."""
|
|
lines = markdown.splitlines()
|
|
out: list[tuple[str, str]] = []
|
|
heads = [(i, len(m.group(1)), m.group(2).strip()) for i, line in enumerate(lines)
|
|
if (m := re.match(r"^(#{2,4})\s+(.+?)\s*$", line))]
|
|
for index, (line_no, level, text) in enumerate(heads):
|
|
end = len(lines)
|
|
for later_no, later_level, _ in heads[index + 1:]:
|
|
if later_level <= level:
|
|
end = later_no
|
|
break
|
|
out.append((text, "\n".join(lines[line_no + 1:end])))
|
|
return out
|
|
|
|
|
|
def _real_cell(body: str, language: str) -> bool:
|
|
"""A data row (below a table's separator) with a real value outside the label column."""
|
|
empty = _UNDETERMINED[language]
|
|
in_rows = False
|
|
for line in body.splitlines():
|
|
if not line.startswith("|"):
|
|
in_rows = False
|
|
continue
|
|
if _SEPARATOR.match(line.strip()):
|
|
in_rows = True
|
|
continue
|
|
if not in_rows:
|
|
continue # the header row names columns; it is not data
|
|
cells = [cell.strip() for cell in line.strip().strip("|").split("|")]
|
|
if any(cell not in empty for cell in cells[1:]):
|
|
return True
|
|
return False
|
|
|
|
|
|
def _column_values(body: str, header: str) -> list[str]:
|
|
"""Values of one named column across the tables in a section body."""
|
|
values: list[str] = []
|
|
index: int | None = None
|
|
in_rows = False
|
|
for line in body.splitlines():
|
|
if not line.startswith("|"):
|
|
index, in_rows = None, False
|
|
continue
|
|
cells = [cell.strip() for cell in line.strip().strip("|").split("|")]
|
|
if _SEPARATOR.match(line.strip()):
|
|
in_rows = index is not None
|
|
continue
|
|
if not in_rows:
|
|
lowered = [cell.lower() for cell in cells]
|
|
index = lowered.index(header.lower()) if header.lower() in lowered else None
|
|
continue
|
|
if index is not None and index < len(cells):
|
|
values.append(cells[index])
|
|
return values
|
|
|
|
|
|
def _prose(body: str) -> bool:
|
|
text = "\n".join(line for line in body.splitlines() if line.strip() and not line.startswith("|"))
|
|
return len(text.strip()) >= 12
|
|
|
|
|
|
def audit_report(markdown: str, language: str = "zh") -> list[dict[str, str]]:
|
|
"""Findings for one exported report; an empty list means full coverage."""
|
|
findings: list[dict[str, str]] = []
|
|
sections = _sections(markdown)
|
|
for topic in TOPICS:
|
|
wanted = topic.zh if language == "zh" else topic.en
|
|
matches = [body for text, body in sections if text.startswith(wanted)]
|
|
if not matches:
|
|
findings.append({"check": "missing_section", "topic": topic.upstream, "heading": wanted})
|
|
continue
|
|
if topic.kind == "group":
|
|
continue
|
|
ok = any(_real_cell(body, language) or (topic.kind == "text" and _prose(body)) for body in matches)
|
|
if not ok:
|
|
findings.append({"check": "empty_section", "topic": topic.upstream, "heading": wanted})
|
|
continue
|
|
if topic.column:
|
|
header = topic.column[0] if language == "zh" else topic.column[1]
|
|
values = [value for body in matches for value in _column_values(body, header)]
|
|
real = [value for value in values if value not in _UNDETERMINED[language]]
|
|
if not values or (topic.column[2] == "all" and len(real) < len(values)) or not real:
|
|
findings.append({"check": "empty_column", "topic": topic.upstream, "heading": f"{wanted} · {header}"})
|
|
for marker in DEGRADED_MARKERS[language]:
|
|
if marker in markdown:
|
|
findings.append({"check": "degraded_marker", "topic": marker, "heading": ""})
|
|
return findings
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = list(sys.argv[1:] if argv is None else argv)
|
|
language = "zh"
|
|
if "--language" in args:
|
|
index = args.index("--language")
|
|
language = args[index + 1]
|
|
del args[index:index + 2]
|
|
if not args:
|
|
print(__doc__)
|
|
return 2
|
|
with open(args[0], encoding="utf-8") as handle:
|
|
findings = audit_report(handle.read(), language)
|
|
for item in findings:
|
|
print(f"{item['check']}\t{item['topic']}\t{item['heading']}")
|
|
print(f"{len(TOPICS)} topics checked, {len(findings)} findings, {len(NOT_CARRIED)} not carried on record")
|
|
return 1 if findings else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|