edsl 0.1.38.dev3__py3-none-any.whl → 0.1.38.dev4__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.
Files changed (256) hide show
  1. edsl/Base.py +332 -303
  2. edsl/BaseDiff.py +260 -260
  3. edsl/TemplateLoader.py +24 -24
  4. edsl/__init__.py +49 -49
  5. edsl/__version__.py +1 -1
  6. edsl/agents/Agent.py +867 -858
  7. edsl/agents/AgentList.py +413 -362
  8. edsl/agents/Invigilator.py +233 -222
  9. edsl/agents/InvigilatorBase.py +265 -284
  10. edsl/agents/PromptConstructor.py +354 -353
  11. edsl/agents/__init__.py +3 -3
  12. edsl/agents/descriptors.py +99 -99
  13. edsl/agents/prompt_helpers.py +129 -129
  14. edsl/auto/AutoStudy.py +117 -117
  15. edsl/auto/StageBase.py +230 -230
  16. edsl/auto/StageGenerateSurvey.py +178 -178
  17. edsl/auto/StageLabelQuestions.py +125 -125
  18. edsl/auto/StagePersona.py +61 -61
  19. edsl/auto/StagePersonaDimensionValueRanges.py +88 -88
  20. edsl/auto/StagePersonaDimensionValues.py +74 -74
  21. edsl/auto/StagePersonaDimensions.py +69 -69
  22. edsl/auto/StageQuestions.py +73 -73
  23. edsl/auto/SurveyCreatorPipeline.py +21 -21
  24. edsl/auto/utilities.py +224 -224
  25. edsl/base/Base.py +279 -279
  26. edsl/config.py +157 -149
  27. edsl/conversation/Conversation.py +290 -290
  28. edsl/conversation/car_buying.py +58 -58
  29. edsl/conversation/chips.py +95 -95
  30. edsl/conversation/mug_negotiation.py +81 -81
  31. edsl/conversation/next_speaker_utilities.py +93 -93
  32. edsl/coop/PriceFetcher.py +54 -54
  33. edsl/coop/__init__.py +2 -2
  34. edsl/coop/coop.py +1028 -961
  35. edsl/coop/utils.py +131 -131
  36. edsl/data/Cache.py +555 -530
  37. edsl/data/CacheEntry.py +233 -228
  38. edsl/data/CacheHandler.py +149 -149
  39. edsl/data/RemoteCacheSync.py +78 -97
  40. edsl/data/SQLiteDict.py +292 -292
  41. edsl/data/__init__.py +4 -4
  42. edsl/data/orm.py +10 -10
  43. edsl/data_transfer_models.py +73 -73
  44. edsl/enums.py +175 -173
  45. edsl/exceptions/BaseException.py +21 -21
  46. edsl/exceptions/__init__.py +54 -54
  47. edsl/exceptions/agents.py +42 -42
  48. edsl/exceptions/cache.py +5 -5
  49. edsl/exceptions/configuration.py +16 -16
  50. edsl/exceptions/coop.py +10 -10
  51. edsl/exceptions/data.py +14 -14
  52. edsl/exceptions/general.py +34 -34
  53. edsl/exceptions/jobs.py +33 -33
  54. edsl/exceptions/language_models.py +63 -63
  55. edsl/exceptions/prompts.py +15 -15
  56. edsl/exceptions/questions.py +91 -91
  57. edsl/exceptions/results.py +29 -29
  58. edsl/exceptions/scenarios.py +22 -22
  59. edsl/exceptions/surveys.py +37 -37
  60. edsl/inference_services/AnthropicService.py +87 -87
  61. edsl/inference_services/AwsBedrock.py +120 -120
  62. edsl/inference_services/AzureAI.py +217 -217
  63. edsl/inference_services/DeepInfraService.py +18 -18
  64. edsl/inference_services/GoogleService.py +148 -156
  65. edsl/inference_services/GroqService.py +20 -20
  66. edsl/inference_services/InferenceServiceABC.py +147 -147
  67. edsl/inference_services/InferenceServicesCollection.py +97 -97
  68. edsl/inference_services/MistralAIService.py +123 -123
  69. edsl/inference_services/OllamaService.py +18 -18
  70. edsl/inference_services/OpenAIService.py +224 -224
  71. edsl/inference_services/PerplexityService.py +163 -0
  72. edsl/inference_services/TestService.py +89 -89
  73. edsl/inference_services/TogetherAIService.py +170 -170
  74. edsl/inference_services/models_available_cache.py +118 -118
  75. edsl/inference_services/rate_limits_cache.py +25 -25
  76. edsl/inference_services/registry.py +41 -39
  77. edsl/inference_services/write_available.py +10 -10
  78. edsl/jobs/Answers.py +56 -56
  79. edsl/jobs/Jobs.py +898 -1358
  80. edsl/jobs/JobsChecks.py +147 -0
  81. edsl/jobs/JobsPrompts.py +268 -0
  82. edsl/jobs/JobsRemoteInferenceHandler.py +239 -0
  83. edsl/jobs/__init__.py +1 -1
  84. edsl/jobs/buckets/BucketCollection.py +63 -63
  85. edsl/jobs/buckets/ModelBuckets.py +65 -65
  86. edsl/jobs/buckets/TokenBucket.py +251 -251
  87. edsl/jobs/interviews/Interview.py +661 -661
  88. edsl/jobs/interviews/InterviewExceptionCollection.py +99 -99
  89. edsl/jobs/interviews/InterviewExceptionEntry.py +186 -186
  90. edsl/jobs/interviews/InterviewStatistic.py +63 -63
  91. edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -25
  92. edsl/jobs/interviews/InterviewStatusDictionary.py +78 -78
  93. edsl/jobs/interviews/InterviewStatusLog.py +92 -92
  94. edsl/jobs/interviews/ReportErrors.py +66 -66
  95. edsl/jobs/interviews/interview_status_enum.py +9 -9
  96. edsl/jobs/runners/JobsRunnerAsyncio.py +466 -361
  97. edsl/jobs/runners/JobsRunnerStatus.py +330 -332
  98. edsl/jobs/tasks/QuestionTaskCreator.py +242 -242
  99. edsl/jobs/tasks/TaskCreators.py +64 -64
  100. edsl/jobs/tasks/TaskHistory.py +450 -451
  101. edsl/jobs/tasks/TaskStatusLog.py +23 -23
  102. edsl/jobs/tasks/task_status_enum.py +163 -163
  103. edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
  104. edsl/jobs/tokens/TokenUsage.py +34 -34
  105. edsl/language_models/KeyLookup.py +30 -30
  106. edsl/language_models/LanguageModel.py +668 -708
  107. edsl/language_models/ModelList.py +155 -109
  108. edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
  109. edsl/language_models/__init__.py +3 -3
  110. edsl/language_models/fake_openai_call.py +15 -15
  111. edsl/language_models/fake_openai_service.py +61 -61
  112. edsl/language_models/registry.py +190 -137
  113. edsl/language_models/repair.py +156 -156
  114. edsl/language_models/unused/ReplicateBase.py +83 -83
  115. edsl/language_models/utilities.py +64 -64
  116. edsl/notebooks/Notebook.py +258 -258
  117. edsl/notebooks/__init__.py +1 -1
  118. edsl/prompts/Prompt.py +362 -357
  119. edsl/prompts/__init__.py +2 -2
  120. edsl/questions/AnswerValidatorMixin.py +289 -289
  121. edsl/questions/QuestionBase.py +664 -660
  122. edsl/questions/QuestionBaseGenMixin.py +161 -161
  123. edsl/questions/QuestionBasePromptsMixin.py +217 -217
  124. edsl/questions/QuestionBudget.py +227 -227
  125. edsl/questions/QuestionCheckBox.py +359 -359
  126. edsl/questions/QuestionExtract.py +182 -183
  127. edsl/questions/QuestionFreeText.py +114 -114
  128. edsl/questions/QuestionFunctional.py +166 -166
  129. edsl/questions/QuestionList.py +231 -231
  130. edsl/questions/QuestionMultipleChoice.py +286 -286
  131. edsl/questions/QuestionNumerical.py +153 -153
  132. edsl/questions/QuestionRank.py +324 -324
  133. edsl/questions/Quick.py +41 -41
  134. edsl/questions/RegisterQuestionsMeta.py +71 -71
  135. edsl/questions/ResponseValidatorABC.py +174 -174
  136. edsl/questions/SimpleAskMixin.py +73 -73
  137. edsl/questions/__init__.py +26 -26
  138. edsl/questions/compose_questions.py +98 -98
  139. edsl/questions/decorators.py +21 -21
  140. edsl/questions/derived/QuestionLikertFive.py +76 -76
  141. edsl/questions/derived/QuestionLinearScale.py +87 -87
  142. edsl/questions/derived/QuestionTopK.py +93 -93
  143. edsl/questions/derived/QuestionYesNo.py +82 -82
  144. edsl/questions/descriptors.py +413 -413
  145. edsl/questions/prompt_templates/question_budget.jinja +13 -13
  146. edsl/questions/prompt_templates/question_checkbox.jinja +32 -32
  147. edsl/questions/prompt_templates/question_extract.jinja +11 -11
  148. edsl/questions/prompt_templates/question_free_text.jinja +3 -3
  149. edsl/questions/prompt_templates/question_linear_scale.jinja +11 -11
  150. edsl/questions/prompt_templates/question_list.jinja +17 -17
  151. edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -33
  152. edsl/questions/prompt_templates/question_numerical.jinja +36 -36
  153. edsl/questions/question_registry.py +177 -147
  154. edsl/questions/settings.py +12 -12
  155. edsl/questions/templates/budget/answering_instructions.jinja +7 -7
  156. edsl/questions/templates/budget/question_presentation.jinja +7 -7
  157. edsl/questions/templates/checkbox/answering_instructions.jinja +10 -10
  158. edsl/questions/templates/checkbox/question_presentation.jinja +22 -22
  159. edsl/questions/templates/extract/answering_instructions.jinja +7 -7
  160. edsl/questions/templates/likert_five/answering_instructions.jinja +10 -10
  161. edsl/questions/templates/likert_five/question_presentation.jinja +11 -11
  162. edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -5
  163. edsl/questions/templates/linear_scale/question_presentation.jinja +5 -5
  164. edsl/questions/templates/list/answering_instructions.jinja +3 -3
  165. edsl/questions/templates/list/question_presentation.jinja +5 -5
  166. edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -9
  167. edsl/questions/templates/multiple_choice/question_presentation.jinja +11 -11
  168. edsl/questions/templates/numerical/answering_instructions.jinja +6 -6
  169. edsl/questions/templates/numerical/question_presentation.jinja +6 -6
  170. edsl/questions/templates/rank/answering_instructions.jinja +11 -11
  171. edsl/questions/templates/rank/question_presentation.jinja +15 -15
  172. edsl/questions/templates/top_k/answering_instructions.jinja +8 -8
  173. edsl/questions/templates/top_k/question_presentation.jinja +22 -22
  174. edsl/questions/templates/yes_no/answering_instructions.jinja +6 -6
  175. edsl/questions/templates/yes_no/question_presentation.jinja +11 -11
  176. edsl/results/CSSParameterizer.py +108 -0
  177. edsl/results/Dataset.py +424 -293
  178. edsl/results/DatasetExportMixin.py +731 -717
  179. edsl/results/DatasetTree.py +275 -145
  180. edsl/results/Result.py +465 -456
  181. edsl/results/Results.py +1165 -1071
  182. edsl/results/ResultsDBMixin.py +238 -238
  183. edsl/results/ResultsExportMixin.py +43 -43
  184. edsl/results/ResultsFetchMixin.py +33 -33
  185. edsl/results/ResultsGGMixin.py +121 -121
  186. edsl/results/ResultsToolsMixin.py +98 -98
  187. edsl/results/Selector.py +135 -135
  188. edsl/results/TableDisplay.py +198 -0
  189. edsl/results/__init__.py +2 -2
  190. edsl/results/table_display.css +78 -0
  191. edsl/results/tree_explore.py +115 -115
  192. edsl/scenarios/FileStore.py +632 -458
  193. edsl/scenarios/Scenario.py +601 -544
  194. edsl/scenarios/ScenarioHtmlMixin.py +64 -64
  195. edsl/scenarios/ScenarioJoin.py +127 -0
  196. edsl/scenarios/ScenarioList.py +1287 -1112
  197. edsl/scenarios/ScenarioListExportMixin.py +52 -52
  198. edsl/scenarios/ScenarioListPdfMixin.py +261 -261
  199. edsl/scenarios/__init__.py +4 -4
  200. edsl/shared.py +1 -1
  201. edsl/study/ObjectEntry.py +173 -173
  202. edsl/study/ProofOfWork.py +113 -113
  203. edsl/study/SnapShot.py +80 -80
  204. edsl/study/Study.py +528 -528
  205. edsl/study/__init__.py +4 -4
  206. edsl/surveys/DAG.py +148 -148
  207. edsl/surveys/Memory.py +31 -31
  208. edsl/surveys/MemoryPlan.py +244 -244
  209. edsl/surveys/Rule.py +326 -326
  210. edsl/surveys/RuleCollection.py +387 -387
  211. edsl/surveys/Survey.py +1801 -1787
  212. edsl/surveys/SurveyCSS.py +261 -261
  213. edsl/surveys/SurveyExportMixin.py +259 -259
  214. edsl/surveys/SurveyFlowVisualizationMixin.py +179 -121
  215. edsl/surveys/SurveyQualtricsImport.py +284 -284
  216. edsl/surveys/__init__.py +3 -3
  217. edsl/surveys/base.py +53 -53
  218. edsl/surveys/descriptors.py +56 -56
  219. edsl/surveys/instructions/ChangeInstruction.py +49 -49
  220. edsl/surveys/instructions/Instruction.py +65 -53
  221. edsl/surveys/instructions/InstructionCollection.py +77 -77
  222. edsl/templates/error_reporting/base.html +23 -23
  223. edsl/templates/error_reporting/exceptions_by_model.html +34 -34
  224. edsl/templates/error_reporting/exceptions_by_question_name.html +16 -16
  225. edsl/templates/error_reporting/exceptions_by_type.html +16 -16
  226. edsl/templates/error_reporting/interview_details.html +115 -115
  227. edsl/templates/error_reporting/interviews.html +19 -10
  228. edsl/templates/error_reporting/overview.html +4 -4
  229. edsl/templates/error_reporting/performance_plot.html +1 -1
  230. edsl/templates/error_reporting/report.css +73 -73
  231. edsl/templates/error_reporting/report.html +117 -117
  232. edsl/templates/error_reporting/report.js +25 -25
  233. edsl/tools/__init__.py +1 -1
  234. edsl/tools/clusters.py +192 -192
  235. edsl/tools/embeddings.py +27 -27
  236. edsl/tools/embeddings_plotting.py +118 -118
  237. edsl/tools/plotting.py +112 -112
  238. edsl/tools/summarize.py +18 -18
  239. edsl/utilities/SystemInfo.py +28 -28
  240. edsl/utilities/__init__.py +22 -22
  241. edsl/utilities/ast_utilities.py +25 -25
  242. edsl/utilities/data/Registry.py +6 -6
  243. edsl/utilities/data/__init__.py +1 -1
  244. edsl/utilities/data/scooter_results.json +1 -1
  245. edsl/utilities/decorators.py +77 -77
  246. edsl/utilities/gcp_bucket/cloud_storage.py +96 -96
  247. edsl/utilities/interface.py +627 -627
  248. edsl/utilities/naming_utilities.py +263 -263
  249. edsl/utilities/repair_functions.py +28 -28
  250. edsl/utilities/restricted_python.py +70 -70
  251. edsl/utilities/utilities.py +424 -409
  252. {edsl-0.1.38.dev3.dist-info → edsl-0.1.38.dev4.dist-info}/LICENSE +21 -21
  253. {edsl-0.1.38.dev3.dist-info → edsl-0.1.38.dev4.dist-info}/METADATA +2 -1
  254. edsl-0.1.38.dev4.dist-info/RECORD +277 -0
  255. edsl-0.1.38.dev3.dist-info/RECORD +0 -269
  256. {edsl-0.1.38.dev3.dist-info → edsl-0.1.38.dev4.dist-info}/WHEEL +0 -0
