edsl 0.1.36.dev2__py3-none-any.whl → 0.1.36.dev6__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 +303 -298
- edsl/BaseDiff.py +260 -260
- edsl/TemplateLoader.py +24 -24
- edsl/__init__.py +47 -47
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +804 -800
- edsl/agents/AgentList.py +337 -337
- edsl/agents/Invigilator.py +222 -222
- edsl/agents/InvigilatorBase.py +294 -294
- edsl/agents/PromptConstructor.py +312 -311
- edsl/agents/__init__.py +3 -3
- edsl/agents/descriptors.py +86 -86
- edsl/agents/prompt_helpers.py +129 -129
- edsl/auto/AutoStudy.py +117 -117
- edsl/auto/StageBase.py +230 -230
- edsl/auto/StageGenerateSurvey.py +178 -178
- edsl/auto/StageLabelQuestions.py +125 -125
- edsl/auto/StagePersona.py +61 -61
- edsl/auto/StagePersonaDimensionValueRanges.py +88 -88
- edsl/auto/StagePersonaDimensionValues.py +74 -74
- edsl/auto/StagePersonaDimensions.py +69 -69
- edsl/auto/StageQuestions.py +73 -73
- edsl/auto/SurveyCreatorPipeline.py +21 -21
- edsl/auto/utilities.py +224 -224
- edsl/base/Base.py +289 -289
- edsl/config.py +149 -149
- edsl/conjure/AgentConstructionMixin.py +152 -152
- edsl/conjure/Conjure.py +62 -62
- edsl/conjure/InputData.py +659 -659
- edsl/conjure/InputDataCSV.py +48 -48
- edsl/conjure/InputDataMixinQuestionStats.py +182 -182
- edsl/conjure/InputDataPyRead.py +91 -91
- edsl/conjure/InputDataSPSS.py +8 -8
- edsl/conjure/InputDataStata.py +8 -8
- edsl/conjure/QuestionOptionMixin.py +76 -76
- edsl/conjure/QuestionTypeMixin.py +23 -23
- edsl/conjure/RawQuestion.py +65 -65
- edsl/conjure/SurveyResponses.py +7 -7
- edsl/conjure/__init__.py +9 -9
- edsl/conjure/naming_utilities.py +263 -263
- edsl/conjure/utilities.py +201 -201
- edsl/conversation/Conversation.py +238 -238
- edsl/conversation/car_buying.py +58 -58
- edsl/conversation/mug_negotiation.py +81 -81
- edsl/conversation/next_speaker_utilities.py +93 -93
- edsl/coop/PriceFetcher.py +54 -58
- edsl/coop/__init__.py +2 -2
- edsl/coop/coop.py +849 -815
- edsl/coop/utils.py +131 -131
- edsl/data/Cache.py +527 -527
- edsl/data/CacheEntry.py +228 -228
- edsl/data/CacheHandler.py +149 -149
- edsl/data/RemoteCacheSync.py +84 -0
- edsl/data/SQLiteDict.py +292 -292
- edsl/data/__init__.py +4 -4
- edsl/data/orm.py +10 -10
- edsl/data_transfer_models.py +73 -73
- edsl/enums.py +173 -173
- edsl/exceptions/__init__.py +50 -50
- edsl/exceptions/agents.py +40 -40
- edsl/exceptions/configuration.py +16 -16
- edsl/exceptions/coop.py +10 -2
- edsl/exceptions/data.py +14 -14
- edsl/exceptions/general.py +34 -34
- edsl/exceptions/jobs.py +33 -33
- edsl/exceptions/language_models.py +63 -63
- edsl/exceptions/prompts.py +15 -15
- edsl/exceptions/questions.py +91 -91
- edsl/exceptions/results.py +26 -26
- edsl/exceptions/surveys.py +34 -34
- edsl/inference_services/AnthropicService.py +87 -87
- edsl/inference_services/AwsBedrock.py +115 -115
- edsl/inference_services/AzureAI.py +217 -217
- edsl/inference_services/DeepInfraService.py +18 -18
- edsl/inference_services/GoogleService.py +156 -156
- edsl/inference_services/GroqService.py +20 -20
- edsl/inference_services/InferenceServiceABC.py +147 -119
- edsl/inference_services/InferenceServicesCollection.py +72 -68
- edsl/inference_services/MistralAIService.py +123 -123
- edsl/inference_services/OllamaService.py +18 -18
- edsl/inference_services/OpenAIService.py +224 -224
- edsl/inference_services/TestService.py +89 -89
- edsl/inference_services/TogetherAIService.py +170 -170
- edsl/inference_services/models_available_cache.py +118 -94
- edsl/inference_services/rate_limits_cache.py +25 -25
- edsl/inference_services/registry.py +39 -39
- edsl/inference_services/write_available.py +10 -10
- edsl/jobs/Answers.py +56 -56
- edsl/jobs/Jobs.py +1112 -1089
- edsl/jobs/__init__.py +1 -1
- edsl/jobs/buckets/BucketCollection.py +63 -63
- edsl/jobs/buckets/ModelBuckets.py +65 -65
- edsl/jobs/buckets/TokenBucket.py +248 -248
- edsl/jobs/interviews/Interview.py +651 -633
- edsl/jobs/interviews/InterviewExceptionCollection.py +99 -90
- edsl/jobs/interviews/InterviewExceptionEntry.py +182 -164
- edsl/jobs/interviews/InterviewStatistic.py +63 -63
- edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -25
- edsl/jobs/interviews/InterviewStatusDictionary.py +78 -78
- edsl/jobs/interviews/InterviewStatusLog.py +92 -92
- edsl/jobs/interviews/ReportErrors.py +66 -66
- edsl/jobs/interviews/interview_status_enum.py +9 -9
- edsl/jobs/runners/JobsRunnerAsyncio.py +337 -343
- edsl/jobs/runners/JobsRunnerStatus.py +332 -332
- edsl/jobs/tasks/QuestionTaskCreator.py +242 -242
- edsl/jobs/tasks/TaskCreators.py +64 -64
- edsl/jobs/tasks/TaskHistory.py +441 -425
- edsl/jobs/tasks/TaskStatusLog.py +23 -23
- edsl/jobs/tasks/task_status_enum.py +163 -163
- edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
- edsl/jobs/tokens/TokenUsage.py +34 -34
- edsl/language_models/LanguageModel.py +718 -718
- edsl/language_models/ModelList.py +102 -102
- edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
- edsl/language_models/__init__.py +2 -2
- edsl/language_models/fake_openai_call.py +15 -15
- edsl/language_models/fake_openai_service.py +61 -61
- edsl/language_models/registry.py +137 -137
- edsl/language_models/repair.py +156 -156
- edsl/language_models/unused/ReplicateBase.py +83 -83
- edsl/language_models/utilities.py +64 -64
- edsl/notebooks/Notebook.py +259 -259
- edsl/notebooks/__init__.py +1 -1
- edsl/prompts/Prompt.py +358 -358
- edsl/prompts/__init__.py +2 -2
- edsl/questions/AnswerValidatorMixin.py +289 -289
- edsl/questions/QuestionBase.py +616 -616
- edsl/questions/QuestionBaseGenMixin.py +161 -161
- edsl/questions/QuestionBasePromptsMixin.py +266 -266
- edsl/questions/QuestionBudget.py +227 -227
- edsl/questions/QuestionCheckBox.py +359 -359
- edsl/questions/QuestionExtract.py +183 -183
- edsl/questions/QuestionFreeText.py +113 -113
- edsl/questions/QuestionFunctional.py +159 -155
- edsl/questions/QuestionList.py +231 -231
- edsl/questions/QuestionMultipleChoice.py +286 -286
- edsl/questions/QuestionNumerical.py +153 -153
- edsl/questions/QuestionRank.py +324 -324
- edsl/questions/Quick.py +41 -41
- edsl/questions/RegisterQuestionsMeta.py +71 -71
- edsl/questions/ResponseValidatorABC.py +174 -174
- edsl/questions/SimpleAskMixin.py +73 -73
- edsl/questions/__init__.py +26 -26
- edsl/questions/compose_questions.py +98 -98
- edsl/questions/decorators.py +21 -21
- edsl/questions/derived/QuestionLikertFive.py +76 -76
- edsl/questions/derived/QuestionLinearScale.py +87 -87
- edsl/questions/derived/QuestionTopK.py +91 -91
- edsl/questions/derived/QuestionYesNo.py +82 -82
- edsl/questions/descriptors.py +418 -418
- edsl/questions/prompt_templates/question_budget.jinja +13 -13
- edsl/questions/prompt_templates/question_checkbox.jinja +32 -32
- edsl/questions/prompt_templates/question_extract.jinja +11 -11
- edsl/questions/prompt_templates/question_free_text.jinja +3 -3
- edsl/questions/prompt_templates/question_linear_scale.jinja +11 -11
- edsl/questions/prompt_templates/question_list.jinja +17 -17
- edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -33
- edsl/questions/prompt_templates/question_numerical.jinja +36 -36
- edsl/questions/question_registry.py +147 -147
- edsl/questions/settings.py +12 -12
- edsl/questions/templates/budget/answering_instructions.jinja +7 -7
- edsl/questions/templates/budget/question_presentation.jinja +7 -7
- edsl/questions/templates/checkbox/answering_instructions.jinja +10 -10
- edsl/questions/templates/checkbox/question_presentation.jinja +22 -22
- edsl/questions/templates/extract/answering_instructions.jinja +7 -7
- edsl/questions/templates/likert_five/answering_instructions.jinja +10 -10
- edsl/questions/templates/likert_five/question_presentation.jinja +11 -11
- edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -5
- edsl/questions/templates/linear_scale/question_presentation.jinja +5 -5
- edsl/questions/templates/list/answering_instructions.jinja +3 -3
- edsl/questions/templates/list/question_presentation.jinja +5 -5
- edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -9
- edsl/questions/templates/multiple_choice/question_presentation.jinja +11 -11
- edsl/questions/templates/numerical/answering_instructions.jinja +6 -6
- edsl/questions/templates/numerical/question_presentation.jinja +6 -6
- edsl/questions/templates/rank/answering_instructions.jinja +11 -11
- edsl/questions/templates/rank/question_presentation.jinja +15 -15
- edsl/questions/templates/top_k/answering_instructions.jinja +8 -8
- edsl/questions/templates/top_k/question_presentation.jinja +22 -22
- edsl/questions/templates/yes_no/answering_instructions.jinja +6 -6
- edsl/questions/templates/yes_no/question_presentation.jinja +11 -11
- edsl/results/Dataset.py +293 -281
- edsl/results/DatasetExportMixin.py +693 -693
- edsl/results/DatasetTree.py +145 -145
- edsl/results/Result.py +433 -431
- edsl/results/Results.py +1158 -1146
- edsl/results/ResultsDBMixin.py +238 -238
- edsl/results/ResultsExportMixin.py +43 -43
- edsl/results/ResultsFetchMixin.py +33 -33
- edsl/results/ResultsGGMixin.py +121 -121
- edsl/results/ResultsToolsMixin.py +98 -98
- edsl/results/Selector.py +118 -118
- edsl/results/__init__.py +2 -2
- edsl/results/tree_explore.py +115 -115
- edsl/scenarios/FileStore.py +443 -443
- edsl/scenarios/Scenario.py +507 -496
- edsl/scenarios/ScenarioHtmlMixin.py +59 -59
- edsl/scenarios/ScenarioList.py +1101 -1101
- edsl/scenarios/ScenarioListExportMixin.py +52 -52
- edsl/scenarios/ScenarioListPdfMixin.py +261 -261
- edsl/scenarios/__init__.py +2 -2
- edsl/shared.py +1 -1
- edsl/study/ObjectEntry.py +173 -173
- edsl/study/ProofOfWork.py +113 -113
- edsl/study/SnapShot.py +80 -80
- edsl/study/Study.py +528 -528
- edsl/study/__init__.py +4 -4
- edsl/surveys/DAG.py +148 -148
- edsl/surveys/Memory.py +31 -31
- edsl/surveys/MemoryPlan.py +244 -244
- edsl/surveys/Rule.py +324 -324
- edsl/surveys/RuleCollection.py +387 -387
- edsl/surveys/Survey.py +1772 -1769
- edsl/surveys/SurveyCSS.py +261 -261
- edsl/surveys/SurveyExportMixin.py +259 -259
- edsl/surveys/SurveyFlowVisualizationMixin.py +121 -121
- edsl/surveys/SurveyQualtricsImport.py +284 -284
- edsl/surveys/__init__.py +3 -3
- edsl/surveys/base.py +53 -53
- edsl/surveys/descriptors.py +56 -56
- edsl/surveys/instructions/ChangeInstruction.py +47 -47
- edsl/surveys/instructions/Instruction.py +51 -34
- edsl/surveys/instructions/InstructionCollection.py +77 -77
- edsl/templates/error_reporting/base.html +23 -23
- edsl/templates/error_reporting/exceptions_by_model.html +34 -34
- edsl/templates/error_reporting/exceptions_by_question_name.html +16 -16
- edsl/templates/error_reporting/exceptions_by_type.html +16 -16
- edsl/templates/error_reporting/interview_details.html +115 -115
- edsl/templates/error_reporting/interviews.html +9 -9
- edsl/templates/error_reporting/overview.html +4 -4
- edsl/templates/error_reporting/performance_plot.html +1 -1
- edsl/templates/error_reporting/report.css +73 -73
- edsl/templates/error_reporting/report.html +117 -117
- edsl/templates/error_reporting/report.js +25 -25
- edsl/tools/__init__.py +1 -1
- edsl/tools/clusters.py +192 -192
- edsl/tools/embeddings.py +27 -27
- edsl/tools/embeddings_plotting.py +118 -118
- edsl/tools/plotting.py +112 -112
- edsl/tools/summarize.py +18 -18
- edsl/utilities/SystemInfo.py +28 -28
- edsl/utilities/__init__.py +22 -22
- edsl/utilities/ast_utilities.py +25 -25
- edsl/utilities/data/Registry.py +6 -6
- edsl/utilities/data/__init__.py +1 -1
- edsl/utilities/data/scooter_results.json +1 -1
- edsl/utilities/decorators.py +77 -77
- edsl/utilities/gcp_bucket/cloud_storage.py +96 -96
- edsl/utilities/interface.py +627 -627
- edsl/utilities/repair_functions.py +28 -28
- edsl/utilities/restricted_python.py +70 -70
- edsl/utilities/utilities.py +391 -391
- {edsl-0.1.36.dev2.dist-info → edsl-0.1.36.dev6.dist-info}/LICENSE +21 -21
- {edsl-0.1.36.dev2.dist-info → edsl-0.1.36.dev6.dist-info}/METADATA +1 -1
- edsl-0.1.36.dev6.dist-info/RECORD +279 -0
- edsl-0.1.36.dev2.dist-info/RECORD +0 -278
- {edsl-0.1.36.dev2.dist-info → edsl-0.1.36.dev6.dist-info}/WHEEL +0 -0
@@ -1,121 +1,121 @@
|
|
1
|
-
"""A mixin for visualizing the flow of a survey."""
|
2
|
-
|
3
|
-
from typing import Optional
|
4
|
-
from edsl.surveys.base import RulePriority, EndOfSurvey
|
5
|
-
import tempfile
|
6
|
-
|
7
|
-
|
8
|
-
class SurveyFlowVisualizationMixin:
|
9
|
-
"""A mixin for visualizing the flow of a survey."""
|
10
|
-
|
11
|
-
def show_flow(self, filename: Optional[str] = None):
|
12
|
-
"""Create an image showing the flow of users through the survey."""
|
13
|
-
# Create a graph object
|
14
|
-
import pydot
|
15
|
-
|
16
|
-
graph = pydot.Dot(graph_type="digraph")
|
17
|
-
|
18
|
-
# Add nodes for each question
|
19
|
-
for index, question in enumerate(self.questions):
|
20
|
-
graph.add_node(
|
21
|
-
pydot.Node(
|
22
|
-
f"Q{index}", label=f"{question.question_name}", shape="ellipse"
|
23
|
-
)
|
24
|
-
)
|
25
|
-
|
26
|
-
# Add an "EndOfSurvey" node
|
27
|
-
graph.add_node(
|
28
|
-
pydot.Node("EndOfSurvey", label="End of Survey", shape="rectangle")
|
29
|
-
)
|
30
|
-
|
31
|
-
# Add edges for normal flow through the survey
|
32
|
-
num_questions = len(self.questions)
|
33
|
-
for index in range(num_questions - 1): # From Q1 to Q3
|
34
|
-
graph.add_edge(pydot.Edge(f"Q{index}", f"Q{index+1}"))
|
35
|
-
|
36
|
-
graph.add_edge(pydot.Edge(f"Q{num_questions-1}", "EndOfSurvey"))
|
37
|
-
|
38
|
-
relevant_rules = [
|
39
|
-
rule
|
40
|
-
for rule in self.rule_collection
|
41
|
-
if rule.priority > RulePriority.DEFAULT.value
|
42
|
-
]
|
43
|
-
|
44
|
-
# edge-colors to cycle through
|
45
|
-
colors = [
|
46
|
-
"blue",
|
47
|
-
"red",
|
48
|
-
"orange",
|
49
|
-
"purple",
|
50
|
-
"brown",
|
51
|
-
"cyan",
|
52
|
-
"green",
|
53
|
-
]
|
54
|
-
rule_colors = {
|
55
|
-
rule: colors[i % len(colors)] for i, rule in enumerate(relevant_rules)
|
56
|
-
}
|
57
|
-
|
58
|
-
for rule in relevant_rules:
|
59
|
-
color = rule_colors[rule]
|
60
|
-
edge_label = f"if {rule.expression}"
|
61
|
-
source_node = f"Q{rule.current_q}"
|
62
|
-
target_node = (
|
63
|
-
f"Q{rule.next_q}"
|
64
|
-
if rule.next_q != EndOfSurvey and rule.next_q < num_questions
|
65
|
-
else "EndOfSurvey"
|
66
|
-
)
|
67
|
-
if rule.before_rule: # Assume skip rules have an attribute `is_skip`
|
68
|
-
edge = pydot.Edge(
|
69
|
-
source_node,
|
70
|
-
target_node,
|
71
|
-
label=edge_label,
|
72
|
-
color=color,
|
73
|
-
fontcolor=color,
|
74
|
-
tailport="n",
|
75
|
-
headport="n",
|
76
|
-
)
|
77
|
-
else:
|
78
|
-
edge = pydot.Edge(
|
79
|
-
source_node,
|
80
|
-
target_node,
|
81
|
-
label=edge_label,
|
82
|
-
color=color,
|
83
|
-
fontcolor=color,
|
84
|
-
)
|
85
|
-
|
86
|
-
graph.add_edge(edge)
|
87
|
-
|
88
|
-
if filename is not None:
|
89
|
-
graph.write_png(filename)
|
90
|
-
print(f"Flowchart saved to {filename}")
|
91
|
-
return
|
92
|
-
|
93
|
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp_file:
|
94
|
-
try:
|
95
|
-
graph.write_png(tmp_file.name)
|
96
|
-
except FileNotFoundError:
|
97
|
-
print(
|
98
|
-
"""File not found. Most likely it's because you don't have graphviz installed. Please install it and try again.
|
99
|
-
It's
|
100
|
-
$ sudo apt-get install graphviz
|
101
|
-
on Ubuntu.
|
102
|
-
"""
|
103
|
-
)
|
104
|
-
from edsl.utilities.utilities import is_notebook
|
105
|
-
|
106
|
-
if is_notebook():
|
107
|
-
from IPython.display import Image
|
108
|
-
|
109
|
-
display(Image(tmp_file.name))
|
110
|
-
else:
|
111
|
-
import os
|
112
|
-
import sys
|
113
|
-
|
114
|
-
if os.name == "nt": # Windows
|
115
|
-
os.system(f"start {tmp_file.name}")
|
116
|
-
elif os.name == "posix": # macOS, Linux, Unix, etc.
|
117
|
-
os.system(
|
118
|
-
f"open {tmp_file.name}"
|
119
|
-
if sys.platform == "darwin"
|
120
|
-
else f"xdg-open {tmp_file.name}"
|
121
|
-
)
|
1
|
+
"""A mixin for visualizing the flow of a survey."""
|
2
|
+
|
3
|
+
from typing import Optional
|
4
|
+
from edsl.surveys.base import RulePriority, EndOfSurvey
|
5
|
+
import tempfile
|
6
|
+
|
7
|
+
|
8
|
+
class SurveyFlowVisualizationMixin:
|
9
|
+
"""A mixin for visualizing the flow of a survey."""
|
10
|
+
|
11
|
+
def show_flow(self, filename: Optional[str] = None):
|
12
|
+
"""Create an image showing the flow of users through the survey."""
|
13
|
+
# Create a graph object
|
14
|
+
import pydot
|
15
|
+
|
16
|
+
graph = pydot.Dot(graph_type="digraph")
|
17
|
+
|
18
|
+
# Add nodes for each question
|
19
|
+
for index, question in enumerate(self.questions):
|
20
|
+
graph.add_node(
|
21
|
+
pydot.Node(
|
22
|
+
f"Q{index}", label=f"{question.question_name}", shape="ellipse"
|
23
|
+
)
|
24
|
+
)
|
25
|
+
|
26
|
+
# Add an "EndOfSurvey" node
|
27
|
+
graph.add_node(
|
28
|
+
pydot.Node("EndOfSurvey", label="End of Survey", shape="rectangle")
|
29
|
+
)
|
30
|
+
|
31
|
+
# Add edges for normal flow through the survey
|
32
|
+
num_questions = len(self.questions)
|
33
|
+
for index in range(num_questions - 1): # From Q1 to Q3
|
34
|
+
graph.add_edge(pydot.Edge(f"Q{index}", f"Q{index+1}"))
|
35
|
+
|
36
|
+
graph.add_edge(pydot.Edge(f"Q{num_questions-1}", "EndOfSurvey"))
|
37
|
+
|
38
|
+
relevant_rules = [
|
39
|
+
rule
|
40
|
+
for rule in self.rule_collection
|
41
|
+
if rule.priority > RulePriority.DEFAULT.value
|
42
|
+
]
|
43
|
+
|
44
|
+
# edge-colors to cycle through
|
45
|
+
colors = [
|
46
|
+
"blue",
|
47
|
+
"red",
|
48
|
+
"orange",
|
49
|
+
"purple",
|
50
|
+
"brown",
|
51
|
+
"cyan",
|
52
|
+
"green",
|
53
|
+
]
|
54
|
+
rule_colors = {
|
55
|
+
rule: colors[i % len(colors)] for i, rule in enumerate(relevant_rules)
|
56
|
+
}
|
57
|
+
|
58
|
+
for rule in relevant_rules:
|
59
|
+
color = rule_colors[rule]
|
60
|
+
edge_label = f"if {rule.expression}"
|
61
|
+
source_node = f"Q{rule.current_q}"
|
62
|
+
target_node = (
|
63
|
+
f"Q{rule.next_q}"
|
64
|
+
if rule.next_q != EndOfSurvey and rule.next_q < num_questions
|
65
|
+
else "EndOfSurvey"
|
66
|
+
)
|
67
|
+
if rule.before_rule: # Assume skip rules have an attribute `is_skip`
|
68
|
+
edge = pydot.Edge(
|
69
|
+
source_node,
|
70
|
+
target_node,
|
71
|
+
label=edge_label,
|
72
|
+
color=color,
|
73
|
+
fontcolor=color,
|
74
|
+
tailport="n",
|
75
|
+
headport="n",
|
76
|
+
)
|
77
|
+
else:
|
78
|
+
edge = pydot.Edge(
|
79
|
+
source_node,
|
80
|
+
target_node,
|
81
|
+
label=edge_label,
|
82
|
+
color=color,
|
83
|
+
fontcolor=color,
|
84
|
+
)
|
85
|
+
|
86
|
+
graph.add_edge(edge)
|
87
|
+
|
88
|
+
if filename is not None:
|
89
|
+
graph.write_png(filename)
|
90
|
+
print(f"Flowchart saved to {filename}")
|
91
|
+
return
|
92
|
+
|
93
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp_file:
|
94
|
+
try:
|
95
|
+
graph.write_png(tmp_file.name)
|
96
|
+
except FileNotFoundError:
|
97
|
+
print(
|
98
|
+
"""File not found. Most likely it's because you don't have graphviz installed. Please install it and try again.
|
99
|
+
It's
|
100
|
+
$ sudo apt-get install graphviz
|
101
|
+
on Ubuntu.
|
102
|
+
"""
|
103
|
+
)
|
104
|
+
from edsl.utilities.utilities import is_notebook
|
105
|
+
|
106
|
+
if is_notebook():
|
107
|
+
from IPython.display import Image
|
108
|
+
|
109
|
+
display(Image(tmp_file.name))
|
110
|
+
else:
|
111
|
+
import os
|
112
|
+
import sys
|
113
|
+
|
114
|
+
if os.name == "nt": # Windows
|
115
|
+
os.system(f"start {tmp_file.name}")
|
116
|
+
elif os.name == "posix": # macOS, Linux, Unix, etc.
|
117
|
+
os.system(
|
118
|
+
f"open {tmp_file.name}"
|
119
|
+
if sys.platform == "darwin"
|
120
|
+
else f"xdg-open {tmp_file.name}"
|
121
|
+
)
|