Skip to content

Commit c56b7ce

Browse files
Merge branch 'develop' into pip_installation_scripts
2 parents f8b6ef8 + f0d0461 commit c56b7ce

File tree

2 files changed

+146
-102
lines changed

2 files changed

+146
-102
lines changed

e2e/cypress/integration/tests/actions.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
context('Actions', () => {
44
beforeEach(() => {
55
cy.visit('http://localhost:8000')
6-
})
6+
});
77

88
it('All + elements are clickable', () => {
9-
cy.get('.step-up').click( { multiple: true } )
9+
cy.get('.step-up').click( { multiple: true } );
1010

1111
// This gets the "first" input from the sidebar. From clicking step up,
12-
// the number of days to project should increase from default 60 to 70.
12+
// the Regional Population should increase from default 4119405 to 4219405.
1313
cy.get('input.st-al')
14-
.should('has.value', '70')
14+
.should('has.value', '4219405')
1515
})
16-
})
16+
});

src/penn_chime/presentation.py

Lines changed: 141 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .parameters import Parameters
1212

1313
DATE_FORMAT = "%b, %d" # see https://strftime.org
14-
14+
DOCS_URL = "https://code-for-philly.gitbook.io/chime"
1515

1616
hide_menu_style = """
1717
<style>
@@ -63,7 +63,12 @@ def display_header(st, m, p):
6363
"""**IMPORTANT NOTICE**: Admissions and Census calculations were previously **undercounting**. Please update your reports generated before """ + p.change_date() + """. See more about changes [here](https://github.com/CodeForPhilly/chime/labels/models)."""
6464
)
6565
st.markdown(
66-
"""*This tool was developed by the [Predictive Healthcare team](http://predictivehealthcare.pennmedicine.org/) at [Penn Medicine](https://www.pennmedicine.org) to assist hospitals and public health officials with hospital capacity planning, but can be used anywhere in the world. Customize it for your region by modifying data inputs in the left pane, or read the [User Documentation](https://code-for-philly.gitbook.io/chime/) to learn more.*"""
66+
"""*This tool was developed by the [Predictive Healthcare team](http://predictivehealthcare.pennmedicine.org/) at
67+
Penn Medicine to assist hospitals and public health officials with hospital capacity planning,
68+
but can be used anywhere in the world.
69+
Customize it for your region by modifying data inputs in the left panel.
70+
For questions on how to use this tool see the [User docs]({docs_url}). Code can be found on [Github](https://github.com/CodeForPhilly/chime)*.
71+
""".format(docs_url=DOCS_URL)
6772
)
6873

6974
st.markdown(
@@ -95,6 +100,7 @@ def display_header(st, m, p):
95100
r_t=m.r_t,
96101
doubling_time_t=abs(m.doubling_time_t),
97102
impact_statement=("halves the infections every" if m.r_t < 1 else "reduces the doubling time to"),
103+
docs_url=DOCS_URL,
98104
infection_warning_str=infection_warning_str,
99105
infected_population_warning_str=infected_population_warning_str
100106
)
@@ -103,6 +109,30 @@ def display_header(st, m, p):
103109
return None
104110

105111

112+
class InputWrapper:
113+
"""Helper to separate Streamlit input definition from creation/rendering"""
114+
def __init__(self, st_obj, label, value, kwargs):
115+
self.st_obj = st_obj
116+
self.label = label
117+
self.value = value
118+
self.kwargs = kwargs
119+
120+
def build(self):
121+
return self.st_obj(self.label, value=self.value, **self.kwargs)
122+
123+
124+
class NumberInputWrapper(InputWrapper):
125+
def __init__(self, st_obj, label, min_value=None, max_value=None, value=None, step=None, format=None, key=None):
126+
kwargs = dict(min_value=min_value, max_value=max_value, step=step, format=format, key=key)
127+
super().__init__(st_obj.number_input, label, value, kwargs)
128+
129+
130+
class CheckboxWrapper(InputWrapper):
131+
def __init__(self, st_obj, label, value=None, key=None):
132+
kwargs = dict(key=key)
133+
super().__init__(st_obj.checkbox, label, value, kwargs)
134+
135+
106136
def display_sidebar(st, d: Constants) -> Parameters:
107137
# Initialize variables
108138
# these functions create input elements and bind the values they are set to
@@ -111,149 +141,163 @@ def display_sidebar(st, d: Constants) -> Parameters:
111141

