# Selfdocprint
Provides enhanced and configurable `print()` functionality that allows for easily printing values such that they are:
* *self-documented*
* *formatted*
* *nicely laid out*
Fully compatible with python's built-in `print()`. Supports all its keyword arguments, including `file=` and `flush=`.
The module comes with four layout classes. Below is an example of InlineLayout.
```python
from selfdocprint import PrintFunc, InlineLayout
# instantiate a function
print = PrintFunc() # this will now shadow python's built-in print function
# some data
formula = "Ultimate Question of Life,\nthe Universe, and Everything"
theta = 6.006
x = 7
# let's print it with our print function
print(formula, theta, x, x*theta, layout=InlineLayout())
```
![image_1](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_1.png)
The default value for the `layout=` keyword argument (normally `None`) can be configured so that subsequent calls require even less typing. In this case it would be good practice to not call the function 'print' to avoid confusion with the expected behaviour of python's built-in `print()`.
```python
prinline = PrintFunc(default_layout=InlineLayout())
prinline(formula, theta, x, x*theta)
```
![image_2](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_2.png)
A layout can be customised by overriding one or more of its fields (The fields are described in detail in the section: 'Style, format and layout specification'). Note that in the example below we override `head=` to suppress the empty line that is normally printed in front of the output when using the InlineLayout.
```python
for i in range(0, 99, 21):
print(i, i * theta, layout=InlineLayout(float_format="12.6f", pointer=" -> ", head=""))
```
![image_3](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_3.png)
Custom layouts can be created and referenced in subsequent calls. Note that in the example below we change the `style=` for the labels, which is specified as [ANSI Select Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) parameters.
```python
my_layout = InlineLayout(style="92;3", int_format="4")
print(x, x * theta, layout=my_layout)
```
![image_4](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_4.png)
## Built-in layouts
Next to the *'inline'* layout three additional layouts are available. The example below demonstrates the *'dict'* layout. In addition it shows the use of the `beg=` keyword argument which can be used to provide a heading to the output.
```python
from selfdocprint import DictLayout
print(formula, theta, x, x*theta, layout=DictLayout(), beg="Using the 'dict' layout:\n")
```
![image_5](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_5.png)
For values that take up a lot of horizontal space the *'scroll'* layout is particularly useful.
```python
from selfdocprint import ScrollLayout
import numpy as np
X = np.random.rand(5,5)
print(X, X.T @ X, layout=ScrollLayout(), beg="Using the 'scroll' layout:\n")
```
![image_6](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_6.png)
Use the *'minimal'* layout if you only want to print labels in front of the values.
```python
from selfdocprint import MinimalLayout
print(formula, theta, x, theta*x, layout=MinimalLayout(), beg="Using the 'minimal' layout:\n\n")
```
![image_7](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_7.png)
## Style, format and layout specification
The `selfdocprint.print_layout_specs()` function prints the specification for every built-in layout and a rudimentary description of the layout algorithm.
```python
import selfdocprint as sdp
sdp.print_layout_specs()
```
![image_8](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_8.png)
All parameters are of type str. The format parameters are specified according to python's [Format Specification Mini-Language](https://docs.python.org/3/library/string.html#formatspec). If an alignment character (<, >, or ^) is specified without a fixed width in the lbl_format, then the alignment will be made relative to all other <labels\>. For the str_format a missing width value will result in an alignment of all lines in the string representation of a value. The algorithm injects the width of the longest string of the <label\> strings and the width of the longest line in a <value\> string into lbl_format and str_format respectively.
The sty parameter is a string with zero or more [ANSI Select Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) parameters seperated by semicolons (;).
The layout algorithm globally works as follows: 1) adjust lbl_format and str_format where necessary; 2) style and format the concatenations of each <label\> with `pointer`; 3) format the values; 4) layout each <label\>/<value\> pair in a 'pane'; 5) join these panes together with `seperator`; 6) print the panes: if `seperator` contains a newline ('\n') character then the panes are laid out from top to bottom, if not, they are laid out from left to right.
## Limitations
* Selfdocprint cannot be used in the Repl nor with `eval()`, `exec()` and `compile()`. Selfdocprint uses the `inspect` module to discover the labels and this does not work in these situations.
* Selfdocprint's print function cannot accept arguments that use the unpack operator, for example to unpack a tuple: `*my_tuple`. This does not make sense anyway because there is nothing to label the individual values of the tuple with, so it's just as informative to just use the tuple variable as is.
Raw data
{
"_id": null,
"home_page": "https://github.com/marcelloDC/selfdocprint",
"name": "selfdocprint",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": "",
"keywords": "print,pretty,self-documenting,layout,format",
"author": "Marcel de Croock",
"author_email": "marcel.decroock@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/b9/31/f66e6293c3d37ae1c31a5810a7785de2541614e4f4a5eeeb5e0e8c2abaee/selfdocprint-0.2.2.tar.gz",
"platform": null,
"description": "# Selfdocprint\n\nProvides enhanced and configurable `print()` functionality that allows for easily printing values such that they are: \n\n* *self-documented*\n* *formatted*\n* *nicely laid out*\n\nFully compatible with python's built-in `print()`. Supports all its keyword arguments, including `file=` and `flush=`. \n\nThe module comes with four layout classes. Below is an example of InlineLayout.\n\n\n```python\nfrom selfdocprint import PrintFunc, InlineLayout\n\n# instantiate a function\nprint = PrintFunc() # this will now shadow python's built-in print function\n\n# some data\nformula = \"Ultimate Question of Life,\\nthe Universe, and Everything\"\ntheta = 6.006\nx = 7\n\n# let's print it with our print function\nprint(formula, theta, x, x*theta, layout=InlineLayout())\n```\n\n![image_1](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_1.png)\n\nThe default value for the `layout=` keyword argument (normally `None`) can be configured so that subsequent calls require even less typing. In this case it would be good practice to not call the function 'print' to avoid confusion with the expected behaviour of python's built-in `print()`.\n\n\n```python\nprinline = PrintFunc(default_layout=InlineLayout())\n\nprinline(formula, theta, x, x*theta)\n```\n\n![image_2](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_2.png)\n\nA layout can be customised by overriding one or more of its fields (The fields are described in detail in the section: 'Style, format and layout specification'). Note that in the example below we override `head=` to suppress the empty line that is normally printed in front of the output when using the InlineLayout.\n\n\n```python\nfor i in range(0, 99, 21):\n print(i, i * theta, layout=InlineLayout(float_format=\"12.6f\", pointer=\" -> \", head=\"\"))\n```\n\n![image_3](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_3.png)\n\nCustom layouts can be created and referenced in subsequent calls. Note that in the example below we change the `style=` for the labels, which is specified as [ANSI Select Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) parameters.\n\n\n```python\nmy_layout = InlineLayout(style=\"92;3\", int_format=\"4\")\n\nprint(x, x * theta, layout=my_layout)\n```\n\n![image_4](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_4.png)\n\n## Built-in layouts\nNext to the *'inline'* layout three additional layouts are available. The example below demonstrates the *'dict'* layout. In addition it shows the use of the `beg=` keyword argument which can be used to provide a heading to the output.\n\n\n```python\nfrom selfdocprint import DictLayout\n\nprint(formula, theta, x, x*theta, layout=DictLayout(), beg=\"Using the 'dict' layout:\\n\")\n```\n\n![image_5](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_5.png)\n\nFor values that take up a lot of horizontal space the *'scroll'* layout is particularly useful.\n\n\n```python\nfrom selfdocprint import ScrollLayout\nimport numpy as np\n\nX = np.random.rand(5,5)\n\nprint(X, X.T @ X, layout=ScrollLayout(), beg=\"Using the 'scroll' layout:\\n\")\n```\n\n![image_6](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_6.png)\n\nUse the *'minimal'* layout if you only want to print labels in front of the values.\n\n\n```python\nfrom selfdocprint import MinimalLayout\n\nprint(formula, theta, x, theta*x, layout=MinimalLayout(), beg=\"Using the 'minimal' layout:\\n\\n\")\n```\n\n![image_7](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_7.png)\n\n## Style, format and layout specification\nThe `selfdocprint.print_layout_specs()` function prints the specification for every built-in layout and a rudimentary description of the layout algorithm.\n\n\n```python\nimport selfdocprint as sdp\n\nsdp.print_layout_specs()\n```\n\n![image_8](https://raw.githubusercontent.com/marcelloDC/selfdocprint/main/images/output_image_8.png)\n\nAll parameters are of type str. The format parameters are specified according to python's [Format Specification Mini-Language](https://docs.python.org/3/library/string.html#formatspec). If an alignment character (<, >, or ^) is specified without a fixed width in the lbl_format, then the alignment will be made relative to all other <labels\\>. For the str_format a missing width value will result in an alignment of all lines in the string representation of a value. The algorithm injects the width of the longest string of the <label\\> strings and the width of the longest line in a <value\\> string into lbl_format and str_format respectively.\n\nThe sty parameter is a string with zero or more [ANSI Select Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) parameters seperated by semicolons (;).\n\nThe layout algorithm globally works as follows: 1) adjust lbl_format and str_format where necessary; 2) style and format the concatenations of each <label\\> with `pointer`; 3) format the values; 4) layout each <label\\>/<value\\> pair in a 'pane'; 5) join these panes together with `seperator`; 6) print the panes: if `seperator` contains a newline ('\\n') character then the panes are laid out from top to bottom, if not, they are laid out from left to right.\n\n## Limitations\n* Selfdocprint cannot be used in the Repl nor with `eval()`, `exec()` and `compile()`. Selfdocprint uses the `inspect` module to discover the labels and this does not work in these situations.\n* Selfdocprint's print function cannot accept arguments that use the unpack operator, for example to unpack a tuple: `*my_tuple`. This does not make sense anyway because there is nothing to label the individual values of the tuple with, so it's just as informative to just use the tuple variable as is.\n",
"bugtrack_url": null,
"license": "GPL-3.0-only",
"summary": "A self-documenting, auto-layout print() function.",
"version": "0.2.2",
"project_urls": {
"Homepage": "https://github.com/marcelloDC/selfdocprint",
"Repository": "https://github.com/marcelloDC/selfdocprint"
},
"split_keywords": [
"print",
"pretty",
"self-documenting",
"layout",
"format"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6dee95e710fe907a8ad34122839328ba11a0bf375758e9398721d21f60fe16d5",
"md5": "08cf0d0e71fd388fdda2375c8c301260",
"sha256": "8b30a633627c0189840af9454d0fcb061c518c2932c094745c97034098810186"
},
"downloads": -1,
"filename": "selfdocprint-0.2.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "08cf0d0e71fd388fdda2375c8c301260",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 22899,
"upload_time": "2023-10-22T23:55:05",
"upload_time_iso_8601": "2023-10-22T23:55:05.687450Z",
"url": "https://files.pythonhosted.org/packages/6d/ee/95e710fe907a8ad34122839328ba11a0bf375758e9398721d21f60fe16d5/selfdocprint-0.2.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b931f66e6293c3d37ae1c31a5810a7785de2541614e4f4a5eeeb5e0e8c2abaee",
"md5": "fb81a112778de97ec2d07d256fa58606",
"sha256": "ac20ed6498bd3c10d3fffe99c81b54947bd8226a62bc49b69aab6b8277b4a584"
},
"downloads": -1,
"filename": "selfdocprint-0.2.2.tar.gz",
"has_sig": false,
"md5_digest": "fb81a112778de97ec2d07d256fa58606",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 22710,
"upload_time": "2023-10-22T23:55:07",
"upload_time_iso_8601": "2023-10-22T23:55:07.702751Z",
"url": "https://files.pythonhosted.org/packages/b9/31/f66e6293c3d37ae1c31a5810a7785de2541614e4f4a5eeeb5e0e8c2abaee/selfdocprint-0.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-22 23:55:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "marcelloDC",
"github_project": "selfdocprint",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "selfdocprint"
}