@@ -1,121 +1,121 @@
1
- """Mixin class for ggplot2 plotting."""
2
-
3
- import subprocess
4
- import tempfile
5
- from typing import Optional
6
-
7
-
8
- class ResultsGGMixin:
9
- """Mixin class for ggplot2 plotting."""
10
-
11
- def ggplot2(
12
- self,
13
- ggplot_code: str,
14
- filename: str = None,
15
- shape="wide",
16
- sql: str = None,
17
- remove_prefix: bool = True,
18
- debug: bool = False,
19
- height=4,
20
- width=6,
21
- format="svg",
22
- factor_orders: Optional[dict] = None,
23
- ):
24
- """Create a ggplot2 plot from a DataFrame.
25
-
26
- :param ggplot_code: The ggplot2 code to execute.
27
- :param filename: The filename to save the plot to.
28
- :param shape: The shape of the data in the DataFrame (wide or long).
29
- :param sql: The SQL query to execute beforehand to manipulate the data.
30
- :param remove_prefix: Whether to remove the prefix from the column names.
31
- :param debug: Whether to print the R code instead of executing it.
32
- :param height: The height of the plot in inches.
33
- :param width: The width of the plot in inches.
34
- :param format: The format to save the plot in (png or svg).
35
- :param factor_orders: A dictionary of factor columns and their order.
36
- """
37
-
38
- if sql == None:
39
- sql = "select * from self"
40
-
41
- if shape == "long":
42
- df = self.sql(sql, shape="long")
43
- elif shape == "wide":
44
- df = self.sql(sql, shape="wide", remove_prefix=remove_prefix)
45
-
46
- # Convert DataFrame to CSV format
47
- csv_data = df.to_csv(index=False)
48
-
49
- # Embed the CSV data within the R script
50
- csv_data_escaped = csv_data.replace("\n", "\\n").replace("'", "\\'")
51
- read_csv_code = f"self <- read.csv(text = '{csv_data_escaped}', sep = ',')\n"
52
-
53
- if factor_orders is not None:
54
- for factor, order in factor_orders.items():
55
- # read_csv_code += f"""self${{{factor}}} <- factor(self${{{factor}}}, levels=c({','.join(['"{}"'.format(x) for x in order])}))"""
56
-
57
- level_string = ", ".join([f'"{x}"' for x in order])
58
- read_csv_code += (
59
- f"self${factor} <- factor(self${factor}, levels=c({level_string}))"
60
- )
61
- read_csv_code += "\n"
62
-
63
- # Load ggplot2 library
64
- load_ggplot2 = "library(ggplot2)\n"
65
-
66
- # Check if a filename is provided for the plot, if not create a temporary one
67
- if not filename:
68
- filename = tempfile.mktemp(suffix=f".{format}")
69
-
70
- # Combine all R script parts
71
- full_r_code = load_ggplot2 + read_csv_code + ggplot_code
72
-
73
- # Add command to save the plot to a file
74
- full_r_code += f'\nggsave("{filename}", plot = last_plot(), width = {width}, height = {height}, device = "{format}")'
75
-
76
- if debug:
77
- print(full_r_code)
78
- return
79
-
80
- result = subprocess.run(
81
- ["Rscript", "-"],
82
- input=full_r_code,
83
- text=True,
84
- stdout=subprocess.PIPE,
85
- stderr=subprocess.PIPE,
86
- )
87
-
88
- if result.returncode != 0:
89
- if result.returncode == 127: # 'command not found'
90
- raise RuntimeError(
91
- "Rscript is probably not installed. Please install R from https://cran.r-project.org/"
92
- )
93
- else:
94
- raise RuntimeError(
95
- f"An error occurred while running Rscript: {result.stderr}"
96
- )
97
-
98
- if result.stderr:
99
- print("Error in R script:", result.stderr)
100
- else:
101
- self._display_plot(filename, width, height)
102
-
103
- def _display_plot(self, filename: str, width: float, height: float):
104
- """Display the plot in the notebook."""
105
- import matplotlib.pyplot as plt
106
- import matplotlib.image as mpimg
107
-
108
- if filename.endswith(".png"):
109
- img = mpimg.imread(filename)
110
- plt.figure(
111
- figsize=(width, height)
112
- ) # Set the figure size (width, height) in inches
113
- plt.imshow(img)
114
- plt.axis("off")
115
- plt.show()
116
- elif filename.endswith(".svg"):
117
- from IPython.display import SVG, display
118
-
119
- display(SVG(filename=filename))
120
- else:
121
- print("Unsupported file format. Please provide a PNG or SVG file.")
1
+ """Mixin class for ggplot2 plotting."""
2
+
3
+ import subprocess
4
+ import tempfile
5
+ from typing import Optional
6
+
7
+
8
+ class ResultsGGMixin:
9
+ """Mixin class for ggplot2 plotting."""
10
+
11
+ def ggplot2(
12
+ self,
13
+ ggplot_code: str,
14
+ filename: str = None,
15
+ shape="wide",
16
+ sql: str = None,
17
+ remove_prefix: bool = True,
18
+ debug: bool = False,
19
+ height=4,
20
+ width=6,
21
+ format="svg",
22
+ factor_orders: Optional[dict] = None,
23
+ ):
24
+ """Create a ggplot2 plot from a DataFrame.
25
+
26
+ :param ggplot_code: The ggplot2 code to execute.
27
+ :param filename: The filename to save the plot to.
28
+ :param shape: The shape of the data in the DataFrame (wide or long).
29
+ :param sql: The SQL query to execute beforehand to manipulate the data.
30
+ :param remove_prefix: Whether to remove the prefix from the column names.
31
+ :param debug: Whether to print the R code instead of executing it.
32
+ :param height: The height of the plot in inches.
33
+ :param width: The width of the plot in inches.
34
+ :param format: The format to save the plot in (png or svg).
35
+ :param factor_orders: A dictionary of factor columns and their order.
36
+ """
37
+
38
+ if sql == None:
39
+ sql = "select * from self"
40
+
41
+ if shape == "long":
42
+ df = self.sql(sql, shape="long")
43
+ elif shape == "wide":
44
+ df = self.sql(sql, shape="wide", remove_prefix=remove_prefix)
45
+
46
+ # Convert DataFrame to CSV format
47
+ csv_data = df.to_csv(index=False)
48
+
49
+ # Embed the CSV data within the R script
50
+ csv_data_escaped = csv_data.replace("\n", "\\n").replace("'", "\\'")
51
+ read_csv_code = f"self <- read.csv(text = '{csv_data_escaped}', sep = ',')\n"
52
+
53
+ if factor_orders is not None:
54
+ for factor, order in factor_orders.items():
55
+ # read_csv_code += f"""self${{{factor}}} <- factor(self${{{factor}}}, levels=c({','.join(['"{}"'.format(x) for x in order])}))"""
56
+
57
+ level_string = ", ".join([f'"{x}"' for x in order])
58
+ read_csv_code += (
59
+ f"self${factor} <- factor(self${factor}, levels=c({level_string}))"
60
+ )
61
+ read_csv_code += "\n"
62
+
63
+ # Load ggplot2 library
64
+ load_ggplot2 = "library(ggplot2)\n"
65
+
66
+ # Check if a filename is provided for the plot, if not create a temporary one
67
+ if not filename:
68
+ filename = tempfile.mktemp(suffix=f".{format}")
69
+
70
+ # Combine all R script parts
71
+ full_r_code = load_ggplot2 + read_csv_code + ggplot_code
72
+
73
+ # Add command to save the plot to a file
74
+ full_r_code += f'\nggsave("{filename}", plot = last_plot(), width = {width}, height = {height}, device = "{format}")'
75
+
76
+ if debug:
77
+ print(full_r_code)
78
+ return
79
+
80
+ result = subprocess.run(
81
+ ["Rscript", "-"],
82
+ input=full_r_code,
83
+ text=True,
84
+ stdout=subprocess.PIPE,
85
+ stderr=subprocess.PIPE,
86
+ )
87
+
88
+ if result.returncode != 0:
89
+ if result.returncode == 127: # 'command not found'
90
+ raise RuntimeError(
91
+ "Rscript is probably not installed. Please install R from https://cran.r-project.org/"
92
+ )
93
+ else:
94
+ raise RuntimeError(
95
+ f"An error occurred while running Rscript: {result.stderr}"
96
+ )
97
+
98
+ if result.stderr:
99
+ print("Error in R script:", result.stderr)
100
+ else:
101
+ self._display_plot(filename, width, height)
102
+
103
+ def _display_plot(self, filename: str, width: float, height: float):
104
+ """Display the plot in the notebook."""
105
+ import matplotlib.pyplot as plt
106
+ import matplotlib.image as mpimg
107
+
108
+ if filename.endswith(".png"):
109
+ img = mpimg.imread(filename)
110
+ plt.figure(
111
+ figsize=(width, height)
112
+ ) # Set the figure size (width, height) in inches
113
+ plt.imshow(img)
114
+ plt.axis("off")
115
+ plt.show()
116
+ elif filename.endswith(".svg"):
117
+ from IPython.display import SVG, display
118
+
119
+ display(SVG(filename=filename))
120
+ else:
121
+ print("Unsupported file format. Please provide a PNG or SVG file.")
@@ -1,98 +1,98 @@
1
- class ResultsToolsMixin:
2
- def get_themes(
3
- self,
4
- field: str,
5
- context: str,
6
- max_values=100,
7
- num_themes: int = 10,
8
- seed=None,
9
- progress_bar=False,
10
- print_exceptions=False,
11
- ) -> list:
12
- values = [
13
- str(txt)[:1000]
14
- for txt in self.shuffle(seed=seed).select(field).to_list()[:max_values]
15
- ]
16
- from edsl import ScenarioList
17
- from edsl.questions import QuestionList, QuestionCheckBox
18
-
19
- q = QuestionList(
20
- question_text=f"""
21
- {context}
22
- Here are some examples: { values }.
23
- What are some 5-8 word themes that would mostly capture these examples?
24
- Please shoot for {num_themes} as target number of themes.
25
- """,
26
- question_name="themes",
27
- )
28
- results = q.run(print_exceptions=print_exceptions, progress_bar=progress_bar)
29
- return results.select("themes").first()
30
-
31
- def answers_to_themes(
32
- self,
33
- field,
34
- context: str,
35
- themes: list,
36
- progress_bar=False,
37
- print_exceptions=False,
38
- ) -> dict:
39
- from edsl import ScenarioList
40
- from edsl import QuestionCheckBox
41
-
42
- values = self.select(field).to_list()
43
- scenarios = ScenarioList.from_list("field", values).add_value(
44
- "context", context
45
- )
46
- q = QuestionCheckBox(
47
- question_text="""
48
- {{ context }}
49
- Consider the following response:
50
-
51
- " {{ field }} "
52
-
53
- Please check the themes that apply to these examples.
54
- If blank, please check 'None'.
55
- """,
56
- question_options=themes + ["None", "Other"],
57
- question_name="themes",
58
- )
59
- results = q.by(scenarios).run(
60
- progress_bar=progress_bar, print_exceptions=print_exceptions
61
- )
62
- return {k: v for k, v in results.select("field", "themes").to_list()}
63
-
64
- def apply_themes(self, field: str, new_field: str, answers_to_themes: dict):
65
- def translate(x):
66
- return answers_to_themes.get(x, "Other")
67
-
68
- self.mutate(f"{new_field} = f({field})", functions_dict={"f": translate})
69
- return self
70
-
71
- def auto_theme(
72
- self,
73
- field: str,
74
- context: str,
75
- themes: list[str],
76
- newfield: str = None,
77
- progress_bar=False,
78
- print_exceptions=False,
79
- ) -> tuple:
80
- """
81
- :param field: The field to be themed.
82
- :param context: The context of the field.
83
- :param themes: The list of themes.
84
- :param newfield: The new field name.
85
-
86
- """
87
-
88
- if not newfield:
89
- newfield = f"{field}_themes"
90
-
91
- answers_to_themes = self.answers_to_themes(
92
- field=field,
93
- context=context,
94
- themes=themes,
95
- progress_bar=progress_bar,
96
- print_exceptions=print_exceptions,
97
- )
98
- return self.apply_themes(field, newfield, answers_to_themes), themes
1
+ class ResultsToolsMixin:
2
+ def get_themes(
3
+ self,
4
+ field: str,
5
+ context: str,
6
+ max_values=100,
7
+ num_themes: int = 10,
8
+ seed=None,
9
+ progress_bar=False,
10
+ print_exceptions=False,
11
+ ) -> list:
12
+ values = [
13
+ str(txt)[:1000]
14
+ for txt in self.shuffle(seed=seed).select(field).to_list()[:max_values]
15
+ ]
16
+ from edsl import ScenarioList
17
+ from edsl.questions import QuestionList, QuestionCheckBox
18
+
19
+ q = QuestionList(
20
+ question_text=f"""
21
+ {context}
22
+ Here are some examples: { values }.
23
+ What are some 5-8 word themes that would mostly capture these examples?
24
+ Please shoot for {num_themes} as target number of themes.
25
+ """,
26
+ question_name="themes",
27
+ )
28
+ results = q.run(print_exceptions=print_exceptions, progress_bar=progress_bar)
29
+ return results.select("themes").first()
30
+
31
+ def answers_to_themes(
32
+ self,
33
+ field,
34
+ context: str,
35
+ themes: list,
36
+ progress_bar=False,
37
+ print_exceptions=False,
38
+ ) -> dict:
39
+ from edsl import ScenarioList
40
+ from edsl import QuestionCheckBox
41
+
42
+ values = self.select(field).to_list()
43
+ scenarios = ScenarioList.from_list("field", values).add_value(
44
+ "context", context
45
+ )
46
+ q = QuestionCheckBox(
47
+ question_text="""
48
+ {{ context }}
49
+ Consider the following response:
50
+
51
+ " {{ field }} "
52
+
53
+ Please check the themes that apply to these examples.
54
+ If blank, please check 'None'.
55
+ """,
56
+ question_options=themes + ["None", "Other"],
57
+ question_name="themes",
58
+ )
59
+ results = q.by(scenarios).run(
60
+ progress_bar=progress_bar, print_exceptions=print_exceptions
61
+ )
62
+ return {k: v for k, v in results.select("field", "themes").to_list()}
63
+
64
+ def apply_themes(self, field: str, new_field: str, answers_to_themes: dict):
65
+ def translate(x):
66
+ return answers_to_themes.get(x, "Other")
67
+
68
+ self.mutate(f"{new_field} = f({field})", functions_dict={"f": translate})
69
+ return self
70
+
71
+ def auto_theme(
72
+ self,
73
+ field: str,
74
+ context: str,
75
+ themes: list[str],
76
+ newfield: str = None,
77
+ progress_bar=False,
78
+ print_exceptions=False,
79
+ ) -> tuple:
80
+ """
81
+ :param field: The field to be themed.
82
+ :param context: The context of the field.
83
+ :param themes: The list of themes.
84
+ :param newfield: The new field name.
85
+
86
+ """
87
+
88
+ if not newfield:
89
+ newfield = f"{field}_themes"
90
+
91
+ answers_to_themes = self.answers_to_themes(
92
+ field=field,
93
+ context=context,
94
+ themes=themes,
95
+ progress_bar=progress_bar,
96
+ print_exceptions=print_exceptions,
97
+ )
98
+ return self.apply_themes(field, newfield, answers_to_themes), themes