many revisions, getting closer

This commit is contained in:
2026-02-16 17:49:20 -08:00
parent 1cb4ea07eb
commit 661a7a3309
36 changed files with 23555 additions and 0 deletions

View File

@@ -0,0 +1,771 @@
#!/usr/bin/env python3
"""
Create PowerPoint: The Stories Our Data Tells
How DTS Helps Save Lives - 45 minute internal presentation
"""
import os
import sys
# Add parent directory to path for shared assets
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
# Create presentation with widescreen dimensions
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
# Color scheme - DTS-inspired professional blue
DARK_BLUE = RGBColor(0, 48, 87) # Deep navy
ACCENT_BLUE = RGBColor(0, 120, 174) # Bright blue
LIGHT_BLUE = RGBColor(173, 216, 230) # Light accent
DARK_GRAY = RGBColor(51, 51, 51)
LIGHT_GRAY = RGBColor(245, 245, 245)
WHITE = RGBColor(255, 255, 255)
ACCENT_ORANGE = RGBColor(230, 126, 34)
HIGHLIGHT_RED = RGBColor(192, 57, 43)
def add_title_slide(title, subtitle=""):
"""Full-bleed title slide"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Dark blue background
bg = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height
)
bg.fill.solid()
bg.fill.fore_color.rgb = DARK_BLUE
bg.line.fill.background()
# Title
title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(2.8), Inches(12.333), Inches(1.5)
)
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(60)
p.font.bold = True
p.font.color.rgb = WHITE
p.alignment = PP_ALIGN.CENTER
if subtitle:
sub_box = slide.shapes.add_textbox(
Inches(0.5), Inches(4.5), Inches(12.333), Inches(0.8)
)
tf = sub_box.text_frame
p = tf.paragraphs[0]
p.text = subtitle
p.font.size = Pt(28)
p.font.color.rgb = LIGHT_BLUE
p.alignment = PP_ALIGN.CENTER
return slide
def add_section_slide(title, subtitle=""):
"""Section divider with accent bar"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Left accent bar
bar = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, Inches(0.4), prs.slide_height
)
bar.fill.solid()
bar.fill.fore_color.rgb = ACCENT_BLUE
bar.line.fill.background()
# Section title
title_box = slide.shapes.add_textbox(Inches(1), Inches(2.5), Inches(11), Inches(2))
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(48)
p.font.bold = True
p.font.color.rgb = DARK_BLUE
if subtitle:
p = tf.add_paragraph()
p.text = subtitle
p.font.size = Pt(24)
p.font.color.rgb = DARK_GRAY
return slide
def add_stat_slide(number, description, context=""):
"""Big number impact slide"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Number
num_box = slide.shapes.add_textbox(
Inches(0.5), Inches(2), Inches(12.333), Inches(2.5)
)
tf = num_box.text_frame
p = tf.paragraphs[0]
p.text = number
p.font.size = Pt(144)
p.font.bold = True
p.font.color.rgb = ACCENT_BLUE
p.alignment = PP_ALIGN.CENTER
# Description
desc_box = slide.shapes.add_textbox(
Inches(0.5), Inches(4.5), Inches(12.333), Inches(1)
)
tf = desc_box.text_frame
p = tf.paragraphs[0]
p.text = description
p.font.size = Pt(32)
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
if context:
ctx_box = slide.shapes.add_textbox(
Inches(1), Inches(5.8), Inches(11.333), Inches(1)
)
tf = ctx_box.text_frame
p = tf.paragraphs[0]
p.text = context
p.font.size = Pt(18)
p.font.italic = True
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
return slide
def add_quote_slide(quote, attribution=""):
"""Quote slide with large text"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Quote
quote_box = slide.shapes.add_textbox(
Inches(1), Inches(2), Inches(11.333), Inches(3)
)
tf = quote_box.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.text = f'"{quote}"'
p.font.size = Pt(36)
p.font.italic = True
p.font.color.rgb = DARK_BLUE
p.alignment = PP_ALIGN.CENTER
if attribution:
attr_box = slide.shapes.add_textbox(
Inches(1), Inches(5.5), Inches(11.333), Inches(0.5)
)
tf = attr_box.text_frame
p = tf.paragraphs[0]
p.text = f"- {attribution}"
p.font.size = Pt(20)
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
return slide
def add_content_slide(title, bullets, subtitle=""):
"""Standard content slide with bullets"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Header bar
header = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Inches(1.2)
)
header.fill.solid()
header.fill.fore_color.rgb = DARK_BLUE
header.line.fill.background()
# Title
title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(0.25), Inches(12), Inches(0.9)
)
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(36)
p.font.bold = True
p.font.color.rgb = WHITE
# Subtitle in header
if subtitle:
sub_box = slide.shapes.add_textbox(
Inches(0.5), Inches(0.75), Inches(12), Inches(0.4)
)
tf = sub_box.text_frame
p = tf.paragraphs[0]
p.text = subtitle
p.font.size = Pt(16)
p.font.color.rgb = LIGHT_BLUE
# Bullets
bullet_box = slide.shapes.add_textbox(
Inches(0.8), Inches(1.6), Inches(11.5), Inches(5.5)
)
tf = bullet_box.text_frame
tf.word_wrap = True
for i, bullet in enumerate(bullets):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.text = f" {bullet}"
p.font.size = Pt(24)
p.font.color.rgb = DARK_GRAY
p.space_after = Pt(18)
return slide
def add_two_column_slide(title, left_title, left_items, right_title, right_items):
"""Two column comparison slide"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Header
header = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Inches(1.0)
)
header.fill.solid()
header.fill.fore_color.rgb = DARK_BLUE
header.line.fill.background()
title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(0.2), Inches(12), Inches(0.7)
)
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(32)
p.font.bold = True
p.font.color.rgb = WHITE
# Left column title
left_title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(1.3), Inches(6), Inches(0.5)
)
tf = left_title_box.text_frame
p = tf.paragraphs[0]
p.text = left_title
p.font.size = Pt(22)
p.font.bold = True
p.font.color.rgb = ACCENT_BLUE
# Left items
left_box = slide.shapes.add_textbox(
Inches(0.5), Inches(1.9), Inches(5.8), Inches(5)
)
tf = left_box.text_frame
tf.word_wrap = True
for i, item in enumerate(left_items):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.text = f" {item}"
p.font.size = Pt(18)
p.font.color.rgb = DARK_GRAY
p.space_after = Pt(10)
# Divider line
divider = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, Inches(6.5), Inches(1.3), Inches(0.02), Inches(5.5)
)
divider.fill.solid()
divider.fill.fore_color.rgb = LIGHT_BLUE
divider.line.fill.background()
# Right column title
right_title_box = slide.shapes.add_textbox(
Inches(6.8), Inches(1.3), Inches(6), Inches(0.5)
)
tf = right_title_box.text_frame
p = tf.paragraphs[0]
p.text = right_title
p.font.size = Pt(22)
p.font.bold = True
p.font.color.rgb = ACCENT_BLUE
# Right items
right_box = slide.shapes.add_textbox(Inches(6.8), Inches(1.9), Inches(6), Inches(5))
tf = right_box.text_frame
tf.word_wrap = True
for i, item in enumerate(right_items):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.text = f" {item}"
p.font.size = Pt(18)
p.font.color.rgb = DARK_GRAY
p.space_after = Pt(10)
return slide
def add_story_headline_slide(headline, subtext=""):
"""Newspaper-style headline slide"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Light gray "newspaper" background
bg = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, Inches(0.5), Inches(1.5), Inches(12.333), Inches(4.5)
)
bg.fill.solid()
bg.fill.fore_color.rgb = LIGHT_GRAY
bg.line.color.rgb = DARK_GRAY
# Headline
headline_box = slide.shapes.add_textbox(
Inches(1), Inches(2.5), Inches(11.333), Inches(2)
)
tf = headline_box.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.text = headline
p.font.size = Pt(44)
p.font.bold = True
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
if subtext:
sub_box = slide.shapes.add_textbox(
Inches(1), Inches(4.8), Inches(11.333), Inches(0.8)
)
tf = sub_box.text_frame
p = tf.paragraphs[0]
p.text = subtext
p.font.size = Pt(24)
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
return slide
def add_graph_placeholder_slide(title, graph_description, caption=""):
"""Slide with placeholder for graph/chart"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Header
header = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Inches(1.0)
)
header.fill.solid()
header.fill.fore_color.rgb = DARK_BLUE
header.line.fill.background()
title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(0.2), Inches(12), Inches(0.7)
)
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(32)
p.font.bold = True
p.font.color.rgb = WHITE
# Graph placeholder
graph = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, Inches(1), Inches(1.5), Inches(11.333), Inches(4.5)
)
graph.fill.solid()
graph.fill.fore_color.rgb = LIGHT_GRAY
graph.line.color.rgb = ACCENT_BLUE
# Graph description
desc_box = slide.shapes.add_textbox(
Inches(1), Inches(3.3), Inches(11.333), Inches(1)
)
tf = desc_box.text_frame
p = tf.paragraphs[0]
p.text = f"[{graph_description}]"
p.font.size = Pt(24)
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
if caption:
cap_box = slide.shapes.add_textbox(
Inches(1), Inches(6.3), Inches(11.333), Inches(0.8)
)
tf = cap_box.text_frame
p = tf.paragraphs[0]
p.text = caption
p.font.size = Pt(18)
p.font.italic = True
p.font.color.rgb = DARK_GRAY
p.alignment = PP_ALIGN.CENTER
return slide
def add_connection_slide(title, connections):
"""Show flow/connection between concepts"""
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Header
header = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, Inches(1.0)
)
header.fill.solid()
header.fill.fore_color.rgb = DARK_BLUE
header.line.fill.background()
title_box = slide.shapes.add_textbox(
Inches(0.5), Inches(0.2), Inches(12), Inches(0.7)
)
tf = title_box.text_frame
p = tf.paragraphs[0]
p.text = title
p.font.size = Pt(32)
p.font.bold = True
p.font.color.rgb = WHITE
# Connection boxes
num_items = len(connections)
box_width = Inches(2.2)
spacing = (prs.slide_width - box_width * num_items) / (num_items + 1)
for i, item in enumerate(connections):
x = spacing + i * (box_width + spacing)
# Box
box = slide.shapes.add_shape(
MSO_SHAPE.ROUNDED_RECTANGLE, x, Inches(3), box_width, Inches(1.5)
)
box.fill.solid()
box.fill.fore_color.rgb = ACCENT_BLUE if i % 2 == 0 else DARK_BLUE
box.line.fill.background()
# Text
text_box = slide.shapes.add_textbox(x, Inches(3.3), box_width, Inches(1))
tf = text_box.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.text = item
p.font.size = Pt(16)
p.font.bold = True
p.font.color.rgb = WHITE
p.alignment = PP_ALIGN.CENTER
# Arrow (except for last)
if i < num_items - 1:
arrow = slide.shapes.add_shape(
MSO_SHAPE.RIGHT_ARROW,
x + box_width + Inches(0.1),
Inches(3.5),
spacing - Inches(0.2),
Inches(0.5),
)
arrow.fill.solid()
arrow.fill.fore_color.rgb = LIGHT_BLUE
arrow.line.fill.background()
return slide
# ============================================================================
# BUILD THE PRESENTATION
# ============================================================================
# Slide 1: Title
add_title_slide("The Stories Our Data Tells", "How DTS Helps Save Lives")
# Slide 2: The Number That Matters
add_stat_slide(
"117,000",
"Lives saved every year in the U.S. alone",
"Compared to 1970 fatality rates - a 77% reduction per mile driven",
)
# Slide 3: Quote - Crashed Car
add_quote_slide(
"A crashed car is destroyed in milliseconds. The data is what remains.",
"The foundation of safety engineering",
)
# Slide 4: Section - Part 1
add_section_slide("PART 1", "The Data Behind the Headlines")
# Slide 5: Story 1 - Airbag Headline
add_story_headline_slide(
"Airbag Kills Child in Minor Crash",
"1990s Airbag Crisis - 175+ deaths from safety devices",
)
# Slide 6: What the Data Revealed
add_content_slide(
"What the Data Revealed",
[
"Early airbags designed for one scenario only:",
" Unbelted 50th percentile male in 30 mph crash",
"Inflation speed: ~200 mph",
"Actual occupants hit: Children, small women, close-sitters",
"Neck loads in small dummies: Off the charts",
"Data from out-of-position testing showed fatal forces",
],
"Instrumented testing exposed the deadly design flaw",
)
# Slide 7: Engineering Response
add_content_slide(
"The Engineering Response",
[
"1998: Immediate depowering (20-35% force reduction)",
"Dual-stage inflators: Variable deployment force",
"Occupant classification: Weight sensors in seats",
"Suppression systems: Turn off for rear-facing child seats",
"Multi-stage deployment: Match force to crash severity",
"Result: Deaths dropped from 50+/year to near zero",
],
"Every solution required new testing with instrumented dummies",
)
# Slide 8: DTS Connection - Airbags
add_content_slide(
"The DTS Connection",
[
"OOP testing requires precise measurements in small packages",
"Forces on child dummy necks",
"Acceleration of infant heads",
"Chest deflection of 5th percentile female",
"DTS accelerometers in CRABI infant dummy",
"DTS DAQ captures millisecond-by-millisecond events",
],
"Without this data: No depowering. No dual-stage. More dead children.",
)
# Slide 9: Story 2 - Small Overlap
add_story_headline_slide(
"Luxury Cars Fail New Crash Test",
"2012 Small Overlap Shock - Premium brands exposed",
)
# Slide 10: The Results
add_two_column_slide(
"The 2012 Small Overlap Results",
"FAILED (Marginal/Poor)",
[
"BMW 5-Series: Marginal",
"Mercedes C-Class: Marginal",
"Audi A4: Marginal",
"Lexus ES: Poor",
"Volkswagen Passat: Marginal",
"",
"Only 3 of 13 midsize cars",
"earned 'Good' rating",
],
"WHY THEY FAILED",
[
"Structure bypassed main rails",
"Wheels pushed into footwell",
"Firewalls collapsed",
"Steering columns displaced",
"Feet trapped in crushed metal",
"",
"The dummies told the story:",
"HIC exceeded limits, leg loads critical",
],
)
# Slide 11: Industry Response
add_content_slide(
"The Industry Response",
[
"Fundamental redesign of front structures",
"Small overlap-specific load paths added",
"Extended bumper beams",
"Reinforced A-pillars",
"Modified wheel well geometry",
"By 2015: Most vehicles earning 'Good' ratings",
],
"Every redesign validated with crash testing and instrumented dummies",
)
# Slide 12: Story 3 - Football
add_story_headline_slide(
"The Sport That Was Killing Players",
"1960s-70s: 32 football deaths per year from head injuries",
)
# Slide 13: NOCSAE Solution
add_content_slide(
"The NOCSAE Solution",
[
"1969: National Operating Committee formed",
"Developed the drop test: Helmeted headform from 60 inches",
"Instrumented with accelerometers",
"Metric: Severity Index (SI) < 1200",
"Simple. Repeatable. Science-based.",
"Standard mandated in 1980",
],
"A measurement standard that would actually prevent deaths",
)
# Slide 14: Football Results
add_graph_placeholder_slide(
"Football Fatalities: Before and After",
"Graph: Deaths per year - 32 (1970) dropping to 8 (1980) to 3 (2020)",
"90% reduction in fatalities - from helmets validated with instrumented testing",
)
# Slide 15: Section - Part 2
add_section_slide("PART 2", "Customers You Didn't Know You Had")
# Slide 16: Surprising Applications Overview
add_content_slide(
"DTS Equipment: Beyond Automotive",
[
"Military: WIAMan dummy for IED underbody blast",
"Space: Astronaut protection during landing",
"Theme Parks: Roller coaster acceleration limits",
"Medical Devices: Implant impact testing",
"Sports: Helmet certification across all sports",
"Research: University biomechanics labs worldwide",
],
"Same measurement principles - different life-saving applications",
)
# Slide 17: WIAMan
add_content_slide(
"Military: The WIAMan Dummy",
[
"IEDs send blast forces up through vehicle floors",
"Traditional dummies designed for horizontal impact",
"WIAMan: Warrior Injury Assessment Manikin",
"Specifically designed for underbody blast",
"DTS partnership: Instrumentation for lumbar spine loads",
"Protecting soldiers' backs from being broken",
],
"Not automotive - but the same mission: Use data to save lives",
)
# Slide 18: Common Thread
add_connection_slide(
"The Common Thread",
[
"Dynamic Event",
"Precise Measurement",
"Data Analysis",
"Engineering Decision",
"Lives Saved",
],
)
# Slide 19: Section - Part 3
add_section_slide("PART 3", "Good Data Enables Good Decisions")
# Slide 20: Good vs Bad Data
add_two_column_slide(
"Data Quality: Why It Matters",
"GOOD DATA",
[
"Clean pre-trigger baseline",
"Appropriate CFC filtering",
"Clear signal, no saturation",
"Proper sensor range",
"No zero shift after impact",
"No cable artifacts",
"",
"= Data you can trust",
"= Good engineering decisions",
],
"BAD DATA",
[
"Saturated signal (overranged)",
"Excessive noise/interference",
"Zero shift (baseline moved)",
"Cable yanked = false spike",
"Resonance artifacts",
"Missing channels",
"",
"= Data you cannot trust",
"= Dangerous decisions",
],
)
# Slide 21: Your Decisions Matter
add_content_slide(
"Why This Matters for Your Work",
[
"Sensor range selection: Will customers saturate?",
"Mounting design: Will they get resonance artifacts?",
"Calibration procedures: What's the accuracy baseline?",
"Cable design: Will it survive the test?",
"Software algorithms: Is filtering correct?",
"",
"Your decisions affect every test run with our equipment",
],
"These aren't abstract - they determine if engineers can trust the data",
)
# Slide 22: Ripple Effect
add_connection_slide(
"The Ripple Effect of Your Work",
[
"DTS Product",
"Customer Test",
"Vehicle Design",
"1M Vehicles Built",
"Millions Protected",
],
)
# Slide 23: Section - Closing
add_section_slide("CLOSING", "Remember the Why")
# Slide 24: Real Customers
add_content_slide(
"The Real Customers",
[
"Not the test lab",
"Not the automotive OEM",
"Not the government regulator",
"",
"The real customers are the people who will sit",
"in vehicles designed using our data",
"",
"They don't know our name - but their lives depend on us",
],
"Families. Children. Commuters. Soldiers. Athletes.",
)
# Slide 25: Work Isn't Done
add_content_slide(
"The Work Isn't Done",
[
"Electric vehicles: Battery integrity, high-voltage safety",
"Autonomous vehicles: Active safety validation",
"Pedestrians & cyclists: Rising fatalities need solutions",
"Military: Evolving threats require new testing",
"Sports: Brain injury mechanisms still being discovered",
"",
"Every challenge will require new instrumentation, new data",
],
"New challenges for the next generation of DTS products",
)
# Slide 26: Final Quote
add_quote_slide(
"Every channel of data tells a story. Make sure it's accurate enough to save a life."
)
# Slide 27: Questions
add_title_slide("Questions?", "Ben - Application Engineer | [email]")
# ============================================================================
# Save the presentation
# ============================================================================
output_file = "The_Stories_Our_Data_Tells.pptx"
prs.save(output_file)
print(f"Presentation created: {output_file}")
print(f"Total slides: {len(prs.slides)}")