Skip to content

Commit 641831e

Browse files
committed
Replace numeric cell type by float and int cell types
1 parent 7b51e50 commit 641831e

File tree

8 files changed

+56
-49
lines changed

8 files changed

+56
-49
lines changed

examples/format.ipynb

+10-3
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@
1616
"outputs": [],
1717
"source": [
1818
"sheet = ipysheet.sheet()\n",
19-
"cell0 = ipysheet.cell(0, 0, 0, numeric_format='0.0', type='numeric')\n",
19+
"cell0 = ipysheet.cell(0, 0, 0, numeric_format='.2', type='float')\n",
2020
"cell1 = ipysheet.cell(1, 0, \"Hello\", type='text')\n",
21-
"cell2 = ipysheet.cell(0, 1, 0.1, numeric_format='0.000', type='numeric')\n",
22-
"cell3 = ipysheet.cell(1, 1, 15.9, numeric_format='0.00', type='numeric')\n",
21+
"cell2 = ipysheet.cell(0, 1, 10000000000, numeric_format='e', type='int')\n",
22+
"cell3 = ipysheet.cell(1, 1, 5.91234314, numeric_format='.4', type='float')\n",
2323
"cell4 = ipysheet.cell(2, 2, \"02/14/2019\", date_format='MM/DD/YYYY', type='date')\n",
2424
"\n",
2525
"sheet"
2626
]
27+
},
28+
{
29+
"cell_type": "code",
30+
"execution_count": null,
31+
"metadata": {},
32+
"outputs": [],
33+
"source": []
2734
}
2835
],
2936
"metadata": {

ipysheet/easy.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"""
66
__all__ = ['sheet', 'current', 'cell', 'calculation', 'row', 'column', 'cell_range', 'hold_cells', 'renderer']
77

8-
import numbers
98
import six
109
from contextlib import contextmanager
1110

@@ -23,15 +22,15 @@
2322

2423
_common_doc = {
2524
'args': """
26-
type (string): Type of cell, options are: text, numeric, checkbox, dropdown, numeric, date, widget.
25+
type (string): Type of cell, options are: text, int, float, checkbox, dropdown, date, widget.
2726
If type is None, the type is inferred from the type of the value being passed,
28-
numeric (float or int type), boolean (bool type), widget (any widget object), or else text.
27+
float, int, boolean (bool type), widget (any widget object), or else text.
2928
When choice is given the type will be assumed to be dropdown.
3029
The types refer (currently) to the handsontable types: https://handsontable.com/docs/6.2.2/demo-custom-renderers.html
3130
color (string): The text color in the cell
3231
background_color (string): The background color in the cell
3332
read_only (bool): Whether the cell is editable or not
34-
numeric_format (string): Numbers format
33+
numeric_format (ipywidgets.widgets.trait_types.NumberFormat): Numbers format, default is 'd' for int cells, '.2f' for float cells
3534
date_format (string): Dates format
3635
time_format (string): Time format
3736
renderer (string): Renderer name to use for the cell
@@ -95,7 +94,7 @@ def current():
9594
@doc_subst(_common_doc)
9695
def cell(row, column, value=0., type=None, color=None, background_color=None,
9796
font_style=None, font_weight=None, style=None, label_left=None, choice=None,
98-
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, **kwargs):
97+
read_only=False, numeric_format=None, date_format='YYYY/MM/DD', renderer=None, **kwargs):
9998
"""Adds a new ``Cell`` widget to the current ``Sheet``
10099
101100
Args:
@@ -111,7 +110,8 @@ def cell(row, column, value=0., type=None, color=None, background_color=None,
111110
>>> from ipysheet import sheet, cell
112111
>>>
113112
>>> s1 = sheet()
114-
>>> cell(0, 0, 36.) # The Cell type will be 'numeric'
113+
>>> cell(0, 0, 36) # The Cell type will be 'int'
114+
>>> cell(0, 0, 36.3) # The Cell type will be 'float'
115115
>>> cell(1, 0, True) # The Cell type will be 'checkbox'
116116
>>> cell(0, 1, 'Hello World!') # The Cell type will be 'text'
117117
>>> c = cell(1, 1, True)
@@ -121,8 +121,10 @@ def cell(row, column, value=0., type=None, color=None, background_color=None,
121121
if type is None:
122122
if isinstance(value, bool):
123123
type = 'checkbox'
124-
elif isinstance(value, numbers.Number):
125-
type = 'numeric'
124+
elif isinstance(value, int):
125+
type = 'int'
126+
elif isinstance(value, float):
127+
type = 'float'
126128
elif isinstance(value, widgets.Widget):
127129
type = 'widget'
128130
else:
@@ -157,7 +159,7 @@ def cell(row, column, value=0., type=None, color=None, background_color=None,
157159
@doc_subst(_common_doc)
158160
def row(row, value, column_start=0, column_end=None, type=None, color=None, background_color=None,
159161
font_style=None, font_weight=None, style=None, choice=None,
160-
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, **kwargs):
162+
read_only=False, numeric_format=None, date_format='YYYY/MM/DD', renderer=None, **kwargs):
161163
"""Create a ``Cell`` widget, representing multiple cells in a sheet, in a horizontal row
162164
163165
Args:
@@ -187,7 +189,7 @@ def row(row, value, column_start=0, column_end=None, type=None, color=None, back
187189
@doc_subst(_common_doc)
188190
def column(column, value, row_start=0, row_end=None, type=None, color=None, background_color=None,
189191
font_style=None, font_weight=None, style=None, choice=None,
190-
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, **kwargs):
192+
read_only=False, numeric_format=None, date_format='YYYY/MM/DD', renderer=None, **kwargs):
191193
"""Create a ``Cell`` widget, representing multiple cells in a sheet, in a vertical column
192194
193195
Args:
@@ -219,7 +221,7 @@ def cell_range(value,
219221
row_start=0, column_start=0, row_end=None, column_end=None, transpose=False,
220222
squeeze_row=False, squeeze_column=False, type=None, color=None, background_color=None,
221223
font_style=None, font_weight=None, style=None, choice=None,
222-
read_only=False, numeric_format='0.000', date_format='YYYY/MM/DD', renderer=None, **kwargs):
224+
read_only=False, numeric_format=None, date_format='YYYY/MM/DD', renderer=None, **kwargs):
223225
"""Create a ``Cell`` widget, representing multiple cells in a sheet
224226
225227
Args:
@@ -278,7 +280,8 @@ def cell_range(value,
278280
# see if we an infer a type from the data, otherwise leave it None
279281
if type is None:
280282
type_check_map = [('checkbox', lambda x: isinstance(x, bool)),
281-
('numeric', lambda x: isinstance(x, numbers.Number)),
283+
('int', lambda x: isinstance(x, int)),
284+
('float', lambda x: isinstance(x, float) or isinstance(x, int)),
282285
('text', lambda x: isinstance(x, six.string_types)),
283286
('widget', lambda x: isinstance(x, widgets.Widget)),
284287
]

ipysheet/numpy_loader.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .easy import sheet, column, cell_range
2-
from .utils import extract_data, get_cell_type, get_cell_numeric_format
2+
from .utils import extract_data, get_cell_type
33

44

55
def from_array(array):
@@ -27,7 +27,6 @@ def from_array(array):
2727
columns = 1 if len(array.shape) == 1 else array.shape[1]
2828

2929
kwargs = {
30-
'numeric_format': get_cell_numeric_format(array.dtype),
3130
'type': get_cell_type(array.dtype)
3231
}
3332

ipysheet/pandas_loader.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .sheet import Cell, Sheet
2-
from .utils import extract_data, get_cell_numeric_format, get_cell_type
2+
from .utils import extract_data, get_cell_type
33

44

55
def _format_date(date):
@@ -56,7 +56,6 @@ def from_dataframe(dataframe):
5656
column_start=idx,
5757
column_end=idx,
5858
type=get_cell_type(arr.dtype),
59-
numeric_format=get_cell_numeric_format(arr.dtype),
6059
squeeze_row=False,
6160
squeeze_column=True
6261
))

