likingInitiative 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kianté Fernandez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: likingInitiative
3
+ Version: 0.2.1
4
+ Summary: The Liking Rating Database in Python
5
+ Author: Kianté Fernandez
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/liking-initiative/likingInitiative-py
8
+ Project-URL: Source, https://github.com/liking-initiative/likingInitiative-py
9
+ Project-URL: Issues, https://github.com/liking-initiative/likingInitiative-py/issues
10
+ Project-URL: Changelog, https://github.com/liking-initiative/likingInitiative-py/blob/main/CHANGELOG.md
11
+ Project-URL: Data, https://doi.org/10.5281/zenodo.22216442
12
+ Keywords: psychology,decision-making,open-data,preference,liking
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Scientific/Engineering
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: polars>=0.20
29
+ Requires-Dist: requests>=2.28
30
+ Requires-Dist: platformdirs>=3.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7; extra == "dev"
33
+ Requires-Dist: ruff>=0.5; extra == "dev"
34
+ Requires-Dist: build; extra == "dev"
35
+ Requires-Dist: twine; extra == "dev"
36
+ Dynamic: license-file
37
+
38
+ # likingInitiative — Python
39
+
40
+ [![CI](https://github.com/liking-initiative/likingInitiative-py/actions/workflows/ci.yml/badge.svg)](https://github.com/liking-initiative/likingInitiative-py/actions/workflows/ci.yml)
41
+ [![DOI](https://img.shields.io/badge/data%20DOI-10.5281%2Fzenodo.22216442-blue)](https://doi.org/10.5281/zenodo.22216442)
42
+
43
+ The Liking Rating Database in Python: subjective liking ratings from
44
+ published decision-making studies, as [polars](https://pola.rs) frames.
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install git+https://github.com/liking-initiative/likingInitiative-py
50
+ ```
51
+
52
+ Requires Python 3.9 or newer. Data is downloaded from Zenodo on first use and
53
+ cached locally; no account or token is needed.
54
+
55
+ ## Use
56
+
57
+ ```python
58
+ import likingInitiative
59
+
60
+ likingInitiative.list_datasets() # 59 datasets
61
+ likingInitiative.list_studies() # 38 studies
62
+ likingInitiative.list_items() # 2,217 stimuli
63
+
64
+ d = likingInitiative.get_dataset("leeholyoak2021")
65
+ d.data # polars DataFrame
66
+ d.scale # (1.0, 100.0)
67
+ d.timepoints # [1, 2, 3]
68
+ print(d.cite())
69
+
70
+ likingInitiative.get_dataset(["leeholyoak2021", "leehare2023exp2"]).data # stacked
71
+ ```
72
+
73
+ ### One item across every study that used it
74
+
75
+ The cross-study view — the thing this database is built for:
76
+
77
+ ```python
78
+ k = likingInitiative.get_item("kitkat") # 1,626 ratings across 25 datasets
79
+ k.by_dataset() # mean / sd / median per study, 0-1 scale
80
+ ```
81
+
82
+ ### The whole corpus
83
+
84
+ ```python
85
+ db = likingInitiative.load_database()
86
+ db["ratings"] # 759,399 rows
87
+ ```
88
+
89
+ ## Two things to get right
90
+
91
+ **Cross-study comparisons must use `normalized_rating`.** Studies use
92
+ different response scales (0–4, 1–100, 1–870, willingness-to-pay in dollars),
93
+ so raw `rating` values are not comparable. `normalized_rating` is
94
+ `(rating − scale_min) / (scale_max − scale_min)` and always lies in 0–1.
95
+
96
+ **Subject ids are unique only within a dataset.** Subject `"12"` in two
97
+ datasets is two different people — key on `(dataset_code, subject_id)`.
98
+
99
+ ## Repeated rating phases
100
+
101
+ Six datasets repeat the whole rating phase (`chenhol1`, `chenhol2`,
102
+ `crosswebb`, `hamesmcc`, `leehare2023exp2`, `leeholyoak2021`), so
103
+ `(subject_id, item_id)` alone is not unique for them:
104
+
105
+ ```python
106
+ d = likingInitiative.get_dataset("leeholyoak2021") # phases 1, 2, 3
107
+ d.data.group_by("timepoint").agg(pl.col("normalized_rating").mean())
108
+
109
+ likingInitiative.get_dataset("leeholyoak2021", timepoint=2) # one phase
110
+ ```
111
+
112
+ `get_item()` uses each dataset's first phase only, so a repeated-phase study
113
+ does not carry extra weight in a cross-study comparison.
114
+
115
+ ## Versions and caching
116
+
117
+ Data comes from versioned release files, not a live service, so a pinned
118
+ version returns the same rows however long from now.
119
+
120
+ ```python
121
+ likingInitiative.release_info() # version, date, counts, migrations applied
122
+ likingInitiative.get_dataset("leeholyoak2021", version="1.6.2") # pin it
123
+ likingInitiative.cache_info(); likingInitiative.clear_cache()
124
+ ```
125
+
126
+ Set `LIKING_INITIATIVE_RELEASE_DIR` to a directory built by
127
+ `scripts/build_release.py` to work against an unreleased build.
128
+
129
+ ## API
130
+
131
+ | Function | Returns |
132
+ |----------|---------|
133
+ | `list_studies()` / `list_datasets()` / `list_items()` | catalogue frames |
134
+ | `get_dataset(code, version, timepoint)` | `Dataset` — `.data`, `.metadata`, `.cite()` |
135
+ | `get_item(name, version)` | `Item` — `.data`, `.by_dataset()`, `.cite()` |
136
+ | `load_database(version)` | dict of frames |
137
+ | `cite(x)` / `bibtex(x)` | citation text |
138
+ | `release_info()` / `cache_info()` / `clear_cache()` | housekeeping |
139
+
140
+ ## Citation
141
+
142
+ Please cite the database and the studies whose data you use. `cite()` with no
143
+ argument returns the database citation; `cite(d)` returns a study's.
144
+
145
+ > Fernandez, K., Goyal, S., & Krajbich, I. (2026). The Liking Initiative: a
146
+ > database of subjective evaluation ratings for decision-making research
147
+ > [Data set]. Zenodo. https://doi.org/10.5281/zenodo.22216442
148
+
149
+ That is the concept DOI, which always resolves to the newest version. To name
150
+ the exact bytes an analysis ran on, cite the version DOI that Zenodo lists for
151
+ the version `release_info()` reports.
152
+
153
+ ## License
154
+
155
+ MIT. The underlying data remain subject to the terms of the original
156
+ publications.
@@ -0,0 +1,119 @@
1
+ # likingInitiative — Python
2
+
3
+ [![CI](https://github.com/liking-initiative/likingInitiative-py/actions/workflows/ci.yml/badge.svg)](https://github.com/liking-initiative/likingInitiative-py/actions/workflows/ci.yml)
4
+ [![DOI](https://img.shields.io/badge/data%20DOI-10.5281%2Fzenodo.22216442-blue)](https://doi.org/10.5281/zenodo.22216442)
5
+
6
+ The Liking Rating Database in Python: subjective liking ratings from
7
+ published decision-making studies, as [polars](https://pola.rs) frames.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pip install git+https://github.com/liking-initiative/likingInitiative-py
13
+ ```
14
+
15
+ Requires Python 3.9 or newer. Data is downloaded from Zenodo on first use and
16
+ cached locally; no account or token is needed.
17
+
18
+ ## Use
19
+
20
+ ```python
21
+ import likingInitiative
22
+
23
+ likingInitiative.list_datasets() # 59 datasets
24
+ likingInitiative.list_studies() # 38 studies
25
+ likingInitiative.list_items() # 2,217 stimuli
26
+
27
+ d = likingInitiative.get_dataset("leeholyoak2021")
28
+ d.data # polars DataFrame
29
+ d.scale # (1.0, 100.0)
30
+ d.timepoints # [1, 2, 3]
31
+ print(d.cite())
32
+
33
+ likingInitiative.get_dataset(["leeholyoak2021", "leehare2023exp2"]).data # stacked
34
+ ```
35
+
36
+ ### One item across every study that used it
37
+
38
+ The cross-study view — the thing this database is built for:
39
+
40
+ ```python
41
+ k = likingInitiative.get_item("kitkat") # 1,626 ratings across 25 datasets
42
+ k.by_dataset() # mean / sd / median per study, 0-1 scale
43
+ ```
44
+
45
+ ### The whole corpus
46
+
47
+ ```python
48
+ db = likingInitiative.load_database()
49
+ db["ratings"] # 759,399 rows
50
+ ```
51
+
52
+ ## Two things to get right
53
+
54
+ **Cross-study comparisons must use `normalized_rating`.** Studies use
55
+ different response scales (0–4, 1–100, 1–870, willingness-to-pay in dollars),
56
+ so raw `rating` values are not comparable. `normalized_rating` is
57
+ `(rating − scale_min) / (scale_max − scale_min)` and always lies in 0–1.
58
+
59
+ **Subject ids are unique only within a dataset.** Subject `"12"` in two
60
+ datasets is two different people — key on `(dataset_code, subject_id)`.
61
+
62
+ ## Repeated rating phases
63
+
64
+ Six datasets repeat the whole rating phase (`chenhol1`, `chenhol2`,
65
+ `crosswebb`, `hamesmcc`, `leehare2023exp2`, `leeholyoak2021`), so
66
+ `(subject_id, item_id)` alone is not unique for them:
67
+
68
+ ```python
69
+ d = likingInitiative.get_dataset("leeholyoak2021") # phases 1, 2, 3
70
+ d.data.group_by("timepoint").agg(pl.col("normalized_rating").mean())
71
+
72
+ likingInitiative.get_dataset("leeholyoak2021", timepoint=2) # one phase
73
+ ```
74
+
75
+ `get_item()` uses each dataset's first phase only, so a repeated-phase study
76
+ does not carry extra weight in a cross-study comparison.
77
+
78
+ ## Versions and caching
79
+
80
+ Data comes from versioned release files, not a live service, so a pinned
81
+ version returns the same rows however long from now.
82
+
83
+ ```python
84
+ likingInitiative.release_info() # version, date, counts, migrations applied
85
+ likingInitiative.get_dataset("leeholyoak2021", version="1.6.2") # pin it
86
+ likingInitiative.cache_info(); likingInitiative.clear_cache()
87
+ ```
88
+
89
+ Set `LIKING_INITIATIVE_RELEASE_DIR` to a directory built by
90
+ `scripts/build_release.py` to work against an unreleased build.
91
+
92
+ ## API
93
+
94
+ | Function | Returns |
95
+ |----------|---------|
96
+ | `list_studies()` / `list_datasets()` / `list_items()` | catalogue frames |
97
+ | `get_dataset(code, version, timepoint)` | `Dataset` — `.data`, `.metadata`, `.cite()` |
98
+ | `get_item(name, version)` | `Item` — `.data`, `.by_dataset()`, `.cite()` |
99
+ | `load_database(version)` | dict of frames |
100
+ | `cite(x)` / `bibtex(x)` | citation text |
101
+ | `release_info()` / `cache_info()` / `clear_cache()` | housekeeping |
102
+
103
+ ## Citation
104
+
105
+ Please cite the database and the studies whose data you use. `cite()` with no
106
+ argument returns the database citation; `cite(d)` returns a study's.
107
+
108
+ > Fernandez, K., Goyal, S., & Krajbich, I. (2026). The Liking Initiative: a
109
+ > database of subjective evaluation ratings for decision-making research
110
+ > [Data set]. Zenodo. https://doi.org/10.5281/zenodo.22216442
111
+
112
+ That is the concept DOI, which always resolves to the newest version. To name
113
+ the exact bytes an analysis ran on, cite the version DOI that Zenodo lists for
114
+ the version `release_info()` reports.
115
+
116
+ ## License
117
+
118
+ MIT. The underlying data remain subject to the terms of the original
119
+ publications.
@@ -0,0 +1,64 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "likingInitiative"
7
+ version = "0.2.1"
8
+ description = "The Liking Rating Database in Python"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Kianté Fernandez" }]
13
+ keywords = ["psychology", "decision-making", "open-data", "preference", "liking"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Science/Research",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Scientific/Engineering",
26
+ "Typing :: Typed",
27
+ ]
28
+ dependencies = [
29
+ "polars>=0.20",
30
+ "requests>=2.28",
31
+ "platformdirs>=3.0",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = ["pytest>=7", "ruff>=0.5", "build", "twine"]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/liking-initiative/likingInitiative-py"
39
+ Source = "https://github.com/liking-initiative/likingInitiative-py"
40
+ Issues = "https://github.com/liking-initiative/likingInitiative-py/issues"
41
+ Changelog = "https://github.com/liking-initiative/likingInitiative-py/blob/main/CHANGELOG.md"
42
+ Data = "https://doi.org/10.5281/zenodo.22216442"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ likingInitiative = ["py.typed"]
49
+
50
+ [tool.ruff]
51
+ line-length = 100
52
+ target-version = "py39"
53
+
54
+ [tool.ruff.lint]
55
+ # Pinned explicitly so a newer ruff on CI cannot widen the rule set. The
56
+ # package is deliberately camelCase (it matches the R package), so
57
+ # pep8-naming's module-name rule is not selected.
58
+ select = ["E", "F", "W", "I"]
59
+
60
+ [tool.ruff.lint.isort]
61
+ known-first-party = ["likingInitiative"]
62
+
63
+ [tool.pytest.ini_options]
64
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,60 @@
1
+ """
2
+ likingInitiative — the Liking Rating Database in Python.
3
+
4
+ Subjective liking ratings from published decision-making studies, as polars
5
+ frames.
6
+
7
+ import likingInitiative
8
+
9
+ likingInitiative.list_datasets() # the catalogue
10
+ d = likingInitiative.get_dataset("leeholyoak2021") # one study's ratings
11
+ d.data # polars DataFrame
12
+ d.cite()
13
+
14
+ likingInitiative.get_item("kitkat") # one item, every study
15
+ likingInitiative.load_database() # the whole corpus
16
+
17
+ Data comes from versioned release files, not a live service, so a pinned
18
+ version returns the same rows however long from now. Assets are cached
19
+ locally after first download — see ``cache_info()``.
20
+
21
+ Two things to get right:
22
+
23
+ * **Cross-study comparisons must use ``normalized_rating``.** Response scales
24
+ differ between studies (0-4, 1-100, 1-870, willingness-to-pay in dollars),
25
+ so raw ``rating`` values are not comparable. ``normalized_rating`` is
26
+ ``(rating - scale_min) / (scale_max - scale_min)`` and always lies in 0-1.
27
+ * **Subject ids are unique only within a dataset.** Subject "12" in two
28
+ datasets is two different people; key on ``(dataset_code, subject_id)``.
29
+ """
30
+ from .catalog import list_datasets, list_items, list_studies, release_info
31
+ from .citation import bibtex, cite
32
+ from .database import load_database
33
+ from .dataset import Dataset, get_dataset
34
+ from .item import Item, get_item
35
+ from .release import (
36
+ LikingInitiativeError,
37
+ cache_info,
38
+ clear_cache,
39
+ resolve_version,
40
+ )
41
+
42
+ __all__ = [
43
+ "list_studies",
44
+ "list_datasets",
45
+ "list_items",
46
+ "get_dataset",
47
+ "get_item",
48
+ "load_database",
49
+ "cite",
50
+ "bibtex",
51
+ "release_info",
52
+ "resolve_version",
53
+ "cache_info",
54
+ "clear_cache",
55
+ "Dataset",
56
+ "Item",
57
+ "LikingInitiativeError",
58
+ ]
59
+
60
+ __version__ = "0.2.1"
@@ -0,0 +1,61 @@
1
+ """The release catalogue: studies, datasets, and items."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any, Dict
5
+
6
+ import polars as pl
7
+
8
+ from .release import LikingInitiativeError, asset_path, load_catalog
9
+
10
+
11
+ def release_info(version: str = "latest") -> Dict[str, Any]:
12
+ """Version, date, and headline counts for the release in use."""
13
+ return load_catalog(version)["release"]
14
+
15
+
16
+ def list_studies(version: str = "latest") -> pl.DataFrame:
17
+ """Every publication in the database."""
18
+ return pl.DataFrame(load_catalog(version)["studies"])
19
+
20
+
21
+ def list_datasets(version: str = "latest") -> pl.DataFrame:
22
+ """Every dataset, with its study, response scale, and size.
23
+
24
+ ``timepoints`` lists the rating phases a dataset holds; all but two have
25
+ a single phase.
26
+ """
27
+ rows = load_catalog(version)["datasets"]
28
+ frame = pl.DataFrame(rows, infer_schema_length=None)
29
+ return frame.with_columns(
30
+ pl.col("timepoints").list.len().alias("n_timepoints")
31
+ )
32
+
33
+
34
+ def list_items(version: str = "latest") -> pl.DataFrame:
35
+ """Every stimulus, with the number of datasets it appears in."""
36
+ return pl.read_csv(
37
+ asset_path("items.tsv", version),
38
+ separator="\t",
39
+ schema_overrides={"item_id": pl.String, "name": pl.String},
40
+ )
41
+
42
+
43
+ def dataset_entry(code: str, version: str = "latest") -> Dict[str, Any]:
44
+ """Look up one dataset's catalogue entry by code, id, or unique prefix."""
45
+ datasets = load_catalog(version)["datasets"]
46
+ lowered = code.lower()
47
+
48
+ for d in datasets:
49
+ if d["dataset_code"].lower() == lowered or d["dataset_id"] == code:
50
+ return d
51
+
52
+ prefix = [d for d in datasets if d["dataset_code"].lower().startswith(lowered)]
53
+ if len(prefix) == 1:
54
+ return prefix[0]
55
+ if len(prefix) > 1:
56
+ names = ", ".join(sorted(d["dataset_code"] for d in prefix))
57
+ raise LikingInitiativeError(f"'{code}' is ambiguous; matches: {names}")
58
+
59
+ raise LikingInitiativeError(
60
+ f"no dataset named '{code}'. Use likingInitiative.list_datasets() to see the catalogue."
61
+ )
@@ -0,0 +1,66 @@
1
+ """Citations for the database and for the studies it draws on."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any, Optional
5
+
6
+ # The concept DOI, which Zenodo resolves to the newest version. Cite this to
7
+ # mean "the database"; cite the version DOI that release_info() reports when an
8
+ # analysis needs to name the exact bytes it ran on.
9
+ DATABASE_DOI = "10.5281/zenodo.22216442"
10
+
11
+ DATABASE_CITATION = (
12
+ "Fernandez, K., Goyal, S., & Krajbich, I. (2026). The Liking Initiative: a "
13
+ "database of subjective evaluation ratings for decision-making research "
14
+ "[Data set]. Zenodo. https://doi.org/" + DATABASE_DOI
15
+ )
16
+
17
+
18
+ def _entry(x: Any) -> Optional[dict]:
19
+ """Accept a Dataset/Item object or a raw catalogue dict."""
20
+ if x is None:
21
+ return None
22
+ if isinstance(x, dict):
23
+ return x
24
+ return getattr(x, "metadata", None)
25
+
26
+
27
+ def cite(x: Any = None) -> str:
28
+ """Citation for a dataset's source publication.
29
+
30
+ Returns only that study's citation. Appending the database's every time
31
+ would be noise in a loop over datasets -- call ``cite()`` with no argument
32
+ for the database's own citation, and please include it alongside whichever
33
+ studies you use.
34
+ """
35
+ entry = _entry(x)
36
+ if entry is None:
37
+ return DATABASE_CITATION
38
+
39
+ citation = entry.get("citation") or entry.get("study_name") or ""
40
+ doi = entry.get("paper_doi")
41
+ if doi:
42
+ citation = f"{citation} https://doi.org/{doi}"
43
+ return citation
44
+
45
+
46
+ def bibtex(x: Any) -> str:
47
+ """A BibTeX entry for a dataset's source publication."""
48
+ entry = _entry(x)
49
+ if entry is None:
50
+ raise ValueError("bibtex() needs a dataset or item")
51
+
52
+ authors = " and ".join(
53
+ a.strip() for a in (entry.get("authors") or "").split(";") if a.strip()
54
+ )
55
+ year = entry.get("year") or ""
56
+ first = (entry.get("first_author") or "study").lower().replace(" ", "")
57
+ fields = [
58
+ f" author = {{{authors}}}",
59
+ f" title = {{{entry.get('study_name', '')}}}",
60
+ f" year = {{{year}}}",
61
+ ]
62
+ if entry.get("journal"):
63
+ fields.append(f" journal = {{{entry['journal']}}}")
64
+ if entry.get("paper_doi"):
65
+ fields.append(f" doi = {{{entry['paper_doi']}}}")
66
+ return "@article{" + f"{first}{year}" + ",\n" + ",\n".join(fields) + "\n}"
@@ -0,0 +1,46 @@
1
+ """load_database() — the whole corpus in one call."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Dict
5
+
6
+ import polars as pl
7
+
8
+ from .catalog import list_items, list_studies
9
+ from .release import asset_path, load_catalog
10
+
11
+ _cache: Dict[str, Dict[str, pl.DataFrame]] = {}
12
+
13
+ _SCHEMA = {
14
+ "subject_id": pl.String,
15
+ "item_id": pl.String,
16
+ "item_name": pl.String,
17
+ "dataset_code": pl.String,
18
+ "study_id": pl.String,
19
+ }
20
+
21
+
22
+ def load_database(version: str = "latest") -> Dict[str, pl.DataFrame]:
23
+ """Every rating, plus the study, dataset and item tables.
24
+
25
+ Returns ``{"ratings", "studies", "datasets", "items"}``. Held in memory
26
+ after the first call, so repeated use is free.
27
+ """
28
+ resolved = load_catalog(version)["release"]["version"]
29
+ if resolved in _cache:
30
+ return _cache[resolved]
31
+
32
+ ratings = pl.read_csv(
33
+ asset_path("ratings.tsv.gz", version),
34
+ separator="\t",
35
+ schema_overrides=_SCHEMA,
36
+ )
37
+ datasets = pl.DataFrame(load_catalog(version)["datasets"], infer_schema_length=None)
38
+
39
+ out = {
40
+ "ratings": ratings,
41
+ "studies": list_studies(version),
42
+ "datasets": datasets,
43
+ "items": list_items(version),
44
+ }
45
+ _cache[resolved] = out
46
+ return out