55import json
66import logging
77import textwrap
8- from typing import Any
98
109from retrai .tools .python_exec import python_exec
1110
@@ -93,7 +92,10 @@ def _build_summary_code(file_path: str) -> str:
9392 "columns": list(df.columns),
9493 "dtypes": {{col: str(dtype) for col, dtype in df.dtypes.items()}},
9594 "missing": {{col: int(v) for col, v in df.isnull().sum().items() if v > 0}},
96- "missing_pct": {{col: round(v / len(df) * 100, 1) for col, v in df.isnull().sum().items() if v > 0}},
95+ "missing_pct": {{
96+ col: round(v / len(df) * 100, 1)
97+ for col, v in df.isnull().sum().items() if v > 0
98+ }},
9799 }}
98100
99101 # Numeric summary
@@ -181,7 +183,10 @@ def _build_quality_code(file_path: str) -> str:
181183 "memory_mb": round(df.memory_usage(deep=True).sum() / 1024 / 1024, 2),
182184 "duplicate_rows": int(df.duplicated().sum()),
183185 "complete_rows": int(df.dropna().shape[0]),
184- "completeness_pct": round(df.dropna().shape[0] / len(df) * 100, 1) if len(df) > 0 else 0,
186+ "completeness_pct": (
187+ round(df.dropna().shape[0] / len(df) * 100, 1)
188+ if len(df) > 0 else 0
189+ ),
185190 }}
186191
187192 # Per-column quality
@@ -190,9 +195,15 @@ def _build_quality_code(file_path: str) -> str:
190195 info = {{
191196 "dtype": str(df[col].dtype),
192197 "missing": int(df[col].isnull().sum()),
193- "missing_pct": round(df[col].isnull().sum() / len(df) * 100, 1) if len(df) > 0 else 0,
198+ "missing_pct": (
199+ round(df[col].isnull().sum() / len(df) * 100, 1)
200+ if len(df) > 0 else 0
201+ ),
194202 "unique": int(df[col].nunique()),
195- "unique_pct": round(df[col].nunique() / len(df) * 100, 1) if len(df) > 0 else 0,
203+ "unique_pct": (
204+ round(df[col].nunique() / len(df) * 100, 1)
205+ if len(df) > 0 else 0
206+ ),
196207 }}
197208 if df[col].dtype in ["float64", "int64"]:
198209 info["zeros"] = int((df[col] == 0).sum())
@@ -240,12 +251,21 @@ def _build_distribution_code(file_path: str) -> str:
240251 col_info = {{"dtype": str(df[col].dtype)}}
241252
242253 if df[col].dtype in ["float64", "int64"]:
243- col_info["min"] = float(df[col].min()) if not df[col].isnull().all() else None
244- col_info["max"] = float(df[col].max()) if not df[col].isnull().all() else None
245- col_info["mean"] = round(float(df[col].mean()), 4) if not df[col].isnull().all() else None
246- col_info["median"] = float(df[col].median()) if not df[col].isnull().all() else None
247- col_info["std"] = round(float(df[col].std()), 4) if not df[col].isnull().all() else None
248- col_info["skewness"] = round(float(df[col].skew()), 4) if not df[col].isnull().all() else None
254+ not_null = not df[col].isnull().all()
255+ col_info["min"] = float(df[col].min()) if not_null else None
256+ col_info["max"] = float(df[col].max()) if not_null else None
257+ col_info["mean"] = (
258+ round(float(df[col].mean()), 4) if not_null else None
259+ )
260+ col_info["median"] = (
261+ float(df[col].median()) if not_null else None
262+ )
263+ col_info["std"] = (
264+ round(float(df[col].std()), 4) if not_null else None
265+ )
266+ col_info["skewness"] = (
267+ round(float(df[col].skew()), 4) if not_null else None
268+ )
249269
250270 # Histogram bins
251271 try:
0 commit comments