edsl 0.1.45__py3-none-any.whl → 0.1.47__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 (44) hide show
  1. edsl/Base.py +87 -16
  2. edsl/__version__.py +1 -1
  3. edsl/agents/PromptConstructor.py +26 -79
  4. edsl/agents/QuestionInstructionPromptBuilder.py +70 -32
  5. edsl/agents/QuestionTemplateReplacementsBuilder.py +12 -2
  6. edsl/coop/coop.py +289 -147
  7. edsl/data/Cache.py +2 -0
  8. edsl/data/CacheEntry.py +10 -2
  9. edsl/data/RemoteCacheSync.py +10 -9
  10. edsl/inference_services/AvailableModelFetcher.py +1 -1
  11. edsl/inference_services/PerplexityService.py +9 -5
  12. edsl/jobs/AnswerQuestionFunctionConstructor.py +12 -1
  13. edsl/jobs/Jobs.py +35 -17
  14. edsl/jobs/JobsComponentConstructor.py +2 -1
  15. edsl/jobs/JobsPrompts.py +49 -26
  16. edsl/jobs/JobsRemoteInferenceHandler.py +4 -5
  17. edsl/jobs/data_structures.py +3 -0
  18. edsl/jobs/interviews/Interview.py +6 -3
  19. edsl/language_models/LanguageModel.py +7 -1
  20. edsl/questions/QuestionBase.py +5 -0
  21. edsl/questions/question_base_gen_mixin.py +2 -0
  22. edsl/questions/question_registry.py +6 -7
  23. edsl/results/DatasetExportMixin.py +124 -6
  24. edsl/results/Results.py +59 -0
  25. edsl/scenarios/FileStore.py +112 -7
  26. edsl/scenarios/ScenarioList.py +283 -21
  27. edsl/study/Study.py +2 -2
  28. edsl/surveys/Survey.py +15 -20
  29. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/METADATA +4 -3
  30. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/RECORD +32 -44
  31. edsl/auto/AutoStudy.py +0 -130
  32. edsl/auto/StageBase.py +0 -243
  33. edsl/auto/StageGenerateSurvey.py +0 -178
  34. edsl/auto/StageLabelQuestions.py +0 -125
  35. edsl/auto/StagePersona.py +0 -61
  36. edsl/auto/StagePersonaDimensionValueRanges.py +0 -88
  37. edsl/auto/StagePersonaDimensionValues.py +0 -74
  38. edsl/auto/StagePersonaDimensions.py +0 -69
  39. edsl/auto/StageQuestions.py +0 -74
  40. edsl/auto/SurveyCreatorPipeline.py +0 -21
  41. edsl/auto/utilities.py +0 -218
  42. edsl/base/Base.py +0 -279
  43. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/LICENSE +0 -0
  44. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/WHEEL +0 -0
@@ -436,35 +436,98 @@ class ScenarioList(Base, UserList, ScenarioListMixin):
436
436
  new_scenarios.append(new_scenario)
437
437
  return ScenarioList(new_scenarios)
438
438
 
439
- def concatenate(self, fields: List[str], separator: str = ";") -> ScenarioList:
440
- """Concatenate specified fields into a single field.
441
-
439
+ def _concatenate(self, fields: List[str], output_type: str = "string", separator: str = ";") -> ScenarioList:
440
+ """Private method to handle concatenation logic for different output types.
441
+
442
442
  :param fields: The fields to concatenate.
443
- :param separator: The separator to use.
444
-
443
+ :param output_type: The type of output ("string", "list", or "set").
444
+ :param separator: The separator to use for string concatenation.
445
+
445
446
  Returns:
446
447
  ScenarioList: A new ScenarioList with concatenated fields.
447
-
448
- Example:
449
- >>> s = ScenarioList([Scenario({'a': 1, 'b': 2, 'c': 3}), Scenario({'a': 4, 'b': 5, 'c': 6})])
450
- >>> s.concatenate(['a', 'b', 'c'])
451
- ScenarioList([Scenario({'concat_a_b_c': '1;2;3'}), Scenario({'concat_a_b_c': '4;5;6'})])
452
448
  """
449
+ # Check if fields is a string and raise an exception
450
+ if isinstance(fields, str):
451
+ raise ScenarioError(
452
+ f"The 'fields' parameter must be a list of field names, not a string. Got '{fields}'."
453
+ )
454
+
453
455
  new_scenarios = []
454
456
  for scenario in self:
455
457
  new_scenario = scenario.copy()
456
- concat_values = []
458
+ values = []
457
459
  for field in fields:
458
460
  if field in new_scenario:
459
- concat_values.append(str(new_scenario[field]))
461
+ values.append(new_scenario[field])
460
462
  del new_scenario[field]
461
463
 
462
464
  new_field_name = f"concat_{'_'.join(fields)}"
463
- new_scenario[new_field_name] = separator.join(concat_values)
465
+
466
+ if output_type == "string":
467
+ # Convert all values to strings and join with separator
468
+ new_scenario[new_field_name] = separator.join(str(v) for v in values)
469
+ elif output_type == "list":
470
+ # Keep as a list
471
+ new_scenario[new_field_name] = values
472
+ elif output_type == "set":
473
+ # Convert to a set (removes duplicates)
474
+ new_scenario[new_field_name] = set(values)
475
+ else:
476
+ raise ValueError(f"Invalid output_type: {output_type}. Must be 'string', 'list', or 'set'.")
477
+
464
478
  new_scenarios.append(new_scenario)
465
479
 
466
480
  return ScenarioList(new_scenarios)
467
481
 
482
+ def concatenate(self, fields: List[str], separator: str = ";") -> ScenarioList:
483
+ """Concatenate specified fields into a single string field.
484
+
485
+ :param fields: The fields to concatenate.
486
+ :param separator: The separator to use.
487
+
488
+ Returns:
489
+ ScenarioList: A new ScenarioList with concatenated fields.
490
+
491
+ Example:
492
+ >>> s = ScenarioList([Scenario({'a': 1, 'b': 2, 'c': 3}), Scenario({'a': 4, 'b': 5, 'c': 6})])
493
+ >>> s.concatenate(['a', 'b', 'c'])
494
+ ScenarioList([Scenario({'concat_a_b_c': '1;2;3'}), Scenario({'concat_a_b_c': '4;5;6'})])
495
+ """
496
+ return self._concatenate(fields, output_type="string", separator=separator)
497
+
498
+ def concatenate_to_list(self, fields: List[str]) -> ScenarioList:
499
+ """Concatenate specified fields into a single list field.
500
+
501
+ :param fields: The fields to concatenate.
502
+
503
+ Returns:
504
+ ScenarioList: A new ScenarioList with fields concatenated into a list.
505
+
506
+ Example:
507
+ >>> s = ScenarioList([Scenario({'a': 1, 'b': 2, 'c': 3}), Scenario({'a': 4, 'b': 5, 'c': 6})])
508
+ >>> s.concatenate_to_list(['a', 'b', 'c'])
509
+ ScenarioList([Scenario({'concat_a_b_c': [1, 2, 3]}), Scenario({'concat_a_b_c': [4, 5, 6]})])
510
+ """
511
+ return self._concatenate(fields, output_type="list")
512
+
513
+ def concatenate_to_set(self, fields: List[str]) -> ScenarioList:
514
+ """Concatenate specified fields into a single set field.
515
+
516
+ :param fields: The fields to concatenate.
517
+
518
+ Returns:
519
+ ScenarioList: A new ScenarioList with fields concatenated into a set.
520
+
521
+ Example:
522
+ >>> s = ScenarioList([Scenario({'a': 1, 'b': 2, 'c': 3}), Scenario({'a': 4, 'b': 5, 'c': 6})])
523
+ >>> s.concatenate_to_set(['a', 'b', 'c'])
524
+ ScenarioList([Scenario({'concat_a_b_c': {1, 2, 3}}), Scenario({'concat_a_b_c': {4, 5, 6}})])
525
+ >>> s = ScenarioList([Scenario({'a': 1, 'b': 1, 'c': 3})])
526
+ >>> s.concatenate_to_set(['a', 'b', 'c'])
527
+ ScenarioList([Scenario({'concat_a_b_c': {1, 3}})])
528
+ """
529
+ return self._concatenate(fields, output_type="set")
530
+
468
531
  def unpack_dict(
469
532
  self, field: str, prefix: Optional[str] = None, drop_field: bool = False
470
533
  ) -> ScenarioList:
@@ -937,16 +1000,42 @@ class ScenarioList(Base, UserList, ScenarioListMixin):
937
1000
  # return new_list
938
1001
 
939
1002
  @classmethod
940
- def from_sqlite(cls, filepath: str, table: str):
941
- """Create a ScenarioList from a SQLite database."""
1003
+ def from_sqlite(cls, filepath: str, table: Optional[str] = None, sql_query: Optional[str] = None):
1004
+ """Create a ScenarioList from a SQLite database.
1005
+
1006
+ Args:
1007
+ filepath (str): Path to the SQLite database file
1008
+ table (Optional[str]): Name of table to query. If None, sql_query must be provided.
1009
+ sql_query (Optional[str]): SQL query to execute. Used if table is None.
1010
+
1011
+ Returns:
1012
+ ScenarioList: List of scenarios created from database rows
1013
+
1014
+ Raises:
1015
+ ValueError: If both table and sql_query are None
1016
+ sqlite3.Error: If there is an error executing the database query
1017
+ """
942
1018
  import sqlite3
943
1019
 
944
- with sqlite3.connect(filepath) as conn:
945
- cursor = conn.cursor()
946
- cursor.execute(f"SELECT * FROM {table}")
947
- columns = [description[0] for description in cursor.description]
948
- data = cursor.fetchall()
949
- return cls([Scenario(dict(zip(columns, row))) for row in data])
1020
+ if table is None and sql_query is None:
1021
+ raise ValueError("Either table or sql_query must be provided")
1022
+
1023
+ try:
1024
+ with sqlite3.connect(filepath) as conn:
1025
+ cursor = conn.cursor()
1026
+
1027
+ if table is not None:
1028
+ cursor.execute(f"SELECT * FROM {table}")
1029
+ else:
1030
+ cursor.execute(sql_query)
1031
+
1032
+ columns = [description[0] for description in cursor.description]
1033
+ data = cursor.fetchall()
1034
+
1035
+ return cls([Scenario(dict(zip(columns, row))) for row in data])
1036
+
1037
+ except sqlite3.Error as e:
1038
+ raise sqlite3.Error(f"Database error occurred: {str(e)}")
950
1039
 
951
1040
  @classmethod
952
1041
  def from_latex(cls, tex_file_path: str):
@@ -1067,6 +1156,7 @@ class ScenarioList(Base, UserList, ScenarioListMixin):
1067
1156
 
1068
1157
  return scenario_list
1069
1158
 
1159
+ @classmethod
1070
1160
  def from_wikipedia(cls, url: str, table_index: int = 0):
1071
1161
  """
1072
1162
  Extracts a table from a Wikipedia page.
@@ -1540,6 +1630,178 @@ class ScenarioList(Base, UserList, ScenarioListMixin):
1540
1630
  new_scenarios.extend(replacement_scenarios)
1541
1631
  return ScenarioList(new_scenarios)
1542
1632
 
1633
+ def collapse(self, field: str) -> ScenarioList:
1634
+ """Collapse a ScenarioList by grouping on all fields except the specified one,
1635
+ collecting the values of the specified field into a list.
1636
+
1637
+ Args:
1638
+ field: The field to collapse (whose values will be collected into lists)
1639
+
1640
+ Returns:
1641
+ ScenarioList: A new ScenarioList with the specified field collapsed into lists
1642
+
1643
+ Example:
1644
+ >>> s = ScenarioList([
1645
+ ... Scenario({'category': 'fruit', 'color': 'red', 'item': 'apple'}),
1646
+ ... Scenario({'category': 'fruit', 'color': 'yellow', 'item': 'banana'}),
1647
+ ... Scenario({'category': 'fruit', 'color': 'red', 'item': 'cherry'}),
1648
+ ... Scenario({'category': 'vegetable', 'color': 'green', 'item': 'spinach'})
1649
+ ... ])
1650
+ >>> s.collapse('item')
1651
+ ScenarioList([Scenario({'category': 'fruit', 'color': 'red', 'item': ['apple', 'cherry']}), Scenario({'category': 'fruit', 'color': 'yellow', 'item': ['banana']}), Scenario({'category': 'vegetable', 'color': 'green', 'item': ['spinach']})])
1652
+ """
1653
+ if not self:
1654
+ return ScenarioList([])
1655
+
1656
+ # Determine all fields except the one to collapse
1657
+ id_vars = [key for key in self[0].keys() if key != field]
1658
+
1659
+ # Group the scenarios
1660
+ grouped = defaultdict(list)
1661
+ for scenario in self:
1662
+ # Create a tuple of the values of all fields except the one to collapse
1663
+ key = tuple(scenario[id_var] for id_var in id_vars)
1664
+ # Add the value of the field to collapse to the list for this key
1665
+ grouped[key].append(scenario[field])
1666
+
1667
+ # Create a new ScenarioList with the collapsed field
1668
+ result = []
1669
+ for key, values in grouped.items():
1670
+ new_scenario = dict(zip(id_vars, key))
1671
+ new_scenario[field] = values
1672
+ result.append(Scenario(new_scenario))
1673
+
1674
+ return ScenarioList(result)
1675
+
1676
+ def create_comparisons(
1677
+ self,
1678
+ bidirectional: bool = False,
1679
+ num_options: int = 2,
1680
+ option_prefix: str = "option_",
1681
+ use_alphabet: bool = False
1682
+ ) -> ScenarioList:
1683
+ """Create a new ScenarioList with comparisons between scenarios.
1684
+
1685
+ Each scenario in the result contains multiple original scenarios as dictionaries,
1686
+ allowing for side-by-side comparison.
1687
+
1688
+ Args:
1689
+ bidirectional (bool): If True, include both (A,B) and (B,A) comparisons.
1690
+ If False, only include (A,B) where A comes before B in the original list.
1691
+ num_options (int): Number of scenarios to include in each comparison.
1692
+ Default is 2 for pairwise comparisons.
1693
+ option_prefix (str): Prefix for the keys in the resulting scenarios.
1694
+ Default is "option_", resulting in keys like "option_1", "option_2", etc.
1695
+ Ignored if use_alphabet is True.
1696
+ use_alphabet (bool): If True, use letters as keys (A, B, C, etc.) instead of
1697
+ the option_prefix with numbers.
1698
+
1699
+ Returns:
1700
+ ScenarioList: A new ScenarioList where each scenario contains multiple original
1701
+ scenarios as dictionaries.
1702
+
1703
+ Example:
1704
+ >>> s = ScenarioList([
1705
+ ... Scenario({'id': 1, 'text': 'Option A'}),
1706
+ ... Scenario({'id': 2, 'text': 'Option B'}),
1707
+ ... Scenario({'id': 3, 'text': 'Option C'})
1708
+ ... ])
1709
+ >>> s.create_comparisons(use_alphabet=True)
1710
+ ScenarioList([Scenario({'A': {'id': 1, 'text': 'Option A'}, 'B': {'id': 2, 'text': 'Option B'}}), Scenario({'A': {'id': 1, 'text': 'Option A'}, 'B': {'id': 3, 'text': 'Option C'}}), Scenario({'A': {'id': 2, 'text': 'Option B'}, 'B': {'id': 3, 'text': 'Option C'}})])
1711
+ >>> s.create_comparisons(num_options=3, use_alphabet=True)
1712
+ ScenarioList([Scenario({'A': {'id': 1, 'text': 'Option A'}, 'B': {'id': 2, 'text': 'Option B'}, 'C': {'id': 3, 'text': 'Option C'}})])
1713
+ """
1714
+ from itertools import combinations, permutations
1715
+ import string
1716
+
1717
+ if num_options < 2:
1718
+ raise ValueError("num_options must be at least 2")
1719
+
1720
+ if num_options > len(self):
1721
+ raise ValueError(f"num_options ({num_options}) cannot exceed the number of scenarios ({len(self)})")
1722
+
1723
+ if use_alphabet and num_options > 26:
1724
+ raise ValueError("When using alphabet labels, num_options cannot exceed 26 (the number of letters in the English alphabet)")
1725
+
1726
+ # Convert each scenario to a dictionary
1727
+ scenario_dicts = [scenario.to_dict(add_edsl_version=False) for scenario in self]
1728
+
1729
+ # Generate combinations or permutations based on bidirectional flag
1730
+ if bidirectional:
1731
+ # For bidirectional, use permutations to get all ordered arrangements
1732
+ if num_options == 2:
1733
+ # For pairwise, we can use permutations with r=2
1734
+ scenario_groups = permutations(scenario_dicts, 2)
1735
+ else:
1736
+ # For more than 2 options with bidirectional=True,
1737
+ # we need all permutations of the specified size
1738
+ scenario_groups = permutations(scenario_dicts, num_options)
1739
+ else:
1740
+ # For unidirectional, use combinations to get unordered groups
1741
+ scenario_groups = combinations(scenario_dicts, num_options)
1742
+
1743
+ # Create new scenarios with the combinations
1744
+ result = []
1745
+ for group in scenario_groups:
1746
+ new_scenario = {}
1747
+ for i, scenario_dict in enumerate(group):
1748
+ if use_alphabet:
1749
+ # Use uppercase letters (A, B, C, etc.)
1750
+ key = string.ascii_uppercase[i]
1751
+ else:
1752
+ # Use the option prefix with numbers (option_1, option_2, etc.)
1753
+ key = f"{option_prefix}{i+1}"
1754
+ new_scenario[key] = scenario_dict
1755
+ result.append(Scenario(new_scenario))
1756
+
1757
+ return ScenarioList(result)
1758
+
1759
+ @classmethod
1760
+ def from_parquet(cls, filepath: str) -> ScenarioList:
1761
+ """Create a ScenarioList from a Parquet file.
1762
+
1763
+ Args:
1764
+ filepath (str): Path to the Parquet file
1765
+
1766
+ Returns:
1767
+ ScenarioList: A ScenarioList containing the data from the Parquet file
1768
+
1769
+ Example:
1770
+ >>> import pandas as pd
1771
+ >>> import tempfile
1772
+ >>> df = pd.DataFrame({'name': ['Alice', 'Bob'], 'age': [30, 25]})
1773
+ >>> # The following would create and read a parquet file if dependencies are installed:
1774
+ >>> # with tempfile.NamedTemporaryFile(suffix='.parquet', delete=False) as f:
1775
+ >>> # df.to_parquet(f.name)
1776
+ >>> # scenario_list = ScenarioList.from_parquet(f.name)
1777
+ >>> # Instead, we'll demonstrate the equivalent result:
1778
+ >>> scenario_list = ScenarioList.from_pandas(df)
1779
+ >>> len(scenario_list)
1780
+ 2
1781
+ >>> scenario_list[0]['name']
1782
+ 'Alice'
1783
+ """
1784
+ import pandas as pd
1785
+
1786
+ try:
1787
+ # Try to read the Parquet file with pandas
1788
+ df = pd.read_parquet(filepath)
1789
+ except ImportError as e:
1790
+ # Handle missing dependencies with a helpful error message
1791
+ if "pyarrow" in str(e) or "fastparquet" in str(e):
1792
+ raise ImportError(
1793
+ "Missing dependencies for Parquet support. Please install either pyarrow or fastparquet:\n"
1794
+ " pip install pyarrow\n"
1795
+ " or\n"
1796
+ " pip install fastparquet"
1797
+ ) from e
1798
+ else:
1799
+ raise
1800
+
1801
+ # Convert the DataFrame to a ScenarioList
1802
+ return cls.from_pandas(df)
1803
+
1804
+
1543
1805
 
1544
1806
  if __name__ == "__main__":
1545
1807
  import doctest
edsl/study/Study.py CHANGED
@@ -504,12 +504,12 @@ class Study:
504
504
  )
505
505
 
506
506
  @classmethod
