#!/usr/bin/env python3 """ Convert salary data from Excel to JSON format. This script converts an Excel file containing company salary data into the JSON format expected by salary_lookup.py. Prerequisites: pip install openpyxl Usage: python tools/convert_salary_excel.py python tools/convert_salary_excel.py --source "My Union Stats 2025" python tools/convert_salary_excel.py --baseline 100 --baseline-desc "Index 100 = median salary" The output file (salary_data.json) will be written to the repository root. Expected Excel format: - A header row with column names - A "Company" or "Firma" column (required) - An optional "City" or "By" column - Any number of numeric data columns (salary index, count, etc.) The script auto-detects the header row and column layout. For Excel files with paired count/index columns per category, it groups them automatically. """ import json import sys import argparse import re from pathlib import Path try: import openpyxl except ImportError: openpyxl = None # Column name patterns for auto-detection COMPANY_PATTERNS = {"firma", "company", "virksomhed", "employer", "arbejdsgiver"} CITY_PATTERNS = {"by", "city", "kommune", "location", "lokation", "sted"} COUNT_PATTERNS = {"antal", "count", "number", "n", "employees", "medarbejdere"} INDEX_PATTERNS = {"indeks", "index", "idx", "salary", "løn", "median", "average", "gennemsnit"} DANISH_COMPOUND_PATTERNS = {"antal", "indeks", "løn", "gennemsnit", "medarbejdere"} def header_matches(header, patterns): """Return True when a header contains a meaningful pattern match.""" h = header.lower().strip() tokens = set(re.findall(r"[a-zæøåöäü0-9]+", h)) for p in patterns: if p in tokens: return True if p in DANISH_COMPOUND_PATTERNS and p in h: return True return False def strip_type_patterns(header, patterns): """Remove count/index words from a header to derive a category name.""" name = header.lower() for p in patterns: name = re.sub(rf"(?