edsl 0.1.14__py3-none-any.whl → 0.1.40__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 (407) hide show
  1. edsl/Base.py +348 -38
  2. edsl/BaseDiff.py +260 -0
  3. edsl/TemplateLoader.py +24 -0
  4. edsl/__init__.py +46 -10
  5. edsl/__version__.py +1 -0
  6. edsl/agents/Agent.py +842 -144
  7. edsl/agents/AgentList.py +521 -25
  8. edsl/agents/Invigilator.py +250 -374
  9. edsl/agents/InvigilatorBase.py +257 -0
  10. edsl/agents/PromptConstructor.py +272 -0
  11. edsl/agents/QuestionInstructionPromptBuilder.py +128 -0
  12. edsl/agents/QuestionTemplateReplacementsBuilder.py +137 -0
  13. edsl/agents/descriptors.py +43 -13
  14. edsl/agents/prompt_helpers.py +129 -0
  15. edsl/agents/question_option_processor.py +172 -0
  16. edsl/auto/AutoStudy.py +130 -0
  17. edsl/auto/StageBase.py +243 -0
  18. edsl/auto/StageGenerateSurvey.py +178 -0
  19. edsl/auto/StageLabelQuestions.py +125 -0
  20. edsl/auto/StagePersona.py +61 -0
  21. edsl/auto/StagePersonaDimensionValueRanges.py +88 -0
  22. edsl/auto/StagePersonaDimensionValues.py +74 -0
  23. edsl/auto/StagePersonaDimensions.py +69 -0
  24. edsl/auto/StageQuestions.py +74 -0
  25. edsl/auto/SurveyCreatorPipeline.py +21 -0
  26. edsl/auto/utilities.py +218 -0
  27. edsl/base/Base.py +279 -0
  28. edsl/config.py +121 -104
  29. edsl/conversation/Conversation.py +290 -0
  30. edsl/conversation/car_buying.py +59 -0
  31. edsl/conversation/chips.py +95 -0
  32. edsl/conversation/mug_negotiation.py +81 -0
  33. edsl/conversation/next_speaker_utilities.py +93 -0
  34. edsl/coop/CoopFunctionsMixin.py +15 -0
  35. edsl/coop/ExpectedParrotKeyHandler.py +125 -0
  36. edsl/coop/PriceFetcher.py +54 -0
  37. edsl/coop/__init__.py +1 -0
  38. edsl/coop/coop.py +1029 -134
  39. edsl/coop/utils.py +131 -0
  40. edsl/data/Cache.py +560 -89
  41. edsl/data/CacheEntry.py +230 -0
  42. edsl/data/CacheHandler.py +168 -0
  43. edsl/data/RemoteCacheSync.py +186 -0
  44. edsl/data/SQLiteDict.py +292 -0
  45. edsl/data/__init__.py +5 -3
  46. edsl/data/orm.py +6 -33
  47. edsl/data_transfer_models.py +74 -27
  48. edsl/enums.py +165 -8
  49. edsl/exceptions/BaseException.py +21 -0
  50. edsl/exceptions/__init__.py +52 -46
  51. edsl/exceptions/agents.py +33 -15
  52. edsl/exceptions/cache.py +5 -0
  53. edsl/exceptions/coop.py +8 -0
  54. edsl/exceptions/general.py +34 -0
  55. edsl/exceptions/inference_services.py +5 -0
  56. edsl/exceptions/jobs.py +15 -0
  57. edsl/exceptions/language_models.py +46 -1
  58. edsl/exceptions/questions.py +80 -5
  59. edsl/exceptions/results.py +16 -5
  60. edsl/exceptions/scenarios.py +29 -0
  61. edsl/exceptions/surveys.py +13 -10
  62. edsl/inference_services/AnthropicService.py +106 -0
  63. edsl/inference_services/AvailableModelCacheHandler.py +184 -0
  64. edsl/inference_services/AvailableModelFetcher.py +215 -0
  65. edsl/inference_services/AwsBedrock.py +118 -0
  66. edsl/inference_services/AzureAI.py +215 -0
  67. edsl/inference_services/DeepInfraService.py +18 -0
  68. edsl/inference_services/GoogleService.py +143 -0
  69. edsl/inference_services/GroqService.py +20 -0
  70. edsl/inference_services/InferenceServiceABC.py +80 -0
  71. edsl/inference_services/InferenceServicesCollection.py +138 -0
  72. edsl/inference_services/MistralAIService.py +120 -0
  73. edsl/inference_services/OllamaService.py +18 -0
  74. edsl/inference_services/OpenAIService.py +236 -0
  75. edsl/inference_services/PerplexityService.py +160 -0
  76. edsl/inference_services/ServiceAvailability.py +135 -0
  77. edsl/inference_services/TestService.py +90 -0
  78. edsl/inference_services/TogetherAIService.py +172 -0
  79. edsl/inference_services/data_structures.py +134 -0
  80. edsl/inference_services/models_available_cache.py +118 -0
  81. edsl/inference_services/rate_limits_cache.py +25 -0
  82. edsl/inference_services/registry.py +41 -0
  83. edsl/inference_services/write_available.py +10 -0
  84. edsl/jobs/AnswerQuestionFunctionConstructor.py +223 -0
  85. edsl/jobs/Answers.py +21 -20
  86. edsl/jobs/FetchInvigilator.py +47 -0
  87. edsl/jobs/InterviewTaskManager.py +98 -0
  88. edsl/jobs/InterviewsConstructor.py +50 -0
  89. edsl/jobs/Jobs.py +684 -204
  90. edsl/jobs/JobsChecks.py +172 -0
  91. edsl/jobs/JobsComponentConstructor.py +189 -0
  92. edsl/jobs/JobsPrompts.py +270 -0
  93. edsl/jobs/JobsRemoteInferenceHandler.py +311 -0
  94. edsl/jobs/JobsRemoteInferenceLogger.py +239 -0
  95. edsl/jobs/RequestTokenEstimator.py +30 -0
  96. edsl/jobs/async_interview_runner.py +138 -0
  97. edsl/jobs/buckets/BucketCollection.py +104 -0
  98. edsl/jobs/buckets/ModelBuckets.py +65 -0
  99. edsl/jobs/buckets/TokenBucket.py +283 -0
  100. edsl/jobs/buckets/TokenBucketAPI.py +211 -0
  101. edsl/jobs/buckets/TokenBucketClient.py +191 -0
  102. edsl/jobs/check_survey_scenario_compatibility.py +85 -0
  103. edsl/jobs/data_structures.py +120 -0
  104. edsl/jobs/decorators.py +35 -0
  105. edsl/jobs/interviews/Interview.py +392 -0
  106. edsl/jobs/interviews/InterviewExceptionCollection.py +99 -0
  107. edsl/jobs/interviews/InterviewExceptionEntry.py +186 -0
  108. edsl/jobs/interviews/InterviewStatistic.py +63 -0
  109. edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -0
  110. edsl/jobs/interviews/InterviewStatusDictionary.py +78 -0
  111. edsl/jobs/interviews/InterviewStatusLog.py +92 -0
  112. edsl/jobs/interviews/ReportErrors.py +66 -0
  113. edsl/jobs/interviews/interview_status_enum.py +9 -0
  114. edsl/jobs/jobs_status_enums.py +9 -0
  115. edsl/jobs/loggers/HTMLTableJobLogger.py +304 -0
  116. edsl/jobs/results_exceptions_handler.py +98 -0
  117. edsl/jobs/runners/JobsRunnerAsyncio.py +151 -110
  118. edsl/jobs/runners/JobsRunnerStatus.py +298 -0
  119. edsl/jobs/tasks/QuestionTaskCreator.py +244 -0
  120. edsl/jobs/tasks/TaskCreators.py +64 -0
  121. edsl/jobs/tasks/TaskHistory.py +470 -0
  122. edsl/jobs/tasks/TaskStatusLog.py +23 -0
  123. edsl/jobs/tasks/task_status_enum.py +161 -0
  124. edsl/jobs/tokens/InterviewTokenUsage.py +27 -0
  125. edsl/jobs/tokens/TokenUsage.py +34 -0
  126. edsl/language_models/ComputeCost.py +63 -0
  127. edsl/language_models/LanguageModel.py +507 -386
  128. edsl/language_models/ModelList.py +164 -0
  129. edsl/language_models/PriceManager.py +127 -0
  130. edsl/language_models/RawResponseHandler.py +106 -0
  131. edsl/language_models/RegisterLanguageModelsMeta.py +184 -0
  132. edsl/language_models/__init__.py +1 -8
  133. edsl/language_models/fake_openai_call.py +15 -0
  134. edsl/language_models/fake_openai_service.py +61 -0
  135. edsl/language_models/key_management/KeyLookup.py +63 -0
  136. edsl/language_models/key_management/KeyLookupBuilder.py +273 -0
  137. edsl/language_models/key_management/KeyLookupCollection.py +38 -0
  138. edsl/language_models/key_management/__init__.py +0 -0
  139. edsl/language_models/key_management/models.py +131 -0
  140. edsl/language_models/model.py +256 -0
  141. edsl/language_models/repair.py +109 -41
  142. edsl/language_models/utilities.py +65 -0
  143. edsl/notebooks/Notebook.py +263 -0
  144. edsl/notebooks/NotebookToLaTeX.py +142 -0
  145. edsl/notebooks/__init__.py +1 -0
  146. edsl/prompts/Prompt.py +222 -93
  147. edsl/prompts/__init__.py +1 -1
  148. edsl/questions/ExceptionExplainer.py +77 -0
  149. edsl/questions/HTMLQuestion.py +103 -0
  150. edsl/questions/QuestionBase.py +518 -0
  151. edsl/questions/QuestionBasePromptsMixin.py +221 -0
  152. edsl/questions/QuestionBudget.py +164 -67
  153. edsl/questions/QuestionCheckBox.py +281 -62
  154. edsl/questions/QuestionDict.py +343 -0
  155. edsl/questions/QuestionExtract.py +136 -50
  156. edsl/questions/QuestionFreeText.py +79 -55
  157. edsl/questions/QuestionFunctional.py +138 -41
  158. edsl/questions/QuestionList.py +184 -57
  159. edsl/questions/QuestionMatrix.py +265 -0
  160. edsl/questions/QuestionMultipleChoice.py +293 -69
  161. edsl/questions/QuestionNumerical.py +109 -56
  162. edsl/questions/QuestionRank.py +244 -49
  163. edsl/questions/Quick.py +41 -0
  164. edsl/questions/SimpleAskMixin.py +74 -0
  165. edsl/questions/__init__.py +9 -6
  166. edsl/questions/{AnswerValidatorMixin.py → answer_validator_mixin.py} +153 -38
  167. edsl/questions/compose_questions.py +13 -7
  168. edsl/questions/data_structures.py +20 -0
  169. edsl/questions/decorators.py +21 -0
  170. edsl/questions/derived/QuestionLikertFive.py +28 -26
  171. edsl/questions/derived/QuestionLinearScale.py +41 -28
  172. edsl/questions/derived/QuestionTopK.py +34 -26
  173. edsl/questions/derived/QuestionYesNo.py +40 -27
  174. edsl/questions/descriptors.py +228 -74
  175. edsl/questions/loop_processor.py +149 -0
  176. edsl/questions/prompt_templates/question_budget.jinja +13 -0
  177. edsl/questions/prompt_templates/question_checkbox.jinja +32 -0
  178. edsl/questions/prompt_templates/question_extract.jinja +11 -0
  179. edsl/questions/prompt_templates/question_free_text.jinja +3 -0
  180. edsl/questions/prompt_templates/question_linear_scale.jinja +11 -0
  181. edsl/questions/prompt_templates/question_list.jinja +17 -0
  182. edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -0
  183. edsl/questions/prompt_templates/question_numerical.jinja +37 -0
  184. edsl/questions/question_base_gen_mixin.py +168 -0
  185. edsl/questions/question_registry.py +130 -46
  186. edsl/questions/register_questions_meta.py +71 -0
  187. edsl/questions/response_validator_abc.py +188 -0
  188. edsl/questions/response_validator_factory.py +34 -0
  189. edsl/questions/settings.py +5 -2
  190. edsl/questions/templates/__init__.py +0 -0
  191. edsl/questions/templates/budget/__init__.py +0 -0
  192. edsl/questions/templates/budget/answering_instructions.jinja +7 -0
  193. edsl/questions/templates/budget/question_presentation.jinja +7 -0
  194. edsl/questions/templates/checkbox/__init__.py +0 -0
  195. edsl/questions/templates/checkbox/answering_instructions.jinja +10 -0
  196. edsl/questions/templates/checkbox/question_presentation.jinja +22 -0
  197. edsl/questions/templates/dict/__init__.py +0 -0
  198. edsl/questions/templates/dict/answering_instructions.jinja +21 -0
  199. edsl/questions/templates/dict/question_presentation.jinja +1 -0
  200. edsl/questions/templates/extract/__init__.py +0 -0
  201. edsl/questions/templates/extract/answering_instructions.jinja +7 -0
  202. edsl/questions/templates/extract/question_presentation.jinja +1 -0
  203. edsl/questions/templates/free_text/__init__.py +0 -0
  204. edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
  205. edsl/questions/templates/free_text/question_presentation.jinja +1 -0
  206. edsl/questions/templates/likert_five/__init__.py +0 -0
  207. edsl/questions/templates/likert_five/answering_instructions.jinja +10 -0
  208. edsl/questions/templates/likert_five/question_presentation.jinja +12 -0
  209. edsl/questions/templates/linear_scale/__init__.py +0 -0
  210. edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -0
  211. edsl/questions/templates/linear_scale/question_presentation.jinja +5 -0
  212. edsl/questions/templates/list/__init__.py +0 -0
  213. edsl/questions/templates/list/answering_instructions.jinja +4 -0
  214. edsl/questions/templates/list/question_presentation.jinja +5 -0
  215. edsl/questions/templates/matrix/__init__.py +1 -0
  216. edsl/questions/templates/matrix/answering_instructions.jinja +5 -0
  217. edsl/questions/templates/matrix/question_presentation.jinja +20 -0
  218. edsl/questions/templates/multiple_choice/__init__.py +0 -0
  219. edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -0
  220. edsl/questions/templates/multiple_choice/html.jinja +0 -0
  221. edsl/questions/templates/multiple_choice/question_presentation.jinja +12 -0
  222. edsl/questions/templates/numerical/__init__.py +0 -0
  223. edsl/questions/templates/numerical/answering_instructions.jinja +7 -0
  224. edsl/questions/templates/numerical/question_presentation.jinja +7 -0
  225. edsl/questions/templates/rank/__init__.py +0 -0
  226. edsl/questions/templates/rank/answering_instructions.jinja +11 -0
  227. edsl/questions/templates/rank/question_presentation.jinja +15 -0
  228. edsl/questions/templates/top_k/__init__.py +0 -0
  229. edsl/questions/templates/top_k/answering_instructions.jinja +8 -0
  230. edsl/questions/templates/top_k/question_presentation.jinja +22 -0
  231. edsl/questions/templates/yes_no/__init__.py +0 -0
  232. edsl/questions/templates/yes_no/answering_instructions.jinja +6 -0
  233. edsl/questions/templates/yes_no/question_presentation.jinja +12 -0
  234. edsl/results/CSSParameterizer.py +108 -0
  235. edsl/results/Dataset.py +550 -19
  236. edsl/results/DatasetExportMixin.py +594 -0
  237. edsl/results/DatasetTree.py +295 -0
  238. edsl/results/MarkdownToDocx.py +122 -0
  239. edsl/results/MarkdownToPDF.py +111 -0
  240. edsl/results/Result.py +477 -173
  241. edsl/results/Results.py +987 -269
  242. edsl/results/ResultsExportMixin.py +28 -125
  243. edsl/results/ResultsGGMixin.py +83 -15
  244. edsl/results/TableDisplay.py +125 -0
  245. edsl/results/TextEditor.py +50 -0
  246. edsl/results/__init__.py +1 -1
  247. edsl/results/file_exports.py +252 -0
  248. edsl/results/results_fetch_mixin.py +33 -0
  249. edsl/results/results_selector.py +145 -0
  250. edsl/results/results_tools_mixin.py +98 -0
  251. edsl/results/smart_objects.py +96 -0
  252. edsl/results/table_data_class.py +12 -0
  253. edsl/results/table_display.css +78 -0
  254. edsl/results/table_renderers.py +118 -0
  255. edsl/results/tree_explore.py +115 -0
  256. edsl/scenarios/ConstructDownloadLink.py +109 -0
  257. edsl/scenarios/DocumentChunker.py +102 -0
  258. edsl/scenarios/DocxScenario.py +16 -0
  259. edsl/scenarios/FileStore.py +543 -0
  260. edsl/scenarios/PdfExtractor.py +40 -0
  261. edsl/scenarios/Scenario.py +431 -62
  262. edsl/scenarios/ScenarioHtmlMixin.py +65 -0
  263. edsl/scenarios/ScenarioList.py +1415 -45
  264. edsl/scenarios/ScenarioListExportMixin.py +45 -0
  265. edsl/scenarios/ScenarioListPdfMixin.py +239 -0
  266. edsl/scenarios/__init__.py +2 -0
  267. edsl/scenarios/directory_scanner.py +96 -0
  268. edsl/scenarios/file_methods.py +85 -0
  269. edsl/scenarios/handlers/__init__.py +13 -0
  270. edsl/scenarios/handlers/csv.py +49 -0
  271. edsl/scenarios/handlers/docx.py +76 -0
  272. edsl/scenarios/handlers/html.py +37 -0
  273. edsl/scenarios/handlers/json.py +111 -0
  274. edsl/scenarios/handlers/latex.py +5 -0
  275. edsl/scenarios/handlers/md.py +51 -0
  276. edsl/scenarios/handlers/pdf.py +68 -0
  277. edsl/scenarios/handlers/png.py +39 -0
  278. edsl/scenarios/handlers/pptx.py +105 -0
  279. edsl/scenarios/handlers/py.py +294 -0
  280. edsl/scenarios/handlers/sql.py +313 -0
  281. edsl/scenarios/handlers/sqlite.py +149 -0
  282. edsl/scenarios/handlers/txt.py +33 -0
  283. edsl/scenarios/scenario_join.py +131 -0
  284. edsl/scenarios/scenario_selector.py +156 -0
  285. edsl/shared.py +1 -0
  286. edsl/study/ObjectEntry.py +173 -0
  287. edsl/study/ProofOfWork.py +113 -0
  288. edsl/study/SnapShot.py +80 -0
  289. edsl/study/Study.py +521 -0
  290. edsl/study/__init__.py +4 -0
  291. edsl/surveys/ConstructDAG.py +92 -0
  292. edsl/surveys/DAG.py +92 -11
  293. edsl/surveys/EditSurvey.py +221 -0
  294. edsl/surveys/InstructionHandler.py +100 -0
  295. edsl/surveys/Memory.py +9 -4
  296. edsl/surveys/MemoryManagement.py +72 -0
  297. edsl/surveys/MemoryPlan.py +156 -35
  298. edsl/surveys/Rule.py +221 -74
  299. edsl/surveys/RuleCollection.py +241 -61
  300. edsl/surveys/RuleManager.py +172 -0
  301. edsl/surveys/Simulator.py +75 -0
  302. edsl/surveys/Survey.py +1079 -339
  303. edsl/surveys/SurveyCSS.py +273 -0
  304. edsl/surveys/SurveyExportMixin.py +235 -40
  305. edsl/surveys/SurveyFlowVisualization.py +181 -0
  306. edsl/surveys/SurveyQualtricsImport.py +284 -0
  307. edsl/surveys/SurveyToApp.py +141 -0
  308. edsl/surveys/__init__.py +4 -2
  309. edsl/surveys/base.py +19 -3
  310. edsl/surveys/descriptors.py +17 -6
  311. edsl/surveys/instructions/ChangeInstruction.py +48 -0
  312. edsl/surveys/instructions/Instruction.py +56 -0
  313. edsl/surveys/instructions/InstructionCollection.py +82 -0
  314. edsl/surveys/instructions/__init__.py +0 -0
  315. edsl/templates/error_reporting/base.html +24 -0
  316. edsl/templates/error_reporting/exceptions_by_model.html +35 -0
  317. edsl/templates/error_reporting/exceptions_by_question_name.html +17 -0
  318. edsl/templates/error_reporting/exceptions_by_type.html +17 -0
  319. edsl/templates/error_reporting/interview_details.html +116 -0
  320. edsl/templates/error_reporting/interviews.html +19 -0
  321. edsl/templates/error_reporting/overview.html +5 -0
  322. edsl/templates/error_reporting/performance_plot.html +2 -0
  323. edsl/templates/error_reporting/report.css +74 -0
  324. edsl/templates/error_reporting/report.html +118 -0
  325. edsl/templates/error_reporting/report.js +25 -0
  326. edsl/tools/__init__.py +1 -0
  327. edsl/tools/clusters.py +192 -0
  328. edsl/tools/embeddings.py +27 -0
  329. edsl/tools/embeddings_plotting.py +118 -0
  330. edsl/tools/plotting.py +112 -0
  331. edsl/tools/summarize.py +18 -0
  332. edsl/utilities/PrettyList.py +56 -0
  333. edsl/utilities/SystemInfo.py +5 -0
  334. edsl/utilities/__init__.py +21 -20
  335. edsl/utilities/ast_utilities.py +3 -0
  336. edsl/utilities/data/Registry.py +2 -0
  337. edsl/utilities/decorators.py +41 -0
  338. edsl/utilities/gcp_bucket/__init__.py +0 -0
  339. edsl/utilities/gcp_bucket/cloud_storage.py +96 -0
  340. edsl/utilities/interface.py +310 -60
  341. edsl/utilities/is_notebook.py +18 -0
  342. edsl/utilities/is_valid_variable_name.py +11 -0
  343. edsl/utilities/naming_utilities.py +263 -0
  344. edsl/utilities/remove_edsl_version.py +24 -0
  345. edsl/utilities/repair_functions.py +28 -0
  346. edsl/utilities/restricted_python.py +70 -0
  347. edsl/utilities/utilities.py +203 -13
  348. edsl-0.1.40.dist-info/METADATA +111 -0
  349. edsl-0.1.40.dist-info/RECORD +362 -0
  350. {edsl-0.1.14.dist-info → edsl-0.1.40.dist-info}/WHEEL +1 -1
  351. edsl/agents/AgentListExportMixin.py +0 -24
  352. edsl/coop/old.py +0 -31
  353. edsl/data/Database.py +0 -141
  354. edsl/data/crud.py +0 -121
  355. edsl/jobs/Interview.py +0 -417
  356. edsl/jobs/JobsRunner.py +0 -63
  357. edsl/jobs/JobsRunnerStatusMixin.py +0 -115
  358. edsl/jobs/base.py +0 -47
  359. edsl/jobs/buckets.py +0 -166
  360. edsl/jobs/runners/JobsRunnerDryRun.py +0 -19
  361. edsl/jobs/runners/JobsRunnerStreaming.py +0 -54
  362. edsl/jobs/task_management.py +0 -218
  363. edsl/jobs/token_tracking.py +0 -78
  364. edsl/language_models/DeepInfra.py +0 -69
  365. edsl/language_models/OpenAI.py +0 -98
  366. edsl/language_models/model_interfaces/GeminiPro.py +0 -66
  367. edsl/language_models/model_interfaces/LanguageModelOpenAIFour.py +0 -8
  368. edsl/language_models/model_interfaces/LanguageModelOpenAIThreeFiveTurbo.py +0 -8
  369. edsl/language_models/model_interfaces/LlamaTwo13B.py +0 -21
  370. edsl/language_models/model_interfaces/LlamaTwo70B.py +0 -21
  371. edsl/language_models/model_interfaces/Mixtral8x7B.py +0 -24
  372. edsl/language_models/registry.py +0 -81
  373. edsl/language_models/schemas.py +0 -15
  374. edsl/language_models/unused/ReplicateBase.py +0 -83
  375. edsl/prompts/QuestionInstructionsBase.py +0 -6
  376. edsl/prompts/library/agent_instructions.py +0 -29
  377. edsl/prompts/library/agent_persona.py +0 -17
  378. edsl/prompts/library/question_budget.py +0 -26
  379. edsl/prompts/library/question_checkbox.py +0 -32
  380. edsl/prompts/library/question_extract.py +0 -19
  381. edsl/prompts/library/question_freetext.py +0 -14
  382. edsl/prompts/library/question_linear_scale.py +0 -20
  383. edsl/prompts/library/question_list.py +0 -22
  384. edsl/prompts/library/question_multiple_choice.py +0 -44
  385. edsl/prompts/library/question_numerical.py +0 -31
  386. edsl/prompts/library/question_rank.py +0 -21
  387. edsl/prompts/prompt_config.py +0 -33
  388. edsl/prompts/registry.py +0 -185
  389. edsl/questions/Question.py +0 -240
  390. edsl/report/InputOutputDataTypes.py +0 -134
  391. edsl/report/RegressionMixin.py +0 -28
  392. edsl/report/ReportOutputs.py +0 -1228
  393. edsl/report/ResultsFetchMixin.py +0 -106
  394. edsl/report/ResultsOutputMixin.py +0 -14
  395. edsl/report/demo.ipynb +0 -645
  396. edsl/results/ResultsDBMixin.py +0 -184
  397. edsl/surveys/SurveyFlowVisualizationMixin.py +0 -92
  398. edsl/trackers/Tracker.py +0 -91
  399. edsl/trackers/TrackerAPI.py +0 -196
  400. edsl/trackers/TrackerTasks.py +0 -70
  401. edsl/utilities/pastebin.py +0 -141
  402. edsl-0.1.14.dist-info/METADATA +0 -69
  403. edsl-0.1.14.dist-info/RECORD +0 -141
  404. /edsl/{language_models/model_interfaces → inference_services}/__init__.py +0 -0
  405. /edsl/{report/__init__.py → jobs/runners/JobsRunnerStatusData.py} +0 -0
  406. /edsl/{trackers/__init__.py → language_models/ServiceDataSources.py} +0 -0
  407. {edsl-0.1.14.dist-info → edsl-0.1.40.dist-info}/LICENSE +0 -0