ipysheet/sheet.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ipywidgets as widgets
22
from ipywidgets.widgets.widget_layout import LayoutTraitType
3+
from ipywidgets.widgets.trait_types import NumberFormat
34

45
import traitlets
56
from traitlets import Unicode, CInt, List, Tuple, Instance, Union, Dict, Bool, Any
@@ -33,7 +34,7 @@ class Cell(widgets.Widget):
3334
squeeze_column = Bool(True).tag(sync=True)
3435
transpose = Bool(False).tag(sync=True)
3536
choice = List(Unicode(), allow_none=True, default_value=None).tag(sync=True)
36-
numeric_format = Unicode('0.000', allow_none=True).tag(sync=True)
37+
numeric_format = NumberFormat(None, allow_none=True).tag(sync=True)
3738
date_format = Unicode('YYYY/MM/DD', allow_none=True).tag(sync=True)
3839
time_format = Unicode('h:mm:ss a', allow_none=True).tag(sync=True)
3940

ipysheet/test_all.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,10 @@ def test_cell_values():
276276

277277
cell = ipysheet.cell(0, 0, value=1.2)
278278
assert cell.value == 1.2
279-
assert cell.type == 'numeric'
279+
assert cell.type == 'float'
280280
cell = ipysheet.cell(0, 0, value=1)
281281
assert cell.value == 1
282-
assert cell.type == 'numeric'
282+
assert cell.type == 'int'
283283

