edsl 0.1.30.dev1__py3-none-any.whl → 0.1.30.dev3__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/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.30.dev1"
1
+ __version__ = "0.1.30.dev3"
edsl/agents/Agent.py CHANGED
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
  import copy
5
5
  import inspect
6
6
  import types
7
- from typing import Any, Callable, Optional, Union, Dict, Sequence
7
+ from typing import Callable, Optional, Union
8
+ from uuid import uuid4
8
9
  from edsl.Base import Base
9
10
 
10
11
  from edsl.exceptions.agents import (
@@ -688,13 +689,14 @@ class Agent(Base):
688
689
  return table
689
690
 
690
691
  @classmethod
691
- def example(cls) -> Agent:
692
- """Return an example agent.
692
+ def example(cls, randomize: bool = False) -> Agent:
693
+ """
694
+ Returns an example Agent instance.
693
695
 
694
- >>> Agent.example()
695
- Agent(traits = {'age': 22, 'hair': 'brown', 'height': 5.5})
696
+ :param randomize: If True, adds a random string to the value of an example key.
696
697
  """
697
- return cls(traits={"age": 22, "hair": "brown", "height": 5.5})
698
+ addition = "" if not randomize else str(uuid4())
699
+ return cls(traits={"age": 22, "hair": f"brown{addition}", "height": 5.5})
698
700
 
699
701
  def code(self) -> str:
700
702
  """Return the code for the agent.
edsl/agents/AgentList.py CHANGED
@@ -11,23 +11,15 @@ Example usage:
11
11
  """
12
12
 
13
13
  from __future__ import annotations
14
+ import csv
15
+ import json
14
16
  from collections import UserList
15
- from typing import Optional, Union, Sequence, List, Any
17
+ from typing import Any, List, Optional, Union
16
18
  from rich import print_json
17
19
  from rich.table import Table
18
- import json
19
- import csv
20
-
21
-
22
20
  from simpleeval import EvalWithCompoundTypes
23
-
24
21
  from edsl.Base import Base
25
-
26
- # from edsl.agents import Agent
27
- from edsl.utilities.decorators import (
28
- add_edsl_version,
29
- remove_edsl_version,
30
- )
22
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
31
23
 
32
24
 
33
25
  class AgentList(UserList, Base):
@@ -239,17 +231,15 @@ class AgentList(UserList, Base):
239
231
  return cls(agents)
240
232
 
241
233
  @classmethod
242
- def example(cls) -> "AgentList":
243
- """Return an example AgentList.
244
-
245
- >>> al = AgentList.example()
246
- >>> len(al)
247
- 2
234
+ def example(cls, randomize: bool = False) -> AgentList:
235
+ """
236
+ Returns an example AgentList instance.
248
237
 
238
+ :param randomize: If True, uses Agent's randomize method.
249
239
  """
250
240
  from edsl.agents.Agent import Agent
251
241
 
252
- return cls([Agent.example(), Agent.example()])
242
+ return cls([Agent.example(randomize), Agent.example(randomize)])
253
243
 
254
244
  @classmethod
255
245
  def from_list(self, trait_name: str, values: List[Any]):
@@ -74,15 +74,14 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
74
74
 
75
75
  This cleans up the raw response to make it suitable to pass to AgentResponseDict.
76
76
  """
77
- # not actually used, but this removes the temptation to delete agent from the signature
78
77
  _ = agent
79
78
  try:
80
79
  response = question._validate_answer(raw_response)
81
80
  except Exception as e:
81
+ """If the response is invalid, remove it from the cache and raise the exception."""
82
82
  self._remove_from_cache(raw_response)
83
83
  raise e
84
84
 
85
- # breakpoint()
86
85
  question_dict = self.survey.question_names_to_questions()
87
86
  for other_question, answer in self.current_answers.items():
88
87
  if other_question in question_dict:
@@ -95,12 +94,10 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
95
94
  question_dict[new_question].comment = answer
96
95
 
97
96
  combined_dict = {**question_dict, **scenario}
98
- # print("combined_dict: ", combined_dict)
99
- # print("response: ", response)
100
- # breakpoint()
101
97
  answer = question._translate_answer_code_to_answer(
102
98
  response["answer"], combined_dict
103
99
  )
100
+ # breakpoint()
104
101
  data = {
105
102
  "answer": answer,
106
103
  "comment": response.get(
@@ -111,6 +108,8 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
111
108
  "cached_response": raw_response.get("cached_response", None),
112
109
  "usage": raw_response.get("usage", {}),
113
110
  "raw_model_response": raw_model_response,
111
+ "cache_used": raw_response.get("cache_used", False),
112
+ "cache_key": raw_response.get("cache_key", None),
114
113
  }
115
114
  return AgentResponseDict(**data)
116
115
 
edsl/data/Cache.py CHANGED
@@ -7,17 +7,10 @@ import json
7
7
  import os
8
8
  import warnings
9
9
  from typing import Optional, Union
10
- import time
11
- from edsl.config import CONFIG
12
- from edsl.data.CacheEntry import CacheEntry
13
-
14
- # from edsl.data.SQLiteDict import SQLiteDict
15
10
  from edsl.Base import Base
11
+ from edsl.data.CacheEntry import CacheEntry
16
12
  from edsl.utilities.utilities import dict_hash
17
- from edsl.utilities.decorators import (
18
- add_edsl_version,
19
- remove_edsl_version,
20
- )
13
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
21
14
 
22
15
 
23
16
  class Cache(Base):
@@ -41,6 +34,7 @@ class Cache(Base):
41
34
  data: Optional[Union["SQLiteDict", dict]] = None,
42
35
  immediate_write: bool = True,
43
36
  method=None,
37
+ verbose=False,
44
38
  ):
45
39
  """
46
40
  Create two dictionaries to store the cache data.
@@ -59,6 +53,7 @@ class Cache(Base):
59
53
  self.new_entries = {}
60
54
  self.new_entries_to_write_later = {}
61
55
  self.coop = None
56
+ self.verbose = verbose
62
57
 
63
58
  self.filename = filename
64
59
  if filename and data:
@@ -122,7 +117,7 @@ class Cache(Base):
122
117
  system_prompt: str,
123
118
  user_prompt: str,
124
119
  iteration: int,
125
- ) -> Union[None, str]:
120
+ ) -> tuple(Union[None, str], str):
126
121
  """
127
122
  Fetch a value (LLM output) from the cache.
128
123
 
@@ -135,7 +130,7 @@ class Cache(Base):
135
130
  Return None if the response is not found.
136
131
 
137
132
  >>> c = Cache()
138
- >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1) is None
133
+ >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1)[0] is None
139
134
  True
140
135
 
141
136
 
@@ -151,8 +146,13 @@ class Cache(Base):
151
146
  )
152
147
  entry = self.data.get(key, None)
153
148
  if entry is not None:
149
+ if self.verbose:
150
+ print(f"Cache hit for key: {key}")
154
151
  self.fetched_data[key] = entry
155
- return None if entry is None else entry.output
152
+ else:
153
+ if self.verbose:
154
+ print(f"Cache miss for key: {key}")
155
+ return None if entry is None else entry.output, key
156
156
 
157
157
  def store(
158
158
  self,
@@ -354,6 +354,9 @@ class Cache(Base):
354
354
  for key, entry in self.new_entries_to_write_later.items():
355
355
  self.data[key] = entry
356
356
 
357
+ if self.filename:
358
+ self.write(self.filename)
359
+
357
360
  ####################
358
361
  # DUNDER / USEFUL
359
362
  ####################
@@ -470,12 +473,18 @@ class Cache(Base):
470
473
  webbrowser.open("file://" + filepath)
471
474
 
472
475
  @classmethod
473
- def example(cls) -> Cache:
476
+ def example(cls, randomize: bool = False) -> Cache:
474
477
  """
