11
11
from .parameters import Parameters
12
12
13
13
DATE_FORMAT = "%b, %d" # see https://strftime.org
14
-
14
+ DOCS_URL = "https://code-for-philly.gitbook.io/chime"
15
15
16
16
hide_menu_style = """
17
17
<style>
@@ -49,7 +49,7 @@ def display_header(st, m, p):
49
49
)
50
50
st .markdown (
51
51
"""*This tool was developed by the [Predictive Healthcare team](http://predictivehealthcare.pennmedicine.org/) at
52
- Penn Medicine. For questions on how to use this tool see the [User docs](https://code-for-philly.gitbook.io/chime/ ). Code can be found on [Github](https://github.com/CodeForPhilly/chime).
52
+ Penn Medicine. 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).
53
53
Join our [Slack channel](https://codeforphilly.org/chat?channel=covid19-chime-penn) if you would like to get involved!*"""
54
54
)
55
55
@@ -78,13 +78,38 @@ def display_header(st, m, p):
78
78
relative_contact_rate = p .relative_contact_rate ,
79
79
r_t = m .r_t ,
80
80
doubling_time_t = abs (m .doubling_time_t ),
81
- impact_statement = ("halves the infections every" if m .r_t < 1 else "reduces the doubling time to" )
81
+ impact_statement = ("halves the infections every" if m .r_t < 1 else "reduces the doubling time to" ),
82
+ docs_url = DOCS_URL
82
83
)
83
84
)
84
85
85
86
return None
86
87
87
88
89
+ class InputWrapper :
90
+ """Helper to separate Streamlit input definition from creation/rendering"""
91
+ def __init__ (self , st_obj , label , value , kwargs ):
92
+ self .st_obj = st_obj
93
+ self .label = label
94
+ self .value = value
95
+ self .kwargs = kwargs
96
+
97
+ def build (self ):
98
+ return self .st_obj (self .label , value = self .value , ** self .kwargs )
99
+
100
+
101
+ class NumberInputWrapper (InputWrapper ):
102
+ def __init__ (self , st_obj , label , min_value = None , max_value = None , value = None , step = None , format = None , key = None ):
103
+ kwargs = dict (min_value = min_value , max_value = max_value , step = step , format = format , key = key )
104
+ super ().__init__ (st_obj .number_input , label , value , kwargs )
105
+
106
+
107
+ class CheckboxWrapper (InputWrapper ):
108
+ def __init__ (self , st_obj , label , value = None , key = None ):
109
+ kwargs = dict (key = key )
110
+ super ().__init__ (st_obj .checkbox , label , value , kwargs )
111
+
112
+
88
113
def display_sidebar (st , d : Constants ) -> Parameters :
89
114
# Initialize variables
90
115
# these functions create input elements and bind the values they are set to
@@ -93,149 +118,163 @@ def display_sidebar(st, d: Constants) -> Parameters:
93
118
94
119
if d .known_infected < 1 :
95
120
raise ValueError ("Known cases must be larger than one to enable predictions." )
96
-
97
- n_days = st .sidebar .number_input (
98
- "Number of days to project" ,
99
- min_value = 30 ,
100
- value = d .n_days ,
101
- step = 10 ,
102
- format = "%i" ,
103
- )
104
-
105
- current_hospitalized = st .sidebar .number_input (
121
+ st_obj = st .sidebar
122
+ current_hospitalized = NumberInputWrapper (
123
+ st_obj ,
106
124
"Currently Hospitalized COVID-19 Patients" ,
107
125
min_value = 0 ,
108
126
value = d .current_hospitalized ,
109
127
step = 1 ,
110
128
format = "%i" ,
111
129
)
112
-
113
- doubling_time = st .sidebar .number_input (
130
+ n_days = NumberInputWrapper (
131
+ st_obj ,
132
+ "Number of days to project" ,
133
+ min_value = 30 ,
134
+ value = d .n_days ,
135
+ step = 10 ,
136
+ format = "%i" ,
137
+ )
138
+ doubling_time = NumberInputWrapper (
139
+ st_obj ,
114
140
"Doubling time before social distancing (days)" ,
115
141
min_value = 0 ,
116
142
value = d .doubling_time ,
117
143
step = 1 ,
118
144
format = "%i" ,
119
145
)
120
-
121
- relative_contact_rate = (
122
- st .sidebar .number_input (
123
- "Social distancing (% reduction in social contact)" ,
124
- min_value = 0 ,
125
- max_value = 100 ,
126
- value = int (d .relative_contact_rate * 100 ),
127
- step = 5 ,
128
- format = "%i" ,
129
- )
130
- / 100.0
146
+ relative_contact_rate = NumberInputWrapper (
147
+ st_obj ,
148
+ "Social distancing (% reduction in social contact)" ,
149
+ min_value = 0 ,
150
+ max_value = 100 ,
151
+ value = int (d .relative_contact_rate * 100 ),
152
+ step = 5 ,
153
+ format = "%i" ,
131
154
)
132
-
133
- hospitalized_rate = (
134
- st .sidebar .number_input (
135
- "Hospitalization %(total infections)" ,
136
- min_value = 0.001 ,
137
- max_value = 100.0 ,
138
- value = d .hospitalized .rate * 100 ,
139
- step = 1.0 ,
140
- format = "%f" ,
141
- )
142
- / 100.0
155
+ hospitalized_rate = NumberInputWrapper (
156
+ st_obj ,
157
+ "Hospitalization %(total infections)" ,
158
+ min_value = 0.001 ,
159
+ max_value = 100.0 ,
160
+ value = d .hospitalized .rate * 100 ,
161
+ step = 1.0 ,
162
+ format = "%f" ,
143
163
)
144
- icu_rate = (
145
- st .sidebar .number_input (
146
- "ICU %(total infections)" ,
147
- min_value = 0.0 ,
148
- max_value = 100.0 ,
149
- value = d .icu .rate * 100 ,
150
- step = 1.0 ,
151
- format = "%f" ,
152
- )
153
- / 100.0
164
+ icu_rate = NumberInputWrapper (
165
+ st_obj ,
166
+ "ICU %(total infections)" ,
167
+ min_value = 0.0 ,
168
+ max_value = 100.0 ,
169
+ value = d .icu .rate * 100 ,
170
+ step = 1.0 ,
171
+ format = "%f" ,
154
172
)
155
- ventilated_rate = (
156
- st .sidebar .number_input (
157
- "Ventilated %(total infections)" ,
158
- min_value = 0.0 ,
159
- max_value = 100.0 ,
160
- value = d .ventilated .rate * 100 ,
161
- step = 1.0 ,
162
- format = "%f" ,
163
- )
164
- / 100.0
173
+ ventilated_rate = NumberInputWrapper (
174
+ st_obj ,
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" ,
165
181
)
166
-
167
- hospitalized_los = st . sidebar . number_input (
182
+ hospitalized_los = NumberInputWrapper (
183
+ st_obj ,
168
184
"Hospital Length of Stay" ,
169
185
min_value = 0 ,
170
186
value = d .hospitalized .length_of_stay ,
171
187
step = 1 ,
172
188
format = "%i" ,
173
189
)
174
- icu_los = st .sidebar .number_input (
190
+ icu_los = NumberInputWrapper (
191
+ st_obj ,
175
192
"ICU Length of Stay" ,
176
193
min_value = 0 ,
177
194
value = d .icu .length_of_stay ,
178
195
step = 1 ,
179
196
format = "%i" ,
180
197
)
181
- ventilated_los = st .sidebar .number_input (
198
+ ventilated_los = NumberInputWrapper (
199
+ st_obj ,
182
200
"Vent Length of Stay" ,
183
201
min_value = 0 ,
184
202
value = d .ventilated .length_of_stay ,
185
203
step = 1 ,
186
204
format = "%i" ,
187
205
)
188
-
189
- market_share = (
190
- st .sidebar .number_input (
191
- "Hospital Market Share (%)" ,
192
- min_value = 0.001 ,
193
- max_value = 100.0 ,
194
- value = d .market_share * 100 ,
195
- step = 1.0 ,
196
- format = "%f" ,
197
- )
198
- / 100.0
206
+ market_share = NumberInputWrapper (
207
+ st_obj ,
208
+ "Hospital Market Share (%)" ,
209
+ min_value = 0.001 ,
210
+ max_value = 100.0 ,
211
+ value = d .market_share * 100 ,
212
+ step = 1.0 ,
213
+ format = "%f" ,
199
214
)
200
- susceptible = st .sidebar .number_input (
215
+ susceptible = NumberInputWrapper (
216
+ st_obj ,
201
217
"Regional Population" ,
202
218
min_value = 1 ,
203
219
value = d .region .susceptible ,
204
220
step = 100000 ,
205
221
format = "%i" ,
206
222
)
207
-
208
- known_infected = st . sidebar . number_input (
223
+ known_infected = NumberInputWrapper (
224
+ st_obj ,
209
225
"Currently Known Regional Infections (only used to compute detection rate - does not change projections)" ,
210
226
min_value = 0 ,
211
227
value = d .known_infected ,
212
228
step = 10 ,
213
229
format = "%i" ,
214
230
)
231
+ as_date = CheckboxWrapper (st_obj , "Present result as dates instead of days" , value = False )
232
+ max_y_axis_set = CheckboxWrapper (st_obj , "Set the Y-axis on graphs to a static value" )
215
233
216
- as_date = st .sidebar .checkbox (label = "Present result as dates instead of days" , value = False )
217
-
218
- max_y_axis_set = st .sidebar .checkbox ("Set the Y-axis on graphs to a static value" )
219
234
max_y_axis = None
220
235
if max_y_axis_set :
221
- max_y_axis = st .sidebar .number_input (
222
- "Y-axis static value" , value = 500 , format = "%i" , step = 25 ,
223
- )
236
+ max_y_axis = NumberInputWrapper (st_obj , "Y-axis static value" , value = 500 , format = "%i" , step = 25 )
237
+
238
+ # Build in desired order
239
+ st .sidebar .markdown ("### Regional Parameters [ℹ]({docs_url}/what-is-chime/parameters)" .format (docs_url = DOCS_URL ))
240
+ susceptible .build ()
241
+ market_share .build ()
242
+ known_infected .build ()
243
+ current_hospitalized .build ()
244
+
245
+ st .sidebar .markdown ("### Spread and Contact Parameters [ℹ]({docs_url}/what-is-chime/parameters)"
246
+ .format (docs_url = DOCS_URL ))
247
+ doubling_time .build ()
248
+ relative_contact_rate .build ()
249
+
250
+ st .sidebar .markdown ("### Severity Parameters [ℹ]({docs_url}/what-is-chime/parameters)" .format (docs_url = DOCS_URL ))
251
+ hospitalized_rate .build ()
252
+ icu_rate .build ()
253
+ ventilated_rate .build ()
254
+ hospitalized_los .build ()
255
+ icu_los .build ()
256
+ ventilated_los .build ()
257
+
258
+ st .sidebar .markdown ("### Display Parameters [ℹ]({docs_url}/what-is-chime/parameters)" .format (docs_url = DOCS_URL ))
259
+ n_days .build ()
260
+ max_y_axis .build ()
261
+ as_date .build ()
224
262
225
263
return Parameters (
226
- as_date = as_date ,
227
- current_hospitalized = current_hospitalized ,
228
- doubling_time = doubling_time ,
229
- known_infected = known_infected ,
230
- market_share = market_share ,
231
- max_y_axis = max_y_axis ,
232
- n_days = n_days ,
233
- relative_contact_rate = relative_contact_rate ,
234
- susceptible = susceptible ,
235
-
236
- hospitalized = RateLos (hospitalized_rate , hospitalized_los ),
237
- icu = RateLos (icu_rate , icu_los ),
238
- ventilated = RateLos (ventilated_rate , ventilated_los ),
264
+ as_date = as_date .value ,
265
+ current_hospitalized = current_hospitalized .value ,
266
+ market_share = market_share .value ,
267
+ known_infected = known_infected .value ,
268
+ doubling_time = doubling_time .value ,
269
+
270
+ max_y_axis = max_y_axis .value ,
271
+ n_days = n_days .value ,
272
+ relative_contact_rate = relative_contact_rate .value / 100.0 ,
273
+ susceptible = susceptible .value ,
274
+
275
+ hospitalized = RateLos (hospitalized_rate .value / 100.0 , hospitalized_los .value ),
276
+ icu = RateLos (icu_rate .value / 100.0 , icu_los .value ),
277
+ ventilated = RateLos (ventilated_rate .value / 100.0 , ventilated_los .value ),
239
278
)
240
279
241
280
@@ -344,7 +383,7 @@ def write_definitions(st):
344
383
st .subheader ("Guidance on Selecting Inputs" )
345
384
st .markdown (
346
385
"""**This information has been moved to the
347
- [User Documentation](https://code-for-philly.gitbook.io/chime/ what-is-chime/parameters#guidance-on-selecting-inputs)**"""
386
+ [User Documentation]({docs_url}/ what-is-chime/parameters#guidance-on-selecting-inputs)**""" . format ( docs_url = DOCS_URL )
348
387
)
349
388
350
389
0 commit comments