• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

colour-science / colour-datasets / 7853010122

10 Feb 2024 05:53AM UTC coverage: 96.225%. Remained the same
7853010122

push

github

KelSolaar
Use `np.reshape` function instead of `.reshape` method.

2243 of 2331 relevant lines covered (96.22%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.36
/colour_datasets/utilities/spreadsheet.py
1
"""
2
Spreadsheet Utilities
3
=====================
4

5
Defines various spreadsheet related utilities.
6

7
References
8
----------
9
-   :cite:`OpenpyxlDevelopers2019` : Openpyxl Developers. (2019). openpyxl.
10
    https://bitbucket.org/openpyxl/openpyxl/
11
"""
12

13
from __future__ import annotations
1✔
14

15
import re
1✔
16

17
import xlrd
1✔
18
from colour.hints import Dict, List
1✔
19
from colour.utilities import CanonicalMapping, attest
1✔
20

21
__author__ = "Colour Developers, Openpyxl Developers"
1✔
22
__copyright__ = "Copyright 2019 Colour Developers"
1✔
23
__copyright__ += ", "
1✔
24
__copyright__ = "Copyright (C) 2010 openpyxl"
1✔
25
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
1✔
26
__license__ += ", "
1✔
27
__license__ += "MIT Licence - https://opensource.org/licenses/MIT"
1✔
28
__maintainer__ = "Colour Developers"
1✔
29
__email__ = "colour-developers@colour-science.org"
1✔
30
__status__ = "Production"
1✔
31

32
__all__ = [
1✔
33
    "column_to_index",
34
    "row_to_index",
35
    "index_to_column",
36
    "index_to_row",
37
    "cell_range_values",
38
]
39

40
# https://stackoverflow.com/questions/64264563/\
41
# attributeerror-elementtree-object-has-no-attribute-getiterator-when-trying
42
xlrd.xlsx.ensure_elementtree_imported(False, None)
1✔
43
xlrd.xlsx.Element_has_iter = True
1✔
44

45

46
def _column_number_to_letters(number: int) -> str:
1✔
47
    """
48
    Convert given column number into a column letters.
49

50
    Right shifts the column index by 26 to find column letters in reverse
51
    order. These numbers are 1-based, and can be converted to ASCII
52
    ordinals by adding 64.
53

54
    Parameters
55
    ----------
56
    number
57
        Column number to convert to column letters.
58

59
    Returns
60
    -------
61
    :class:`str`
62
        Column letters.
63

64
    References
65
    ----------
66
    :cite:`OpenpyxlDevelopers2019`
67

68
    Examples
69
    --------
70
    >>> _column_number_to_letters(128)
71
    'DX'
72
    """
73

74
    attest(
1✔
75
        1 <= number <= 18278,
76
        f"Column number {number} must be in range [1, 18278]!",
77
    )
78

79
    letters = []
1✔
80
    while number > 0:
1✔
81
        number, remainder = divmod(number, 26)
1✔
82
        if remainder == 0:
1✔
83
            remainder = 26
1✔
84
            number -= 1
1✔
85
        letters.append(chr(remainder + 64))
1✔
86

87
    return "".join(reversed(letters))
1✔
88

89

90
_LETTERS_TO_NUMBER_CACHE: CanonicalMapping = CanonicalMapping()
1✔
91
"""Letters, e.g. *Microsoft Excel* column letters to numbers cache."""
1✔
92

93
_NUMBER_TO_LETTERS_CACHE: Dict = {}
1✔
94
"""Numbers to letters, e.g. *Microsoft Excel* column letters cache."""
1✔
95

96
for i in range(1, 18279):
1✔
97
    letter = _column_number_to_letters(i)
1✔
98
    _NUMBER_TO_LETTERS_CACHE[i] = letter
1✔
99
    _LETTERS_TO_NUMBER_CACHE[letter] = i
1✔
100

101

102
def row_to_index(row: int | str) -> int:
1✔
103
    """
104
    Return the 0-based index of given row name.
105

106
    Parameters
107
    ----------
108
    row
109
        Row name.
110

111
    Returns
112
    -------
113
    :class`int` or :class:`str`
114
        0-based row index.
115

116
    Examples
117
    --------
118
    >>> row_to_index("1")
119
    0
120
    """
121

122
    row = int(row)
1✔
123

124
    attest(row > 0, "Row must be greater than 0!")
1✔
125

126
    return row - 1
1✔
127

128

129
def index_to_row(index: int) -> str:
1✔
130
    """
131
    Return the row name of given 0-based index.
132

133
    Parameters
134
    ----------
135
    index
136
        0-based row index.
137

138
    Returns
139
    -------
140
    :class:`str`
141
        Row name.
142

143
    Examples
144
    --------
145
    >>> index_to_row(0)
146
    '1'
147
    """
148

149
    return str(index + 1)
1✔
150

151

152
def column_to_index(column: str) -> int:
1✔
153
    """
154
    Return the 0-based index of given column letters.
155

156
    Parameters
157
    ----------
158
    column
159
        Column letters
160

161
    Returns
162
    -------
163
    :class:`int`
164
        0-based column index.
165

166
    Examples
167
    --------
168
    >>> column_to_index("A")
169
    0
170
    """
171

172
    return _LETTERS_TO_NUMBER_CACHE[column] - 1
1✔
173

174

175
def index_to_column(index: int) -> str:
1✔
176
    """
177
    Return the column letters of given 0-based index.
178

179
    Parameters
180
    ----------
181
    index
182
        0-based column index.
183

184
    Returns
185
    -------
186
    :class:`str`
187
        Column letters
188

189
    Examples
190
    --------
191
    >>> index_to_column(0)
192
    'A'
193
    """
194

195
    return _NUMBER_TO_LETTERS_CACHE[index + 1]
1✔
196

197

198
_CELL_RANGE_REGEX: re.Pattern = re.compile(
1✔
199
    r"^[$]?(?P<column_in>[A-Za-z]{1,3})?[$]?(?P<row_in>\d+)?"
200
    r"(:[$]?(?P<column_out>[A-Za-z]{1,3})?[$]?(?P<row_out>\d+)?)?$"
201
)
202
"""Regular expression to match a cell range, e.g. "A1:C3"."""
1✔
203

204

205
def cell_range_values(sheet: xlrd.sheet.Sheet, cell_range: str) -> List[str]:
1✔
206
    """
207
    Return given workbook sheet cell range values, i.e. the values of the
208
    rows and columns for given cell range.
209

210
    Parameters
211
    ----------
212
    sheet : Sheet
213
        Workbook sheet.
214
    cell_range
215
        Cell range values, e.g. "A1:C3".
216

217
    Returns
218
    -------
219
    :class:`list`
220
        List of row values.
221
    """
222

223
    table: List[str] = []
1✔
224

225
    match = re.match(_CELL_RANGE_REGEX, cell_range)
1✔
226
    if match:
1✔
227
        groups = match.groupdict()
1✔
228
    else:
229
        return table
×
230

231
    column_in = column_to_index(groups["column_in"])
1✔
232
    row_in = row_to_index(groups["row_in"])
1✔
233
    column_out = column_to_index(groups["column_out"])
1✔
234
    row_out = row_to_index(groups["row_out"])
1✔
235

236
    for row in range(row_in, row_out + 1, 1):
1✔
237
        table.append(
1✔
238
            sheet.row_values(row, start_colx=column_in, end_colx=column_out + 1)
239
        )
240

241
    return table
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc