Import¶
In [49]:
Copied!
import pandas as pd
import re, os, json
from pathlib import Path
from collections import Counter
import pandas as pd
import re, os, json
from pathlib import Path
from collections import Counter
User Input¶
Base Path¶
In [50]:
Copied!
base_path = r"C:\gitlab\vivaplus-docs\docs\hbm4vt\LS-Dyna\50M"
base_path = r"C:\gitlab\vivaplus-docs\docs\hbm4vt\LS-Dyna\50M"
Notebooks to update (can be ignored)¶
In [51]:
Copied!
orig_nb_names = [
r"bouquet_1994_50M\Bouquet_1994_assessment_Pelvis.ipynb",
r"bouquet_1994_50M\Bouquet_1994_assessment_Sternum.ipynb",
r"cesari_1990_50M\Cesari_1990_assessment.ipynb",
r"compigne_2004_50M\Compigne_2004_assessment.ipynb",
r"forman_2005_50M\Forman_2005_assessment_double_belt.ipynb",
r"forman_2013_50M\Forman_2013_assessment.ipynb",
r"kroell_1971_50M\Kroell_1971_assessment.ipynb",
r"lateral-impactors-viano-1989_50M\Viano_1989_assessment.ipynb",
r"leport_2007_50Mn\Leport_2007_assessment_Hub.ipynb",
r"leport_2007_50M\Leport_2007_assessment_Minisled.ipynb",
r"lopez_valdes_2017_50M\Lopez_Valdes_2017_assessment.ipynb",
r"petit_2019-_50M\Petit_2019_assessment.ipynb",
r"rupp_2008_50M\Rupp_2008_assessment.ipynb",
r"salzar_2009_50M\Salzar_2009_assessment.ipynb",
r"shaw_2004_50M\Shaw_2004_assessment.ipynb",
r"shaw_2006_50M\Shaw_2006_assessment.ipynb",
r"shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x2.ipynb",
r"shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x4.ipynb",
r"shaw_2009_50M\Shaw_2009_assessment.ipynb",
r"tabletop_kent_2004_50M\Kent_2004_assessment_belt.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_distributed.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_double_belt.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_hub.ipynb",
r"uriot_2015_50M\Uriot_2015_assessment.ipynb",
r"yoganandan_1997_50M\Yoganandan_1997_assessment.ipynb",
]
orig_nb_names = [
r"bouquet_1994_50M\Bouquet_1994_assessment_Pelvis.ipynb",
r"bouquet_1994_50M\Bouquet_1994_assessment_Sternum.ipynb",
r"cesari_1990_50M\Cesari_1990_assessment.ipynb",
r"compigne_2004_50M\Compigne_2004_assessment.ipynb",
r"forman_2005_50M\Forman_2005_assessment_double_belt.ipynb",
r"forman_2013_50M\Forman_2013_assessment.ipynb",
r"kroell_1971_50M\Kroell_1971_assessment.ipynb",
r"lateral-impactors-viano-1989_50M\Viano_1989_assessment.ipynb",
r"leport_2007_50Mn\Leport_2007_assessment_Hub.ipynb",
r"leport_2007_50M\Leport_2007_assessment_Minisled.ipynb",
r"lopez_valdes_2017_50M\Lopez_Valdes_2017_assessment.ipynb",
r"petit_2019-_50M\Petit_2019_assessment.ipynb",
r"rupp_2008_50M\Rupp_2008_assessment.ipynb",
r"salzar_2009_50M\Salzar_2009_assessment.ipynb",
r"shaw_2004_50M\Shaw_2004_assessment.ipynb",
r"shaw_2006_50M\Shaw_2006_assessment.ipynb",
r"shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x2.ipynb",
r"shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x4.ipynb",
r"shaw_2009_50M\Shaw_2009_assessment.ipynb",
r"tabletop_kent_2004_50M\Kent_2004_assessment_belt.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_distributed.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_double_belt.ipynb",
r"tabletop_kent_2004-main\Kent_2004_assessment_hub.ipynb",
r"uriot_2015_50M\Uriot_2015_assessment.ipynb",
r"yoganandan_1997_50M\Yoganandan_1997_assessment.ipynb",
]
Main¶
In [52]:
Copied!
def to_path(p):
return p if isinstance(p, Path) else Path(p)
def to_path(p):
return p if isinstance(p, Path) else Path(p)
In [53]:
Copied!
def load_settings(settings_path):
# Fail-Safe: No "settings"-File
if not settings_path.exists():
raise FileNotFoundError(f"Settings file not found: {settings_path.resolve()}")
new_settings = {}
pattern = re.compile(r'^\s*"([^"]+)"\s*:\s*(.+?)(?:,?\s*)$')
# Load new Settings
for line in settings_path.read_text(encoding="utf-8").splitlines():
# Skip emtpy Lines or Comments
line = line.strip()
if not line or line.startswith("#"):
continue
# Find Key and Value
key_and_val = pattern.match(line)
if not key_and_val:
continue
key, val = key_and_val.group(1), key_and_val.group(2).rstrip().rstrip(",").rstrip()
new_settings[key] = val
return new_settings
def load_settings(settings_path):
# Fail-Safe: No "settings"-File
if not settings_path.exists():
raise FileNotFoundError(f"Settings file not found: {settings_path.resolve()}")
new_settings = {}
pattern = re.compile(r'^\s*"([^"]+)"\s*:\s*(.+?)(?:,?\s*)$')
# Load new Settings
for line in settings_path.read_text(encoding="utf-8").splitlines():
# Skip emtpy Lines or Comments
line = line.strip()
if not line or line.startswith("#"):
continue
# Find Key and Value
key_and_val = pattern.match(line)
if not key_and_val:
continue
key, val = key_and_val.group(1), key_and_val.group(2).rstrip().rstrip(",").rstrip()
new_settings[key] = val
return new_settings
In [54]:
Copied!
def find_settings_block_position(orig_nb):
# Find Start of "setttings"-Block
start_brace = re.search(r'settings\s*=\s*\{', orig_nb[0:], flags=re.DOTALL)
if not start_brace:
return None
start = start_brace.end() - 1
# Find Length of "settings"-Block
depth = 0
for i, c in enumerate(orig_nb[start:], start):
depth += (c == '{') - (c == '}')
if depth == 0:
return (start, i)
def find_settings_block_position(orig_nb):
# Find Start of "setttings"-Block
start_brace = re.search(r'settings\s*=\s*\{', orig_nb[0:], flags=re.DOTALL)
if not start_brace:
return None
start = start_brace.end() - 1
# Find Length of "settings"-Block
depth = 0
for i, c in enumerate(orig_nb[start:], start):
depth += (c == '{') - (c == '}')
if depth == 0:
return (start, i)
In [55]:
Copied!
def replace_keys(settings_block, new_settings):
# Find and replace Key Values
for key, val in new_settings.items():
# Find Keys
pattern = rf'((["\']){re.escape(key)}\2\s*:\s*)([^,}}]+)'
# Replace Values
def replace(match): return f"{match.group(1)}{val}"
settings_block, n = re.subn(pattern, replace, settings_block)
if n:
changed = True
return settings_block, changed
def replace_keys(settings_block, new_settings):
# Find and replace Key Values
for key, val in new_settings.items():
# Find Keys
pattern = rf'((["\']){re.escape(key)}\2\s*:\s*)([^,}}]+)'
# Replace Values
def replace(match): return f"{match.group(1)}{val}"
settings_block, n = re.subn(pattern, replace, settings_block)
if n:
changed = True
return settings_block, changed
In [56]:
Copied!
def update_notebook_settings(base_path, orig_nb_name):
# Define Paths
base_path = to_path(base_path)
settings_path = base_path / "new_settings.txt"
orig_nb_path = base_path / orig_nb_name
# Load new "settings"-Block
new_settings = load_settings(settings_path)
# Skip missing Notebooks
if not orig_nb_path.exists():
return
# Load original Notebooks
with orig_nb_path.open("r", encoding="utf-8") as f:
nb = json.load(f)
# Find Code in Notebook
for cell in (c for c in nb.get("cells", []) if c.get("cell_type") == "code"):
# Code to String
source = cell.get("source", "")
orig_nb = "".join(source) if isinstance(source, list) else (source or "")
# Find "settings"-Block Position
settings_block_pos = find_settings_block_position(orig_nb)
if not settings_block_pos:
continue
start, end = settings_block_pos
before = orig_nb[:start]
settings_block = orig_nb[start:end + 1]
after = orig_nb[end + 1:]
# Update "settings"-Block
new_settings_block, changed = replace_keys(settings_block, new_settings)
if changed:
src = before + new_settings_block + after
# Jupyter cells expect list of strings
cell["source"] = src.splitlines(keepends=True)
# Output
print(f"\n- {orig_nb_name}")
if changed:
with orig_nb_path.open("w", encoding="utf-8") as f:
json.dump(nb, f, indent=1, ensure_ascii=False)
print(f"> updated")
else:
print(f"-> no replacements made in")
def update_notebook_settings(base_path, orig_nb_name):
# Define Paths
base_path = to_path(base_path)
settings_path = base_path / "new_settings.txt"
orig_nb_path = base_path / orig_nb_name
# Load new "settings"-Block
new_settings = load_settings(settings_path)
# Skip missing Notebooks
if not orig_nb_path.exists():
return
# Load original Notebooks
with orig_nb_path.open("r", encoding="utf-8") as f:
nb = json.load(f)
# Find Code in Notebook
for cell in (c for c in nb.get("cells", []) if c.get("cell_type") == "code"):
# Code to String
source = cell.get("source", "")
orig_nb = "".join(source) if isinstance(source, list) else (source or "")
# Find "settings"-Block Position
settings_block_pos = find_settings_block_position(orig_nb)
if not settings_block_pos:
continue
start, end = settings_block_pos
before = orig_nb[:start]
settings_block = orig_nb[start:end + 1]
after = orig_nb[end + 1:]
# Update "settings"-Block
new_settings_block, changed = replace_keys(settings_block, new_settings)
if changed:
src = before + new_settings_block + after
# Jupyter cells expect list of strings
cell["source"] = src.splitlines(keepends=True)
# Output
print(f"\n- {orig_nb_name}")
if changed:
with orig_nb_path.open("w", encoding="utf-8") as f:
json.dump(nb, f, indent=1, ensure_ascii=False)
print(f"> updated")
else:
print(f"-> no replacements made in")
Output¶
In [57]:
Copied!
for orig_nb_name in orig_nb_names:
update_notebook_settings(base_path, orig_nb_name)
for orig_nb_name in orig_nb_names:
update_notebook_settings(base_path, orig_nb_name)
- bouquet_1994_50M\Bouquet_1994_assessment_Pelvis.ipynb > updated - bouquet_1994_50M\Bouquet_1994_assessment_Sternum.ipynb > updated - cesari_1990_50M\Cesari_1990_assessment.ipynb > updated - compigne_2004_50M\Compigne_2004_assessment.ipynb > updated - forman_2005_50M\Forman_2005_assessment_double_belt.ipynb > updated - forman_2013_50M\Forman_2013_assessment.ipynb > updated - kroell_1971_50M\Kroell_1971_assessment.ipynb > updated - leport_2007_50M\Leport_2007_assessment_Minisled.ipynb > updated - lopez_valdes_2017_50M\Lopez_Valdes_2017_assessment.ipynb > updated - rupp_2008_50M\Rupp_2008_assessment.ipynb > updated - salzar_2009_50M\Salzar_2009_assessment.ipynb > updated - shaw_2004_50M\Shaw_2004_assessment.ipynb > updated - shaw_2006_50M\Shaw_2006_assessment.ipynb > updated - shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x2.ipynb > updated - shaw_2007_50M\Shaw_2007_Dynamic_assessment_2x4.ipynb > updated - shaw_2009_50M\Shaw_2009_assessment.ipynb > updated - tabletop_kent_2004_50M\Kent_2004_assessment_belt.ipynb > updated - uriot_2015_50M\Uriot_2015_assessment.ipynb > updated - yoganandan_1997_50M\Yoganandan_1997_assessment.ipynb > updated