edsl 0.1.39.dev2__py3-none-any.whl → 0.1.39.dev3__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 (334) hide show
  1. edsl/Base.py +332 -385
  2. edsl/BaseDiff.py +260 -260
  3. edsl/TemplateLoader.py +24 -24
  4. edsl/__init__.py +49 -57
  5. edsl/__version__.py +1 -1
  6. edsl/agents/Agent.py +867 -1079
  7. edsl/agents/AgentList.py +413 -551
  8. edsl/agents/Invigilator.py +233 -285
  9. edsl/agents/InvigilatorBase.py +270 -254
  10. edsl/agents/PromptConstructor.py +354 -252
  11. edsl/agents/__init__.py +3 -2
  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 -177
  27. edsl/conversation/Conversation.py +290 -290
  28. edsl/conversation/car_buying.py +58 -59
  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 -1090
  35. edsl/coop/utils.py +131 -131
  36. edsl/data/Cache.py +555 -562
  37. edsl/data/CacheEntry.py +233 -230
  38. edsl/data/CacheHandler.py +149 -170
  39. edsl/data/RemoteCacheSync.py +78 -78
  40. edsl/data/SQLiteDict.py +292 -292
  41. edsl/data/__init__.py +4 -5
  42. edsl/data/orm.py +10 -10
  43. edsl/data_transfer_models.py +73 -74
  44. edsl/enums.py +175 -195
  45. edsl/exceptions/BaseException.py +21 -21
  46. edsl/exceptions/__init__.py +54 -54
  47. edsl/exceptions/agents.py +42 -54
  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 -109
  57. edsl/exceptions/results.py +29 -29
  58. edsl/exceptions/scenarios.py +22 -29
  59. edsl/exceptions/surveys.py +37 -37
  60. edsl/inference_services/AnthropicService.py +87 -84
  61. edsl/inference_services/AwsBedrock.py +120 -118
  62. edsl/inference_services/AzureAI.py +217 -215
  63. edsl/inference_services/DeepInfraService.py +18 -18
  64. edsl/inference_services/GoogleService.py +148 -139
  65. edsl/inference_services/GroqService.py +20 -20
  66. edsl/inference_services/InferenceServiceABC.py +147 -80
  67. edsl/inference_services/InferenceServicesCollection.py +97 -122
  68. edsl/inference_services/MistralAIService.py +123 -120
  69. edsl/inference_services/OllamaService.py +18 -18
  70. edsl/inference_services/OpenAIService.py +224 -221
  71. edsl/inference_services/PerplexityService.py +163 -160
  72. edsl/inference_services/TestService.py +89 -92
  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 -41
  77. edsl/inference_services/write_available.py +10 -10
  78. edsl/jobs/Answers.py +56 -43
  79. edsl/jobs/Jobs.py +898 -757
  80. edsl/jobs/JobsChecks.py +147 -172
  81. edsl/jobs/JobsPrompts.py +268 -270
  82. edsl/jobs/JobsRemoteInferenceHandler.py +239 -287
  83. edsl/jobs/__init__.py +1 -1
  84. edsl/jobs/buckets/BucketCollection.py +63 -104
  85. edsl/jobs/buckets/ModelBuckets.py +65 -65
  86. edsl/jobs/buckets/TokenBucket.py +251 -283
  87. edsl/jobs/interviews/Interview.py +661 -358
  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 -421
  97. edsl/jobs/runners/JobsRunnerStatus.py +330 -330
  98. edsl/jobs/tasks/QuestionTaskCreator.py +242 -244
  99. edsl/jobs/tasks/TaskCreators.py +64 -64
  100. edsl/jobs/tasks/TaskHistory.py +450 -449
  101. edsl/jobs/tasks/TaskStatusLog.py +23 -23
  102. edsl/jobs/tasks/task_status_enum.py +163 -161
  103. edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
  104. edsl/jobs/tokens/TokenUsage.py +34 -34
  105. edsl/language_models/KeyLookup.py +30 -0
  106. edsl/language_models/LanguageModel.py +668 -571
  107. edsl/language_models/ModelList.py +155 -153
  108. edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
  109. edsl/language_models/__init__.py +3 -2
  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 -180
  113. edsl/language_models/repair.py +156 -156
  114. edsl/language_models/unused/ReplicateBase.py +83 -0
  115. edsl/language_models/utilities.py +64 -65
  116. edsl/notebooks/Notebook.py +258 -263
  117. edsl/notebooks/__init__.py +1 -1
  118. edsl/prompts/Prompt.py +362 -352
  119. edsl/prompts/__init__.py +2 -2
  120. edsl/questions/AnswerValidatorMixin.py +289 -334
  121. edsl/questions/QuestionBase.py +664 -509
  122. edsl/questions/QuestionBaseGenMixin.py +161 -165
  123. edsl/questions/QuestionBasePromptsMixin.py +217 -221
  124. edsl/questions/QuestionBudget.py +227 -227
  125. edsl/questions/QuestionCheckBox.py +359 -359
  126. edsl/questions/QuestionExtract.py +182 -182
  127. edsl/questions/QuestionFreeText.py +114 -113
  128. edsl/questions/QuestionFunctional.py +166 -166
  129. edsl/questions/QuestionList.py +231 -229
  130. edsl/questions/QuestionMultipleChoice.py +286 -330
  131. edsl/questions/QuestionNumerical.py +153 -151
  132. edsl/questions/QuestionRank.py +324 -314
  133. edsl/questions/Quick.py +41 -41
  134. edsl/questions/RegisterQuestionsMeta.py +71 -71
  135. edsl/questions/ResponseValidatorABC.py +174 -200
  136. edsl/questions/SimpleAskMixin.py +73 -74
  137. edsl/questions/__init__.py +26 -27
  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 -90
  142. edsl/questions/derived/QuestionTopK.py +93 -93
  143. edsl/questions/derived/QuestionYesNo.py +82 -82
  144. edsl/questions/descriptors.py +413 -427
  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 -177
  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 -108
  177. edsl/results/Dataset.py +424 -587
  178. edsl/results/DatasetExportMixin.py +731 -653
  179. edsl/results/DatasetTree.py +275 -295
  180. edsl/results/Result.py +465 -451
  181. edsl/results/Results.py +1165 -1172
  182. edsl/results/ResultsDBMixin.py +238 -0
  183. edsl/results/ResultsExportMixin.py +43 -45
  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 -145
  188. edsl/results/TableDisplay.py +198 -125
  189. edsl/results/__init__.py +2 -2
  190. edsl/results/table_display.css +77 -77
  191. edsl/results/tree_explore.py +115 -115
  192. edsl/scenarios/FileStore.py +632 -511
  193. edsl/scenarios/Scenario.py +601 -498
  194. edsl/scenarios/ScenarioHtmlMixin.py +64 -65
  195. edsl/scenarios/ScenarioJoin.py +127 -131
  196. edsl/scenarios/ScenarioList.py +1287 -1430
  197. edsl/scenarios/ScenarioListExportMixin.py +52 -45
  198. edsl/scenarios/ScenarioListPdfMixin.py +261 -239
  199. edsl/scenarios/__init__.py +4 -3
  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 -521
  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 -327
  210. edsl/surveys/RuleCollection.py +387 -385
  211. edsl/surveys/Survey.py +1801 -1229
  212. edsl/surveys/SurveyCSS.py +261 -273
  213. edsl/surveys/SurveyExportMixin.py +259 -259
  214. edsl/surveys/{SurveyFlowVisualization.py → SurveyFlowVisualizationMixin.py} +179 -181
  215. edsl/surveys/SurveyQualtricsImport.py +284 -284
  216. edsl/surveys/__init__.py +3 -5
  217. edsl/surveys/base.py +53 -53
  218. edsl/surveys/descriptors.py +56 -60
  219. edsl/surveys/instructions/ChangeInstruction.py +49 -48
  220. edsl/surveys/instructions/Instruction.py +65 -56
  221. edsl/surveys/instructions/InstructionCollection.py +77 -82
  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 -19
  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 -436
  252. {edsl-0.1.39.dev2.dist-info → edsl-0.1.39.dev3.dist-info}/LICENSE +21 -21
  253. {edsl-0.1.39.dev2.dist-info → edsl-0.1.39.dev3.dist-info}/METADATA +10 -12
  254. edsl-0.1.39.dev3.dist-info/RECORD +277 -0
  255. edsl/agents/QuestionInstructionPromptBuilder.py +0 -128
  256. edsl/agents/QuestionOptionProcessor.py +0 -172
  257. edsl/agents/QuestionTemplateReplacementsBuilder.py +0 -137
  258. edsl/coop/CoopFunctionsMixin.py +0 -15
  259. edsl/coop/ExpectedParrotKeyHandler.py +0 -125
  260. edsl/exceptions/inference_services.py +0 -5
  261. edsl/inference_services/AvailableModelCacheHandler.py +0 -184
  262. edsl/inference_services/AvailableModelFetcher.py +0 -209
  263. edsl/inference_services/ServiceAvailability.py +0 -135
  264. edsl/inference_services/data_structures.py +0 -62
  265. edsl/jobs/AnswerQuestionFunctionConstructor.py +0 -188
  266. edsl/jobs/FetchInvigilator.py +0 -40
  267. edsl/jobs/InterviewTaskManager.py +0 -98
  268. edsl/jobs/InterviewsConstructor.py +0 -48
  269. edsl/jobs/JobsComponentConstructor.py +0 -189
  270. edsl/jobs/JobsRemoteInferenceLogger.py +0 -239
  271. edsl/jobs/RequestTokenEstimator.py +0 -30
  272. edsl/jobs/buckets/TokenBucketAPI.py +0 -211
  273. edsl/jobs/buckets/TokenBucketClient.py +0 -191
  274. edsl/jobs/decorators.py +0 -35
  275. edsl/jobs/jobs_status_enums.py +0 -9
  276. edsl/jobs/loggers/HTMLTableJobLogger.py +0 -304
  277. edsl/language_models/ComputeCost.py +0 -63
  278. edsl/language_models/PriceManager.py +0 -127
  279. edsl/language_models/RawResponseHandler.py +0 -106
  280. edsl/language_models/ServiceDataSources.py +0 -0
  281. edsl/language_models/key_management/KeyLookup.py +0 -63
  282. edsl/language_models/key_management/KeyLookupBuilder.py +0 -273
  283. edsl/language_models/key_management/KeyLookupCollection.py +0 -38
  284. edsl/language_models/key_management/__init__.py +0 -0
  285. edsl/language_models/key_management/models.py +0 -131
  286. edsl/notebooks/NotebookToLaTeX.py +0 -142
  287. edsl/questions/ExceptionExplainer.py +0 -77
  288. edsl/questions/HTMLQuestion.py +0 -103
  289. edsl/questions/LoopProcessor.py +0 -149
  290. edsl/questions/QuestionMatrix.py +0 -265
  291. edsl/questions/ResponseValidatorFactory.py +0 -28
  292. edsl/questions/templates/matrix/__init__.py +0 -1
  293. edsl/questions/templates/matrix/answering_instructions.jinja +0 -5
  294. edsl/questions/templates/matrix/question_presentation.jinja +0 -20
  295. edsl/results/MarkdownToDocx.py +0 -122
  296. edsl/results/MarkdownToPDF.py +0 -111
  297. edsl/results/TextEditor.py +0 -50
  298. edsl/results/smart_objects.py +0 -96
  299. edsl/results/table_data_class.py +0 -12
  300. edsl/results/table_renderers.py +0 -118
  301. edsl/scenarios/ConstructDownloadLink.py +0 -109
  302. edsl/scenarios/DirectoryScanner.py +0 -96
  303. edsl/scenarios/DocumentChunker.py +0 -102
  304. edsl/scenarios/DocxScenario.py +0 -16
  305. edsl/scenarios/PdfExtractor.py +0 -40
  306. edsl/scenarios/ScenarioSelector.py +0 -156
  307. edsl/scenarios/file_methods.py +0 -85
  308. edsl/scenarios/handlers/__init__.py +0 -13
  309. edsl/scenarios/handlers/csv.py +0 -38
  310. edsl/scenarios/handlers/docx.py +0 -76
  311. edsl/scenarios/handlers/html.py +0 -37
  312. edsl/scenarios/handlers/json.py +0 -111
  313. edsl/scenarios/handlers/latex.py +0 -5
  314. edsl/scenarios/handlers/md.py +0 -51
  315. edsl/scenarios/handlers/pdf.py +0 -68
  316. edsl/scenarios/handlers/png.py +0 -39
  317. edsl/scenarios/handlers/pptx.py +0 -105
  318. edsl/scenarios/handlers/py.py +0 -294
  319. edsl/scenarios/handlers/sql.py +0 -313
  320. edsl/scenarios/handlers/sqlite.py +0 -149
  321. edsl/scenarios/handlers/txt.py +0 -33
  322. edsl/surveys/ConstructDAG.py +0 -92
  323. edsl/surveys/EditSurvey.py +0 -221
  324. edsl/surveys/InstructionHandler.py +0 -100
  325. edsl/surveys/MemoryManagement.py +0 -72
  326. edsl/surveys/RuleManager.py +0 -172
  327. edsl/surveys/Simulator.py +0 -75
  328. edsl/surveys/SurveyToApp.py +0 -141
  329. edsl/utilities/PrettyList.py +0 -56
  330. edsl/utilities/is_notebook.py +0 -18
  331. edsl/utilities/is_valid_variable_name.py +0 -11
  332. edsl/utilities/remove_edsl_version.py +0 -24
  333. edsl-0.1.39.dev2.dist-info/RECORD +0 -352
  334. {edsl-0.1.39.dev2.dist-info → edsl-0.1.39.dev3.dist-info}/WHEEL +0 -0
@@ -1,68 +0,0 @@
1
- import os
2
- import base64
3
-
4
- from edsl.scenarios.file_methods import FileMethods
5
-
6
-
7
- class PdfMethods(FileMethods):
8
- suffix = "pdf"
9
-
10
- def extract_text(self):
11
- from PyPDF2 import PdfReader
12
-
13
- # Create a PDF reader object
14
- reader = PdfReader(self.path)
15
-
16
- # Get number of pages
17
- num_pages = len(reader.pages)
18
-
19
- # Extract text from all pages
20
- text = ""
21
- for page_num in range(num_pages):
22
- # Get the page object
23
- page = reader.pages[page_num]
24
- # Extract text from page
25
- text += page.extract_text()
26
-
27
- return text
28
-
29
- def view_system(self):
30
- import os
31
- import subprocess
32
-
33
- if os.path.exists(self.path):
34
- try:
35
- if (os_name := os.name) == "posix":
36
- subprocess.run(["open", self.path], check=True) # macOS
37
- elif os_name == "nt":
38
- os.startfile(self.path) # Windows
39
- else:
40
- subprocess.run(["xdg-open", self.path], check=True) # Linux
41
- except Exception as e:
42
- print(f"Error opening PDF: {e}")
43
- else:
44
- print("PDF file was not found.")
45
-
46
- def view_notebook(self):
47
- from IPython.display import HTML, display
48
-
49
- with open(self.path, "rb") as f:
50
- base64_pdf = base64.b64encode(f.read()).decode("utf-8")
51
-
52
- html = f"""
53
- <iframe
54
- src="data:application/pdf;base64,{base64_pdf}"
55
- width="800px"
56
- height="800px"
57
- type="application/pdf"
58
- ></iframe>
59
- """
60
- display(HTML(html))
61
- return
62
-
63
- def example(self):
64
- from edsl.results.Results import Results
65
-
66
- return (
67
- Results.example().select("answer.how_feeling").first().pdf().to_tempfile()
68
- )
@@ -1,39 +0,0 @@
1
- import tempfile
2
- from edsl.scenarios.file_methods import FileMethods
3
-
4
-
5
- class PngMethods(FileMethods):
6
- suffix = "png"
7
-
8
- def view_system(self):
9
- import os
10
- import subprocess
11
-
12
- if os.path.exists(self.path):
13
- try:
14
- if (os_name := os.name) == "posix":
15
- subprocess.run(["open", self.path], check=True) # macOS
16
- elif os_name == "nt":
17
- os.startfile(self.path) # Windows
18
- else:
19
- subprocess.run(["xdg-open", self.path], check=True) # Linux
20
- except Exception as e:
21
- print(f"Error opening PNG: {e}")
22
- else:
23
- print("PNG file was not found.")
24
-
25
- def view_notebook(self):
26
- from IPython.display import Image, display
27
-
28
- display(Image(filename=self.path))
29
-
30
- def example(self):
31
- import matplotlib.pyplot as plt
32
- import numpy as np
33
-
34
- x = np.linspace(0, 10, 100)
35
- y = np.sin(x)
36
- plt.plot(x, y)
37
- with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as f:
38
- plt.savefig(f.name)
39
- return f.name
@@ -1,105 +0,0 @@
1
- from edsl.scenarios.file_methods import FileMethods
2
- import os
3
- import tempfile
4
-
5
-
6
- class PptxMethods(FileMethods):
7
- suffix = "pptx"
8
-
9
- def extract_text(self):
10
- from pptx import Presentation
11
-
12
- self.ppt = Presentation(self.path)
13
-
14
- # Extract all text from slides
15
- full_text = []
16
- for slide in self.ppt.slides:
17
- slide_text = []
18
- for shape in slide.shapes:
19
- if hasattr(shape, "text"):
20
- slide_text.append(shape.text)
21
- full_text.append("\n".join(slide_text))
22
-
23
- text = "\n\n".join(full_text)
24
- return text
25
-
26
- def view_system(self):
27
- import os
28
- import subprocess
29
-
30
- if os.path.exists(self.path):
31
- try:
32
- if (os_name := os.name) == "posix":
33
- subprocess.run(["open", self.path], check=True) # macOS
34
- elif os_name == "nt":
35
- os.startfile(self.path) # Windows
36
- else:
37
- subprocess.run(["xdg-open", self.path], check=True) # Linux
38
- except Exception as e:
39
- print(f"Error opening PPTX: {e}")
40
- else:
41
- print("PPTX file was not found.")
42
-
43
- def view_notebook(self):
44
- from pptx import Presentation
45
- from IPython.display import HTML, display
46
-
47
- prs = Presentation(self.path)
48
-
49
- # Create a simple HTML representation of the slides
50
- html_content = []
51
- for i, slide in enumerate(prs.slides, 1):
52
- slide_content = []
53
- for shape in slide.shapes:
54
- if hasattr(shape, "text"):
55
- slide_content.append(f"<p>{shape.text}</p>")
56
-
57
- html_content.append(
58
- f"""
59
- <div style='border: 1px solid #ccc; margin: 10px; padding: 10px;'>
60
- <h3>Slide {i}</h3>
61
- {''.join(slide_content)}
62
- </div>
63
- """
64
- )
65
-
66
- html = f"""
67
- <div style="width: 800px; height: 800px; padding: 20px;
68
- border: 1px solid #ccc; overflow-y: auto;">
69
- {''.join(html_content)}
70
- </div>
71
- """
72
- display(HTML(html))
73
-
74
- def example(self):
75
- from pptx import Presentation
76
- from edsl.scenarios.Scenario import Scenario
77
- from edsl.scenarios.ScenarioList import ScenarioList
78
-
79
- os.makedirs("test_dir", exist_ok=True)
80
-
81
- # Create first presentation
82
- ppt1 = Presentation()
83
- slide = ppt1.slides.add_slide(ppt1.slide_layouts[0])
84
- title = slide.shapes.title
85
- title.text = "First Presentation"
86
- ppt1.save("test_dir/test1.pptx")
87
-
88
- # Create second presentation
89
- ppt2 = Presentation()
90
- slide = ppt2.slides.add_slide(ppt2.slide_layouts[0])
91
- title = slide.shapes.title
92
- title.text = "Second Presentation"
93
-
94
- with tempfile.NamedTemporaryFile(delete=False, suffix=".pptx") as tmp:
95
- ppt2.save(tmp.name)
96
- tmp.close()
97
-
98
- return tmp.name
99
-
100
-
101
- if __name__ == "__main__":
102
- pptx_temp = PptxMethods.example()
103
- from edsl.scenarios.FileStore import FileStore
104
-
105
- fs = FileStore(pptx_temp)
@@ -1,294 +0,0 @@
1
- from edsl.scenarios.file_methods import FileMethods
2
- import tempfile
3
- import re
4
- from typing import List, Optional, Dict
5
- import ast
6
- import black
7
- import textwrap
8
- import subprocess
9
- import sys
10
- from importlib import util
11
-
12
-
13
- class PyMethods(FileMethods):
14
- suffix = "py"
15
-
16
- def view_system(self):
17
- """Open the Python file in the system's default editor."""
18
- import os
19
- import subprocess
20
-
21
- if os.path.exists(self.path):
22
- try:
23
- if (os_name := os.name) == "posix":
24
- subprocess.run(["open", self.path], check=True) # macOS
25
- elif os_name == "nt":
26
- os.startfile(self.path) # Windows
27
- else:
28
- subprocess.run(["xdg-open", self.path], check=True) # Linux
29
- except Exception as e:
30
- print(f"Error opening Python file: {e}")
31
- else:
32
- print("Python file was not found.")
33
-
34
- def view_notebook(self):
35
- """Display the Python file with syntax highlighting in a notebook."""
36
- from IPython.display import FileLink, display, HTML
37
- import pygments
38
- from pygments.lexers import PythonLexer
39
- from pygments.formatters import HtmlFormatter
40
- from pygments.styles import get_style_by_name
41
-
42
- try:
43
- with open(self.path, "r", encoding="utf-8") as f:
44
- content = f.read()
45
-
46
- # Create custom CSS for better visibility in both light and dark themes
47
- custom_css = """
48
- .highlight {
49
- background: var(--jp-cell-editor-background, #f7f7f7);
50
- border: 1px solid var(--jp-border-color2, #ddd);
51
- border-radius: 3px;
52
- padding: 1em;
53
- margin: 1em 0;
54
- }
55
- .highlight pre {
56
- margin: 0;
57
- color: var(--jp-content-font-color0, #000);
58
- background: transparent;
59
- }
60
- .highlight .hll { background-color: var(--jp-cell-editor-active-background, #ffffcc) }
61
- .highlight .c { color: #408080; font-style: italic } /* Comment */
62
- .highlight .k { color: #008000; font-weight: bold } /* Keyword */
63
- .highlight .o { color: #666666 } /* Operator */
64
- .highlight .s { color: #BA2121 } /* String */
65
- .highlight .n { color: var(--jp-content-font-color0, #000) } /* Name */
66
- .highlight .p { color: var(--jp-content-font-color0, #000) } /* Punctuation */
67
- """
68
-
69
- formatter = HtmlFormatter(style="default")
70
- highlighted_python = pygments.highlight(content, PythonLexer(), formatter)
71
-
72
- # Combine the custom CSS with basic formatter CSS
73
- css = formatter.get_style_defs(".highlight") + custom_css
74
-
75
- display(HTML(f"<style>{css}</style>{highlighted_python}"))
76
- display(FileLink(self.path))
77
- except Exception as e:
78
- print(f"Error displaying Python: {e}")
79
-
80
- def format_python(self) -> bool:
81
- """Format the Python file using black."""
82
- try:
83
- with open(self.path, "r", encoding="utf-8") as f:
84
- content = f.read()
85
-
86
- # Format using black
87
- formatted_content = black.format_str(content, mode=black.FileMode())
88
-
89
- with open(self.path, "w", encoding="utf-8") as f:
90
- f.write(formatted_content)
91
-
92
- return True
93
- except Exception as e:
94
- print(f"Error formatting Python: {e}")
95
- return False
96
-
97
- def validate_syntax(self) -> bool:
98
- """Validate Python syntax using ast.parse."""
99
- try:
100
- with open(self.path, "r", encoding="utf-8") as f:
101
- content = f.read()
102
-
103
- ast.parse(content)
104
- return True
105
- except SyntaxError as e:
106
- print(f"Syntax error in Python file: {e}")
107
- return False
108
- except Exception as e:
109
- print(f"Error validating Python: {e}")
110
- return False
111
-
112
- def extract_imports(self) -> List[str]:
113
- """Extract all import statements from the Python file."""
114
- imports = []
115
- try:
116
- with open(self.path, "r", encoding="utf-8") as f:
117
- content = f.read()
118
-
119
- tree = ast.parse(content)
120
- for node in ast.walk(tree):
121
- if isinstance(node, ast.Import):
122
- for name in node.names:
123
- imports.append(name.name)
124
- elif isinstance(node, ast.ImportFrom):
125
- module = node.module or ""
126
- for name in node.names:
127
- imports.append(f"{module}.{name.name}")
128
-
129
- return sorted(list(set(imports)))
130
- except Exception as e:
131
- print(f"Error extracting imports: {e}")
132
- return []
133
-
134
- def extract_functions(self) -> List[str]:
135
- """Extract all function names from the Python file."""
136
- functions = []
137
- try:
138
- with open(self.path, "r", encoding="utf-8") as f:
139
- content = f.read()
140
-
141
- tree = ast.parse(content)
142
- for node in ast.walk(tree):
143
- if isinstance(node, ast.FunctionDef):
144
- functions.append(node.name)
145
-
146
- return sorted(functions)
147
- except Exception as e:
148
- print(f"Error extracting functions: {e}")
149
- return []
150
-
151
- def extract_classes(self) -> List[str]:
152
- """Extract all class names from the Python file."""
153
- classes = []
154
- try:
155
- with open(self.path, "r", encoding="utf-8") as f:
156
- content = f.read()
157
-
158
- tree = ast.parse(content)
159
- for node in ast.walk(tree):
160
- if isinstance(node, ast.ClassDef):
161
- classes.append(node.name)
162
-
163
- return sorted(classes)
164
- except Exception as e:
165
- print(f"Error extracting classes: {e}")
166
- return []
167
-
168
- def get_docstrings(self) -> Dict[str, str]:
169
- """Extract docstrings for all functions and classes."""
170
- docstrings = {}
171
- try:
172
- with open(self.path, "r", encoding="utf-8") as f:
173
- content = f.read()
174
-
175
- tree = ast.parse(content)
176
- for node in ast.walk(tree):
177
- if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
178
- docstring = ast.get_docstring(node)
179
- if docstring:
180
- docstrings[node.name] = docstring
181
-
182
- return docstrings
183
- except Exception as e:
184
- print(f"Error extracting docstrings: {e}")
185
- return {}
186
-
187
- def run_file(self, args: List[str] = None) -> Optional[int]:
188
- """Run the Python file as a script with optional arguments."""
189
- try:
190
- cmd = [sys.executable, self.path]
191
- if args:
192
- cmd.extend(args)
193
-
194
- result = subprocess.run(cmd, capture_output=True, text=True)
195
- print(result.stdout)
196
- if result.stderr:
197
- print("Errors:", result.stderr, file=sys.stderr)
198
- return result.returncode
199
- except Exception as e:
200
- print(f"Error running Python file: {e}")
201
- return None
202
-
203
- def check_dependencies(self) -> List[str]:
204
- """Check if all imported modules are available."""
205
- missing_deps = []
206
- try:
207
- imports = self.extract_imports()
208
- for imp in imports:
209
- # Get the top-level module name
210
- top_module = imp.split(".")[0]
211
- if not util.find_spec(top_module):
212
- missing_deps.append(top_module)
213
- return missing_deps
214
- except Exception as e:
215
- print(f"Error checking dependencies: {e}")
216
- return []
217
-
218
- def example(self):
219
- """Create a sample Python file with common patterns."""
220
- sample_python = '''#!/usr/bin/env python3
221
- """Example Python module demonstrating common patterns."""
222
-
223
- import sys
224
- from typing import List, Optional
225
- from dataclasses import dataclass
226
-
227
-
228
- @dataclass
229
- class Employee:
230
- """Represents an employee in the system."""
231
- name: str
232
- department: str
233
- salary: float
234
- hire_date: str
235
-
236
-
237
- class EmployeeManager:
238
- """Manages employee operations."""
239
-
240
- def __init__(self):
241
- self.employees: List[Employee] = []
242
-
243
- def add_employee(self, employee: Employee) -> None:
244
- """Add a new employee to the system."""
245
- self.employees.append(employee)
246
-
247
- def get_department_stats(self, department: str) -> Optional[dict]:
248
- """Calculate statistics for a department."""
249
- dept_employees = [e for e in self.employees if e.department == department]
250
-
251
- if not dept_employees:
252
- return None
253
-
254
- return {
255
- 'count': len(dept_employees),
256
- 'avg_salary': sum(e.salary for e in dept_employees) / len(dept_employees)
257
- }
258
-
259
-
260
- def main(args: List[str]) -> int:
261
- """Main entry point for the script."""
262
- manager = EmployeeManager()
263
-
264
- # Add sample employees
265
- manager.add_employee(Employee(
266
- "John Doe",
267
- "Engineering",
268
- 75000.00,
269
- "2023-01-15"
270
- ))
271
-
272
- manager.add_employee(Employee(
273
- "Jane Smith",
274
- "Marketing",
275
- 65000.00,
276
- "2023-02-01"
277
- ))
278
-
279
- # Print department statistics
280
- stats = manager.get_department_stats("Engineering")
281
- if stats:
282
- print(f"Engineering department stats: {stats}")
283
-
284
- return 0
285
-
286
-
287
- if __name__ == "__main__":
288
- sys.exit(main(sys.argv[1:]))
289
- '''
290
- with tempfile.NamedTemporaryFile(
291
- delete=False, suffix=".py", mode="w", encoding="utf-8"
292
- ) as f:
293
- f.write(sample_python)
294
- return f.name