basilefuchs commited on
Commit
0eb1c65
·
1 Parent(s): 7062112
src/page/acte.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import unidecode
3
+ import polars as pl
4
+ import streamlit as st
5
+
6
+
7
+ GRIST_URL = "https://grist.numerique.gouv.fr/o/dim-chu-brest/api/docs/5ZXqTKBiHTD2qqUj6GVPtp" # ou ton serveur
8
+ TABLE = "Actes_classants"
9
+
10
+ records = requests.get(f"{GRIST_URL}/tables/{TABLE}/records").json()["records"]
11
+
12
+ acte = pl.DataFrame(records).drop("id").unnest("fields")
13
+
14
+ names = {
15
+ "CODE_ACTE": "Code acte",
16
+ "LIBELLE_ACTE": "Libellé acte",
17
+ "PARAGRAPHE": "Sous-Paragraphe",
18
+ "TECHNIQUE": "Technique",
19
+ }
20
+
21
+ items = (
22
+ acte.filter(pl.col("LIBELLE_CARACTERISTIQUE").is_not_null())["LIBELLE_CARACTERISTIQUE"]
23
+ .unique()
24
+ .str.to_titlecase()
25
+ .sort()
26
+ .to_list()
27
+ )
28
+
29
+ st.title("Actes CCAM")
30
+
31
+ # widgets
32
+ col1, col2, col3 = st.columns(3)
33
+
34
+ exp = col1.text_input("Mot(s) clef(s):", "")
35
+ exp = unidecode.unidecode(exp)
36
+
37
+ selection = col3.multiselect("Filtre(s) :", options=items, default=[])
38
+
39
+ _temp = (
40
+ acte.filter(
41
+ (pl.col("CODE_ACTE").str.contains(r"(?i)" + exp))
42
+ | (pl.col("LIBELLE_ACTE").str.contains(r"(?i)" + exp))
43
+ | (pl.col("LIBELLE_CARACTERISTIQUE").str.contains(r"(?i)" + exp))
44
+ | (pl.col("PARAGRAPHE").str.contains(r"(?i)" + exp))
45
+ )
46
+ .select("CODE_ACTE")
47
+ .unique()
48
+ )
49
+
50
+ df = (
51
+ acte.join(_temp, on="CODE_ACTE", how="inner")
52
+ .with_columns(
53
+ pl.lit(1).alias("flag"),
54
+ )
55
+ .pivot(
56
+ "LIBELLE_CARACTERISTIQUE",
57
+ index=["CODE_ACTE", "LIBELLE_ACTE", "PARAGRAPHE", "TECHNIQUE"],
58
+ values="flag",
59
+ sort_columns=True,
60
+ )
61
+ .sort("CODE_ACTE")
62
+ )
63
+
64
+ if selection:
65
+ _temp = acte.filter((pl.col("LIBELLE_CARACTERISTIQUE").is_in(selection))).select("CODE_ACTE").unique()
66
+ df = df.join(_temp, on="CODE_ACTE", how="inner").rename(names)
67
+
68
+ st.dataframe(df.to_pandas(), hide_index=True, use_container_width=True)
src/page/ctxt.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import unidecode
3
+ import polars as pl
4
+ import streamlit as st
5
+
6
+
7
+ GRIST_URL = "https://grist.numerique.gouv.fr/o/dim-chu-brest/api/docs/5ZXqTKBiHTD2qqUj6GVPtp" # ou ton serveur
8
+ TABLE = "Ctxt"
9
+
10
+ records = requests.get(f"{GRIST_URL}/tables/{TABLE}/records").json()["records"]
11
+
12
+ ctxt = pl.DataFrame(records).drop("id").unnest("fields").sort(pl.col("Code_CIM_10"))
13
+
14
+ st.title("Contexte patient")
15
+
16
+ st.dataframe(ctxt.to_pandas(), hide_index=True, use_container_width=True)
17
+
18
+ st.divider()
src/page/germes.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import unidecode
3
+ import polars as pl
4
+ import streamlit as st
5
+
6
+
7
+ GRIST_URL = "https://grist.numerique.gouv.fr/o/dim-chu-brest/api/docs/5ZXqTKBiHTD2qqUj6GVPtp" # ou ton serveur
8
+ TABLE = "Germes"
9
+
10
+ records = requests.get(f"{GRIST_URL}/tables/{TABLE}/records").json()["records"]
11
+
12
+ data = pl.DataFrame(records).drop("id").unnest("fields").select("Germe", "Code_du_germe", "Code_si_sepsis").sort("Germe")
13
+
14
+ st.title("Germes CIM-10")
15
+
16
+ st.divider()
17
+
18
+ # widgets
19
+ col1, col2, col3 = st.columns(3)
20
+
21
+ exp = col1.text_input("Mot(s) clef(s):", "")
22
+ exp = unidecode.unidecode(exp)
23
+
24
+ # filter data with options
25
+ df = data.filter(
26
+ (
27
+ (pl.col("Germe").str.contains(r"(?i)" + exp))
28
+ | (pl.col("Code_du_germe").str.contains(r"(?i)" + exp))
29
+ | (pl.col("Code_si_sepsis").str.contains(r"(?i)" + exp))
30
+ )
31
+ )
32
+
33
+ st.dataframe(
34
+ df.to_pandas(), hide_index=True, use_container_width=True
35
+ )
36
+
37
+ st.divider()
src/page/hello.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+ st.header("Bienvenue sur notre application d'aide au codage PMSI+")
5
+
6
+ st.divider()
7
+
8
+ st.write(
9
+ """Nous sommes ravis de vous accueillir dans cet outil conçu pour **faciliter votre travail** au sein de notre hôpital. Le Programme de Médicalisation des Systèmes d'Information (PMSI) est essentiel pour garantir une gestion optimale des données de santé, et nous savons que le codage peut parfois représenter un défi.
10
+
11
+ Notre application a été développée pour vous accompagner tout au long de ce processus.
12
+
13
+ Que vous soyez un professionnel de la santé expérimenté ou que vous débutiez dans ce domaine, nous sommes là pour vous soutenir.
14
+ Grâce à des _**ressources adaptées**_, des _**guides pratiques**_ et des _**outils de recherche avancés**_, vous pourrez **coder plus efficacement et avec confiance**.
15
+
16
+ N'hésitez pas à explorer toutes les fonctionnalités disponibles et à nous faire part de vos retours. Ensemble, nous pouvons **améliorer la qualité des données** et optimiser la prise en charge des patients.
17
+
18
+ **Merci de faire partie de cette aventure !**
19
+
20
+ _L’équipe de développement_"""
21
+ )
22
+
23
+ st.divider()
24
+
25
+ st.write("_Auteurs :_")
26
+ st.write("_**Département d'information médicale**_, CHU de Brest")
27
+ st.write("_**Centre de Données Cliniques**_, CHU de Brest")
src/page/intox.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import unidecode
3
+ import polars as pl
4
+ import streamlit as st
5
+
6
+
7
+ GRIST_URL = "https://grist.numerique.gouv.fr/o/dim-chu-brest/api/docs/5ZXqTKBiHTD2qqUj6GVPtp" # ou ton serveur
8
+ TABLE1 = "Intox_data"
9
+ TABLE2 = "Intox_data2"
10
+
11
+ records1 = requests.get(f"{GRIST_URL}/tables/{TABLE1}/records").json()["records"]
12
+ records2 = requests.get(f"{GRIST_URL}/tables/{TABLE2}/records").json()["records"]
13
+
14
+ cim10 = pl.DataFrame(records1).drop("id").unnest("fields").sort("SUBSTANCE")
15
+ data = pl.DataFrame(records2).drop("id").unnest("fields").sort("Nom")
16
+
17
+ data = data.with_columns(
18
+ pl.col("Nom")
19
+ .map_elements(lambda x: unidecode.unidecode(x), return_dtype=pl.Utf8)
20
+ .name.keep(),
21
+ pl.col("DCI")
22
+ .map_elements(lambda x: unidecode.unidecode(x), return_dtype=pl.Utf8)
23
+ .name.keep(),
24
+ pl.col("SUBSTANCE")
25
+ .map_elements(lambda x: unidecode.unidecode(x), return_dtype=pl.Utf8)
26
+ .name.keep(),
27
+ )
28
+
29
+ st.title("Intox CIM-10")
30
+
31
+ st.divider()
32
+
33
+ st.header("Médicaments - Codes CIM-10")
34
+
35
+ # widgets
36
+ col1, col2, col3 = st.columns(3)
37
+
38
+ exp = col1.text_input("Mot(s) clef(s):", "")
39
+ exp = unidecode.unidecode(exp)
40
+ fm = col3.toggle("Afficher les correspondances exactes", value=True)
41
+
42
+ # filter data with options
43
+ df = data.filter(
44
+ (
45
+ (pl.col("Nom").str.contains("(?i)" + exp))
46
+ | (pl.col("DCI").str.contains("(?i)" + exp))
47
+ | (pl.col("SUBSTANCE").str.contains("(?i)" + exp))
48
+ )
49
+ & ((pl.col("full_match") == fm) | (pl.col("full_match") == True))
50
+ )
51
+
52
+ st.dataframe(
53
+ df.drop("full_match").to_pandas(), hide_index=True, use_container_width=True
54
+ )
55
+ st.divider()
56
+
57
+ st.header("Table des effets nocifs")
58
+
59
+ # widgets
60
+ col4, col5, col6 = st.columns(3)
61
+
62
+ exp2 = col4.text_input("Mot(s) clef(s): ", "")
63
+ exp2 = unidecode.unidecode(exp2)
64
+
65
+ # filter data with options
66
+ df2 = cim10.filter(pl.col("SUBSTANCE").str.contains("(?i)" + exp2))
67
+
68
+ st.dataframe(df2.to_pandas(), hide_index=True, use_container_width=True)
69
+ st.divider()
src/streamlit_app.py CHANGED
@@ -1,40 +1,20 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
5
 
6
- """
7
- # Welcome to Streamlit!
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
 
 
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
 
 
 
 
 
 
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
 
 
 
3
 
4
+ hello_page = st.Page("page/hello.py", title="Bienvenue !", icon="👋")
5
+ intox_page = st.Page("page/intox.py", title="Intox CIM-10", icon="☠️")
6
+ ctxt_page = st.Page("page/ctxt.py", title="Contexte patient", icon="😷")
7
+ acte_page = st.Page("page/acte.py", title="Actes CCAM", icon="🩺")
8
+ germes_page = st.Page("page/germes.py", title="Germes CIM-10", icon="🦠")
9
 
10
+ pg = st.navigation(
11
+ {
12
+ "PMSI+": [hello_page],
13
+ "CIM-10": [intox_page, germes_page],
14
+ "CCAM": [],
15
+ "HDJ": [acte_page, ctxt_page],
16
+ }
17
+ )
18
 
19
+ st.set_page_config(page_title="PMSI+", page_icon="📚", layout="wide")
20
+ pg.run()