From a57f331e2f2d0b5fa388642e6097e533d2a16a7c Mon Sep 17 00:00:00 2001 From: david-salac Date: Fri, 12 Mar 2021 10:38:24 +0000 Subject: [PATCH 1/5] Start --- portable_spreadsheet/cell.py | 214 ++++++++++++++---- portable_spreadsheet/cell_indices.py | 16 +- .../cell_indices_templates.py | 2 +- 3 files changed, 180 insertions(+), 52 deletions(-) diff --git a/portable_spreadsheet/cell.py b/portable_spreadsheet/cell.py index 9bd2478..1424029 100644 --- a/portable_spreadsheet/cell.py +++ b/portable_spreadsheet/cell.py @@ -42,6 +42,8 @@ class Cell(object): variable defined by formulas. excel_data_validation (dict): Define data validation restriction based on xlsxwriter 'data_validation' possibilities. + compute_only_values (bool): If true, only values are computed and + no word is constructed. """ def __init__(self, row: Optional[int] = None, @@ -84,12 +86,16 @@ def __init__(self, self._excel_format: dict = {} self._description: Optional[str] = None self._excel_row_position: Optional[int] = None - - if words is not None: - self._constructing_words: WordConstructor = words + self.compute_only_values: bool = True + + if not self.compute_only_values: + if words is not None: + self._constructing_words: WordConstructor = words + else: + self._constructing_words: WordConstructor = \ + WordConstructor.init_from_new_cell(self) else: - self._constructing_words: WordConstructor = \ - WordConstructor.init_from_new_cell(self) + self._constructing_words: WordConstructor = None self._variable_words: WordConstructor = None self.excel_data_validation: dict = None @@ -290,6 +296,14 @@ def _compute_value(function: callable, # Maximally generic here is OK return CellValueError() + @staticmethod + def _construct_word(source: 'Cell', + function: callable, + *args) -> Optional[WordConstructor]: + if not source.compute_only_values: + return function(*args) + else: + return None # ===================================== # === BINARY OPERATORS: === @@ -304,7 +318,11 @@ def add(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a + b, a=self.value, b=other.value), - words=WordConstructor.add(self, other), + words=self._construct_word( + self, + WordConstructor.add, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -320,7 +338,11 @@ def subtract(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a - b, a=self.value, b=other.value), - words=WordConstructor.subtract(self, other), + words=self._construct_word( + self, + WordConstructor.subtract, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -336,7 +358,11 @@ def multiply(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a * b, a=self.value, b=other.value), - words=WordConstructor.multiply(self, other), + words=self._construct_word( + self, + WordConstructor.multiply, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -352,7 +378,11 @@ def divide(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a / b, a=self.value, b=other.value), - words=WordConstructor.divide(self, other), + words=self._construct_word( + self, + WordConstructor.divide, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -368,7 +398,11 @@ def modulo(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a % b, a=self.value, b=other.value), - words=WordConstructor.modulo(self, other), + words=self._construct_word( + self, + WordConstructor.modulo, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -384,7 +418,11 @@ def power(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a ** b, a=self.value, b=other.value), - words=WordConstructor.power(self, other), + words=self._construct_word( + self, + WordConstructor.power, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -400,7 +438,11 @@ def equalTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a == b, a=self.value, b=other.value), - words=WordConstructor.equalTo(self, other), + words=self._construct_word( + self, + WordConstructor.equalTo, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -416,7 +458,11 @@ def notEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a != b, a=self.value, b=other.value), - words=WordConstructor.notEqualTo(self, other), + words=self._construct_word( + self, + WordConstructor.notEqualTo, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -432,7 +478,11 @@ def greaterThan(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a > b, a=self.value, b=other.value), - words=WordConstructor.greaterThan(self, other), + words=self._construct_word( + self, + WordConstructor.greaterThan, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -448,7 +498,11 @@ def greaterThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a >= b, a=self.value, b=other.value), - words=WordConstructor.greaterThanOrEqualTo(self, other), + words=self._construct_word( + self, + WordConstructor.greaterThanOrEqualTo, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -464,7 +518,11 @@ def lessThan(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a < b, a=self.value, b=other.value), - words=WordConstructor.lessThan(self, other), + words=self._construct_word( + self, + WordConstructor.lessThan, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -480,7 +538,11 @@ def lessThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a <= b, a=self.value, b=other.value), - words=WordConstructor.lessThanOrEqualTo(self, other), + words=self._construct_word( + self, + WordConstructor.lessThanOrEqualTo, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -496,7 +558,11 @@ def logicalConjunction(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a and b, a=self.value, b=other.value), - words=WordConstructor.logicalConjunction(self, other), + words=self._construct_word( + self, + WordConstructor.logicalConjunction, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -512,7 +578,11 @@ def logicalDisjunction(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: a or b, a=self.value, b=other.value), - words=WordConstructor.logicalDisjunction(self, other), + words=self._construct_word( + self, + WordConstructor.logicalDisjunction, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -528,7 +598,11 @@ def concatenate(self, other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=self._compute_value(lambda a, b: str(a.value) + str(b.value), a=self, b=other), - words=WordConstructor.concatenate(self, other), + words=self._construct_word( + self, + WordConstructor.concatenate, + self, other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -798,7 +872,9 @@ def _aggregate_fun( cell_value = CellValueError() return Cell(value=cell_value, - words=WordConstructor.aggregation( + words=Cell._construct_word( + cell_start, + WordConstructor.aggregation, cell_start, cell_end, grammar_method ), cell_indices=cell_start.cell_indices, @@ -821,7 +897,11 @@ def reference(other: 'Cell', /) -> 'Cell': # noqa: E225 raise ValueError("The referenced cell has to be anchored.") return Cell(value=Cell._compute_value(lambda x: x.value, x=other), - words=WordConstructor.reference(other), + words=Cell._construct_word( + other, + WordConstructor.reference, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -842,7 +922,11 @@ def cross_reference(target: 'Cell', sheet: 'Sheet') -> 'Cell': raise ValueError("The referenced cell has to be anchored.") return Cell(value=Cell._compute_value(lambda x: x.value, x=target), - words=WordConstructor.cross_reference(target, sheet), + words=Cell._construct_word( + target, + WordConstructor.cross_reference, + target, sheet + ), cell_indices=target.cell_indices, cell_type=CellType.computational ) @@ -860,7 +944,11 @@ def raw(other: 'Cell', words: Dict[str, str], /) -> 'Cell': # noqa: E225 Cell: Expression with defined word """ return Cell(value=Cell._compute_value(lambda x: x.value, x=other), - words=WordConstructor.raw(other, words), + words=Cell._construct_word( + other, + WordConstructor.raw, + other, words + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -878,7 +966,11 @@ def variable(other: 'Cell', /) -> 'Cell': # noqa: E225 if not other.is_variable: raise ValueError("Only the variable type cell is accepted!") return Cell(value=Cell._compute_value(lambda x: x.value, x=other), - words=WordConstructor.variable(other), + words=Cell._construct_word( + other, + WordConstructor.variable, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -894,7 +986,11 @@ def brackets(other: 'Cell', /) -> 'Cell': # noqa: E225 Cell: Expression in brackets """ return Cell(value=Cell._compute_value(lambda x: x.value, x=other), - words=WordConstructor.brackets(other), + words=Cell._construct_word( + other, + WordConstructor.brackets, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -911,7 +1007,11 @@ def logarithm(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.log(x.value), x=other), - words=WordConstructor.logarithm(other), + words=Cell._construct_word( + other, + WordConstructor.logarithm, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -928,7 +1028,11 @@ def exponential(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.exp(x.value), x=other), - words=WordConstructor.exponential(other), + words=Cell._construct_word( + other, + WordConstructor.exponential, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -945,7 +1049,11 @@ def ceil(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.ceil(x.value), x=other), - words=WordConstructor.ceil(other), + words=Cell._construct_word( + other, + WordConstructor.ceil, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -962,7 +1070,11 @@ def floor(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.floor(x.value), x=other), - words=WordConstructor.floor(other), + words=Cell._construct_word( + other, + WordConstructor.floor, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -979,7 +1091,11 @@ def round(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.round(x.value), x=other), - words=WordConstructor.round(other), + words=Cell._construct_word( + other, + WordConstructor.round, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -996,7 +1112,11 @@ def abs(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.abs(x.value), x=other), - words=WordConstructor.abs(other), + words=Cell._construct_word( + other, + WordConstructor.abs, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -1013,7 +1133,11 @@ def sqrt(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.sqrt(x.value), x=other), - words=WordConstructor.sqrt(other), + words=Cell._construct_word( + other, + WordConstructor.sqrt, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -1030,7 +1154,11 @@ def signum(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: np.sign(x.value), x=other), - words=WordConstructor.signum(other), + words=Cell._construct_word( + other, + WordConstructor.signum, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -1047,7 +1175,11 @@ def logicalNegation(other: 'Cell', /) -> 'Cell': # noqa: E225 """ return Cell(value=Cell._compute_value(lambda x: not x.value, x=other), - words=WordConstructor.logicalNegation(other), + words=Cell._construct_word( + other, + WordConstructor.logicalNegation, + other + ), cell_indices=other.cell_indices, cell_type=CellType.computational ) @@ -1077,7 +1209,9 @@ def conditional(condition: 'Cell', return Cell(value=Cell._compute_value( lambda cons, cond, alte: cons.value if cond.value else alte.value, cons=consequent, cond=condition, alte=alternative), - words=WordConstructor.conditional( + words=Cell._construct_word( + condition, + WordConstructor.conditional, condition, consequent, alternative ), cell_indices=condition.cell_indices, @@ -1113,7 +1247,9 @@ def offset(reference: 'Cell', raise ValueError("Both reference cell and target cell must be" " anchored!") return Cell(value=Cell._compute_value(lambda x: x.value, x=target), - words=WordConstructor.offset( + words=Cell._construct_word( + reference, + WordConstructor.offset, reference, row_skip, column_skip ), cell_indices=reference.cell_indices, @@ -1153,7 +1289,9 @@ def linear_interpolation( (y_e.value - y_s.value) / (x_e.value - x_s.value), x_s=x_start, y_s=y_start, x_e=x_end, y_e=y_end, x_v=x ), - words=WordConstructor.linear_interpolation( + words=Cell._construct_word( + x_start, + WordConstructor.linear_interpolation, x_start, y_start, x_end, y_end, x ), cell_indices=x.cell_indices, diff --git a/portable_spreadsheet/cell_indices.py b/portable_spreadsheet/cell_indices.py index 4ec82b1..8240854 100644 --- a/portable_spreadsheet/cell_indices.py +++ b/portable_spreadsheet/cell_indices.py @@ -148,23 +148,13 @@ def __init__(self, self.columns_help_text: List[str] = copy.deepcopy(columns_help_text) @property - def supported_languages(self) -> List[str]: - """Returns all languages supported by the indicies. - - Returns: - List[str]: All languages supported by this indices. - """ - return [].extend(self.user_defined_languages, system_languages) - - @property - def shape(self) -> Tuple[int]: + def shape(self) -> Tuple[int, int]: """Return the shape of the object in the NumPy logic. Returns: - Tuple[int]: Number of rows, Number of columns + Tuple[int, int]: Number of rows, Number of columns """ - language = list(self.columns.keys())[0] - return len(self.rows[language]), len(self.columns[language]) + return self.number_of_rows, self.number_of_columns @property def languages(self) -> List[str]: diff --git a/portable_spreadsheet/cell_indices_templates.py b/portable_spreadsheet/cell_indices_templates.py index a4668ab..7d8326b 100644 --- a/portable_spreadsheet/cell_indices_templates.py +++ b/portable_spreadsheet/cell_indices_templates.py @@ -86,4 +86,4 @@ def native_generator(rows: int, "python_numpy": python_numpy_generator, "native": native_generator, } -system_languages = ['excel', 'python_numpy'] +system_languages = [] #['excel'] # ['excel', 'python_numpy'] From efcf10c38a013564e10701684f0a92e0f68c4ee0 Mon Sep 17 00:00:00 2001 From: david-salac Date: Mon, 15 Mar 2021 15:22:47 +0000 Subject: [PATCH 2/5] Values only --- README.md | 2 ++ portable_spreadsheet/cell.py | 13 ++++++++----- portable_spreadsheet/cell_indices.py | 3 +++ portable_spreadsheet/cell_indices_templates.py | 2 +- portable_spreadsheet/sheet.py | 7 ++++++- portable_spreadsheet/sheet_utils.py | 5 ++--- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0931941..a5d9c33 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,8 @@ on the beginning of the sheet as a offset for labels. added on the beginning of the sheet as a offset for labels. 8. `warning_logger (Callable[[str], None]])`: Function that logs the warnings (or `None` if logging should be skipped). +9. `values_only (bool)`: If set to True, only values are computed and +nothing can be exported (makes script run faster) First two are the most important because they define labels for the columns and rows indices. The warnings mention above occurs when the slices are diff --git a/portable_spreadsheet/cell.py b/portable_spreadsheet/cell.py index 1424029..f497177 100644 --- a/portable_spreadsheet/cell.py +++ b/portable_spreadsheet/cell.py @@ -86,7 +86,7 @@ def __init__(self, self._excel_format: dict = {} self._description: Optional[str] = None self._excel_row_position: Optional[int] = None - self.compute_only_values: bool = True + self.compute_only_values: bool = self.cell_indices.values_only if not self.compute_only_values: if words is not None: @@ -907,12 +907,15 @@ def reference(other: 'Cell', /) -> 'Cell': # noqa: E225 ) @staticmethod - def cross_reference(target: 'Cell', sheet: 'Sheet') -> 'Cell': + def cross_reference(target: 'Cell', + target_sheet: 'Sheet', + source_sheet: 'Sheet') -> 'Cell': """Cross reference to other sheet in the workbook. Args: target (Cell): Target cell in a different sheet. - sheet (Sheet): Sheet of the target cell. + target_sheet (Sheet): Sheet of the target cell. + source_sheet (Sheet): Source sheet (where cell is set to exist). Return: Cell: reference to the different location. @@ -925,9 +928,9 @@ def cross_reference(target: 'Cell', sheet: 'Sheet') -> 'Cell': words=Cell._construct_word( target, WordConstructor.cross_reference, - target, sheet + target, target_sheet ), - cell_indices=target.cell_indices, + cell_indices=source_sheet.cell_indices, cell_type=CellType.computational ) diff --git a/portable_spreadsheet/cell_indices.py b/portable_spreadsheet/cell_indices.py index 8240854..6ce9a19 100644 --- a/portable_spreadsheet/cell_indices.py +++ b/portable_spreadsheet/cell_indices.py @@ -146,6 +146,9 @@ def __init__(self, # assign the help texts self.rows_help_text: List[str] = copy.deepcopy(rows_help_text) self.columns_help_text: List[str] = copy.deepcopy(columns_help_text) + # This set the sheet to store only values and not to constructs words + # it is used by Cell class + self.values_only: bool = False @property def shape(self) -> Tuple[int, int]: diff --git a/portable_spreadsheet/cell_indices_templates.py b/portable_spreadsheet/cell_indices_templates.py index 7d8326b..a4668ab 100644 --- a/portable_spreadsheet/cell_indices_templates.py +++ b/portable_spreadsheet/cell_indices_templates.py @@ -86,4 +86,4 @@ def native_generator(rows: int, "python_numpy": python_numpy_generator, "native": native_generator, } -system_languages = [] #['excel'] # ['excel', 'python_numpy'] +system_languages = ['excel', 'python_numpy'] diff --git a/portable_spreadsheet/sheet.py b/portable_spreadsheet/sheet.py index dc77b76..57731e3 100644 --- a/portable_spreadsheet/sheet.py +++ b/portable_spreadsheet/sheet.py @@ -80,7 +80,8 @@ def create_new_sheet( columns_help_text: List[str] = None, excel_append_row_labels: bool = True, excel_append_column_labels: bool = True, - warning_logger: Optional[Callable[[str], None]] = None + warning_logger: Optional[Callable[[str], None]] = None, + values_only: bool = False ) -> 'Sheet': """Direct way of creating instance. @@ -104,6 +105,9 @@ def create_new_sheet( on the beginning of the sheet as a offset for labels. warning_logger (Optional[Callable[[str], None]]): Function that logs the warnings (or None if skipped). + values_only (bool): Set the sheet to store only values and not to + constructs words - makes computation faster but disable all + export functionality Returns: Sheet: New instance of spreadsheet. @@ -120,6 +124,7 @@ def create_new_sheet( excel_append_column_labels=excel_append_column_labels, warning_logger=warning_logger ) + class_index.values_only = values_only return cls(class_index, warning_logger, name) def _initialise_array(self) -> T_sheet: diff --git a/portable_spreadsheet/sheet_utils.py b/portable_spreadsheet/sheet_utils.py index 7b99d37..3b2396a 100644 --- a/portable_spreadsheet/sheet_utils.py +++ b/portable_spreadsheet/sheet_utils.py @@ -177,8 +177,7 @@ def brackets(body: Cell) -> Cell: """ return Cell.brackets(body) - @staticmethod - def cross_reference(target: Cell, sheet: 'Sheet') -> Cell: + def cross_reference(self, target: Cell, sheet: 'Sheet') -> Cell: """Cross reference to other sheet in the workbook. Args: @@ -188,7 +187,7 @@ def cross_reference(target: Cell, sheet: 'Sheet') -> Cell: Return: Cell: reference to the different location. """ - return Cell.cross_reference(target, sheet) + return Cell.cross_reference(target, sheet, self.spreadsheet) @staticmethod def ln(value: Cell) -> Cell: From 24b4a13fbd6f693786ec2ccb708b675941f9e91a Mon Sep 17 00:00:00 2001 From: david-salac Date: Mon, 15 Mar 2021 15:29:46 +0000 Subject: [PATCH 3/5] simple sheet --- tests/test_cell_word_constructor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cell_word_constructor.py b/tests/test_cell_word_constructor.py index ee0ba7f..0b7ffa7 100644 --- a/tests/test_cell_word_constructor.py +++ b/tests/test_cell_word_constructor.py @@ -739,7 +739,7 @@ def test_cross_reference(self): ) with self.assertRaises(ValueError): Cell.cross_reference(self.u_operand, sheet) - u_reference = Cell.cross_reference(self.a_operand, sheet) + u_reference = Cell.cross_reference(self.a_operand, sheet, sheet) u_ref_word = u_reference.parse self.assertEqual(u_ref_word['excel'], "=" + "'Results'!F5") self.assertEqual(u_ref_word['python_numpy'], "Results.values[3,4]") From e0654c1fabc53e9c74a105164a97c5ce58d76223 Mon Sep 17 00:00:00 2001 From: david-salac Date: Mon, 15 Mar 2021 15:31:19 +0000 Subject: [PATCH 4/5] simple sheet --- tests/test_cell_word_constructor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cell_word_constructor.py b/tests/test_cell_word_constructor.py index 0b7ffa7..0a1e0e7 100644 --- a/tests/test_cell_word_constructor.py +++ b/tests/test_cell_word_constructor.py @@ -738,7 +738,7 @@ def test_cross_reference(self): 3, 3 ) with self.assertRaises(ValueError): - Cell.cross_reference(self.u_operand, sheet) + Cell.cross_reference(self.u_operand, sheet, sheet) u_reference = Cell.cross_reference(self.a_operand, sheet, sheet) u_ref_word = u_reference.parse self.assertEqual(u_ref_word['excel'], "=" + "'Results'!F5") From 9fdbe1217682fb5196d0aa96b456a84ba3ae1021 Mon Sep 17 00:00:00 2001 From: david-salac Date: Mon, 15 Mar 2021 15:47:03 +0000 Subject: [PATCH 5/5] V 2.1.9 --- portable_spreadsheet/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portable_spreadsheet/__init__.py b/portable_spreadsheet/__init__.py index 24f61e8..db7ccdb 100644 --- a/portable_spreadsheet/__init__.py +++ b/portable_spreadsheet/__init__.py @@ -7,5 +7,5 @@ from .grammar_utils import GrammarUtils # noqa from .skipped_label import SkippedLabel # noqa -__version__ = "2.1.8" +__version__ = "2.1.9" __status__ = "Production" diff --git a/setup.py b/setup.py index 9d56a7a..49856a8 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="portable-spreadsheet", - version="2.1.8", + version="2.1.9", author="David Salac", author_email="info@davidsalac.eu", description="A simple spreadsheet that keeps tracks of each operation of each cell in defined languages. Logic allows exporting sheets to Excel files (and see how each cell is computed), to the JSON strings with a description of computation of each cell (e. g. in the native language). Other formats, like HTML, CSV and Markdown (MD), are also implemented (user can define own format). It also allows reconstructing behaviours in native Python with NumPy.", # noqa