edsl 0.1.33__py3-none-any.whl → 0.1.33.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edsl/Base.py +3 -9
- edsl/__init__.py +0 -1
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +6 -6
- edsl/agents/Invigilator.py +3 -6
- edsl/agents/InvigilatorBase.py +27 -8
- edsl/agents/{PromptConstructor.py → PromptConstructionMixin.py} +29 -101
- edsl/config.py +34 -26
- edsl/coop/coop.py +2 -11
- edsl/data_transfer_models.py +73 -26
- edsl/enums.py +0 -2
- edsl/inference_services/GoogleService.py +1 -1
- edsl/inference_services/InferenceServiceABC.py +13 -44
- edsl/inference_services/OpenAIService.py +4 -7
- edsl/inference_services/TestService.py +15 -24
- edsl/inference_services/registry.py +0 -2
- edsl/jobs/Jobs.py +8 -18
- edsl/jobs/buckets/BucketCollection.py +15 -24
- edsl/jobs/buckets/TokenBucket.py +10 -64
- edsl/jobs/interviews/Interview.py +47 -115
- edsl/jobs/interviews/InterviewExceptionEntry.py +0 -2
- edsl/jobs/interviews/{InterviewExceptionCollection.py → interview_exception_tracking.py} +0 -16
- edsl/jobs/interviews/retry_management.py +39 -0
- edsl/jobs/runners/JobsRunnerAsyncio.py +170 -95
- edsl/jobs/runners/JobsRunnerStatusMixin.py +333 -0
- edsl/jobs/tasks/TaskHistory.py +0 -17
- edsl/language_models/LanguageModel.py +31 -26
- edsl/language_models/registry.py +9 -13
- edsl/questions/QuestionBase.py +14 -63
- edsl/questions/QuestionBudget.py +41 -93
- edsl/questions/QuestionFreeText.py +0 -6
- edsl/questions/QuestionMultipleChoice.py +23 -8
- edsl/questions/QuestionNumerical.py +4 -5
- edsl/questions/ResponseValidatorABC.py +5 -6
- edsl/questions/derived/QuestionLinearScale.py +1 -4
- edsl/questions/derived/QuestionTopK.py +1 -4
- edsl/questions/derived/QuestionYesNo.py +2 -8
- edsl/results/DatasetExportMixin.py +1 -5
- edsl/results/Result.py +1 -1
- edsl/results/Results.py +1 -4
- edsl/scenarios/FileStore.py +10 -71
- edsl/scenarios/Scenario.py +21 -86
- edsl/scenarios/ScenarioImageMixin.py +2 -2
- edsl/scenarios/ScenarioList.py +0 -13
- edsl/scenarios/ScenarioListPdfMixin.py +4 -150
- edsl/study/Study.py +0 -32
- edsl/surveys/Rule.py +1 -10
- edsl/surveys/RuleCollection.py +3 -19
- edsl/surveys/Survey.py +0 -7
- edsl/templates/error_reporting/interview_details.html +1 -6
- edsl/utilities/utilities.py +1 -9
- {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/METADATA +1 -2
- {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/RECORD +55 -61
- edsl/inference_services/TogetherAIService.py +0 -170
- edsl/jobs/runners/JobsRunnerStatus.py +0 -331
- edsl/questions/Quick.py +0 -41
- edsl/questions/templates/budget/__init__.py +0 -0
- edsl/questions/templates/budget/answering_instructions.jinja +0 -7
- edsl/questions/templates/budget/question_presentation.jinja +0 -7
- edsl/questions/templates/extract/__init__.py +0 -0
- edsl/questions/templates/rank/__init__.py +0 -0
- {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/LICENSE +0 -0
- {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/WHEEL +0 -0
edsl/questions/QuestionBudget.py
CHANGED
@@ -1,60 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
|
3
|
-
|
4
|
-
from pydantic import Field, BaseModel, validator
|
5
|
-
|
2
|
+
import random
|
3
|
+
from typing import Any, Optional, Union
|
6
4
|
from edsl.questions.QuestionBase import QuestionBase
|
7
5
|
from edsl.questions.descriptors import IntegerDescriptor, QuestionOptionsDescriptor
|
8
|
-
from edsl.questions.ResponseValidatorABC import ResponseValidatorABC
|
9
|
-
|
10
|
-
|
11
|
-
class BudgewResponseValidator(ResponseValidatorABC):
|
12
|
-
valid_examples = []
|
13
|
-
|
14
|
-
invalid_examples = []
|
15
|
-
|
16
|
-
def fix(self, response, verbose=False):
|
17
|
-
if verbose:
|
18
|
-
print(f"Fixing list response: {response}")
|
19
|
-
answer = str(response.get("answer") or response.get("generated_tokens", ""))
|
20
|
-
if len(answer.split(",")) > 0:
|
21
|
-
return (
|
22
|
-
{"answer": answer.split(",")} | {"comment": response.get("comment")}
|
23
|
-
if "comment" in response
|
24
|
-
else {}
|
25
|
-
)
|
26
|
-
|
27
|
-
|
28
|
-
def create_budget_model(
|
29
|
-
budget_sum: float, permissive: bool, question_options: List[str]
|
30
|
-
):
|
31
|
-
class BudgetResponse(BaseModel):
|
32
|
-
answer: List[float] = Field(
|
33
|
-
...,
|
34
|
-
description="List of non-negative numbers representing budget allocation",
|
35
|
-
min_items=len(question_options),
|
36
|
-
max_items=len(question_options),
|
37
|
-
)
|
38
|
-
comment: Optional[str] = None
|
39
|
-
generated_tokens: Optional[str] = None
|
40
|
-
|
41
|
-
@validator("answer")
|
42
|
-
def validate_answer(cls, v):
|
43
|
-
if len(v) != len(question_options):
|
44
|
-
raise ValueError(f"Must provide {len(question_options)} values")
|
45
|
-
if any(x < 0 for x in v):
|
46
|
-
raise ValueError("All values must be non-negative")
|
47
|
-
total = sum(v)
|
48
|
-
if not permissive and total != budget_sum:
|
49
|
-
raise ValueError(f"Sum of numbers must equal {budget_sum}")
|
50
|
-
elif permissive and total > budget_sum:
|
51
|
-
raise ValueError(f"Sum of numbers cannot exceed {budget_sum}")
|
52
|
-
return v
|
53
|
-
|
54
|
-
class Config:
|
55
|
-
extra = "forbid"
|
56
|
-
|
57
|
-
return BudgetResponse
|
58
6
|
|
59
7
|
|
60
8
|
class QuestionBudget(QuestionBase):
|
@@ -64,7 +12,7 @@ class QuestionBudget(QuestionBase):
|
|
64
12
|
budget_sum: int = IntegerDescriptor(none_allowed=False)
|
65
13
|
question_options: list[str] = QuestionOptionsDescriptor(q_budget=True)
|
66
14
|
_response_model = None
|
67
|
-
response_validator_class =
|
15
|
+
response_validator_class = None
|
68
16
|
|
69
17
|
def __init__(
|
70
18
|
self,
|
@@ -72,10 +20,8 @@ class QuestionBudget(QuestionBase):
|
|
72
20
|
question_text: str,
|
73
21
|
question_options: list[str],
|
74
22
|
budget_sum: int,
|
75
|
-
include_comment: bool = True,
|
76
23
|
question_presentation: Optional[str] = None,
|
77
24
|
answering_instructions: Optional[str] = None,
|
78
|
-
permissive: bool = False,
|
79
25
|
):
|
80
26
|
"""Instantiate a new QuestionBudget.
|
81
27
|
|
@@ -90,17 +36,20 @@ class QuestionBudget(QuestionBase):
|
|
90
36
|
self.budget_sum = budget_sum
|
91
37
|
self.question_presentation = question_presentation
|
92
38
|
self.answering_instructions = answering_instructions
|
93
|
-
self.permissive = permissive
|
94
|
-
self.include_comment = include_comment
|
95
39
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
40
|
+
################
|
41
|
+
# Answer methods
|
42
|
+
################
|
43
|
+
def _validate_answer(self, answer: dict[str, Any]) -> dict[str, Union[int, str]]:
|
44
|
+
"""Validate the answer."""
|
45
|
+
self._validate_answer_template_basic(answer)
|
46
|
+
self._validate_answer_key_value(answer, "answer", dict)
|
47
|
+
self._validate_answer_budget(answer)
|
48
|
+
return answer
|
100
49
|
|
101
50
|
def _translate_answer_code_to_answer(
|
102
|
-
self,
|
103
|
-
)
|
51
|
+
self, answer_codes: dict[str, int], scenario: "Scenario" = None
|
52
|
+
):
|
104
53
|
"""
|
105
54
|
Translate the answer codes to the actual answers.
|
106
55
|
|
@@ -109,35 +58,35 @@ class QuestionBudget(QuestionBase):
|
|
109
58
|
This code will translate that to "a".
|
110
59
|
"""
|
111
60
|
translated_codes = []
|
112
|
-
for answer_code,
|
113
|
-
translated_codes.append({
|
61
|
+
for answer_code, response in answer_codes.items():
|
62
|
+
translated_codes.append({self.question_options[int(answer_code)]: response})
|
114
63
|
|
115
64
|
return translated_codes
|
116
65
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
66
|
+
def _simulate_answer(self, human_readable=True):
|
67
|
+
"""Simulate a valid answer for debugging purposes (what the validator expects)."""
|
68
|
+
from edsl.utilities.utilities import random_string
|
69
|
+
|
70
|
+
if human_readable:
|
71
|
+
keys = self.question_options
|
72
|
+
else:
|
73
|
+
keys = range(len(self.question_options))
|
74
|
+
remaining_budget = self.budget_sum
|
75
|
+
values = []
|
76
|
+
for _ in range(len(self.question_options)):
|
77
|
+
if _ == len(self.question_options) - 1:
|
78
|
+
# Assign remaining budget to the last value
|
79
|
+
values.append(remaining_budget)
|
80
|
+
else:
|
81
|
+
# Generate a random value between 0 and remaining budget
|
82
|
+
value = random.randint(0, remaining_budget)
|
83
|
+
values.append(value)
|
84
|
+
remaining_budget -= value
|
85
|
+
answer = dict(zip(keys, values))
|
86
|
+
return {
|
87
|
+
"answer": answer,
|
88
|
+
"comment": random_string(),
|
89
|
+
}
|
141
90
|
|
142
91
|
@property
|
143
92
|
def question_html_content(self) -> str:
|
@@ -184,14 +133,13 @@ class QuestionBudget(QuestionBase):
|
|
184
133
|
# Helpful methods
|
185
134
|
################
|
186
135
|
@classmethod
|
187
|
-
def example(cls
|
136
|
+
def example(cls) -> QuestionBudget:
|
188
137
|
"""Return an example of a budget question."""
|
189
138
|
return cls(
|
190
139
|
question_name="food_budget",
|
191
140
|
question_text="How would you allocate $100?",
|
192
141
|
question_options=["Pizza", "Ice Cream", "Burgers", "Salad"],
|
193
142
|
budget_sum=100,
|
194
|
-
include_comment=include_comment,
|
195
143
|
)
|
196
144
|
|
197
145
|
|
@@ -36,12 +36,6 @@ class FreeTextResponseValidator(ResponseValidatorABC):
|
|
36
36
|
),
|
37
37
|
]
|
38
38
|
|
39
|
-
def fix(self, response, verbose=False):
|
40
|
-
return {
|
41
|
-
"answer": str(response.get("generated_tokens")),
|
42
|
-
"generated_tokens": str(response.get("generated_tokens")),
|
43
|
-
}
|
44
|
-
|
45
39
|
|
46
40
|
class QuestionFreeText(QuestionBase):
|
47
41
|
"""This question prompts the agent to respond with free text."""
|
@@ -1,14 +1,22 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import Union, Literal, Optional
|
3
|
-
|
2
|
+
from typing import Union, Literal, Optional
|
4
3
|
from jinja2 import Template
|
4
|
+
|
5
5
|
from pydantic import BaseModel, Field
|
6
|
+
from typing import Optional, Literal
|
6
7
|
|
7
|
-
from edsl.scenarios.Scenario import Scenario
|
8
8
|
from edsl.questions.QuestionBase import QuestionBase
|
9
9
|
from edsl.questions.descriptors import QuestionOptionsDescriptor
|
10
10
|
from edsl.questions.decorators import inject_exception
|
11
|
+
|
11
12
|
from edsl.questions.ResponseValidatorABC import ResponseValidatorABC
|
13
|
+
from edsl.questions.ResponseValidatorABC import BaseResponse
|
14
|
+
|
15
|
+
from edsl.exceptions import QuestionAnswerValidationError
|
16
|
+
|
17
|
+
from pydantic import BaseModel, Field, create_model
|
18
|
+
|
19
|
+
from typing import List, Any, Literal
|
12
20
|
|
13
21
|
|
14
22
|
def create_response_model(choices: List[str], permissive: bool = False):
|
@@ -19,6 +27,7 @@ def create_response_model(choices: List[str], permissive: bool = False):
|
|
19
27
|
:param permissive: If True, any value will be accepted as an answer.
|
20
28
|
:return: A new Pydantic model class.
|
21
29
|
"""
|
30
|
+
# Convert the choices list to a tuple for use with Literal
|
22
31
|
choice_tuple = tuple(choices)
|
23
32
|
|
24
33
|
if not permissive:
|
@@ -57,6 +66,16 @@ def create_response_model(choices: List[str], permissive: bool = False):
|
|
57
66
|
return ChoiceResponse
|
58
67
|
|
59
68
|
|
69
|
+
def fix_multiple_choice(response, question_options, use_code, verbose=False):
|
70
|
+
"""Fix the response to a multiple choice question.
|
71
|
+
Respnse is a dictionary with keys:
|
72
|
+
- answer: the answer code
|
73
|
+
- generated_tokens: the generated tokens
|
74
|
+
- comment: the comment
|
75
|
+
"""
|
76
|
+
pass
|
77
|
+
|
78
|
+
|
60
79
|
class MultipleChoiceResponseValidator(ResponseValidatorABC):
|
61
80
|
required_params = ["question_options", "use_code"]
|
62
81
|
|
@@ -142,11 +161,6 @@ class QuestionMultipleChoice(QuestionBase):
|
|
142
161
|
:param question_name: The name of the question.
|
143
162
|
:param question_text: The text of the question.
|
144
163
|
:param question_options: The options the agent should select from.
|
145
|
-
:param include_comment: Whether to include a comment field.
|
146
|
-
:param use_code: Whether to use code for the options.
|
147
|
-
:param answering_instructions: Instructions for the question.
|
148
|
-
:param question_presentation: The presentation of the question.
|
149
|
-
:param permissive: Whether to force the answer to be one of the options.
|
150
164
|
|
151
165
|
"""
|
152
166
|
self.question_name = question_name
|
@@ -188,6 +202,7 @@ class QuestionMultipleChoice(QuestionBase):
|
|
188
202
|
'Happy'
|
189
203
|
|
190
204
|
"""
|
205
|
+
from edsl.scenarios.Scenario import Scenario
|
191
206
|
|
192
207
|
scenario = scenario or Scenario()
|
193
208
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
|
3
|
-
# from decimal import Decimal
|
2
|
+
from decimal import Decimal
|
4
3
|
from random import uniform
|
5
4
|
from typing import Any, Optional, Union, Literal
|
6
5
|
|
@@ -15,8 +14,8 @@ from edsl.exceptions.questions import QuestionAnswerValidationError
|
|
15
14
|
|
16
15
|
|
17
16
|
def create_numeric_response(
|
18
|
-
min_value: Optional[
|
19
|
-
max_value: Optional[
|
17
|
+
min_value: Optional[Decimal] = None,
|
18
|
+
max_value: Optional[Decimal] = None,
|
20
19
|
permissive=False,
|
21
20
|
):
|
22
21
|
field_kwargs = {}
|
@@ -28,7 +27,7 @@ def create_numeric_response(
|
|
28
27
|
field_kwargs["le"] = max_value
|
29
28
|
|
30
29
|
class ConstrainedNumericResponse(BaseModel):
|
31
|
-
answer: Union[
|
30
|
+
answer: Union[Decimal] = Field(**field_kwargs)
|
32
31
|
comment: Optional[str] = Field(None)
|
33
32
|
generated_tokens: Optional[Any] = Field(None)
|
34
33
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
from pydantic import BaseModel, Field, field_validator
|
3
|
-
|
4
|
-
# from decimal import Decimal
|
3
|
+
from decimal import Decimal
|
5
4
|
from typing import Optional, Any, List, TypedDict
|
6
5
|
|
7
6
|
from edsl.exceptions import QuestionAnswerValidationError
|
@@ -65,7 +64,7 @@ class ResponseValidatorABC(ABC):
|
|
65
64
|
>>> rv = ResponseValidatorABC.example()
|
66
65
|
>>> rv.override_answer = {"answer": 42}
|
67
66
|
>>> rv.validate({"answer": 23})
|
68
|
-
{'answer': 42, 'comment': None, 'generated_tokens': None}
|
67
|
+
{'answer': Decimal('42'), 'comment': None, 'generated_tokens': None}
|
69
68
|
"""
|
70
69
|
if self.exception_to_throw:
|
71
70
|
raise self.exception_to_throw
|
@@ -76,7 +75,7 @@ class ResponseValidatorABC(ABC):
|
|
76
75
|
|
77
76
|
>>> rv = ResponseValidatorABC.example("numerical")
|
78
77
|
>>> rv._base_validate({"answer": 42})
|
79
|
-
ConstrainedNumericResponse(answer=42, comment=None, generated_tokens=None)
|
78
|
+
ConstrainedNumericResponse(answer=Decimal('42'), comment=None, generated_tokens=None)
|
80
79
|
"""
|
81
80
|
try:
|
82
81
|
return self.response_model(**data)
|
@@ -98,7 +97,7 @@ class ResponseValidatorABC(ABC):
|
|
98
97
|
|
99
98
|
>>> rv = ResponseValidatorABC.example("numerical")
|
100
99
|
>>> rv.validate({"answer": 42})
|
101
|
-
{'answer': 42, 'comment': None, 'generated_tokens': None}
|
100
|
+
{'answer': Decimal('42'), 'comment': None, 'generated_tokens': None}
|
102
101
|
>>> rv.max_value
|
103
102
|
86.7
|
104
103
|
>>> rv.validate({"answer": "120"})
|
@@ -110,7 +109,7 @@ class ResponseValidatorABC(ABC):
|
|
110
109
|
>>> q.permissive = True
|
111
110
|
>>> rv = q.response_validator
|
112
111
|
>>> rv.validate({"answer": "120"})
|
113
|
-
{'answer': 120, 'comment': None, 'generated_tokens': None}
|
112
|
+
{'answer': Decimal('120'), 'comment': None, 'generated_tokens': None}
|
114
113
|
>>> rv.validate({"answer": "poo"})
|
115
114
|
Traceback (most recent call last):
|
116
115
|
...
|
@@ -22,7 +22,6 @@ class QuestionLinearScale(QuestionMultipleChoice):
|
|
22
22
|
option_labels: Optional[dict[int, str]] = None,
|
23
23
|
answering_instructions: Optional[str] = None,
|
24
24
|
question_presentation: Optional[str] = None,
|
25
|
-
include_comment: Optional[bool] = True,
|
26
25
|
):
|
27
26
|
"""Instantiate a new QuestionLinearScale.
|
28
27
|
|
@@ -37,7 +36,6 @@ class QuestionLinearScale(QuestionMultipleChoice):
|
|
37
36
|
question_text=question_text,
|
38
37
|
question_options=question_options,
|
39
38
|
use_code=False, # question linear scale will have it's own code
|
40
|
-
include_comment=include_comment,
|
41
39
|
)
|
42
40
|
self.question_options = question_options
|
43
41
|
self.option_labels = (
|
@@ -51,14 +49,13 @@ class QuestionLinearScale(QuestionMultipleChoice):
|
|
51
49
|
################
|
52
50
|
@classmethod
|
53
51
|
@inject_exception
|
54
|
-
def example(cls
|
52
|
+
def example(cls) -> QuestionLinearScale:
|
55
53
|
"""Return an example of a linear scale question."""
|
56
54
|
return cls(
|
57
55
|
question_text="How much do you like ice cream?",
|
58
56
|
question_options=[1, 2, 3, 4, 5],
|
59
57
|
question_name="ice_cream",
|
60
58
|
option_labels={1: "I hate it", 5: "I love it"},
|
61
|
-
include_comment=include_comment,
|
62
59
|
)
|
63
60
|
|
64
61
|
|
@@ -20,7 +20,6 @@ class QuestionTopK(QuestionCheckBox):
|
|
20
20
|
max_selections: int,
|
21
21
|
question_presentation: Optional[str] = None,
|
22
22
|
answering_instructions: Optional[str] = None,
|
23
|
-
include_comment: Optional[bool] = True,
|
24
23
|
):
|
25
24
|
"""Initialize the question.
|
26
25
|
|
@@ -38,7 +37,6 @@ class QuestionTopK(QuestionCheckBox):
|
|
38
37
|
max_selections=max_selections,
|
39
38
|
question_presentation=question_presentation,
|
40
39
|
answering_instructions=answering_instructions,
|
41
|
-
include_comment=include_comment,
|
42
40
|
)
|
43
41
|
if min_selections != max_selections:
|
44
42
|
raise QuestionCreationValidationError(
|
@@ -54,7 +52,7 @@ class QuestionTopK(QuestionCheckBox):
|
|
54
52
|
################
|
55
53
|
@classmethod
|
56
54
|
@inject_exception
|
57
|
-
def example(cls
|
55
|
+
def example(cls) -> QuestionTopK:
|
58
56
|
"""Return an example question."""
|
59
57
|
return cls(
|
60
58
|
question_name="two_fruits",
|
@@ -62,7 +60,6 @@ class QuestionTopK(QuestionCheckBox):
|
|
62
60
|
question_options=["apple", "banana", "carrot", "durian"],
|
63
61
|
min_selections=2,
|
64
62
|
max_selections=2,
|
65
|
-
include_comment=include_comment,
|
66
63
|
)
|
67
64
|
|
68
65
|
|
@@ -19,7 +19,6 @@ class QuestionYesNo(QuestionMultipleChoice):
|
|
19
19
|
question_options: list[str] = ["No", "Yes"],
|
20
20
|
answering_instructions: Optional[str] = None,
|
21
21
|
question_presentation: Optional[str] = None,
|
22
|
-
include_comment: Optional[bool] = True,
|
23
22
|
):
|
24
23
|
"""Instantiate a new QuestionYesNo.
|
25
24
|
|
@@ -34,7 +33,6 @@ class QuestionYesNo(QuestionMultipleChoice):
|
|
34
33
|
use_code=False,
|
35
34
|
answering_instructions=answering_instructions,
|
36
35
|
question_presentation=question_presentation,
|
37
|
-
include_comment=include_comment,
|
38
36
|
)
|
39
37
|
self.question_options = question_options
|
40
38
|
|
@@ -43,13 +41,9 @@ class QuestionYesNo(QuestionMultipleChoice):
|
|
43
41
|
################
|
44
42
|
@classmethod
|
45
43
|
@inject_exception
|
46
|
-
def example(cls
|
44
|
+
def example(cls) -> QuestionYesNo:
|
47
45
|
"""Return an example of a yes/no question."""
|
48
|
-
return cls(
|
49
|
-
question_name="is_it_equal",
|
50
|
-
question_text="Is 5 + 5 equal to 11?",
|
51
|
-
include_comment=include_comment,
|
52
|
-
)
|
46
|
+
return cls(question_name="is_it_equal", question_text="Is 5 + 5 equal to 11?")
|
53
47
|
|
54
48
|
|
55
49
|
def main():
|
@@ -472,11 +472,7 @@ class DatasetExportMixin:
|
|
472
472
|
from edsl import ScenarioList, Scenario
|
473
473
|
|
474
474
|
list_of_dicts = self.to_dicts(remove_prefix=remove_prefix)
|
475
|
-
|
476
|
-
for d in list_of_dicts:
|
477
|
-
scenarios.append(Scenario(d))
|
478
|
-
return ScenarioList(scenarios)
|
479
|
-
# return ScenarioList([Scenario(d) for d in list_of_dicts])
|
475
|
+
return ScenarioList([Scenario(d) for d in list_of_dicts])
|
480
476
|
|
481
477
|
def to_agent_list(self, remove_prefix: bool = True):
|
482
478
|
"""Convert the results to a list of dictionaries, one per agent.
|
edsl/results/Result.py
CHANGED
@@ -367,7 +367,7 @@ class Result(Base, UserDict):
|
|
367
367
|
"raw_model_response", {"raw_model_response": "No raw model response"}
|
368
368
|
),
|
369
369
|
question_to_attributes=json_dict.get("question_to_attributes", None),
|
370
|
-
generated_tokens=json_dict.get("generated_tokens",
|
370
|
+
generated_tokens=json_dict.get("generated_tokens", None),
|
371
371
|
)
|
372
372
|
return result
|
373
373
|
|
edsl/results/Results.py
CHANGED
@@ -245,9 +245,7 @@ class Results(UserList, Mixins, Base):
|
|
245
245
|
)
|
246
246
|
|
247
247
|
def __repr__(self) -> str:
|
248
|
-
|
249
|
-
|
250
|
-
return f"Results(data = {reprlib.repr(self.data)}, survey = {repr(self.survey)}, created_columns = {self.created_columns})"
|
248
|
+
return f"Results(data = {self.data}, survey = {repr(self.survey)}, created_columns = {self.created_columns})"
|
251
249
|
|
252
250
|
def _repr_html_(self) -> str:
|
253
251
|
from IPython.display import HTML
|
@@ -1091,7 +1089,6 @@ class Results(UserList, Mixins, Base):
|
|
1091
1089
|
stop_on_exception=True,
|
1092
1090
|
skip_retry=True,
|
1093
1091
|
raise_validation_errors=True,
|
1094
|
-
disable_remote_inference=True,
|
1095
1092
|
)
|
1096
1093
|
return results
|
1097
1094
|
|
edsl/scenarios/FileStore.py
CHANGED
@@ -120,22 +120,14 @@ class FileStore(Scenario):
|
|
120
120
|
return info
|
121
121
|
|
122
122
|
@classmethod
|
123
|
-
def pull(cls, uuid
|
124
|
-
scenario_version = Scenario.pull(uuid
|
123
|
+
def pull(cls, uuid):
|
124
|
+
scenario_version = Scenario.pull(uuid)
|
125
125
|
return cls.from_dict(scenario_version.to_dict())
|
126
126
|
|
127
127
|
|
128
128
|
class CSVFileStore(FileStore):
|
129
|
-
def __init__(
|
130
|
-
|
131
|
-
filename,
|
132
|
-
binary: Optional[bool] = None,
|
133
|
-
suffix: Optional[str] = None,
|
134
|
-
base64_string: Optional[str] = None,
|
135
|
-
):
|
136
|
-
super().__init__(
|
137
|
-
filename, binary=binary, base64_string=base64_string, suffix=".csv"
|
138
|
-
)
|
129
|
+
def __init__(self, filename):
|
130
|
+
super().__init__(filename, suffix=".csv")
|
139
131
|
|
140
132
|
@classmethod
|
141
133
|
def example(cls):
|
@@ -155,16 +147,8 @@ class CSVFileStore(FileStore):
|
|
155
147
|
|
156
148
|
|
157
149
|
class PDFFileStore(FileStore):
|
158
|
-
def __init__(
|
159
|
-
|
160
|
-
filename,
|
161
|
-
binary: Optional[bool] = None,
|
162
|
-
suffix: Optional[str] = None,
|
163
|
-
base64_string: Optional[str] = None,
|
164
|
-
):
|
165
|
-
super().__init__(
|
166
|
-
filename, binary=binary, base64_string=base64_string, suffix=".pdf"
|
167
|
-
)
|
150
|
+
def __init__(self, filename):
|
151
|
+
super().__init__(filename, suffix=".pdf")
|
168
152
|
|
169
153
|
def view(self):
|
170
154
|
pdf_path = self.to_tempfile()
|
@@ -241,16 +225,8 @@ class PDFFileStore(FileStore):
|
|
241
225
|
|
242
226
|
|
243
227
|
class PNGFileStore(FileStore):
|
244
|
-
def __init__(
|
245
|
-
|
246
|
-
filename,
|
247
|
-
binary: Optional[bool] = None,
|
248
|
-
suffix: Optional[str] = None,
|
249
|
-
base64_string: Optional[str] = None,
|
250
|
-
):
|
251
|
-
super().__init__(
|
252
|
-
filename, binary=binary, base64_string=base64_string, suffix=".png"
|
253
|
-
)
|
228
|
+
def __init__(self, filename):
|
229
|
+
super().__init__(filename, suffix=".png")
|
254
230
|
|
255
231
|
@classmethod
|
256
232
|
def example(cls):
|
@@ -275,16 +251,8 @@ class PNGFileStore(FileStore):
|
|
275
251
|
|
276
252
|
|
277
253
|
class SQLiteFileStore(FileStore):
|
278
|
-
def __init__(
|
279
|
-
|
280
|
-
filename,
|
281
|
-
binary: Optional[bool] = None,
|
282
|
-
suffix: Optional[str] = None,
|
283
|
-
base64_string: Optional[str] = None,
|
284
|
-
):
|
285
|
-
super().__init__(
|
286
|
-
filename, binary=binary, base64_string=base64_string, suffix=".sqlite"
|
287
|
-
)
|
254
|
+
def __init__(self, filename):
|
255
|
+
super().__init__(filename, suffix=".sqlite")
|
288
256
|
|
289
257
|
@classmethod
|
290
258
|
def example(cls):
|
@@ -297,8 +265,6 @@ class SQLiteFileStore(FileStore):
|
|
297
265
|
c.execute("""CREATE TABLE stocks (date text)""")
|
298
266
|
conn.commit()
|
299
267
|
|
300
|
-
return cls(f.name)
|
301
|
-
|
302
268
|
def view(self):
|
303
269
|
import subprocess
|
304
270
|
import os
|
@@ -307,33 +273,6 @@ class SQLiteFileStore(FileStore):
|
|
307
273
|
os.system(f"sqlite3 {sqlite_path}")
|
308
274
|
|
309
275
|
|
310
|
-
class HTMLFileStore(FileStore):
|
311
|
-
def __init__(
|
312
|
-
self,
|
313
|
-
filename,
|
314
|
-
binary: Optional[bool] = None,
|
315
|
-
suffix: Optional[str] = None,
|
316
|
-
base64_string: Optional[str] = None,
|
317
|
-
):
|
318
|
-
super().__init__(
|
319
|
-
filename, binary=binary, base64_string=base64_string, suffix=".html"
|
320
|
-
)
|
321
|
-
|
322
|
-
@classmethod
|
323
|
-
def example(cls):
|
324
|
-
import tempfile
|
325
|
-
|
326
|
-
with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as f:
|
327
|
-
f.write("<html><body><h1>Test</h1></body></html>".encode())
|
328
|
-
return cls(f.name)
|
329
|
-
|
330
|
-
def view(self):
|
331
|
-
import webbrowser
|
332
|
-
|
333
|
-
html_path = self.to_tempfile()
|
334
|
-
webbrowser.open("file://" + html_path)
|
335
|
-
|
336
|
-
|
337
276
|
if __name__ == "__main__":
|
338
277
|
# file_path = "../conjure/examples/Ex11-2.sav"
|
339
278
|
# fs = FileStore(file_path)
|