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.
- edsl/Base.py +348 -38
- edsl/BaseDiff.py +260 -0
- edsl/TemplateLoader.py +24 -0
- edsl/__init__.py +46 -10
- edsl/__version__.py +1 -0
- 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 +121 -104
- 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 -204
- 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.14.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 -417
- edsl/jobs/JobsRunner.py +0 -63
- edsl/jobs/JobsRunnerStatusMixin.py +0 -115
- edsl/jobs/base.py +0 -47
- edsl/jobs/buckets.py +0 -166
- edsl/jobs/runners/JobsRunnerDryRun.py +0 -19
- edsl/jobs/runners/JobsRunnerStreaming.py +0 -54
- edsl/jobs/task_management.py +0 -218
- 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.14.dist-info/METADATA +0 -69
- edsl-0.1.14.dist-info/RECORD +0 -141
- /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.14.dist-info → edsl-0.1.40.dist-info}/LICENSE +0 -0
edsl/utilities/interface.py
CHANGED
@@ -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
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
"""
|
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
|
-
|
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
|
136
|
-
|
169
|
+
def print_results_long(results, max_rows=None):
|
170
|
+
from rich.console import Console
|
171
|
+
from rich.table import Table
|
137
172
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
211
|
+
console.print(table)
|
212
|
+
# display_table(console, table, filename)
|
187
213
|
|
188
214
|
|
189
215
|
def print_dict_as_html_table(
|
190
|
-
d,
|
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
|
-
|
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
|
-
|
332
|
+
console.print(table)
|
333
|
+
# display_table(console, table, filename)
|
255
334
|
|
256
335
|
|
257
|
-
def
|
258
|
-
|
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
|
-
|
261
|
-
|
262
|
-
|
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
|
-
|
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
|
-
|
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(
|
500
|
+
f.write(markdown_table)
|
296
501
|
else:
|
297
|
-
|
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
|
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
|
-
|
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
|
+
)
|