507
- def pull(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
507
+ def pull(cls, url_or_uuid: Union[str, UUID]):
508
508
  """Pull the object from coop."""
509
509
  from edsl.coop import Coop
510
510
 
511
511
  coop = Coop()
512
- return coop.get(uuid, url, "study")
512
+ return coop.get(url_or_uuid, "study")
513
513
 
514
514
  def __repr__(self):
515
515
  return f"""Study(name = "{self.name}", description = "{self.description}", objects = {self.objects}, cache = {self.cache}, filename = "{self.filename}", coop = {self.coop}, use_study_cache = {self.use_study_cache}, overwrite_on_change = {self.overwrite_on_change})"""
edsl/surveys/Survey.py CHANGED
@@ -172,6 +172,13 @@ class Survey(SurveyExportMixin, Base):
172
172
 
173
173
  self._seed = None
174
174
 
175
+ # Cache the InstructionCollection
176
+ self._cached_instruction_collection = None
177
+
178
+ def question_names_valid(self) -> bool:
179
+ """Check if the question names are valid."""
180
+ return all(q.is_valid_question_name() for q in self.questions)
181
+
175
182
  def draw(self) -> "Survey":
176
183
  """Return a new survey with a randomly selected permutation of the options."""
177
184
  if self._seed is None: # only set once
@@ -205,28 +212,16 @@ class Survey(SurveyExportMixin, Base):
205
212
  # region: Survey instruction handling
206
213
  @property
207
214
  def _relevant_instructions_dict(self) -> InstructionCollection:
208
- """Return a dictionary with keys as question names and values as instructions that are relevant to the question.
209
-
210
- >>> s = Survey.example(include_instructions=True)
211
- >>> s._relevant_instructions_dict
212
- {'q0': [Instruction(name="attention", text="Please pay attention!")], 'q1': [Instruction(name="attention", text="Please pay attention!")], 'q2': [Instruction(name="attention", text="Please pay attention!")]}
213
-
214
- """
215
- return InstructionCollection(
216
- self._instruction_names_to_instructions, self.questions
217
- )
215
+ """Return a dictionary with keys as question names and values as instructions that are relevant to the question."""
216
+ if self._cached_instruction_collection is None:
217
+ self._cached_instruction_collection = InstructionCollection(
218
+ self._instruction_names_to_instructions, self.questions
219
+ )
220
+ return self._cached_instruction_collection
218
221
 
219
222
  def _relevant_instructions(self, question: QuestionBase) -> dict:
220
- """This should be a dictionry with keys as question names and values as instructions that are relevant to the question.
221
-
222
- :param question: The question to get the relevant instructions for.
223
-
224
- # Did the instruction come before the question and was it not modified by a change instruction?
225
-
226
- """
227
- return InstructionCollection(
228
- self._instruction_names_to_instructions, self.questions
229
- )[question]
223
+ """Return instructions that are relevant to the question."""
224
+ return self._relevant_instructions_dict[question]
230
225
 
231
226
  def show_flow(self, filename: Optional[str] = None) -> None:
232
227
  """Show the flow of the survey."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.45
3
+ Version: 0.1.47
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
17
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Provides-Extra: screenshots
19
20
  Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
20
21
  Requires-Dist: anthropic (>=0.45.0,<0.46.0)
21
22
  Requires-Dist: azure-ai-inference (>=1.0.0b3,<2.0.0)
@@ -239,8 +240,8 @@ An integrated platform for running experiments, sharing workflows and launching
239
240
  - <a href="https://discord.com/invite/mxAYkjfy9m" target="_blank" rel="noopener noreferrer">Discord</a>
240
241
  - <a href="https://x.com/ExpectedParrot" target="_blank" rel="noopener noreferrer">Twitter</a>
241
242
  - <a href="https://www.linkedin.com/company/expectedparrot/" target="_blank" rel="noopener noreferrer">LinkedIn</a>
242
- - <a href="https://blog.expectedparrot.com" target="_blank" rel="noopener noreferrer">Blog</a>
243
+ - <a href="https://blog.expectedparrot.com" target="_blank" rel="noopener noreferrer">Blog</a>.
243
244
 
244
245
  ## Contact
245
- - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>.
246
+ - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>
246
247
 
@@ -1,31 +1,19 @@
1
- edsl/Base.py,sha256=Mozyr7Mao_WwBA1YynlJ9gqm8oymtZ5WSbwEIdPVjPY,13256
1
+ edsl/Base.py,sha256=6FfnzsUtqSaRyzxL5WXh5mAZT1KgQaT3lrYWiJKqUNc,15252
2
2
  edsl/BaseDiff.py,sha256=92BirXj2u3TEGHJWni9TBsvZjvq8wpb4wDL2vxX9Lb0,8253
3
3
  edsl/TemplateLoader.py,sha256=sDBlSMt7EfOduM7w3h6v03gvh_Rzn9hVrlS-iLSQdZA,849
4
4
  edsl/__init__.py,sha256=iB5q_P2pXDV6Wb5oHKsFDhi_rJXID0aaqio1I98dwXA,1936
5
- edsl/__version__.py,sha256=G1Bw5SEeRoSlHVxmFKf6PIpK38SHTYTFhSFGm9d8YQM,23
5
+ edsl/__version__.py,sha256=BqdH88p7_x5NtwJCtqUPLKt1fAJF1mVKUoKH7vlX5dQ,23
6
6
  edsl/agents/Agent.py,sha256=lF7GD_bCvRLP4hrtm3w451AUfuJln5jZHGYBH84CMVE,40741
7
7
  edsl/agents/AgentList.py,sha256=iRfQfyUYtaJbJ3sRubPqPKRr77nKQgzhFEeZ0wcAEk0,18955
8
8
  edsl/agents/Invigilator.py,sha256=SObe7PC08XoWNpOubZMFlVKPN8nfZplYBwY9LXJou8c,12084
9
9
  edsl/agents/InvigilatorBase.py,sha256=SfpKlZm3oP6b0XIMSK5c1oD3MUevemUe7qNfqsokY40,9098
10
- edsl/agents/PromptConstructor.py,sha256=6EShFpyYlR42uZSAXQjPkqcch4P1MXYyv7btt_TZnv8,14488
11
- edsl/agents/QuestionInstructionPromptBuilder.py,sha256=wl3UdlZaFdwsJpxHV_ruzQZg5P22b33zV3mbVdwYGAw,8764
12
- edsl/agents/QuestionTemplateReplacementsBuilder.py,sha256=yiOmeH0bF742hJ8JbRA-aRkidzVD7jmTfRd71TmWByE,8231
10
+ edsl/agents/PromptConstructor.py,sha256=az29xdlMmuR6tYDDmn5AOHZhtHIPLqdneD89ff_Qh_A,12218
11
+ edsl/agents/QuestionInstructionPromptBuilder.py,sha256=D1hI4Z1w4TTQ_DmsfGAcX53zd8NI01tQS-Cfqr2L-jI,9426
12
+ edsl/agents/QuestionTemplateReplacementsBuilder.py,sha256=57ZztPSw0kVWg2HG8NU58qMJdVMn1xEFv0tyZYOJXHI,8767
13
13
  edsl/agents/__init__.py,sha256=a3H1lxDwu9HR8fwh79C5DgxPSFv_bE2rzQ6y1D8Ba5c,80
14
14
  edsl/agents/descriptors.py,sha256=JxM_ckzhDmfZT1igSUdCxgyQcCK0o9MhU5jbLIned9g,3189
15
15
  edsl/agents/prompt_helpers.py,sha256=JkVRPrLQ1egPqbBKcgR22c6WYnTU4QjzZG5HwxDEHjs,5076
16
16
  edsl/agents/question_option_processor.py,sha256=ozh6XqW8z_eaXRauncYifOvEgsmb29F4FMapxhW3hCY,6715
17
- edsl/auto/AutoStudy.py,sha256=XniD-g7jg19vbD5CWqq0QAiMsIz2CboKAAIluDODqzo,4326
18
- edsl/auto/StageBase.py,sha256=7ZjV0T-8FQBL-r5LeAozNQY_0RJ_GySdX48ToM7-dLc,8254
19
- edsl/auto/StageGenerateSurvey.py,sha256=_lC1-hhFjqd6md1-RE9uEOPtZp7dZHxJn0ERpszSfow,7394
20
- edsl/auto/StageLabelQuestions.py,sha256=8uHrDi6t-o_NgumfguiCENsNU3rmYF4nmanTMEtbkYI,4663
21
- edsl/auto/StagePersona.py,sha256=1oqHedJGmT1E0F5F-5uq36SudkP7d4FHDd8mbmb5hOw,1886
22
- edsl/auto/StagePersonaDimensionValueRanges.py,sha256=z_fJJK4vydId13IVQnI92RUoDQkl6Tr9XxUOMNrKyYI,2933
23
- edsl/auto/StagePersonaDimensionValues.py,sha256=o6xUVkYLa1wooY5mDmy1j8bGQbK4EzUZ-Zqi7Lfv1hI,2313
24
- edsl/auto/StagePersonaDimensions.py,sha256=9tjZJGA1ytTgMlTspRrYKRXj0QYvkWx9Yg5Comf_x8k,2069
25
- edsl/auto/StageQuestions.py,sha256=f2h0z-1slFDxdriM9Wxb9BiGLmQLL-VTHu3MK0XEIig,2209
26
- edsl/auto/SurveyCreatorPipeline.py,sha256=b1rvJ1u_snPzdXIotfv_Zq3LV7OQVpIicudiFpny-S4,660
27
- edsl/auto/utilities.py,sha256=Wfl0VYxnarhFB2NrJYwmswG_JwJ2AyqOPpS3smVoEFU,7402
28
- edsl/base/Base.py,sha256=dTXYSNcmNbkUVe6cv5kskJOmY1bbTRgQw0OGdtH_Dck,8534
29
17
  edsl/config.py,sha256=iL5r-JAFGN7-05p3NX4FKICEBb_gOG7CWmVd1C_ZkhQ,6951
30
18
  edsl/conversation/Conversation.py,sha256=GDGEq_2_ni1hEUM__2x2MBoaw4GZ1Nl5RqyvLiA5wzs,9589
31
19
  edsl/conversation/car_buying.py,sha256=SmRd-_L62AmiZJK5UgJV3_tYTsVPTpEYQWb81ygN9Xo,1964
@@ -36,12 +24,12 @@ edsl/coop/CoopFunctionsMixin.py,sha256=5Vm8fFTRSg9dFnNBxYqZpeUABSZa2Ttzaal6zB13F
36
24
  edsl/coop/ExpectedParrotKeyHandler.py,sha256=1lriainznM1FfQ7GEvTiI1EW8uNi8Sms3Vt5UDxso3U,4456
37
25
  edsl/coop/PriceFetcher.py,sha256=J5EaM-bPqnd2B0ZBVVqXJ-UQK-D4SdjmddYepnN7jz4,1777
38
26
  edsl/coop/__init__.py,sha256=4iZCwJSzJVyjBYk8ggGxY2kZjq9dXVT1jhyPDNyew4I,115
39
- edsl/coop/coop.py,sha256=h2fusj3mZGxC-Dd_ySfNQwPYVLH2Igm4sryx-9sB2-s,44391
27
+ edsl/coop/coop.py,sha256=zdTezq4OGIp8U9U48F_rxd4fafp79c2ePK9ceOsPjUo,49650
40
28
  edsl/coop/utils.py,sha256=SBV76sk5_2rhP3RKGkJsOkrx9Qr-jD0puqYhVR_MgSY,3900
41
- edsl/data/Cache.py,sha256=ryMWLowyXa8VwWKru-0pF43JHh2UVyL5Zezst-26J6c,18510
42
- edsl/data/CacheEntry.py,sha256=mTc-WG_dWc4s9s3MrOl3yUqao2Q_igCerNcluM4XCSQ,7376
29
+ edsl/data/Cache.py,sha256=b6n5e7VwHMRRevPKe1g9PHXLDS9DA9OAD07ht6SOS8s,18561
30
+ edsl/data/CacheEntry.py,sha256=pfau_At962iylwwoMOzwHqmSiIb56dibZHXKUHCZ9FU,7753
43
31
  edsl/data/CacheHandler.py,sha256=wy2AdKkk_pmwP71htdmLV9UzXM4AuHm5pn1qscJlX9s,5150
44
- edsl/data/RemoteCacheSync.py,sha256=QVTVjpcGVZz1VxYXZPP7kBGsU9fXOS6EHALHOnQLfRU,6094
32
+ edsl/data/RemoteCacheSync.py,sha256=kGVQYShpuhouF10PhdLlJ1ZO6H3aJtKihl7QAcc_rpY,6124
45
33
  edsl/data/SQLiteDict.py,sha256=V5Nfnxctgh4Iblqcw1KmbnkjtfmWrrombROSQ3mvg6A,8979
46
34
  edsl/data/__init__.py,sha256=i_bbYBc-vrdASBpDMcpIcfhbLKYOkvqA57R3ysBcQ6o,177
47
35
  edsl/data/orm.py,sha256=Jz6rvw5SrlxwysTL0QI9r68EflKxeEBmf6j6himHDS8,238
@@ -65,7 +53,7 @@ edsl/exceptions/scenarios.py,sha256=j4OE9xrSrLKdRMwmr3webIRHBwBgvx0DL0uDThRW7yY,
65
53
  edsl/exceptions/surveys.py,sha256=BJUKFVkj6nrsq3TyvaZfEE-zjy3BCAM-s1lsdcrv_MM,677
66
54
  edsl/inference_services/AnthropicService.py,sha256=BDT6-28M0BmRDT60jmPQ056Z6yMocHIe_UjrmwY5rC8,3980
67
55
  edsl/inference_services/AvailableModelCacheHandler.py,sha256=9zGT1Huz0VTOZyN5GpakcMAe6pZyYmZcdSzuqPUZ09g,6179
68
- edsl/inference_services/AvailableModelFetcher.py,sha256=LlBPXjadXJVvmqAgpQcujauWod9NgbOlyfhzZiUdPZo,8037
56
+ edsl/inference_services/AvailableModelFetcher.py,sha256=YKejiwgHbVM31qYs73JURUSysdctp6r-EDoJH84oJZI,8061
69
57
  edsl/inference_services/AwsBedrock.py,sha256=vs83ickoxkjKoR78cPgGQzpeaLRPLaWG857nDzlJZv0,3974
70
58
  edsl/inference_services/AzureAI.py,sha256=QSR0dgZWw4PhP3mI6nAdiC1YOqGS8PZEb2cuBsRQQR8,8972
71
59
  edsl/inference_services/DeepInfraService.py,sha256=fWlH5sCNxf8eHPHxPPxJMEVWpCM9sDenkC8IZYqtXfA,515
@@ -77,7 +65,7 @@ edsl/inference_services/InferenceServicesCollection.py,sha256=i0eaf5K6zGbPfpuFhz
77
65
  edsl/inference_services/MistralAIService.py,sha256=GHKZXtB4npdSpUvLqLc-OBJaihJpmky67NWBH_ql8xk,3763
78
66
  edsl/inference_services/OllamaService.py,sha256=oro9CRl8IUE2Ro-zE69Cr4Zaf6Gdw29XW5CFU-46E0k,498
79
67
  edsl/inference_services/OpenAIService.py,sha256=O5eavTstXPnMHHMcOS9kmMHHEO_CkUJ5o_bgumiNxbI,8470
80
- edsl/inference_services/PerplexityService.py,sha256=u852C6rQ2FoEXa9mqf2XjVE90y4FvZ3HPPwkNQWQzv0,5664
68
+ edsl/inference_services/PerplexityService.py,sha256=TPClKR3nlkg8LipNCcZWLTqk4Fh9VHs_F08BLpd9VRo,5787
81
69
  edsl/inference_services/ServiceAvailability.py,sha256=z2GaZ7Qt2qILcRTVl1X7zZVlPFOP3THntB5WSgbbesQ,4741
82
70
  edsl/inference_services/TestService.py,sha256=sLme9cgQsR0Nzdew3GyDpdfTeEEByxeak4YiodSZKvI,2986
83
71
  edsl/inference_services/TogetherAIService.py,sha256=fe349fdJQw-9OHz5mDGa5qxdC9Nccz0MtkisNIZjBkI,6360
@@ -88,16 +76,16 @@ edsl/inference_services/models_available_cache.py,sha256=bOvevfRn2HlmBcHalaDkjFL
88
76
  edsl/inference_services/rate_limits_cache.py,sha256=HYslviz7mxF9U4CUTPAkoyBsiXjSju-YCp4HHir6e34,1398
89
77
  edsl/inference_services/registry.py,sha256=feFqywZs0ogzOheIMdKA_NWVPj1p8Iaik3O8_RbuVFs,1498
90
78
  edsl/inference_services/write_available.py,sha256=NNwhATlaMp8IYY635MSx-oYxt5X15acjAfaqYCo_I1Y,285
91
- edsl/jobs/AnswerQuestionFunctionConstructor.py,sha256=wNM2HNhEQLYO8BRCfzqPGpJrqmtw0FBkGPa_VUe9emQ,7977
79
+ edsl/jobs/AnswerQuestionFunctionConstructor.py,sha256=4-sw2nyH4rfzZafldDKGI2NzVXGYHXBFKtsLP3Vaw90,8408
92
80
  edsl/jobs/Answers.py,sha256=lZpbGAqYqMQw7MUsmpivqMZkHjHHOmCY32s9Km284pQ,1445
93
81
  edsl/jobs/FetchInvigilator.py,sha256=83tbrqY_1qK0biNF1x51N0sFx49FFmuOi3o5HmFuCIY,1785
94
82
  edsl/jobs/InterviewTaskManager.py,sha256=I1GShC2CrBFnGOcWn3q2YUU0SJbesmeLrrM2_nkuhZo,3748
95
83
  edsl/jobs/InterviewsConstructor.py,sha256=MyRgygmi4318PgERjhhZZXlNUju2lB1CBu8LJJjYNSs,1853
96
- edsl/jobs/Jobs.py,sha256=lZ2pszXM_F_aY1HoP8qPrbrKymREdMiLw_3VfgFrs4M,31182
84
+ edsl/jobs/Jobs.py,sha256=1hWygFykW9jlPDFJSwJfLA3jjtYph3tW9BrCj6zdpM4,32105
97
85
  edsl/jobs/JobsChecks.py,sha256=2KT_Bs41SR0-0ryYC99VrE9j7V2ICxf9nPe21YHp67o,5265
98
- edsl/jobs/JobsComponentConstructor.py,sha256=yzjBFQx1oK8CN2taniB82kpXo6W712dIG1E9ouwkujg,6969
99
- edsl/jobs/JobsPrompts.py,sha256=XA52HydVoIWZqmVMnfpTrM1M1vMutNYZR3bUqhilBUk,12831
100
- edsl/jobs/JobsRemoteInferenceHandler.py,sha256=UC5LM7bedT9WabqspfdFo2HW6CRNJFNkjh-pSJqu3nU,11464
86
+ edsl/jobs/JobsComponentConstructor.py,sha256=Bzg0_5Plw1DlwT6RSgUfJheCF8AIFhim7eByBryL-XA,7034
87
+ edsl/jobs/JobsPrompts.py,sha256=NuHtCXskGHLX1Y6SbBTFlfbGxwPvX3m2esjoUsl-hpQ,13179
88
+ edsl/jobs/JobsRemoteInferenceHandler.py,sha256=RyDjUm4FZvVRxk3rFciNcfqQnuk4f1mCj_KNg7iZy_k,11495
101
89
  edsl/jobs/JobsRemoteInferenceLogger.py,sha256=rUaImMQWVZO24i8cXBeDpd4rMu3fUSbolfqBNbrG1ms,9265
102
90
  edsl/jobs/RequestTokenEstimator.py,sha256=IF2sb1Tt_exzNyWnuvd8mm81gfyZsv-rUP-GUHBX32E,1183
103
91
  edsl/jobs/__init__.py,sha256=aKuAyd_GoalGj-k7djOoVwEbFUE2XLPlikXaA1_8yAg,32
@@ -108,9 +96,9 @@ edsl/jobs/buckets/TokenBucket.py,sha256=DNv5aOO8kwq3PvCXg84HCBhYFkzSiOqLBLiEJRFu
108
96
  edsl/jobs/buckets/TokenBucketAPI.py,sha256=ht0b-xZvzaR9ymhjin4c1AZwapuLPOoJ2N9hViSPuA4,6847
109
97
  edsl/jobs/buckets/TokenBucketClient.py,sha256=Jx20nDAdUSh3USUX9B4PHd1uAFMdyOHtRa2phzFnh-w,7095
110
98
  edsl/jobs/check_survey_scenario_compatibility.py,sha256=JTn2FOaPAZmcitRrysr8KvvSaG7Xia_bey0ZEK5N0pc,3826
111
- edsl/jobs/data_structures.py,sha256=VwMLmfAiajRzdy1ruJJC-v3gU2FkOVnbsC9NZjpystw,3756
99
+ edsl/jobs/data_structures.py,sha256=wEjmQjARia09UAWF6H5vSkieajku8pQk40JnGweAwoE,3870
112
100
  edsl/jobs/decorators.py,sha256=vpeSgI3EP4RFz5V_OclFdnhiSrswihavAN8C9ygRhGE,1135
113
- edsl/jobs/interviews/Interview.py,sha256=GTUS1yuz1dCtlHEVe2N76qTSpmk6OecR5PMkDAjRzsQ,15051
101
+ edsl/jobs/interviews/Interview.py,sha256=xWeT2cPWtfd__nIX9ZnEVUVClEcqYYMeKY1UI40mbiE,15223
114
102
  edsl/jobs/interviews/InterviewExceptionCollection.py,sha256=ZIe9nnI8pznxp1D0K2Ii9SHorc9-f0k_lQV-Giq41P8,3666
115
103
  edsl/jobs/interviews/InterviewExceptionEntry.py,sha256=A-7QGREECViHc1bZoPXXvJxgQ5aW-PdgOxADH-G7h9A,6478
116
104
  edsl/jobs/interviews/InterviewStatistic.py,sha256=hY5d2EkIJ96NilPpZAvZZzZoxLXM7ss3xx5MIcKtTPs,1856
@@ -133,7 +121,7 @@ edsl/jobs/tasks/task_status_enum.py,sha256=FLmfSgHSbB921UyC-mvKpBLg5HLRf_NbHKXF4
133
121
  edsl/jobs/tokens/InterviewTokenUsage.py,sha256=u_6-IHpGFwZ6qMEXr24-jyLVUSSp4dSs_4iAZsBv7O4,1100
134
122
  edsl/jobs/tokens/TokenUsage.py,sha256=odj2-wDNEbHl9noyFAQ0DSKV0D9cv3aDOpmXufKZ8O4,1323
135
123
  edsl/language_models/ComputeCost.py,sha256=SLP_tQiZwMonlIVAsOseWpN4Gd3zVirSxN2WJsO5kzs,2310
136
- edsl/language_models/LanguageModel.py,sha256=zB4WD9SDKf1PSukH_pF_O_mFdZkGf8dM91NYVnOz9OU,21881
124
+ edsl/language_models/LanguageModel.py,sha256=rnnIwbCzX2BZm6vQPmDfbjMdPgfY6FQx_CXEK3Pv0SE,22078
137
125
  edsl/language_models/ModelList.py,sha256=n8OWnPBeKT66XsXvbG5xWqvrs7MHBiuuFWp82gVQD0o,4731
138
126
  edsl/language_models/PriceManager.py,sha256=Atl2715WOl9u4cU1a_S_Ycrejc787T8_mi_o-DENCeQ,5757
139
127
  edsl/language_models/RawResponseHandler.py,sha256=4ekXsNlDUOb_cfzmfJLS-KIjQXjf6xGgGdDgloqANxI,3904
@@ -157,7 +145,7 @@ edsl/prompts/Prompt.py,sha256=gSpMneHIlfOr1_rxWKiMdFMC98w458dg0KEFQDJmLAA,14081
157
145
  edsl/prompts/__init__.py,sha256=wrtkH7JW72U93_pnmTvqQx_NoadH5OPRNfrZ5AaD7Co,87
158
146
  edsl/questions/ExceptionExplainer.py,sha256=BgM80FRPJjS_TrY6XaVmlT666MzY9DEagviGQj9-WEQ,2868
159
147
  edsl/questions/HTMLQuestion.py,sha256=mRzVpfFLZ2RYBSDbLHeXTyAXbUHorpiwhNf-nuUSC5M,3431
160
- edsl/questions/QuestionBase.py,sha256=2x4uMYxc2JDlF_IxTp-WKWZZtTSrZr3EthHHvDVhtUI,19280
148
+ edsl/questions/QuestionBase.py,sha256=plUPstwR4G50LnQ8n3m_W8mw7EdvZQel6Z1RqaGug1Q,19496
161
149
  edsl/questions/QuestionBasePromptsMixin.py,sha256=7Pboia46duzxwKcyO0CXcP3PxtAwD3inv_IFfmm3Oy4,11740
162
150
  edsl/questions/QuestionBudget.py,sha256=fBxDRfPJ3HctSCNTzqGLPuRCACySb3NHugXCNE7pXH8,8133
163
151
  edsl/questions/QuestionCheckBox.py,sha256=ho_tyr3a6gHcA2kWlfz0dSW_-2yd6ifdC3niPPPQJAY,12847
@@ -192,8 +180,8 @@ edsl/questions/prompt_templates/question_linear_scale.jinja,sha256=VB9bFPeLGGb5a
192
180
  edsl/questions/prompt_templates/question_list.jinja,sha256=MAkNv88E79jXK9TxKdnf5KgA77CWz9vXc2TZm2r-g-A,495
193
181
  edsl/questions/prompt_templates/question_multiple_choice.jinja,sha256=sSyAhnexZF6oWqHL-45r7o69vrFcCbbYXLZ3zu7q76U,761
194
182
  edsl/questions/prompt_templates/question_numerical.jinja,sha256=c20sp3HfFonfaRwwmnF7HjAEugU15QlgpNAIkNHasl0,1218
195
- edsl/questions/question_base_gen_mixin.py,sha256=5Jy_bRzaa7s7-p7Gw2QDrZRnf9id0m0eCJwIs97b5qM,9945
196
- edsl/questions/question_registry.py,sha256=H4Q4JYMHn7-_5rU7Ap26N6Ruzz9WSZqOf1b89MScIDI,6352
183
+ edsl/questions/question_base_gen_mixin.py,sha256=6cW1Pw8ErAPErWB5iBoWrXIAWj0gRBnfjA_hfeyYefQ,10028
184
+ edsl/questions/question_registry.py,sha256=S3gJ5k8XAq_IP2DrfVv7HTyLj5LhAsjVqNLXU0tJa7Q,6239
197
185
  edsl/questions/register_questions_meta.py,sha256=2h_9iZt3cjr_7JRmveTqbmEBBCvjtefMDfhM7Pgd_zg,2598
198
186
  edsl/questions/response_validator_abc.py,sha256=410DIb8Z5uF_xu1lG32OF6X7aoOtL6gG3UIMY83kfeo,6838
199
187
  edsl/questions/response_validator_factory.py,sha256=IzRHHcr2CjWFLgCHXHojwWa5Erc6E8pilTLys1M-5zE,1301
@@ -244,12 +232,12 @@ edsl/questions/templates/yes_no/answering_instructions.jinja,sha256=UAcssfcYeW8z
244
232
  edsl/questions/templates/yes_no/question_presentation.jinja,sha256=hoEVj4GQD3EYnR2AStXkMFOJeqISNoEVzBd8-cx2yWg,273
245
233
  edsl/results/CSSParameterizer.py,sha256=vI3VTgTihJeCYGfmGp7fOhTitHZ17jrDGbq46Sa2rd8,3677
246
234
  edsl/results/Dataset.py,sha256=81Wf7NAlXfOht4cVFFTLo3lMpTqsPtBq7txLBtJESHw,22495
247
- edsl/results/DatasetExportMixin.py,sha256=4K3k-RcBI7Z_s-8cigHoLfN8M6DnJFvy19OWJ-AoFMQ,33125
235
+ edsl/results/DatasetExportMixin.py,sha256=6g_mmnqFUz-RbUzGnOHkOCM2htAggnSA0dcoJQ_l5Hk,37739
248
236
  edsl/results/DatasetTree.py,sha256=nvNCF9psLcQ65qsxze7qkrhLn-U-N8OJ327Nf-sFskQ,10178
249
237
  edsl/results/MarkdownToDocx.py,sha256=e8kdDPoqS6Zvd8OTldP9AXbjtmr8BZnro7f0-g1ENi4,4123
250
238
  edsl/results/MarkdownToPDF.py,sha256=RgQ8V86AD_h0HlohUiTWcbL8zOpI8xFC4FK-aOh26HE,3608
251
239
  edsl/results/Result.py,sha256=Rg3SeD2v30zI92jQb25WGgcnyPGcTUXVE5wzeKkLvuQ,22611
252
- edsl/results/Results.py,sha256=eo9DgxFklrpUwtAAdzwcM0wG5RlEoEYf-UboAwo6CgY,49087
240
+ edsl/results/Results.py,sha256=8HUq_jppThd9ymg2AXr4ggaW_VbhVUHJUoAT9lwxRS0,51654
253
241
  edsl/results/ResultsExportMixin.py,sha256=v9N4pUMrycmKIDzdWn1grmx7F8lxIPAOjfV6OScYSwc,1379
254
242
  edsl/results/ResultsGGMixin.py,sha256=h42-fmicXgGDi71y2kgPSPAS9wTjYYS5_VQELBcp-cM,6625
255
243
  edsl/results/TableDisplay.py,sha256=xGJcotgUqWrmCkQLeD9YIwLrNv7su4VDce3EnllfrLQ,3725
@@ -267,11 +255,11 @@ edsl/results/tree_explore.py,sha256=hQjiO4E71rIOPDgEHgK8T8ukxqoNdgX_tvyiDlG4_9U,
267
255
  edsl/scenarios/ConstructDownloadLink.py,sha256=DGfF6hoCUovpTQ_GWiEndc--fXe9St6UdiaPhj7ZJZw,3529
268
256
  edsl/scenarios/DocumentChunker.py,sha256=ox8YhNybeg8Ukn6QuRYM8dsAmtTg5iwTAJSUWEkLnh4,3675
269
257
  edsl/scenarios/DocxScenario.py,sha256=ul3nkX826m_T6LFptswqtnH5czP_yxMlLWgbTmFIZI4,482
270
- edsl/scenarios/FileStore.py,sha256=b2DlqLZQ_CaRShzQnlQTEbgjF6vsBZB49qahEwesyzE,18140
258
+ edsl/scenarios/FileStore.py,sha256=OKmDIUV7DW-Upjerj0aArqgCNtNOJyU_dItURAb7vjw,21716
271
259
  edsl/scenarios/PdfExtractor.py,sha256=0L3-TizSWglaxT1OBZBEbZoCeMknt8zFhDKzN-TikOI,1922
272
260
  edsl/scenarios/Scenario.py,sha256=01Fv49eVKhXENCrbghDzajmUxYNdoMqE9FV0MMK5beI,19784
273
261
  edsl/scenarios/ScenarioHtmlMixin.py,sha256=5H8MnPPWqlGZ0_Ojv1WjkFaNNRrr-JpCRwlABDBfPXs,2111
274
- edsl/scenarios/ScenarioList.py,sha256=47W860C5pvAYr2kEzkL3JcacL11Q5jjHoWE9q4H2Nxo,58327
262
+ edsl/scenarios/ScenarioList.py,sha256=fjTcMwP5J7eL_spjekKUD3admT6lP4svG5vJZWulzVk,70194
275
263
  edsl/scenarios/ScenarioListExportMixin.py,sha256=eghBPIi4CmvkPbHV2hpFyE08jtOzuHiKAlt4JC9D81w,1475
276
264
  edsl/scenarios/ScenarioListPdfMixin.py,sha256=6sGXgDYo7e5lv7sB685iq5DS7KSbXNav-k6y6MRYNLM,7725
277
265
  edsl/scenarios/__init__.py,sha256=CQXwTNTIG9jg_pLkDPZgapUFY0_LwZFVQ8HaYvof0Nc,145
@@ -298,7 +286,7 @@ edsl/shared.py,sha256=lgLa-mCk2flIhxXarXLtfXZjXG_6XHhC2A3O8yRTjXc,20
298
286
  edsl/study/ObjectEntry.py,sha256=Jtg8V_63BXKKMAOMBqhuHFBjuNqFdkHen8gS2LAWc8Q,5811
299
287
  edsl/study/ProofOfWork.py,sha256=FaqYtLgeiTEQXWKukPgPUTWMcIN5t1FR7h7Re8QEtgc,3433
300
288
  edsl/study/SnapShot.py,sha256=2p9-eP6F9-AfbN_3LL_ZBN5ve4jiQLBzP8XZ3rk3gCI,2701
301
- edsl/study/Study.py,sha256=esM6o-pp3hnK9gBF5zxFLuryZBi0lTftZD_ob1ngDVw,18051
289
+ edsl/study/Study.py,sha256=Sc9KOOOTrTSLw6qzq_j7TmHZNG_a55tX46EwWMEwtJA,18016
302
290
  edsl/study/__init__.py,sha256=YAvPLTPG3hK_eN9Ar3d1_d-E3laXpSya879A25-JAxU,170
303
291
  edsl/surveys/ConstructDAG.py,sha256=2t5IstNAtVt6jnvFblgtuspXZQU8_JG5hLAwCFdO56w,3269
304
292
  edsl/surveys/DAG.py,sha256=dnIbrfJ_lQ3QEKjpyuo1I6b0kcnW2KMMyPir0A6J4XM,4235
@@ -311,7 +299,7 @@ edsl/surveys/Rule.py,sha256=Hou5_sSpvIfBdZNQk8tHFf-q4JT0wrV_kPMGbmLBfgA,12403
311
299
  edsl/surveys/RuleCollection.py,sha256=UC300EOPhjrMc-88eWt5kKBg1pVvKzzwgda2hjHW_sk,14790
312
300
  edsl/surveys/RuleManager.py,sha256=8k1XfTWaJbgjLLJsryBxVSiZ2_YuJPqE750jZEEtVwI,6216
313
301
  edsl/surveys/Simulator.py,sha256=I4_vHNnwe43SAbw7CK1xa45tahAKHfNRbRxGTRXdHuA,2586
314
- edsl/surveys/Survey.py,sha256=ebzPn3wfrt09XrjGjLDNrpuQu3Ds87oqtjyqKfCmxAk,48674
302
+ edsl/surveys/Survey.py,sha256=Te319t8L4FLTdUvg1eKQwBBA3791_HXtGcO2FL-455A,48438
315
303
  edsl/surveys/SurveyCSS.py,sha256=fIdiLuXTUq6KuoXXAU_LTHTTe6RchnCmZpj3j7qnt5Y,8796
316
304
  edsl/surveys/SurveyExportMixin.py,sha256=Kvkd2ku2Kemsn2Nw-Yt8GTnGFcUqfEiKznmisAeO7ck,8339
317
305
  edsl/surveys/SurveyFlowVisualization.py,sha256=Dbkgo-6PBwZ-l2Ok-6dl79CP1JNrqcm04Z4y5ZgKJ-o,8858
@@ -360,7 +348,7 @@ edsl/utilities/remove_edsl_version.py,sha256=3n2RoXvZ4pH3k-_lc7B-vkeUyHXHX6vKHQS
360
348
  edsl/utilities/repair_functions.py,sha256=tftmklAqam6LOQQu_-9U44N-llycffhW8LfO63vBmNw,929
361
349
  edsl/utilities/restricted_python.py,sha256=5-_zUhrNbos7pLhDl9nr8d24auRlquR6w-vKkmNjPiA,2060
362
350
  edsl/utilities/utilities.py,sha256=FbI9QYGD4eaHrwZ6ePx51jjpatZqwSPHJhimx-h6HyA,12660
363
- edsl-0.1.45.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
364
- edsl-0.1.45.dist-info/METADATA,sha256=zBph31PAc_qwZ9uzrvRfVl3F64a4Edj-jfgf3iAa1no,11696
365
- edsl-0.1.45.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
366
- edsl-0.1.45.dist-info/RECORD,,
351
+ edsl-0.1.47.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
352
+ edsl-0.1.47.dist-info/METADATA,sha256=vgqfrEJtQ03QZ85Fu4pi3PsM0pKMkycGavcpK6m5TSQ,11724
353
+ edsl-0.1.47.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
354
+ edsl-0.1.47.dist-info/RECORD,,