edsl 0.1.54__py3-none-any.whl → 0.1.56__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/__init__.py +8 -1
- edsl/__init__original.py +134 -0
- edsl/__version__.py +1 -1
- edsl/agents/agent.py +29 -0
- edsl/agents/agent_list.py +36 -1
- edsl/base/base_class.py +281 -151
- edsl/base/data_transfer_models.py +15 -4
- edsl/buckets/__init__.py +8 -3
- edsl/buckets/bucket_collection.py +9 -3
- edsl/buckets/model_buckets.py +4 -2
- edsl/buckets/token_bucket.py +2 -2
- edsl/buckets/token_bucket_client.py +5 -3
- edsl/caching/cache.py +131 -62
- edsl/caching/cache_entry.py +70 -58
- edsl/caching/sql_dict.py +17 -0
- edsl/cli.py +99 -0
- edsl/config/config_class.py +16 -0
- edsl/conversation/__init__.py +31 -0
- edsl/coop/coop.py +276 -242
- edsl/coop/coop_jobs_objects.py +59 -0
- edsl/coop/coop_objects.py +29 -0
- edsl/coop/coop_regular_objects.py +26 -0
- edsl/coop/utils.py +24 -19
- edsl/dataset/dataset.py +338 -101
- edsl/dataset/dataset_operations_mixin.py +216 -180
- edsl/db_list/sqlite_list.py +349 -0
- edsl/inference_services/__init__.py +40 -5
- edsl/inference_services/exceptions.py +11 -0
- edsl/inference_services/services/anthropic_service.py +5 -2
- edsl/inference_services/services/aws_bedrock.py +6 -2
- edsl/inference_services/services/azure_ai.py +6 -2
- edsl/inference_services/services/google_service.py +7 -3
- edsl/inference_services/services/mistral_ai_service.py +6 -2
- edsl/inference_services/services/open_ai_service.py +6 -2
- edsl/inference_services/services/perplexity_service.py +6 -2
- edsl/inference_services/services/test_service.py +94 -5
- edsl/interviews/answering_function.py +167 -59
- edsl/interviews/interview.py +124 -72
- edsl/interviews/interview_task_manager.py +10 -0
- edsl/interviews/request_token_estimator.py +8 -0
- edsl/invigilators/invigilators.py +35 -13
- edsl/jobs/async_interview_runner.py +146 -104
- edsl/jobs/data_structures.py +6 -4
- edsl/jobs/decorators.py +61 -0
- edsl/jobs/fetch_invigilator.py +61 -18
- edsl/jobs/html_table_job_logger.py +14 -2
- edsl/jobs/jobs.py +180 -104
- edsl/jobs/jobs_component_constructor.py +2 -2
- edsl/jobs/jobs_interview_constructor.py +2 -0
- edsl/jobs/jobs_pricing_estimation.py +154 -113
- edsl/jobs/jobs_remote_inference_logger.py +4 -0
- edsl/jobs/jobs_runner_status.py +30 -25
- edsl/jobs/progress_bar_manager.py +79 -0
- edsl/jobs/remote_inference.py +35 -1
- edsl/key_management/key_lookup_builder.py +6 -1
- edsl/language_models/language_model.py +110 -12
- edsl/language_models/model.py +10 -3
- edsl/language_models/price_manager.py +176 -71
- edsl/language_models/registry.py +5 -0
- edsl/notebooks/notebook.py +77 -10
- edsl/questions/VALIDATION_README.md +134 -0
- edsl/questions/__init__.py +24 -1
- edsl/questions/exceptions.py +21 -0
- edsl/questions/question_dict.py +201 -16
- edsl/questions/question_multiple_choice_with_other.py +624 -0
- edsl/questions/question_registry.py +2 -1
- edsl/questions/templates/multiple_choice_with_other/__init__.py +0 -0
- edsl/questions/templates/multiple_choice_with_other/answering_instructions.jinja +15 -0
- edsl/questions/templates/multiple_choice_with_other/question_presentation.jinja +17 -0
- edsl/questions/validation_analysis.py +185 -0
- edsl/questions/validation_cli.py +131 -0
- edsl/questions/validation_html_report.py +404 -0
- edsl/questions/validation_logger.py +136 -0
- edsl/results/result.py +115 -46
- edsl/results/results.py +702 -171
- edsl/scenarios/construct_download_link.py +16 -3
- edsl/scenarios/directory_scanner.py +226 -226
- edsl/scenarios/file_methods.py +5 -0
- edsl/scenarios/file_store.py +150 -9
- edsl/scenarios/handlers/__init__.py +5 -1
- edsl/scenarios/handlers/mp4_file_store.py +104 -0
- edsl/scenarios/handlers/webm_file_store.py +104 -0
- edsl/scenarios/scenario.py +120 -101
- edsl/scenarios/scenario_list.py +800 -727
- edsl/scenarios/scenario_list_gc_test.py +146 -0
- edsl/scenarios/scenario_list_memory_test.py +214 -0
- edsl/scenarios/scenario_list_source_refactor.md +35 -0
- edsl/scenarios/scenario_selector.py +5 -4
- edsl/scenarios/scenario_source.py +1990 -0
- edsl/scenarios/tests/test_scenario_list_sources.py +52 -0
- edsl/surveys/survey.py +22 -0
- edsl/tasks/__init__.py +4 -2
- edsl/tasks/task_history.py +198 -36
- edsl/tests/scenarios/test_ScenarioSource.py +51 -0
- edsl/tests/scenarios/test_scenario_list_sources.py +51 -0
- edsl/utilities/__init__.py +2 -1
- edsl/utilities/decorators.py +121 -0
- edsl/utilities/memory_debugger.py +1010 -0
- {edsl-0.1.54.dist-info → edsl-0.1.56.dist-info}/METADATA +51 -76
- {edsl-0.1.54.dist-info → edsl-0.1.56.dist-info}/RECORD +103 -79
- edsl/jobs/jobs_runner_asyncio.py +0 -281
- edsl/language_models/unused/fake_openai_service.py +0 -60
- {edsl-0.1.54.dist-info → edsl-0.1.56.dist-info}/LICENSE +0 -0
- {edsl-0.1.54.dist-info → edsl-0.1.56.dist-info}/WHEEL +0 -0
- {edsl-0.1.54.dist-info → edsl-0.1.56.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
"""
|
2
|
+
Test script to investigate garbage collection behavior with ScenarioList.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import gc
|
6
|
+
import os
|
7
|
+
import psutil
|
8
|
+
import sys
|
9
|
+
import pickle
|
10
|
+
import tracemalloc
|
11
|
+
from typing import Dict, List, Any
|
12
|
+
|
13
|
+
def get_memory_usage() -> float:
|
14
|
+
"""Get current memory usage in MB"""
|
15
|
+
process = psutil.Process(os.getpid())
|
16
|
+
memory_info = process.memory_info()
|
17
|
+
memory_mb = memory_info.rss / (1024 * 1024)
|
18
|
+
return memory_mb
|
19
|
+
|
20
|
+
def display_memory_usage(label: str) -> float:
|
21
|
+
"""Display and return current memory usage."""
|
22
|
+
mem = get_memory_usage()
|
23
|
+
print(f"{label}: {mem:.2f} MB")
|
24
|
+
return mem
|
25
|
+
|
26
|
+
def test_pickle_gc() -> None:
|
27
|
+
"""Test if pickle.dumps objects are properly garbage collected."""
|
28
|
+
display_memory_usage("Initial memory")
|
29
|
+
|
30
|
+
# Force garbage collection
|
31
|
+
gc.collect()
|
32
|
+
start_mem = display_memory_usage("Memory after initial gc")
|
33
|
+
|
34
|
+
# Test with a string of 1MB
|
35
|
+
text = "x" * (1024 * 1024) # 1MB string
|
36
|
+
display_memory_usage("Memory after creating 1MB string")
|
37
|
+
|
38
|
+
# Create 100 large dictionaries
|
39
|
+
data_list: List[Dict[str, Any]] = []
|
40
|
+
for i in range(100):
|
41
|
+
data = {"id": i, "text": text, "value": i * 100}
|
42
|
+
data_list.append(data)
|
43
|
+
|
44
|
+
gc.collect()
|
45
|
+
display_memory_usage("Memory after creating 100 dicts with shared string")
|
46
|
+
|
47
|
+
# Now pickle each object
|
48
|
+
print("\nPickling objects one at a time:")
|
49
|
+
for i, data in enumerate(data_list):
|
50
|
+
# Pickle the object and immediately delete the reference
|
51
|
+
serialized = pickle.dumps(data)
|
52
|
+
# Explicitly delete to help garbage collection
|
53
|
+
del serialized
|
54
|
+
|
55
|
+
# Every 10 items, force garbage collection and check memory
|
56
|
+
if i % 10 == 9:
|
57
|
+
gc.collect()
|
58
|
+
display_memory_usage(f"Memory after pickling {i+1} objects and gc")
|
59
|
+
|
60
|
+
# Final garbage collection
|
61
|
+
gc.collect()
|
62
|
+
end_mem = display_memory_usage("Memory after final gc")
|
63
|
+
|
64
|
+
print(f"\nTotal memory increase: {end_mem - start_mem:.2f} MB")
|
65
|
+
|
66
|
+
# Now test with tracemalloc to see exactly where memory is allocated
|
67
|
+
print("\nDetailed memory tracing with tracemalloc:")
|
68
|
+
tracemalloc.start()
|
69
|
+
|
70
|
+
# Get snapshot before
|
71
|
+
data = {"id": 1, "text": "x" * (1024 * 1024), "value": 100}
|
72
|
+
snapshot1 = tracemalloc.take_snapshot()
|
73
|
+
|
74
|
+
# Do 10 pickling operations
|
75
|
+
for i in range(10):
|
76
|
+
serialized = pickle.dumps(data)
|
77
|
+
del serialized
|
78
|
+
|
79
|
+
# Get snapshot after
|
80
|
+
snapshot2 = tracemalloc.take_snapshot()
|
81
|
+
|
82
|
+
# Compare and show top differences
|
83
|
+
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
|
84
|
+
print("\nTop 10 memory allocations:")
|
85
|
+
for stat in top_stats[:10]:
|
86
|
+
print(f"{stat.traceback.format()[0]} - {stat.size_diff / 1024:.2f} KB")
|
87
|
+
|
88
|
+
tracemalloc.stop()
|
89
|
+
|
90
|
+
def test_sqlite_insert() -> None:
|
91
|
+
"""Test SQLite insertion memory behavior."""
|
92
|
+
import sqlite3
|
93
|
+
import tempfile
|
94
|
+
|
95
|
+
display_memory_usage("Initial memory")
|
96
|
+
|
97
|
+
# Force garbage collection
|
98
|
+
gc.collect()
|
99
|
+
start_mem = display_memory_usage("Memory after initial gc")
|
100
|
+
|
101
|
+
# Create a temporary database
|
102
|
+
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as tmp:
|
103
|
+
db_path = tmp.name
|
104
|
+
|
105
|
+
# Connect to the database
|
106
|
+
conn = sqlite3.connect(db_path)
|
107
|
+
conn.execute("CREATE TABLE IF NOT EXISTS items (idx INTEGER, value BLOB)")
|
108
|
+
|
109
|
+
# Create a large string and dictionary
|
110
|
+
text = "x" * (1024 * 1024) # 1MB string
|
111
|
+
display_memory_usage("Memory after creating 1MB string")
|
112
|
+
|
113
|
+
# Insert 100 large pickled objects
|
114
|
+
print("\nInserting objects one at a time:")
|
115
|
+
for i in range(100):
|
116
|
+
data = {"id": i, "text": text, "value": i * 100}
|
117
|
+
serialized = pickle.dumps(data)
|
118
|
+
|
119
|
+
# Insert into database
|
120
|
+
conn.execute("INSERT INTO items (idx, value) VALUES (?, ?)", (i, serialized))
|
121
|
+
|
122
|
+
# Explicitly delete serialized data
|
123
|
+
del serialized
|
124
|
+
|
125
|
+
# Every 10 items, force garbage collection and check memory
|
126
|
+
if i % 10 == 9:
|
127
|
+
conn.commit() # Commit to ensure SQLite releases memory
|
128
|
+
gc.collect()
|
129
|
+
display_memory_usage(f"Memory after inserting {i+1} objects and gc")
|
130
|
+
|
131
|
+
# Close connection and clean up
|
132
|
+
conn.close()
|
133
|
+
os.unlink(db_path)
|
134
|
+
|
135
|
+
# Final garbage collection
|
136
|
+
gc.collect()
|
137
|
+
end_mem = display_memory_usage("Memory after final gc")
|
138
|
+
|
139
|
+
print(f"\nTotal memory increase: {end_mem - start_mem:.2f} MB")
|
140
|
+
|
141
|
+
if __name__ == "__main__":
|
142
|
+
print("===== Testing pickle garbage collection =====")
|
143
|
+
test_pickle_gc()
|
144
|
+
|
145
|
+
print("\n\n===== Testing SQLite insertion memory behavior =====")
|
146
|
+
test_sqlite_insert()
|
@@ -0,0 +1,214 @@
|
|
1
|
+
"""
|
2
|
+
Memory usage test for ScenarioList with different data sizes.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import gc
|
6
|
+
import os
|
7
|
+
import psutil
|
8
|
+
import time
|
9
|
+
import json
|
10
|
+
from typing import Dict, List, Any, Tuple
|
11
|
+
import matplotlib.pyplot as plt
|
12
|
+
|
13
|
+
def get_memory_usage() -> float:
|
14
|
+
"""Get current memory usage in MB"""
|
15
|
+
process = psutil.Process(os.getpid())
|
16
|
+
memory_info = process.memory_info()
|
17
|
+
memory_mb = memory_info.rss / (1024 * 1024)
|
18
|
+
return memory_mb
|
19
|
+
|
20
|
+
def log_memory(label: str) -> float:
|
21
|
+
"""Log and return current memory usage."""
|
22
|
+
mem = get_memory_usage()
|
23
|
+
print(f"{label}: {mem:.2f} MB")
|
24
|
+
return mem
|
25
|
+
|
26
|
+
def run_memory_test(sizes: List[int], item_size_kb: int = 10) -> Dict[str, Dict[int, float]]:
|
27
|
+
"""
|
28
|
+
Test memory usage for ScenarioList with different dataset sizes.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
sizes: List of dataset sizes to test
|
32
|
+
item_size_kb: Size of text data in each scenario (in KB)
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
Dictionary with memory usage metrics for each size
|
36
|
+
"""
|
37
|
+
from edsl.scenarios import ScenarioList
|
38
|
+
|
39
|
+
results = {
|
40
|
+
"creation": {},
|
41
|
+
"filter": {},
|
42
|
+
"baseline": {},
|
43
|
+
"total": {}
|
44
|
+
}
|
45
|
+
|
46
|
+
for size in sizes:
|
47
|
+
print(f"\n{'='*50}")
|
48
|
+
print(f"Testing with {size} scenarios (each with {item_size_kb}KB text)")
|
49
|
+
print(f"{'='*50}")
|
50
|
+
|
51
|
+
# Force garbage collection before starting
|
52
|
+
gc.collect()
|
53
|
+
gc.collect()
|
54
|
+
time.sleep(1) # Give system time to stabilize
|
55
|
+
|
56
|
+
baseline_mem = log_memory(f"Baseline memory")
|
57
|
+
results["baseline"][size] = baseline_mem
|
58
|
+
|
59
|
+
# Create test data
|
60
|
+
text_size = item_size_kb * 1024 # Convert KB to bytes
|
61
|
+
text = "x" * text_size
|
62
|
+
|
63
|
+
# Create scenarios
|
64
|
+
print(f"Creating {size} scenarios...")
|
65
|
+
scenarios = []
|
66
|
+
for i in range(size):
|
67
|
+
scenarios.append({
|
68
|
+
"id": i,
|
69
|
+
"text": text,
|
70
|
+
"category": "A" if i % 2 == 0 else "B",
|
71
|
+
"value": i * 10
|
72
|
+
})
|
73
|
+
|
74
|
+
# Measure memory after creating raw data
|
75
|
+
after_raw_mem = log_memory("Memory after creating raw data")
|
76
|
+
|
77
|
+
# Create ScenarioList
|
78
|
+
print(f"Creating ScenarioList...")
|
79
|
+
start_time = time.time()
|
80
|
+
sl = ScenarioList(scenarios)
|
81
|
+
creation_time = time.time() - start_time
|
82
|
+
|
83
|
+
# Measure memory after creating ScenarioList
|
84
|
+
after_creation_mem = log_memory("Memory after creating ScenarioList")
|
85
|
+
creation_mem_diff = after_creation_mem - after_raw_mem
|
86
|
+
results["creation"][size] = creation_mem_diff
|
87
|
+
print(f"Creation memory increase: {creation_mem_diff:.2f} MB")
|
88
|
+
print(f"Creation time: {creation_time:.2f} seconds")
|
89
|
+
|
90
|
+
# Filter ScenarioList
|
91
|
+
print(f"Filtering ScenarioList...")
|
92
|
+
start_time = time.time()
|
93
|
+
filtered = sl.filter("id % 2 == 0")
|
94
|
+
filter_time = time.time() - start_time
|
95
|
+
|
96
|
+
# Measure memory after filtering
|
97
|
+
after_filter_mem = log_memory("Memory after filtering")
|
98
|
+
filter_mem_diff = after_filter_mem - after_creation_mem
|
99
|
+
results["filter"][size] = filter_mem_diff
|
100
|
+
results["total"][size] = after_filter_mem - baseline_mem
|
101
|
+
print(f"Filter memory increase: {filter_mem_diff:.2f} MB")
|
102
|
+
print(f"Filter time: {filter_time:.2f} seconds")
|
103
|
+
print(f"Total memory increase: {after_filter_mem - baseline_mem:.2f} MB")
|
104
|
+
|
105
|
+
# Clean up to prepare for next iteration
|
106
|
+
del scenarios
|
107
|
+
del sl
|
108
|
+
del filtered
|
109
|
+
gc.collect()
|
110
|
+
gc.collect()
|
111
|
+
time.sleep(1) # Give system time to stabilize
|
112
|
+
|
113
|
+
return results
|
114
|
+
|
115
|
+
def plot_results(results: Dict[str, Dict[int, float]],
|
116
|
+
output_path: str = "memory_usage_plot.png") -> None:
|
117
|
+
"""
|
118
|
+
Plot memory usage results.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
results: Dictionary with memory usage metrics
|
122
|
+
output_path: Path to save the plot
|
123
|
+
"""
|
124
|
+
sizes = sorted(results["creation"].keys())
|
125
|
+
|
126
|
+
# Extract data for plotting
|
127
|
+
creation_memory = [results["creation"][size] for size in sizes]
|
128
|
+
filter_memory = [results["filter"][size] for size in sizes]
|
129
|
+
total_memory = [results["total"][size] for size in sizes]
|
130
|
+
|
131
|
+
# Create figure and axis
|
132
|
+
plt.figure(figsize=(12, 8))
|
133
|
+
|
134
|
+
# Plot memory usage
|
135
|
+
plt.subplot(2, 1, 1)
|
136
|
+
plt.plot(sizes, creation_memory, 'o-', label='ScenarioList Creation')
|
137
|
+
plt.plot(sizes, filter_memory, 's-', label='Filter Operation')
|
138
|
+
plt.plot(sizes, total_memory, '^-', label='Total Memory Usage')
|
139
|
+
plt.xlabel('Number of Scenarios')
|
140
|
+
plt.ylabel('Memory Usage (MB)')
|
141
|
+
plt.title('Memory Usage vs. Dataset Size')
|
142
|
+
plt.grid(True)
|
143
|
+
plt.legend()
|
144
|
+
|
145
|
+
# Plot memory usage per scenario
|
146
|
+
plt.subplot(2, 1, 2)
|
147
|
+
mem_per_scenario_creation = [mem/size for mem, size in zip(creation_memory, sizes)]
|
148
|
+
mem_per_scenario_filter = [mem/size for mem, size in zip(filter_memory, sizes)]
|
149
|
+
mem_per_scenario_total = [mem/size for mem, size in zip(total_memory, sizes)]
|
150
|
+
|
151
|
+
plt.plot(sizes, mem_per_scenario_creation, 'o-', label='Creation (per scenario)')
|
152
|
+
plt.plot(sizes, mem_per_scenario_filter, 's-', label='Filter (per scenario)')
|
153
|
+
plt.plot(sizes, mem_per_scenario_total, '^-', label='Total (per scenario)')
|
154
|
+
plt.xlabel('Number of Scenarios')
|
155
|
+
plt.ylabel('Memory Usage per Scenario (MB)')
|
156
|
+
plt.title('Memory Efficiency vs. Dataset Size')
|
157
|
+
plt.grid(True)
|
158
|
+
plt.legend()
|
159
|
+
|
160
|
+
# Set log scale for x-axis to better visualize the trend
|
161
|
+
plt.xscale('log')
|
162
|
+
|
163
|
+
plt.tight_layout()
|
164
|
+
plt.savefig(output_path)
|
165
|
+
print(f"Plot saved to {output_path}")
|
166
|
+
|
167
|
+
def main():
|
168
|
+
"""Run memory tests and plot results."""
|
169
|
+
# Test with increasing dataset sizes
|
170
|
+
sizes = [100, 500, 1000, 2000, 5000, 10000]
|
171
|
+
|
172
|
+
# Each scenario will have a 10KB text field
|
173
|
+
item_size_kb = 10
|
174
|
+
|
175
|
+
# Create output directory if it doesn't exist
|
176
|
+
os.makedirs("benchmark_logs/memory_reports", exist_ok=True)
|
177
|
+
|
178
|
+
# Run tests
|
179
|
+
results = run_memory_test(sizes, item_size_kb)
|
180
|
+
|
181
|
+
# Save results as JSON
|
182
|
+
timestamp = time.strftime("%Y%m%d_%H%M%S")
|
183
|
+
results_path = f"benchmark_logs/memory_reports/memory_test_results_{timestamp}.json"
|
184
|
+
with open(results_path, 'w') as f:
|
185
|
+
json.dump(results, f, indent=2)
|
186
|
+
print(f"\nResults saved to {results_path}")
|
187
|
+
|
188
|
+
# Plot results
|
189
|
+
plot_path = f"benchmark_logs/memory_reports/memory_usage_plot_{timestamp}.png"
|
190
|
+
plot_results(results, plot_path)
|
191
|
+
|
192
|
+
|
193
|
+
def test_scenario_list_memory():
|
194
|
+
"""
|
195
|
+
Simple test function for pytest to run a small memory test.
|
196
|
+
This is a simplified version of the main benchmarking function.
|
197
|
+
"""
|
198
|
+
# Use very small sample size for pytest
|
199
|
+
sizes = [10, 20]
|
200
|
+
item_size_kb = 1
|
201
|
+
|
202
|
+
# Run a minimal test
|
203
|
+
results = run_memory_test(sizes, item_size_kb)
|
204
|
+
|
205
|
+
# Verify we got results
|
206
|
+
assert isinstance(results, dict)
|
207
|
+
assert "creation" in results
|
208
|
+
assert "filter" in results
|
209
|
+
assert "total" in results
|
210
|
+
|
211
|
+
# No need to return anything for pytest
|
212
|
+
|
213
|
+
if __name__ == "__main__":
|
214
|
+
main()
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# ScenarioList Source Refactoring Checklist
|
2
|
+
|
3
|
+
This document outlines the refactoring process to move the `from_X` methods from `ScenarioList` to child classes of `Source`.
|
4
|
+
|
5
|
+
## Refactoring Process
|
6
|
+
|
7
|
+
For each source type, follow these steps:
|
8
|
+
|
9
|
+
1. Create a new child class of `Source` in `scenario_source.py`
|
10
|
+
2. Add a deprecated classmethod in `ScenarioList` that references the new source class
|
11
|
+
3. Run pytest to confirm everything works correctly
|
12
|
+
4. Move to the next source type
|
13
|
+
|
14
|
+
## Source Types Checklist
|
15
|
+
|
16
|
+
- [x] `urls` - Already implemented as `URLSource`
|
17
|
+
- [x] `list` - Already implemented as `ListSource`
|
18
|
+
- [x] `directory` - Implemented as `DirectorySource`
|
19
|
+
- [x] `list_of_tuples` - Implemented as `TuplesSource`
|
20
|
+
- [x] `sqlite` - Implemented as `SQLiteSource`
|
21
|
+
- [x] `latex` - Implemented as `LaTeXSource`
|
22
|
+
- [x] `google_doc` - Implemented as `GoogleDocSource`
|
23
|
+
- [x] `pandas` - Implemented as `PandasSource`
|
24
|
+
- [x] `dta` - Implemented as `StataSource`
|
25
|
+
- [x] `wikipedia` - Implemented as `WikipediaSource`
|
26
|
+
- [x] `excel` - Implemented as `ExcelSource`
|
27
|
+
- [x] `google_sheet` - Implemented as `GoogleSheetSource`
|
28
|
+
- [x] `delimited_file` - Implemented as `DelimitedFileSource`
|
29
|
+
- [x] `csv` - Implemented as `CSVSource` (extending `DelimitedFileSource`)
|
30
|
+
- [x] `tsv` - Implemented as `TSVSource` (extending `DelimitedFileSource`)
|
31
|
+
- [ ] `dict` - Implement as `DictSource`
|
32
|
+
- [ ] `nested_dict` - Implement as `NestedDictSource`
|
33
|
+
- [x] `parquet` - Implemented as `ParquetSource`
|
34
|
+
- [x] `pdf` - Implemented as `PDFSource`
|
35
|
+
- [x] `pdf_to_image` - Implemented as `PDFImageSource`
|
@@ -131,10 +131,11 @@ class ScenarioSelector:
|
|
131
131
|
f"No fields matched the given patterns: {patterns}. "
|
132
132
|
f"Available fields are: {self.available_fields}"
|
133
133
|
)
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
|
135
|
+
new_sl = self.scenario_list.__class__(data=[], codebook=self.scenario_list.codebook)
|
136
|
+
for scenario in self.scenario_list:
|
137
|
+
new_sl.append(scenario.select(fields_to_select))
|
138
|
+
return new_sl
|
138
139
|
|
139
140
|
def get_available_fields(self) -> list[str]:
|
140
141
|
"""
|