masaccio / numbers-parser

Python module for parsing Apple Numbers .numbers files
MIT License
201 stars 14 forks source link

Bug with Numerical Zero as Cell Value None #3

Closed semireg closed 2 years ago

semireg commented 2 years ago

I have a basic numbers spreadsheet with a cell value of 0 (cell data format set to Automatic).

2021-12-12 at 10 44 AM

When run through numbers-parser I see...

2021-12-12 10:42:35,792 DEBUG Table 1@[3,3]: value=0.0

But the cell value from iter_rows is None.

If I change the data format to Text, the result is a string "0" (which I expect).

The None result seems like a bug in conditional logic.

(p.s. Thank you so much for this library. I'm finally adding Numbers support to my app 🥳)

masaccio commented 2 years ago

I can't see anything obvious and a quick try to reproduce didn't get what I hoped. I tried:


doc = Document("/Users/jon/Downloads/issue-3.numbers")
sheets = doc.sheets()
tables = sheets[0].tables()
table = tables[0]
for i, row in enumerate(table.iter_rows()):
    print(i, row[0].value)

Using a similar spreadsheet to your image I got:

0 value
1 1.0
2 None
3 0.0

Any chance you can share a code snippet and the spreadsheet?

semireg commented 2 years ago

Sorry, hoping it would be an easy repro, too 😄

2021-12-12 at 12 26 PM

simple.numbers.zip

2021-12-12 12:25:57,694 DEBUG    Log level set to DEBUG
2021-12-12 12:25:57,724 DEBUG    1 Sheets
2021-12-12 12:25:57,724 DEBUG      Sheet "Sheet 1" - 1 Tables
2021-12-12 12:25:57,725 DEBUG    Table 1@[0,0]: value=A
2021-12-12 12:25:57,725 DEBUG    Table 1@[0,1]: value=B
2021-12-12 12:25:57,725 DEBUG    Table 1@[1,0]: value=2.0
2021-12-12 12:25:57,725 DEBUG    Table 1@[1,1]: value=0.0  <-- curiously, correct
2021-12-12 12:25:57,725 DEBUG    Table 1@[2,0]: value=3.0
2021-12-12 12:25:57,725 DEBUG    Table 1@[2,1]: value=1.0
2021-12-12 12:25:57,727 DEBUG          row: ('A', 'B', None, None, None, None, None)
2021-12-12 12:25:57,727 DEBUG          row: (2.0, None, None, None, None, None, None)  <-- 2nd column is None, should be 0.0
2021-12-12 12:25:57,727 DEBUG          row: (3.0, 1.0, None, None, None, None, None)
2021-12-12 12:25:57,727 DEBUG          row: (None, None, None, None, None, None, None)
2021-12-12 12:25:57,727 DEBUG          row: (None, None, None, None, None, None, None)
2021-12-12 12:25:57,727 DEBUG          row: (None, None, None, None, None, None, None)
2021-12-12 12:25:57,727 DEBUG          row: (None, None, None, None, None, None, None)

Code is basically:

    sheets = doc.sheets()
    log.debug(f'{len(sheets)} Sheets')

    for sheet in sheets:
        tables = sheet.tables()
        log.debug(f'  Sheet "{sheet.name}" - {len(tables)} Tables')

        for table in tables:
            # log.debug(f'    Table "{table.name}"')
            for row in table.iter_rows(values_only=True):
                log.debug(f'      row: {row}')

Let me know how I can help.

masaccio commented 2 years ago

That was enough. values_only=True is at fault. As a quick workaround you can skip the parameter to iter_rows and get the values with cell.value.

It was indeed a logic error (yielding cell.value or None). Will be an easy fix so will publish a new patch version in the next couple of days latest.

masaccio commented 2 years ago

Should be fixed in 2.1.1 which I just uploaded to PyPI

semireg commented 2 years ago

Verified working as expected. 👏