@@ -1,18 +1,50 @@
1
+ """A module for displaying data in various formats."""
2
+
1
3
  from html import escape
2
- from IPython.display import HTML
3
- from IPython.display import display as ipython_diplay
4
- from PIL import Image, ImageDraw, ImageFont
5
- from rich.console import Console
6
- from rich.table import Table
7
4
 
8
5
 
9
- def heartbeat_generator():
10
- while True:
11
- for c in "|/-\\":
12
- yield c
6
+ def create_image(console, image_filename):
7
+ """Create an image from the console output."""
8
+ font_size = 15
9
+ from PIL import Image, ImageDraw, ImageFont
10
+
11
+ text = console.export_text() # Get the console output as text.
12
+
13
+ # Create an image from the text
14
+ font_size = 15
15
+ font = ImageFont.load_default() # Use the default font to avoid file path issues.
16
+ # text_width, text_height = ImageDraw.Draw(
17
+ # Image.new("RGB", (100, 100))
18
+ # ).multiline_textsize(text, font=font)
19
+ text_width, text_height = get_multiline_textsize(text, font)
20
+ image = Image.new(
21
+ "RGB", (text_width + 20, text_height + 20), color=(255, 255, 255)
22
+ ) # Add some padding
23
+ d = ImageDraw.Draw(image)
24
+
25
+ # Draw text to image
26
+ d.multiline_text((10, 10), text, font=font, fill=(0, 0, 0))
27
+ # Save the image
28
+ image.save(image_filename)
29
+
30
+
31
+ def display_table(console, table, filename):
32
+ # from rich.console import Console
33
+ # from rich.table import Table
34
+ """Display the table using the rich library and save it to a file if a filename is provided."""
35
+ if filename is not None:
36
+ with open(filename, "w") as f:
37
+ with console.capture() as capture:
38
+ console.print(table)
39
+ f.write(capture.get())
40
+ create_image(console, filename + ".png")
41
+ else:
42
+ console.print(table)
13
43
 
