> ## Documentation Index
> Fetch the complete documentation index at: https://docs.expectedparrot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Results

> A *Results* object represents the outcome of running a *Survey*. It contains a list of individual *Result* objects, where each *Result* corresponds to a response to the survey for a unique combination of *Agent*, Model, and Scenario objects used with the survey.

For example, if a survey (of one more more questions) is administered to 2 agents and 2 language models (without any scenarios for the questions), the Results will contain 4 Result objects: one for each combination of agent and model used with the survey. If the survey questions are parameterized with 2 scenarios, the Results will expand to include 8 Result objects, accounting for all combinations of agents, models, and scenarios.

## Generating results

A Results object is not typically instantiated directly, but is returned by calling the run() method of a Survey after any agents, language models and scenarios are added to it.

In order to demonstrate how to access and interact with results, we use the following code to generate results for a simple survey. Note that specifying agent traits, scenarios (question parameter values) and language models is optional, and we include those steps here for illustration purposes. See the [Agents](/en/latest/agents), [Scenarios](/en/latest/scenarios) and models sections for more details on these components.

<Note>
  **Note:**

  You must store API keys for language models in order to generate results. Please see the [Managing Keys](/en/latest/api_keys) section for instructions on activating [Remote Inference](/en/latest/remote_inference) or storing your own API keys for inference service providers.
</Note>

To construct a survey we start by creating questions:

```python theme={null}
from edsl import QuestionLinearScale, QuestionMultipleChoice

q1 = QuestionLinearScale(
  question_name = "important",
  question_text = "On a scale from 1 to 5, how important to you is `{{ scenario.topic }}`?",
  question_options = [0, 1, 2, 3, 4, 5],
  option_labels = {0:"Not at all important", 5:"Very important"}
)

q2 = QuestionMultipleChoice(
  question_name = "read",
  question_text = "Have you read any books about `{{ scenario.topic }}`?",
  question_options = ["Yes", "No", "I do not know"]
)
```

We combine them in a survey to administer them together:

```python theme={null}
from edsl import Survey

survey = Survey([q1, q2])
```

We have parameterized our questions, so we can use them with different scenarios:

```python theme={null}
from edsl import ScenarioList

scenarios = ScenarioList.from_list("topic", ["climate change", "house prices"])
```

We can optionally create agents with personas or other relevant traits to answer the survey:

```python theme={null}
from edsl import AgentList, Agent

agents = AgentList(
  Agent(traits = {"persona": p}) for p in ["student", "celebrity"]
)
```

We can specify the language models that we want to use to generate responses:

```python theme={null}
from edsl import ModelList, Model

models = ModelList(
  Model(m) for m in ["gemini-1.5-flash", "gpt-4o"]
)
```

Finally, we generate results by adding the scenarios, agents and models to the survey and calling the run() method:

```python theme={null}
results = survey.by(scenarios).by(agents).by(models).run()
```