475
- Return an example Cache.
476
- The example Cache has one entry.
478
+ Returns an example Cache instance.
479
+
480
+ :param randomize: If True, uses CacheEntry's randomize method.
477
481
  """
478
- return cls(data={CacheEntry.example().key: CacheEntry.example()})
482
+ return cls(
483
+ data={
484
+ CacheEntry.example(randomize).key: CacheEntry.example(),
485
+ CacheEntry.example(randomize).key: CacheEntry.example(),
486
+ }
487
+ )
479
488
 
480
489
 
481
490
  if __name__ == "__main__":
edsl/data/CacheEntry.py CHANGED
@@ -2,11 +2,8 @@ from __future__ import annotations
2
2
  import json
3
3
  import datetime
4
4
  import hashlib
5
- import random
6
5
  from typing import Optional
7
-
8
-
9
- # TODO: Timestamp should probably be float?
6
+ from uuid import uuid4
10
7
 
11
8
 
12
9
  class CacheEntry:
@@ -151,10 +148,12 @@ class CacheEntry:
151
148
  @classmethod
152
149
  def example(cls, randomize: bool = False) -> CacheEntry:
153
150
  """
154
- Returns a CacheEntry example.
151
+ Returns an example CacheEntry instance.
152
+
153
+ :param randomize: If True, adds a random string to the system prompt.
155
154
  """
156
- # if random, create a random number for 0-100
157
- addition = "" if not randomize else str(random.randint(0, 1000))
155
+ # if random, create a uuid
156
+ addition = "" if not randomize else str(uuid4())
158
157
  return CacheEntry(
159
158
  model="gpt-3.5-turbo",
160
159
  parameters={"temperature": 0.5},
@@ -17,6 +17,8 @@ class AgentResponseDict(UserDict):
17
17
  cached_response=None,
18
18
  raw_model_response=None,
19
19
  simple_model_raw_response=None,
20
+ cache_used=None,
21
+ cache_key=None,
20
22
  ):
21
23
  """Initialize the AgentResponseDict object."""
22
24
  usage = usage or {"prompt_tokens": 0, "completion_tokens": 0}
@@ -30,5 +32,7 @@ class AgentResponseDict(UserDict):
30
32
  "cached_response": cached_response,
31
33
  "raw_model_response": raw_model_response,
32
34
  "simple_model_raw_response": simple_model_raw_response,
35
+ "cache_used": cache_used,
36
+ "cache_key": cache_key,
33
37
  }
34
38
  )
edsl/jobs/Jobs.py CHANGED
@@ -461,6 +461,13 @@ class Jobs(Base):
461
461
  remote_inference = False
462
462
 
463
463
  if remote_inference:
464
+ from edsl.agents.Agent import Agent
465
+ from edsl.language_models.registry import Model
466
+ from edsl.results.Result import Result
467
+ from edsl.results.Results import Results
468
+ from edsl.scenarios.Scenario import Scenario
469
+ from edsl.surveys.Survey import Survey
470
+
464
471
  self._output("Remote inference activated. Sending job to server...")
465
472
  if remote_cache:
466
473
  self._output(
@@ -680,7 +687,9 @@ class Jobs(Base):
680
687
  # Example methods
681
688
  #######################
682
689
  @classmethod
683
- def example(cls, throw_exception_probability=0) -> Jobs:
690
+ def example(
691
+ cls, throw_exception_probability: int = 0, randomize: bool = False
692
+ ) -> Jobs:
684
693
  """Return an example Jobs instance.
685
694
 
686
695
  :param throw_exception_probability: the probability that an exception will be thrown when answering a question. This is useful for testing error handling.
@@ -690,10 +699,13 @@ class Jobs(Base):
690
699
 
691
700
  """
692
701
  import random
702
+ from uuid import uuid4
693
703
  from edsl.questions import QuestionMultipleChoice
694
704
  from edsl.agents.Agent import Agent
695
705
  from edsl.scenarios.Scenario import Scenario
696
706
 
707
+ addition = "" if not randomize else str(uuid4())
708
+
697
709
  # (status, question, period)
698
710
  agent_answers = {
699
711
  ("Joyful", "how_feeling", "morning"): "OK",
@@ -736,7 +748,10 @@ class Jobs(Base):
736
748
  base_survey = Survey(questions=[q1, q2])
737
749
 
738
750
  scenario_list = ScenarioList(
739
- [Scenario({"period": "morning"}), Scenario({"period": "afternoon"})]
751
+ [
752
+ Scenario({"period": f"morning{addition}"}),
753
+ Scenario({"period": "afternoon"}),
754
+ ]
740
755
  )
741
756
  job = base_survey.by(scenario_list).by(joy_agent, sad_agent)
742
757
 
@@ -25,6 +25,16 @@ class ModelBuckets:
25
25
  tokens_bucket=self.tokens_bucket + other.tokens_bucket,
26
26
  )
27
27
 
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity for both buckets."""
30
+ self.requests_bucket.turbo_mode_on()
31
+ self.tokens_bucket.turbo_mode_on()
32
+
33
+ def turbo_mode_off(self):
34
+ """Restore the refill rate to its original value for both buckets."""
35
+ self.requests_bucket.turbo_mode_off()
36
+ self.tokens_bucket.turbo_mode_off()
37
+
28
38
  @classmethod
29
39
  def infinity_bucket(cls, model_name: str = "not_specified") -> "ModelBuckets":
30
40
  """Create a bucket with infinite capacity and refill rate."""
@@ -17,11 +17,28 @@ class TokenBucket:
17
17
  self.bucket_name = bucket_name
18
18
  self.bucket_type = bucket_type
19
19
  self.capacity = capacity # Maximum number of tokens
20
+ self._old_capacity = capacity
20
21
  self.tokens = capacity # Current number of available tokens
21
22
  self.refill_rate = refill_rate # Rate at which tokens are refilled
23
+ self._old_refill_rate = refill_rate
22
24
  self.last_refill = time.monotonic() # Last refill time
23
-
24
25
  self.log: List[Any] = []
26
+ self.turbo_mode = False
27
+
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity."""
30
+ if self.turbo_mode:
31
+ pass
32
+ else:
33
+ self.turbo_mode = True
34
+ self.capacity = float("inf")
35
+ self.refill_rate = float("inf")
36
+
37
+ def turbo_mode_off(self):
38
+ """Restore the refill rate to its original value."""
39
+ self.turbo_mode = False
40
+ self.capacity = self._old_capacity
41
+ self.refill_rate = self._old_refill_rate
25
42
 
26
43
  def __add__(self, other) -> "TokenBucket":
27
44
  """Combine two token buckets.
@@ -98,7 +115,7 @@ class TokenBucket:
98
115
  raise ValueError(msg)
99
116
  while self.tokens < amount:
100
117
  self.refill()
101
- await asyncio.sleep(0.1) # Sleep briefly to prevent busy waiting
118
+ await asyncio.sleep(0.01) # Sleep briefly to prevent busy waiting
102
119
  self.tokens -= amount
103
120
 
104
121
  now = time.monotonic()
@@ -30,14 +30,14 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
30
30
 