14
44
 
15
45
  def gen_html_sandwich(html_inner, interactive=False):
46
+ """Wrap the inner HTML content in a header and footer to make a complete HTML document."""
47
+ return html_inner
16
48
  if interactive:
17
49
  html_header = """
18
50
  <html>
@@ -78,6 +110,7 @@ def gen_html_sandwich(html_inner, interactive=False):
78
110
 
79
111
 
80
112
  def view_html(html):
113
+ """Display HTML content in a web browser."""
81
114
  import tempfile
82
115
  import webbrowser
83
116
 
@@ -91,7 +124,8 @@ def view_html(html):
91
124
 
92
125
 
93
126
  def human_readable_labeler_creator():
94
- """Creates a function that maps thread ids to human-readable labels.
127
+ """Create a function that maps thread ids to human-readable labels.
128
+
95
129
  It is structured as a closure, so that the mapping is persistent.
96
130
  I.e., when the returned function is called, it will use the same
97
131
  dictionary to map thread ids to human-readable labels if it's seen that ID
@@ -111,7 +145,7 @@ def human_readable_labeler_creator():
111
145
 
112
146
 
113
147
  def get_multiline_textsize(text, font):
114
- # Split the text by lines
148
+ """Get the size of the text when it is drawn on an image."""
115
149
  lines = text.split("\n")
116
150
 
117
151
  # Initialize width and height
@@ -132,42 +166,30 @@ def get_multiline_textsize(text, font):
132
166
  return max_width, total_height
133
167
 
134
168
 
135
- def create_image(console, image_filename):
136
- font_size = 15
169
+ def print_results_long(results, max_rows=None):
170
+ from rich.console import Console
171
+ from rich.table import Table
137
172
 
138
- text = console.export_text() # Get the console output as text.
139
-
140
- # Create an image from the text
141
- font_size = 15
142
- font = ImageFont.load_default() # Use the default font to avoid file path issues.
143
- # text_width, text_height = ImageDraw.Draw(
144
- # Image.new("RGB", (100, 100))
145
- # ).multiline_textsize(text, font=font)
146
- text_width, text_height = get_multiline_textsize(text, font)
147
- image = Image.new(
148
- "RGB", (text_width + 20, text_height + 20), color=(255, 255, 255)
149
- ) # Add some padding
150
- d = ImageDraw.Draw(image)
151
-
152
- # Draw text to image
153
- d.multiline_text((10, 10), text, font=font, fill=(0, 0, 0))
154
- # Save the image
155
- image.save(image_filename)
156
-
157
-
158
- def display(console, table, filename):
159
- if filename is not None:
160
- with open(filename, "w") as f:
161
- with console.capture() as capture:
162
- console.print(table)
163
- f.write(capture.get())
164
- create_image(console, filename + ".png")
165
- else:
166
- console.print(table)
173
+ console = Console(record=True)
174
+ table = Table(show_header=True, header_style="bold magenta")
175
+ table.add_column("Result index", style="dim")
176
+ table.add_column("Key", style="dim")
177
+ table.add_column("Value", style="dim")
178
+ list_of_dicts = results.to_dicts()
179
+ num_rows = 0
180
+ for i, results_dict in enumerate(list_of_dicts):
181
+ for key, value in results_dict.items():
182
+ table.add_row(str(i), key, str(value))
183
+ num_rows += 1
184
+ if max_rows is not None and num_rows >= max_rows:
185
+ break
186
+ console.print(table)
167
187
 
168
188
 
169
189
  def print_dict_with_rich(d, key_name="Key", value_name="Value", filename=None):
170
- """
190
+ """Print a dictionary as a table using the rich library.
191
+
192
+ Example:
171
193
  >>> print_dict_with_rich({"a": 1, "b": 2, "c": 3})
172
194
  ┏━━━━━┳━━━━━━━┓
173
195
  ┃ Key ┃ Value ┃
@@ -177,19 +199,34 @@ def print_dict_with_rich(d, key_name="Key", value_name="Value", filename=None):
177
199
  │ c │ 3 │
178
200
  └─────┴───────┘
179
201
  """
