Practical work — Tensile test data analysis (4h)#
In this lab you will analyze tensile-test data exported as CSV files. The method is always the same:
Get your code working on one file.
Generalize to a batch of files.
Learning goals#
Load and clean experimental data from CSV exports.
Plot true stress–true strain curves.
Compute key mechanical properties:
Ultimate tensile strength Rm
Young’s modulus E
0.2% offset yield strength Re0.2
Build a summary table and rank materials.
Dataset#
The CSV files are located in
_data_trac/.The columns of interest are (French labels in the export):
Déformation réelle(true strain)Contrainte réelle(true stress)
Session plan (suggested)#
Part A : understand the format + load one file.
Part B : batch loading + plot all curves.
Part C : parse metadata.
Part D : compute Rm, E, Re0.2.
Part E : summary table + ranking.
You will fill in the TODO sections in the code cells.
# Setup
from pathlib import Path
import glob
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib widget
Part A — Work on ONE file first#
Q1 — Inspect the header#
Many test machines export metadata before the table. Inspect the first lines to decide:
the separator (often
;)the encoding (Windows “ANSI” is often
cp1252)which rows to skip (
skiprows=[...])
# use the glob methode to list all csv files in the data directory
# example : csv_files = glob.glob('xxx/*.csv')
# Pick a single file for development/debug
# csv_path = csv_files[0]
# csv_path
# Inspect the first lines of the file
# TODO: try: 'cp1252', 'latin1', or 'utf-8'.
# Sugested code :
# ENCODING = "cp1252"
# with open(csv_path, encoding=ENCODING) as f:
# for i in range(12):
# line = f.readline()
# print(f"{i:02d}: {line.rstrip()}")
Q2 — Load and clean the data table#
Implement load_trac_csv(path).
Constraints (adapt if your inspection shows differences)
Use
sep='...'Use
skiprows=[0,1,2,...]Keep only the two columns of interest
rename columns to
STRAIN_COLandSTRESS_COLto avoid encoding issues
Tip: if your column names look like Déformation réelle, your encoding is wrong.
def load_trac_csv(path):
"""Load one tensile CSV and return a clean dataframe with (strain, stress)."""
# TODO: read CSV
data = 0.0
# TODO: keep only the two columns
return data
# test the function on the first file
df = load_trac_csv("path_to a file")
Q3 — Plot the curve (one file)#
Plot Contrainte réelle vs Déformation réelle.
Checklist:
labels, title, grid
curve is continuous (no non-numeric values)
# plot 'strain' vs 'stress'
Part B — Batch processing#
Q4 — Load all files + plot all curves#
Create a dictionary data_by_file:
key: filename stem (without extension)
value: cleaned DataFrame
Then plot all curves in one figure.
Part C — Metadata#
Q5 — Parse metadata from the header#
Read the first 5 lines of the CSV file.
Each line is separated by ; and looks like:
Key;Value;Unit
Implement read_metadata(path) and test it on one file.
def read_metadata(path: Path):
metadata = {}
return metadata
metadata = read_metadata("path_to a file")
metadata
{}
Part D — Mechanical properties#
Q6 — Compute Rm#
Rm is the maximum stress on the curve.
Q7 — Estimate E#
Estimate E as the Young’s modulus.
Q8 — Compute Re0.2 (0.2% offset)#
Re0.2 is the stress at the intersection with the experimental curve.
Hint: find where stress - sigma_offset changes sign, where sigma_offset = 0.002 * E.
Part E — Summary + ranking#
Q9 — Build a summary datafram (one row per file)#
For each file, compute Rm, E, and Re0.2.
Optionally add othe file name.
Q10 — Display material properties#
Make a look like hasby diagrmam with Rm, E, Re0.2.
Optional (if time) — Wrap everything in a class#
Create a class TensileTest that stores:
.metadata.dataAnd exposes:.Rm,.E,.Re02.plot()
class TensileTest:
def __init__(self, path: Path):
self.path = Path(path)
# TODO
# self.metadata = read_metadata(self.path)
# self.data = load_trac_csv(self.path)
@property
def Rm(self):
# TODO
raise NotImplementedError
@property
def E(self):
# TODO
raise NotImplementedError
@property
def Re02(self):
# TODO
raise NotImplementedError
def plot(self):
# TODO
raise NotImplementedError
def __repr__(self):
return f"TensileTest({self.path.name})"
# Example (after implementation)
# test = TensileTest(csv_path)
# test.plot()
# test.Rm, test.E, test.Re02