ImperialCollegeLondon / ImperialCollegeLondon/virtual_ecosystem

Aligning functional group loading methods

Open
#305 0 comments 1 reaction 2 assignees View on GitHub

@TaranRallings is already working on this.

Since Sep 6, 2023.

Dominant language
Python
Stars
20
Forks
5
Avg merge
2d 1h
Merged PRs (30d)
34

Description

**Is your feature request related to a problem? Please describe.**

At the moment the `plants` and `animals` are using different input formats for defining functional groups:

* `animals` uses a CSV file and iterates over rows to create a dictionary of `animals.functional_group.FunctionalGroup` objects,
* `plants` uses the `toml` config files to pass in an array of tables of `ftypes` objects, which are use to create a `dict` like `Flora` object keying to `plants.functional_types.PlantFunctionalType` instances.

In both models, these form part of the model config (bit of a blurry line on data v config here) so we can try and align these a bit better.

The `toml` variant is useful in that:
* it _requires_ the arguments to the functional type/group class be set in the schema,
* and the inputs are then automatically validated against the model schema.

But a pain in that:
* it is harder and more error prone to write out
* and is less familiar for many users

**Describe the solution you'd like**

The JSON schema approach is probably where we should start - so update the `animal` model to do this - but then it would be good to also provide a shared approach to loading from CSV instead. So,

1. the config for either model could provide a table of `ftypes` _or_ an `ftypes_csv`.
2. If `ftypes` are used then they are already validated and can be converted into `FunctionalGroup/PlantFunctionalType`
3. if `ftypes_csv` is provided then a utility function should:
* load the csv file,
* iterate over the rows, applying the JSON schema for the model to validate the values
* create the `FunctionalGroup/PlantFunctionalType` from the validated inputs.

Something like:

```python
import csv

def load_csv_rows_to_dataclass(csv_path: Path, target_class: target_class, class_schema: dict) -> dict(target_class):
items = {}

with open(csv_path) as f:
dict_reader = csv.DictReader(f)

for row_dict in dict_reader:
# something clever with validating row_dict against the class schema
items[row_dict['name']] = target_class(**row_dict)

return items
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.