202
+ from rich.console import Console
203
+ from rich.table import Table
204
+
180
205
  console = Console(record=True)
181
206
  table = Table(show_header=True, header_style="bold magenta")
182
207
  table.add_column(key_name, style="dim")
183
208
  table.add_column(value_name, style="dim")
184
209
  for key, value in d.items():
185
210
  table.add_row(key, str(value))
186
- display(console, table, filename)
211
+ console.print(table)
212
+ # display_table(console, table, filename)
187
213
 
188
214
 
189
215
  def print_dict_as_html_table(
190
- d, show=False, key_name="Key", value_name="Value", filename=None
216
+ d,
217
+ show=False,
218
+ key_name="Key",
219
+ value_name="Value",
220
+ filename=None,
191
221
  ):
192
- """ """
222
+ """Print a dictionary as an HTML table.
223
+
224
+ :param d: The dictionary to print.
225
+ :param show: Whether to display the HTML table in the browser.
226
+ :param key_name: The name of the key column.
227
+ :param value_name: The name of the value column.
228
+ :param filename: The name of the file to save the HTML table to.
229
+ """
193
230
  # Start the HTML table
194
231
  html_table = f'<table border="1">\n<tr><th>{escape(key_name)}</th><th>{escape(value_name)}</th></tr>\n'
