edsl 0.1.15__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.
- edsl/Base.py +348 -38
- edsl/BaseDiff.py +260 -0
- edsl/TemplateLoader.py +24 -0
- edsl/__init__.py +45 -10
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +842 -144
- edsl/agents/AgentList.py +521 -25
- edsl/agents/Invigilator.py +250 -374
- edsl/agents/InvigilatorBase.py +257 -0
- edsl/agents/PromptConstructor.py +272 -0
- edsl/agents/QuestionInstructionPromptBuilder.py +128 -0
- edsl/agents/QuestionTemplateReplacementsBuilder.py +137 -0
- edsl/agents/descriptors.py +43 -13
- edsl/agents/prompt_helpers.py +129 -0
- edsl/agents/question_option_processor.py +172 -0
- edsl/auto/AutoStudy.py +130 -0
- edsl/auto/StageBase.py +243 -0
- edsl/auto/StageGenerateSurvey.py +178 -0
- edsl/auto/StageLabelQuestions.py +125 -0
- edsl/auto/StagePersona.py +61 -0
- edsl/auto/StagePersonaDimensionValueRanges.py +88 -0
- edsl/auto/StagePersonaDimensionValues.py +74 -0
- edsl/auto/StagePersonaDimensions.py +69 -0
- edsl/auto/StageQuestions.py +74 -0
- edsl/auto/SurveyCreatorPipeline.py +21 -0
- edsl/auto/utilities.py +218 -0
- edsl/base/Base.py +279 -0
- edsl/config.py +115 -113
- edsl/conversation/Conversation.py +290 -0
- edsl/conversation/car_buying.py +59 -0
- edsl/conversation/chips.py +95 -0
- edsl/conversation/mug_negotiation.py +81 -0
- edsl/conversation/next_speaker_utilities.py +93 -0
- edsl/coop/CoopFunctionsMixin.py +15 -0
- edsl/coop/ExpectedParrotKeyHandler.py +125 -0
- edsl/coop/PriceFetcher.py +54 -0
- edsl/coop/__init__.py +1 -0
- edsl/coop/coop.py +1029 -134
- edsl/coop/utils.py +131 -0
- edsl/data/Cache.py +560 -89
- edsl/data/CacheEntry.py +230 -0
- edsl/data/CacheHandler.py +168 -0
- edsl/data/RemoteCacheSync.py +186 -0
- edsl/data/SQLiteDict.py +292 -0
- edsl/data/__init__.py +5 -3
- edsl/data/orm.py +6 -33
- edsl/data_transfer_models.py +74 -27
- edsl/enums.py +165 -8
- edsl/exceptions/BaseException.py +21 -0
- edsl/exceptions/__init__.py +52 -46
- edsl/exceptions/agents.py +33 -15
- edsl/exceptions/cache.py +5 -0
- edsl/exceptions/coop.py +8 -0
- edsl/exceptions/general.py +34 -0
- edsl/exceptions/inference_services.py +5 -0
- edsl/exceptions/jobs.py +15 -0
- edsl/exceptions/language_models.py +46 -1
- edsl/exceptions/questions.py +80 -5
- edsl/exceptions/results.py +16 -5
- edsl/exceptions/scenarios.py +29 -0
- edsl/exceptions/surveys.py +13 -10
- edsl/inference_services/AnthropicService.py +106 -0
- edsl/inference_services/AvailableModelCacheHandler.py +184 -0
- edsl/inference_services/AvailableModelFetcher.py +215 -0
- edsl/inference_services/AwsBedrock.py +118 -0
- edsl/inference_services/AzureAI.py +215 -0
- edsl/inference_services/DeepInfraService.py +18 -0
- edsl/inference_services/GoogleService.py +143 -0
- edsl/inference_services/GroqService.py +20 -0
- edsl/inference_services/InferenceServiceABC.py +80 -0
- edsl/inference_services/InferenceServicesCollection.py +138 -0
- edsl/inference_services/MistralAIService.py +120 -0
- edsl/inference_services/OllamaService.py +18 -0
- edsl/inference_services/OpenAIService.py +236 -0
- edsl/inference_services/PerplexityService.py +160 -0
- edsl/inference_services/ServiceAvailability.py +135 -0
- edsl/inference_services/TestService.py +90 -0
- edsl/inference_services/TogetherAIService.py +172 -0
- edsl/inference_services/data_structures.py +134 -0
- edsl/inference_services/models_available_cache.py +118 -0
- edsl/inference_services/rate_limits_cache.py +25 -0
- edsl/inference_services/registry.py +41 -0
- edsl/inference_services/write_available.py +10 -0
- edsl/jobs/AnswerQuestionFunctionConstructor.py +223 -0
- edsl/jobs/Answers.py +21 -20
- edsl/jobs/FetchInvigilator.py +47 -0
- edsl/jobs/InterviewTaskManager.py +98 -0
- edsl/jobs/InterviewsConstructor.py +50 -0
- edsl/jobs/Jobs.py +684 -206
- edsl/jobs/JobsChecks.py +172 -0
- edsl/jobs/JobsComponentConstructor.py +189 -0
- edsl/jobs/JobsPrompts.py +270 -0
- edsl/jobs/JobsRemoteInferenceHandler.py +311 -0
- edsl/jobs/JobsRemoteInferenceLogger.py +239 -0
- edsl/jobs/RequestTokenEstimator.py +30 -0
- edsl/jobs/async_interview_runner.py +138 -0
- edsl/jobs/buckets/BucketCollection.py +104 -0
- edsl/jobs/buckets/ModelBuckets.py +65 -0
- edsl/jobs/buckets/TokenBucket.py +283 -0
- edsl/jobs/buckets/TokenBucketAPI.py +211 -0
- edsl/jobs/buckets/TokenBucketClient.py +191 -0
- edsl/jobs/check_survey_scenario_compatibility.py +85 -0
- edsl/jobs/data_structures.py +120 -0
- edsl/jobs/decorators.py +35 -0
- edsl/jobs/interviews/Interview.py +392 -0
- edsl/jobs/interviews/InterviewExceptionCollection.py +99 -0
- edsl/jobs/interviews/InterviewExceptionEntry.py +186 -0
- edsl/jobs/interviews/InterviewStatistic.py +63 -0
- edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -0
- edsl/jobs/interviews/InterviewStatusDictionary.py +78 -0
- edsl/jobs/interviews/InterviewStatusLog.py +92 -0
- edsl/jobs/interviews/ReportErrors.py +66 -0
- edsl/jobs/interviews/interview_status_enum.py +9 -0
- edsl/jobs/jobs_status_enums.py +9 -0
- edsl/jobs/loggers/HTMLTableJobLogger.py +304 -0
- edsl/jobs/results_exceptions_handler.py +98 -0
- edsl/jobs/runners/JobsRunnerAsyncio.py +151 -110
- edsl/jobs/runners/JobsRunnerStatus.py +298 -0
- edsl/jobs/tasks/QuestionTaskCreator.py +244 -0
- edsl/jobs/tasks/TaskCreators.py +64 -0
- edsl/jobs/tasks/TaskHistory.py +470 -0
- edsl/jobs/tasks/TaskStatusLog.py +23 -0
- edsl/jobs/tasks/task_status_enum.py +161 -0
- edsl/jobs/tokens/InterviewTokenUsage.py +27 -0
- edsl/jobs/tokens/TokenUsage.py +34 -0
- edsl/language_models/ComputeCost.py +63 -0
- edsl/language_models/LanguageModel.py +507 -386
- edsl/language_models/ModelList.py +164 -0
- edsl/language_models/PriceManager.py +127 -0
- edsl/language_models/RawResponseHandler.py +106 -0
- edsl/language_models/RegisterLanguageModelsMeta.py +184 -0
- edsl/language_models/__init__.py +1 -8
- edsl/language_models/fake_openai_call.py +15 -0
- edsl/language_models/fake_openai_service.py +61 -0
- edsl/language_models/key_management/KeyLookup.py +63 -0
- edsl/language_models/key_management/KeyLookupBuilder.py +273 -0
- edsl/language_models/key_management/KeyLookupCollection.py +38 -0
- edsl/language_models/key_management/__init__.py +0 -0
- edsl/language_models/key_management/models.py +131 -0
- edsl/language_models/model.py +256 -0
- edsl/language_models/repair.py +109 -41
- edsl/language_models/utilities.py +65 -0
- edsl/notebooks/Notebook.py +263 -0
- edsl/notebooks/NotebookToLaTeX.py +142 -0
- edsl/notebooks/__init__.py +1 -0
- edsl/prompts/Prompt.py +222 -93
- edsl/prompts/__init__.py +1 -1
- edsl/questions/ExceptionExplainer.py +77 -0
- edsl/questions/HTMLQuestion.py +103 -0
- edsl/questions/QuestionBase.py +518 -0
- edsl/questions/QuestionBasePromptsMixin.py +221 -0
- edsl/questions/QuestionBudget.py +164 -67
- edsl/questions/QuestionCheckBox.py +281 -62
- edsl/questions/QuestionDict.py +343 -0
- edsl/questions/QuestionExtract.py +136 -50
- edsl/questions/QuestionFreeText.py +79 -55
- edsl/questions/QuestionFunctional.py +138 -41
- edsl/questions/QuestionList.py +184 -57
- edsl/questions/QuestionMatrix.py +265 -0
- edsl/questions/QuestionMultipleChoice.py +293 -69
- edsl/questions/QuestionNumerical.py +109 -56
- edsl/questions/QuestionRank.py +244 -49
- edsl/questions/Quick.py +41 -0
- edsl/questions/SimpleAskMixin.py +74 -0
- edsl/questions/__init__.py +9 -6
- edsl/questions/{AnswerValidatorMixin.py → answer_validator_mixin.py} +153 -38
- edsl/questions/compose_questions.py +13 -7
- edsl/questions/data_structures.py +20 -0
- edsl/questions/decorators.py +21 -0
- edsl/questions/derived/QuestionLikertFive.py +28 -26
- edsl/questions/derived/QuestionLinearScale.py +41 -28
- edsl/questions/derived/QuestionTopK.py +34 -26
- edsl/questions/derived/QuestionYesNo.py +40 -27
- edsl/questions/descriptors.py +228 -74
- edsl/questions/loop_processor.py +149 -0
- edsl/questions/prompt_templates/question_budget.jinja +13 -0
- edsl/questions/prompt_templates/question_checkbox.jinja +32 -0
- edsl/questions/prompt_templates/question_extract.jinja +11 -0
- edsl/questions/prompt_templates/question_free_text.jinja +3 -0
- edsl/questions/prompt_templates/question_linear_scale.jinja +11 -0
- edsl/questions/prompt_templates/question_list.jinja +17 -0
- edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -0
- edsl/questions/prompt_templates/question_numerical.jinja +37 -0
- edsl/questions/question_base_gen_mixin.py +168 -0
- edsl/questions/question_registry.py +130 -46
- edsl/questions/register_questions_meta.py +71 -0
- edsl/questions/response_validator_abc.py +188 -0
- edsl/questions/response_validator_factory.py +34 -0
- edsl/questions/settings.py +5 -2
- edsl/questions/templates/__init__.py +0 -0
- edsl/questions/templates/budget/__init__.py +0 -0
- edsl/questions/templates/budget/answering_instructions.jinja +7 -0
- edsl/questions/templates/budget/question_presentation.jinja +7 -0
- edsl/questions/templates/checkbox/__init__.py +0 -0
- edsl/questions/templates/checkbox/answering_instructions.jinja +10 -0
- edsl/questions/templates/checkbox/question_presentation.jinja +22 -0
- edsl/questions/templates/dict/__init__.py +0 -0
- edsl/questions/templates/dict/answering_instructions.jinja +21 -0
- edsl/questions/templates/dict/question_presentation.jinja +1 -0
- edsl/questions/templates/extract/__init__.py +0 -0
- edsl/questions/templates/extract/answering_instructions.jinja +7 -0
- edsl/questions/templates/extract/question_presentation.jinja +1 -0
- edsl/questions/templates/free_text/__init__.py +0 -0
- edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
- edsl/questions/templates/free_text/question_presentation.jinja +1 -0
- edsl/questions/templates/likert_five/__init__.py +0 -0
- edsl/questions/templates/likert_five/answering_instructions.jinja +10 -0
- edsl/questions/templates/likert_five/question_presentation.jinja +12 -0
- edsl/questions/templates/linear_scale/__init__.py +0 -0
- edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -0
- edsl/questions/templates/linear_scale/question_presentation.jinja +5 -0
- edsl/questions/templates/list/__init__.py +0 -0
- edsl/questions/templates/list/answering_instructions.jinja +4 -0
- edsl/questions/templates/list/question_presentation.jinja +5 -0
- edsl/questions/templates/matrix/__init__.py +1 -0
- edsl/questions/templates/matrix/answering_instructions.jinja +5 -0
- edsl/questions/templates/matrix/question_presentation.jinja +20 -0
- edsl/questions/templates/multiple_choice/__init__.py +0 -0
- edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -0
- edsl/questions/templates/multiple_choice/html.jinja +0 -0
- edsl/questions/templates/multiple_choice/question_presentation.jinja +12 -0
- edsl/questions/templates/numerical/__init__.py +0 -0
- edsl/questions/templates/numerical/answering_instructions.jinja +7 -0
- edsl/questions/templates/numerical/question_presentation.jinja +7 -0
- edsl/questions/templates/rank/__init__.py +0 -0
- edsl/questions/templates/rank/answering_instructions.jinja +11 -0
- edsl/questions/templates/rank/question_presentation.jinja +15 -0
- edsl/questions/templates/top_k/__init__.py +0 -0
- edsl/questions/templates/top_k/answering_instructions.jinja +8 -0
- edsl/questions/templates/top_k/question_presentation.jinja +22 -0
- edsl/questions/templates/yes_no/__init__.py +0 -0
- edsl/questions/templates/yes_no/answering_instructions.jinja +6 -0
- edsl/questions/templates/yes_no/question_presentation.jinja +12 -0
- edsl/results/CSSParameterizer.py +108 -0
- edsl/results/Dataset.py +550 -19
- edsl/results/DatasetExportMixin.py +594 -0
- edsl/results/DatasetTree.py +295 -0
- edsl/results/MarkdownToDocx.py +122 -0
- edsl/results/MarkdownToPDF.py +111 -0
- edsl/results/Result.py +477 -173
- edsl/results/Results.py +987 -269
- edsl/results/ResultsExportMixin.py +28 -125
- edsl/results/ResultsGGMixin.py +83 -15
- edsl/results/TableDisplay.py +125 -0
- edsl/results/TextEditor.py +50 -0
- edsl/results/__init__.py +1 -1
- edsl/results/file_exports.py +252 -0
- edsl/results/results_fetch_mixin.py +33 -0
- edsl/results/results_selector.py +145 -0
- edsl/results/results_tools_mixin.py +98 -0
- edsl/results/smart_objects.py +96 -0
- edsl/results/table_data_class.py +12 -0
- edsl/results/table_display.css +78 -0
- edsl/results/table_renderers.py +118 -0
- edsl/results/tree_explore.py +115 -0
- edsl/scenarios/ConstructDownloadLink.py +109 -0
- edsl/scenarios/DocumentChunker.py +102 -0
- edsl/scenarios/DocxScenario.py +16 -0
- edsl/scenarios/FileStore.py +543 -0
- edsl/scenarios/PdfExtractor.py +40 -0
- edsl/scenarios/Scenario.py +431 -62
- edsl/scenarios/ScenarioHtmlMixin.py +65 -0
- edsl/scenarios/ScenarioList.py +1415 -45
- edsl/scenarios/ScenarioListExportMixin.py +45 -0
- edsl/scenarios/ScenarioListPdfMixin.py +239 -0
- edsl/scenarios/__init__.py +2 -0
- edsl/scenarios/directory_scanner.py +96 -0
- edsl/scenarios/file_methods.py +85 -0
- edsl/scenarios/handlers/__init__.py +13 -0
- edsl/scenarios/handlers/csv.py +49 -0
- edsl/scenarios/handlers/docx.py +76 -0
- edsl/scenarios/handlers/html.py +37 -0
- edsl/scenarios/handlers/json.py +111 -0
- edsl/scenarios/handlers/latex.py +5 -0
- edsl/scenarios/handlers/md.py +51 -0
- edsl/scenarios/handlers/pdf.py +68 -0
- edsl/scenarios/handlers/png.py +39 -0
- edsl/scenarios/handlers/pptx.py +105 -0
- edsl/scenarios/handlers/py.py +294 -0
- edsl/scenarios/handlers/sql.py +313 -0
- edsl/scenarios/handlers/sqlite.py +149 -0
- edsl/scenarios/handlers/txt.py +33 -0
- edsl/scenarios/scenario_join.py +131 -0
- edsl/scenarios/scenario_selector.py +156 -0
- edsl/shared.py +1 -0
- edsl/study/ObjectEntry.py +173 -0
- edsl/study/ProofOfWork.py +113 -0
- edsl/study/SnapShot.py +80 -0
- edsl/study/Study.py +521 -0
- edsl/study/__init__.py +4 -0
- edsl/surveys/ConstructDAG.py +92 -0
- edsl/surveys/DAG.py +92 -11
- edsl/surveys/EditSurvey.py +221 -0
- edsl/surveys/InstructionHandler.py +100 -0
- edsl/surveys/Memory.py +9 -4
- edsl/surveys/MemoryManagement.py +72 -0
- edsl/surveys/MemoryPlan.py +156 -35
- edsl/surveys/Rule.py +221 -74
- edsl/surveys/RuleCollection.py +241 -61
- edsl/surveys/RuleManager.py +172 -0
- edsl/surveys/Simulator.py +75 -0
- edsl/surveys/Survey.py +1079 -339
- edsl/surveys/SurveyCSS.py +273 -0
- edsl/surveys/SurveyExportMixin.py +235 -40
- edsl/surveys/SurveyFlowVisualization.py +181 -0
- edsl/surveys/SurveyQualtricsImport.py +284 -0
- edsl/surveys/SurveyToApp.py +141 -0
- edsl/surveys/__init__.py +4 -2
- edsl/surveys/base.py +19 -3
- edsl/surveys/descriptors.py +17 -6
- edsl/surveys/instructions/ChangeInstruction.py +48 -0
- edsl/surveys/instructions/Instruction.py +56 -0
- edsl/surveys/instructions/InstructionCollection.py +82 -0
- edsl/surveys/instructions/__init__.py +0 -0
- edsl/templates/error_reporting/base.html +24 -0
- edsl/templates/error_reporting/exceptions_by_model.html +35 -0
- edsl/templates/error_reporting/exceptions_by_question_name.html +17 -0
- edsl/templates/error_reporting/exceptions_by_type.html +17 -0
- edsl/templates/error_reporting/interview_details.html +116 -0
- edsl/templates/error_reporting/interviews.html +19 -0
- edsl/templates/error_reporting/overview.html +5 -0
- edsl/templates/error_reporting/performance_plot.html +2 -0
- edsl/templates/error_reporting/report.css +74 -0
- edsl/templates/error_reporting/report.html +118 -0
- edsl/templates/error_reporting/report.js +25 -0
- edsl/tools/__init__.py +1 -0
- edsl/tools/clusters.py +192 -0
- edsl/tools/embeddings.py +27 -0
- edsl/tools/embeddings_plotting.py +118 -0
- edsl/tools/plotting.py +112 -0
- edsl/tools/summarize.py +18 -0
- edsl/utilities/PrettyList.py +56 -0
- edsl/utilities/SystemInfo.py +5 -0
- edsl/utilities/__init__.py +21 -20
- edsl/utilities/ast_utilities.py +3 -0
- edsl/utilities/data/Registry.py +2 -0
- edsl/utilities/decorators.py +41 -0
- edsl/utilities/gcp_bucket/__init__.py +0 -0
- edsl/utilities/gcp_bucket/cloud_storage.py +96 -0
- edsl/utilities/interface.py +310 -60
- edsl/utilities/is_notebook.py +18 -0
- edsl/utilities/is_valid_variable_name.py +11 -0
- edsl/utilities/naming_utilities.py +263 -0
- edsl/utilities/remove_edsl_version.py +24 -0
- edsl/utilities/repair_functions.py +28 -0
- edsl/utilities/restricted_python.py +70 -0
- edsl/utilities/utilities.py +203 -13
- edsl-0.1.40.dist-info/METADATA +111 -0
- edsl-0.1.40.dist-info/RECORD +362 -0
- {edsl-0.1.15.dist-info → edsl-0.1.40.dist-info}/WHEEL +1 -1
- edsl/agents/AgentListExportMixin.py +0 -24
- edsl/coop/old.py +0 -31
- edsl/data/Database.py +0 -141
- edsl/data/crud.py +0 -121
- edsl/jobs/Interview.py +0 -435
- edsl/jobs/JobsRunner.py +0 -63
- edsl/jobs/JobsRunnerStatusMixin.py +0 -115
- edsl/jobs/base.py +0 -47
- edsl/jobs/buckets.py +0 -178
- edsl/jobs/runners/JobsRunnerDryRun.py +0 -19
- edsl/jobs/runners/JobsRunnerStreaming.py +0 -54
- edsl/jobs/task_management.py +0 -215
- edsl/jobs/token_tracking.py +0 -78
- edsl/language_models/DeepInfra.py +0 -69
- edsl/language_models/OpenAI.py +0 -98
- edsl/language_models/model_interfaces/GeminiPro.py +0 -66
- edsl/language_models/model_interfaces/LanguageModelOpenAIFour.py +0 -8
- edsl/language_models/model_interfaces/LanguageModelOpenAIThreeFiveTurbo.py +0 -8
- edsl/language_models/model_interfaces/LlamaTwo13B.py +0 -21
- edsl/language_models/model_interfaces/LlamaTwo70B.py +0 -21
- edsl/language_models/model_interfaces/Mixtral8x7B.py +0 -24
- edsl/language_models/registry.py +0 -81
- edsl/language_models/schemas.py +0 -15
- edsl/language_models/unused/ReplicateBase.py +0 -83
- edsl/prompts/QuestionInstructionsBase.py +0 -6
- edsl/prompts/library/agent_instructions.py +0 -29
- edsl/prompts/library/agent_persona.py +0 -17
- edsl/prompts/library/question_budget.py +0 -26
- edsl/prompts/library/question_checkbox.py +0 -32
- edsl/prompts/library/question_extract.py +0 -19
- edsl/prompts/library/question_freetext.py +0 -14
- edsl/prompts/library/question_linear_scale.py +0 -20
- edsl/prompts/library/question_list.py +0 -22
- edsl/prompts/library/question_multiple_choice.py +0 -44
- edsl/prompts/library/question_numerical.py +0 -31
- edsl/prompts/library/question_rank.py +0 -21
- edsl/prompts/prompt_config.py +0 -33
- edsl/prompts/registry.py +0 -185
- edsl/questions/Question.py +0 -240
- edsl/report/InputOutputDataTypes.py +0 -134
- edsl/report/RegressionMixin.py +0 -28
- edsl/report/ReportOutputs.py +0 -1228
- edsl/report/ResultsFetchMixin.py +0 -106
- edsl/report/ResultsOutputMixin.py +0 -14
- edsl/report/demo.ipynb +0 -645
- edsl/results/ResultsDBMixin.py +0 -184
- edsl/surveys/SurveyFlowVisualizationMixin.py +0 -92
- edsl/trackers/Tracker.py +0 -91
- edsl/trackers/TrackerAPI.py +0 -196
- edsl/trackers/TrackerTasks.py +0 -70
- edsl/utilities/pastebin.py +0 -141
- edsl-0.1.15.dist-info/METADATA +0 -69
- edsl-0.1.15.dist-info/RECORD +0 -142
- /edsl/{language_models/model_interfaces → inference_services}/__init__.py +0 -0
- /edsl/{report/__init__.py → jobs/runners/JobsRunnerStatusData.py} +0 -0
- /edsl/{trackers/__init__.py → language_models/ServiceDataSources.py} +0 -0
- {edsl-0.1.15.dist-info → edsl-0.1.40.dist-info}/LICENSE +0 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
from edsl.scenarios.file_methods import FileMethods
|
2
|
+
import tempfile
|
3
|
+
import json
|
4
|
+
from typing import Optional, Dict, Any
|
5
|
+
|
6
|
+
|
7
|
+
class JsonMethods(FileMethods):
|
8
|
+
suffix = "json"
|
9
|
+
|
10
|
+
def view_system(self):
|
11
|
+
import os
|
12
|
+
import subprocess
|
13
|
+
|
14
|
+
if os.path.exists(self.path):
|
15
|
+
try:
|
16
|
+
if (os_name := os.name) == "posix":
|
17
|
+
subprocess.run(["open", self.path], check=True) # macOS
|
18
|
+
elif os_name == "nt":
|
19
|
+
os.startfile(self.path) # Windows
|
20
|
+
else:
|
21
|
+
subprocess.run(["xdg-open", self.path], check=True) # Linux
|
22
|
+
except Exception as e:
|
23
|
+
print(f"Error opening JSON: {e}")
|
24
|
+
else:
|
25
|
+
print("JSON file was not found.")
|
26
|
+
|
27
|
+
def view_notebook(self):
|
28
|
+
from IPython.display import FileLink, JSON, display
|
29
|
+
import json
|
30
|
+
|
31
|
+
# Read and parse the JSON file
|
32
|
+
try:
|
33
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
34
|
+
content = json.load(f)
|
35
|
+
|
36
|
+
# Display formatted JSON
|
37
|
+
display(JSON(content))
|
38
|
+
|
39
|
+
# Provide download link
|
40
|
+
display(FileLink(self.path))
|
41
|
+
except json.JSONDecodeError as e:
|
42
|
+
print(f"Error parsing JSON: {e}")
|
43
|
+
except Exception as e:
|
44
|
+
print(f"Error reading file: {e}")
|
45
|
+
|
46
|
+
def validate_json(self, schema: Optional[Dict[str, Any]] = None) -> bool:
|
47
|
+
"""
|
48
|
+
Validate the JSON file against a schema if provided,
|
49
|
+
or check if it's valid JSON if no schema is provided.
|
50
|
+
"""
|
51
|
+
try:
|
52
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
53
|
+
content = json.load(f)
|
54
|
+
|
55
|
+
if schema is not None:
|
56
|
+
from jsonschema import validate
|
57
|
+
|
58
|
+
validate(instance=content, schema=schema)
|
59
|
+
|
60
|
+
return True
|
61
|
+
except json.JSONDecodeError as e:
|
62
|
+
print(f"Invalid JSON format: {e}")
|
63
|
+
return False
|
64
|
+
except Exception as e:
|
65
|
+
print(f"Validation error: {e}")
|
66
|
+
return False
|
67
|
+
|
68
|
+
def pretty_print(self):
|
69
|
+
"""Pretty print the JSON content with proper indentation."""
|
70
|
+
try:
|
71
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
72
|
+
content = json.load(f)
|
73
|
+
|
74
|
+
pretty_json = json.dumps(content, indent=2, sort_keys=True)
|
75
|
+
print(pretty_json)
|
76
|
+
except Exception as e:
|
77
|
+
print(f"Error pretty printing JSON: {e}")
|
78
|
+
|
79
|
+
def example(self):
|
80
|
+
sample_json = {
|
81
|
+
"person": {
|
82
|
+
"name": "John Doe",
|
83
|
+
"age": 30,
|
84
|
+
"contact": {"email": "john@example.com", "phone": "+1-555-555-5555"},
|
85
|
+
"interests": ["programming", "data science", "machine learning"],
|
86
|
+
"active": True,
|
87
|
+
"metadata": {"last_updated": "2024-01-01", "version": 1.0},
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
with tempfile.NamedTemporaryFile(
|
92
|
+
delete=False, suffix=".json", mode="w", encoding="utf-8"
|
93
|
+
) as f:
|
94
|
+
json.dump(sample_json, f, indent=2)
|
95
|
+
return f.name
|
96
|
+
|
97
|
+
def format_file(self):
|
98
|
+
"""Read, format, and write back the JSON with consistent formatting."""
|
99
|
+
try:
|
100
|
+
# Read the current content
|
101
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
102
|
+
content = json.load(f)
|
103
|
+
|
104
|
+
# Write back with consistent formatting
|
105
|
+
with open(self.path, "w", encoding="utf-8") as f:
|
106
|
+
json.dump(content, f, indent=2, sort_keys=True)
|
107
|
+
|
108
|
+
return True
|
109
|
+
except Exception as e:
|
110
|
+
print(f"Error formatting JSON file: {e}")
|
111
|
+
return False
|
@@ -0,0 +1,51 @@
|
|
1
|
+
from edsl.scenarios.file_methods import FileMethods
|
2
|
+
import tempfile
|
3
|
+
|
4
|
+
|
5
|
+
class MarkdownMethods(FileMethods):
|
6
|
+
suffix = "md"
|
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 Markdown: {e}")
|
22
|
+
else:
|
23
|
+
print("Markdown file was not found.")
|
24
|
+
|
25
|
+
def view_notebook(self):
|
26
|
+
from IPython.display import FileLink, Markdown, display
|
27
|
+
|
28
|
+
# First display the content of the markdown file
|
29
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
30
|
+
content = f.read()
|
31
|
+
display(Markdown(content))
|
32
|
+
|
33
|
+
# Then provide a download link
|
34
|
+
display(FileLink(self.path))
|
35
|
+
|
36
|
+
def example(self):
|
37
|
+
markdown_content = """# Sample Markdown
|
38
|
+
|
39
|
+
## Features
|
40
|
+
- **Bold text** demonstration
|
41
|
+
- *Italic text* demonstration
|
42
|
+
- Code block example:
|
43
|
+
```python
|
44
|
+
print("Hello, World!")
|
45
|
+
```
|
46
|
+
"""
|
47
|
+
with tempfile.NamedTemporaryFile(
|
48
|
+
delete=False, suffix=".md", mode="w", encoding="utf-8"
|
49
|
+
) as f:
|
50
|
+
f.write(markdown_content)
|
51
|
+
return f.name
|
@@ -0,0 +1,68 @@
|
|
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
|
+
)
|
@@ -0,0 +1,39 @@
|
|
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
|
@@ -0,0 +1,105 @@
|
|
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)
|
@@ -0,0 +1,294 @@
|
|
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
|