284284
cell = ipysheet.Cell(value='1.2')
285285
assert cell.value == '1.2'
@@ -291,18 +291,18 @@ def test_cell_values():
291291

292292
cell = ipysheet.row(0, [0, 1.2])
293293
assert cell.value == [0, 1.2]
294-
assert cell.type == 'numeric'
294+
assert cell.type == 'float'
295295

296296
cell = ipysheet.row(0, [0, 1])
297297
assert cell.value == [0, 1]
298-
assert cell.type == 'numeric'
298+
assert cell.type == 'int'
299299

300300
cell = ipysheet.row(0, ['a', 'b'])
301301
assert cell.value == ['a', 'b']
302302
assert cell.type == 'text'
303303

304304
cell = ipysheet.row(0, [True, 0])
305-
assert cell.type == 'numeric'
305+
assert cell.type == 'int'
306306

307307
cell = ipysheet.row(0, [True, 'bla'])
308308
assert cell.type is None
@@ -442,21 +442,21 @@ def test_from_dataframe():
442442
sheet = ipysheet.from_dataframe(df)
443443
assert len(sheet.cells) == 7
444444
assert sheet.cells[0].value == [1., 1., 1., 1.]
445-
assert sheet.cells[0].type == 'numeric'
445+
assert sheet.cells[0].type == 'float'
446446
assert sheet.cells[1].value == [None, '2013/01/02', None, '2013/01/02']
447447
assert sheet.cells[1].type == 'date'
448448
assert sheet.cells[2].value == [1., 1., 1., 1.]
449-
assert sheet.cells[2].type == 'numeric'
450-
assert sheet.cells[2].numeric_format == '0.000'
449+
assert sheet.cells[2].type == 'float'
450+
assert sheet.cells[2].numeric_format is None
451451
assert sheet.cells[3].value == [False, True, False, False]
452452
assert sheet.cells[3].type == 'checkbox'
453453
assert sheet.cells[4].value == ['test', 'train', 'test', 'train']
454454
assert sheet.cells[4].type == 'text'
455455
assert sheet.cells[5].value == ['foo', 'foo', 'foo', 'foo']
456456
assert sheet.cells[5].type == 'text'
457457
assert sheet.cells[6].value == [0, 3, 9, 18]
458-
assert sheet.cells[6].type == 'numeric'
459-
assert sheet.cells[6].numeric_format == '0[.]0'
458+
assert sheet.cells[6].type == 'int'
459+
assert sheet.cells[6].numeric_format is None
460460

461461

462462
def test_from_to_dataframe():
@@ -503,7 +503,7 @@ def test_from_array():
503503
arr = np.random.randn(6, 10)
504504
sheet = ipysheet.from_array(arr)
505505
assert len(sheet.cells) == 1
506-
assert sheet.cells[0].type == 'numeric'
506+
assert sheet.cells[0].type == 'float'
507507
assert sheet.cells[0].value is arr
508508
assert sheet.rows == 6
509509
assert sheet.columns == 10

ipysheet/utils.py

+4-12
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,16 @@ def extract_data(sheet):
5050

5151

5252
def get_cell_type(dt):
53-
# TODO Differentiate integer and float? Using custom renderers and
54-
# validators for integers?
5553
# Add support for void type from NumPy?
5654
# See https://handsontable.com/docs/6.2.2/tutorial-cell-types.html
5755
return {
5856
'b': 'checkbox',
59-
'i': 'numeric',
60-
'u': 'numeric',
61-
'f': 'numeric',
62-
'm': 'numeric',
57+
'i': 'int',
58+
'u': 'int',
59+
'f': 'float',
60+
'm': 'float',
6361
'M': 'date',
6462
'S': 'text',
6563
'U': 'text'
6664
}.get(dt.kind, 'text')
6765

68-
69-
def get_cell_numeric_format(dt):
70-
return {
71-
'i': '0[.]0',
72-
'f': '0.000',
73-
}.get(dt.kind)

js/src/sheet.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ let CellRangeModel = widgets.WidgetModel.extend({
3636
squeeze_row: true,
3737
squeeze_column: true,
3838
transpose: false,
39-
numeric_format: '0.000',
39+
numeric_format: null,
4040
date_format: 'YYYY/MM/DD',
4141
time_format: 'h:mm:ss a'
4242
});
@@ -275,9 +275,9 @@ let put_values2d = function(grid, values) {
275275

276276

277277
// Register `int` and `float` cell types
278-
class NumberEditor extends Handsontable.editors.TextEditor {
278+
class IntEditor extends Handsontable.editors.TextEditor {
279279
getValue() {
280-
return Number.parseFloat(this.TEXTAREA.value);
280+
return parseInt(this.TEXTAREA.value);
281281
}
282282
};
283283

@@ -291,23 +291,29 @@ function int_validator(query, callback) {
291291
}
292292

293293
(Handsontable.cellTypes as any).registerCellType('int', {
294-
editor: NumberEditor,
294+
editor: IntEditor,
295295
renderer: int_renderer,
296296
validator: int_validator,
297297
allowInvalid: false
298298
});
299299

300+
class FloatEditor extends Handsontable.editors.TextEditor {
301+
getValue() {
302+
return parseFloat(this.TEXTAREA.value);
303+
}
304+
};
305+
300306
function float_renderer(hotInstance, td, row, column, prop, value, cellProperties) {
301307
const numeric_format = cellProperties.numericFormat || '.2f';
302308
td.innerHTML = d3.format(numeric_format)(value);
303309
}
304310

305311
function float_validator(query, callback) {
306-
callback(Number.isInteger(query));
312+
callback(typeof query == 'number');
307313
}
308314

309315
(Handsontable.cellTypes as any).registerCellType('float', {
310-
editor: NumberEditor,
316+
editor: FloatEditor,
311317
renderer: float_renderer,
312318
validator: float_validator,
313319
allowInvalid: false

0 commit comments

Comments
 (0)