Metadata-Version: 2.1
Name: flash-handler
Version: 1.0.1
Summary: A simple Excel file handler
Home-page: UNKNOWN
License: UNKNOWN
Description: # Flash-Bomb-Demo 春耕项目教学demo - 使用文档
        
        **注意**：该工具只可用于**python 3**环境中。
        
        # 使用方法
        
        ## Step: 检查文件夹结构
        
        首先，一个完整的代码包，至少应包含下面的文件：
        
        ```.
        ├── flash_handler                   存放项目代码的文件夹
        │   ├── config.py                   存放了一些常量，见后文
        │   ├── const.py                    存放了一些常量，见后文
        │   ├── excel_processor.py          存放用于操作Excel的基础模块
        │   ├── file_keeper.py              存放用于维护文件列表的基础模块
        │   ├── handler.py                                              存放中间逻辑，桥接基础模块和上层逻辑          
        │   ├── spring.py                   存放上层逻辑
        │   ├── static                                                        存放待操作eExcel文件的文件夹                 
        │   │   ├── 闪光科技北京库存.xlsx      具体的待操作的Excel文件
        │   │   ├── ...                             
        │   └── utils.py                    存放工具类函数
        └── requirements.txt                存放程序依赖的第三方库的名称和版本
        ```
        
        请确保`spring.py`文件和`static`文件夹处在同一目录下。
        
        ## Step: 安装依赖项
        
        在运行工具之前，需要确保工具所依赖的第三方库被正确安装。所需第三方库的名称及版本已经在`requirements.txt`中，可在终端内执行下面的命令以安装上相应的第三方库：
        
        ```
        pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple  -r requirements.txt
        ```
        
        注：`-i https://pypi.tuna.tsinghua.edu.cn/simple`可以让pip3工具是为了加快软件下载
        
        ## Step: 准备Excel文件
        
        将待操作的Excel文件位于`static`文件，该文件夹下的其它Excel文件均可删除，以避免干扰。
        
        由于`static`文件夹下允许存在多个Excel文件，请尽量让`static`文件夹下的Excel文件有相同的表头，以避免意外情况的发生。
        
        ## Step: 运行前检查
        
        请确保Microsoft Excel、WPS等软件没有占用`static`文件夹下的任何一个Excel文件。
        
        ## Step: 运行
        
        在终端中把当前目录切换到`spring.py`所在的目录，执行如下命令，即可使用工具：
        
        ```
        python spring.py
        ```
        
        # 文件内容描述
        
        ## 文件Config.py
        
        存放程序所需的一些配置项。
        
            class Config(object):
                  # 工作目录。程序将从此处获取Excel文件。
                DIR_PATH = os.getenv('FBD_DIR_PATH', 'static')
                
                # 邮箱设置
                SMTP_QQ_HOST = 'smtp.qq.com'
                SMTP_QQ_PORT = 587
                SMTP_MAIL_SUBJECT = 'python发送附件'
        ## 文件const.py
        
        存放程序所需的一些常量。
        
            # 分隔符。如，用户输入多个数据时在不同数据间使用的分隔符。
            DELIMETERS = ',|，'
            
            # 图表种类的内部表示
            CHART_BAR_TYPE = 'bar'
            CHART_PIE_TYPE = 'pie'
            CHART_LINE_TYPE = 'line'
            
            # 图表种类对外展现的名称
            CHART_BAR_REPR = '柱状图'
            CHART_PIE_REPR = '饼图'
            CHART_LINE_REPR = '折线图'
            
            # 图表种类对外展现的名称和内部表示的映射关系
            CHART_REPR2TYPE = {
                CHART_BAR_REPR: CHART_BAR_TYPE,
                CHART_PIE_REPR: CHART_PIE_TYPE,
                CHART_LINE_REPR: CHART_LINE_TYPE,
            }
            
            # 图表纵坐标（柱状图或折线图）或统计量（饼图）计算方法的内部表示
            METHOD_SUM_TYPE = 'sum'
            METHOD_COUNT_TYPE = 'count'
            
            # 图表纵坐标（柱状图或折线图）或统计量（饼图）计算方法对外展现的名称
            METHOD_SUM_REPR = '加和'
            METHOD_COUNT_REPR = '计数'
            
            # 图表纵坐标（柱状图或折线图）或统计量（饼图）计算方法对外展现的名称和内部表示之间的映射关系
            METHOD_REPR2TYPE = {
                METHOD_SUM_REPR: METHOD_SUM_TYPE,
                METHOD_COUNT_REPR: METHOD_COUNT_TYPE,
            }
        ## 文件excel_processor.py
        
        > 该文件包括操作Excel文件的基础模块及它所需要的辅助函数。
        
        ### 函数_setup_preferred_font()
        
        > 设置合适的字体，使中文字符在图表中能正常显示。优先使用沙盒中存在的中文字体。
        
        ### 函数_setup_remedial_font()
        
        > 设置合适的字体，使中文字符在图表中能正常显示。用于无法找到沙盒中存在的支持中文的字体的情况。
        
        ### 函数_setup_matplotlib()
        
        > 设置字体（调用上面两个函数）。
        
        ### 类ExcelProcessor
        
        > 用于操作单个Excel文件的基础模块，不存在与用户交互。
        
        #### 方法search(file_path, primary_key, secondary_key)
        
        > 根据主键primary_key和secondary_key，搜索位于路径file_path的Excel文件，并将搜索结果返回。
        
        #### 方法append(file_path, values)
        
        > 向位于路径file_path的Excel文件添加一行新的数据，数据的值由values指定。
        
        #### 方法delete(file_path, row_indexes)
        
        > 从位于路径file_path的Excel文件中删除一些行，具体哪些行由行的索引row_indexes指定。
        
        #### 方法update(file_path, row_indexes, column_index, new_value)
        
        > 修改位于路径file_path的Excel文件中的一些行，将这些行的指定列的取值更改为new_value。具体哪些行由行的索引row_indexes指定，具体哪一列由列的索引column_index指定。
        
        #### 方法read_all(file_path)
        
        > 读取位于路径file_path的Excel文件的所有数据并返回。
        
        #### 方法read_headers(file_path)
        
        > 读取位于路径file_path的Excel文件的表头并返回。
        
        #### 方法draw_chart(cls, file_path, chart_type, horizontal_axis, vertical_axis, method, title, output_path
        
        > 绘制图表。
        >
        > file_path：提供数据的Excel文件的路径
        >
        > chart_type：图表类型：柱状图、饼图、折线图
        >
        > horizontal_axis：Excel文件中用作横坐标的列名
        >
        > vertical_axis：Excel文件中用来计算图表纵坐标值（柱状图或折线图）或统计值（饼图）的列的名字
        >
        > method：计算纵坐标值（柱状图或折线图）或统计值（饼图）的方法：计数或加和
        >
        > title：图表标题
        >
        > output_path：图表保存的路径
        
        #### 方法post_draw_line_chart(df, axis)
        
        > 折线图特殊处理，用于调整折线图的刻度显示，使其与柱状图在样式上风格一致。
        >
        > df：数据源。
        >
        > axis：图表对象。
        
        ## 文件file_keeper.py
        
        > 该文件包含了类FileKeeper及其实例。
        
        ### 类FileKeeper
        
        > 文件“管家”。管理工作目录下的Excel文件列表和全部文件的列表。每个文件都有自己的索引。可用该索引获取文件名和文件路径，并进行相关操作。这是一个基础功能模块，不存在与用户交互。
        
        #### 构造器_init__(self, dir_path)
        
        > 构造该类的实例。
        
        #### 方法refresh(self)
        
        > 更新文件列表。
        
        #### 属性all_files(self)
        
        > 全部文件的列表。字典类型：键为索引，值为文件名。
        
        #### 属性excel_files(self)
        
        > 全部Excel文件的列表。字典类型：键为索引，值为文件名。
        
        #### 方法get_file_path(self, index)
        
        > 根据文件索引，获取文件的路径。
        
        #### 方法print_excel_files(self, indexes=None)
        
        > 打印所有Excel文件。可选参数indexes是文件索引，可以用于选择要打印的文件。
        
        #### 方法print_all_files(self)
        
        > 打印所有文件。
        
        ## 文件handler.py
        
        ### 函数_split(str_)
        
        > 把用户输入的数据按分隔符分割。
        
        ### 函数_to_index_list(file_indexes)
        
        > 把用户输入的文件索引转化成索引列表。
        
        ### 函数print_headers(file_path, prompt='')
        
        > 打印位于file_path的Excel文件的表头。其中的prompt是打印在表头前的提示信息，默认为空。
        
        ### 函数print_match_detail(matches, primary_key, secondary_key)
        
        > 打印以primary_key为主键、以secondary_key为次键的Excel查询结果的详细信息：查询命中的文件名和具体数据行。
        
        ### 函数print_match_summary(matches)
        
        > 打印以primary_key为主键、以secondary_key为次键的Excel查询结果的概要信息：查询命中的文件名。
        
        ### 函数excel_search(primary_key, secondary_key='')
        
        > 以主键primary_key和次键secondary_key对Excel文件进行搜索。所需要的其它信息会要求用户进行输入。其中的secondary_key为可选参数，默认为空字符串。
        
        ### 函数excel_files(path)
        
        > 打印工作目录下的Excel文件名。参数path并无作用，只是为了满足`spring.py`的需要。
        
        ### 函数excel_add(file_indexes)
        
        > 向索引file_indexes指定的Excel文件添加新的一行数据。所需要的其它信息会要求用户进行输入。
        
        ### 函数excel_delete(matches, file_indexes)
        
        > 根据查询结果，对索引file_indexes指定的Excel文件进行删除操作。所需要的其它信息会要求用户进行输入。
        
        ### 函数excel_headers(file_indexes, prompt='表格的表头是: ')
        
        > 打印file_indexes指定的Excel文件中第1个文件的表头。其中的prompt是打印在表头前的提示信息。
        
        ### 函数excel_update(matches, file_indexes, column)
        
        > 根据查询结果matches，对文件索引file_indexes指定的Excel文件的列进行更新。具体是哪个列由参数column决定。所需要的其它信息会要求用户进行输入。
        
        ### 函数auto_picture()
        
        > 绘制图表。所需要的信息会要求用户进行输入。
        
        ### 函数auto_email()
        
        > 发送邮件。所需要的信息会要求用户进行输入。
        
        ## 文件spring.py
        
        ### 函数auto_add()
        
        > 向工作目录下的部分或全部Excel文件添加新的一行数据，然后打印新增的行等信息。所需要的全部信息会要求用户进行输入。
        
        ### 函数auto_search()
        
        > 对工作目录下的部分或全部Excel文件中的数据进行搜索，打印搜索结果。所需要的全部信息会要求用户进行输入。
        
        ### 函数auto_delete()
        
        > 删除工作目录下的部分或全部Excel文件中符合特定条件的行，随后打印删除操作是否成功等结果信息。所需要的全部信息会要求用户进行输入。
        
        ### 函数auto_update()
        
        > 对工作目录下的部分或全部Excel文件中符合特定条件的行，随后打印更新操作产生的效果等结果信息。所需要的全部信息会要求用户进行输入。
        
        ### 函数pro_controller()
        
        > 入口函数。在终端上提供菜单，让用户选择欲进行的Excel操作，并调用相应函数（上面所列函数）。
        
        ## 文件Utils.py
        
        > 包含工具类Utils。
        
        ### 类Utils
        
        #### 方法to_chart_type(type_repr)
        
        > 把图表种类对外展现的名称转化为内部表示。转化失败时返回None。
        
        #### 方法to_method_type(type_repr)
        
        > 把图表纵坐标（柱状图或折线图）或统计量（饼图）计算方法对外展现的名称转化为内部表示。转化失败时返回None。
        
        #### 方法get_all_methods(delimeter='/')
        
        > 把程序所支持的、图表纵坐标（柱状图或折线图）或统计量（饼图）的所有计算方法（计数或加和）对外展现的名称用分隔符连接起来，得到字符串供调用者进行打印。分隔符的默认值为`'/'`。
        
        #### 方法send_mail(to_mail, from_mail, auth_code, body, file_paths=None)
        
        > 以to_mail为目标邮箱、from_mail为发送人邮箱、auth_code为发送邮件所需要的授权码、body为邮件正文、file_paths为邮件附件，发送邮件。file_paths默认为`None`，表示邮件不带附件。
        
        ## 文件requirements.txt
        
        存放程序依赖的第三方库的名称和版本。
        
        通常只在安装依赖项时有用（见前面步骤），一般无需理会。
        
        ```
        cycler==0.10.0
        et-xmlfile==1.0.1
        jdcal==1.4.1
        kiwisolver==1.1.0
        matplotlib==3.1.2
        numpy==1.18.1
        openpyxl==3.0.2
        pandas==0.25.3
        pyparsing==2.4.6
        python-dateutil==2.8.1
        pytz==2019.3
        six==1.13.0
        ```
        
        # 高级设置
        
        如果不希望把Excel文件放在`static`文件夹中，可在终端中设置环境变量，将当前目录切换至`spring.py`文件所在文件夹。Linux/Mac下的具体命令是：
        
        ```
        export FBD_DIR_PATH=Excel文件所在的路径
        ```
        
        Windows下的具体命令是：
        
        ```
        set FBD_DIR_PATH=Excel文件所在的路径
        ```
        
        # 开发规范
        
        ## 安装
        
        欲安装依赖项，可参考命令：
        ```
        pip install -r requirements.txt  -i https://pypi.tuna.tsinghua.edu.cn/simple 
        ```
        
        ## 代码规范
        
        ### flake8
        
        检查代码规范符合程度：
        ```
        flake8 .
        ```
        
        如果使用了虚拟环境，可能需要使用：
        ```
        flake8 . --exclude=env名称
        ```
        
        ### autopep8
        
        尝试自动修复规范错误：
        ```
        autopep8 -i --exclude spring.py -r .
        ```
        
        ## 单元测试
        
        
        建议优先使用coverage方式，并通过它报告的覆盖率是否在90%左右，来判断程序功能是否异常。这是因为，目前的单测重点落在跑通功能，而没有对运行结果做过多的检测。也就是说，即使过程当中有一些错误，单测可能也不会报告出来。这时，如果覆盖率比较大，则过程当中很可能就没有出错。当然，以后应该把对结构的检测补上。
        
        
        ### 准备
        
        环境变量准备：
        
        项目使用dotenv从.env配置文件中读取环境变量。这些环境变量目前主要由开发自已用来单元测试，并没有面向用户。
        
        当前可配置的环境变量如下：
        
        ```
        FROM_MAIL=源邮箱地址
        AUTH_CODE=认证码
        TO_MAILS=目标邮箱地址
        CC_MAILS=抄送邮箱地址
        ```
        
        如果想通过环境变量更改“excel所在文件夹”，可参考前面“高级设置”。也可以写在.env中。
        
        
        ### unittest
        
        执行整个测试文件中的测试
        ```
        PYTHONPATH=. pytest
        ```
        
        执行单个测试用例类
        ```
        PYTHONPATH=. pytest flash_handler/tests/test_basic.py::TestSpring
        ```
        
        执行单个测试用例类的方法
        ```
        PYTHONPATH=. pytest flash_handler/tests/test_basic.py::TestSpring::test_auto_add
        ```
        
        如果使用pipenv，可以在项目根目录执行如下命令：
        ```
        pipenv run pytest
        ```
        
        ### coverage
        
        用coverage跑单元测试：
        ```
        coverage run --source . -m pytest
        ```
        
        生成代码覆盖率概要信息：
        ```
        coverage report -m
        ```
        
        生成代码覆盖率html文件：
        ```
        coverage html
        ```
        随后，可在`htmlcov`文件夹中打开`index.html`，观看覆盖率数据。
        
        
        # 上传至pypi？
        
        ## 主要参考
        - [How to Publish an Open-Source Python Package to PyPI](https://realpython.com/pypi-publish-python-package/)
        
        ## 主要步骤
        
        - 准备
          - 安装twine
            `pip install twine`
          - 在TestPyPI上注册账号。这里可用公司个人邮箱。其实自个儿邮箱也没问题，因为这个网站本身就是供发包人进行测试用的。
          - 在PyPI上注册账号。这里可用公司个人邮箱。
        - 修改setup.py
          - 作者、邮箱、版本、license等
        - 打包
          `python setup.py sdist`
        - 测试打出的包
          - 检查包中文件：`tar tzf XXX-X.X.X.tar.gz`
          - 检查包的描述是否会在pypi上被正确地展示：`twine check dist/*`
          - 上传至TestPyPI进行测试
            - 上传命令：`twine upload --repository-url https://test.pypi.org/legacy/ dist/*`
            - 上传后，即可在TestPyPI上查看该包。
            - 在新的环境上测试包的安装和使用：
              - 可从TestPyPI上把包手动下载下来，方便用国内源。
              - 然后在终端中切换到包所在的文件夹，使用下面命令去安装:
                `pip install 下载下来的包名 -i https://pypi.tuna.tsinghua.edu.cn/simple`
              - 在终端或脚本中，用`from flash_handler import handler`来导入`handler`，对其进行测试。
        
        ## 注意
        
        **千万别发⼀个不可⽤的包。**别的不说，pypi不允许名字重⽤。如果发了⼀个不可⽤包，下次发包时，版本号肯定得变（通常是变
        ⼤）。
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown
