ImperialCollegeLondon / ImperialCollegeLondon/virtual_ecosystem
Aligning functional group loading methods
@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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.