spreadsheet

terminal spreadsheet application
git clone https://git.ce9e.org/spreadsheet.git

commit
220c3f07f21a2d13adc0d689d10ece05c1484bb1
parent
509574a9b3cfa6742b05932cfa561c7868d2892c
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2024-07-06 18:13
implement bar plot

Diffstat

M sheet/__main__.py 3 +++
M sheet/csv.py 5 ++++-
M sheet/sheet.py 26 ++++++++++++++++++++++----

3 files changed, 29 insertions, 5 deletions


diff --git a/sheet/__main__.py b/sheet/__main__.py

@@ -7,6 +7,7 @@ from .expression import shift_refs
    7     7 from .expression import unparse
    8     8 from .expression import x2col
    9     9 from .input import Input
   -1    10 from .sheet import Bar
   10    11 from .sheet import iter_range
   11    12 from .term import align_center
   12    13 from .term import align_left
@@ -22,6 +23,8 @@ def to_cell(value: float|int|str|None|Exception, width: int) -> str:
   22    23         return align_right(s, width)
   23    24     elif isinstance(value, str):
   24    25         return align_left(value, width)
   -1    26     elif isinstance(value, Bar):
   -1    27         return value.render(width)
   25    28     elif value is None:
   26    29         return ' ' * width
   27    30     elif isinstance(value, Exception):

diff --git a/sheet/csv.py b/sheet/csv.py

@@ -1,15 +1,18 @@
    1     1 import csv
    2     2 
   -1     3 from .sheet import Bar
    3     4 from .sheet import Sheet
    4     5 
    5     6 
    6    -1 def to_display(value: float|int|str|None|Exception) -> str:
   -1     7 def to_display(value: float|int|str|Bar|None|Exception) -> str:
    7     8     if isinstance(value, float):
    8     9         return str(value)
    9    10     elif isinstance(value, int):
   10    11         return str(value)
   11    12     elif isinstance(value, str):
   12    13         return value
   -1    14     elif isinstance(value, Bar):
   -1    15         return value.render(10)
   13    16     elif value is None:
   14    17         return ''
   15    18     elif isinstance(value, Exception):

diff --git a/sheet/sheet.py b/sheet/sheet.py

@@ -3,6 +3,16 @@ from .expression import ParseError
    3     3 from .expression import parse
    4     4 
    5     5 
   -1     6 class Bar:
   -1     7     def __init__(self, value):
   -1     8         self.value = value
   -1     9 
   -1    10     def render(self, width):
   -1    11         x = int(self.value * width)
   -1    12         x = max(0, min(x, width))
   -1    13         return '#' * x + ' ' * (width - x)
   -1    14 
   -1    15 
    6    16 def iter_range(cell1, cell2):
    7    17     x1, y1 = cell1
    8    18     x2, y2 = cell2
@@ -15,13 +25,15 @@ def iter_range(cell1, cell2):
   15    25             yield x, y
   16    26 
   17    27 
   18    -1 def to_number(value: float|int|str|None|Exception) -> float|int:
   -1    28 def to_number(value: float|int|str|Bar|None|Exception) -> float|int:
   19    29     if isinstance(value, float):
   20    30         return value
   21    31     elif isinstance(value, int):
   22    32         return value
   23    33     elif isinstance(value, str):
   24    34         raise TypeError(value)
   -1    35     elif isinstance(value, Bar):
   -1    36         return value.value
   25    37     elif value is None:
   26    38         return 0
   27    39     elif isinstance(value, Exception):
@@ -50,7 +62,9 @@ class Sheet:
   50    62             pass
   51    63         return raw
   52    64 
   53    -1     def call_function(self, name: str, args: list[tuple], _commas: list[str]) -> float|int|str:
   -1    65     def call_function(
   -1    66         self, name: str, args: list[tuple], _commas: list[str]
   -1    67     ) -> float|int|str|Bar:
   54    68         if name == 'sum':
   55    69             if len(args) != 1 or args[0][0] != 'range':
   56    70                 raise ValueError(args)
@@ -65,10 +79,14 @@ class Sheet:
   65    79             base = to_number(self.evaluate(args[0]))
   66    80             exp = to_number(self.evaluate(args[1]))
   67    81             return base ** exp
   -1    82         elif name == 'bar':
   -1    83             if len(args) != 1:
   -1    84                 raise ValueError(args)
   -1    85             return Bar(to_number(self.evaluate(args[0])))
   68    86         else:
   69    87             raise NameError(name)
   70    88 
   71    -1     def evaluate(self, expr: tuple) -> float|int|str:
   -1    89     def evaluate(self, expr: tuple) -> float|int|str|Bar:
   72    90         if expr[0] in ['int', 'float', 'str']:
   73    91             return expr[1]
   74    92         elif expr[0] == 'ref':
@@ -112,7 +130,7 @@ class Sheet:
  112   130     def get_parsed(self, cell) -> tuple|float|int|str|None:
  113   131         return self.parsed.get(cell)
  114   132 
  115    -1     def get_value(self, cell) -> float|int|str|None|Exception:
   -1   133     def get_value(self, cell) -> float|int|str|Bar|None|Exception:
  116   134         parsed = self.get_parsed(cell)
  117   135         if isinstance(parsed, tuple):
  118   136             if cell not in self.cache: