Skip to content

Commit e8aeb0d

Browse files
change options for slider (#79)
* change options for slider * fix slider choice and comma error * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 513f887 commit e8aeb0d

File tree

2 files changed

+64
-29
lines changed

2 files changed

+64
-29
lines changed

reproschema/redcap2reproschema.py

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -200,40 +200,43 @@ def process_choices(choices_str, field_name):
200200

201201
choices = []
202202
choices_value_type = []
203-
for ii, choice in enumerate(choices_str.split("|")):
204-
choice = (
205-
choice.strip()
206-
) # Strip leading/trailing whitespace for each choice
207-
parts = [p.strip() for p in choice.split(",")]
208-
209-
# Handle the case where the choice is something like "1,"
210-
if len(parts) == 1:
203+
for choice in choices_str.split("|"):
204+
choice = choice.strip()
205+
206+
# Split only on the first comma to separate value from label
207+
first_comma_split = choice.split(",", 1)
208+
value_part = first_comma_split[0].strip()
209+
210+
# Get the full label part (keeping all commas and equals signs)
211+
if len(first_comma_split) > 1:
212+
label_part = first_comma_split[1].strip()
213+
else:
214+
# Handle cases where there's no comma
211215
if choice.endswith(","):
212-
parts = [parts[0][:-1], ""]
216+
label_part = ""
213217
else:
214218
print(
215-
f"Warning: Invalid choice format '{choice}' in a {field_name} field, adding integer as a value"
219+
f"Warning: Invalid choice format '{choice}' in {field_name} field"
216220
)
217-
parts = [ii, parts[0]]
221+
label_part = choice
218222

219-
# Determine if value should be treated as an integer or string
220-
if parts[0] == "0":
221-
# Special case for "0", treat it as an integer
223+
# Determine value type
224+
if value_part == "0":
222225
value = 0
223226
choices_value_type.append("xsd:integer")
224-
elif parts[0].isdigit() and parts[0][0] == "0":
225-
# If it has leading zeros, treat it as a string
226-
value = parts[0]
227+
elif value_part.isdigit() and value_part[0] == "0":
228+
value = value_part
227229
choices_value_type.append("xsd:string")
228230
else:
229231
try:
230-
value = int(parts[0])
232+
value = int(value_part)
231233
choices_value_type.append("xsd:integer")
232234
except ValueError:
233-
value = parts[0]
235+
value = value_part
234236
choices_value_type.append("xsd:string")
237+
235238
choice_obj = {
236-
"name": {"en": " ".join(parts[1:]).strip()},
239+
"name": {"en": label_part},
237240
"value": value,
238241
}
239242
choices.append(choice_obj)
@@ -308,15 +311,30 @@ def process_row(
308311
and value
309312
and input_type in ["radio", "select", "slider"]
310313
):
311-
choices, choices_val_type_l = process_choices(
312-
value, field_name=field["Variable / Field Name"]
313-
)
314-
rowData["responseOptions"].update(
315-
{
316-
"choices": choices,
317-
"valueType": choices_val_type_l,
318-
}, # updating value type for choices (can be int or str)
319-
)
314+
if input_type == "slider":
315+
# For sliders, add both choices and min/max values
316+
choices, choices_val_type_l = process_choices(
317+
value, field_name=field["Variable / Field Name"]
318+
)
319+
rowData["responseOptions"].update(
320+
{
321+
"choices": choices,
322+
"valueType": choices_val_type_l,
323+
"minValue": 0, # hardcoded for redcap/now
324+
"maxValue": 100, # hardcoded for redcap/now
325+
}
326+
)
327+
else:
328+
# For radio and select, just process choices normally
329+
choices, choices_val_type_l = process_choices(
330+
value, field_name=field["Variable / Field Name"]
331+
)
332+
rowData["responseOptions"].update(
333+
{
334+
"choices": choices,
335+
"valueType": choices_val_type_l,
336+
}
337+
)
320338
# for now adding only for numerics, sometimes can be string or date.. TODO
321339
elif (
322340
SCHEMA_MAP.get(key) in RESPONSE_COND

reproschema/tests/test_process_choices.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,23 @@ def test_process_choices_spaces_in_values():
116116
assert sorted(value_types) == ["xsd:string"]
117117

118118

119+
def test_process_choices_likert_scale():
120+
# Test Likert scale choices with number prefixes in descriptions
121+
choices_str = "0, 0=None (Not at all) | 1, 1=Slight (Rare, less than a day or two) | 2, 2=Mild (Several days) | 3, 3=Moderate (More than half the days) | 4, 4=Severe (Nearly every day)"
122+
choices, value_types = process_choices(choices_str, "likert_scale")
123+
assert choices == [
124+
{"name": {"en": "0=None (Not at all)"}, "value": 0},
125+
{
126+
"name": {"en": "1=Slight (Rare, less than a day or two)"},
127+
"value": 1,
128+
},
129+
{"name": {"en": "2=Mild (Several days)"}, "value": 2},
130+
{"name": {"en": "3=Moderate (More than half the days)"}, "value": 3},
131+
{"name": {"en": "4=Severe (Nearly every day)"}, "value": 4},
132+
]
133+
assert value_types == ["xsd:integer"]
134+
135+
119136
# Run pytest if script is called directly
120137
if __name__ == "__main__":
121138
pytest.main()

0 commit comments

Comments
 (0)