edsl 0.1.37.dev4__py3-none-any.whl → 0.1.37.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edsl/Base.py +303 -303
- edsl/BaseDiff.py +260 -260
- edsl/TemplateLoader.py +24 -24
- edsl/__init__.py +48 -48
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +855 -804
- edsl/agents/AgentList.py +350 -345
- edsl/agents/Invigilator.py +222 -222
- edsl/agents/InvigilatorBase.py +284 -305
- edsl/agents/PromptConstructor.py +353 -312
- edsl/agents/__init__.py +3 -3
- edsl/agents/descriptors.py +99 -86
- edsl/agents/prompt_helpers.py +129 -129
- edsl/auto/AutoStudy.py +117 -117
- edsl/auto/StageBase.py +230 -230
- edsl/auto/StageGenerateSurvey.py +178 -178
- edsl/auto/StageLabelQuestions.py +125 -125
- edsl/auto/StagePersona.py +61 -61
- edsl/auto/StagePersonaDimensionValueRanges.py +88 -88
- edsl/auto/StagePersonaDimensionValues.py +74 -74
- edsl/auto/StagePersonaDimensions.py +69 -69
- edsl/auto/StageQuestions.py +73 -73
- edsl/auto/SurveyCreatorPipeline.py +21 -21
- edsl/auto/utilities.py +224 -224
- edsl/base/Base.py +289 -289
- edsl/config.py +149 -149
- edsl/conjure/AgentConstructionMixin.py +160 -152
- edsl/conjure/Conjure.py +62 -62
- edsl/conjure/InputData.py +659 -659
- edsl/conjure/InputDataCSV.py +48 -48
- edsl/conjure/InputDataMixinQuestionStats.py +182 -182
- edsl/conjure/InputDataPyRead.py +91 -91
- edsl/conjure/InputDataSPSS.py +8 -8
- edsl/conjure/InputDataStata.py +8 -8
- edsl/conjure/QuestionOptionMixin.py +76 -76
- edsl/conjure/QuestionTypeMixin.py +23 -23
- edsl/conjure/RawQuestion.py +65 -65
- edsl/conjure/SurveyResponses.py +7 -7
- edsl/conjure/__init__.py +9 -9
- edsl/conjure/naming_utilities.py +263 -263
- edsl/conjure/utilities.py +201 -201
- edsl/conversation/Conversation.py +290 -238
- edsl/conversation/car_buying.py +58 -58
- edsl/conversation/chips.py +95 -0
- edsl/conversation/mug_negotiation.py +81 -81
- edsl/conversation/next_speaker_utilities.py +93 -93
- edsl/coop/PriceFetcher.py +54 -54
- edsl/coop/__init__.py +2 -2
- edsl/coop/coop.py +958 -827
- edsl/coop/utils.py +131 -131
- edsl/data/Cache.py +527 -527
- edsl/data/CacheEntry.py +228 -228
- edsl/data/CacheHandler.py +149 -149
- edsl/data/RemoteCacheSync.py +97 -97
- edsl/data/SQLiteDict.py +292 -292
- edsl/data/__init__.py +4 -4
- edsl/data/orm.py +10 -10
- edsl/data_transfer_models.py +73 -73
- edsl/enums.py +173 -173
- edsl/exceptions/BaseException.py +21 -0
- edsl/exceptions/__init__.py +54 -50
- edsl/exceptions/agents.py +38 -40
- edsl/exceptions/configuration.py +16 -16
- edsl/exceptions/coop.py +10 -10
- edsl/exceptions/data.py +14 -14
- edsl/exceptions/general.py +34 -34
- edsl/exceptions/jobs.py +33 -33
- edsl/exceptions/language_models.py +63 -63
- edsl/exceptions/prompts.py +15 -15
- edsl/exceptions/questions.py +91 -91
- edsl/exceptions/results.py +29 -26
- edsl/exceptions/scenarios.py +22 -0
- edsl/exceptions/surveys.py +37 -34
- edsl/inference_services/AnthropicService.py +87 -87
- edsl/inference_services/AwsBedrock.py +120 -120
- edsl/inference_services/AzureAI.py +217 -217
- edsl/inference_services/DeepInfraService.py +18 -18
- edsl/inference_services/GoogleService.py +156 -156
- edsl/inference_services/GroqService.py +20 -20
- edsl/inference_services/InferenceServiceABC.py +147 -147
- edsl/inference_services/InferenceServicesCollection.py +97 -74
- edsl/inference_services/MistralAIService.py +123 -123
- edsl/inference_services/OllamaService.py +18 -18
- edsl/inference_services/OpenAIService.py +224 -224
- edsl/inference_services/TestService.py +89 -89
- edsl/inference_services/TogetherAIService.py +170 -170
- edsl/inference_services/models_available_cache.py +118 -118
- edsl/inference_services/rate_limits_cache.py +25 -25
- edsl/inference_services/registry.py +39 -39
- edsl/inference_services/write_available.py +10 -10
- edsl/jobs/Answers.py +56 -56
- edsl/jobs/Jobs.py +1347 -1135
- edsl/jobs/__init__.py +1 -1
- edsl/jobs/buckets/BucketCollection.py +63 -63
- edsl/jobs/buckets/ModelBuckets.py +65 -65
- edsl/jobs/buckets/TokenBucket.py +248 -248
- edsl/jobs/interviews/Interview.py +661 -661
- edsl/jobs/interviews/InterviewExceptionCollection.py +99 -99
- edsl/jobs/interviews/InterviewExceptionEntry.py +186 -182
- edsl/jobs/interviews/InterviewStatistic.py +63 -63
- edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -25
- edsl/jobs/interviews/InterviewStatusDictionary.py +78 -78
- edsl/jobs/interviews/InterviewStatusLog.py +92 -92
- edsl/jobs/interviews/ReportErrors.py +66 -66
- edsl/jobs/interviews/interview_status_enum.py +9 -9
- edsl/jobs/runners/JobsRunnerAsyncio.py +338 -338
- edsl/jobs/runners/JobsRunnerStatus.py +332 -332
- edsl/jobs/tasks/QuestionTaskCreator.py +242 -242
- edsl/jobs/tasks/TaskCreators.py +64 -64
- edsl/jobs/tasks/TaskHistory.py +442 -441
- edsl/jobs/tasks/TaskStatusLog.py +23 -23
- edsl/jobs/tasks/task_status_enum.py +163 -163
- edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
- edsl/jobs/tokens/TokenUsage.py +34 -34
- edsl/language_models/KeyLookup.py +30 -0
- edsl/language_models/LanguageModel.py +706 -718
- edsl/language_models/ModelList.py +102 -102
- edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
- edsl/language_models/__init__.py +3 -2
- edsl/language_models/fake_openai_call.py +15 -15
- edsl/language_models/fake_openai_service.py +61 -61
- edsl/language_models/registry.py +137 -137
- edsl/language_models/repair.py +156 -156
- edsl/language_models/unused/ReplicateBase.py +83 -83
- edsl/language_models/utilities.py +64 -64
- edsl/notebooks/Notebook.py +259 -259
- edsl/notebooks/__init__.py +1 -1
- edsl/prompts/Prompt.py +357 -353
- edsl/prompts/__init__.py +2 -2
- edsl/questions/AnswerValidatorMixin.py +289 -289
- edsl/questions/QuestionBase.py +656 -616
- edsl/questions/QuestionBaseGenMixin.py +161 -161
- edsl/questions/QuestionBasePromptsMixin.py +234 -266
- edsl/questions/QuestionBudget.py +227 -227
- edsl/questions/QuestionCheckBox.py +359 -359
- edsl/questions/QuestionExtract.py +183 -183
- edsl/questions/QuestionFreeText.py +114 -114
- edsl/questions/QuestionFunctional.py +159 -159
- edsl/questions/QuestionList.py +231 -231
- edsl/questions/QuestionMultipleChoice.py +286 -286
- edsl/questions/QuestionNumerical.py +153 -153
- edsl/questions/QuestionRank.py +324 -324
- edsl/questions/Quick.py +41 -41
- edsl/questions/RegisterQuestionsMeta.py +71 -71
- edsl/questions/ResponseValidatorABC.py +174 -174
- edsl/questions/SimpleAskMixin.py +73 -73
- edsl/questions/__init__.py +26 -26
- edsl/questions/compose_questions.py +98 -98
- edsl/questions/decorators.py +21 -21
- edsl/questions/derived/QuestionLikertFive.py +76 -76
- edsl/questions/derived/QuestionLinearScale.py +87 -87
- edsl/questions/derived/QuestionTopK.py +91 -91
- edsl/questions/derived/QuestionYesNo.py +82 -82
- edsl/questions/descriptors.py +413 -418
- edsl/questions/prompt_templates/question_budget.jinja +13 -13
- edsl/questions/prompt_templates/question_checkbox.jinja +32 -32
- edsl/questions/prompt_templates/question_extract.jinja +11 -11
- edsl/questions/prompt_templates/question_free_text.jinja +3 -3
- edsl/questions/prompt_templates/question_linear_scale.jinja +11 -11
- edsl/questions/prompt_templates/question_list.jinja +17 -17
- edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -33
- edsl/questions/prompt_templates/question_numerical.jinja +36 -36
- edsl/questions/question_registry.py +147 -147
- edsl/questions/settings.py +12 -12
- edsl/questions/templates/budget/answering_instructions.jinja +7 -7
- edsl/questions/templates/budget/question_presentation.jinja +7 -7
- edsl/questions/templates/checkbox/answering_instructions.jinja +10 -10
- edsl/questions/templates/checkbox/question_presentation.jinja +22 -22
- edsl/questions/templates/extract/answering_instructions.jinja +7 -7
- edsl/questions/templates/likert_five/answering_instructions.jinja +10 -10
- edsl/questions/templates/likert_five/question_presentation.jinja +11 -11
- edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -5
- edsl/questions/templates/linear_scale/question_presentation.jinja +5 -5
- edsl/questions/templates/list/answering_instructions.jinja +3 -3
- edsl/questions/templates/list/question_presentation.jinja +5 -5
- edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -9
- edsl/questions/templates/multiple_choice/question_presentation.jinja +11 -11
- edsl/questions/templates/numerical/answering_instructions.jinja +6 -6
- edsl/questions/templates/numerical/question_presentation.jinja +6 -6
- edsl/questions/templates/rank/answering_instructions.jinja +11 -11
- edsl/questions/templates/rank/question_presentation.jinja +15 -15
- edsl/questions/templates/top_k/answering_instructions.jinja +8 -8
- edsl/questions/templates/top_k/question_presentation.jinja +22 -22
- edsl/questions/templates/yes_no/answering_instructions.jinja +6 -6
- edsl/questions/templates/yes_no/question_presentation.jinja +11 -11
- edsl/results/Dataset.py +293 -293
- edsl/results/DatasetExportMixin.py +717 -693
- edsl/results/DatasetTree.py +145 -145
- edsl/results/Result.py +450 -435
- edsl/results/Results.py +1071 -1160
- edsl/results/ResultsDBMixin.py +238 -238
- edsl/results/ResultsExportMixin.py +43 -43
- edsl/results/ResultsFetchMixin.py +33 -33
- edsl/results/ResultsGGMixin.py +121 -121
- edsl/results/ResultsToolsMixin.py +98 -98
- edsl/results/Selector.py +135 -118
- edsl/results/__init__.py +2 -2
- edsl/results/tree_explore.py +115 -115
- edsl/scenarios/FileStore.py +458 -458
- edsl/scenarios/Scenario.py +546 -510
- edsl/scenarios/ScenarioHtmlMixin.py +64 -59
- edsl/scenarios/ScenarioList.py +1112 -1101
- edsl/scenarios/ScenarioListExportMixin.py +52 -52
- edsl/scenarios/ScenarioListPdfMixin.py +261 -261
- edsl/scenarios/__init__.py +4 -4
- edsl/shared.py +1 -1
- edsl/study/ObjectEntry.py +173 -173
- edsl/study/ProofOfWork.py +113 -113
- edsl/study/SnapShot.py +80 -80
- edsl/study/Study.py +528 -528
- edsl/study/__init__.py +4 -4
- edsl/surveys/DAG.py +148 -148
- edsl/surveys/Memory.py +31 -31
- edsl/surveys/MemoryPlan.py +244 -244
- edsl/surveys/Rule.py +330 -324
- edsl/surveys/RuleCollection.py +387 -387
- edsl/surveys/Survey.py +1795 -1772
- edsl/surveys/SurveyCSS.py +261 -261
- edsl/surveys/SurveyExportMixin.py +259 -259
- edsl/surveys/SurveyFlowVisualizationMixin.py +121 -121
- edsl/surveys/SurveyQualtricsImport.py +284 -284
- edsl/surveys/__init__.py +3 -3
- edsl/surveys/base.py +53 -53
- edsl/surveys/descriptors.py +56 -56
- edsl/surveys/instructions/ChangeInstruction.py +47 -47
- edsl/surveys/instructions/Instruction.py +51 -51
- edsl/surveys/instructions/InstructionCollection.py +77 -77
- edsl/templates/error_reporting/base.html +23 -23
- edsl/templates/error_reporting/exceptions_by_model.html +34 -34
- edsl/templates/error_reporting/exceptions_by_question_name.html +16 -16
- edsl/templates/error_reporting/exceptions_by_type.html +16 -16
- edsl/templates/error_reporting/interview_details.html +115 -115
- edsl/templates/error_reporting/interviews.html +9 -9
- edsl/templates/error_reporting/overview.html +4 -4
- edsl/templates/error_reporting/performance_plot.html +1 -1
- edsl/templates/error_reporting/report.css +73 -73
- edsl/templates/error_reporting/report.html +117 -117
- edsl/templates/error_reporting/report.js +25 -25
- edsl/tools/__init__.py +1 -1
- edsl/tools/clusters.py +192 -192
- edsl/tools/embeddings.py +27 -27
- edsl/tools/embeddings_plotting.py +118 -118
- edsl/tools/plotting.py +112 -112
- edsl/tools/summarize.py +18 -18
- edsl/utilities/SystemInfo.py +28 -28
- edsl/utilities/__init__.py +22 -22
- edsl/utilities/ast_utilities.py +25 -25
- edsl/utilities/data/Registry.py +6 -6
- edsl/utilities/data/__init__.py +1 -1
- edsl/utilities/data/scooter_results.json +1 -1
- edsl/utilities/decorators.py +77 -77
- edsl/utilities/gcp_bucket/cloud_storage.py +96 -96
- edsl/utilities/interface.py +627 -627
- edsl/utilities/repair_functions.py +28 -28
- edsl/utilities/restricted_python.py +70 -70
- edsl/utilities/utilities.py +409 -391
- {edsl-0.1.37.dev4.dist-info → edsl-0.1.37.dev5.dist-info}/LICENSE +21 -21
- {edsl-0.1.37.dev4.dist-info → edsl-0.1.37.dev5.dist-info}/METADATA +1 -1
- edsl-0.1.37.dev5.dist-info/RECORD +283 -0
- edsl-0.1.37.dev4.dist-info/RECORD +0 -279
- {edsl-0.1.37.dev4.dist-info → edsl-0.1.37.dev5.dist-info}/WHEEL +0 -0
edsl/conjure/InputDataStata.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
from edsl.conjure.InputDataPyRead import InputDataPyRead
|
2
|
-
|
3
|
-
|
4
|
-
class InputDataStata(InputDataPyRead):
|
5
|
-
def pyread_function(self, datafile_name):
|
6
|
-
from pyreadstat import read_dta
|
7
|
-
|
8
|
-
return read_dta(datafile_name)
|
1
|
+
from edsl.conjure.InputDataPyRead import InputDataPyRead
|
2
|
+
|
3
|
+
|
4
|
+
class InputDataStata(InputDataPyRead):
|
5
|
+
def pyread_function(self, datafile_name):
|
6
|
+
from pyreadstat import read_dta
|
7
|
+
|
8
|
+
return read_dta(datafile_name)
|
@@ -1,76 +1,76 @@
|
|
1
|
-
from typing import Union, List
|
2
|
-
|
3
|
-
|
4
|
-
class QuestionOptionMixin:
|
5
|
-
@property
|
6
|
-
def question_options(self):
|
7
|
-
if not hasattr(self, "_question_options"):
|
8
|
-
self.question_options = None
|
9
|
-
return self._question_options
|
10
|
-
|
11
|
-
@question_options.setter
|
12
|
-
def question_options(self, value):
|
13
|
-
if value is None:
|
14
|
-
value = [self._get_question_options(qn) for qn in self.question_names]
|
15
|
-
self._question_options = value
|
16
|
-
|
17
|
-
def _get_question_options(self, question_name) -> Union[List[str], None]:
|
18
|
-
"""Return the options for a question.
|
19
|
-
|
20
|
-
>>> from edsl.conjure.InputData import InputDataABC
|
21
|
-
>>> id = InputDataABC.example()
|
22
|
-
>>> sorted(id._get_question_options('morning'))
|
23
|
-
['1', '4']
|
24
|
-
|
25
|
-
"""
|
26
|
-
qt = self.question_statistics(question_name)
|
27
|
-
idx = self.question_names.index(question_name)
|
28
|
-
question_type = self.question_types[idx]
|
29
|
-
if question_type == "multiple_choice":
|
30
|
-
return [str(o) for o in qt.unique_responses]
|
31
|
-
else:
|
32
|
-
if question_type == "multiple_choice_with_other":
|
33
|
-
options = self.unique_responses_more_than_k(2)[
|
34
|
-
self.question_names.index(question_name)
|
35
|
-
] + [self.OTHER_STRING]
|
36
|
-
return [str(o) for o in options]
|
37
|
-
else:
|
38
|
-
return None
|
39
|
-
|
40
|
-
def order_options(self) -> None:
|
41
|
-
"""Order the options for multiple choice questions using an LLM."""
|
42
|
-
from edsl import QuestionList, ScenarioList
|
43
|
-
import textwrap
|
44
|
-
|
45
|
-
scenarios = (
|
46
|
-
ScenarioList.from_list("example_question_name", self.question_names)
|
47
|
-
.add_list("example_question_text", self.question_texts)
|
48
|
-
.add_list("example_question_type", self.question_types)
|
49
|
-
.add_list("example_question_options", self.question_options)
|
50
|
-
).filter(
|
51
|
-
'example_question_type == "multiple_choice" or example_question_type == "multiple_choice_with_other"'
|
52
|
-
)
|
53
|
-
|
54
|
-
question = QuestionList(
|
55
|
-
question_text=textwrap.dedent(
|
56
|
-
"""\
|
57
|
-
We have a survey question: `{{ example_question_text }}`.
|
58
|
-
|
59
|
-
The survey had following options: '{{ example_question_options }}'.
|
60
|
-
The options might be out of order. Please put them in the correct order.
|
61
|
-
If there is not natural order, just put then in order they were presented.
|
62
|
-
"""
|
63
|
-
),
|
64
|
-
question_name="ordering",
|
65
|
-
)
|
66
|
-
proposed_ordering = question.by(scenarios).run()
|
67
|
-
d = dict(
|
68
|
-
proposed_ordering.select("example_question_name", "ordering").to_list()
|
69
|
-
)
|
70
|
-
self._question_options = [d.get(qn, None) for qn in self.question_names]
|
71
|
-
|
72
|
-
|
73
|
-
if __name__ == "__main__":
|
74
|
-
import doctest
|
75
|
-
|
76
|
-
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
1
|
+
from typing import Union, List
|
2
|
+
|
3
|
+
|
4
|
+
class QuestionOptionMixin:
|
5
|
+
@property
|
6
|
+
def question_options(self):
|
7
|
+
if not hasattr(self, "_question_options"):
|
8
|
+
self.question_options = None
|
9
|
+
return self._question_options
|
10
|
+
|
11
|
+
@question_options.setter
|
12
|
+
def question_options(self, value):
|
13
|
+
if value is None:
|
14
|
+
value = [self._get_question_options(qn) for qn in self.question_names]
|
15
|
+
self._question_options = value
|
16
|
+
|
17
|
+
def _get_question_options(self, question_name) -> Union[List[str], None]:
|
18
|
+
"""Return the options for a question.
|
19
|
+
|
20
|
+
>>> from edsl.conjure.InputData import InputDataABC
|
21
|
+
>>> id = InputDataABC.example()
|
22
|
+
>>> sorted(id._get_question_options('morning'))
|
23
|
+
['1', '4']
|
24
|
+
|
25
|
+
"""
|
26
|
+
qt = self.question_statistics(question_name)
|
27
|
+
idx = self.question_names.index(question_name)
|
28
|
+
question_type = self.question_types[idx]
|
29
|
+
if question_type == "multiple_choice":
|
30
|
+
return [str(o) for o in qt.unique_responses]
|
31
|
+
else:
|
32
|
+
if question_type == "multiple_choice_with_other":
|
33
|
+
options = self.unique_responses_more_than_k(2)[
|
34
|
+
self.question_names.index(question_name)
|
35
|
+
] + [self.OTHER_STRING]
|
36
|
+
return [str(o) for o in options]
|
37
|
+
else:
|
38
|
+
return None
|
39
|
+
|
40
|
+
def order_options(self) -> None:
|
41
|
+
"""Order the options for multiple choice questions using an LLM."""
|
42
|
+
from edsl import QuestionList, ScenarioList
|
43
|
+
import textwrap
|
44
|
+
|
45
|
+
scenarios = (
|
46
|
+
ScenarioList.from_list("example_question_name", self.question_names)
|
47
|
+
.add_list("example_question_text", self.question_texts)
|
48
|
+
.add_list("example_question_type", self.question_types)
|
49
|
+
.add_list("example_question_options", self.question_options)
|
50
|
+
).filter(
|
51
|
+
'example_question_type == "multiple_choice" or example_question_type == "multiple_choice_with_other"'
|
52
|
+
)
|
53
|
+
|
54
|
+
question = QuestionList(
|
55
|
+
question_text=textwrap.dedent(
|
56
|
+
"""\
|
57
|
+
We have a survey question: `{{ example_question_text }}`.
|
58
|
+
|
59
|
+
The survey had following options: '{{ example_question_options }}'.
|
60
|
+
The options might be out of order. Please put them in the correct order.
|
61
|
+
If there is not natural order, just put then in order they were presented.
|
62
|
+
"""
|
63
|
+
),
|
64
|
+
question_name="ordering",
|
65
|
+
)
|
66
|
+
proposed_ordering = question.by(scenarios).run()
|
67
|
+
d = dict(
|
68
|
+
proposed_ordering.select("example_question_name", "ordering").to_list()
|
69
|
+
)
|
70
|
+
self._question_options = [d.get(qn, None) for qn in self.question_names]
|
71
|
+
|
72
|
+
|
73
|
+
if __name__ == "__main__":
|
74
|
+
import doctest
|
75
|
+
|
76
|
+
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
@@ -1,23 +1,23 @@
|
|
1
|
-
class QuestionTypeMixin:
|
2
|
-
@property
|
3
|
-
def question_types(self):
|
4
|
-
if not hasattr(self, "_question_types"):
|
5
|
-
self.question_types = None
|
6
|
-
return self._question_types
|
7
|
-
|
8
|
-
@question_types.setter
|
9
|
-
def question_types(self, value):
|
10
|
-
if value is None:
|
11
|
-
value = [self._infer_question_type(qn) for qn in self.question_names]
|
12
|
-
self._question_types = value
|
13
|
-
|
14
|
-
def _infer_question_type(self, question_name) -> str:
|
15
|
-
qt = self.question_statistics(question_name)
|
16
|
-
if qt.num_unique_responses > self.NUM_UNIQUE_THRESHOLD:
|
17
|
-
if qt.frac_numerical > self.FRAC_NUMERICAL_THRESHOLD:
|
18
|
-
return "numerical"
|
19
|
-
if qt.frac_obs_from_top_5 > self.MULTIPLE_CHOICE_OTHER_THRESHOLD:
|
20
|
-
return "multiple_choice_with_other"
|
21
|
-
return "free_text"
|
22
|
-
else:
|
23
|
-
return "multiple_choice"
|
1
|
+
class QuestionTypeMixin:
|
2
|
+
@property
|
3
|
+
def question_types(self):
|
4
|
+
if not hasattr(self, "_question_types"):
|
5
|
+
self.question_types = None
|
6
|
+
return self._question_types
|
7
|
+
|
8
|
+
@question_types.setter
|
9
|
+
def question_types(self, value):
|
10
|
+
if value is None:
|
11
|
+
value = [self._infer_question_type(qn) for qn in self.question_names]
|
12
|
+
self._question_types = value
|
13
|
+
|
14
|
+
def _infer_question_type(self, question_name) -> str:
|
15
|
+
qt = self.question_statistics(question_name)
|
16
|
+
if qt.num_unique_responses > self.NUM_UNIQUE_THRESHOLD:
|
17
|
+
if qt.frac_numerical > self.FRAC_NUMERICAL_THRESHOLD:
|
18
|
+
return "numerical"
|
19
|
+
if qt.frac_obs_from_top_5 > self.MULTIPLE_CHOICE_OTHER_THRESHOLD:
|
20
|
+
return "multiple_choice_with_other"
|
21
|
+
return "free_text"
|
22
|
+
else:
|
23
|
+
return "multiple_choice"
|
edsl/conjure/RawQuestion.py
CHANGED
@@ -1,65 +1,65 @@
|
|
1
|
-
from dataclasses import dataclass, field
|
2
|
-
from typing import List, Optional, Union
|
3
|
-
from edsl.questions import QuestionBase
|
4
|
-
from edsl import Question
|
5
|
-
|
6
|
-
from edsl.conjure.utilities import convert_value
|
7
|
-
|
8
|
-
|
9
|
-
@dataclass
|
10
|
-
class RawQuestion:
|
11
|
-
"""
|
12
|
-
A class to represent a question before it is converted to edsl class.
|
13
|
-
|
14
|
-
>>> rq = RawQuestion.example()
|
15
|
-
>>> rq.to_question()
|
16
|
-
Question('multiple_choice', question_name = \"""how_are_you\""", question_text = \"""How are you doing?\""", question_options = ['Good', 'Bad'])
|
17
|
-
"""
|
18
|
-
|
19
|
-
question_type: str
|
20
|
-
question_name: str
|
21
|
-
question_text: str
|
22
|
-
responses: List[str] = field(default_factory=list)
|
23
|
-
question_options: Optional[List[str]] = None
|
24
|
-
|
25
|
-
@classmethod
|
26
|
-
def example(cls):
|
27
|
-
return cls(
|
28
|
-
question_type="multiple_choice",
|
29
|
-
question_name="how_are_you",
|
30
|
-
question_text="How are you doing?",
|
31
|
-
responses=["Good", "Bad", "Bad", "Good"],
|
32
|
-
question_options=["Good", "Bad"],
|
33
|
-
)
|
34
|
-
|
35
|
-
def __post_init__(self):
|
36
|
-
self.responses = [convert_value(r) for r in self.responses]
|
37
|
-
|
38
|
-
def to_question(self) -> QuestionBase:
|
39
|
-
"""Return a Question object from the RawQuestion."""
|
40
|
-
|
41
|
-
# TODO: Remove this once we have a better way to handle multiple_choice_with_other
|
42
|
-
if self.question_type == "multiple_choice_with_other":
|
43
|
-
question_type = "multiple_choice"
|
44
|
-
else:
|
45
|
-
question_type = self.question_type
|
46
|
-
|
47
|
-
# exclude responses from the dictionary if they have a None value; don't inlcude responses in the dictionary
|
48
|
-
d = {
|
49
|
-
k: v
|
50
|
-
for k, v in {
|
51
|
-
"question_type": question_type,
|
52
|
-
"question_name": self.question_name,
|
53
|
-
"question_text": self.question_text,
|
54
|
-
"responses": self.responses,
|
55
|
-
"question_options": self.question_options,
|
56
|
-
}.items()
|
57
|
-
if v is not None and k != "responses"
|
58
|
-
}
|
59
|
-
return Question(**d)
|
60
|
-
|
61
|
-
|
62
|
-
if __name__ == "__main__":
|
63
|
-
import doctest
|
64
|
-
|
65
|
-
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import List, Optional, Union
|
3
|
+
from edsl.questions import QuestionBase
|
4
|
+
from edsl import Question
|
5
|
+
|
6
|
+
from edsl.conjure.utilities import convert_value
|
7
|
+
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class RawQuestion:
|
11
|
+
"""
|
12
|
+
A class to represent a question before it is converted to edsl class.
|
13
|
+
|
14
|
+
>>> rq = RawQuestion.example()
|
15
|
+
>>> rq.to_question()
|
16
|
+
Question('multiple_choice', question_name = \"""how_are_you\""", question_text = \"""How are you doing?\""", question_options = ['Good', 'Bad'])
|
17
|
+
"""
|
18
|
+
|
19
|
+
question_type: str
|
20
|
+
question_name: str
|
21
|
+
question_text: str
|
22
|
+
responses: List[str] = field(default_factory=list)
|
23
|
+
question_options: Optional[List[str]] = None
|
24
|
+
|
25
|
+
@classmethod
|
26
|
+
def example(cls):
|
27
|
+
return cls(
|
28
|
+
question_type="multiple_choice",
|
29
|
+
question_name="how_are_you",
|
30
|
+
question_text="How are you doing?",
|
31
|
+
responses=["Good", "Bad", "Bad", "Good"],
|
32
|
+
question_options=["Good", "Bad"],
|
33
|
+
)
|
34
|
+
|
35
|
+
def __post_init__(self):
|
36
|
+
self.responses = [convert_value(r) for r in self.responses]
|
37
|
+
|
38
|
+
def to_question(self) -> QuestionBase:
|
39
|
+
"""Return a Question object from the RawQuestion."""
|
40
|
+
|
41
|
+
# TODO: Remove this once we have a better way to handle multiple_choice_with_other
|
42
|
+
if self.question_type == "multiple_choice_with_other":
|
43
|
+
question_type = "multiple_choice"
|
44
|
+
else:
|
45
|
+
question_type = self.question_type
|
46
|
+
|
47
|
+
# exclude responses from the dictionary if they have a None value; don't inlcude responses in the dictionary
|
48
|
+
d = {
|
49
|
+
k: v
|
50
|
+
for k, v in {
|
51
|
+
"question_type": question_type,
|
52
|
+
"question_name": self.question_name,
|
53
|
+
"question_text": self.question_text,
|
54
|
+
"responses": self.responses,
|
55
|
+
"question_options": self.question_options,
|
56
|
+
}.items()
|
57
|
+
if v is not None and k != "responses"
|
58
|
+
}
|
59
|
+
return Question(**d)
|
60
|
+
|
61
|
+
|
62
|
+
if __name__ == "__main__":
|
63
|
+
import doctest
|
64
|
+
|
65
|
+
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
edsl/conjure/SurveyResponses.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
from typing import Dict, List
|
2
|
-
from collections import UserDict
|
3
|
-
|
4
|
-
|
5
|
-
class SurveyResponses(UserDict):
|
6
|
-
def __init__(self, responses: Dict[str, List[str]]):
|
7
|
-
super().__init__(responses)
|
1
|
+
from typing import Dict, List
|
2
|
+
from collections import UserDict
|
3
|
+
|
4
|
+
|
5
|
+
class SurveyResponses(UserDict):
|
6
|
+
def __init__(self, responses: Dict[str, List[str]]):
|
7
|
+
super().__init__(responses)
|
edsl/conjure/__init__.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# from edsl.conjure.SurveyBuilder import SurveyBuilder
|
2
|
-
# from edsl.conjure.SurveyBuilderCSV import SurveyBuilderCSV
|
3
|
-
# from edsl.conjure.SurveyBuilderCSV import SurveyBuilderStata
|
4
|
-
# from edsl.conjure.SurveyBuilderSPSS import SurveyBuilderSPSS
|
5
|
-
# from edsl.conjure.InputData.InputDataSPSS import InputDataSPSS
|
6
|
-
# from edsl.conjure.InputData.InputDataCSV import InputDataCSV
|
7
|
-
# from edsl.conjure.InputData.InputDataStata import InputDataStata
|
8
|
-
# from edsl.conjure.InputData import InputDataSPSS
|
9
|
-
# from edsl.conjure.InputData import InputData
|
1
|
+
# from edsl.conjure.SurveyBuilder import SurveyBuilder
|
2
|
+
# from edsl.conjure.SurveyBuilderCSV import SurveyBuilderCSV
|
3
|
+
# from edsl.conjure.SurveyBuilderCSV import SurveyBuilderStata
|
4
|
+
# from edsl.conjure.SurveyBuilderSPSS import SurveyBuilderSPSS
|
5
|
+
# from edsl.conjure.InputData.InputDataSPSS import InputDataSPSS
|
6
|
+
# from edsl.conjure.InputData.InputDataCSV import InputDataCSV
|
7
|
+
# from edsl.conjure.InputData.InputDataStata import InputDataStata
|
8
|
+
# from edsl.conjure.InputData import InputDataSPSS
|
9
|
+
# from edsl.conjure.InputData import InputData
|