edsl 0.1.29.dev6__py3-none-any.whl → 0.1.30.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. edsl/Base.py +6 -3
  2. edsl/__init__.py +23 -23
  3. edsl/__version__.py +1 -1
  4. edsl/agents/Agent.py +35 -34
  5. edsl/agents/AgentList.py +16 -5
  6. edsl/agents/Invigilator.py +19 -1
  7. edsl/agents/descriptors.py +2 -1
  8. edsl/base/Base.py +289 -0
  9. edsl/config.py +2 -1
  10. edsl/coop/utils.py +28 -1
  11. edsl/data/Cache.py +19 -5
  12. edsl/data/SQLiteDict.py +11 -3
  13. edsl/jobs/Answers.py +15 -1
  14. edsl/jobs/Jobs.py +69 -31
  15. edsl/jobs/buckets/ModelBuckets.py +4 -2
  16. edsl/jobs/buckets/TokenBucket.py +1 -2
  17. edsl/jobs/interviews/Interview.py +0 -6
  18. edsl/jobs/interviews/InterviewTaskBuildingMixin.py +9 -5
  19. edsl/jobs/runners/JobsRunnerAsyncio.py +12 -16
  20. edsl/jobs/tasks/TaskHistory.py +4 -3
  21. edsl/language_models/LanguageModel.py +5 -11
  22. edsl/language_models/ModelList.py +1 -1
  23. edsl/language_models/repair.py +8 -7
  24. edsl/notebooks/Notebook.py +9 -3
  25. edsl/questions/QuestionBase.py +6 -2
  26. edsl/questions/QuestionBudget.py +5 -6
  27. edsl/questions/QuestionCheckBox.py +7 -3
  28. edsl/questions/QuestionExtract.py +5 -3
  29. edsl/questions/QuestionFreeText.py +3 -3
  30. edsl/questions/QuestionFunctional.py +0 -3
  31. edsl/questions/QuestionList.py +3 -4
  32. edsl/questions/QuestionMultipleChoice.py +12 -5
  33. edsl/questions/QuestionNumerical.py +4 -3
  34. edsl/questions/QuestionRank.py +5 -3
  35. edsl/questions/__init__.py +4 -3
  36. edsl/questions/descriptors.py +4 -2
  37. edsl/results/DatasetExportMixin.py +491 -0
  38. edsl/results/Result.py +13 -65
  39. edsl/results/Results.py +91 -39
  40. edsl/results/ResultsDBMixin.py +7 -3
  41. edsl/results/ResultsExportMixin.py +22 -537
  42. edsl/results/ResultsGGMixin.py +3 -3
  43. edsl/results/ResultsToolsMixin.py +1 -4
  44. edsl/scenarios/FileStore.py +140 -0
  45. edsl/scenarios/Scenario.py +5 -6
  46. edsl/scenarios/ScenarioList.py +17 -8
  47. edsl/scenarios/ScenarioListExportMixin.py +32 -0
  48. edsl/scenarios/ScenarioListPdfMixin.py +2 -1
  49. edsl/scenarios/__init__.py +1 -0
  50. edsl/surveys/MemoryPlan.py +11 -4
  51. edsl/surveys/Survey.py +9 -4
  52. edsl/surveys/SurveyExportMixin.py +4 -2
  53. edsl/surveys/SurveyFlowVisualizationMixin.py +6 -4
  54. edsl/utilities/__init__.py +21 -21
  55. edsl/utilities/interface.py +66 -45
  56. edsl/utilities/utilities.py +11 -13
  57. {edsl-0.1.29.dev6.dist-info → edsl-0.1.30.dev1.dist-info}/METADATA +1 -1
  58. {edsl-0.1.29.dev6.dist-info → edsl-0.1.30.dev1.dist-info}/RECORD +60 -56
  59. {edsl-0.1.29.dev6.dist-info → edsl-0.1.30.dev1.dist-info}/LICENSE +0 -0
  60. {edsl-0.1.29.dev6.dist-info → edsl-0.1.30.dev1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,491 @@
1
+ """Mixin class for exporting results."""
2
+
3
+ import base64
4
+ import csv
5
+ import io
6
+
7
+ from typing import Literal, Optional, Union
8
+
9
+
10
+ class DatasetExportMixin:
11
+ """Mixin class"""
12
+
13
+ def relevant_columns(
14
+ self, data_type: Optional[str] = None, remove_prefix=False
15
+ ) -> list:
16
+ """Return the set of keys that are present in the dataset.
17
+
18
+ >>> from edsl.results.Dataset import Dataset
19
+ >>> d = Dataset([{'a.b':[1,2,3,4]}])
20
+ >>> d.relevant_columns()
21
+ ['a.b']
22
+
23
+ >>> d.relevant_columns(remove_prefix=True)
24
+ ['b']
25
+
26
+ >>> from edsl.results import Results; Results.example().select('how_feeling', 'how_feeling_yesterday').relevant_columns()
27
+ ['answer.how_feeling', 'answer.how_feeling_yesterday']
28
+ """
29
+ columns = [list(x.keys())[0] for x in self]
30
+ # columns = set([list(result.keys())[0] for result in self.data])
31
+ if remove_prefix:
32
+ columns = [column.split(".")[-1] for column in columns]
33
+
34
+ if data_type:
35
+ columns = [
36
+ column for column in columns if column.split(".")[0] == data_type
37
+ ]
38
+
39
+ return columns
40
+
41
+ def _make_tabular(self, remove_prefix: bool, pretty_labels: Optional[dict] = None):
42
+ """Turn the results into a tabular format.
43
+
44
+ :param remove_prefix: Whether to remove the prefix from the column names.
45
+
46
+ >>> from edsl.results import Results
47
+ >>> r = Results.example()
48
+ >>> r.select('how_feeling')._make_tabular(remove_prefix = True)
49
+ (['how_feeling'], [['OK'], ['Great'], ['Terrible'], ['OK']])
50
+
51
+ >>> r.select('how_feeling')._make_tabular(remove_prefix = True, pretty_labels = {'how_feeling': "How are you feeling"})
52
+ (['How are you feeling'], [['OK'], ['Great'], ['Terrible'], ['OK']])
53
+ """
54
+ d = {}
55
+ full_header = sorted(list(self.relevant_columns()))
56
+ for entry in self.data:
57
+ key, list_of_values = list(entry.items())[0]
58
+ d[key] = list_of_values
59
+ if remove_prefix:
60
+ header = [h.split(".")[-1] for h in full_header]
61
+ else:
62
+ header = full_header
63
+ num_observations = len(list(self[0].values())[0])
64
+ rows = []
65
+ # rows.append(header)
66
+ for i in range(num_observations):
67
+ row = [d[h][i] for h in full_header]
68
+ rows.append(row)
69
+ if pretty_labels is not None:
70
+ header = [pretty_labels.get(h, h) for h in header]
71
+ return header, rows
72
+
73
+ def print_long(self):
74
+ """Print the results in a long format."""
75
+ for entry in self:
76
+ key, list_of_values = list(entry.items())[0]
77
+ for value in list_of_values:
78
+ print(f"{key}: {value}")
79
+
80
+ def print(
81
+ self,
82
+ pretty_labels: Optional[dict] = None,
83
+ filename: Optional[str] = None,
84
+ format: Literal["rich", "html", "markdown", "latex"] = None,
85
+ interactive: bool = False,
86
+ split_at_dot: bool = True,
87
+ max_rows=None,
88
+ tee=False,
89
+ iframe=False,
90
+ iframe_height: int = 200,
91
+ iframe_width: int = 600,
92
+ web=False,
93
+ ) -> None:
94
+ """Print the results in a pretty format.
95
+
96
+ :param pretty_labels: A dictionary of pretty labels for the columns.
97
+ :param filename: The filename to save the results to.
98
+ :param format: The format to print the results in. Options are 'rich', 'html', or 'markdown'.
99
+ :param interactive: Whether to print the results interactively in a Jupyter notebook.
100
+ :param split_at_dot: Whether to split the column names at the last dot w/ a newline.
101
+
102
+ Example: Print in rich format at the terminal
103
+
104
+ >>> from edsl.results import Results
105
+ >>> r = Results.example()
106
+ >>> r.select('how_feeling').print(format = "rich")
107
+ ┏━━━━━━━━━━━━━━┓
108
+ ┃ answer ┃
109
+ ┃ .how_feeling ┃
110
+ ┡━━━━━━━━━━━━━━┩
111
+ │ OK │
112
+ ├──────────────┤
113
+ │ Great │
114
+ ├──────────────┤
115
+ │ Terrible │
116
+ ├──────────────┤
117
+ │ OK │
118
+ └──────────────┘
119
+
120
+ Example: using the pretty_labels parameter
121
+
122
+ >>> r.select('how_feeling').print(format="rich", pretty_labels = {'answer.how_feeling': "How are you feeling"})
123
+ ┏━━━━━━━━━━━━━━━━━━━━━┓
124
+ ┃ How are you feeling ┃
125
+ ┡━━━━━━━━━━━━━━━━━━━━━┩
126
+ │ OK │
127
+ ├─────────────────────┤
128
+ │ Great │
129
+ ├─────────────────────┤
130
+ │ Terrible │
131
+ ├─────────────────────┤
132
+ │ OK │
133
+ └─────────────────────┘
134
+
135
+ Example: printing in markdown format
136
+
137
+ >>> r.select('how_feeling').print(format='markdown')
138
+ | answer.how_feeling |
139
+ |--|
140
+ | OK |
141
+ | Great |
142
+ | Terrible |
143
+ | OK |
144
+ ...
145
+ """
146
+ from IPython.display import HTML, display
147
+ from edsl.utilities.utilities import is_notebook
148
+
149
+ if format is None:
150
+ if is_notebook():
151
+ format = "html"
152
+ else:
153
+ format = "rich"
154
+
155
+ if pretty_labels is None:
156
+ pretty_labels = {}
157
+
158
+ if format not in ["rich", "html", "markdown", "latex"]:
159
+ raise ValueError("format must be one of 'rich', 'html', or 'markdown'.")
160
+
161
+ new_data = []
162
+ for index, entry in enumerate(self):
163
+ key, list_of_values = list(entry.items())[0]
164
+ new_data.append({pretty_labels.get(key, key): list_of_values})
165
+
166
+ if max_rows is not None:
167
+ for entry in new_data:
168
+ for key in entry:
169
+ actual_rows = len(entry[key])
170
+ entry[key] = entry[key][:max_rows]
171
+ # print(f"Showing only the first {max_rows} rows of {actual_rows} rows.")
172
+
173
+ if format == "rich":
174
+ from edsl.utilities.interface import print_dataset_with_rich
175
+
176
+ print_dataset_with_rich(
177
+ new_data, filename=filename, split_at_dot=split_at_dot
178
+ )
179
+ elif format == "html":
180
+ notebook = is_notebook()
181
+ from edsl.utilities.interface import print_list_of_dicts_as_html_table
182
+
183
+ html_source = print_list_of_dicts_as_html_table(
184
+ new_data, interactive=interactive
185
+ )
186
+ if iframe:
187
+ import html
188
+
189
+ height = iframe_height
190
+ width = iframe_width
191
+ escaped_output = html.escape(html_source)
192
+ # escaped_output = html_source
193
+ iframe = f""""
194
+ <iframe srcdoc="{ escaped_output }" style="width: {width}px; height: {height}px;"></iframe>
195
+ """
196
+ display(HTML(iframe))
197
+ elif notebook:
198
+ display(HTML(html_source))
199
+ else:
200
+ from edsl.utilities.interface import view_html
201
+
202
+ view_html(html_source)
203
+
204
+ elif format == "markdown":
205
+ from edsl.utilities.interface import print_list_of_dicts_as_markdown_table
206
+
207
+ print_list_of_dicts_as_markdown_table(new_data, filename=filename)
208
+ elif format == "latex":
209
+ df = self.to_pandas()
210
+ df.columns = [col.replace("_", " ") for col in df.columns]
211
+ latex_string = df.to_latex()
212
+ if filename is not None:
213
+ with open(filename, "w") as f:
214
+ f.write(latex_string)
215
+ else:
216
+ return latex_string
217
+ # raise NotImplementedError("Latex format not yet implemented.")
218
+ # latex_string = create_latex_table_from_data(new_data, filename=filename)
219
+ # if filename is None:
220
+ # return latex_string
221
+ # Not working quite
222
+
223
+ else:
224
+ raise ValueError("format not recognized.")
225
+
226
+ if tee:
227
+ return self
228
+
229
+ def to_csv(
230
+ self,
231
+ filename: Optional[str] = None,
232
+ remove_prefix: bool = False,
233
+ download_link: bool = False,
234
+ pretty_labels: Optional[dict] = None,
235
+ ):
236
+ """Export the results to a CSV file.
237
+
238
+ :param filename: The filename to save the CSV file to.
239
+ :param remove_prefix: Whether to remove the prefix from the column names.
240
+ :param download_link: Whether to display a download link in a Jupyter notebook.
241
+
242
+ Example:
243
+
244
+ >>> from edsl.results import Results
245
+ >>> r = Results.example()
246
+ >>> r.select('how_feeling').to_csv()
247
+ 'answer.how_feeling\\r\\nOK\\r\\nGreat\\r\\nTerrible\\r\\nOK\\r\\n'
248
+ """
249
+ if pretty_labels is None:
250
+ pretty_labels = {}
251
+ header, rows = self._make_tabular(
252
+ remove_prefix=remove_prefix, pretty_labels=pretty_labels
253
+ )
254
+
255
+ if filename is not None:
256
+ with open(filename, "w") as f:
257
+ writer = csv.writer(f)
258
+ writer.writerow(header)
259
+ writer.writerows(rows)
260
+ else:
261
+ output = io.StringIO()
262
+ writer = csv.writer(output)
263
+ writer.writerow(header)
264
+ writer.writerows(rows)
265
+
266
+ if download_link:
267
+ csv_file = output.getvalue()
268
+ b64 = base64.b64encode(csv_file.encode()).decode()
269
+ download_link = f'<a href="data:file/csv;base64,{b64}" download="my_data.csv">Download CSV file</a>'
270
+ display(HTML(download_link))
271
+ else:
272
+ return output.getvalue()
273
+
274
+ def to_pandas(self, remove_prefix: bool = False) -> "pd.DataFrame":
275
+ """Convert the results to a pandas DataFrame.
276
+
277
+ :param remove_prefix: Whether to remove the prefix from the column names.
278
+
279
+ >>> from edsl.results import Results
280
+ >>> r = Results.example()
281
+ >>> r.select('how_feeling').to_pandas()
282
+ answer.how_feeling
283
+ 0 OK
284
+ 1 Great
285
+ 2 Terrible
286
+ 3 OK
287
+ """
288
+ import pandas as pd
289
+
290
+ csv_string = self.to_csv(remove_prefix=remove_prefix)
291
+ csv_buffer = io.StringIO(csv_string)
292
+ df = pd.read_csv(csv_buffer)
293
+ df_sorted = df.sort_index(axis=1) # Sort columns alphabetically
294
+ return df_sorted
295
+
296
+ def to_scenario_list(self, remove_prefix: bool = True) -> list[dict]:
297
+ """Convert the results to a list of dictionaries, one per scenario.
298
+
299
+ :param remove_prefix: Whether to remove the prefix from the column names.
300
+
301
+ >>> from edsl.results import Results
302
+ >>> r = Results.example()
303
+ >>> r.select('how_feeling').to_scenario_list()
304
+ ScenarioList([Scenario({'how_feeling': 'OK'}), Scenario({'how_feeling': 'Great'}), Scenario({'how_feeling': 'Terrible'}), Scenario({'how_feeling': 'OK'})])
305
+ """
306
+ from edsl import ScenarioList, Scenario
307
+
308
+ list_of_dicts = self.to_dicts(remove_prefix=remove_prefix)
309
+ return ScenarioList([Scenario(d) for d in list_of_dicts])
310
+
311
+ def to_agent_list(self, remove_prefix: bool = True):
312
+ from edsl import AgentList, Agent
313
+
314
+ list_of_dicts = self.to_dicts(remove_prefix=remove_prefix)
315
+ return AgentList([Agent(d) for d in list_of_dicts])
316
+
317
+ def to_dicts(self, remove_prefix: bool = True) -> list[dict]:
318
+ """Convert the results to a list of dictionaries.
319
+
320
+ :param remove_prefix: Whether to remove the prefix from the column names.
321
+
322
+ >>> from edsl.results import Results
323
+ >>> r = Results.example()
324
+ >>> r.select('how_feeling').to_dicts()
325
+ [{'how_feeling': 'OK'}, {'how_feeling': 'Great'}, {'how_feeling': 'Terrible'}, {'how_feeling': 'OK'}]
326
+
327
+ """
328
+ list_of_keys = []
329
+ list_of_values = []
330
+ for entry in self:
331
+ key, values = list(entry.items())[0]
332
+ list_of_keys.append(key)
333
+ list_of_values.append(values)
334
+
335
+ if remove_prefix:
336
+ list_of_keys = [key.split(".")[-1] for key in list_of_keys]
337
+
338
+ list_of_dicts = []
339
+ for entries in zip(*list_of_values):
340
+ list_of_dicts.append(dict(zip(list_of_keys, entries)))
341
+
342
+ return list_of_dicts
343
+
344
+ def to_list(self, flatten=False, remove_none=False) -> list[list]:
345
+ """Convert the results to a list of lists.
346
+
347
+ >>> from edsl.results import Results
348
+ >>> Results.example().select('how_feeling', 'how_feeling_yesterday')
349
+ Dataset([{'answer.how_feeling': ['OK', 'Great', 'Terrible', 'OK']}, {'answer.how_feeling_yesterday': ['Great', 'Good', 'OK', 'Terrible']}])
350
+
351
+ >>> Results.example().select('how_feeling', 'how_feeling_yesterday').to_list()
352
+ [('OK', 'Great'), ('Great', 'Good'), ('Terrible', 'OK'), ('OK', 'Terrible')]
353
+
354
+ >>> r = Results.example()
355
+ >>> r.select('how_feeling').to_list()
356
+ ['OK', 'Great', 'Terrible', 'OK']
357
+ """
358
+ if len(self.relevant_columns()) > 1 and flatten:
359
+ raise ValueError(
360
+ "Cannot flatten a list of lists when there are multiple columns selected."
361
+ )
362
+
363
+ if len(self.relevant_columns()) == 1:
364
+ # if only one 'column' is selected (which is typical for this method
365
+ list_to_return = list(self[0].values())[0]
366
+ else:
367
+ keys = self.relevant_columns()
368
+ data = self.to_dicts(remove_prefix=False)
369
+ list_to_return = []
370
+ for d in data:
371
+ list_to_return.append(tuple([d[key] for key in keys]))
372
+
373
+ if remove_none:
374
+ list_to_return = [item for item in list_to_return if item is not None]
375
+
376
+ if flatten:
377
+ new_list = []
378
+ for item in list_to_return:
379
+ if isinstance(item, list):
380
+ new_list.extend(item)
381
+ else:
382
+ new_list.append(item)
383
+ list_to_return = new_list
384
+
385
+ return list_to_return
386
+
387
+ def html(
388
+ self, filename: str = None, cta: str = "Open in browser", return_link=False
389
+ ):
390
+ import os
391
+ import tempfile
392
+ from edsl.utilities.utilities import is_notebook
393
+ from IPython.display import HTML, display
394
+ from edsl.utilities.utilities import is_notebook
395
+
396
+ df = self.to_pandas()
397
+
398
+ if filename is None:
399
+ current_directory = os.getcwd()
400
+ filename = tempfile.NamedTemporaryFile(
401
+ "w", delete=False, suffix=".html", dir=current_directory
402
+ ).name
403
+
404
+ with open(filename, "w") as f:
405
+ f.write(df.to_html())
406
+
407
+ if is_notebook():
408
+ html_url = f"/files/{filename}"
409
+ html_link = f'<a href="{html_url}" target="_blank">{cta}</a>'
410
+ display(HTML(html_link))
411
+ else:
412
+ print(f"Saved to {filename}")
413
+ import webbrowser
414
+ import os
415
+
416
+ webbrowser.open(f"file://{os.path.abspath(filename)}")
417
+
418
+ if return_link:
419
+ return filename
420
+
421
+ def tally(
422
+ self, *fields: Optional[str], top_n=None, output="dict"
423
+ ) -> Union[dict, "Dataset"]:
424
+ """Tally the values of a field or perform a cross-tab of multiple fields.
425
+
426
+ :param fields: The field(s) to tally, multiple fields for cross-tabulation.
427
+
428
+ >>> from edsl.results import Results
429
+ >>> r = Results.example()
430
+ >>> r.select('how_feeling').tally('answer.how_feeling')
431
+ {'OK': 2, 'Great': 1, 'Terrible': 1}
432
+ >>> r.select('how_feeling', 'period').tally('how_feeling', 'period')
433
+ {('OK', 'morning'): 1, ('Great', 'afternoon'): 1, ('Terrible', 'morning'): 1, ('OK', 'afternoon'): 1}
434
+ """
435
+ from collections import Counter
436
+
437
+ if len(fields) == 0:
438
+ fields = self.relevant_columns()
439
+
440
+ relevant_columns_without_prefix = [
441
+ column.split(".")[-1] for column in self.relevant_columns()
442
+ ]
443
+
444
+ if not all(
445
+ f in self.relevant_columns() or f in relevant_columns_without_prefix
446
+ for f in fields
447
+ ):
448
+ raise ValueError("One or more specified fields are not in the dataset.")
449
+
450
+ if len(fields) == 1:
451
+ field = fields[0]
452
+ values = self._key_to_value(field)
453
+ else:
454
+ values = list(zip(*(self._key_to_value(field) for field in fields)))
455
+
456
+ for value in values:
457
+ if isinstance(value, list):
458
+ value = tuple(value)
459
+
460
+ tally = dict(Counter(values))
461
+ sorted_tally = dict(sorted(tally.items(), key=lambda item: -item[1]))
462
+ if top_n is not None:
463
+ sorted_tally = dict(list(sorted_tally.items())[:top_n])
464
+
465
+ import warnings
466
+ import textwrap
467
+ from edsl.results.Dataset import Dataset
468
+
469
+ if output == "dict":
470
+ warnings.warn(
471
+ textwrap.dedent(
472
+ """\
473
+ The default output from tally will change to Dataset in the future.
474
+ Use output='Dataset' to get the Dataset object for now.
475
+ """
476
+ )
477
+ )
478
+ return sorted_tally
479
+ elif output == "Dataset":
480
+ return Dataset(
481
+ [
482
+ {"value": list(sorted_tally.keys())},
483
+ {"count": list(sorted_tally.values())},
484
+ ]
485
+ )
486
+
487
+
488
+ if __name__ == "__main__":
489
+ import doctest
490
+
491
+ doctest.testmod(optionflags=doctest.ELLIPSIS)
edsl/results/Result.py CHANGED
@@ -3,16 +3,7 @@ from __future__ import annotations
3
3
  from collections import UserDict
4
4
  from typing import Any, Type, Callable, Optional
5
5
  from collections import UserDict
6
-
7
- from rich.table import Table
8
-
9
- from IPython.display import display
10
-
11
- from edsl.agents import Agent
12
- from edsl.language_models import LanguageModel
13
- from edsl.scenarios import Scenario
14
6
  from edsl.Base import Base
15
- from edsl.prompts import Prompt
16
7
  from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
17
8
 
18
9
 
@@ -21,6 +12,8 @@ class PromptDict(UserDict):
21
12
 
22
13
  def rich_print(self):
23
14
  """Display an object as a table."""
15
+ from rich.table import Table
16
+
24
17
  table = Table(title="")
25
18
  table.add_column("Attribute", style="bold")
26
19
  table.add_column("Value")
@@ -71,9 +64,9 @@ class Result(Base, UserDict):
71
64
 
72
65
  def __init__(
73
66
  self,
74
- agent: Agent,
75
- scenario: Scenario,
76
- model: Type[LanguageModel],
67
+ agent: "Agent",
68
+ scenario: "Scenario",
69
+ model: Type["LanguageModel"],
77
70
  iteration: int,
78
71
  answer: str,
79
72
  prompt: dict[str, str] = None,
@@ -278,6 +271,12 @@ class Result(Base, UserDict):
278
271
  @remove_edsl_version
279
272
  def from_dict(self, json_dict: dict) -> Result:
280
273
  """Return a Result object from a dictionary representation."""
274
+
275
+ from edsl import Agent
276
+ from edsl import Scenario
277
+ from edsl.language_models.LanguageModel import LanguageModel
278
+ from edsl.prompts.Prompt import Prompt
279
+
281
280
  prompt_data = json_dict.get("prompt", {})
282
281
  prompt_d = {}
283
282
  for prompt_name, prompt_obj in prompt_data.items():
@@ -301,6 +300,7 @@ class Result(Base, UserDict):
301
300
  """Display an object as a table."""
302
301
  # from edsl.utilities import print_dict_with_rich
303
302
  from rich import print
303
+ from rich.table import Table
304
304
 
305
305
  table = Table(title="Result")
306
306
  table.add_column("Attribute", style="bold")
@@ -325,7 +325,7 @@ class Result(Base, UserDict):
325
325
  @classmethod
326
326
  def example(cls):
327
327
  """Return an example Result object."""
328
- from edsl.results import Results
328
+ from edsl.results.Results import Results
329
329
 
330
330
  return Results.example()[0]
331
331
 
@@ -350,59 +350,7 @@ class Result(Base, UserDict):
350
350
  return scoring_function(**params)
351
351
 
352
352
 
353
- def main():
354
- """Run the main function."""
355
- from edsl.results.Result import Result
356
- import json
357
-
358
- print("Being imported")
359
- json_string = """
360
- {
361
- "agent": {
362
- "traits": {
363
- "status": "Unhappy"
364
- }
365
- },
366
- "scenario": {
367
- "period": "morning"
368
- },
369
- "model": {
370
- "model": "gpt-3.5-turbo",
371
- "parameters": {
372
- "temperature": 0.5,
373
- "max_tokens": 1000,
374
- "top_p": 1,
375
- "frequency_penalty": 0,
376
- "presence_penalty": 0,
377
- "use_cache": true
378
- }
379
- },
380
- "iteration": 0,
381
- "answer": {
382
- "how_feeling": "Bad"
383
- },
384
- "prompt": {"how_feeling_user_prompt": "How are you feeling today?", "how_feeling_system_prompt": "Answer the question"}
385
- }
386
- """
387
-
388
- result = Result.from_dict(json.loads(json_string))
389
-
390
- result.sub_dicts
391
- assert result.combined_dict["how_feeling"] == "Bad"
392
-
393
- result.combined_dict
394
- assert result.get_value("answer", "how_feeling") == "Bad"
395
-
396
- result.key_to_data_type
397
- print(result)
398
-
399
- assert result == result.copy()
400
-
401
- result.to_dict()
402
-
403
-
404
353
  if __name__ == "__main__":
405
- # print(Result.example())
406
354
  import doctest
407
355
 
408
356
  doctest.testmod(optionflags=doctest.ELLIPSIS)