31
31
  def __init__(
32
32
  self,
33
- agent: Agent,
34
- survey: Survey,
35
- scenario: Scenario,
36
- model: Type[LanguageModel],
37
- debug: bool = False,
33
+ agent: "Agent",
34
+ survey: "Survey",
35
+ scenario: "Scenario",
36
+ model: Type["LanguageModel"],
37
+ debug: Optional[bool] = False,
38
38
  iteration: int = 0,
39
39
  cache: "Cache" = None,
40
- sidecar_model: LanguageModel = None,
40
+ sidecar_model: "LanguageModel" = None,
41
41
  ):
42
42
  """Initialize the Interview instance.
43
43
 
@@ -99,6 +99,7 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
99
99
  if model_buckets is None or hasattr(self.agent, "answer_question_directly"):
100
100
  model_buckets = ModelBuckets.infinity_bucket()
101
101
 
102
+ # FOR TESTING
102
103
  # model_buckets = ModelBuckets.infinity_bucket()
103
104
 
104
105
  ## build the tasks using the InterviewTaskBuildingMixin
@@ -88,6 +88,8 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
88
88
  self.total_interviews.append(interview)
89
89
 
90
90
  async def run_async(self, cache=None) -> Results:
91
+ from edsl.results.Results import Results
92
+
91
93
  if cache is None:
92
94
  self.cache = Cache()
93
95
  else:
@@ -98,6 +100,8 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
98
100
  return Results(survey=self.jobs.survey, data=data)
99
101
 
100
102
  def simple_run(self):
103
+ from edsl.results.Results import Results
104
+
101
105
  data = asyncio.run(self.run_async())
102
106
  return Results(survey=self.jobs.survey, data=data)
103
107
 
@@ -144,12 +144,20 @@ class QuestionTaskCreator(UserList):
144
144
  self.task_status = TaskStatus.FAILED
145
145
  raise e
146
146
 
147
- if "cached_response" in results:
148
- if results["cached_response"]:
149
- # Gives back the tokens b/c the API was not called.
150
- self.tokens_bucket.add_tokens(requested_tokens)
151
- self.requests_bucket.add_tokens(1)
152
- self.from_cache = True
147
+ ## This isn't working
148
+ # breakpoint()
149
+ if results.get("cache_used", False):
150
+ self.tokens_bucket.add_tokens(requested_tokens)
151
+ self.requests_bucket.add_tokens(1)
152
+ self.from_cache = True
153
+ # print("Turning on turbo!")
154
+ self.tokens_bucket.turbo_mode_on()
155
+ self.requests_bucket.turbo_mode_on()
156
+ else:
157
+ # breakpoint()
158
+ # print("Turning off turbo!")
159
+ self.tokens_bucket.turbo_mode_off()
160
+ self.requests_bucket.turbo_mode_off()
153
161
 
154
162
  _ = results.pop("cached_response", None)
155
163
 
@@ -323,12 +323,10 @@ class LanguageModel(
323
323
  image_hash = hashlib.md5(encoded_image.encode()).hexdigest()
324
324
  cache_call_params["user_prompt"] = f"{user_prompt} {image_hash}"
325
325
 
326
- cached_response = cache.fetch(**cache_call_params)
327
-
326
+ cached_response, cache_key = cache.fetch(**cache_call_params)
328
327
  if cached_response:
329
328
  response = json.loads(cached_response)
330
329
  cache_used = True
331
- cache_key = None
332
330
  else:
333
331
  remote_call = hasattr(self, "remote") and self.remote
334
332
  f = (
@@ -340,7 +338,7 @@ class LanguageModel(
340
338
  if encoded_image:
341
339
  params["encoded_image"] = encoded_image
342
340
  response = await f(**params)
343
- cache_key = cache.store(
341
+ new_cache_key = cache.store(
344
342
  user_prompt=user_prompt,
345
343
  model=str(self.model),
346
344
  parameters=self.parameters,
@@ -348,6 +346,7 @@ class LanguageModel(
348
346
  response=response,
349
347
  iteration=iteration,
350
348
  )
349
+ assert new_cache_key == cache_key
351
350
  cache_used = False
352
351
 
353
352
  return response, cache_used, cache_key
@@ -412,7 +411,7 @@ class LanguageModel(
412
411
 
413
412
  dict_response.update(
414
413
  {
415
- "cached_used": cache_used,
414
+ "cache_used": cache_used,
416
415
  "cache_key": cache_key,
417
416
  "usage": raw_response.get("usage", {}),
418
417
  "raw_model_response": raw_response,
@@ -1,14 +1,11 @@
1
1
  """A Notebook is a utility class that allows you to easily share/pull ipynbs from Coop."""
2
2
 
3
+ from __future__ import annotations
3
4
  import json
4
5
  from typing import Dict, List, Optional
5
-
6
-
6
+ from uuid import uuid4
7
7
  from edsl.Base import Base
8
- from edsl.utilities.decorators import (
9
- add_edsl_version,
10
- remove_edsl_version,
11
- )
8
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
12
9
 
13
10
 
14
11
  class Notebook(Base):
@@ -192,10 +189,13 @@ class Notebook(Base):
192
189
  return table
193
190
 
194
191
  @classmethod
195
- def example(cls) -> "Notebook":
192
+ def example(cls, randomize: bool = False) -> Notebook:
196
193
  """
197
- Return an example Notebook.
194
+ Returns an example Notebook instance.
195
+
196
+ :param randomize: If True, adds a random string one of the cells' output.
198
197
  """
198
+ addition = "" if not randomize else str(uuid4())
199
199
  cells = [
200
200
  {
201
201
  "cell_type": "markdown",
@@ -210,7 +210,7 @@ class Notebook(Base):
210
210
  {
211
211
  "name": "stdout",
212
212
  "output_type": "stream",
213
- "text": "Hello world!\n",
213
+ "text": f"Hello world!\n{addition}",
214
214
  }
215
215
  ],
216
216
  "source": 'print("Hello world!")',
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import textwrap
3
3
  from typing import Any, Optional
4
+ from uuid import uuid4
4
5
  from edsl.questions.QuestionBase import QuestionBase
5
6
 
6
7
 
@@ -65,9 +66,10 @@ class QuestionFreeText(QuestionBase):
65
66
  return question_html_content
66
67
 
67
68
  @classmethod
68
- def example(cls) -> QuestionFreeText:
69
+ def example(cls, randomize: bool = False) -> QuestionFreeText:
69
70
  """Return an example instance of a free text question."""
70
- return cls(question_name="how_are_you", question_text="How are you?")
71
+ addition = "" if not randomize else str(uuid4())
72
+ return cls(question_name="how_are_you", question_text=f"How are you?{addition}")
71
73
 
72
74
 
73
75
  def main():
edsl/results/Results.py CHANGED
@@ -949,7 +949,7 @@ class Results(UserList, Mixins, Base):
949
949
  return Results(survey=self.survey, data=new_data, created_columns=None)
950
950
 
951
951
  @classmethod
952
- def example(cls, debug: bool = False) -> Results:
952
+ def example(cls, debug: bool = False, randomize: bool = False) -> Results:
953
953
  """Return an example `Results` object.
954
954
 
955
955
  Example usage:
@@ -962,7 +962,7 @@ class Results(UserList, Mixins, Base):
962
962
  from edsl.data.Cache import Cache
963
963
 
964
964
  c = Cache()
965
- job = Jobs.example()
965
+ job = Jobs.example(randomize=randomize)
966
966
  results = job.run(cache=c, debug=debug)
967
967
  return results
968
968
 
@@ -32,6 +32,9 @@ class FileStore(Scenario):
32
32
  def from_dict(cls, d):
33
33
  return cls(d["filename"], d["binary"], d["suffix"], d["base64_string"])