For more details on each of the above steps, please see the [Agents](/en/latest/agents#agents), [Scenarios](/en/latest/scenarios#scenarios) and models sections of the docs.

## Result objects

We can check the number of Result objects created by inspecting the length of the Results:

```python theme={null}
len(results)
```

This will count 2 (scenarios) x 2 (agents) x 2 (models) = 8 Result objects:

```
8
```

## Generating multiple results

If we want to generate multiple results for a survey–i.e., more than 1 result for each combination of Agent, Model and Scenario objects used–we can pass the desired number of iterations when calling the run() method. For example, the following code will generate 3 results for our survey (n=3):

```python theme={null}
results = survey.by(scenarios).by(agents).by(models).run(n=3)
```

We can verify that the number of Result objects created is now 24 = 3 iterations x 2 scenarios x 2 agents x 2 models:

```
len(results)
```

```
24
```

We can readily inspect a result:

```python theme={null}
results[0]
```

Output:

## Results components

Results contain components that can be accessed and analyzed individually or collectively. We can see a list of these components by calling the columns method:

```python theme={null}
results.columns
```

### Visualizing column structure

For complex Results with many nested columns, you can use the `show_columns()` method to generate a tree visualization showing the hierarchical structure of your columns:

```python theme={null}
results.show_columns()
```

This creates a mermaid diagram that displays the column hierarchy, making it easier to understand the structure of your Results and identify which columns are available for selection.

The following list will be returned for the results generated by the above code:

| agent.agent\_index | agent.agent\_instruction | agent.agent\_name | agent.persona | answer.important | answer.read | cache\_keys.important\_cache\_key | cache\_keys.read\_cache\_key | cache\_keys.important\_cache\_used | cache\_keys.read\_cache\_used | comment.important\_comment | comment.read\_comment | generated\_tokens.important\_generated\_tokens | generated\_tokens.read\_generated\_tokens | iteration.iteration | model.frequency\_penalty | model.logprobs | model.maxOutputTokens | model.max\_tokens | model.model | model.presence\_penalty | model.stopSequences | model.temperature | model.topK | model.topP | model.top\_logprobs | model.top\_p | prompt.important\_system\_prompt | prompt.important\_user\_prompt | prompt.read\_system\_prompt | prompt.read\_user\_prompt | question\_options.important\_question\_options | question\_options.read\_question\_options | question\_text.important\_question\_text | question\_text.read\_question\_text | question\_type.important\_question\_type | question\_type.read\_question\_type | raw\_model\_response.important\_cost | raw\_model\_response.important\_input\_price\_per\_million\_tokens | raw\_model\_response.important\_input\_tokens | raw\_model\_response.important\_one\_usd\_buys | raw\_model\_response.important\_output\_price\_per\_million\_tokens | raw\_model\_response.important\_output\_tokens | raw\_model\_response.important\_raw\_model\_response | raw\_model\_response.read\_cost | raw\_model\_response.read\_input\_price\_per\_million\_tokens | raw\_model\_response.read\_input\_tokens | raw\_model\_response.read\_one\_usd\_buys | raw\_model\_response.read\_output\_price\_per\_million\_tokens | raw\_model\_response.read\_output\_tokens | raw\_model\_response.read\_raw\_model\_response | scenario.scenario\_index | scenario.topic |
| ------------------ | ------------------------ | ----------------- | ------------- | ---------------- | ----------- | --------------------------------- | ---------------------------- | ---------------------------------- | ----------------------------- | -------------------------- | --------------------- | ---------------------------------------------- | ----------------------------------------- | ------------------- | ------------------------ | -------------- | --------------------- | ----------------- | ----------- | ----------------------- | ------------------- | ----------------- | ---------- | ---------- | ------------------- | ------------ | -------------------------------- | ------------------------------ | --------------------------- | ------------------------- | ---------------------------------------------- | ----------------------------------------- | ---------------------------------------- | ----------------------------------- | ---------------------------------------- | ----------------------------------- | ------------------------------------ | ------------------------------------------------------------------ | --------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------- | ------------------------------- | ------------------------------------------------------------- | ---------------------------------------- | ----------------------------------------- | -------------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------- | ------------------------ | -------------- |

The columns include information about each *agent*, *model* and corresponding *prompts* used to simulate the *answer* to each *question* and *scenario* in the survey, together with each *raw model response*. If the survey was run multiple times (run(n=\<integer>)) then the iteration.iteration column will show the iteration number for each result.

*Agent* information:

* **agent.agent\_index**: The index of the agent in the AgentList used to create the survey.
* **agent.instruction**: The instruction for the agent. This field is the optional instruction that was passed to the agent when it was created.
* **agent.agent\_name**: This field is always included in any Results object. It contains a unique identifier for each Agent that can be specified when an agent is is created (Agent(name=\<name>, traits=\{\<traits\_dict>})). If not specified, it is added automatically when results are generated (in the form Agent\_0, etc.).
* **agent.persona**: Each of the traits that we pass to an agent is represented in a column of the results. Our example code created a “persona” trait for each agent, so our results include a “persona” column for this information. Note that the keys for the traits dictionary should be a valid Python keys.

*Answer* information:

* **answer.important**: Agent responses to the linear scale important question.
* **answer.read**: Agent responses to the multiple choice read question.

*Cache* information:

* **cache\_keys.important\_cache\_key**: The cache key for the important question.
* **cache\_keys.important\_cache\_used**: Whether the existing cache was used for the important question.
* **cache\_keys.read\_cache\_key**: The cache key for the read question.
* **cache\_keys.read\_cache\_used**: Whether the existing cache was used for the read question.

*Comment* information:

A “comment” field is automatically included for every question in a survey other than free text questions, to allow the model to provide additional information about its response. The default instruction for the agent to provide a comment is included in user\_prompt for a question, and can be modified or omitted when creating the question. (See the [Prompts](/en/latest/prompts#prompts) section for details on modifying user and system prompts, and information about prompts in results below. Comments can also be automatically excluded by passing a parameter include\_comment=False a question when creating it.)

* **comment.important\_comment**: Agent commentary on responses to the important question.
* **comment.read\_comment**: Agent commentary on responses to the read question.

*Generated tokens* information:

* **generated\_tokens.important\_generated\_tokens**: The generated tokens for the important question.
* **generated\_tokens.read\_generated\_tokens**: The generated tokens for the read question.

*Iteration* information:

The iteration column shows the number of the run (run(n=\<integer>)) for the combination of components used (scenarios, agents and models).

*Model* information:

Each of model columns is a modifiable parameter of the models used to generate the responses.

* **model.frequency\_penalty**: The frequency penalty for the model.
* **model.logprobs**: The logprobs for the model.
* **model.maxOutputTokens**: The maximum number of output tokens for the model.
* **model.max\_tokens**: The maximum number of tokens for the model.
* **model.model**: The name of the model used.
* **model.presence\_penalty**: The presence penalty for the model.
* **model.stopSequences**: The stop sequences for the model.
* **model.temperature**: The temperature for the model.
* **model.topK**: The top k for the model.
* **model.topP**: The top p for the model.
* **model.top\_logprobs**: The top logprobs for the model.
* **model.top\_p**: The top p for the model.
* **model.use\_cache**: Whether the model uses cache.

<Note>
  **Note:** Some of the above fields are particular to specific models, and may have different names (e.g., top\_p vs. topP).
</Note>

*Prompt* information:

* **prompt.important\_system\_prompt**: The system prompt for the important question.
* **prompt.important\_user\_prompt**: The user prompt for the important question.
* **prompt.read\_system\_prompt**: The system prompt for the read question.
* **prompt.read\_user\_prompt**: The user prompt for the read question.

For more details about prompts, please see the [Prompts](/en/latest/prompts#prompts) section.

*Question* information:

* **question\_options.important\_question\_options**: The options for the important question, if any.
* **question\_options.read\_question\_options**: The options for the read question, if any.
* **question\_text.important\_question\_text**: The text of the important question.
* **question\_text.read\_question\_text**: The text of the read question.
* **question\_type.important\_question\_type**: The type of the important question.
* **question\_type.read\_question\_type**: The type of the read question.

*Raw model response* information:

* **raw\_model\_response.important\_cost**: The cost of the result for the important question, applying the token quanities & prices.
* **raw\_model\_response.important\_input\_price\_per\_million\_tokenss**: The price per million input tokens for the important question for the relevant model.
* **raw\_model\_response.important\_input\_tokens**: The number of input tokens for the important question for the relevant model.
* **raw\_model\_response.important\_one\_usd\_buys**: The number of identical results for the important question that 1USD would cover.
* **raw\_model\_response.important\_output\_price\_per\_million\_tokens**: The price per million output tokens for the important question for the relevant model.
* **raw\_model\_response.important\_output\_tokens**: The number of output tokens for the important question for the relevant model.
* **raw\_model\_response.important\_raw\_model\_response**: The raw model response for the important question.
* **raw\_model\_response.read\_cost**: The cost of the result for the read question, applying the token quanities & prices.
* **raw\_model\_response.read\_input\_price\_per\_million\_tokens**: The price per million input tokens for the read question for the relevant model.
* **raw\_model\_response.read\_input\_tokens**: The number of input tokens for the read question for the relevant model.
* **raw\_model\_response.read\_one\_usd\_buys**: The number of identical results for the read question that 1USD would cover.
* **raw\_model\_response.read\_output\_price\_per\_million\_tokens**: The price per million output tokens for the read question for the relevant model.
* **raw\_model\_response.read\_output\_tokens**: The number of output tokens for the read question for the relevant model.
* **raw\_model\_response.read\_raw\_model\_response**: The raw model response for the read question.

<Note>
  **Note:**

  Note that the cost of a result for a question is specific to the components (scenario, agent, model used with it).
</Note>

*Scenario* information:

* **scenario.scenario\_index**: The index of the scenario.
* **scenario.topic**: The values provided for the “topic” scenario for the questions.

<Note>
  **Note:**

  We recently added support for OpenAI reasoning models. See an example notebook for usage [here](https://www.expectedparrot.com/content/RobinHorton/reasoning-model-example). The Results that are generated with reasoning models include additional fields for reasoning summaries.
</Note>

## Creating tables by selecting columns

Each of these columns can be accessed directly by calling the select() method and passing the column names. Alternatively, we can specify the columns to exclude by calling the drop() method. These methods can be chained together to display the specified columns in a table format.

### Wildcard pattern support

The select() method supports wildcard patterns using `*` to match multiple columns at once. This is particularly useful when you want to select all columns of a certain type or with a common prefix:

```python theme={null}
# Select all answer columns
results.select("answer.*")

# Select all cost-related columns
results.select("*_cost")

# Select all columns from raw_model_response
results.select("raw_model_response.*")
```

For example, the following code will print a table showing the answers for read and important together with model, persona and topic columns (because the column names are unique we can drop the model, agent, scenario and answer prefixes when selecting them):

```python theme={null}
results = survey.by(scenarios).by(agents).by(models).run() # Running the survey once
results.select("model", "persona", "topic", "read", "important")
```

A table with the selected columns will be printed:

| model.model      | agent.persona | scenario.topic | answer.read | answer.important |
| :--------------- | :------------ | :------------- | :---------- | :--------------- |
| gemini-1.5-flash | student       | climate change | Yes         | 5                |
| gpt-4o           | student       | climate change | Yes         | 5                |
| gemini-1.5-flash | student       | house prices   | No          | 1                |
| gpt-4o           | student       | house prices   | No          | 3                |
| gemini-1.5-flash | celebrity     | climate change | Yes         | 5                |
| gpt-4o           | celebrity     | climate change | Yes         | 5                |
| gemini-1.5-flash | celebrity     | house prices   | Yes         | 3                |
| gpt-4o           | celebrity     | house prices   | No          | 3                |

## Sorting results

We can sort the columns by calling the sort\_by method and passing it the column names to sort by:

```python theme={null}
  results
  .sort_by("model", "persona", reverse=False)
  .select("model", "persona", "topic", "read", "important")
)
```

The following table will be printed:

| model.model      | agent.persona | scenario.topic | answer.read | answer.important |
| :--------------- | :------------ | :------------- | :---------- | :--------------- |
| gemini-1.5-flash | celebrity     | climate change | Yes         | 5                |
| gemini-1.5-flash | celebrity     | house prices   | Yes         | 3                |
| gemini-1.5-flash | student       | climate change | Yes         | 5                |
| gemini-1.5-flash | student       | house prices   | No          | 1                |
| gpt-4o           | celebrity     | climate change | Yes         | 5                |
| gpt-4o           | celebrity     | house prices   | No          | 3                |
| gpt-4o           | student       | climate change | Yes         | 5                |
| gpt-4o           | student       | house prices   | No          | 3                |

## Labeling results

We can also add some table labels by passing a dictionary to the pretty\_labels argument of the print method (note that we need to include the column prefixes when specifying the table labels, as shown below):

```python theme={null}
  results
  .sort_by("model", "persona", reverse=True)
  .select("model", "persona", "topic", "read", "important")
  .print(pretty_labels={
      "model.model": "LLM",
      "agent.persona": "Agent",
      "scenario.topic": "Topic",
      "answer.read": q2.question_text,
      "answer.important": q1.question_text
      }, format="rich")
)
```

The following table will be printed:

| LLM              | Agent     | Topic          | Have you read any books about `{{ scenario.topic }}`? | On a scale from 1 to 5, how important to you is `{{ scenario.topic }}`? |
| :--------------- | :-------- | :------------- | :---------------------------------------------------- | :---------------------------------------------------------------------- |
| gpt-4o           | student   | climate change | Yes                                                   | 5                                                                       |
| gpt-4o           | student   | house prices   | No                                                    | 3                                                                       |
| gpt-4o           | celebrity | climate change | Yes                                                   | 5                                                                       |
| gpt-4o           | celebrity | house prices   | No                                                    | 3                                                                       |
| gemini-1.5-flash | student   | climate change | Yes                                                   | 5                                                                       |
| gemini-1.5-flash | student   | house prices   | No                                                    | 1                                                                       |
| gemini-1.5-flash | celebrity | climate change | Yes                                                   | 5                                                                       |
| gemini-1.5-flash | celebrity | house prices   | Yes                                                   | 3                                                                       |

## Filtering results

Results can be filtered by using the filter method and passing it a logical expression identifying the results that should be selected. For example, the following code will filter results where the answer to important is “5” and then just print the topic and important\_comment columns:

```python theme={null}
  results
  .filter("important == 5")
  .select("topic", "important", "important_comment")
)
```

This will return an abbreviated table:

| scenario.topic | answer.important | comment.important\_comment                                                                                                                                                                                                                                                          |
| :------------- | :--------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| climate change | 5                | It’s, like, a huge deal. The future of the planet is at stake, and that affects everything - from the environment to the economy to social justice. It’s something I worry about a lot.                                                                                             |
| climate change | 5                | As a student, I’m really concerned about climate change because it affects our future and the planet we’ll inherit. It’s crucial to understand and address it to ensure a sustainable world for generations to come.                                                                |
| climate change | 5                | It’s a huge issue, you know? We only have one planet, and if we don’t take care of it, what kind of world are we leaving for future generations? It’s not just about polar bears; it’s about everything. It’s my responsibility, as someone with a platform, to speak out about it. |
| climate change | 5                | Climate change is a critical issue that affects everyone globally, and as a public figure, I believe it’s important to use my platform to raise awareness and advocate for sustainable practices.                                                                                   |

**Note:** The filter method allows us to pass the unique short names of the columns (without the prefixes) when specifying the logical expression. However, because the model.model column name is also a prefix, we need to include the prefix when filtering by this column, as shown in the example below:

```python theme={null}
  results
  .filter("model.model == 'gpt-4o'")
  .select("model", "persona", "topic", "read", "important")
)
```

This will return a table of results where the model is “gpt-4o”:

| model.model | agent.persona | scenario.topic | answer.read | answer.important |
| :---------- | :------------ | :------------- | :---------- | :--------------- |
| gpt-4o      | student       | climate change | Yes         | 5                |
| gpt-4o      | student       | house prices   | No          | 3                |
| gpt-4o      | celebrity     | climate change | Yes         | 5                |
| gpt-4o      | celebrity     | house prices   | No          | 3                |

## Limiting results

We can select and print a limited number of results by passing the desired number of max\_rows to the print() method. This can be useful for quickly checking the first few results:

```python theme={null}
  results
  .select("model", "persona", "topic", "read", "important")
  .print(max_rows=4, format="rich")
)
```

This will return a table of the selected components of the first 4 results:

| model.model      | agent.persona | scenario.topic | answer.read | answer.important |
| :--------------- | :------------ | :------------- | :---------- | :--------------- |
| gemini-1.5-flash | student       | climate change | Yes         | 5                |
| gpt-4o           | student       | climate change | Yes         | 5                |
| gemini-1.5-flash | student       | house prices   | No          | 1                |
| gpt-4o           | student       | house prices   | No          | 3                |

## Sampling results

We can select a sample of n results by passing the desired number of random results to the sample() method. This can be useful for checking a random subset of the results with different parameters:

```python theme={null}
sample_results = results.sample(2)

(
  sample_results
  .sort_by("model")
  .select("model", "persona", "topic", "read", "important")
)
```

This will return a table of the specified number of randomly selected results:

| model.model | agent.persona | scenario.topic | answer.read | answer.important |
| :---------- | :------------ | :------------- | :---------- | :--------------- |
| gpt-4o      | celebrity     | house prices   | No          | 3                |
| gpt-4o      | celebrity     | climate change | Yes         | 5                |

## Shuffling results

We can shuffle results by calling the shuffle() method. This can be useful for quickly checking the first few results:

```python theme={null}
shuffle_results = results.shuffle()

(
  shuffle_results
  .select("model", "persona", "topic", "read", "important")
)
```

This will return a table of shuffled results:

| model.model      | agent.persona | scenario.topic | answer.read | answer.important |
| :--------------- | :------------ | :------------- | :---------- | :--------------- |
| gemini-1.5-flash | celebrity     | climate change | Yes         | 5                |
| gpt-4o           | student       | house prices   | No          | 3                |
| gemini-1.5-flash | celebrity     | house prices   | Yes         | 3                |
| gemini-1.5-flash | student       | house prices   | No          | 1                |
| gpt-4o           | celebrity     | house prices   | No          | 3                |
| gpt-4o           | celebrity     | climate change | Yes         | 5                |
| gpt-4o           | student       | climate change | Yes         | 5                |
| gemini-1.5-flash | student       | climate change | Yes         | 5                |

## Adding results

We can add results together straightforwardly by using the + operator:

```python theme={null}
add_results = results + results
```

We can see that the results have doubled:

```python theme={null}
len(add_results)
```

This will return the number of results:

```
16
```

## Flattening results

If a field of results contains dictionaries we can flatten them into separate fields by calling the flatten() method. This method takes a list of the fields to flatten and a boolean indicator whether to preserve the original fields in the new Results object that is returned.

For example:

```python theme={null}
from edsl import QuestionDict, Model

 m = Model("gemini-1.5-flash")

 q = QuestionDict(
   question_name = "recipe",
   question_text = "Please provide a simple recipe for hot chocolate.",
   answer_keys = ["title", "ingredients", "instructions"]
 )

 r = q.by(m).run()

 r.select("model", "recipe").flatten(field="answer.recipe", keep_original=True)
```

This will return a table of the flattened results:

| model.model      | answer.recipe                                                                                                                                                                                                                                                                                                                                                                                                                | answer.recipe.title  | answer.recipe.ingredients                                                                                                             | answer.recipe.instructions                                                                                                                                                                                         |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| gemini-1.5-flash | \{‘title’: ‘Simple Hot Chocolate’, ‘ingredients’: \[‘1 cup milk (dairy or non-dairy)’, ‘1 tablespoon unsweetened cocoa powder’, ‘1-2 tablespoons sugar (or to taste)’, ‘Pinch of salt’], ‘instructions’: \[‘Combine milk, cocoa powder, sugar, and salt in a small saucepan.’, ‘Heat over medium heat, stirring constantly, until the mixture is smooth and heated through.’, ‘Do not boil.’, ‘Pour into a mug and enjoy!’]} | Simple Hot Chocolate | \[‘1 cup milk (dairy or non-dairy)’, ‘1 tablespoon unsweetened cocoa powder’, ‘1-2 tablespoons sugar (or to taste)’, ‘Pinch of salt’] | \[‘Combine milk, cocoa powder, sugar, and salt in a small saucepan.’, ‘Heat over medium heat, stirring constantly, until the mixture is smooth and heated through.’, ‘Do not boil.’, ‘Pour into a mug and enjoy!’] |

## Retrieving results

We can retrieve details about results posted to Expected Parrot by calling the list() method on the Results class. For example, the following code will return information about the 10 most recent results posted to the platform:

```python theme={null}
from edsl import Results

results = Results.list()
```

The following information will be returned:

| Column            | Description                                                  |
| :---------------- | :----------------------------------------------------------- |
| last\_updated\_ts | The timestamp when the result was last updated.              |
| alias             | The alias for the results.                                   |
| uuid              | The UUID of the results.                                     |
| version           | The version of the result.                                   |
| created\_ts       | The timestamp when the results were created.                 |
| visibility        | The visibility of the results (public, private or unlisted). |
| description       | A description of the results, if any.                        |
| url               | The URL to access the results.                               |
| object\_type      | The type of object (e.g., Results).                          |
| owner\_username   | The username of the owner of the results.                    |
| alias\_url        | The URL for the alias, if any.                               |

To access the next page of results, you can specify the page= parameter:

```python theme={null}
results = Results.list(page=2)
```

This will return the next page of results, with the same columns as above.

```python theme={null}
from edsl import Results

# Retrieve the first 2 pages of results and collect their UUIDs
uuids = []
for i in range(1, 3):
  results = Results.list(page=i)
  uuids.extend(list(results.to_key_value("uuid")))
```

If you have a predetermined number of objects, you can also use page\_size= to specify the number of objects per page (up to 100 objects):

```python theme={null}
results = Results.list(page_size=5)
```

This will return the first 5 results, with the same columns as above.

By default, the most recently created objects are returned first. You can reverse this by specifying sort\_ascending=True:

```python theme={null}
from edsl import Results

# Retrieve the first 10 results, sorted in ascending order by creation time
results = Results.list(sort_ascending=True)
```

You can also filter objects by description using the search\_query parameter:

```python theme={null}
from edsl import Results

# Retrieve results with a description containing the word "testing"
results = Results.list(search_query="testing")
```

If you want not just the metadata, but the actual object, you can call .fetch() on the metadata list:

```python theme={null}
from edsl import Results

# Retrieve the first 10 results and fetch the actual objects
results = Results.list().fetch()
```

The list() method can also be called on Agent and Jobs objects, and the `Coop` client object (to retrieve details of objects of any type).

## Generating a report

We can create a report of the results by calling the report() method and passing the columns to be included (all columns are included by default). This generates a report in markdown by iterating through the rows, presented as observations. You can optionally pass headers, a divider and a limit on the number of observations to include. It can be useful if you want to display some sample part of larger results in a working notebook you are sharing.

For example, the following code will generate a report of the first 4 results:

```python theme={null}
from edsl import QuestionFreeText, ScenarioList, Model

m = Model("gemini-1.5-flash")

s = ScenarioList.from_list("language", ["German", "Dutch", "French", "English"])

q = QuestionFreeText(
  question_name = "poem",
  question_text = "Please write me a short poem about winter in `{{ language }}`."
)

r = q.by(s).by(m).run()

r.select("model", "poem", "language").report(top_n=2, divider=False, return_string=True)
```

This will return a report of the first 2 results:

```python theme={null}
Observation: 1

model.model
gemini-1.5-flash

answer.poem
Der Schnee fällt leis', ein weicher Flor, Die Welt in Weiß, ein Zauberchor. Die Bäume stehn, in Stille gehüllt, Der Winterwind, sein Lied erfüllt.

(Translation: The snow falls softly, a gentle veil, / The world in white, a magic choir. / The trees stand, wrapped in silence, / The winter wind, its song fulfilled.)

scenario.language
German

Observation: 2
model.model
gemini-1.5-flash

answer.poem
De winter komt, de dagen kort, De sneeuw valt zacht, een wit decor. De bomen staan, kaal en stil, Een ijzige wind, een koude tril.

(Translation: Winter comes, the days are short, / The snow falls softly, a white décor. / The trees stand, bare and still, / An icy wind, a cold shiver.)

scenario.language
Dutch

"# Observation: 1n## model.modelngemini-1.5-flashn## answer.poemnDer Schnee fällt leis', ein weicher Flor,nDie Welt in Weiß, ein Zauberchor.nDie Bäume stehn, in Stille gehüllt,nDer Winterwind, sein Lied erfüllt.nn(Translation: The snow falls softly, a gentle veil, / The world in white, a magic choir. / The trees stand, wrapped in silence, / The winter wind, its song fulfilled.)n## scenario.languagenGermannn---nn# Observation: 2n## model.modelngemini-1.5-flashn## answer.poemnDe winter komt, de dagen kort,nDe sneeuw valt zacht, een wit decor.nDe bomen staan, kaal en stil,nEen ijzige wind, een koude tril.nn(Translation: Winter comes, the days are short, / The snow falls softly, a white décor. / The trees stand, bare and still, / An icy wind, a cold shiver.)n## scenario.languagenDutchn"
```

## Accessing results with SQL

We can interact with results via SQL using the sql method. This is done by passing a SQL query and a shape (“long” or “wide”) for the resulting table, where the table name in the query is “self”.

For example, the following code will return a table showing the model, persona, read and important columns for the first 4 results:

```python theme={null}
results.sql("select model, persona, read, important from self limit 4")
```

This following table will be displayed

| model            | persona | read | important |
| :--------------- | :------ | :--- | :-------- |
| gemini-1.5-flash | student | Yes  | 5         |
| gpt-4o           | student | Yes  | 5         |
| gemini-1.5-flash | student | No   | 1         |
| gpt-4o           | student | No   | 3         |

## Dataframes

We can also export results to other formats. The to\_pandas method will turn our results into a Pandas dataframe:

```python theme={null}
results.to_pandas()
```

For example, here we use it to create a dataframe consisting of the models, personas and the answers to the important question:

```python theme={null}
results.to_pandas()[["model.model", "agent.persona", "answer.important"]]
```

## Exporting to CSV or JSON

The to\_csv method will write the results to a CSV file:

```python theme={null}
results.to_pandas().to_csv("results.csv")
```

The to\_json method will write the results to a JSON file:

```python theme={null}
results.to_pandas().to_json("results.json")
```

## Revising prompts to improve results

If any of your results are missing model responses, you can use the spot\_issues() method to help identify the issues and then revise the prompts to improve the results. This method runs a meta-survey of (2) questions for any prompts that generated a bad or null response, and then returns the results of the meta-survey.

The first question in the survey is a QuestionFreeText question which prompts the model to describe the likely issues with the prompts:

```python theme={null}
The following prompts generated a bad or null response: '`{{ original_prompts }}`'
What do you think was the likely issue(s)?
```

The second question in the survey is a QuestionDict question which prompts the model to return a dictionary consisting of revised user and system prompts:

```python theme={null}
The following prompts generated a bad or null response: '`{{ original_prompts }}`'
You identified the issue(s) as '`{{ issues.answer }}`'.
Please revise the prompts to address the issue(s).
```

You can optionally pass a list of models to use with the meta-survey, instead of the default model.

Example usage:

```python theme={null}
# Returns a Results object with the results of the meta-survey
results.spot_issues(models=["gpt-4o"])

# You can inspect the metadata for your original prompts together with the results of the meta-survey
results.select(
  "original_question", # The name of the question that generated a bad or null response
  "original_agent_index", # The index of the agent that generated a bad or null response
  "original_scenario_index", # The index of the scenario that generated a bad or null response
  "original_prompts", # The original prompts that generated a bad or null response
  "answer.issues", # Free text description of potential issues in the original prompts
  "answer.revised" # A dictionary of revised user and system prompts
)
```

See an [example of the method](https://www.expectedparrot.com/content/385734e7-7767-4464-9ebd-0b009dd2e15f).

## Exceptions

If any exceptions are raised when the survey is run a detailed exceptions report is generated and can be opened in your browser. See the [Exceptions & Debugging](/en/latest/exceptions#exceptions) section for more information on exceptions.

## Result class

> ### *class* edsl.results.Result(*agent: [Agent](/en/latest/agents#result-class)*, *scenario: [Scenario](/en/latest/scenarios#scenario-class "edsl.scenarios.Scenario")*, *model: [LanguageModel](/en/latest/language_models#languagemodel-class "edsl.language_models.LanguageModel")*, *iteration: int*, *answer: dict\[QuestionName, AnswerValue]*, *prompt: dict\[QuestionName, str] = None*, *raw\_model\_response: dict | None = None*, *survey: 'Survey' | None = None*, *question\_to\_attributes: dict\[QuestionName, Any] | None = None*, *generated\_tokens: dict | None = None*, *comments\_dict: dict | None = None*, *reasoning\_summaries\_dict: dict | None = None*, *cache\_used\_dict: dict\[QuestionName, bool] | None = None*, *indices: dict | None = None*, *cache\_keys: dict\[QuestionName, str] | None = None*, *validated\_dict: dict\[QuestionName, bool] | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Bases: [`Base`](/en/latest/base#base-class "edsl.base.base_class.Base"), `UserDict`

The Result class captures the complete data from one agent interview.

A Result object stores the agent, scenario, language model, and all answers provided during an interview, along with metadata such as token usage, caching information, and raw model responses. It provides a rich interface for accessing this data and supports serialization for storage and retrieval.

The Result class inherits from both Base (for serialization) and UserDict (for dictionary-like behavior), allowing it to be accessed like a dictionary while maintaining a rich object model.

> ### **Attributes:**

agent: The Agent object that was interviewed. scenario: The Scenario object that was presented to the agent. model: The LanguageModel object that was used to generate responses. answer: Dictionary mapping question names to answer values. sub\_dicts: Organized sub-dictionaries for different data types. combined\_dict: Flattened dictionary combining all sub-dictionaries. problem\_keys: List of keys that have naming conflicts.

> ### **Note:**

Results are typically created by the Jobs system when running interviews and collected into a Results collection for analysis. You rarely need to create Result objects manually.

> ### **Examples:**

```python theme={null}
>>> result = Result.example()
>>> result['answer']['how_feeling']
'OK'
```

> #### *class* ClassOrInstanceMethod(*func*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Bases: `object`

Descriptor that allows a method to be called as both a class method and an instance method.

> #### **init**(*func*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### **init**(*agent: [Agent](/en/latest/agents#result-class)*, *scenario: [Scenario](/en/latest/scenarios#scenario-class "edsl.scenarios.Scenario")*, *model: [LanguageModel](/en/latest/language_models#languagemodel-class "edsl.language_models.LanguageModel")*, *iteration: int*, *answer: dict\[QuestionName, AnswerValue]*, *prompt: dict\[QuestionName, str] = None*, *raw\_model\_response: dict | None = None*, *survey: 'Survey' | None = None*, *question\_to\_attributes: dict\[QuestionName, Any] | None = None*, *generated\_tokens: dict | None = None*, *comments\_dict: dict | None = None*, *reasoning\_summaries\_dict: dict | None = None*, *cache\_used\_dict: dict\[QuestionName, bool] | None = None*, *indices: dict | None = None*, *cache\_keys: dict\[QuestionName, str] | None = None*, *validated\_dict: dict\[QuestionName, bool] | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Initialize a Result object.

> **Args:**

agent: The Agent object that was interviewed. scenario: The Scenario object that was presented. model: The LanguageModel object that generated responses. iteration: The iteration number for this result. answer: Dictionary mapping question names to answer values. prompt: Dictionary of prompts used for each question. Defaults to None. raw\_model\_response: The raw response from the language model. Defaults to None. survey: The Survey object containing the questions. Defaults to None. question\_to\_attributes: Dictionary of question attributes. Defaults to None. generated\_tokens: Dictionary of token usage statistics. Defaults to None. comments\_dict: Dictionary of comments for each question. Defaults to None. reasoning\_summaries\_dict: Dictionary of reasoning summaries. Defaults to None. cache\_used\_dict: Dictionary indicating cache usage for each question. Defaults to None. indices: Dictionary of indices for data organization. Defaults to None. cache\_keys: Dictionary of cache keys for each question. Defaults to None. validated\_dict: Dictionary indicating validation status for each question. Defaults to None.

> #### *property* agent\*: [Agent](/en/latest/agents#result-class)\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the Agent object.

> #### *property* answer\*: dict\[str, Any]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the answers.

> #### apply\_command(*command\_name*, *kwargs*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### by\_question\_data(*flatten\_nested\_dicts: bool = False*, *separator: str = '\_'*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Organize result data by question with optional flattening of nested dictionaries.

This method reorganizes the result data structure to be organized by question name, making it easier to analyze answers and related metadata on a per-question basis.

**Args:**

flatten\_nested\_dicts: Whether to flatten nested dictionaries using the separator.

Defaults to False.

separator: The separator to use when flattening nested dictionaries.

Defaults to “\_”.

**Returns:**

A dictionary organized by question name, with each question containing its associated data (answer, prompt, metadata, etc.).

> #### check\_expression(*expression: str*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Check if an expression references a problematic key.

**Args:**

expression: The expression string to check for problematic keys.

**Raises:**

ResultsColumnNotFoundError: If the expression contains a problematic key

that should use the full qualified name instead.

> #### clear() → None.  Remove all items from D.[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### clipboard()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Copy this object’s representation to the system clipboard.

This method first checks if the object has a custom clipboard\_data() method. If it does, it uses that method’s output. Otherwise, it serializes the object to a dictionary (without version info) and copies it to the system clipboard as JSON text.

**Returns:**

None, but prints a confirmation message

> #### code()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a string of code that can be used to recreate the Result object.

**Raises:**

ResultsError: This method is not implemented for Result objects.

> #### *property* combined\_dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> ### copy() → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a copy of the Result object.

> #### **Returns:**

A new Result object that is a copy of this one.

> #### **Examples:**

```python theme={null}
>>> r = Result.example()
>>> r2 = r.copy()
>>> r == r2
True
>>> id(r) == id(r2)
False
```

> #### create\_download\_link()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Generate a downloadable link for this object.

Creates a temporary file containing the serialized object and generates a download link that can be shared with others.

**Returns:**

str: A URL that can be used to download the object

> #### *classmethod* delete(*url\_or\_uuid: str | UUID*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Delete the object from coop.

> #### display\_dict()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create a flattened dictionary representation for display purposes.

This method creates a flattened view of nested structures using colon notation in keys to represent hierarchy.

**Returns:**

dict: A flattened dictionary suitable for display

> #### display\_transcript(*show\_options: bool = True*, *show\_agent\_info: bool = True*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display a rich-formatted chat transcript of the interview.

This method creates a ChatTranscript object and displays the conversation between questions and agent responses in a beautiful, chat-like format using the Rich library.

**Args:**

show\_options: Whether to display question options if available. Defaults to True. show\_agent\_info: Whether to show agent information at the top. Defaults to True.

> #### duplicate(*add\_edsl\_version=False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create and return a deep copy of the object.

**Args:**

add\_edsl\_version: Whether to include EDSL version information in the duplicated object

**Returns:**

A new instance of the same class with identical properties

> #### *classmethod* example() → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return an example Result object.

**Returns:**

A sample Result object for testing and demonstration purposes.

> ### **Examples:**

```python theme={null}
>>> result = Result.example()
>>> type(result)
<class 'edsl.results.result.Result'>
>>> isinstance(result, Result)
True
```

> #### *classmethod* from\_dict(*data: dict*) → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a Result object from a dictionary representation.

**Args:**

json\_dict: Dictionary containing Result data.

**Returns:**

A new Result object created from the dictionary data.

> #### *classmethod* from\_interview(*interview*) → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a Result object from an interview dictionary.

This method ensures no reference to the original interview is maintained, creating a clean Result object from the interview data.

**Args:**

interview: An interview dictionary containing the raw interview data.

**Returns:**

A new Result object created from the interview data.

> #### *classmethod* from\_yaml(*yaml\_str: str | None = None*, *filename: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create an instance from YAML data.

Deserializes a YAML string or file into a new instance of the class.

**Args:**

yaml\_str: YAML string containing object data filename: Path to a YAML file containing object data

**Returns:**

A new instance of the class populated with the deserialized data

**Raises:**

BaseValueError: If neither yaml\_str nor filename is provided

> #### *classmethod* fromkeys(*iterable*, *value=None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### get(*k*\[, *d*]) → D\[k] if k in D, else d.  d defaults to None.[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### get\_description() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the description of this object.

> #### get\_hash() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a string hash representation of this object based on its content.

**Returns:**

str: A string representation of the hash value

> #### get\_uuid() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the UUID of this object from the Expected Parrot cloud service based on its hash.

This method calculates the hash of the object and queries the cloud service to find if there’s an uploaded version with the same content. If found, it returns the UUID of that object.

**Returns:**

str: The UUID of the object in the cloud service if found

**Raises:**

CoopServerResponseError: If the object is not found or there’s an error

communicating with the server

> #### get\_value(*data\_type: str*, *key: str*) → Any[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the value for a given data type and key.

This method provides a consistent way to access values across different sub-dictionaries in the Result object. It’s particularly useful when you need to programmatically access values without knowing which data type a particular key belongs to.

> **Args:**

data\_type: The category of data to retrieve from. Valid options include:

“agent”, “scenario”, “model”, “answer”, “prompt”, “comment”, “generated\_tokens”, “raw\_model\_response”, “question\_text”, “question\_options”, “question\_type”, “cache\_used”, “cache\_keys”.

key: The specific attribute name within that data type.

> **Returns:**

The value associated with the key in the specified data type.

> **Examples:**

```python theme={null}
>>> r = Result.example()
>>> r.get_value("answer", "how_feeling")
'OK'
>>> r.get_value("scenario", "period")
'morning'
```

> #### *classmethod* help()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display the class documentation string.

This is a convenience method to quickly access the docstring of the class.

**Returns:**

None, but prints the class docstring to stdout

> #### inspect()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create an interactive inspector widget for this object.

This method uses the InspectorWidget registry system to find the appropriate inspector widget class for this object’s type and returns an instance of it.

**Returns:**

InspectorWidget subclass instance: Interactive widget for inspecting this object

**Raises:**

KeyError: If no inspector widget is registered for this object’s class ImportError: If the widgets module cannot be imported

> #### items() → a set-like object providing a view on D's items[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### json()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a formatted JSON representation of this object.

**Returns:**

DisplayJSON: A displayable JSON representation

> #### *property* key\_to\_data\_type[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### keys()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the key names in the object’s dictionary representation.

This method returns all the keys in the serialized form of the object, excluding metadata keys like version information.

**Returns:**

list: A list of key names

> #### *classmethod* list(*visibility: Literal\['private', 'public', 'unlisted'] | List\[Literal\['private', 'public', 'unlisted']] | None = None*, *job\_status: Literal\['queued', 'running', 'completed', 'failed', 'cancelled', 'cancelling', 'partial\_failed'] | List\[Literal\['queued', 'running', 'completed', 'failed', 'cancelled', 'cancelling', 'partial\_failed']] | None = None*, *search\_query: str | None = None*, *page: int = 1*, *page\_size: int = 10*, *sort\_ascending: bool = False*) → CoopObjects[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

List objects from coop.

Notes: - The visibility parameter is not supported for remote inference jobs. - The job\_status parameter is not supported for objects. - search\_query only works with the description field. - If sort\_ascending is False, then the most recently created objects are returned first.

> #### *classmethod* load(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Load the object from a JSON file (compressed or uncompressed).

This method deserializes an object from a file, automatically detecting whether the file is compressed with gzip or not.

**Args:**

filename: Path to the file to load

**Returns:**

An instance of the class populated with data from the file

**Raises:**

Various exceptions may be raised if the file doesn’t exist or contains invalid data

> #### *property* model\*: [LanguageModel](/en/latest/language_models#languagemodel-class "edsl.language_models.LanguageModel")\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the LanguageModel object.

> #### *classmethod* old\_pull(*url\_or\_uuid: str | UUID | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Pull the object from coop.

**Args:**

url\_or\_uuid: Either a UUID string or a URL pointing to the object

> #### *static* open\_compressed\_file(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Read and parse a compressed JSON file.

**Args:**

filename: Path to a gzipped JSON file

**Returns:**

dict: The parsed JSON content

> #### *static* open\_regular\_file(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Read and parse an uncompressed JSON file.

**Args:**

filename: Path to a JSON file

**Returns:**

dict: The parsed JSON content

> #### patch(\*\**kwargs*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### *classmethod* patch\_cls(*url\_or\_uuid: str | UUID*, *description: str | None = None*, *value: Any | None = None*, *visibility: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Patch an uploaded object’s attributes (class method version). - description changes the description of the object on Expected Parrot - value changes the value of the object on Expected Parrot. **has to be an EDSL object** - visibility changes the visibility of the object on Expected Parrot

> #### *property* polly\_commands[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Auto-generate commands list from methods decorated with @polly\_command

> #### pop(*k*\[, *d*]) → v, remove specified key and return the corresponding value.[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

If key is not found, d is returned if given, otherwise KeyError is raised.

> #### popitem() → (k, v), remove and return some (key, value) pair[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

as a 2-tuple; but raise KeyError if D is empty.

> #### print(*format='rich'*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Print a formatted table representation of this object.

**Args:**

format: The output format (currently only ‘rich’ is supported)

**Returns:**

None, but prints a formatted table to the console

> #### *property* problem\_keys[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### *classmethod* pull(*url\_or\_uuid: str | UUID | None = None*, *expected\_parrot\_url: str | None = None*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a signed URL for directly downloading an object from Google Cloud Storage.

This method provides a more efficient way to download objects compared to the old pull() method, especially for large files, by generating a direct signed URL to the storage bucket.

**Args:**

url\_or\_uuid (Union\[str, UUID], optional): Identifier for the object to retrieve.

Can be one of: - UUID string (e.g., “123e4567-e89b-12d3-a456-426614174000”) - Full URL (e.g., “[https://expectedparrot.com/content/123e4567](https://expectedparrot.com/content/123e4567)…”) - Alias URL (e.g., “[https://expectedparrot.com/content/username/my-survey](https://expectedparrot.com/content/username/my-survey)”)

expected\_parrot\_url (str, optional): Optional custom URL for the coop service

**Returns:**

dict: A response containing the signed\_url for direct download

> **Example:**

```python theme={null}
>>> response = SurveyClass.pull("123e4567-e89b-12d3-a456-426614174000")
>>> response = SurveyClass.pull("https://expectedparrot.com/content/username/my-survey")
>>> print(f"Download URL: {response['signed_url']}")
>>> # Use the signed_url to download the object directly
```

> #### push(*description: str | None = None*, *alias: str | None = None*, *visibility: str | None = 'unlisted'*, *expected\_parrot\_url: str | None = None*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a signed URL for directly uploading an object to Google Cloud Storage.

This method provides a more efficient way to upload objects compared to the push() method, especially for large files, by generating a direct signed URL to the storage bucket.

**Args:**

expected\_parrot\_url (str, optional): Optional custom URL for the coop service

**Returns:**

dict: A response containing the signed\_url for direct upload and optionally a job\_id

> **Example:**

```python theme={null}
>>> from edsl.surveys import Survey
>>> survey = Survey(...)
>>> response = survey.push()
>>> print(f"Upload URL: {response['signed_url']}")
>>> # Use the signed_url to upload the object directly
```

> #### *property* rb[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### save(*filename: str | None = None*, *compress: bool = True*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Save the object to a file as JSON with optional compression.

Serializes the object to JSON and writes it to the specified file. By default, the file will be compressed using gzip. File extensions are handled automatically.

> **Args:**

filename: Path where the file should be saved compress: If True, compress the file using gzip (default: True)

> **Returns:**

None

> **Examples:**

```python theme={null}
>>> obj.save("my_object.json.gz")  # Compressed
>>> obj.save("my_object.json", compress=False)  # Uncompressed
```

> #### *property* scenario\*: [Scenario](/en/latest/scenarios#scenario-class "edsl.scenarios.Scenario")\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the Scenario object.

> #### score(*scoring\_function: Callable*) → int | float[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Score the result using a passed-in scoring function.

> **Args:**

scoring\_function: A callable that takes parameters from the Result’s combined\_dict

and returns a numeric score.

> **Returns:**

The numeric score returned by the scoring function.

> **Raises:**

ResultsError: If a required parameter for the scoring function is not found

in the Result object.

> **Examples:**

```python theme={null}
>>> def f(status): return 1 if status == 'Joyful' else 0
>>> result = Result.example()
>>> result.score(f)
1
```

> #### score\_with\_answer\_key(*answer\_key: dict*) → dict\[str, int][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Score the result against a reference answer key.

This method evaluates the correctness of answers by comparing them to a provided answer key. It returns a dictionary with counts of correct, incorrect, and missing answers.

The answer key can contain either single values or lists of acceptable values. If a list is provided, the answer is considered correct if it matches any value in the list.

> **Args:**

answer\_key: A dictionary mapping question names to expected answers.

Values can be single items or lists of acceptable answers.

> **Returns:**

A dictionary with keys ‘correct’, ‘incorrect’, and ‘missing’, indicating the counts of each answer type.

> **Examples:**

```python theme={null}
>>> result = Result.example()
>>> result.answer
{'how_feeling': 'OK', 'how_feeling_yesterday': 'Great'}
```

```python theme={null}
>>> # Using exact match answer key
>>> answer_key = {'how_feeling': 'OK', 'how_feeling_yesterday': 'Great'}
>>> result.score_with_answer_key(answer_key)
{'correct': 2, 'incorrect': 0, 'missing': 0}
```

```python theme={null}
>>> # Using answer key with multiple acceptable answers
>>> answer_key = {'how_feeling': 'OK', 'how_feeling_yesterday': ['Great', 'Good']}
>>> result.score_with_answer_key(answer_key)
{'correct': 2, 'incorrect': 0, 'missing': 0}
```

> #### *classmethod* search(*query*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Search for objects on coop.

> #### setdefault(*k*\[, *d*]) → D.get(k,d), also set D\[k]=d if k not in D[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### show\_methods(*show\_docstrings=True*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display all public methods available on this object.

This utility method helps explore the capabilities of an object by listing all its public methods and optionally their documentation.

**Args:**

show\_docstrings: If True, print method names with docstrings;

if False, return the list of method names

**Returns:**

None or list: If show\_docstrings is True, prints methods and returns None.

If show\_docstrings is False, returns a list of method names.

> #### store(*d: dict*, *key\_name: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Store this object in a dictionary with an optional key.

**Args:**

d: The dictionary in which to store the object key\_name: Optional key to use (defaults to the length of the dictionary)

**Returns:**

None

> #### *property* sub\_dicts[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### to\_dataset(*flatten\_nested\_dicts: bool = False*, *separator: str = '\_'*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the result to a dataset format.

This method transforms the result data into a Dataset object suitable for analysis and data manipulation.

**Args:**

**flatten\_nested\_dicts: Whether to flatten nested dictionaries using the separator.**

Defaults to False.

**separator: The separator to use when flattening nested dictionaries.**

Defaults to “\_”.

**Returns:**

A Dataset object containing the result data organized for analysis.

> #### to\_dict(*add\_edsl\_version: bool = True*, *include\_cache\_info: bool = False*, *full\_dict: bool = False*) → dict\[str, Any][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a dictionary representation of the Result object.

**Args:**

**add\_edsl\_version: Whether to include EDSL version information in the output.**

Defaults to True.

**include\_cache\_info: Whether to include cache information in the output.**

Defaults to False.

**Returns:**

A dictionary representation of the Result object containing all relevant data.

> **Examples:**

```python theme={null}
>>> r = Result.example()
>>> data = r.to_dict()
>>> data['scenario']['period']
'morning'
```

> #### to\_json()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Serialize this object to a JSON string.

**Returns:**

str: A JSON string representation of the object

> #### to\_yaml(*add\_edsl\_version=False*, *filename: str = None*) → str | None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the object to YAML format.

Serializes the object to YAML format and optionally writes it to a file.

**Args:**

add\_edsl\_version: Whether to include EDSL version information filename: If provided, write the YAML to this file path

**Returns:**

str: The YAML string representation if no filename is provided None: If written to file

> #### transcript(*format: str = 'simple'*) → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the questions and answers in a human-readable transcript.

> **Args:**

format: The format for the transcript. Either ‘simple’ or ‘rich’.

‘simple’ (default) returns plain-text format with questions, options, and answers separated by blank lines. ‘rich’ uses the rich library to wrap each Q\&A block in a Panel with colors and formatting.

> **Returns:**

A formatted transcript string of the interview.

> **Raises:**

ImportError: If ‘rich’ format is requested but the rich library is not installed.

> **Examples:**

```python theme={null}
>>> result = Result.example()
>>> transcript = result.transcript(format="simple")
>>> print(transcript)
QUESTION: How are you this `{{ period }}`?
OPTIONS: Good / Great / OK / Terrible
ANSWER: OK

QUESTION: How were you feeling yesterday `{{ period }}`?
OPTIONS: Good / Great / OK / Terrible
ANSWER: Great
```

> #### *property* transformer[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the ResultTransformer instance for this Result.

> #### update(\[*E*, ]\*\**F*) → None.  Update D from mapping/iterable E and F.[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

If E present and has a .keys() method, does: for k in E: D\[k] = E\[k] If E present and lacks .keys() method, does: for (k, v) in E: D\[k] = v In either case, this is followed by: for k, v in F.items(): D\[k] = v

> #### values()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the values in the object’s dictionary representation.

**Returns:**

set: A set containing all the values in the object

> #### view()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display an interactive visualization of this object.

**Returns:**

The result of the dataset’s view method

> #### yaml()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a formatted YAML representation of this object.

**Returns:**

DisplayYAML: A displayable YAML representation

## Results class

> ### *class* edsl.results.Results(*survey: Optional\['Survey'] = None*, *data: Optional\[list\['Result']] = None*, *name: Optional\[str] = None*, *created\_columns: Optional\[list\[str]] = None*, *cache: Optional\['Cache'] = None*, *job\_uuid: Optional\[str] = None*, *total\_results: Optional\[int] = None*, *task\_history: Optional\['TaskHistory'] = None*, *sort\_by\_iteration: bool = False*, *data\_class: Optional\[type] = \<class 'list'>*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Bases: `MutableSequence`, `ResultsOperationsMixin`, [`Base`](/en/latest/base#base-class "edsl.base.base_class.Base")

A collection of Result objects with powerful data analysis capabilities.

The Results class is the primary container for working with data from EDSL surveys. It provides a rich set of methods for data analysis, transformation, and visualization inspired by data manipulation libraries like dplyr and pandas. The Results class implements a functional, fluent interface for data manipulation where each method returns a new Results object, allowing method chaining.

Attributes:

survey: The Survey object containing the questions used to generate results. data: A list of Result objects containing the responses. created\_columns: A list of column names created through transformations. cache: A Cache object for storing model responses. completed: Whether the Results object is ready for use. task\_history: A TaskHistory object containing information about the tasks. known\_data\_types: List of valid data type strings for accessing data.

Key features:

* List-like interface for accessing individual Result objects
* Selection of specific data columns with select()
* Filtering results with boolean expressions using filter()
* Creating new derived columns with mutate()
* Recoding values with recode() and answer\_truncate()
* Sorting results with order\_by()
* Converting to other formats (dataset, table, pandas DataFrame)
* Serialization for storage and retrieval
* Support for remote execution and result retrieval

Results objects have a hierarchical structure with the following components:

1. Each Results object contains multiple Result objects
2. Each Result object contains data organized by type (agent, scenario, model, answer, etc.)
3. Each data type contains multiple attributes (e.g., “how\_feeling” in the answer type)

You can access data in a Results object using dot notation (answer.how\_feeling) or using just the attribute name if it’s not ambiguous (how\_feeling).

The Results class also tracks “created columns” - new derived values that aren’t part of the original data but were created through transformations.

> #### **Examples:**

```python theme={null}
>>> # Create a simple Results object from example data
>>> r = Results.example()
>>> len(r) > 0  # Contains Result objects
True
>>> # Filter and transform data
>>> filtered = r.filter("how_feeling == 'Great'")
>>> # Access hierarchical data
>>> 'agent' in r.known_data_types
True
```

> #### *class* ClassOrInstanceMethod(*func*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Bases: `object`

Descriptor that allows a method to be called as both a class method and an instance method.

> ##### **init**(*func*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### **init**(*survey: Optional\['Survey'] = None*, *data: Optional\[list\['Result']] = None*, *name: Optional\[str] = None*, *created\_columns: Optional\[list\[str]] = None*, *cache: Optional\['Cache'] = None*, *job\_uuid: Optional\[str] = None*, *total\_results: Optional\[int] = None*, *task\_history: Optional\['TaskHistory'] = None*, *sort\_by\_iteration: bool = False*, *data\_class: Optional\[type] = \<class 'list'>*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Instantiate a Results object with a survey and a list of Result objects.

**Args:**

survey: A Survey object containing the questions used to generate results. data: A list of Result objects containing the responses. created\_columns: A list of column names created through transformations. cache: A Cache object for storing model responses. job\_uuid: A string representing the job UUID. total\_results: An integer representing the total number of results. task\_history: A TaskHistory object containing information about the tasks. sort\_by\_iteration: Whether to sort data by iteration before initializing. data\_class: The class to use for the data container (default: list).

> #### add\_task\_history\_entry(*interview: Interview*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### agent\_answers\_by\_question(*agent\_key\_fields: List\[str] | None = None*, *separator: str = ','*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Returns a dictionary of agent answers.

The keys are the agent names and the values are the answers.

```python theme={null}
>>> result = Results.example().agent_answers_by_question()
>>> sorted(result['how_feeling'].values())
['Great', 'OK', 'OK', 'Terrible']
>>> sorted(result['how_feeling_yesterday'].values())
['Good', 'Great', 'OK', 'Terrible']
```

> #### *property* agent\_keys\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a set of all of the keys that are in the Agent data.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.agent_keys
['agent_index', 'agent_instruction', 'agent_name', 'status']
```

> #### *property* agents\*: [AgentList](/en/latest/agents#agentlist-class "edsl.agents.AgentList")\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a list of all of the agents in the Results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.agents
AgentList([Agent(traits = {'status': 'Joyful'}), Agent(traits = {'status': 'Joyful'}), Agent(traits = {'status': 'Sad'}), Agent(traits = {'status': 'Sad'})])
```

> #### *property* all\_keys\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a set of all of the keys that are in the Results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.all_keys
['agent_index', ...]
```

> #### *property* answer\_keys\*: dict\[str, str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a mapping of answer keys to question text.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.answer_keys
{'how_feeling': 'How are you this `{{ period }}`?', 'how_feeling_yesterday': 'How were you feeling yesterday `{{ period }}`?'}
```

> #### apply\_command(*command\_name*, *kwargs*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### bucket\_by(\**columns: str*) → dict\[tuple, list\[[Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")]][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Group Result objects into buckets keyed by the specified column values.

Each key in the returned dictionary is a tuple containing the values of the requested columns (in the same order as supplied). The associated value is a list of `Result` instances whose values match that key.

> **Args:**

[\*](/en/latest/#id2)columns: Names of the columns to group by. Column identifiers

follow the same rules used by [`select()`](/en/latest/#edsl.results.Results.select "edsl.results.Results.select") – they can be specified either as fully-qualified names (e.g. `"agent.status"`) or by bare attribute name when unambiguous.

> **Returns:**

dict\[tuple, list\[Result]]: Mapping from value tuples to lists of `Result` objects.

> **Raises:**

**ResultsError: If no columns are provided or an invalid column name is**

supplied.

> **Examples:**

```python theme={null}
>>> r = Results.example()
>>> buckets = r.bucket_by('how_feeling')
>>> list(buckets.keys())
[('OK',), ('Great',), ('Terrible',)]
>>> all(isinstance(v, list) for v in buckets.values())
True
```

> #### chart()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create a chart from the results.

> #### clipboard()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Copy this object’s representation to the system clipboard.

This method first checks if the object has a custom clipboard\_data() method. If it does, it uses that method’s output. Otherwise, it serializes the object to a dictionary (without version info) and copies it to the system clipboard as JSON text.

**Returns:**

None, but prints a confirmation message

> #### clipboard\_data() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return TSV representation of this object for clipboard operations.

This method is called by the clipboard() method in the base class to provide a custom format for copying objects to the system clipboard.

**Returns:**

str: Tab-separated values representation of the object

> #### code()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Method for generating code representations.

> **Raises:**

ResultsError: This method is not implemented for Results objects.

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> try:
...     r.code()
... except ResultsError as e:
...     str(e).startswith("The code() method is not implemented")
True
```

> #### *property* columns\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a list of all of the columns that are in the Results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.columns
['agent.agent_index', ...]
```

> #### compare(*other\_results: [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Compare two Results objects and return the differences.

> #### compute\_job\_cost(*include\_cached\_responses\_in\_cost: bool = False*) → float[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Compute the cost of a completed job in USD.

This method delegates to the JobCostCalculator class to calculate the total cost of all model responses in the results. By default, it only counts the cost of responses that were not cached.

> **Args:**

**include\_cached\_responses\_in\_cost: Whether to include the cost of cached**

responses in the total. Defaults to False.

> **Returns:**

float: The total cost in USD.

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.compute_job_cost()
0.0
```

> #### create\_download\_link()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Generate a downloadable link for this object.

Creates a temporary file containing the serialized object and generates a download link that can be shared with others.

**Returns:**

str: A URL that can be used to download the object

> #### *classmethod* delete(*url\_or\_uuid: str | UUID*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Delete the object from coop.

> #### display\_dict()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create a flattened dictionary representation for display purposes.

This method creates a flattened view of nested structures using colon notation in keys to represent hierarchy.

**Returns:**

dict: A flattened dictionary suitable for display

> #### duplicate(*add\_edsl\_version=False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create and return a deep copy of the object.

**Args:**

add\_edsl\_version: Whether to include EDSL version information in the duplicated object

**Returns:**

A new instance of the same class with identical properties

> #### *classmethod* example(*randomize: bool = False*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return an example Results object.

Example usage:

```python theme={null}
>>> r = Results.example()
```

**Parameters:**

**randomize** – if True, randomizes agent and scenario combinations

> #### extend\_sorted(*other*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Extend the Results list with items from another iterable.

This method preserves ordering based on ‘order’ attribute if present, otherwise falls back to ‘iteration’ attribute.

> #### fetch(*polling\_interval: float | int = 1.0*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Poll the server for job completion and update this Results instance.

This method delegates to the ResultsRemoteFetcher class to handle the polling and fetching operation.

**Args:**

polling\_interval: Number of seconds to wait between polling attempts (default: 1.0)

**Returns:**

Results: The updated Results instance

**Raises:**

ResultsError: If no job info is available or if there’s an error during fetch.

> #### fetch\_remote(*job\_info: Any*) → bool[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Fetch remote Results object and update this instance with the data.

This method delegates to the ResultsRemoteFetcher class to handle the remote fetching operation.

**Args:**

job\_info: RemoteJobInfo object containing the job\_uuid and other remote job details

**Returns:**

bool: True if the fetch was successful, False if the job is not yet completed.

**Raises:**

ResultsError: If there’s an error during the fetch process.

> #### filter(*expression: str*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Filter results based on a boolean expression.

This method delegates to the ResultsFilter class to evaluate a boolean expression against each Result object in the collection and returns a new Results object containing only those that match.

> **Args:**

expression: A string containing a Python expression that evaluates to a boolean.

The expression is applied to each Result object individually. Can be a multi-line string for better readability. Supports template-style syntax with `{{ field }}` notation.

> **Returns:**

A new Results object containing only the Result objects that satisfy the expression.

> **Raises:**

ResultsFilterError: If the expression is invalid or uses improper syntax

(like using ‘=’ instead of ‘==’).

> **Examples:**

```python theme={null}
>>> r = Results.example()
```

```python theme={null}
>>> # Simple equality filter
>>> r.filter("how_feeling == 'Great'").select('how_feeling')
Dataset([{'answer.how_feeling': ['Great']}])
```

```python theme={null}
>>> # Using OR condition
>>> r.filter("how_feeling == 'Great' or how_feeling == 'Terrible'").select('how_feeling')
Dataset([{'answer.how_feeling': ['Great', 'Terrible']}])
```

```python theme={null}
>>> # Filter on agent properties
>>> r.filter("agent.status == 'Joyful'").select('agent.status')
Dataset([{'agent.status': ['Joyful', 'Joyful']}])
```

> #### first() → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the first observation in the results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.first()
Result(agent...
```

> #### flatten(*field: str*, *keep\_original: bool = False*) → [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Expand a field containing dictionaries into separate fields.

This method takes a field that contains a list of dictionaries and expands it into multiple fields, one for each key in the dictionaries. This is useful when working with nested data structures or results from extraction operations.

> **Parameters:**

field: The field containing dictionaries to flatten keep\_original: Whether to retain the original field in the result

> **Returns:**

A new Dataset with the dictionary keys expanded into separate fields

> **Notes:**

* Each key in the dictionaries becomes a new field with name pattern “{field}.{key}”
* All dictionaries in the field must have compatible structures
* If a dictionary is missing a key, the corresponding value will be None
* Non-dictionary values in the field will cause a warning

> **Examples:**

```python theme={null}
>>> from edsl.dataset import Dataset
```

```python theme={null}
# Basic flattening of nested dictionaries >>> Dataset([{‘a’: [{‘a’: 1, ‘b’: 2}]}, {‘c’: [5]}]).flatten(‘a’) Dataset([{‘c’: [5]}, {‘a.a’: [1]}, {‘a.b’: [2]}])

# Works with prefixed fields too >>> Dataset([{‘answer.example’: [{‘a’: 1, ‘b’: 2}]}, {‘c’: [5]}]).flatten(‘answer.example’) Dataset([{‘c’: [5]}, {‘answer.example.a’: [1]}, {‘answer.example.b’: [2]}])

# Keep the original field if needed >>> d = Dataset([{‘a’: [{‘a’: 1, ‘b’: 2}]}, {‘c’: [5]}]) >>> d.flatten(‘a’, keep_original=True) Dataset([{‘a’: [{‘a’: 1, ‘b’: 2}]}, {‘c’: [5]}, {‘a.a’: [1]}, {‘a.b’: [2]}])

# Can also use unambiguous unprefixed field name >>> result = Dataset([{‘answer.pros_cons’: [{‘pros’: [‘Safety’], ‘cons’: [‘Cost’]}]}]).flatten(‘pros_cons’) >>> sorted(result.keys()) == [‘answer.pros_cons.cons’, ‘answer.pros_cons.pros’] True >>> sorted(result.to_dicts()[0].items()) == sorted({‘cons’: [‘Cost’], ‘pros’: [‘Safety’]}.items()) True

```

> #### *classmethod* from\_dict(*data: dict\[str, Any]*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert a dictionary to a Results object.

This method delegates to the ResultsSerializer class to handle the conversion of a dictionary representation back to a Results object.

> **Args:**

data: A dictionary representation of a Results object.

> **Returns:**

Results: A new Results object created from the dictionary data

> **Examples:**

```python theme={null}
>>> r = Results.example()
>>> d = r.to_dict()
>>> r2 = Results.from_dict(d)
>>> r == r2
True
```

> #### *classmethod* from\_disk(*filepath: str*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Load a Results object from a zip file.

This method delegates to the ResultsSerializer class to handle the disk deserialization.

This method: 1. Extracts the SQLite database file 2. Loads the metadata 3. Creates a new Results instance with the restored data

### > **Args:**

filepath: Path to the zip file containing the serialized Results

> **Returns:**

Results: A new Results instance with the restored data

> **Raises:**

ResultsError: If there’s an error during deserialization

> #### *classmethod* from\_job\_info(*job\_info: dict*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Instantiate a Results object from a job info dictionary.

This method creates a Results object in a not-ready state that will fetch its data from a remote source when methods are called on it.

> **Args:**

job\_info: Dictionary containing information about a remote job.

> **Returns:**

Results: A new Results instance with completed=False that will

fetch remote data when needed.

> **Examples:**

```python theme={null}
>>> # Create a job info dictionary
>>> job_info = {'job_uuid': '12345', 'creation_data': {'model': 'gpt-4'}}
>>> # Create a Results object from the job info
>>> results = Results.from_job_info(job_info)
>>> results.completed
False
>>> hasattr(results, 'job_info')
True
```

> #### *classmethod* from\_yaml(*yaml\_str: str | None = None*, *filename: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create an instance from YAML data.

Deserializes a YAML string or file into a new instance of the class.

**Args:**

yaml\_str: YAML string containing object data filename: Path to a YAML file containing object data

**Returns:**

A new instance of the class populated with the deserialized data

**Raises:**

BaseValueError: If neither yaml\_str nor filename is provided

> #### get\_answers(*question\_name: str*) → list[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the answers for a given question name.

> **Args:**

question\_name: The name of the question to fetch answers for.

> **Returns:**

list: A list of answers, one from each result in the data.

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> answers = r.get_answers('how_feeling')
>>> isinstance(answers, list)
True
>>> len(answers) == len(r)
True
```

> #### get\_description() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the description of this object.

> #### get\_hash() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a string hash representation of this object based on its content.

> **Returns:**

str: A string representation of the hash value

> #### get\_shelved\_result(*key: str*) → [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Retrieve a Result object from persistent storage.

This method delegates to the ResultsSerializer class to handle the retrieval operation.

**Args:**

key: The hash key of the Result to retrieve

**Returns:**

Result: The stored Result object

**Raises:**

ResultsError: If the key doesn’t exist or if there’s an error retrieving the Result

> #### get\_tabular\_data(*remove\_prefix: bool = False*, *pretty\_labels: dict | None = None*) → Tuple\[List\[str], List\[List]][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Internal method to get tabular data in a standard format.

**Args:**

remove\_prefix: Whether to remove the prefix from column names pretty\_labels: Dictionary mapping original column names to pretty labels

**Returns:**

Tuple containing (header\_row, data\_rows)

> #### get\_uuid() → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the UUID of this object from the Expected Parrot cloud service based on its hash.

This method calculates the hash of the object and queries the cloud service to find if there’s an uploaded version with the same content. If found, it returns the UUID of that object.

**Returns:**

str: The UUID of the object in the cloud service if found

**Raises:**

CoopServerResponseError: If the object is not found or there’s an error

communicating with the server

> #### ggplot2(*ggplot\_code: str*, *shape: str = 'wide'*, *sql: str | None = None*, *remove\_prefix: bool = True*, *debug: bool = False*, *height: float = 4*, *width: float = 6*, *factor\_orders: dict | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create visualizations using R’s ggplot2 library.

This method provides a bridge to R’s powerful ggplot2 visualization library, allowing you to create sophisticated plots directly from EDSL data structures.

> **Parameters:**

ggplot\_code: R code string containing ggplot2 commands shape: Data shape to use (“wide” or “long”) sql: Optional SQL query to transform data before visualization remove\_prefix: Whether to remove prefixes (like “answer.”) from column names debug: Whether to display debugging information height: Plot height in inches width: Plot width in inches factor\_orders: Dictionary mapping factor variables to their desired order

**Returns:**

A plot object that renders in Jupyter notebooks

> **Notes:**

* Requires R and the ggplot2 package to be installed
* Data is automatically converted to a format suitable for ggplot2
* The ggplot2 code should reference column names as they appear after any transformations from the shape and remove\_prefix parameters

> **Examples:**

```python theme={null}

>>> from edsl.results import Results
>>> r = Results.example()
>>> # The following would create a plot if R is installed (not shown in doctest):
>>> # r.ggplot2('''
>>> #     ggplot(df, aes(x=how_feeling)) +
>>> #     geom_bar() +
>>> #     labs(title="Distribution of Feelings")
>>> # ''')
```

> #### *property* has\_unfixed\_exceptions\*: bool\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### *property* hashes\*: set\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### *classmethod* help()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display the class documentation string.

This is a convenience method to quickly access the docstring of the class.

**Returns:**

None, but prints the class docstring to stdout

> #### html(*filename: str | None = None*, *cta: str = 'Open in browser'*, *return\_link: bool = False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### initialize\_cache\_from\_results()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### insert\_from\_shelf() → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Move all shelved results into memory using insert\_sorted method.

This method delegates to the ResultsSerializer class to handle the shelf operations. Clears the shelf after successful insertion.

This method preserves the original order of results by using their ‘order’ attribute if available, which ensures consistent ordering even after serialization/deserialization.

**Raises:**

ResultsError: If there’s an error accessing or clearing the shelf

> #### insert\_sorted(*item: [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Insert a Result object into the Results list while maintaining sort order.

Uses the ‘order’ attribute if present, otherwise falls back to ‘iteration’ attribute. Utilizes bisect for efficient insertion point finding.

> **Args:**

item: A Result object to insert

Examples:

```python theme={null}
>>> r = Results.example()
>>> new_result = r[0].copy()
>>> new_result.order = 1.5  # Insert between items
>>> r.insert_sorted(new_result)
```

> #### inspect()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create an interactive inspector widget for this object.

This method uses the InspectorWidget registry system to find the appropriate inspector widget class for this object’s type and returns an instance of it.

**Returns:**

InspectorWidget subclass instance: Interactive widget for inspecting this object

**Raises:**

KeyError: If no inspector widget is registered for this object’s class ImportError: If the widgets module cannot be imported

> #### json()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a formatted JSON representation of this object.

**Returns:**

DisplayJSON: A displayable JSON representation

> #### keys()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the key names in the object’s dictionary representation.

This method returns all the keys in the serialized form of the object, excluding metadata keys like version information.

**Returns:**

list: A list of key names

> #### *classmethod* list(*visibility: Literal\['private', 'public', 'unlisted'] | List\[Literal\['private', 'public', 'unlisted']] | None = None*, *job\_status: Literal\['queued', 'running', 'completed', 'failed', 'cancelled', 'cancelling', 'partial\_failed'] | List\[Literal\['queued', 'running', 'completed', 'failed', 'cancelled', 'cancelling', 'partial\_failed']] | None = None*, *search\_query: str | None = None*, *page: int = 1*, *page\_size: int = 10*, *sort\_ascending: bool = False*) → CoopObjects[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

List objects from coop.

Notes: - The visibility parameter is not supported for remote inference jobs. - The job\_status parameter is not supported for objects. - search\_query only works with the description field. - If sort\_ascending is False, then the most recently created objects are returned first.

> #### *classmethod* load(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Load the object from a JSON file (compressed or uncompressed).

This method deserializes an object from a file, automatically detecting whether the file is compressed with gzip or not.

**Args:**

filename: Path to the file to load

**Returns:**

An instance of the class populated with data from the file

**Raises:**

Various exceptions may be raised if the file doesn’t exist or contains invalid data

> #### make\_tabular(*remove\_prefix: bool*, *pretty\_labels: dict | None = None*) → tuple\[list, List\[list]][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Turn the results into a tabular format.

**Parameters:**

**remove\_prefix** – Whether to remove the prefix from the column names.

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.select('how_feeling').make_tabular(remove_prefix = True)
(['how_feeling'], [['OK'], ['Great'], ['Terrible'], ['OK']])
```

```python theme={null}
>>> r.select('how_feeling').make_tabular(remove_prefix = True, pretty_labels = {'how_feeling': "How are you feeling"})
(['How are you feeling'], [['OK'], ['Great'], ['Terrible'], ['OK']])
```

> #### *property* model\_keys\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a set of all of the keys that are in the LanguageModel data.

```python theme={null}
>>> r = Results.example()
>>> r.model_keys
['canned_response', 'inference_service', 'model', 'model_index', 'temperature']
```

> #### *property* models\*: [ModelList](/en/latest/language_models#modellist-class "edsl.language_models.ModelList")\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a list of all of the models in the Results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.models[0]
Model(model_name = ...)
```

> #### mutate(*new\_var\_string: str*, *functions\_dict: dict | None = None*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Create a new column based on a computational expression.

This method delegates to the ResultsTransformer class to handle the mutation operation.

> **Args:**

**new\_var\_string: A string containing an assignment expression in the form**

“new\_column\_name = expression”. The expression can reference any existing column and use standard Python syntax.

**functions\_dict: Optional dictionary of custom functions that can be used in**

the expression. Keys are function names, values are function objects.

Returns:

A new Results object with the additional column.

Examples:

```python theme={null}
>>> r = Results.example()
```

```python theme={null}
>>> # Create a simple derived column
>>> r.mutate('how_feeling_x = how_feeling + "x"').select('how_feeling_x')
Dataset([{'answer.how_feeling_x': ['OKx', 'Greatx', 'Terriblex', 'OKx']}])
```

```python theme={null}
>>> # Create a binary indicator column
>>> r.mutate('is_great = 1 if how_feeling == "Great" else 0').select('is_great')
Dataset([{'answer.is_great': [0, 1, 0, 0]}])
```

```python theme={null}
>>> # Create a column with custom functions
>>> def sentiment(text):
...     return len(text) > 5
>>> r.mutate('is_long = sentiment(how_feeling)',
...          functions_dict={'sentiment': sentiment}).select('is_long')
Dataset([{'answer.is_long': [False, False, True, False]}])
```

> #### num\_observations()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the number of observations in the dataset.

```python theme={null}
>>> from edsl.results import Results
>>> Results.example().num_observations()
4
```

> #### *classmethod* old\_pull(*url\_or\_uuid: str | UUID | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Pull the object from coop.

**Args:**

url\_or\_uuid: Either a UUID string or a URL pointing to the object

> #### *static* open\_compressed\_file(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Read and parse a compressed JSON file.

**Args:**

filename: Path to a gzipped JSON file

**Returns:**

dict: The parsed JSON content

> #### *static* open\_regular\_file(*filename*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Read and parse an uncompressed JSON file.

**Args:**

filename: Path to a JSON file

**Returns:**

dict: The parsed JSON content

> #### optimzie\_scenarios()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### order\_by(\**columns: str*, *reverse: bool = False*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Sort the results by one or more columns.

This method delegates to the ResultsTransformer class to handle the sorting operation.

> **Args:**

columns: One or more column names as strings. reverse: A boolean that determines whether to sort in reverse order.

> **Returns:**

Results: A new Results object with sorted data.

> **Examples:**

```python theme={null}
>>> r = Results.example()
>>> sorted_results = r.order_by('how_feeling')
>>> len(sorted_results) == len(r)
True
```

> #### patch(\*\**kwargs*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### *classmethod* patch\_cls(*url\_or\_uuid: str | UUID*, *description: str | None = None*, *value: Any | None = None*, *visibility: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Patch an uploaded object’s attributes (class method version). - description changes the description of the object on Expected Parrot - value changes the value of the object on Expected Parrot. **has to be an EDSL object** - visibility changes the visibility of the object on Expected Parrot

> #### *property* polly\_commands[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Auto-generate commands list from methods decorated with @polly\_command

> #### print(*format='rich'*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Print a formatted table representation of this object.

**Args:**

format: The output format (currently only ‘rich’ is supported)

**Returns:**

None, but prints a formatted table to the console

> #### print\_long()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Print the results in a long format. >>> from edsl.results import Results >>> r = Results.example() >>> r.select(‘how\_feeling’).print\_long() answer.how\_feeling: OK answer.how\_feeling: Great answer.how\_feeling: Terrible answer.how\_feeling: OK

> #### *classmethod* pull(*url\_or\_uuid: str | UUID | None = None*, *expected\_parrot\_url: str | None = None*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a signed URL for directly downloading an object from Google Cloud Storage.

This method provides a more efficient way to download objects compared to the old pull() method, especially for large files, by generating a direct signed URL to the storage bucket.

> **Args:**

**url\_or\_uuid (Union\[str, UUID], optional): Identifier for the object to retrieve.**

Can be one of: - UUID string (e.g., “123e4567-e89b-12d3-a456-426614174000”) - Full URL (e.g., “[https://expectedparrot.com/content/123e4567](https://expectedparrot.com/content/123e4567)…”) - Alias URL (e.g., “[https://expectedparrot.com/content/username/my-survey](https://expectedparrot.com/content/username/my-survey)”)

expected\_parrot\_url (str, optional): Optional custom URL for the coop service

> **Returns:**

dict: A response containing the signed\_url for direct download

> **Example:**

```python theme={null}
>>> response = SurveyClass.pull("123e4567-e89b-12d3-a456-426614174000")
>>> response = SurveyClass.pull("https://expectedparrot.com/content/username/my-survey")
>>> print(f"Download URL: {response['signed_url']}")
>>> # Use the signed_url to download the object directly
```

> #### push(*description: str | None = None*, *alias: str | None = None*, *visibility: str | None = 'unlisted'*, *expected\_parrot\_url: str | None = None*) → dict[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a signed URL for directly uploading an object to Google Cloud Storage.

This method provides a more efficient way to upload objects compared to the push() method, especially for large files, by generating a direct signed URL to the storage bucket.

> **Args:**

expected\_parrot\_url (str, optional): Optional custom URL for the coop service

> **Returns:**

dict: A response containing the signed\_url for direct upload and optionally a job\_id

> **Example:**

```python theme={null}
>>> from edsl.surveys import Survey
>>> survey = Survey(...)
>>> response = survey.push()
>>> print(f"Upload URL: {response['signed_url']}")
>>> # Use the signed_url to upload the object directly
```

> #### *property* question\_names\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a list of all of the question names.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.question_names
['how_feeling', 'how_feeling_yesterday']
```

> #### relevant\_cache(*cache: [Cache](/en/latest/data#cache-class "edsl.caching.Cache")*) → [Cache](/en/latest/data#cache-class "edsl.caching.Cache")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return the set of keys that are present in the dataset.

**Parameters:**

* **data\_type** – The data type to filter by.
* **remove\_prefix** – Whether to remove the prefix from the column names.

```python theme={null}
>>> from ..dataset import Dataset
>>> d = Dataset([{'a.b':[1,2,3,4]}])
>>> d.relevant_columns()
['a.b']
```

```python theme={null}
>>> d.relevant_columns(remove_prefix=True)
['b']
```

```python theme={null}
>>> d = Dataset([{'a':[1,2,3,4]}, {'b':[5,6,7,8]}])
>>> d.relevant_columns()
['a', 'b']
```

```python theme={null}
>>> from edsl.results import Results; Results.example().select('how_feeling', 'how_feeling_yesterday').relevant_columns()
['answer.how_feeling', 'answer.how_feeling_yesterday']
```

```python theme={null}
>>> from edsl.results import Results
>>> sorted(Results.example().select().relevant_columns(data_type = "model"))
['model.canned_response', 'model.inference_service', 'model.model', 'model.model_index', 'model.temperature']
```

```python theme={null}
>>> # Testing relevant_columns with invalid data_type raises DatasetValueError - tested in unit tests
```

> #### remove\_prefix()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Returns a new Dataset with the prefix removed from all column names.

The prefix is defined as everything before the first dot (.) in the column name. If removing prefixes would result in duplicate column names, an exception is raised.

> **Returns:**

Dataset: A new Dataset with prefixes removed from column names

> **Raises:**

ValueError: If removing prefixes would result in duplicate column names

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.select('how_feeling', 'how_feeling_yesterday').relevant_columns()
['answer.how_feeling', 'answer.how_feeling_yesterday']
>>> r.select('how_feeling', 'how_feeling_yesterday').remove_prefix().relevant_columns()
['how_feeling', 'how_feeling_yesterday']
```

```python theme={null}
>>> from edsl.dataset import Dataset
>>> d = Dataset([{'a.x': [1, 2, 3]}, {'b.x': [4, 5, 6]}])
>>> # d.remove_prefix()
```

\# Testing remove\_prefix with duplicate column names raises DatasetValueError - tested in unit tests

> #### rename(*old\_name: str*, *new\_name: str*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Rename an answer column in a Results object.

This method delegates to the ResultsTransformer class to handle the renaming operation.

> **Args:**

old\_name: The current name of the column to rename new\_name: The new name for the column

> **Returns:**

Results: A new Results object with the column renamed

> **Examples:**

```python theme={null}
>>> s = Results.example()
>>> s.rename('how_feeling', 'how_feeling_new').select('how_feeling_new')
Dataset([{'answer.how_feeling_new': ['OK', 'Great', 'Terrible', 'OK']}])
```

> #### report(\**fields: str | None*, *top\_n: int | None = None*, *header\_fields: List\[str] | None = None*, *divider: bool = True*, *return\_string: bool = False*, *format: str = 'markdown'*, *filename: str | None = None*) → str | Document | None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Generates a report of the results by iterating through rows.

> **Args:**

[\*](/en/latest/#id4)fields: The fields to include in the report. If none provided, all fields are used. top\_n: Optional limit on the number of observations to include. header\_fields: Optional list of fields to include in the main header instead of as sections. divider: If True, adds a horizontal rule between observations (markdown only). return\_string: If True, returns the markdown string. If False (default in notebooks),

only displays the markdown without returning.

format: Output format - either “markdown” or “docx”. filename: If provided and format is “docx”, saves the document to this file.

> **Returns:**

Depending on format and return\_string: - For markdown: A string if return\_string is True, otherwise None (displays in notebook) - For docx: A docx.Document object, or None if filename is provided (saves to file)

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> report = r.select('how_feeling').report(return_string=True)
>>> "# Observation: 1" in report
True
>>> doc = r.select('how_feeling').report(format="docx")
>>> isinstance(doc, object)
True
```

> #### report\_from\_template(*template: str*, \**fields: str | None*, *top\_n: int | None = None*, *remove\_prefix: bool = True*, *return\_string: bool = False*, *format: str = 'text'*, *filename: str | None = None*, *separator: str = 'nn'*, *observation\_title\_template: str | None = None*, *explode: bool = False*, *filestore: bool = False*) → str | Document | List | [FileStore](/en/latest/filestore#edsl.scenarios.FileStore "edsl.scenarios.FileStore") | None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Generates a report using a Jinja2 template for each row in the dataset.

This method renders a user-provided Jinja2 template for each observation in the dataset, with template variables populated from the row data. This allows for completely customized report formatting using pandoc for advanced output formats.

> **Args:**

template: Jinja2 template string to render for each row [\*](/en/latest/#id6)fields: The fields to include in template context. If none provided, all fields are used. top\_n: Optional limit on the number of observations to include. remove\_prefix: Whether to remove type prefixes (e.g., “answer.”) from field names in template context. return\_string: If True, returns the rendered content. If False (default in notebooks),

only displays the content without returning.

format: Output format - one of “text”, “html”, “pdf”, or “docx”. Formats other than “text” require pandoc. filename: If provided, saves the rendered content to this file. For exploded output,

this becomes a template (e.g., “report\_\{index}”).

separator: String to use between rendered templates for each row (ignored when explode=True). observation\_title\_template: Optional Jinja2 template for observation titles.

Defaults to “Observation {index}” where index is 1-based. Template has access to all row data plus ‘index’ and ‘index0’ variables.

explode: If True, creates separate files for each observation instead of one combined file. filestore: If True, wraps the generated file(s) in FileStore object(s). If no filename is provided,

creates temporary files. For exploded output, returns a list of FileStore objects.

> **Returns:**

Depending on explode, format, return\_string, and filestore: - For text format: String content or None (if displayed in notebook) - For html format: HTML string content or None (if displayed in notebook) - For docx format: Document object or None (if saved to file) - For pdf format: PDF bytes or None (if saved to file) - If explode=True: List of created filenames (when filename provided) or list of documents/content - If filestore=True: FileStore object(s) containing the generated file(s)

> **Notes:**

* Pandoc is required for HTML, PDF, and DOCX output formats
* Templates are treated as Markdown for all non-text formats
* PDF output uses XeLaTeX engine through pandoc
* HTML output includes standalone document structure

> **Examples:**

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> template = "Person feels: `{{ how_feeling }}`"
>>> report = r.select('how_feeling').report_from_template(template, return_string=True)
>>> "Person feels: OK" in report
True
>>> "Person feels: Great" in report
True
```

```python theme={null}
# Custom observation titles >>> custom_title = “Response `{{ index }}`: `{{ how_feeling }}`” >>> report = r.select(‘how_feeling’).report_from_template( … template, observation_title_template=custom_title, return_string=True) >>> “Response 1: OK” in report True

# HTML output (requires pandoc) >>> html_report = r.select(‘how_feeling’).report_from_template( … template, format=”html”, return_string=True) # doctest: +SKIP >>> # Creates HTML with proper document structure

# PDF output (requires pandoc with XeLaTeX) >>> pdf_report = r.select(‘how_feeling’).report_from_template( … template, format=”pdf”) # doctest: +SKIP >>> # Returns PDF bytes

# Basic template functionality >>> template2 = “Feeling: `{{ how_feeling }}`, Index: `{{ index }}`” >>> report2 = r.select(‘how_feeling’).report_from_template( … template2, return_string=True, top_n=2) >>> “Feeling: OK, Index: 1” in report2 True

```

> #### rich\_print()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display an object as a table.

> #### sample(*n: int | None = None*, *frac: float | None = None*, *with\_replacement: bool = True*, *seed: str | None = None*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a random sample of the results.

> **Args:**

n: The number of samples to take. frac: The fraction of samples to take (alternative to n). with\_replacement: Whether to sample with replacement. seed: Random seed for reproducibility.

> **Returns:**

Results: A new Results object containing the sampled data.

> #### save(*filename: str | None = None*, *compress: bool = True*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Save the object to a file as JSON with optional compression.

Serializes the object to JSON and writes it to the specified file. By default, the file will be compressed using gzip. File extensions are handled automatically.

> **Args:**

filename: Path where the file should be saved compress: If True, compress the file using gzip (default: True)

> **Returns:**

None

> **Examples:**

```python theme={null}
>>> obj.save("my_object.json.gz")  # Compressed
>>> obj.save("my_object.json", compress=False)  # Uncompressed
```

> #### *property* scenario\_keys\*: list\[str]\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a set of all of the keys that are in the Scenario data.

```python theme={null}
>>> r = Results.example()
>>> r.scenario_keys
['period', 'scenario_index']
```

> #### *property* scenarios\*: [ScenarioList](/en/latest/scenarios#scenariolist-class "edsl.scenarios.ScenarioList")\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a list of all of the scenarios in the Results.

Example:

```python theme={null}
>>> r = Results.example()
>>> r.scenarios
ScenarioList([Scenario({'period': 'morning'}), Scenario({'period': 'afternoon'}), Scenario({'period': 'morning'}), Scenario({'period': 'afternoon'})])
```

> #### score(*f: Callable*) → list[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Score the results using a function.

This method delegates to the ResultsScorer class to handle the scoring operation.

> **Args:**

f: A function that takes values from a Result object and returns a score.

> **Returns:**

list: A list of scores, one for each Result object.

> **Examples:**

```python theme={null}
>>> r = Results.example()
>>> def f(status): return 1 if status == 'Joyful' else 0
>>> r.score(f)
[1, 1, 0, 0]
```

> #### score\_with\_answer\_key(*answer\_key: dict*) → list[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Score the results using an answer key.

This method delegates to the ResultsScorer class to handle the scoring operation.

> **Args:**

answer\_key: A dictionary that maps answer values to scores.

> **Returns:**

list: A list of scores, one for each Result object.

> #### *classmethod* search(*query*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Search for objects on coop.

> #### select(\*\*columns: str | list\[str]\*) → [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Extract specific columns from the Results into a Dataset.

This method allows you to select specific columns from the Results object and transforms the data into a Dataset for further analysis and visualization. A Dataset is a more general-purpose data structure optimized for analysis operations rather than the hierarchical structure of Result objects.

> **Args:**

[\*](/en/latest/#id8)columns: Column names to select. Each column can be:

* A simple attribute name (e.g., “how\_feeling”)
* A fully qualified name with type (e.g., “answer.how\_feeling”)
* A wildcard pattern (e.g., “answer.\*” to select all answer fields)

If no columns are provided, selects all data.

> **Returns:**

A Dataset object containing the selected data.

> **Notes:**

* Column names are automatically disambiguated if needed
* When column names are ambiguous, specify the full path with data type
* You can use wildcard patterns with “\*” to select multiple related fields
* Selecting with no arguments returns all data
* Results are restructured in a columnar format in the Dataset

> **Examples:**

```python theme={null}
>>> results = Results.example()
```

```python theme={null}
>>> # Select a single column by name
>>> results.select('how_feeling')
Dataset([{'answer.how_feeling': ['OK', 'Great', 'Terrible', 'OK']}])
```

```python theme={null}
>>> # Select multiple columns
>>> ds = results.select('how_feeling', 'how_feeling_yesterday')
>>> sorted([list(d.keys())[0] for d in ds])
['answer.how_feeling', 'answer.how_feeling_yesterday']
```

```python theme={null}
>>> # Using fully qualified names with data type
>>> results.select('answer.how_feeling')
Dataset([{'answer.how_feeling': ['OK', 'Great', 'Terrible', 'OK']}])
```

```python theme={null}
>>> # Using partial matching for column names
>>> results.select('answer.how_feeling_y')
Dataset([{'answer.how_feeling_yesterday': ['Great', 'Good', 'OK', 'Terrible']}])
```

```python theme={null}
>>> # Select all columns (same as calling select with no arguments)
>>> results.select('*.*')
Dataset([...])
```

> #### *property* shelf\_keys\*: set\*[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a copy of the set of shelved result keys.

This property delegates to the ResultsSerializer class.

> #### shelve\_result(*result: [Result](/en/latest/#edsl.results.Result "edsl.results.result.Result")*) → str[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Store a Result object in persistent storage using its hash as the key.

This method delegates to the ResultsSerializer class to handle the shelving operation.

> **Args:**

result: A Result object to store

> **Returns:**

str: The hash key for retrieving the result later

> **Raises:**

ResultsError: If there’s an error storing the Result

> #### show\_exceptions(*traceback=False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Print the exceptions.

> #### show\_methods(*show\_docstrings=True*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Display all public methods available on this object.

This utility method helps explore the capabilities of an object by listing all its public methods and optionally their documentation.

> **Args:**

show\_docstrings: If True, print method names with docstrings;

if False, return the list of method names

> **Returns:**

None or list: If show\_docstrings is True, prints methods and returns None.

If show\_docstrings is False, returns a list of method names.

> #### shuffle(*seed: str | None = 'edsl'*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Return a shuffled copy of the results using Fisher-Yates algorithm.

> **Args:**

seed: Random seed for reproducibility.

> **Returns:**

Results: A new Results object with shuffled data.

> #### sort\_by(\**columns: str*, *reverse: bool = False*) → [Results](/en/latest/#edsl.results.Results "edsl.results.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Sort the results by one or more columns.

This method delegates to the ResultsTransformer class to handle the sorting operation.

> **Args:**

columns: One or more column names as strings. reverse: A boolean that determines whether to sort in reverse order.

> **Returns:**

Results: A new Results object with sorted data.

> **Examples:**

```python theme={null}
>>> r = Results.example()
>>> sorted_results = r.order_by('how_feeling')
>>> len(sorted_results) == len(r)
True
```

> #### spot\_issues(*models: [ModelList](/en/latest/language_models#modellist-class "edsl.language_models.ModelList") | None = None*) → [Results](/en/latest/#edsl.results.Results "edsl.results.Results")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Run a survey to spot issues and suggest improvements for prompts that had no model response.

This method delegates to the ResultsAnalyzer class to handle the analysis and debugging.

**Args:**

models: Optional ModelList to use for the analysis. If None, uses the default model.

**Returns:**

Results: A new Results object containing the analysis and suggestions for improvement.

**Notes:**

Future version: Allow user to optionally pass a list of questions to review, regardless of whether they had a null model response.

> #### sql(*query: str*, *transpose: bool = None*, *transpose\_by: str = None*, *remove\_prefix: bool = True*, *shape: str = 'wide'*) → [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Execute SQL queries on the dataset.

This powerful method allows you to use SQL to query and transform your data, combining the expressiveness of SQL with EDSL’s data structures. It works by creating an in-memory SQLite database from your data and executing the query against it.

> **Parameters:**

query: SQL query string to execute transpose: Whether to transpose the resulting table (rows become columns) transpose\_by: Column to use as the new index when transposing remove\_prefix: Whether to remove type prefixes (e.g., “answer.”) from column names shape: Data shape to use (“wide” or “long”)

* “wide”: Default tabular format with columns for each field
* “long”: Melted format with key-value pairs, useful for certain queries

> **Returns:**

A Dataset object containing the query results

> **Notes:**

* The data is stored in a table named “self” in the SQLite database
* In wide format, column names include their type prefix unless remove\_prefix=True
* In long format, the data is melted into columns: row\_number, key, value, data\_type
* Complex objects like lists and dictionaries are converted to strings

Examples:

```python theme={null}
>>> from edsl import Results
>>> r = Results.example()
```

```python theme={null}
# Basic selection >>> len(r.sql(“SELECT * FROM self”, shape=”wide”)) 4

# Filtering with WHERE clause >>> r.sql(“SELECT * FROM self WHERE how_feeling = ‘Great’”).num_observations() 1

# Aggregation >>> r.sql(“SELECT how_feeling, COUNT(*) as count FROM self GROUP BY how_feeling”).keys() [‘how_feeling’, ‘count’]

# Using long format >>> len(r.sql(“SELECT * FROM self”, shape=”long”)) 200
```

> #### store(*d: dict*, *key\_name: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Store this object in a dictionary with an optional key.

> **Args:**

d: The dictionary in which to store the object key\_name: Optional key to use (defaults to the length of the dictionary)

> **Returns:**

None

> #### table(\**fields*, *tablefmt: str | None = 'rich'*, *pretty\_labels: dict | None = None*, *print\_parameters: dict | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

> #### tally(\**fields: str | None*, *top\_n: int | None = None*, *output='Dataset'*) → dict | [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Count frequency distributions of values in specified fields.

This method tallies the occurrence of unique values within one or more fields, similar to a GROUP BY and COUNT in SQL. When multiple fields are provided, it performs cross-tabulation across those fields.

> **Parameters:**

[\*](/en/latest/#id10)fields: Field names to tally. If none provided, uses all available fields. top\_n: Optional limit to return only the top N most frequent values. output: Format for results, either “Dataset” (recommended) or “dict”.

> **Returns:**

By default, returns a Dataset with columns for the field(s) and a ‘count’ column. If output=”dict”, returns a dictionary mapping values to counts.

> **Notes:**

* For single fields, returns counts of each unique value
* For multiple fields, returns counts of each unique combination of values
* Results are sorted in descending order by count
* Fields can be specified with or without their type prefix

> **Examples:**

```python theme={null}
>>> from edsl import Results
>>> r = Results.example()
```

```python theme={null}
# Single field frequency count >>> r.select(‘how_feeling’).tally(‘answer.how_feeling’, output=”dict”) {‘OK’: 2, ‘Great’: 1, ‘Terrible’: 1}

# Return as Dataset (default) >>> from edsl.dataset import Dataset >>> expected = Dataset([{‘answer.how_feeling’: [‘OK’, ‘Great’, ‘Terrible’]}, {‘count’: [2, 1, 1]}]) >>> r.select(‘how_feeling’).tally(‘answer.how_feeling’, output=”Dataset”) == expected True

# Multi-field cross-tabulation - exact output varies based on data >>> result = r.tally(‘how_feeling’, ‘how_feeling_yesterday’) >>> ‘how_feeling’ in result.keys() and ‘how_feeling_yesterday’ in result.keys() and ‘count’ in result.keys() True
```

> #### to\_agent\_list(*remove\_prefix: bool = True*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a list of dictionaries, one per agent.

> **Parameters:**

**remove\_prefix** – Whether to remove the prefix from the column names.

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.select('how_feeling').to_agent_list()
AgentList([Agent(traits = {'how_feeling': 'OK'}), Agent(traits = {'how_feeling': 'Great'}), Agent(traits = {'how_feeling': 'Terrible'}), Agent(traits = {'how_feeling': 'OK'})])
```

> #### to\_csv(*filename: str | None = None*, *remove\_prefix: bool = False*, *pretty\_labels: dict | None = None*) → [FileStore](/en/latest/filestore#edsl.scenarios.FileStore "edsl.scenarios.FileStore")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Export the results to a FileStore instance containing CSV data.

> #### to\_dataset() → [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert this object to a Dataset for advanced data operations.

> **Returns:**

Dataset: A Dataset object containing this object’s data

> #### to\_dict(*sort: bool = False*, *add\_edsl\_version: bool = True*, *include\_cache: bool = True*, *include\_task\_history: bool = False*, *include\_cache\_info: bool = True*, *offload\_scenarios: bool = True*, *full\_dict: bool = False*) → dict\[str, Any][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the Results object to a dictionary representation.

This method delegates to the ResultsSerializer class to handle the conversion of the Results object to a dictionary format suitable for serialization.

> **Args:**

sort: Whether to sort the results data by hash before serialization add\_edsl\_version: Whether to include the EDSL version in the output include\_cache: Whether to include cache data in the output include\_task\_history: Whether to include task history in the output include\_cache\_info: Whether to include cache information in result data offload\_scenarios: Whether to optimize scenarios before serialization

> **Returns:**

dict\[str, Any]: Dictionary representation of the Results object

> #### to\_dicts(*remove\_prefix: bool = True*) → list\[dict][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a list of dictionaries.

> **Parameters:**

**remove\_prefix** – Whether to remove the prefix from the column names.

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.select('how_feeling').to_dicts()
[{'how_feeling': 'OK'}, {'how_feeling': 'Great'}, {'how_feeling': 'Terrible'}, {'how_feeling': 'OK'}]
```

> #### to\_disk(*filepath: str*) → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Serialize the Results object to a zip file, preserving the SQLite database.

This method delegates to the ResultsSerializer class to handle the disk serialization.

This method creates a zip file containing: 1. The SQLite database file from the data container 2. A metadata.json file with the survey, created\_columns, and other non-data info 3. The cache data if present

**Args:**

filepath: Path where the zip file should be saved

**Raises:**

ResultsError: If there’s an error during serialization

> #### to\_docx(*filename: str | None = None*, *remove\_prefix: bool = False*, *pretty\_labels: dict | None = None*) → [FileStore](/en/latest/filestore#edsl.scenarios.FileStore "edsl.scenarios.FileStore")[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl.py)

Export the results to a FileStore instance containing DOCX data.

Each row of the dataset will be rendered on its own page, with a 2-column table that lists the keys and associated values for that observation.

> #### to\_excel(*filename: str | None = None*, *remove\_prefix: bool = False*, *pretty\_labels: dict | None = None*, *sheet\_name: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Export the results to a FileStore instance containing Excel data.

> #### to\_json()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Serialize this object to a JSON string.

**Returns:**

str: A JSON string representation of the object

> #### to\_jsonl(*filename: str | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Export the results to a FileStore instance containing JSONL data.

> #### to\_list(*flatten=False*, *remove\_none=False*, *unzipped=False*) → list\[list][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a list of lists.

**Parameters:**

* **flatten** – Whether to flatten the list of lists.
* **remove\_none** – Whether to remove None values from the list.

```python theme={null}
>>> from edsl.results import Results
>>> Results.example().select('how_feeling', 'how_feeling_yesterday')
Dataset([{'answer.how_feeling': ['OK', 'Great', 'Terrible', 'OK']}, {'answer.how_feeling_yesterday': ['Great', 'Good', 'OK', 'Terrible']}])
```

```python theme={null}
>>> Results.example().select('how_feeling', 'how_feeling_yesterday').to_list()
[('OK', 'Great'), ('Great', 'Good'), ('Terrible', 'OK'), ('OK', 'Terrible')]
```

```python theme={null}

>>> r = Results.example()
>>> r.select('how_feeling').to_list()
['OK', 'Great', 'Terrible', 'OK']
```

```python theme={null}
>>> from edsl.dataset import Dataset
>>> Dataset([{'a.b': [[1, 9], 2, 3, 4]}]).select('a.b').to_list(flatten = True)
[1, 9, 2, 3, 4]
```

```python theme={null}
>>> from edsl.dataset import Dataset
>>> # Testing to_list flatten with multiple columns raises DatasetValueError - tested in unit tests
```

> #### to\_pandas(*remove\_prefix: bool = False*, *lists\_as\_strings=False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a pandas DataFrame, ensuring that lists remain as lists.

**Args:**

remove\_prefix: Whether to remove the prefix from the column names. lists\_as\_strings: Whether to convert lists to strings.

**Returns:**

A pandas DataFrame.

> #### to\_polars(*remove\_prefix: bool = False*, *lists\_as\_strings=False*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a Polars DataFrame.

**Args:**

remove\_prefix: Whether to remove the prefix from the column names. lists\_as\_strings: Whether to convert lists to strings.

**Returns:**

A Polars DataFrame.

> #### to\_scenario\_list(*remove\_prefix: bool = True*) → list\[dict][\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a list of dictionaries, one per scenario.

**Parameters:**

**remove\_prefix** – Whether to remove the prefix from the column names.

```python theme={null}
>>> from edsl.results import Results
>>> r = Results.example()
>>> r.select('how_feeling').to_scenario_list()
ScenarioList([Scenario({'how_feeling': 'OK'}), Scenario({'how_feeling': 'Great'}), Scenario({'how_feeling': 'Terrible'}), Scenario({'how_feeling': 'OK'})])
```

> #### to\_sqlite(*filename: str | None = None*, *remove\_prefix: bool = False*, *pretty\_labels: dict | None = None*, *table\_name: str = 'results'*, *if\_exists: str = 'replace'*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Export the results to a SQLite database file.

> #### to\_yaml(*add\_edsl\_version=False*, *filename: str = None*) → str | None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the object to YAML format.

Serializes the object to YAML format and optionally writes it to a file.

**Args:**

add\_edsl\_version: Whether to include EDSL version information filename: If provided, write the YAML to this file path

**Returns:**

str: The YAML string representation if no filename is provided None: If written to file

> #### tree(*node\_order: List\[str] | None = None*)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Convert the results to a Tree.

**Args:**

node\_order: The order of the nodes.

**Returns:**

A Tree object.

> #### unpack\_list(*field: str*, *new\_names: List\[str] | None = None*, *keep\_original: bool = True*) → [Dataset](/en/latest/dataset#dataset-methods)[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Unpack list columns into separate columns with provided names or numeric suffixes.

For example, if a dataset contains: \[\{'data': \[\[1, 2, 3], \[4, 5, 6]], 'other': \['x', 'y']}]

After d.unpack\_list('data'), it should become: \[\{'other': \['x', 'y'], 'data\_1': \[1, 4], 'data\_2': \[2, 5], 'data\_3': \[3, 6]}]

> **Args:**

field: The field containing lists to unpack new\_names: Optional list of names for the unpacked fields. If None, uses numeric suffixes. keep\_original: If True, keeps the original field in the dataset

> **Returns:**

A new Dataset with unpacked columns

> **Examples:**

```python theme={null}
>>> from edsl.dataset import Dataset
>>> d = Dataset([{'data': [[1, 2, 3], [4, 5, 6]]}])
>>> d.unpack_list('data')
Dataset([{'data': [[1, 2, 3], [4, 5, 6]]}, {'data_1': [1, 4]}, {'data_2': [2, 5]}, {'data_3': [3, 6]}])
```

```python theme={null}
>>> d.unpack_list('data', new_names=['first', 'second', 'third'])
Dataset([{'data': [[1, 2, 3], [4, 5, 6]]}, {'first': [1, 4]}, {'second': [2, 5]}, {'third': [3, 6]}])
```

> #### values()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get the values in the object’s dictionary representation.

**Returns:**

set: A set containing all the values in the object

> #### view() → None[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

View the results in a Jupyter notebook.

> #### yaml()[\[source\]](https://github.com/expectedparrot/edsl/blob/main/edsl/results.py)

Get a formatted YAML representation of this object.

**Returns:**

DisplayYAML: A displayable YAML representation
