diff --git a/cereja/__init__.py b/cereja/__init__.py index c62380d..cb192b7 100644 --- a/cereja/__init__.py +++ b/cereja/__init__.py @@ -47,7 +47,7 @@ from . import experimental from ._requests import request -VERSION = "1.4.6.final.0" +VERSION = "1.4.7.final.0" __version__ = get_version_pep440_compliant(VERSION) diff --git a/cereja/file/_io.py b/cereja/file/_io.py index d625925..afcd190 100644 --- a/cereja/file/_io.py +++ b/cereja/file/_io.py @@ -527,12 +527,11 @@ class _JsonIO(_FileIO): _is_byte: bool = False _only_read = False _ext_allowed = ('.json',) - indent = 4 + indent = False ensure_ascii = False - def __init__(self, path_: Path, **kwargs): - if 'indent' in kwargs: - self.indent = kwargs.pop('indent') + def __init__(self, path_: Path, indent=False, **kwargs): + self.indent = indent if 'ensure_ascii' in kwargs: self.ensure_ascii = kwargs.pop('ensure_ascii') super().__init__(path_, **kwargs) @@ -541,7 +540,7 @@ def _parse_fp(self, fp: TextIO) -> dict: return json.load(fp) def _save_fp(self, fp): - json.dump(self._data, fp, indent=self.indent, ensure_ascii=self.ensure_ascii) + json.dump(self._data, fp, indent=4 if self.indent else None, ensure_ascii=self.ensure_ascii) def items(self) -> ItemsView: return self._data.items() diff --git a/cereja/utils/_utils.py b/cereja/utils/_utils.py index 3f38f1f..d948b0a 100644 --- a/cereja/utils/_utils.py +++ b/cereja/utils/_utils.py @@ -20,12 +20,13 @@ import gc import math import time +from collections import OrderedDict from importlib import import_module import importlib import sys import types import random -from typing import Any, Union, List, Tuple, Sequence, Iterable +from typing import Any, Union, List, Tuple, Sequence, Iterable, Dict import logging import itertools from copy import copy @@ -38,7 +39,8 @@ 'get_implements', 'get_instances_of', 'import_string', 'install_if_not', 'invert_dict', 'logger_level', 'module_references', 'set_log_level', 'time_format', 'string_to_literal', 'rescale_values', 'Source', 'sample', 'obj_repr', 'truncate', 'type_table_of', - 'list_methods', 'can_do', 'chunk', 'is_iterable', 'is_sequence', 'is_numeric_sequence', 'clipboard'] + 'list_methods', 'can_do', 'chunk', 'is_iterable', 'is_sequence', 'is_numeric_sequence', 'clipboard', + 'sort_dict', 'dict_append'] logger = logging.getLogger(__name__) @@ -750,3 +752,45 @@ def is_numeric_sequence(obj: Sequence[Number]) -> bool: except (TypeError, ValueError): return False return True + + +def sort_dict(obj: dict, by_keys=False, by_values=False, reverse=False, by_len_values=False, func_values=None, + func_keys=None) -> OrderedDict: + func_values = (lambda v: len(v) if by_len_values else v) if func_values is None else func_values + func_keys = (lambda k: k) if func_keys is None else func_keys + + key_func = None + if (by_keys and by_values) or (not by_keys and not by_values): + key_func = (lambda x: (func_keys(x[0]), func_values(x[1]))) + elif by_keys: + key_func = (lambda x: func_keys(x[0])) + elif by_values: + key_func = (lambda x: func_values(x[1])) + return OrderedDict(sorted(obj.items(), key=key_func, reverse=reverse)) + + +def dict_append(obj: Dict[Any, list], key, *v): + """ + Add items to a key, if the key is not in the dictionary it will be created with a list and the value sent. + + e.g: + + >>> import cereja as cj + >>> my_dict = {} + >>> cj.utils.dict_append(my_dict, 'key_eg', 1,2,3,4,5,6) + {'key_eg': [1, 2, 3, 4, 5, 6]} + >>> cj.utils.dict_append(my_dict, 'key_eg', [1,2]) + {'key_eg': [1, 2, 3, 4, 5, 6, [1, 2]]} + + @param obj: Any dict of list values + @param key: dict key + @param v: all values after key + @return: + """ + assert isinstance(obj, dict), 'Error on append values. Please send a dict object.' + if key not in obj: + obj[key] = [] + assert isinstance(obj[key], list), f"Error on append values. Value of key '{key}' isn't a list." + for i in v: + obj[key].append(i) + return obj diff --git a/tests/testsutils.py b/tests/testsutils.py index 4b8a26e..9799ac9 100644 --- a/tests/testsutils.py +++ b/tests/testsutils.py @@ -1,4 +1,5 @@ import unittest +from collections import OrderedDict from cereja import utils, rescale_values from cereja.utils.decorators import singleton @@ -36,8 +37,8 @@ def test_install_if_not(self): def test_invert_dict(self): data = {"s": 0, "y": 1, "v": 2, "l": 3, "i": 4, "p": 5, "b": 6, "z": 7, "c": 8, "a": 9, "k": 10, "e": 11, "d": 12, "j": 13, "x": 14, "u": 15, "o" - : 16, "n": 17, "t": 18, "f": 19, "g": 20, "h": 21, "r": 22, "w": 23, "m": 24, "q": 25} - expected = {0: 's', 1: 'y', 2: 'v', 3: 'l', 4: 'i', 5: 'p', 6: 'b', 7: 'z', 8: 'c', 9: 'a', 10: 'k', 11: 'e', + : 16, "n": 17, "t": 18, "f": 19, "g": 20, "h": 21, "r": 22, "w": 23, "m": 24, "q": 25} + expected = {0: 's', 1: 'y', 2: 'v', 3: 'l', 4: 'i', 5: 'p', 6: 'b', 7: 'z', 8: 'c', 9: 'a', 10: 'k', 11: 'e', 12: 'd', 13: 'j', 14: 'x', 15: 'u', 16: 'o', 17: 'n', 18: 't', 19: 'f', 20: 'g', 21: 'h', 22: 'r', 23: 'w', 24: 'm', 25: 'q'} self.assertDictEqual(utils.invert_dict(data), expected) @@ -118,6 +119,28 @@ def test_truncate(self): def test_type_table_of(self): pass + def test_sort_dict(self): + val = {0: 1, 1: 2, 2: 1, 3: 4, 4: 1, 5: 43, 6: 1, 7: 10, 8: 22, 9: 0} + self.assertDictEqual(utils.sort_dict(val), OrderedDict( + [(0, 1), (1, 2), (2, 1), (3, 4), (4, 1), (5, 43), (6, 1), (7, 10), (8, 22), (9, 0)])) + self.assertDictEqual(utils.sort_dict(val, by_values=True), OrderedDict( + [(9, 0), (0, 1), (2, 1), (4, 1), (6, 1), (1, 2), (3, 4), (7, 10), (8, 22), (5, 43)])) + self.assertDictEqual(utils.sort_dict(val, by_values=True, reverse=True), OrderedDict( + [(5, 43), (8, 22), (7, 10), (3, 4), (1, 2), (0, 1), (2, 1), (4, 1), (6, 1), (9, 0)])) + + self.assertDictEqual(utils.sort_dict(val, by_keys=True), OrderedDict( + [(0, 1), (1, 2), (2, 1), (3, 4), (4, 1), (5, 43), (6, 1), (7, 10), (8, 22), (9, 0)])) + self.assertDictEqual(utils.sort_dict(val, by_keys=True, reverse=True), OrderedDict( + [(9, 0), (8, 22), (7, 10), (6, 1), (5, 43), (4, 1), (3, 4), (2, 1), (1, 2), (0, 1)])) + + def test_dict_append(self): + my_dict = {} + utils.dict_append(my_dict, 'key_eg', 1, 2, 3, 4, 5, 6) + self.assertDictEqual(my_dict, {'key_eg': [1, 2, 3, 4, 5, 6]}) + my_dict = utils.dict_append(my_dict, 'key_eg', [1, 2]) + + self.assertDictEqual(my_dict, {'key_eg': [1, 2, 3, 4, 5, 6, [1, 2]]}) + class CjTestTest(unittest.TestCase):