Skip to content

Commit

Permalink
Merge pull request #9 from david-salac/development
Browse files Browse the repository at this point in the history
Version 0.1.4
  • Loading branch information
david-salac authored May 26, 2020
2 parents 955f888 + 4ab93b2 commit 6d3e993
Show file tree
Hide file tree
Showing 8 changed files with 450 additions and 221 deletions.
400 changes: 204 additions & 196 deletions README.md

Large diffs are not rendered by default.

47 changes: 33 additions & 14 deletions portable_spreadsheet/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def description(self, new_description: Optional[str]):
# =====================================

# === BINARY OPERATORS: ===
def add(self, other: 'Cell', /) -> 'Cell': # noqa E225
def add(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Add two values.
Args:
Expand All @@ -220,7 +220,7 @@ def add(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def subtract(self, other: 'Cell', /) -> 'Cell': # noqa E225
def subtract(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Subtract two values.
Args:
Expand All @@ -235,7 +235,7 @@ def subtract(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def multiply(self, other: 'Cell', /) -> 'Cell': # noqa E225
def multiply(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Multiply two values.
Args:
Expand All @@ -250,7 +250,7 @@ def multiply(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def divide(self, other: 'Cell', /) -> 'Cell': # noqa E225
def divide(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Divide two values.
Args:
Expand All @@ -265,7 +265,7 @@ def divide(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def modulo(self, other: 'Cell', /) -> 'Cell': # noqa E225
def modulo(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Modulo of two values.
Args:
Expand All @@ -280,7 +280,7 @@ def modulo(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def power(self, other: 'Cell', /) -> 'Cell': # noqa E225
def power(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Self power to other.
Args:
Expand All @@ -295,7 +295,7 @@ def power(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def equalTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
def equalTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean equal operator.
Args:
Expand All @@ -310,7 +310,7 @@ def equalTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def notEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
def notEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean not equal operator.
Args:
Expand All @@ -325,7 +325,7 @@ def notEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def greaterThan(self, other: 'Cell', /) -> 'Cell': # noqa E225
def greaterThan(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean greater than operator.
Args:
Expand All @@ -340,7 +340,7 @@ def greaterThan(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def greaterThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
def greaterThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean greater than or equal to operator.
Args:
Expand All @@ -355,7 +355,7 @@ def greaterThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def lessThan(self, other: 'Cell', /) -> 'Cell': # noqa E225
def lessThan(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean less than operator.
Args:
Expand All @@ -370,7 +370,7 @@ def lessThan(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def lessThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
def lessThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Boolean less than or equal to operator.
Args:
Expand All @@ -385,7 +385,7 @@ def lessThanOrEqualTo(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def logicalConjunction(self, other: 'Cell', /) -> 'Cell': # noqa E225
def logicalConjunction(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Logical conjunction operator.
Args:
Expand All @@ -400,7 +400,7 @@ def logicalConjunction(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_type=CellType.computational
)

def logicalDisjunction(self, other: 'Cell', /) -> 'Cell': # noqa E225
def logicalDisjunction(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Logical disjunction operator.
Args:
Expand All @@ -414,6 +414,21 @@ def logicalDisjunction(self, other: 'Cell', /) -> 'Cell': # noqa E225
cell_indices=other.cell_indices,
cell_type=CellType.computational
)

def concatenate(self, other: 'Cell', /) -> 'Cell': # noqa: E225
"""Concatenate two values as strings.
Args:
other (Cell): Another operand.
Returns:
Cell: self concatenate with other
"""
return Cell(value=str(self.value) + str(other.value),
words=WordConstructor.concatenate(self, other),
cell_indices=other.cell_indices,
cell_type=CellType.computational
)
# =========================

# ==== OPERATOR OVERLOADING ====
Expand Down Expand Up @@ -476,6 +491,10 @@ def __or__(self, other):
def __invert__(self):
"""Overload the operator '~'."""
return self.logicalNegation(self)

def __lshift__(self, other):
"""Overload the operator '<<' to string concatenation."""
return self.concatenate(other)
# ==============================

# === AGGREGATE OPERATORS ===
Expand Down
64 changes: 64 additions & 0 deletions portable_spreadsheet/grammars.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,22 @@
"suffix": "",
"separator": "^",
},
# Merge two strings
'concatenate': {
"prefix": "CONCATENATE(",
"suffix": ")",
"separator": ",",
# Context of string
"string-value": {
"prefix": '"',
"suffix": '"',
},
# Context of numbers
"numeric-value": {
"prefix": '',
"suffix": '',
},
},
# AGGREGATE FUNCTIONS
"sum": {
"prefix": "SUM(",
Expand Down Expand Up @@ -374,6 +390,22 @@
"suffix": "",
"separator": " mod ",
},
# Merge two strings
'concatenate': {
"prefix": "concatenate string ",
"suffix": " and ",
"separator": "",
# Context of string
"string-value": {
"prefix": "'",
"suffix": "'",
},
# Context of numbers
"numeric-value": {
"prefix": "'",
"suffix": "'",
},
},
# like 7^3
"power": {
"prefix": "",
Expand Down Expand Up @@ -636,6 +668,22 @@
"suffix": "",
"separator": "**",
},
# Merge two strings
'concatenate': {
"prefix": "",
"suffix": "",
"separator": "+",
# Context of string
"string-value": {
"prefix": '',
"suffix": '',
},
# Context of numbers
"numeric-value": {
"prefix": '"',
"suffix": '"',
},
},
# AGGREGATE FUNCTIONS
"sum": {
"prefix": "np.sum(",
Expand Down Expand Up @@ -945,6 +993,22 @@
"suffix": str,
"separator": str, # Typically '^' (in Python '**')
},
# Merge two strings, like "a" + "b" = "ab"
'concatenate': {
"prefix": str,
"suffix": str,
"separator": str,
# Context of the string constant
"string-value": {
"prefix": str,
"suffix": str,
},
# Context of the numbers constant
"numeric-value": {
"prefix": str,
"suffix": str,
},
},

# === AGGREGATE FUNCTIONS (functions for aggregated cells) ===
# Sum of aggregated cells.
Expand Down
23 changes: 15 additions & 8 deletions portable_spreadsheet/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def to_dictionary(self,
append_dict (dict): Append this dictionary to output.
Returns:
Dict[object, Dict[object, Dict[str, Union[str, float]]]]:
dict:
Dictionary with keys: 1. column/row, 2. row/column, 3. language
or language pseudonym or 'value' keyword for values -> value as
a value or as a cell building string.
Expand Down Expand Up @@ -373,21 +373,28 @@ def to_dictionary(self,
if x_helptext is not None:
values[x_start_key][x[idx_x]][
'help_text'] = x_helptext[idx_x]

# Create data parent
data = {'data': values}

# Add variables
values['variables'] = self._get_variables().variables_dict
data['variables'] = self._get_variables().variables_dict
# Add a row and column labels as arrays
if by_row:
values['row-labels'] = x
values['column-labels'] = y
data['row-labels'] = x
data['column-labels'] = y
else:
values['row-labels'] = y
values['column-labels'] = x
data['row-labels'] = y
data['column-labels'] = x

# Create table parent
table = {'table': data}

# Append dictionary:
for a_key, a_val in append_dict.items():
values[a_key] = a_val
table[a_key] = a_val

return values
return table

def to_json(self,
languages: List[str] = None,
Expand Down
54 changes: 54 additions & 0 deletions portable_spreadsheet/word_constructor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import copy
from numbers import Number
from typing import Dict, Set, Tuple

from .grammars import GRAMMARS
Expand Down Expand Up @@ -290,6 +291,59 @@ def lessThanOrEqualTo(first,
return WordConstructor._binary_operation(first, second,
"less-than-or-equal-to")

@staticmethod
def concatenate(first,
second) -> 'WordConstructor':
"""Concatenate values as two strings and create a word.
Args:
first (Cell): The first cell (operand) of the operator.
second (Cell): The second cell (operand) of the operator.
Returns:
WordConstructor: Word constructed using binary operator concatenate
and two operands.
"""
# Inline function for appending context to inputs
def _generate_word_string_concatenate(in_cell) -> T_word:
"""Generate word for each operand.
Returns:
T_word: Words for each language.
"""
if in_cell.anchored:
return WordConstructor.reference(in_cell).words
else:
if in_cell.cell_type == CellType.computational:
return in_cell._constructing_words.words
elif in_cell.cell_type == CellType.value_only:
words: T_word = {}
for language in instance.languages:
if isinstance(in_cell.value, str):
pref = GRAMMARS[language]['operations'][
'concatenate']['string-value']['prefix']
suff = GRAMMARS[language]['operations'][
'concatenate']['string-value']['suffix']
words[language] = pref + str(in_cell.value) + suff
if isinstance(in_cell.value, Number):
pref = GRAMMARS[language]['operations'][
'concatenate']['numeric-value']['prefix']
suff = GRAMMARS[language]['operations'][
'concatenate']['numeric-value']['suffix']
words[language] = pref + str(in_cell.value) + suff
return words

instance = copy.deepcopy(first.word)
first_words = _generate_word_string_concatenate(first)
second_word = _generate_word_string_concatenate(second)
for language in instance.languages:
pref = GRAMMARS[language]['operations']['concatenate']['prefix']
suff = GRAMMARS[language]['operations']['concatenate']['suffix']
sp = GRAMMARS[language]['operations']['concatenate']['separator']
instance.words[language] = pref + first_words[language] + sp \
+ second_word[language] + suff
return instance

@staticmethod
def _aggregation_parse_cell(cell,
start_idx: Tuple[int, int],
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="portable-spreadsheet",
version="0.1.3",
version="0.1.4",
author="David Salac",
author_email="info@davidsalac.eu",
description="Simple spreadsheet that keeps tracks of each operation in "
Expand Down
Loading

0 comments on commit 6d3e993

Please sign in to comment.