Skip to content

Commit 33c600b

Browse files
authored
refactor: use explicit kwargs over **options, type fixes (#35)
1 parent 80d4a40 commit 33c600b

File tree

2 files changed

+55
-32
lines changed

2 files changed

+55
-32
lines changed

table2ascii/options.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
from typing import List, Optional
33

44
from .alignment import Alignment
5-
from .preset_style import PresetStyle
65
from .table_style import TableStyle
76

87

98
@dataclass
109
class Options:
1110
"""Class for storing options that the user sets"""
1211

13-
first_col_heading: bool = False
14-
last_col_heading: bool = False
15-
column_widths: Optional[List[int]] = None
16-
alignments: Optional[List[Alignment]] = None
17-
style: TableStyle = PresetStyle.double_thin_compact
12+
first_col_heading: bool
13+
last_col_heading: bool
14+
column_widths: Optional[List[int]]
15+
alignments: Optional[List[Alignment]]
16+
style: TableStyle

table2ascii/table_to_ascii.py

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
from math import ceil, floor
2-
from typing import Any, List, Optional, Union
2+
from typing import Any, Callable, List, Optional, Union
33

44
from .alignment import Alignment
55
from .options import Options
6+
from .preset_style import PresetStyle
7+
from .table_style import TableStyle
68

79

810
class TableToAscii:
911
"""Class used to convert a 2D Python table to ASCII text"""
1012

11-
def __init__(self, header: List, body: List[List], footer: List, options: Options):
13+
def __init__(
14+
self,
15+
header: Optional[List[Any]],
16+
body: Optional[List[List[Any]]],
17+
footer: Optional[List[Any]],
18+
options: Options,
19+
):
1220
"""
1321
Validate arguments and initialize fields
1422
1523
Args:
16-
header (List): The values in the header of the table
17-
body (List[List]): The rows of values in the body of the table
18-
footer (List): The values in the footer of the table
24+
header (Optional[List[Any]]): The values in the header of the table
25+
body (Optional[List[List[Any]]]): The rows of values in the body of the table
26+
footer (Optional[List[Any]]): The values in the footer of the table
1927
options (Options): The options for the table
2028
"""
2129
# initialize fields
@@ -85,19 +93,19 @@ def __auto_column_widths(self) -> List[int]:
8593
List[int]: The minimum number of characters needed for each column
8694
"""
8795

88-
def longest_line(text: str) -> int:
89-
"""Returns the length of the longest line in a multi-line string"""
96+
def widest_line(text: str) -> int:
97+
"""Returns the width of the longest line in a multi-line string"""
9098
return max(len(line) for line in text.splitlines()) if len(text) else 0
9199

92100
column_widths = []
93101
# get the width necessary for each column
94102
for i in range(self.__columns):
103+
# col_widest returns the width of the widest line in the ith cell of a given list
104+
col_widest: Callable[[List[Any], int], int] = lambda row, i=i: widest_line(str(row[i]))
95105
# number of characters in column of i of header, each body row, and footer
96-
header_size = longest_line(str(self.__header[i])) if self.__header else 0
97-
body_size = (
98-
map(lambda row, i=i: longest_line(str(row[i])), self.__body) if self.__body else [0]
99-
)
100-
footer_size = longest_line(str(self.__footer[i])) if self.__footer else 0
106+
header_size = col_widest(self.__header) if self.__header else 0
107+
body_size = map(col_widest, self.__body) if self.__body else [0]
108+
footer_size = col_widest(self.__footer) if self.__footer else 0
101109
# get the max and add 2 for padding each side with a space
102110
column_widths.append(max(header_size, *body_size, footer_size) + 2)
103111
return column_widths
@@ -248,7 +256,7 @@ def __heading_sep_to_ascii(self) -> str:
248256
filler=self.__style.heading_row_sep,
249257
)
250258

251-
def __body_to_ascii(self) -> str:
259+
def __body_to_ascii(self, body: List[List[Any]]) -> str:
252260
"""
253261
Assembles the body of the ascii table
254262
@@ -270,7 +278,7 @@ def __body_to_ascii(self) -> str:
270278
right_edge=self.__style.left_and_right_edge,
271279
filler=row,
272280
)
273-
for row in self.__body
281+
for row in body
274282
)
275283

276284
def to_ascii(self) -> str:
@@ -288,7 +296,7 @@ def to_ascii(self) -> str:
288296
table += self.__heading_sep_to_ascii()
289297
# add table body
290298
if self.__body:
291-
table += self.__body_to_ascii()
299+
table += self.__body_to_ascii(self.__body)
292300
# add table footer
293301
if self.__footer:
294302
table += self.__heading_sep_to_ascii()
@@ -300,25 +308,41 @@ def to_ascii(self) -> str:
300308

301309

302310
def table2ascii(
303-
header: Optional[List] = None,
304-
body: Optional[List[List]] = None,
305-
footer: Optional[List] = None,
306-
**options,
311+
header: Optional[List[Any]] = None,
312+
body: Optional[List[List[Any]]] = None,
313+
footer: Optional[List[Any]] = None,
314+
*,
315+
first_col_heading: bool = False,
316+
last_col_heading: bool = False,
317+
column_widths: Optional[List[int]] = None,
318+
alignments: Optional[List[Alignment]] = None,
319+
style: TableStyle = PresetStyle.double_thin_compact,
307320
) -> str:
308321
"""
309322
Convert a 2D Python table to ASCII text
310323
311324
Args:
312-
header (:class:`Optional[List]`): List of column values in the table's header row
313-
body (:class:`Optional[List[List]]`): 2-dimensional list of values in the table's body
314-
footer (:class:`Optional[List]`): List of column values in the table's footer row
315-
style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported)
316-
column_widths (:class:`List[int]`): List of widths in characters for each column (defaults to auto-sizing)
317-
alignments (:class:`List[Alignment]`): List of alignments (ex. `[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]`)
325+
header (:class:`Optional[List[Any]]`): List of column values in the table's header row
326+
body (:class:`Optional[List[List[Any]]]`): 2-dimensional list of values in the table's body
327+
footer (:class:`Optional[List[Any]]`): List of column values in the table's footer row
318328
first_col_heading (:class:`bool`): Whether to add a header column separator after the first column
319329
last_col_heading (:class:`bool`): Whether to add a header column separator before the last column
330+
column_widths (:class:`List[int]`): List of widths in characters for each column (defaults to auto-sizing)
331+
alignments (:class:`List[Alignment]`): List of alignments (ex. `[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]`)
332+
style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported)
320333
321334
Returns:
322335
str: The generated ASCII table
323336
"""
324-
return TableToAscii(header, body, footer, Options(**options)).to_ascii()
337+
return TableToAscii(
338+
header,
339+
body,
340+
footer,
341+
Options(
342+
first_col_heading=first_col_heading,
343+
last_col_heading=last_col_heading,
344+
column_widths=column_widths,
345+
alignments=alignments,
346+
style=style,
347+
),
348+
).to_ascii()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy