Skip to content

Commit

Permalink
Merge pull request #162 from DeepSpace2/devel
Browse files Browse the repository at this point in the history
4.2 release
  • Loading branch information
DeepSpace2 authored Nov 13, 2023
2 parents c8a1117 + 2052ed0 commit 26a2b9c
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 146 deletions.
41 changes: 39 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
Thanks for contributing. If creating a pull request please make sure to submit it to the `devel` branch and not to `master`.
Happy coding!
### Thanks for contributing!

# Branch
Create the pull request against the `devel` branch instead of the `master`.

# Quality
All pull requests are welcome regardless of quality. We will work together to review and improve the pull request.

Of course there are some steps that could be considered to improve the quality of the pull request and to support the process of review and development.

- Make sure your code follows [PEP 8 — Style Guide for Python Code](https://pep8.org/). You can use some [linting tools](https://en.wikipedia.org/wiki/Lint_(software)) to automate the process (e.g. [`pycodestyle`](https://pycodestyle.pycqa.org) or [`flake8`](https://github.com/pycqa/flake8)).
- Test your code using the existing test cases. For details read further.
- It would be great if you could create [`unittest`](https://docs.python.org/3/library/unittest.html)'s for your code.

# Unittesting

This project uses Python's default [`unittest`](https://docs.python.org/3/library/unittest.html) package. You can run all test cases via the *discover* feature when you run this in the projects root folder.

```sh
python3 -m unittest discover
```

The output should look like this
```sh
----------------------------------------------------------------------
Ran 74 tests in 0.823s

OK
```

If you want to run a specific test case or method you need to *install* the package first. It is recommended to use a virtual environment and the `--editable` flag of `pip`. Run this in the projects root folder:
```sh
python3 -m pip install --editable .
```
Please read further to understand the consequences of `--editable`.
- ["pip documentation - Local project installs - Editable installs"](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs)
- ["When would the -e, --editable option be useful with pip install?"](https://stackoverflow.com/q/35064426/4865723)

### Happy coding!
6 changes: 1 addition & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
experimental: [false]
include:
- python-version: 3.10-dev
experimental: true

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
13 changes: 13 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

build:
os: ubuntu-22.04
tools:
python: "3.11"

sphinx:
configuration: docs/conf.py

python:
install:
- requirements: docs/requirements.txt
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
#### 4.2
* **Added Python 3.10 support**
* Added ability to set individual borders' type via the `border_type` argument
when creating a `Styler` object
* Fixes [GitHub issue #108](https://github.com/DeepSpace2/StyleFrame/issues/108) - Styling and exporting a dataframe that
contains a column called "index"
* Fixes error when attempting to use `best_fit` argument in `StyleFrame.to_excel`
on an empty dataframe [GitHub PR #157](https://github.com/DeepSpace2/StyleFrame/pull/157)

#### 4.1
* Added `strikethrough` and `italic` to `Styler`
* Raising `TypeError` in `to_excel` if trying to use a non-openpyxl engine
Expand Down
75 changes: 26 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
[![Codecov branch](https://img.shields.io/codecov/c/github/DeepSpace2/StyleFrame/master.svg?style=plastic)]()
[![Travis branch](https://img.shields.io/travis/DeepSpace2/StyleFrame/master.svg?style=plastic)]()
[![PyPI](https://img.shields.io/pypi/v/styleframe.svg?style=plastic)]()
[![PyPI](https://img.shields.io/pypi/pyversions/StyleFrame.svg?style=plastic)]()
[![Downloads](http://pepy.tech/badge/styleframe)](http://pepy.tech/count/styleframe)
[![codecov](https://codecov.io/gh/DeepSpace2/StyleFrame/branch/master/graph/badge.svg?token=f4Q048ZOwC)](https://codecov.io/gh/DeepSpace2/StyleFrame)
[![GitHub Actions](https://img.shields.io/github/checks-status/deepspace2/styleframe/master?label=Tests&logo=github&style=plastic)](https://github.com/DeepSpace2/StyleFrame/actions/workflows/test.yml?query=branch%3Amaster)
[![PyPI](https://img.shields.io/pypi/v/styleframe.svg?style=plastic)](https://pypi.org/project/styleframe/)
![PyPI](https://img.shields.io/pypi/pyversions/StyleFrame.svg?style=plastic)
[![Downloads](http://pepy.tech/badge/styleframe)](https://pepy.tech/project/styleframe)
[![Documentation Status](https://readthedocs.org/projects/styleframe/badge/?version=latest&style=plastic)](https://styleframe.readthedocs.io/en/latest/?badge=latest)

# StyleFrame
_Exporting DataFrames to a styled Excel file has never been so easy_


A library that wraps pandas and openpyxl and allows easy styling of dataframes in Excel.

[Documentation](http://styleframe.readthedocs.org/en/latest/) and [Changelog](CHANGELOG.md)
- [Documentation](http://styleframe.readthedocs.org/en/latest/)
- [Changelog](CHANGELOG.md)
- [How to contribute](.github/CONTRIBUTING.md)

---

Expand Down Expand Up @@ -48,45 +49,18 @@ $ pip install styleframe
## Basics

* ***Styler***:
```python
__init__(self, bg_color=None, bold=False, font=utils.fonts.arial, font_size=12, font_color=None,
number_format=utils.number_formats.general, protection=False, underline=None,
border_type=utils.borders.thin, horizontal_alignment=utils.horizontal_alignments.center,
vertical_alignment=utils.vertical_alignments.center, wrap_text=True, shrink_to_fit=True,
fill_pattern_type=utils.fill_pattern_types.solid, indent=0,
comment_author=None, comment_text=None, text_rotation=0)
```
Object that represents the style of a cell in our excel file.
Styler is responsible of storing the style of single cell.
Once the style is ready, ```.to_openpyxl_style()``` method is called.
The `Styler` class represents a style of a cell.

* ***utils***:
```python
from styleframe import utils
```
Before you start to style your StyleFrame, take a look in the utils module.
You may find there very useful things such as number formats, colors, borders and more!

The `utils` module contains helper classes for frequently used styling elements,
such as number and date formats, colors and border types.

* ***Container***:
```python
__init__(self, value, styler=None)
```
Object that represents cell in our excel file.
it contains two variables:
    - value which may be anything you wish to put in the cell as long as excel file support its format.
    - style which is the style of the cell- created by ```Styler(...).to_openpyxl_style()```

And finally:
The `Container` class represents a cell, a value/style pair.

* ***StyleFrame***:
```python
__init__(self, obj, styler_obj=None):
```
StyleFrame is the main object we will be dealing with.
It contains self DataFrame which is based on the given obj.
Each item of the self DataFrame is wrapped by a Container object to store the given data and its` style.
StyleFrame (usually referred as sf) reveals a very easy api for styling.
The `StyleFrame` is the main interaction point you will have.
It wraps the `DataFrame` object you will be styling.

## Usage Examples

Expand Down Expand Up @@ -141,11 +115,14 @@ sf.apply_style_by_indexes(indexes_to_style=sf[sf['Pass/Fail'] == 'Failed'],
sf.set_column_width(columns=sf.columns, width=20)
sf.set_row_height(rows=sf.row_indexes, height=25)

sf.to_excel('output.xlsx',
# Add filters in row 0 to each column.
row_to_add_filters=0,
# Freeze the columns before column 'A' (=None) and rows above '2' (=1).
columns_and_rows_to_freeze='A2').save()
writer = sf.to_excel('output.xlsx',
# Add filters in row 0 to each column.
row_to_add_filters=0,
# Freeze the columns before column 'A' (=None)
# and rows above '2' (=1).
columns_and_rows_to_freeze='A2')

writer.close()
```
The final output saved under output.xlsx:
![Example 1](readme-images/example1.PNG?raw=true)
Expand Down Expand Up @@ -224,7 +201,7 @@ from styleframe import Styler, utils


sf.apply_column_style(cols_to_style='Date',
styler_obj=Styler(number_format=utils.number_formats.date,
styler_obj=Styler(date_format=utils.number_formats.date,
font=utils.fonts.calibri,
bold=True))

Expand Down Expand Up @@ -263,7 +240,7 @@ Change the background of all rows where the date is after 14/1/2000 to green
sf.apply_style_by_indexes(indexes_to_style=sf[sf['Date'] > date(2000, 1, 14)],
cols_to_style='Date',
styler_obj=Styler(bg_color=utils.colors.green,
number_format=utils.number_formats.date,
date_format=utils.number_formats.date,
bold=True))
```

Expand All @@ -285,14 +262,14 @@ sf.to_excel(excel_writer=ew,
Adding another excel sheet
```python
other_sheet_sf = StyleFrame({'Dates': [date(2016, 10, 20), date(2016, 10, 21), date(2016, 10, 22)]},
styler_obj=Styler(number_format=utils.number_formats.date))
styler_obj=Styler(date_format=utils.number_formats.date))

other_sheet_sf.to_excel(excel_writer=ew, sheet_name='2')
```

Don't forget to save
```python
ew.save()
ew.close()
```

**_the result:_**
Expand Down
11 changes: 6 additions & 5 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
colour
openpyxl>=2.5,<4
colour>=0.1.5,<0.2
jsonschema
openpyxl
pandas
sphinx==5.0.1
xlrd
pandas<3
xlrd>=1.0.0,<1.3.0 ; python_version<='3.6'
sphinx==7.2.6
sphinx-rtd-theme
2 changes: 1 addition & 1 deletion docs/usage_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Creating ExcelWriter object:

ew = StyleFrame.ExcelWriter(r'C:\my_excel.xlsx')
sf.to_excel(ew)
ew.save()
ew.close()

It is also possible to style a whole column or columns, and decide whether to style the headers or not:
::
Expand Down
3 changes: 3 additions & 0 deletions docs/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ It is possible to directly use a value that is not present in the utils module a
.. autoclass:: styleframe.utils.borders
:members:

.. autoclass:: styleframe.utils.border_locations
:members:

.. autoclass:: styleframe.utils.horizontal_alignments
:members:

Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def find_version(*file_paths):
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9'
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10'
],

# What does your project relate to?
Expand All @@ -86,7 +87,7 @@ def find_version(*file_paths):
'openpyxl>=2.5,<4',
'colour>=0.1.5,<0.2',
'jsonschema',
'pandas<2',
'pandas<3',
"xlrd>=1.0.0,<1.3.0 ; python_version<='3.6'"
]
)
6 changes: 6 additions & 0 deletions styleframe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sys

from pandas import DataFrame

from .container import Container
from .series import Series
from .style_frame import StyleFrame
Expand All @@ -14,3 +16,7 @@

ExcelWriter = StyleFrame.ExcelWriter
read_excel = StyleFrame.read_excel

# applymap is deprecated in pandas > 2, nasty hack to support < 2 and > 2 versions at the same time
if not hasattr(DataFrame, 'map'):
DataFrame.map = DataFrame.applymap
2 changes: 1 addition & 1 deletion styleframe/command_line/commandline.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def _apply_cols_and_rows_dimensions(self, sf, sheet):
sf.set_row_height_dict(row_heights)

def _save(self):
self.excel_writer.save()
self.excel_writer.close()


def get_cli_args():
Expand Down
Loading

0 comments on commit 26a2b9c

Please sign in to comment.