Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| import re | |
| from typing import Any | |
| SECTION_RULES = [ | |
| (("pond", "storage", "freeboard", "spillway", "forebay"), "Storage and Pond Design"), | |
| (("pipe", "conduit", "sewer", "hgl", "surcharge", "velocity"), "Minor-System Hydraulics"), | |
| (("overland", "major system", "spill route", "surface drainage"), "Major-System Assessment"), | |
| (("catchment", "subcatchment", "impervious", "runoff", "hydrology"), "Hydrology and Catchment Parameters"), | |
| (("rainfall", "storm", "idf", "hyetograph"), "Design Storm"), | |
| (("water quality", "tss", "erosion", "sediment"), "Water Quality"), | |
| (("drawing", "profile", "plan", "detail"), "Drawing Coordination"), | |
| (("model", "swmm", "input file", "output file"), "Computer Model and Appendices"), | |
| ] | |
| def parse_comments(value: list | str) -> list[dict[str, Any]]: | |
| if isinstance(value, list): | |
| rows = [] | |
| for n, item in enumerate(value, 1): | |
| if isinstance(item, dict): | |
| text = str(item.get("comment") or item.get("text") or "").strip() | |
| cid = str(item.get("comment_id") or item.get("id") or n) | |
| else: | |
| text = str(item).strip(); cid = str(n) | |
| if text: | |
| rows.append({"comment_id": cid, "comment": text}) | |
| return rows | |
| if not isinstance(value, str): | |
| raise ValueError("comments must be a list or text string.") | |
| text = value.strip() | |
| if not text: | |
| return [] | |
| parts = re.split(r"(?m)^\s*(?:Comment\s*)?(\d+[A-Za-z]?)\s*[.):-]\s*", text) | |
| rows = [] | |
| if len(parts) > 1: | |
| prefix = parts[0].strip() | |
| for i in range(1, len(parts), 2): | |
| cid = parts[i].strip(); body = parts[i+1].strip() if i+1 < len(parts) else "" | |
| if body: rows.append({"comment_id": cid, "comment": body}) | |
| if rows: return rows | |
| return [{"comment_id": str(n), "comment": line.strip(" - ")} | |
| for n, line in enumerate(text.splitlines(), 1) if line.strip()] | |
| def _section(comment: str) -> str: | |
| lower = comment.lower() | |
| for words, section in SECTION_RULES: | |
| if any(word in lower for word in words): | |
| return section | |
| return "General / Executive Summary" | |
| def build_response_matrix(comments: list[dict[str, Any]], revision_review: dict[str, Any] | None = None, | |
| report_changes: dict[str, str] | None = None) -> list[dict[str, Any]]: | |
| revision_rows = (revision_review or {}).get("object_impacts", []) | |
| report_changes = report_changes or {} | |
| result = [] | |
| for item in comments: | |
| text = item["comment"] | |
| mentioned = [] | |
| for row in revision_rows: | |
| oid = str(row.get("object", "")) | |
| if oid and re.search(rf"\b{re.escape(oid)}\b", text, re.I): | |
| mentioned.append(row) | |
| evidence = [] | |
| for row in mentioned: | |
| evidence.append(f"{row.get('object')}: revision impact = {row.get('impact')}") | |
| for ev in row.get("evidence", [])[:3]: | |
| if isinstance(ev, dict): | |
| evidence.append( | |
| f"{ev.get('metric')}: {ev.get('baseline')} -> {ev.get('revised')} {ev.get('units') or ''}".strip() | |
| ) | |
| section = _section(text) | |
| changed = report_changes.get(str(item["comment_id"])) or report_changes.get(section) | |
| if evidence and changed: | |
| status = "Resolved" | |
| elif evidence or changed: | |
| status = "Partially resolved" | |
| else: | |
| status = "Clarification required" | |
| response = ( | |
| "The comment has been mapped to deterministic model/revision evidence and the revised report section." | |
| if status == "Resolved" else | |
| "Additional project-specific evidence or an explicit report/drawing revision is required before this comment can be closed." | |
| ) | |
| result.append({ | |
| "comment_id": item["comment_id"], | |
| "city_comment": text, | |
| "topic": section, | |
| "affected_objects": ", ".join(str(r.get("object")) for r in mentioned), | |
| "engineering_evidence": "; ".join(evidence), | |
| "report_change": changed or "Not supplied", | |
| "consultant_response": response, | |
| "status": status, | |
| }) | |
| return result | |