112142
if d.known_infected < 1:
113143
raise ValueError("Known cases must be larger than one to enable predictions.")
114-
115-
n_days = st.sidebar.number_input(
116-
"Number of days to project",
117-
min_value=30,
118-
value=d.n_days,
119-
step=10,
120-
format="%i",
121-
)
122-
123-
current_hospitalized = st.sidebar.number_input(
144+
st_obj = st.sidebar
145+
current_hospitalized = NumberInputWrapper(
146+
st_obj,
124147
"Currently Hospitalized COVID-19 Patients",
125148
min_value=0,
126149
value=d.current_hospitalized,
127150
step=1,
128151
format="%i",
129152
)
130-
131-
doubling_time = st.sidebar.number_input(
153+
n_days = NumberInputWrapper(
154+
st_obj,
155+
"Number of days to project",
156+
min_value=30,
157+
value=d.n_days,
158+
step=10,
159+
format="%i",
160+
)
161+
doubling_time = NumberInputWrapper(
162+
st_obj,
132163
"Doubling time before social distancing (days)",
133164
min_value=0,
134165
value=d.doubling_time,
135166
step=1,
136167
format="%i",
137168
)
138-
139-
relative_contact_rate = (
140-
st.sidebar.number_input(
141-
"Social distancing (% reduction in social contact)",
142-
min_value=0,
143-
max_value=100,
144-
value=int(d.relative_contact_rate * 100),
145-
step=5,
146-
format="%i",
147-
)
148-
/ 100.0
149-
)
150-
151-
hospitalized_rate = (
152-
st.sidebar.number_input(
153-
"Hospitalization %(total infections)",
154-
min_value=0.001,
155-
max_value=100.0,
156-
value=d.hospitalized.rate * 100,
157-
step=1.0,
158-
format="%f",
159-
)
160-
/ 100.0
161-
)
162-
icu_rate = (
163-
st.sidebar.number_input(
164-
"ICU %(total infections)",
165-
min_value=0.0,
166-
max_value=100.0,
167-
value=d.icu.rate * 100,
168-
step=1.0,
169-
format="%f",
170-
)
171-
/ 100.0
172-
)
173-
ventilated_rate = (
174-
st.sidebar.number_input(
175-
"Ventilated %(total infections)",
176-
min_value=0.0,
177-
max_value=100.0,
178-
value=d.ventilated.rate * 100,
179-
step=1.0,
180-
format="%f",
181-
)
182-
/ 100.0
169+
relative_contact_rate = NumberInputWrapper(
170+
st_obj,
171+
"Social distancing (% reduction in social contact)",
172+
min_value=0,
173+
max_value=100,
174+
value=int(d.relative_contact_rate * 100),
175+
step=5,
176+
format="%i",
183177
)
184-
185-
hospitalized_los = st.sidebar.number_input(
178+
hospitalized_rate = NumberInputWrapper(
179+
st_obj,
180+
"Hospitalization %(total infections)",
181+
min_value=0.001,
182+
max_value=100.0,
183+
value=d.hospitalized.rate * 100,
184+
step=1.0,
185+
format="%f",
186+
)
187+
icu_rate = NumberInputWrapper(
188+
st_obj,
189+
"ICU %(total infections)",
190+
min_value=0.0,
191+
max_value=100.0,
192+
value=d.icu.rate * 100,
193+
step=1.0,
194+
format="%f",
195+
)
196+
ventilated_rate = NumberInputWrapper(
197+
st_obj,
198+
"Ventilated %(total infections)",
199+
min_value=0.0,
200+
max_value=100.0,
201+
value=d.ventilated.rate * 100,
202+
step=1.0,
203+
format="%f",
204+
)
205+
hospitalized_los = NumberInputWrapper(
206+
st_obj,
186207
"Hospital Length of Stay",
187208
min_value=0,
188209
value=d.hospitalized.length_of_stay,
189210
step=1,
190211
format="%i",
191212
)
192-
icu_los = st.sidebar.number_input(
213+
icu_los = NumberInputWrapper(
214+
st_obj,
193215
"ICU Length of Stay",
194216
min_value=0,
195217
value=d.icu.length_of_stay,
196218
step=1,
197219
format="%i",
198220
)
199-
ventilated_los = st.sidebar.number_input(
221+
ventilated_los = NumberInputWrapper(
222+
st_obj,
200223
"Vent Length of Stay",
201224
min_value=0,
202225
value=d.ventilated.length_of_stay,
203226
step=1,
204227
format="%i",
205228
)
206-
207-
market_share = (
208-
st.sidebar.number_input(
209-
"Hospital Market Share (%)",
210-
min_value=0.001,
211-
max_value=100.0,
212-
value=d.market_share * 100,
213-
step=1.0,
214-
format="%f",
215-
)
216-
/ 100.0
217-
)
218-
susceptible = st.sidebar.number_input(
229+
market_share = NumberInputWrapper(
230+
st_obj,
231+
"Hospital Market Share (%)",
232+
min_value=0.001,
233+
max_value=100.0,
234+
value=d.market_share * 100,
235+
step=1.0,
236+
format="%f",
237+
)
238+
susceptible = NumberInputWrapper(
239+
st_obj,
219240
"Regional Population",
220241
min_value=1,
221242
value=d.region.susceptible,
222243
step=100000,
223244
format="%i",
224245
)
225-
226-
known_infected = st.sidebar.number_input(
246+
known_infected = NumberInputWrapper(
247+
st_obj,
227248
"Currently Known Regional Infections (only used to compute detection rate - does not change projections)",
228249
min_value=0,
229250
value=d.known_infected,
230251
step=10,
231252
format="%i",
232253
)
254+
as_date = CheckboxWrapper(st_obj, "Present result as dates instead of days", value=False)
255+
max_y_axis_set = CheckboxWrapper(st_obj, "Set the Y-axis on graphs to a static value")
233256

234-
as_date = st.sidebar.checkbox(label="Present result as dates instead of days", value=False)
235-
236-
max_y_axis_set = st.sidebar.checkbox("Set the Y-axis on graphs to a static value")
237257
max_y_axis = None
238258
if max_y_axis_set:
239-
max_y_axis = st.sidebar.number_input(
240-
"Y-axis static value", value=500, format="%i", step=25,
241-
)
259+
max_y_axis = NumberInputWrapper(st_obj, "Y-axis static value", value=500, format="%i", step=25)
260+
261+
# Build in desired order
262+
st.sidebar.markdown("### Regional Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
263+
susceptible.build()
264+
market_share.build()
265+
known_infected.build()
266+
current_hospitalized.build()
267+
268+
st.sidebar.markdown("### Spread and Contact Parameters [ℹ]({docs_url}/what-is-chime/parameters)"
269+
.format(docs_url=DOCS_URL))
270+
doubling_time.build()
271+
relative_contact_rate.build()
272+
273+
st.sidebar.markdown("### Severity Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
274+
hospitalized_rate.build()
275+
icu_rate.build()
276+
ventilated_rate.build()
277+
hospitalized_los.build()
278+
icu_los.build()
279+
ventilated_los.build()
280+
281+
st.sidebar.markdown("### Display Parameters [ℹ]({docs_url}/what-is-chime/parameters)".format(docs_url=DOCS_URL))
282+
n_days.build()
283+
max_y_axis.build()
284+
as_date.build()
242285

243286
return Parameters(
244-
as_date=as_date,
245-
current_hospitalized=current_hospitalized,
246-
doubling_time=doubling_time,
247-
known_infected=known_infected,
248-
market_share=market_share,
249-
max_y_axis=max_y_axis,
250-
n_days=n_days,
251-
relative_contact_rate=relative_contact_rate,
252-
susceptible=susceptible,
287+
as_date=as_date.value,
288+
current_hospitalized=current_hospitalized.value,
289+
market_share=market_share.value,
290+
known_infected=known_infected.value,
291+
doubling_time=doubling_time.value,
292+
293+
max_y_axis=max_y_axis.value,
294+
n_days=n_days.value,
295+
relative_contact_rate=relative_contact_rate.value / 100.0,
296+
susceptible=susceptible.value,
253297

254-
hospitalized=RateLos(hospitalized_rate, hospitalized_los),
255-
icu=RateLos(icu_rate, icu_los),
256-
ventilated=RateLos(ventilated_rate, ventilated_los),
298+
hospitalized=RateLos(hospitalized_rate.value / 100.0, hospitalized_los.value),
299+
icu=RateLos(icu_rate.value / 100.0, icu_los.value),
300+
ventilated=RateLos(ventilated_rate.value / 100.0, ventilated_los.value),
257301
)
258302

259303

@@ -362,7 +406,7 @@ def write_definitions(st):
362406
st.subheader("Guidance on Selecting Inputs")
363407
st.markdown(
364408
"""**This information has been moved to the
365-
[User Documentation](https://code-for-philly.gitbook.io/chime/what-is-chime/parameters#guidance-on-selecting-inputs)**"""
409+
[User Documentation]({docs_url}/what-is-chime/parameters#guidance-on-selecting-inputs)**""".format(docs_url=DOCS_URL)
366410
)
367411

368412

0 commit comments

Comments
 (0)