Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import re | |
from datetime import datetime | |
import pdfplumber | |
import plotly.graph_objects as go | |
import plotly.express as px | |
import io | |
def extract_data_from_pdf(pdf_content): | |
data_list = [] | |
current_record = {} | |
for line in pdf_content.split('\n'): | |
# Extract header information | |
if 'Entreprise::' in line: | |
if current_record and 'temperature_data' in current_record: | |
data_list.append(current_record) | |
current_record = {'temperature_data': []} | |
# Extract metadata | |
if 'Date:' in line: | |
try: | |
date_str = re.search(r'Date:\s*(\d{2}[./]\d{2}[./]\d{4})', line).group(1) | |
date_str = date_str.replace('/', '.') | |
current_record['date'] = datetime.strptime(date_str, '%d.%m.%Y').strftime('%Y-%m-%d') | |
except: | |
current_record['date'] = None | |
if 'Produit:' in line: | |
current_record['produit'] = line.split('Produit:')[-1].strip() | |
if 'Utilisateur:' in line: | |
current_record['utilisateur'] = line.split('Utilisateur:')[-1].strip() | |
# Extract temperature data | |
if any(x in line for x in ['Début', '+ ', 'Fin']) and '°C' in line: | |
try: | |
parts = line.strip().split() | |
time = parts[0] if 'Début' in line or 'Fin' in line else parts[1] | |
temp_sterilisateur = float(parts[-3].replace('°C', '')) | |
temp_coeur = float(parts[-2].replace('°C', '')) | |
valeur_f = float(parts[-1]) | |
current_record['temperature_data'].append({ | |
'temps': time, | |
'temp_sterilisateur': temp_sterilisateur, | |
'temp_coeur': temp_coeur, | |
'valeur_f': valeur_f | |
}) | |
except: | |
continue | |
# Add last record | |
if current_record and 'temperature_data' in current_record: | |
data_list.append(current_record) | |
return data_list | |
def analyze_sterilization(data): | |
results = [] | |
for record in data: | |
temp_data = pd.DataFrame(record['temperature_data']) | |
# Determine product type and required temperature | |
is_nutabreizh = 'NutaBreizh' in record['produit'] | |
required_temp = 108 if is_nutabreizh else 103 | |
# Count minutes at required temperature | |
minutes_at_temp = len(temp_data[temp_data['temp_coeur'] >= required_temp]) | |
# Calculate max temperatures | |
max_temp_sterilisateur = temp_data['temp_sterilisateur'].max() | |
max_temp_coeur = temp_data['temp_coeur'].max() | |
# Determine if criteria met | |
criteria_met = minutes_at_temp >= 30 | |
results.append({ | |
'Date': record['date'], | |
'Produit': record['produit'], | |
'Utilisateur': record['utilisateur'], | |
'Temperature_Requise': required_temp, | |
'Minutes_Temperature_Requise': minutes_at_temp, | |
'Temperature_Max_Sterilisateur': max_temp_sterilisateur, | |
'Temperature_Max_Coeur': max_temp_coeur, | |
'Criteres_Respectes': criteria_met | |
}) | |
return pd.DataFrame(results) | |
def main(): | |
st.title("Analyse des Protocoles de Stérilisation") | |
uploaded_file = st.file_uploader("Choisir un fichier PDF", type="pdf") | |
if uploaded_file is not None: | |
# Read PDF content | |
pdf_text = "" | |
with pdfplumber.open(uploaded_file) as pdf: | |
for page in pdf.pages: | |
pdf_text += page.extract_text() + "\n" | |
# Process data | |
data = extract_data_from_pdf(pdf_text) | |
results_df = analyze_sterilization(data) | |
# Display results | |
st.subheader("Résultats de l'analyse") | |
st.dataframe(results_df) | |
# Create visualization | |
fig = px.scatter(results_df, | |
x='Date', | |
y='Minutes_Temperature_Requise', | |
color='Criteres_Respectes', | |
hover_data=['Produit', 'Temperature_Requise'], | |
title="Minutes à température requise par production") | |
st.plotly_chart(fig) | |
# Export button | |
if st.button("Exporter en Excel"): | |
output = io.BytesIO() | |
with pd.ExcelWriter(output, engine='xlsxwriter') as writer: | |
results_df.to_excel(writer, index=False) | |
output.seek(0) | |
st.download_button( | |
label="Télécharger l'analyse", | |
data=output, | |
file_name="analyse_sterilisation.xlsx", | |
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | |
) | |
if __name__ == "__main__": | |
main() |