34
34
 
35
+ def __repr__(self):
36
+ return f"FileStore(filename='{self.filename}', binary='{self.binary}', 'suffix'={self.suffix})"
37
+
35
38
  def encode_file_to_base64_string(self, file_path):
36
39
  try:
37
40
  # Attempt to open the file in text mode
@@ -97,8 +100,14 @@ class FileStore(Scenario):
97
100
  file_like_object = self.base64_to_text_file(self["base64_string"])
98
101
 
99
102
  # Create a named temporary file
100
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
101
- temp_file.write(file_like_object.read())
103
+ mode = "wb" if self.binary else "w"
104
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=suffix, mode=mode)
105
+
106
+ if self.binary:
107
+ temp_file.write(file_like_object.read())
108
+ else:
109
+ temp_file.write(file_like_object.read())
110
+
102
111
  temp_file.close()
103
112
 
104
113
  return temp_file.name
@@ -120,11 +129,149 @@ class CSVFileStore(FileStore):
120
129
  def __init__(self, filename):
121
130
  super().__init__(filename, suffix=".csv")
122
131
 
132
+ @classmethod
133
+ def example(cls):
134
+ from edsl.results.Results import Results
135
+
136
+ r = Results.example()
137
+ import tempfile
138
+
139
+ with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as f:
140
+ r.to_csv(filename=f.name)
141
+ return cls(f.name)
142
+
143
+ def view(self):
144
+ import pandas as pd
145
+
146
+ return pd.read_csv(self.to_tempfile())
147
+
123
148
 
124
149
  class PDFFileStore(FileStore):
125
150
  def __init__(self, filename):
126
151
  super().__init__(filename, suffix=".pdf")
127
152
 
153
+ def view(self):
154
+ pdf_path = self.to_tempfile()
155
+ print(f"PDF path: {pdf_path}") # Print the path to ensure it exists
156
+ import os
157
+ import subprocess
158
+
159
+ if os.path.exists(pdf_path):
160
+ try:
161
+ if os.name == "posix":
162
+ # for cool kids
163
+ subprocess.run(["open", pdf_path], check=True) # macOS
164
+ elif os.name == "nt":
165
+ os.startfile(pdf_path) # Windows
166
+ else:
167
+ subprocess.run(["xdg-open", pdf_path], check=True) # Linux
168
+ except Exception as e:
169
+ print(f"Error opening PDF: {e}")
170
+ else:
171
+ print("PDF file was not created successfully.")
172
+
173
+ @classmethod
174
+ def example(cls):
175
+ import textwrap
176
+
177
+ pdf_string = textwrap.dedent(
178
+ """\
179
+ %PDF-1.4
180
+ 1 0 obj
181
+ << /Type /Catalog /Pages 2 0 R >>
182
+ endobj
183
+ 2 0 obj
184
+ << /Type /Pages /Kids [3 0 R] /Count 1 >>
185
+ endobj
186
+ 3 0 obj
187
+ << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>
188
+ endobj
189
+ 4 0 obj
190
+ << /Length 44 >>
191
+ stream
192
+ BT
193
+ /F1 24 Tf
194
+ 100 700 Td
195
+ (Hello, World!) Tj
196
+ ET
197
+ endstream
198
+ endobj
199
+ 5 0 obj
200
+ << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
201
+ endobj
202
+ 6 0 obj
203
+ << /ProcSet [/PDF /Text] /Font << /F1 5 0 R >> >>
204
+ endobj
205
+ xref
206
+ 0 7
207
+ 0000000000 65535 f
208
+ 0000000010 00000 n
209
+ 0000000053 00000 n
210
+ 0000000100 00000 n
211
+ 0000000173 00000 n
212
+ 0000000232 00000 n
213
+ 0000000272 00000 n
214
+ trailer
215
+ << /Size 7 /Root 1 0 R >>
216
+ startxref
217
+ 318
218
+ %%EOF"""
219
+ )
220
+ import tempfile
221
+
222
+ with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f:
223
+ f.write(pdf_string.encode())
224
+ return cls(f.name)
225
+
226
+
227
+ class PNGFileStore(FileStore):
228
+ def __init__(self, filename):
229
+ super().__init__(filename, suffix=".png")
230
+
231
+ @classmethod
232
+ def example(cls):
233
+ import textwrap
234
+
235
+ png_string = textwrap.dedent(
236
+ """\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x00\x00\x00\x01\x00\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\xd7c\x00\x01"""
237
+ )
238
+ import tempfile
239
+
240
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
241
+ f.write(png_string.encode())
242
+ return cls(f.name)
243
+
244
+ def view(self):
245
+ import matplotlib.pyplot as plt
246
+ import matplotlib.image as mpimg
247
+
248
+ img = mpimg.imread(self.to_tempfile())
249
+ plt.imshow(img)
250
+ plt.show()
251
+
252
+
253
+ class SQLiteFileStore(FileStore):
254
+ def __init__(self, filename):
255
+ super().__init__(filename, suffix=".sqlite")
256
+
257
+ @classmethod
258
+ def example(cls):
259
+ import sqlite3
260
+ import tempfile
261
+
262
+ with tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False) as f:
263
+ conn = sqlite3.connect(f.name)
264
+ c = conn.cursor()
265
+ c.execute("""CREATE TABLE stocks (date text)""")
266
+ conn.commit()
267
+
268
+ def view(self):
269
+ import subprocess
270
+ import os
271
+
272
+ sqlite_path = self.to_tempfile()
273
+ os.system(f"sqlite3 {sqlite_path}")
274
+
128
275
 
129
276
  if __name__ == "__main__":
130
277
  # file_path = "../conjure/examples/Ex11-2.sav"
@@ -132,9 +279,21 @@ if __name__ == "__main__":
132
279
  # info = fs.push()
133
280
  # print(info)
134
281
 
282
+ # fs = CSVFileStore.example()
283
+ # fs.to_tempfile()
284
+ # print(fs.view())
285
+
286
+ # fs = PDFFileStore.example()
287
+ # fs.view()
288
+
289
+ # fs = PDFFileStore("paper.pdf")
290
+ # fs.view()
135
291
  # from edsl import Conjure
136
292
 
293
+ fs = PNGFileStore("robot.png")
294
+ fs.view()
295
+
137
296
  # c = Conjure(datafile_name=fs.to_tempfile())
138
- f = PDFFileStore("paper.pdf")
297
+ # f = PDFFileStore("paper.pdf")
139
298
  # print(f.to_tempfile())
140
- f.push()
299
+ # f.push()
@@ -1,21 +1,17 @@
1
1
  """A Scenario is a dictionary with a key/value to parameterize a question."""
2
2
 
3
- import time
3
+ from __future__ import annotations
4
4
  import copy
5
- from collections import UserDict
6
- from typing import Union, List, Optional, Generator
7
5
  import base64
8
6
  import hashlib
9
7
  import os
10
-
8
+ from collections import UserDict
9
+ from typing import Union, List, Optional, Generator
10
+ from uuid import uuid4
11
11
  from edsl.Base import Base
12
12
  from edsl.scenarios.ScenarioImageMixin import ScenarioImageMixin
13
13
  from edsl.scenarios.ScenarioHtmlMixin import ScenarioHtmlMixin
14
-
15
- from edsl.utilities.decorators import (
16
- add_edsl_version,
17
- remove_edsl_version,
18
- )
14
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
19
15
 
20
16
 
21
17
  class Scenario(Base, UserDict, ScenarioImageMixin, ScenarioHtmlMixin):