195
232
 
@@ -216,9 +253,47 @@ def print_dict_as_html_table(
216
253
  return html_table
217
254
 
218
255
 
256
+ def print_scenario_list(data):
257
+ from rich.console import Console
258
+ from rich.table import Table
259
+
260
+ new_data = []
261
+ for obs in data:
262
+ try:
263
+ _ = obs.pop("edsl_version")
264
+ _ = obs.pop("edsl_class_name")
265
+ except KeyError as e:
266
+ # print(e)
267
+ pass
268
+ new_data.append(obs)
269
+
270
+ columns = list(new_data[0].keys())
271
+ console = Console(record=True)
272
+
273
+ # Create a table object
274
+ table = Table(show_header=True, header_style="bold magenta", show_lines=True)
275
+ for column in columns:
276
+ table.add_column(column, style="dim")
277
+
278
+ for obs in new_data:
279
+ row = [str(obs[key]) for key in columns]
280
+ table.add_row(*row)
281
+
282
+ console.print(table)
283
+
284
+
219
285
  def print_list_of_dicts_with_rich(data, filename=None, split_at_dot=True):
220
- # Initialize console object
286
+ raise Exception(
287
+ "print_list_of_dicts_with_rich is now called print_dataset_with_rich"
288
+ )
289
+
290
+
291
+ def print_dataset_with_rich(data, filename=None, split_at_dot=True):
292
+ """Initialize console object."""
221
293
  """
294
+ The list seems superfluous.
295
+ This prints a list of dictionaries as a table using the rich library.
296
+
222
297
  >>> data = [{"a": [1, 2, 3], "b": [4, 5, 6]}]
223
298
  >>> print_list_of_dicts_with_rich(data)
224
299
  ┏━━━┳━━━┓
@@ -231,6 +306,9 @@ def print_list_of_dicts_with_rich(data, filename=None, split_at_dot=True):
231
306
  │ 3 │ 6 │
232
307
  └───┴───┘
233
308
  """
309
+ from rich.console import Console
310
+ from rich.table import Table
311
+
234
312
  console = Console(record=True)
235
313
 
236
314
  # Create a table object
@@ -251,17 +329,119 @@ def print_list_of_dicts_with_rich(data, filename=None, split_at_dot=True):
251
329
  row = [str(d[key][i]) for d in data for key in d.keys()]
252
330
  table.add_row(*row)
253
331
 
254
- display(console, table, filename)
332
+ console.print(table)
333
+ # display_table(console, table, filename)
255
334
 
256
335
 
257
- def print_list_of_dicts_as_html_table(data, filename=None, interactive=False):
258
- # Start the HTML table
336
+ def create_latex_table_from_data(data, filename=None, split_at_dot=True):
337
+ """
338
+ This function takes a list of dictionaries and returns a LaTeX table as a string.
339
+ The table can either be printed or written to a file.
259
340
 
260
- """This prints a list of dictionaries as an HTML table.
261
- The columns are the keys.
262
- The rows are the values.
341
+ >>> data = [{"a": [1, 2, 3], "b": [4, 5, 6]}]
342
+ >>> print(create_latex_table_from_data(data))
343
+ \\begin{tabular}{|c|c|}
344
+ \\hline
345
+ a & b \\\\
346
+ \\hline
347
+ 1 & 4 \\\\
348
+ 2 & 5 \\\\
349
+ 3 & 6 \\\\
350
+ \\hline
351
+ \\end{tabular}
263
352
  """
264
- html_table = '<table id="myTable" class="display">\n'
353
+
354
+ def escape_latex(s):
355
+ replacements = [
356
+ ("_", r"\_"),
357
+ ("&", r"\&"),
358
+ ("%", r"\%"),
359
+ ("$", r"\$"),
360
+ ("#", r"\#"),
361
+ ("{", r"\{"),
362
+ ("}", r"\}"),
363
+ ("~", r"\textasciitilde{}"),
364
+ ("^", r"\textasciicircum{}"),
365
+ ("\\", r"\textbackslash{}"),
366
+ ]
367
+
368
+ for old, new in replacements:
369
+ s = s.replace(old, new)
370
+ return s
371
+
372
+ # Start the LaTeX table
373
+ latex_table = ["\\begin{tabular}{|" + "c|" * len(data[0]) + "}"]
374
+ latex_table.append("\\hline")
375
+
376
+ # Add the header row
377
+ headers = []
378
+ for key in data[0].keys():
379
+ if split_at_dot:
380
+ value = key.replace(".", "\n.")
381
+ else:
382
+ value = key
383
+ headers.append(escape_latex(value))
384
+ latex_table.append(" & ".join(headers) + " \\\\")
385
+ latex_table.append("\\hline")
386
+
387
+ # Determine the number of rows
388
+ num_rows = len(next(iter(data[0].values())))
389
+
390
+ # Debugging: Print the keys of the dictionaries
391
+ # print("Keys in data[0]:", list(data[0].keys()))
392
+
393
+ # Add the data rows
394
+ for i in range(num_rows):
395
+ row = []
396
+ for key in data[0].keys():
397
+ for d in data:
398
+ try:
399
+ row.append(escape_latex(str(d[key][i])))
400
+ except KeyError as e:
401
+ print(
402
+ f"KeyError: {e} - Key '{key}' not found in data dictionary. The keys are {list(d.keys())}"
403
+ )
404
+ raise
405
+ latex_table.append(" & ".join(row) + " \\\\")
406
+
407
+ latex_table.append("\\hline")
408
+ latex_table.append("\\end{tabular}")
409
+
410
+ # Join all parts into a single string
411
+ latex_table_str = "\n".join(latex_table)
412
+
413
+ # Write to file if filename is provided
414
+ if filename:
415
+ with open(filename, "w") as f:
416
+ f.write(latex_table_str)
417
+ print(f"Table written to {filename}")
418
+
419
+ return latex_table_str
420
+
421
+
422
+ def print_list_of_dicts_as_html_table(data, interactive=True):
423
+ """Print a list of dictionaries as an HTML table.
424
+
425
+ :param data: The list of dictionaries to print.
426
+ :param filename: The name of the file to save the HTML table to.
427
+ :param interactive: Whether to make the table interactive using DataTables.
428
+ """
429
+ style = """
430
+ <style>
431
+ table {
432
+ width: 100%;
433
+ border-collapse: collapse;
434
+ }
435
+ table, th, td {
436
+ border: 1px solid black;
437
+ }
438
+ th, td {
439
+ padding: 10px;
440
+ text-align: left;
441
+ }
442
+ </style>
443
+ """
444
+ html_table = style + '<table id="myTable" class="display">\n'
265
445
  html_table += " <thead>\n"
266
446
  # Add the header row
267
447
  headers = [key for d in data for key in d.keys()]
@@ -286,19 +466,47 @@ def print_list_of_dicts_as_html_table(data, filename=None, interactive=False):
286
466
  # Close the table
287
467
  html_table += "</tbody>\n"
288
468
  html_table += "</table>"
469
+ return gen_html_sandwich(html_table, interactive=interactive)
470
+
289
471
 
290
- html = gen_html_sandwich(html_table, interactive=interactive)
472
+ def print_list_of_dicts_as_markdown_table(data, filename=None):
473
+ """Print a list of dictionaries as a Markdown table.
474
+
475
+ :param data: The list of dictionaries to print.
476
+ :param filename: The name of the file to save the Markdown table to.
477
+ """
478
+ if not data:
479
+ print("No data provided")
480
+ return
481
+
482
+ # Gather all unique headers
483
+ # headers = list({key for d in data for key in d.keys()})
484
+ headers = []
485
+ for column in data:
486
+ headers.append(list(column.keys())[0])
487
+
488
+ markdown_table = "| " + " | ".join(headers) + " |\n"
489
+ markdown_table += "|-" + "-|-".join(["" for _ in headers]) + "-|\n"
490
+
491
+ num_rows = len(next(iter(data[0].values())))
492
+ for i in range(num_rows):
493
+ row = [str(d[key][i]) for d in data for key in d.keys()]
494
+ # table.add_row(*row)
495
+ markdown_table += "| " + " | ".join(row) + " |\n"
291
496
 
292
497
  # Output or save to file
293
498
  if filename:
294
499
  with open(filename, "w") as f:
295
- f.write(html)
500
+ f.write(markdown_table)
296
501
  else:
297
- # view_html(html)
298
- ipython_diplay(HTML(html))
502
+ print(markdown_table)
299
503
 
300
504
 
301
505
  def print_public_methods_with_doc(obj):
506
+ """Print the public methods of an object along with their docstrings."""
507
+ from rich.console import Console
508
+ from rich.table import Table
509
+
302
510
  console = Console()
303
511
  public_methods_with_docstrings = [
304
512
  (method, getattr(obj, method).__doc__)
@@ -314,8 +522,47 @@ def print_public_methods_with_doc(obj):
314
522
  console.print(f"\t{doc.strip()}", style="yellow")
315
523
 
316
524
 
317
- def print_table_with_rich(data, filename=None):
525
+ def print_tally_with_rich(data, filename=None):
526
+ """Print a tally of values in a list using the rich library.
527
+
528
+ Example:
529
+ >>> data = {'a':12, 'b':14, 'c':9}
530
+ >>> print_tally_with_rich(data)
531
+ ┏━━━━━━━┳━━━━━━━┓
532
+ ┃ Value ┃ Count ┃
533
+ ┡━━━━━━━╇━━━━━━━┩
534
+ │ a │ 12 │
535
+ │ b │ 14 │
536
+ │ c │ 9 │
537
+ └───────┴───────┘
318
538
  """
539
+ # Initialize a console object
540
+ from rich.console import Console
541
+ from rich.table import Table
542
+ from IPython.display import display
543
+
544
+ console = Console(record=True)
545
+
546
+ # Create a new table
547
+ table = Table(show_header=True, header_style="bold magenta", row_styles=["", "dim"])
548
+
549
+ # Add columns to the table
550
+ table.add_column("Value", style="dim")
551
+ table.add_column("Count", style="dim")
552
+
553
+ # Add rows to the table
554
+ for key, value in data.items():
555
+ table.add_row(key, str(value))
556
+
557
+ from IPython.display import display
558
+
559
+ display_table(console, table, filename)
560
+
561
+
562
+ def print_table_with_rich(data, filename=None):
563
+ """Print a list of dictionaries as a table using the rich library.
564
+
565
+ Example:
319
566
  >>> data = [{"a": 1, "b": 2, "c": 3}]
320
567
  >>> print_table_with_rich(data)
321
568
  ┏━━━┳━━━┳━━━┓
@@ -332,6 +579,9 @@ def print_table_with_rich(data, filename=None):
332
579
  │ 2 │ 9 │ 8 │
333
580
  └───┴───┴───┘
334
581
  """
582
+ from rich.console import Console
583
+ from rich.table import Table
584
+
335
585
  # Initialize a console object - expects a list of dictionaries
336
586
  console = Console(record=True)
337
587
 
@@ -351,7 +601,7 @@ def print_table_with_rich(data, filename=None):
351
601
  for row in data:
352
602
  table.add_row(*[str(value) for value in row.values()])
353
603
 
354
- display(console, table, filename)
604
+ display_table(console, table, filename)
355
605
 
356
606
 
357
607
  if __name__ == "__main__":
@@ -0,0 +1,18 @@
1
+ def is_notebook() -> bool:
2
+ """Check if the code is running in a Jupyter notebook or Google Colab."""
3
+ try:
4
+ shell = get_ipython().__class__.__name__
5
+ if shell == "ZMQInteractiveShell":
6
+ return True # Jupyter notebook or qtconsole
7
+ elif shell == "Shell": # Google Colab's shell class
8
+ import sys
9
+
10
+ if "google.colab" in sys.modules:
11
+ return True # Running in Google Colab
12
+ return False
13
+ elif shell == "TerminalInteractiveShell":
14
+ return False # Terminal running IPython
15
+ else:
16
+ return False # Other type
17
+ except NameError:
18
+ return False # Probably standard Python interpreter
@@ -0,0 +1,11 @@
1
+ import keyword
2
+
3
+
4
+ def is_valid_variable_name(name, allow_name=True):
5
+ """Check if a string is a valid variable name."""
6
+ if allow_name:
7
+ return name.isidentifier() and not keyword.iskeyword(name)
8
+ else:
9
+ return (
10
+ name.isidentifier() and not keyword.iskeyword(name) and not name == "name"
11
+ )