docs: дизайн таблиц, ответы Соннета, CSS, правила без ВМ
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Analyze column widths from YAML specs.
|
||||
Usage: python3 analyze_column_widths.py [stand]
|
||||
stand: test (default), dev, prod
|
||||
"""
|
||||
import os, sys, yaml
|
||||
|
||||
STAND = sys.argv[1] if len(sys.argv) > 1 else 'test'
|
||||
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
YAML_DIR = f'{REPO}/generated/{STAND}/resources_yaml'
|
||||
|
||||
if not os.path.isdir(YAML_DIR):
|
||||
print(f'Error: {YAML_DIR} not found')
|
||||
sys.exit(1)
|
||||
|
||||
all_params = []
|
||||
nested_count = 0
|
||||
|
||||
def extract_params(svc, op, params_list, depth=0):
|
||||
global nested_count
|
||||
for p in params_list:
|
||||
if not isinstance(p, dict): continue
|
||||
all_params.append((svc, op, p, depth))
|
||||
sub = p.get('sub_params', [])
|
||||
if sub:
|
||||
nested_count += len(sub)
|
||||
extract_params(svc, op, sub, depth + 1)
|
||||
|
||||
for fname in sorted(os.listdir(YAML_DIR)):
|
||||
if not fname.endswith('.yaml'): continue
|
||||
with open(os.path.join(YAML_DIR, fname)) as f:
|
||||
data = yaml.safe_load(f)
|
||||
svc = data.get('name', fname)
|
||||
for op in data.get('operations', []):
|
||||
if op.get('action') not in ('create', 'modify'): continue
|
||||
extract_params(svc, op.get('name', '?'), op.get('params', []))
|
||||
|
||||
print(f'Stand: {STAND} | Files: {len(os.listdir(YAML_DIR))}')
|
||||
print(f'Total params: {len(all_params)} | Nested subparams: {nested_count}')
|
||||
|
||||
def stats(items, label):
|
||||
if not items: return
|
||||
lens = [len(str(t[2])) for t in items]
|
||||
n = len(lens)
|
||||
mx, avg = max(lens), sum(lens)/n
|
||||
print(f'\n--- {label} (n={n}) ---')
|
||||
print(f' MAX: {mx} | AVG: {avg:.0f}')
|
||||
print(f' >30: {sum(l in (l>30 for l in lens))/n*100:.0f}% >50: {sum(1 for l in lens if l>50)/n*100:.0f}% >100: {sum(1 for l in lens if l>100)/n*100:.0f}% >200: {sum(1 for l in lens if l>200)/n*100:.0f}% >500: {sum(1 for l in lens if l>500)/n*100:.0f}%')
|
||||
|
||||
codes = [(s,o,p.get('code','')) for s,o,p,d in all_params]
|
||||
dtypes = [(s,o,p.get('data_type', p.get('type',''))) for s,o,p,d in all_params]
|
||||
defs = [(s,o,str(p['default'])) for s,o,p,d in all_params if 'default' in p]
|
||||
descrs = [(s,o,p.get('descr','') or p.get('man','')) for s,o,p,d in all_params if p.get('descr') or p.get('man')]
|
||||
|
||||
constraint_keys = ['min_value','max_value','regex','value_list','max_length','min_length','func','ref_svc_id','unique']
|
||||
constraints = []
|
||||
for s,o,p,d in all_params:
|
||||
parts = []
|
||||
for k in constraint_keys:
|
||||
v = p.get(k)
|
||||
if v is not None: parts.append(f'{k}={v}')
|
||||
if parts: constraints.append((s,o,' | '.join(parts)))
|
||||
|
||||
stats(codes, 'Code'); stats(dtypes, 'Type'); stats(defs, 'Default')
|
||||
stats(descrs, 'Description'); stats(constraints, 'Constraints')
|
||||
|
||||
for name, arr in [('Code', codes), ('Type', dtypes), ('Default', defs),
|
||||
('Description', descrs), ('Constraints', constraints)]:
|
||||
top = sorted(arr, key=lambda x: len(str(x[2])), reverse=True)[:3]
|
||||
print(f'\nTop-3 longest {name}:')
|
||||
for s, o, v in top:
|
||||
print(f' [{s}/{o}] len={len(str(v))}: {str(v)[:120]}')
|
||||
Reference in New Issue
Block a user