@@ -28,9 +24,7 @@ class Scenario(Base, UserDict, ScenarioImageMixin, ScenarioHtmlMixin):
28
24
 
29
25
  :param data: A dictionary of keys/values for parameterizing questions.
30
26
  """
31
- if data is None:
32
- data = {}
33
- self.data = data
27
+ self.data = data if data is not None else {}
34
28
  self.name = name
35
29
 
36
30
  def replicate(self, n: int) -> "ScenarioList":
@@ -415,17 +409,16 @@ class Scenario(Base, UserDict, ScenarioImageMixin, ScenarioHtmlMixin):
415
409
  return table
416
410
 
417
411
  @classmethod
418
- def example(cls) -> "Scenario":
419
- """Return an example scenario.
420
-
421
- Example:
412
+ def example(cls, randomize: bool = False) -> Scenario:
413
+ """
414
+ Returns an example Scenario instance.
422
415
 
423
- >>> Scenario.example()
424
- Scenario({'persona': 'A reseacher studying whether LLMs can be used to generate surveys.'})
416
+ :param randomize: If True, adds a random string to the value of the example key.
425
417
  """
418
+ addition = "" if not randomize else str(uuid4())
426
419
  return cls(
427
420
  {
428
- "persona": "A reseacher studying whether LLMs can be used to generate surveys."
421
+ "persona": f"A reseacher studying whether LLMs can be used to generate surveys.{addition}",
429
422
  }
430
423
  )
431
424
 
@@ -5,10 +5,8 @@ import csv
5
5
  import random
6
6
  from collections import UserList, Counter
7
7
  from collections.abc import Iterable
8
- from typing import Any, Optional, Union, List
9
-
10
8
  from simpleeval import EvalWithCompoundTypes
11
-
9
+ from typing import Any, Optional, Union, List
12
10
  from edsl.Base import Base
13
11
  from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
14
12
  from edsl.scenarios.Scenario import Scenario
@@ -442,9 +440,13 @@ class ScenarioList(Base, UserList, ScenarioListMixin):
442
440
  return lines
443
441
 
444
442
  @classmethod
445
- def example(cls) -> ScenarioList:
446
- """Return an example of the `ScenarioList`."""
447
- return cls([Scenario.example(), Scenario.example()])
443
+ def example(cls, randomize: bool = False) -> ScenarioList:
444
+ """
445
+ Return an example ScenarioList instance.
446
+
447
+ :params randomize: If True, use Scenario's randomize method to randomize the values.
448
+ """
449
+ return cls([Scenario.example(randomize), Scenario.example(randomize)])
448
450
 
449
451
  def rich_print(self) -> None:
450
452
  """Display an object as a table."""
edsl/study/Study.py CHANGED
@@ -6,14 +6,12 @@ import platform
6
6
  import socket
7
7
  from datetime import datetime
8
8
  from typing import Dict, Optional, Union
9
+ from uuid import UUID, uuid4
9
10
  from edsl import Cache, set_session_cache, unset_session_cache
10
11
  from edsl.utilities.utilities import dict_hash
11
12
  from edsl.study.ObjectEntry import ObjectEntry
12
13
  from edsl.study.ProofOfWork import ProofOfWork
13
14
  from edsl.study.SnapShot import SnapShot
14
- from uuid import UUID
15
-
16
- # from edsl.Base import Base
17
15
 
18
16
 
19
17
  class Study:
@@ -402,14 +400,14 @@ class Study:
402
400
  return diff
403
401
 
404
402
  @classmethod
405
- def example(cls, verbose=False):
403
+ def example(cls, verbose=False, randomize=False):
406
404
  import tempfile
407
405
 
408
406
  study_file = tempfile.NamedTemporaryFile()
409
407
  with cls(filename=study_file.name, verbose=verbose) as study:
410
408
  from edsl import QuestionFreeText
411
409
 
412
- q = QuestionFreeText.example()
410
+ q = QuestionFreeText.example(randomize=randomize)
413
411
  return study
414
412
 
415
413
  @classmethod
edsl/surveys/Survey.py CHANGED
@@ -2,23 +2,20 @@
2
2
 
3
3
  from __future__ import annotations
4
4
  import re
5
-
6
5
  from typing import Any, Generator, Optional, Union, List, Literal, Callable
7
-
6
+ from uuid import uuid4
7
+ from edsl.Base import Base
8
8
  from edsl.exceptions import SurveyCreationError, SurveyHasNoRulesError
9
9
  from edsl.questions.QuestionBase import QuestionBase
10
10
  from edsl.surveys.base import RulePriority, EndOfSurvey
11
+ from edsl.surveys.DAG import DAG
12
+ from edsl.surveys.descriptors import QuestionsDescriptor
13
+ from edsl.surveys.MemoryPlan import MemoryPlan
11
14
  from edsl.surveys.Rule import Rule
12
15
  from edsl.surveys.RuleCollection import RuleCollection
13
-
14
- from edsl.Base import Base
15
16
  from edsl.surveys.SurveyExportMixin import SurveyExportMixin
16
- from edsl.surveys.descriptors import QuestionsDescriptor
17
- from edsl.surveys.MemoryPlan import MemoryPlan
18
-
19
- from edsl.surveys.DAG import DAG
20
- from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
21
17
  from edsl.surveys.SurveyFlowVisualizationMixin import SurveyFlowVisualizationMixin
18
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
22
19
 
23
20
 
24
21
  class Survey(SurveyExportMixin, SurveyFlowVisualizationMixin, Base):
@@ -1025,7 +1022,7 @@ class Survey(SurveyExportMixin, SurveyFlowVisualizationMixin, Base):
1025
1022
  return res
1026
1023
 
1027
1024
  @classmethod
1028
- def example(cls, params=False) -> Survey:
1025
+ def example(cls, params: bool = False, randomize: bool = False) -> Survey:
1029
1026
  """Return an example survey.
1030
1027
 
1031
1028
  >>> s = Survey.example()
@@ -1034,8 +1031,9 @@ class Survey(SurveyExportMixin, SurveyFlowVisualizationMixin, Base):
1034
1031
  """
1035
1032
  from edsl.questions.QuestionMultipleChoice import QuestionMultipleChoice
1036
1033
 
