Skip to content

Commit

Permalink
Implement string output
Browse files Browse the repository at this point in the history
Using tabulate package.
  • Loading branch information
alugowski committed Aug 24, 2023
1 parent f7eda09 commit b154d9b
Show file tree
Hide file tree
Showing 11 changed files with 946 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install base dependencies
run: pip install pytest
run: pip install tabulate pytest

- name: Test minimums
run: pytest tests/test_basic.py tests/test_list_like.py
Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ Turn this opaque string:

To one of these:

### String

```
1000×1000, 212345 'float64' elements, coo
0 1 2 3 4 5
┌ ┐
0 │ 0.3876 ... │
1 │ 0.5801 0.5085 0.8927 ... │
2 │ ... │
3 │ 0.7142 ... │
4 │ 0.8631 ... │
5 │ 0.7863 0.1298 0.9918 0.71 ... │
6 │ 0.9481 ... │
7 │ ... │
8 │ 0.4023 ... │
│ : : : : : : ... │
└ ┘
```

`mprint(A)`. Use `to_str()` for the string.

### HTML
![HTML](doc/images/html.png)

Expand All @@ -46,9 +67,11 @@ pip install matrepr
from matrepr import mdisplay
```

* `mdisplay(A)`: Displays the output of `to_html` or `to_latex` in Jupyter.
* `to_str(A)`: Format `A` as string.
* `to_html(A)`: Format `A` as an HTML table. Returns a string.
* `to_latex(A)`: Format `A` as a LaTeX matrix. Returns a string.
* `mprint(A)`: print `A` as a string to stdout.
* `mdisplay(A)`: Displays the output of `to_html`, `to_latex`, or `to_str` in Jupyter.

## Jupyter Integration

Expand Down
605 changes: 542 additions & 63 deletions doc/demo-edgecases.ipynb

Large diffs are not rendered by default.

73 changes: 55 additions & 18 deletions doc/demo-jupyter-screenshots.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.118430Z",
"start_time": "2023-08-22T06:09:09.018011Z"
"end_time": "2023-08-24T04:44:30.750056Z",
"start_time": "2023-08-24T04:44:30.651709Z"
},
"collapsed": false,
"jupyter": {
Expand All @@ -43,8 +43,8 @@
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.237800Z",
"start_time": "2023-08-22T06:09:09.100208Z"
"end_time": "2023-08-24T04:44:30.935314Z",
"start_time": "2023-08-24T04:44:30.749052Z"
},
"collapsed": false,
"jupyter": {
Expand All @@ -65,8 +65,8 @@
"execution_count": 3,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.253149Z",
"start_time": "2023-08-22T06:09:09.242975Z"
"end_time": "2023-08-24T04:44:30.945799Z",
"start_time": "2023-08-24T04:44:30.935561Z"
},
"collapsed": false,
"jupyter": {
Expand Down Expand Up @@ -95,8 +95,8 @@
"execution_count": 4,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.276597Z",
"start_time": "2023-08-22T06:09:09.252429Z"
"end_time": "2023-08-24T04:44:30.954264Z",
"start_time": "2023-08-24T04:44:30.946094Z"
},
"collapsed": false,
"jupyter": {
Expand All @@ -113,8 +113,8 @@
"execution_count": 5,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.281202Z",
"start_time": "2023-08-22T06:09:09.264960Z"
"end_time": "2023-08-24T04:44:31.044602Z",
"start_time": "2023-08-24T04:44:30.961686Z"
}
},
"outputs": [
Expand Down Expand Up @@ -152,7 +152,7 @@
" }\n",
"</style>\n",
"<p>1000×1000, 212345 'float64' elements, coo</p>\n",
"<table >\n",
"<table>\n",
" <thead class=\"head_no_border\">\n",
" <tr>\n",
" <th></th>\n",
Expand Down Expand Up @@ -335,8 +335,8 @@
"execution_count": 6,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.281418Z",
"start_time": "2023-08-22T06:09:09.276820Z"
"end_time": "2023-08-24T04:44:31.046139Z",
"start_time": "2023-08-24T04:44:31.043614Z"
},
"collapsed": false,
"jupyter": {
Expand All @@ -357,8 +357,8 @@
"execution_count": 7,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.289379Z",
"start_time": "2023-08-22T06:09:09.281657Z"
"end_time": "2023-08-24T04:44:31.053089Z",
"start_time": "2023-08-24T04:44:31.046033Z"
},
"collapsed": false,
"jupyter": {
Expand Down Expand Up @@ -400,7 +400,7 @@
" }\n",
"</style>\n",
"<p>1000×1000, 212345 'float64' elements, coo</p>\n",
"<table >\n",
"<table>\n",
" <thead class=\"head_no_border\">\n",
" <tr>\n",
" <th></th>\n",
Expand Down Expand Up @@ -535,8 +535,8 @@
"execution_count": 8,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-22T06:09:09.308825Z",
"start_time": "2023-08-22T06:09:09.295436Z"
"end_time": "2023-08-24T04:44:31.053224Z",
"start_time": "2023-08-24T04:44:31.049894Z"
},
"collapsed": false,
"jupyter": {
Expand Down Expand Up @@ -572,6 +572,43 @@
"matrepr.mdisplay(A, \"latex\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-24T04:44:31.061827Z",
"start_time": "2023-08-24T04:44:31.053627Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"1000×1000, 212345 'float64' elements, coo\n",
" 0 1 2 3 4 5 \n",
" ┌ ┐\n",
" 0 │ 0.3876 ... │\n",
" 1 │ 0.5801 0.5085 0.8927 ... │\n",
" 2 │ ... │\n",
" 3 │ 0.7142 ... │\n",
" 4 │ 0.8631 ... │\n",
" 5 │ 0.7863 0.1298 0.9918 0.71 ... │\n",
" 6 │ 0.9481 ... │\n",
" 7 │ ... │\n",
" 8 │ 0.4023 ... │\n",
" │ : : : : : : ... │\n",
" └ ┘"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"matrepr.mdisplay(A, \"str\")"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
54 changes: 47 additions & 7 deletions matrepr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import dataclasses
from dataclasses import dataclass, asdict
from typing import Type, Callable, Dict, List, Union
from typing import Any, Type, Callable, Dict, List, Union

from .adapters import Driver, MatrixAdapter
from .html_formatter import HTMLTableFormatter, NotebookHTMLFormatter
Expand Down Expand Up @@ -173,7 +173,7 @@ def _get_adapter(mat, unsupported_raise=True) -> MatrixAdapter:
return adapter


def to_html(mat, notebook=False, **kwargs) -> str:
def to_html(mat: Any, notebook=False, **kwargs) -> str:
"""
Render a matrix to HTML.
Expand All @@ -194,7 +194,7 @@ def to_html(mat, notebook=False, **kwargs) -> str:
return str(formatter.format(adapter))


def to_latex(mat, **kwargs):
def to_latex(mat: Any, **kwargs):
"""
Render a matrix to LaTeX.
Expand All @@ -211,20 +211,60 @@ def to_latex(mat, **kwargs):
return str(formatter.format(adapter))


def mdisplay(mat, method="html", **kwargs):
def to_str(mat: Any, **kwargs) -> str:
"""
Render a matrix to a string.
Internally uses `tabulate` and will pass through any arguments not explicitly set by this method.
:param mat: A supported matrix.
:param kwargs: Any argument in :class:`MatReprParams`.
:return: a string representation of `mat`.
"""
options = params.get(**kwargs)

ret = []

if options.title:
if options.title is True:
adapter = _get_adapter(mat)
title = adapter.describe()
else:
title = options.title
ret.append(title)

from .string_formatter import to_tabulate
ret.append(to_tabulate(mat, **kwargs))

return "\n".join(ret)


def mprint(mat: Any, **kwargs):
"""
Prints the output of :func:`to_str`.
:param mat: A supported matrix.
:param kwargs: Any argument in :class:`MatReprParams`.
"""
print(to_str(mat, **kwargs))


def mdisplay(mat: Any, method="html", **kwargs):
"""
Display a matrix in Jupyter.
:param mat: A supported matrix.
:param method: Style to use. One of :code:`"html"`, :code:`"latex"`.
:param method: Style to use. One of :code:`"html"`, :code:`"latex"`, :code:`"str"`.
:param kwargs: Any argument in :class:`MatReprParams`.
"""
from IPython.display import display, HTML, Latex
from IPython.display import display, HTML, Latex, display_pretty

if method == "html":
display(HTML(to_html(mat, notebook=True, **kwargs)))
elif method == "latex":
display(Latex('$' + to_latex(mat, **kwargs) + '$'))
elif method == "str":
display_pretty(to_str(mat, **kwargs), raw=True)
else:
raise ValueError("Unknown method: " + method)

Expand Down Expand Up @@ -253,4 +293,4 @@ def _register_jupyter_formatter(mime_type: str, repr_method: Callable):
formatter.for_type_by_name(type_module, type_name, repr_method)


__all__ = ["to_html", "to_latex", "mdisplay"]
__all__ = ["to_html", "to_latex", "to_str", "mprint", "mdisplay"]
2 changes: 1 addition & 1 deletion matrepr/adapters/list_like.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ListAdapter(MatrixAdapterRow):
def __init__(self, mat: list):
self.mat = mat
self.row_lengths = [(1 if is_single(row) else len(row)) for row in mat]
self.shape = (len(mat), max(self.row_lengths))
self.shape = (len(mat), max(self.row_lengths if self.row_lengths else [0]))
self.nnz = sum((1 if is_single(row) else len(row) - row.count(None)) for row in mat)

def get_shape(self) -> Tuple[int, int]:
Expand Down
Loading

0 comments on commit b154d9b

Please sign in to comment.