From f592e4dcbf2c2604482bc85179925ff19b1e43ac Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Tue, 27 Jun 2023 15:35:23 -0400 Subject: [PATCH 1/5] Fixed #449 --- docs/changelog.md | 4 ++++ peppy/_version.py | 2 +- peppy/project.py | 18 ++++++++++++++---- tests/test_Project.py | 9 ++++++--- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 22ea48b2..9bb8c811 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format. +## [0.35.6] -- 2023-06-27 +### Added +- `orient` argument to `to_dict` method + ## [0.35.5] -- 2023-03-27 ### Fixed - A [bug](https://github.com/pepkit/peppy/issues/435) with custom sample ids diff --git a/peppy/_version.py b/peppy/_version.py index 322d9f85..a51f1e97 100644 --- a/peppy/_version.py +++ b/peppy/_version.py @@ -1 +1 @@ -__version__ = "0.35.5" +__version__ = "0.35.6" diff --git a/peppy/project.py b/peppy/project.py index d16d470f..fdfac8d2 100644 --- a/peppy/project.py +++ b/peppy/project.py @@ -6,7 +6,7 @@ from collections.abc import Mapping from contextlib import suppress from logging import getLogger -from typing import Dict, Iterable, List, Tuple, Union +from typing import Dict, Iterable, List, Tuple, Union, Literal import numpy as np import pandas as pd @@ -227,21 +227,31 @@ def from_dict(self, pep_dictionary: dict) -> "Project": return self - def to_dict(self, expand: bool = False, extended: bool = False) -> dict: + def to_dict( + self, + expand: bool = False, + extended: bool = False, + orient: Literal[ + "dict", "list", "series", "split", "tight", "records", "index" + ] = "dict", + ) -> dict: """ Convert the Project object to a dictionary. :param bool expand: whether to expand the paths :param bool extended: whether to produce complete project dict (used to reinit the project) + :param Literal orient: orientation of the returned df :return dict: a dictionary representation of the Project object """ if extended: if self[SUBSAMPLE_DF_KEY] is not None: - sub_df = [sub_a.to_dict() for sub_a in self[SUBSAMPLE_DF_KEY]] + sub_df = [ + sub_a.to_dict(orient=orient) for sub_a in self[SUBSAMPLE_DF_KEY] + ] else: sub_df = None p_dict = { - SAMPLE_RAW_DICT_KEY: self[SAMPLE_DF_KEY].to_dict(), + SAMPLE_RAW_DICT_KEY: self[SAMPLE_DF_KEY].to_dict(orient=orient), CONFIG_KEY: self[CONFIG_KEY], SUBSAMPLE_RAW_DICT_KEY: sub_df, NAME_KEY: self[NAME_KEY], diff --git a/tests/test_Project.py b/tests/test_Project.py index b585e04a..35218300 100644 --- a/tests/test_Project.py +++ b/tests/test_Project.py @@ -553,13 +553,16 @@ def test_unequality(self, example_pep_cfg_path, example_pep_csv_path): p2 = Project(cfg=example_pep_csv_path) assert not p1 == p2 - @pytest.mark.parametrize("example_pep_cfg_path", ["append"], indirect=True) - def test_from_dict(self, example_pep_cfg_path): + @pytest.mark.parametrize( + "example_pep_cfg_path", ["append", "subtable2"], indirect=True + ) + @pytest.mark.parametrize("orient", ["dict", "record"]) + def test_from_dict(self, example_pep_cfg_path, orient): """ Test initializing project from dict """ p1 = Project(cfg=example_pep_cfg_path) - p1_dict = p1.to_dict(extended=True) + p1_dict = p1.to_dict(extended=True, orient=orient) del p1_dict["_config"]["sample_table"] p2 = Project().from_dict(p1_dict) assert p1 == p2 From 9b689359eac336c9e51d67ba2f4aad3db65860a6 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Wed, 28 Jun 2023 11:57:04 -0400 Subject: [PATCH 2/5] Reduced raw project to 3 items (config, samples, and subsamples) --- peppy/project.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/peppy/project.py b/peppy/project.py index fdfac8d2..a706bc22 100644 --- a/peppy/project.py +++ b/peppy/project.py @@ -214,11 +214,11 @@ def from_dict(self, pep_dictionary: dict) -> "Project": pd.DataFrame(sub_a) for sub_a in pep_dictionary[SUBSAMPLE_RAW_DICT_KEY] ] - if NAME_KEY in pep_dictionary: - self[NAME_KEY] = pep_dictionary[NAME_KEY] + if NAME_KEY in self[CONFIG_KEY]: + self[NAME_KEY] = self[CONFIG_KEY][NAME_KEY] - if DESC_KEY in pep_dictionary: - self[DESC_KEY] = pep_dictionary[DESC_KEY] + if DESC_KEY in self[CONFIG_KEY]: + self[DESC_KEY] = self[CONFIG_KEY][DESC_KEY] self.create_samples(modify=False if self[SAMPLE_TABLE_FILE_KEY] else True) self._sample_table = self._get_table_from_samples( @@ -250,12 +250,12 @@ def to_dict( ] else: sub_df = None + self[CONFIG_KEY][NAME_KEY] = self[NAME_KEY] + self[CONFIG_KEY][DESC_KEY] = self[DESC_KEY] p_dict = { SAMPLE_RAW_DICT_KEY: self[SAMPLE_DF_KEY].to_dict(orient=orient), - CONFIG_KEY: self[CONFIG_KEY], + CONFIG_KEY: self[CONFIG_KEY].to_dict(expand=expand), SUBSAMPLE_RAW_DICT_KEY: sub_df, - NAME_KEY: self[NAME_KEY], - DESC_KEY: self[DESC_KEY], } else: p_dict = self.config.to_dict(expand=expand) From 2dd67a6eb80504c2aaebfaec2dd4196f28bff8e0 Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Wed, 28 Jun 2023 11:58:26 -0400 Subject: [PATCH 3/5] fixed #442 --- peppy/const.py | 2 +- peppy/project.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/peppy/const.py b/peppy/const.py index bf6cc1b6..0f009a52 100644 --- a/peppy/const.py +++ b/peppy/const.py @@ -119,6 +119,6 @@ PEP_LATEST_VERSION = "2.1.0" SAMPLE_RAW_DICT_KEY = "_sample_dict" -SUBSAMPLE_RAW_DICT_KEY = "_subsample_dict" +SUBSAMPLE_RAW_LIST_KEY = "_subsample_list" __all__ = PROJECT_CONSTANTS + SAMPLE_CONSTANTS + OTHER_CONSTANTS diff --git a/peppy/project.py b/peppy/project.py index a706bc22..9e213641 100644 --- a/peppy/project.py +++ b/peppy/project.py @@ -57,7 +57,7 @@ SAMPLE_TABLE_INDEX_KEY, SUBSAMPLE_DF_KEY, SUBSAMPLE_NAME_ATTR, - SUBSAMPLE_RAW_DICT_KEY, + SUBSAMPLE_RAW_LIST_KEY, SUBSAMPLE_TABLE_INDEX_KEY, SUBSAMPLE_TABLES_FILE_KEY, ) @@ -208,11 +208,11 @@ def from_dict(self, pep_dictionary: dict) -> "Project": self[SAMPLE_DF_KEY] = pd.DataFrame(pep_dictionary[SAMPLE_RAW_DICT_KEY]) self[CONFIG_KEY] = pep_dictionary[CONFIG_KEY] - if SUBSAMPLE_RAW_DICT_KEY in pep_dictionary: - if pep_dictionary[SUBSAMPLE_RAW_DICT_KEY]: + if SUBSAMPLE_RAW_LIST_KEY in pep_dictionary: + if pep_dictionary[SUBSAMPLE_RAW_LIST_KEY]: self[SUBSAMPLE_DF_KEY] = [ pd.DataFrame(sub_a) - for sub_a in pep_dictionary[SUBSAMPLE_RAW_DICT_KEY] + for sub_a in pep_dictionary[SUBSAMPLE_RAW_LIST_KEY] ] if NAME_KEY in self[CONFIG_KEY]: self[NAME_KEY] = self[CONFIG_KEY][NAME_KEY] @@ -255,7 +255,7 @@ def to_dict( p_dict = { SAMPLE_RAW_DICT_KEY: self[SAMPLE_DF_KEY].to_dict(orient=orient), CONFIG_KEY: self[CONFIG_KEY].to_dict(expand=expand), - SUBSAMPLE_RAW_DICT_KEY: sub_df, + SUBSAMPLE_RAW_LIST_KEY: sub_df, } else: p_dict = self.config.to_dict(expand=expand) From 8cc24c9699bc3d708bc4f9d784378820cd10645b Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Wed, 28 Jun 2023 12:03:27 -0400 Subject: [PATCH 4/5] updated changelog --- docs/changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 9bb8c811..3ecc3822 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Added - `orient` argument to `to_dict` method +### Fixed +- The name of the raw subsample object to match the actual name (list). Commit: #442 + +### Changed +- Reduced the number of items returned in the to_dict(extended=True) method to 3, with the name and description now stored in the config key. + ## [0.35.5] -- 2023-03-27 ### Fixed - A [bug](https://github.com/pepkit/peppy/issues/435) with custom sample ids From a6c743e96c25c7b5c655f0fc21a63087140f459c Mon Sep 17 00:00:00 2001 From: Khoroshevskyi Date: Wed, 28 Jun 2023 12:21:08 -0400 Subject: [PATCH 5/5] fixed tests --- tests/test_Project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_Project.py b/tests/test_Project.py index 35218300..85a1c488 100644 --- a/tests/test_Project.py +++ b/tests/test_Project.py @@ -556,7 +556,7 @@ def test_unequality(self, example_pep_cfg_path, example_pep_csv_path): @pytest.mark.parametrize( "example_pep_cfg_path", ["append", "subtable2"], indirect=True ) - @pytest.mark.parametrize("orient", ["dict", "record"]) + @pytest.mark.parametrize("orient", ["dict", "records"]) def test_from_dict(self, example_pep_cfg_path, orient): """ Test initializing project from dict