1034
+ addition = "" if not randomize else str(uuid4())
1037
1035
  q0 = QuestionMultipleChoice(
1038
- question_text="Do you like school?",
1036
+ question_text=f"Do you like school?{addition}",
1039
1037
  question_options=["yes", "no"],
1040
1038
  question_name="q0",
1041
1039
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.30.dev1
3
+ Version: 0.1.30.dev3
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -1,10 +1,10 @@
1
1
  edsl/Base.py,sha256=ttNxUotSd9LSEJl2w6LdMtT78d0nMQvYDJ0q4JkqBfg,8945
2
2
  edsl/BaseDiff.py,sha256=RoVEh52UJs22yMa7k7jv8se01G62jJNWnBzaZngo-Ug,8260
3
3
  edsl/__init__.py,sha256=E6PkWI_owu8AUc4uJs2XWDVozqSbcRWzsIqf8_Kskho,1631
4
- edsl/__version__.py,sha256=amcrd2RosTWD41gMCGQ_UQUwccGuD5VryTFhTXadSlE,28
5
- edsl/agents/Agent.py,sha256=nSAwyfro0aj2qezDb-CfTIoSQb35ZC6xQTx2A5pph3s,27085
6
- edsl/agents/AgentList.py,sha256=07RpCsqAJxyAEMY4NvvqWOXSk11i6b80UZhOwa1-y9A,9468
7
- edsl/agents/Invigilator.py,sha256=gfy6yyaWKPa-OfMgZ3VvWAqBwppSdJSjSatH1Gmd_A0,10784
4
+ edsl/__version__.py,sha256=_ANJH4aJYys7O1gdkM91E9Lxb1BeNgrHptZTDFgPUoY,28
5
+ edsl/agents/Agent.py,sha256=qNJsQkN6HuTKqJrQbuUEgRX3Wo7Dwukle0oNWPi0UIE,27191
6
+ edsl/agents/AgentList.py,sha256=_MsdeOEgaANAceLIXwuLC22mwlBn0ruGX4GEqz8_SSY,9467
7
+ edsl/agents/Invigilator.py,sha256=WNgGT9VRKpHbk__h-vd4LASgjnlJnzepf-2FxQ3K98I,10798
8
8
  edsl/agents/InvigilatorBase.py,sha256=ncha1HF2V1Dz4f50Gekg6AzUXCD2Af82ztfSJZbgOHY,7469
9
9
  edsl/agents/PromptConstructionMixin.py,sha256=MP2Frmm9iP3J50ijXKrr6YYIjB_38UuA2J7Mysfs0ZQ,15913
10
10
  edsl/agents/__init__.py,sha256=a3H1lxDwu9HR8fwh79C5DgxPSFv_bE2rzQ6y1D8Ba5c,80
@@ -34,13 +34,13 @@ edsl/conversation/next_speaker_utilities.py,sha256=bqr5JglCd6bdLc9IZ5zGOAsmN2F4E
34
34
  edsl/coop/__init__.py,sha256=4iZCwJSzJVyjBYk8ggGxY2kZjq9dXVT1jhyPDNyew4I,115
35
35
  edsl/coop/coop.py,sha256=Kv6oUOZ9uuxxR59Rn6IG-tB3JaN2z8AnHVW8G-RSLQE,26928
36
36
  edsl/coop/utils.py,sha256=BeBcMWWl9Kxjll_WfDQNHbp-6ct9QjVn4ph2V4ph6XE,3347
37
- edsl/data/Cache.py,sha256=zu0wQ-853tQKgYem5MmnwG4jFbDyWnRukJ_p2Ujb4ug,15217
38
- edsl/data/CacheEntry.py,sha256=AnZBUautQc19KhE6NkI87U_P9wDZI2eu-8B1XopPTOI,7235
37
+ edsl/data/Cache.py,sha256=aR9ydTFvUWiRJZd2G7SLFFtZaS2At8ArbQ1SAhYZBDs,15629
38
+ edsl/data/CacheEntry.py,sha256=_5UiFaJQu_U-Z1_lEPt-h6Gaidp2Eunk02wOd3Ni3MQ,7252
39
39
  edsl/data/CacheHandler.py,sha256=DTr8nJnbl_SidhsDetqbshu1DV-njPFiPPosUWTIBok,4789
40
40
  edsl/data/SQLiteDict.py,sha256=V5Nfnxctgh4Iblqcw1KmbnkjtfmWrrombROSQ3mvg6A,8979
41
41
  edsl/data/__init__.py,sha256=KBNGGEuGHq--D-TlpAQmvv_If906dJc1Gsy028zOx78,170
42
42
  edsl/data/orm.py,sha256=Jz6rvw5SrlxwysTL0QI9r68EflKxeEBmf6j6himHDS8,238
43
- edsl/data_transfer_models.py,sha256=17A3vpxTkJ2DnV8ggTPxwPzwlQAEYn94U4qiBv8hV3o,1026
43
+ edsl/data_transfer_models.py,sha256=ORcI-g_oUE8EofLvHQKnWC5ar-IgZiXGY2bIpTGAZyQ,1157
44
44
  edsl/enums.py,sha256=lW4rMKJJ-AsBdtDw_u6TitlNbHkTznorVPjqqmUKPE0,4876
45
45
  edsl/exceptions/__init__.py,sha256=HVg-U-rJ0fRoG9Rws6gnK5S9B68SkPWDPsoD6KpMZ-A,1370
46
46
  edsl/exceptions/agents.py,sha256=3SORFwFbMGrF6-vAL2GrKEVdPcXo7md_k2oYufnVXHA,673
@@ -66,12 +66,12 @@ edsl/inference_services/rate_limits_cache.py,sha256=HYslviz7mxF9U4CUTPAkoyBsiXjS
66
66
  edsl/inference_services/registry.py,sha256=-Yz86do-KZraunIrziVs9b95EbY-__JUnQb5Ulni7KI,483
67
67
  edsl/inference_services/write_available.py,sha256=NNwhATlaMp8IYY635MSx-oYxt5X15acjAfaqYCo_I1Y,285
68
68
  edsl/jobs/Answers.py,sha256=z4TADN-iHIrbMtI1jVyiaetv0OkTv768dFBpREIQC6c,1799
69
- edsl/jobs/Jobs.py,sha256=IH7DeLEZFBPq32Y8xrKH9hXCDd4t2MsbGFNSf9GaA0o,28825
69
+ edsl/jobs/Jobs.py,sha256=JrJcpTjR3wejMVvuFXZr7PHqCyj6zaRwqNu9eatvy9Y,29339
70
70
  edsl/jobs/__init__.py,sha256=aKuAyd_GoalGj-k7djOoVwEbFUE2XLPlikXaA1_8yAg,32
71
71
  edsl/jobs/buckets/BucketCollection.py,sha256=LA8DBVwMdeTFCbSDI0S2cDzfi_Qo6kRizwrG64tE8S4,1844
72
- edsl/jobs/buckets/ModelBuckets.py,sha256=Rlh1gkXzusyb9GAXYJ9spNCmDMr4Cz1lPLSRP8-f2dY,2038
73
- edsl/jobs/buckets/TokenBucket.py,sha256=CUQDgzwNNJJxWr221Lwmp0KdUd10FFQgBVnMcnyuxCY,5188
74
- edsl/jobs/interviews/Interview.py,sha256=N0FCtU3McpBFazuKleHjQVfcG7Oq2ZdMW8G8BzTt-Jo,9708
72
+ edsl/jobs/buckets/ModelBuckets.py,sha256=hxw_tzc0V42CiB7mh5jIxlgwDVJ-zFZhlLtKrHEg8ho,2419
73
+ edsl/jobs/buckets/TokenBucket.py,sha256=jeWOzJBr70FJKpa_pOhLFwTBz6RB39tg9-ki5x4PmtM,5774
74
+ edsl/jobs/interviews/Interview.py,sha256=mnup2JIDlFrwE23pLBXzPDZpX9tJFp5hw2DqBoFoN0U,9750
75
75
  edsl/jobs/interviews/InterviewStatistic.py,sha256=hY5d2EkIJ96NilPpZAvZZzZoxLXM7ss3xx5MIcKtTPs,1856
76
76
  edsl/jobs/interviews/InterviewStatisticsCollection.py,sha256=_ZZ0fnZBQiIywP9Q_wWjpWhlfcPe2cn32GKut10t5RI,788
77
77
  edsl/jobs/interviews/InterviewStatusDictionary.py,sha256=MSyys4hOWe1d8gfsUvAPbcKrs8YiPnz8jpufBSJL7SU,2485
@@ -82,10 +82,10 @@ edsl/jobs/interviews/ReportErrors.py,sha256=RSzDU2rWwtjfztj7sqaMab0quCiY-X2bG3AE
82
82
  edsl/jobs/interviews/interview_exception_tracking.py,sha256=tIcX92udnkE5fcM5_WXjRF9xgTq2P0uaDXxZf3NQGG0,3271
83
83
  edsl/jobs/interviews/interview_status_enum.py,sha256=KJ-1yLAHdX-p8TiFnM0M3v1tnBwkq4aMCuBX6-ytrI8,229
84
84
  edsl/jobs/interviews/retry_management.py,sha256=9Efn4B3aV45vbocnF6J5WQt88i2FgFjoi5ALzGUukEE,1375
85
- edsl/jobs/runners/JobsRunnerAsyncio.py,sha256=vBUl4uyHHjWrOqK3maXwv-W-bt2rhgUBhowT-1QoQVQ,11834
85
+ edsl/jobs/runners/JobsRunnerAsyncio.py,sha256=L48NdyDiKrgUMQVwvd1wr2uOzT99oYfwXnlStDLHU9I,11934
86
86
  edsl/jobs/runners/JobsRunnerStatusData.py,sha256=-mxcmX0a38GGO9DQ-ItTmj6mvCUk5uC-UudT77lXTG4,10327
87
87
  edsl/jobs/runners/JobsRunnerStatusMixin.py,sha256=yxnXuOovwHgfDokNuluH_qulBcM0gCcbpCQibqVKXFI,3137
88
- edsl/jobs/tasks/QuestionTaskCreator.py,sha256=SXO_ITNPAXh9oBvCh8rcbH9ln0VjOyuM_i2IrRDHnIo,10231
88
+ edsl/jobs/tasks/QuestionTaskCreator.py,sha256=myiRwTJ48HERazdZRdqb7lRGlSSGYcXEVpTHcKho2I0,10483
89
89
  edsl/jobs/tasks/TaskCreators.py,sha256=DbCt5BzJ0CsMSquqLyLdk8el031Wst7vCszVW5EltX8,2418
90
90
  edsl/jobs/tasks/TaskHistory.py,sha256=ZVellGW1cvwqdHt98dYPl0FYhk3VqRGHAZETDOxEkqg,10939
91
91
  edsl/jobs/tasks/TaskStatusLog.py,sha256=bqH36a32F12fjX-M-4lNOhHaK2-WLFzKE-r0PxZPRjI,546
@@ -93,14 +93,14 @@ edsl/jobs/tasks/task_management.py,sha256=KMToZuXzMlnHRHUF_VHL0-lHMTGhklf2GHVuwE
93
93
  edsl/jobs/tasks/task_status_enum.py,sha256=DOyrz61YlIS8R1W7izJNphcLrJ7I_ReUlfdRmk23h0Q,5333
94
94
  edsl/jobs/tokens/InterviewTokenUsage.py,sha256=u_6-IHpGFwZ6qMEXr24-jyLVUSSp4dSs_4iAZsBv7O4,1100
95
95
  edsl/jobs/tokens/TokenUsage.py,sha256=odj2-wDNEbHl9noyFAQ0DSKV0D9cv3aDOpmXufKZ8O4,1323
96
- edsl/language_models/LanguageModel.py,sha256=ighiMbpkppcDMlW0s-5PYsPOUTFIpbDfdO6Cr87JUjo,18886
96
+ edsl/language_models/LanguageModel.py,sha256=r2wLIaF2vTlCNjEhDrDRKOZozmWvw6KkCEANLnZXOPE,18916
97
97
  edsl/language_models/ModelList.py,sha256=DLeAq7o8uniZkP_-z8vJDMwf4JXksqLoPqOeeLI3QBE,2687
98
98
  edsl/language_models/RegisterLanguageModelsMeta.py,sha256=2bvWrVau2BRo-Bb1aO-QATH8xxuW_tF7NmqBMGDOfSg,8191
99
99
  edsl/language_models/__init__.py,sha256=bvY7Gy6VkX1gSbNkRbGPS-M1kUnb0EohL0FSagaEaTs,109
100
100
  edsl/language_models/registry.py,sha256=J7blAbRFHxr2nWSoe61G4p-6kOgzUlKclJ55xVldKWc,3191
101
101
  edsl/language_models/repair.py,sha256=xaNunBRpMWgceSPOzk-ugp5WXtgLuuhj23TgXUeOobw,5963
102
102
  edsl/language_models/unused/ReplicateBase.py,sha256=J1oqf7mEyyKhRwNUomnptVqAsVFYCbS3iTW0EXpKtXo,3331
103
- edsl/notebooks/Notebook.py,sha256=tv5D-ZTNcYcheG3UJu5MAiM0urHw2Au1CjdTN5t5FBU,7114
103
+ edsl/notebooks/Notebook.py,sha256=qwDqUN2Gujr7WUneRrshzRBjHvcPpOIBRyqcrAOc90Q,7341
104
104
  edsl/notebooks/__init__.py,sha256=VNUA3nNq04slWNbYaNrzOhQJu3AZANpvBniyCJSzJ7U,45
105
105
  edsl/prompts/Prompt.py,sha256=12cbeQTKqfVQGpd1urqKZeXiDtKz2RAJqftoXS3q-DE,10070
106
106
  edsl/prompts/QuestionInstructionsBase.py,sha256=xico6ob4cqWsHl-txj2RbY_4Ny5u9UqvIjmoTVgjUhk,348
@@ -123,7 +123,7 @@ edsl/questions/QuestionBase.py,sha256=L0-IMnSGiUh5Uw7kFDsPV057mR9tL9aMwHUtxjLlKs
123
123
  edsl/questions/QuestionBudget.py,sha256=K8cc1YOfoLWRoZBAkWO7WsMDZne0a5oAJMSxv2Jzd1E,6143
124
124
  edsl/questions/QuestionCheckBox.py,sha256=YHS-LEvR_1CWyg4usOlWfj9Gb_cCQlfIWIWhYRWn7Wo,6129
125
125
  edsl/questions/QuestionExtract.py,sha256=fjnsNLS2fNW6dfFuRyc2EgKEHx8ujjONmg2nSRynje4,3988
126
- edsl/questions/QuestionFreeText.py,sha256=umLzZvhDcJlmPwev4z5VFV6cIO-omifPtyBR3EQc4mk,3173
126
+ edsl/questions/QuestionFreeText.py,sha256=ASj1s0EQYcZerJp476fscu_xEME8mKzVK3sPL6egiuU,3289
127
127
  edsl/questions/QuestionFunctional.py,sha256=s49mQBVGc7B4-3sX49_a_mgVZsR9bdPra2VYe4m8XoY,3961
128
128
  edsl/questions/QuestionList.py,sha256=Wf7xDXJsQBsAD_yOrzZ_GstKGT7aZjimTkU6qyqOhhM,4051
129
129
  edsl/questions/QuestionMultipleChoice.py,sha256=Oin_qOJz5wfZdcFopI6dyvlUn2LGocAvbNwSTmxWcQA,4491
@@ -144,18 +144,18 @@ edsl/questions/settings.py,sha256=er_z0ZW_dgmC5CHLWkaqBJiuWgAYzIund85M5YZFQAI,29
144
144
  edsl/results/Dataset.py,sha256=DZgb3vIj69ON7APQ6DimjBwAS1xZvZiXOg68CjW9E3I,8662
145
145
  edsl/results/DatasetExportMixin.py,sha256=QZEuSxJPisgJ5GvFkKbuqayCSgJzblclea1CFwsBZ2w,17959
146
146
  edsl/results/Result.py,sha256=X1qAACs9E6XhRmlIsb3CguDs6_laKkVyxE0JJpOJDZQ,12729
147
- edsl/results/Results.py,sha256=FuwUbcsa0rK3OWX4-nFUBq0egAeVVz7-Zgc8UAH3GkA,36326
147
+ edsl/results/Results.py,sha256=2fL1QxssSWh2iVYIrb7KXGK8pR0FJHSiAtqy3VBbPDk,36370
148
148
  edsl/results/ResultsDBMixin.py,sha256=Vs95zbSB4G7ENY4lU7OBdekg9evwTrtPH0IIL2NAFTk,7936
149
149
  edsl/results/ResultsExportMixin.py,sha256=XizBsPNxziyffirMA4kS7UHpYM1WIE4s1K-B7TqTfDw,1266
150
150
  edsl/results/ResultsFetchMixin.py,sha256=VEa0TKDcXbnTinSKs9YaE4WjOSLmlp9Po1_9kklFvSo,848
151
151
  edsl/results/ResultsGGMixin.py,sha256=SAYz8p4wb1g8x6KhBVz9NHOGib2c2XsqtTclpADrFeM,4344
152
152
  edsl/results/ResultsToolsMixin.py,sha256=I19kAO-BKszgjxzMljE1W8ZsOnpozmO2nc43-XBbrZk,2976
153
153
  edsl/results/__init__.py,sha256=2YcyiVtXi-3vIV0ZzOy1PqBLm2gaziufJVi4fdNrAt8,80
154
- edsl/scenarios/FileStore.py,sha256=sQAhmi7hXzfI9y-q3hOiBbTd-BAIRw9FusMyefM4mSI,4460
155
- edsl/scenarios/Scenario.py,sha256=KCMze1PL0uxLMrqaneEXZBDc65q7AUV71zZIEmeGSVo,14766
154
+ edsl/scenarios/FileStore.py,sha256=AevvU1qdLSmL4Q7cb1PhUiaJk1i5T0sgkTKBYf0KDN4,8722
155
+ edsl/scenarios/Scenario.py,sha256=eQRMV6JD6mrlIMXc7-NK0I-LK5px2oC6rAR_w-qJPnE,14829
156
156
  edsl/scenarios/ScenarioHtmlMixin.py,sha256=EmugmbPJYW5eZS30rM6pDMDQD9yrrvHjmgZWB1qBfq4,1882
157
157
  edsl/scenarios/ScenarioImageMixin.py,sha256=VJ5FqyPrL5-ieORlWMpnjmOAFIau8QFZCIZyEBKgb6I,3530
158
- edsl/scenarios/ScenarioList.py,sha256=9oxTglFTmKtkBexyNOLhIxocs1Jycuqf84OumHGsoII,18629
158
+ edsl/scenarios/ScenarioList.py,sha256=0Hx1JiXeHLfgKqSRQo2CO-HONgABHEC0lJVsaxZGm8o,18782
159
159
  edsl/scenarios/ScenarioListExportMixin.py,sha256=h5_yc__e6XolY6yP6T8cka5zU1mko8T5xbIQtYijNWQ,1003
160
160
  edsl/scenarios/ScenarioListPdfMixin.py,sha256=sRCHVG7z4u4ST4ce-I_Y4md8ZzC9-tj4an9PMouaHVg,3765
161
161
  edsl/scenarios/__init__.py,sha256=KRwZCLf2R0qyJvv1NGbd8M51Bt6Ia6Iylg-Xq_2Fa6M,98
@@ -163,14 +163,14 @@ edsl/shared.py,sha256=lgLa-mCk2flIhxXarXLtfXZjXG_6XHhC2A3O8yRTjXc,20
163
163
  edsl/study/ObjectEntry.py,sha256=e3xRPH8wCN8Pum5HZsQRYgnSoauSvjXunIEH79wu5A8,5788
164
164
  edsl/study/ProofOfWork.py,sha256=FaqYtLgeiTEQXWKukPgPUTWMcIN5t1FR7h7Re8QEtgc,3433
165
165
  edsl/study/SnapShot.py,sha256=-5zoP4uTvnqtu3zRNMD-fKsNAVYX9psoKRADfotsF9E,2439
166
- edsl/study/Study.py,sha256=Rh4Wq4Qxlpb5fOBsrMIXYfiCn-THBS9mk11AZjOzmGw,16934
166
+ edsl/study/Study.py,sha256=5yv5jT1uFxQD0oi_eODcKv_K6qTDbyAdMrAqBNNwOtE,16947
167
167
  edsl/study/__init__.py,sha256=YAvPLTPG3hK_eN9Ar3d1_d-E3laXpSya879A25-JAxU,170
168
168
  edsl/surveys/DAG.py,sha256=ozQuHo9ZQ8Eet5nDXtp7rFpiSocvvfxIHtyTnztvodg,2380
169
169
  edsl/surveys/Memory.py,sha256=-ikOtkkQldGB_BkPCW3o7AYwV5B_pIwlREw7aVCSHaQ,1113
170
170
  edsl/surveys/MemoryPlan.py,sha256=BeLuqS5Q8G2jSluHYFCAxVmj7cNPK-rDQ3mUsuDjikQ,7979
171
171
  edsl/surveys/Rule.py,sha256=ddZyZSObs4gsKtFSmcXkPigXDX8rrh1NFvAplP02TcA,11092
172
172
  edsl/surveys/RuleCollection.py,sha256=sN7aYDQJG3HmE-WxohgpctcQbHewjwE6NAqEVTxvFP8,13359
173
- edsl/surveys/Survey.py,sha256=q-AbzbyOsRZw_zRLrdDOM7y5kYQT6XlgYKQfxjdm1AQ,47107
173
+ edsl/surveys/Survey.py,sha256=oir5fnZD2chtUH1qsVSmTdVdXLRWcB0wkkby_Lcguu8,47227
174
174
  edsl/surveys/SurveyCSS.py,sha256=NjJezs2sTlgFprN6IukjGKwNYmNdXnLjzV2w5K4z4RI,8415
175
175
  edsl/surveys/SurveyExportMixin.py,sha256=vj9bZReHx0wBK9sVuS0alzPIUDdg6AFFMd7bl1RKWKI,6555
176
176
  edsl/surveys/SurveyFlowVisualizationMixin.py,sha256=Z-YqeedMqWOtCFy003YJ9aneJ1n4bn70lDoILwLtTc0,3966
@@ -197,7 +197,7 @@ edsl/utilities/interface.py,sha256=AaKpWiwWBwP2swNXmnFlIf3ZFsjfsR5bjXQAW47tD-8,1
197
197
  edsl/utilities/repair_functions.py,sha256=tftmklAqam6LOQQu_-9U44N-llycffhW8LfO63vBmNw,929
198
198
  edsl/utilities/restricted_python.py,sha256=5-_zUhrNbos7pLhDl9nr8d24auRlquR6w-vKkmNjPiA,2060
199
199
  edsl/utilities/utilities.py,sha256=oU5Gg6szTGqsJ2yBOS0aC3XooezLE8By3SdrQLLpqvA,10107
200
- edsl-0.1.30.dev1.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
201
- edsl-0.1.30.dev1.dist-info/METADATA,sha256=tUJbcT1q2md-1v9-CvYx2xQcuGZ_XtrQHWOxUXz_Lp8,4103
202
- edsl-0.1.30.dev1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
203
- edsl-0.1.30.dev1.dist-info/RECORD,,
200
+ edsl-0.1.30.dev3.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
201
+ edsl-0.1.30.dev3.dist-info/METADATA,sha256=WEosi8qKSarrZxQz2zECc1ZhsGstIRnIfJBOKTEW_YM,4103
202
+ edsl-0.1.30.dev3.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
203
+ edsl-0.1.30.dev3.dist-info/RECORD,,