├── .github └── workflows │ ├── test-dep.yml │ ├── test-install.yml │ └── test-py.yml ├── .gitignore ├── LICENSE.txt ├── NEWS.rst ├── README.rst ├── gtabview ├── __init__.py ├── compat.py ├── dataio.py ├── models.py ├── qtpy.py └── viewer.py ├── gtabview_cli ├── __init__.py └── gtabview.py ├── sample ├── data_ohlcv.csv ├── excel.xls ├── multiindex_H2_I4.csv ├── pandas-example.py ├── test_latin-1.csv └── unicode-example-utf8.txt ├── setup.py └── tests ├── __init__.py ├── data ├── empty-line-1.txt ├── empty-line-2.txt ├── hash-headers.txt ├── not-xls.xls ├── simple.csv └── simple.xls ├── test_dataio.py ├── test_models.py └── test_view.py /.github/workflows/test-dep.yml: -------------------------------------------------------------------------------- 1 | name: Test optional dependencies in isolation 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | name: test set ${{ matrix.dependency-set }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: ["ubuntu-latest"] 13 | python-version: ["3"] 14 | dependency-set: 15 | - "" 16 | - numpy 17 | - pandas 18 | - xlrd 19 | - pandas numpy xlrd 20 | defaults: 21 | run: 22 | shell: bash -l {0} 23 | steps: 24 | - name: Checkout sources 25 | uses: actions/checkout@v2 26 | - name: Setup Conda 27 | uses: conda-incubator/setup-miniconda@v2 28 | with: 29 | auto-update-conda: true 30 | python-version: ${{ matrix.python-version }} 31 | activate-environment: test 32 | - name: Install dependencies 33 | run: | 34 | conda install setuptools pyqt nose ${{ matrix.dependency-set }} 35 | - name: Silence fontconfig 36 | run: | 37 | fc-cache 38 | - name: Run tests 39 | env: 40 | XDG_RUNTIME_DIR: ${{ runner.temp }} 41 | run: | 42 | xvfb-run --auto-servernum nosetests -v 43 | -------------------------------------------------------------------------------- /.github/workflows/test-install.yml: -------------------------------------------------------------------------------- 1 | name: Test cli installation 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | name: test install 8 | runs-on: "ubuntu-latest" 9 | defaults: 10 | run: 11 | shell: bash -l {0} 12 | steps: 13 | - name: Checkout sources 14 | uses: actions/checkout@v2 15 | - name: Setup Conda 16 | uses: conda-incubator/setup-miniconda@v2 17 | with: 18 | auto-update-conda: true 19 | python-version: 3 20 | activate-environment: test 21 | - name: Install dependencies 22 | run: | 23 | conda install setuptools 24 | - name: Run install 25 | run: | 26 | python setup.py install 27 | - name: Run gtabview 28 | run: | 29 | gtabview -h 30 | -------------------------------------------------------------------------------- /.github/workflows/test-py.yml: -------------------------------------------------------------------------------- 1 | name: Test on different Python versions 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | name: test python ${{ matrix.python-version }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: ["ubuntu-latest"] 13 | python-version: ["3.9", "3.8", "3.7", "2.7"] 14 | defaults: 15 | run: 16 | shell: bash -l {0} 17 | steps: 18 | - name: Checkout sources 19 | uses: actions/checkout@v2 20 | - name: Setup Conda 21 | uses: conda-incubator/setup-miniconda@v2 22 | with: 23 | auto-update-conda: true 24 | python-version: ${{ matrix.python-version }} 25 | activate-environment: test 26 | - name: Install dependencies 27 | run: | 28 | conda install setuptools pyqt nose pandas numpy xlrd 29 | - name: Silence fontconfig 30 | run: | 31 | fc-cache 32 | - name: Run tests 33 | env: 34 | XDG_RUNTIME_DIR: ${{ runner.temp }} 35 | run: | 36 | xvfb-run --auto-servernum nosetests -v 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | /*.egg-info/ 4 | /.eggs/ 5 | /build/ 6 | /dist/ 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright(c) 2014-2021: Yuri D'Elia "wave++" 2 | Copyright(c) 2014-2015: Scott Hansen 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /NEWS.rst: -------------------------------------------------------------------------------- 1 | gtabview 0.10.1 2 | --------------- 3 | 4 | * Fixes an issue with column autosizing leading to a division by zero on 5 | some systems. 6 | 7 | gtabview 0.10 8 | ------------- 9 | 10 | * Fixes interactive support within IPython and Jupyter notebooks. 11 | 12 | 13 | gtabview 0.9 14 | ------------ 15 | 16 | * All iterables with a known length (such as sets) can now be visualized 17 | as regular columns without an explicit conversion. 18 | * Sets and dictionary keys are now displayed in native order by default. 19 | A new ``sort`` keyword has been added to enforce ordering again. 20 | * Fixes column autosizing error with Python 3.7+ 21 | * A crash that could occur during shutdown with a running detached view 22 | and Qt5 has been fixed. 23 | * The ``gtabview`` utility is now installed via ``console_scripts``, 24 | fixing usage on Windows platforms. 25 | * Removed support for Blaze, due to broken/unmaintained upstream. 26 | * Version information is now available as a command line via 27 | ``--version`` and in the module itself ``gtabview.__version__``. 28 | 29 | 30 | gtabview 0.8 31 | ------------ 32 | 33 | * Added support for PyQt5 34 | 35 | 36 | gtabview 0.7.1 37 | -------------- 38 | 39 | * Sequences of bytes/strings are now correcly shown as a single column. 40 | 41 | 42 | gtabview 0.7 43 | ------------ 44 | 45 | * More irregular/malformed data structures are now supported. 46 | * Any missing value supported by NumPy/Pandas (such as NaT) is now displayed as 47 | an empty cell for consistency. 48 | * Column-autosizing performance tweaks. 49 | 50 | 51 | gtabview 0.6.1 52 | -------------- 53 | 54 | * Fix exception with PySide. 55 | * Fix segmentation fault in repeated calls to view() in stand-alone programs. 56 | 57 | 58 | gtabview 0.6 59 | ------------ 60 | 61 | * Improved column auto-sizing. 62 | * NaNs (as None) are now also displayed as empty cells. 63 | * Empty structures no longer cause view() to fail. 64 | 65 | 66 | gtabview 0.5 67 | ------------ 68 | 69 | * Correctly pass user-supplied encoding to Blaze. 70 | * Fix color palette selection on Windows. 71 | 72 | 73 | gtabview 0.4 74 | ------------ 75 | 76 | * Added support for Blaze (http://blaze.pydata.org) 77 | * Improved documentation. 78 | 79 | 80 | gtabview 0.3 81 | ------------ 82 | 83 | * Headers and indexes can now be resized. 84 | * Level names in ``pd.DataFrame`` objects are now shown. 85 | * Negative ``start_pos`` offsets are now allowed to conveniently position the 86 | cursor counting from the end of the dataset. 87 | 88 | 89 | gtabview 0.2 90 | ------------ 91 | 92 | * Fix visualization of ``np.matrix`` types. 93 | * Allow data transposition. 94 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | gtabview: a simple graphical tabular data viewer 2 | ================================================ 3 | 4 | Graphical counterpart to `tabview 5 | `_, a simple tabular data viewer 6 | that can be used both stand-alone and as a Python module for various 7 | files and Python/Pandas/NumPy data structures. 8 | 9 | 10 | Stand-alone usage 11 | ----------------- 12 | 13 | `gtabview` reads most text tabular data formats automatically:: 14 | 15 | gtabview data.csv 16 | gtabview data.txt 17 | 18 | If xlrd_ is installed, Excel files can be read directly:: 19 | 20 | gtabview file.xls[x] 21 | 22 | .. _xlrd: https://pypi.org/project/xlrd/ 23 | 24 | 25 | Usage as a module 26 | ----------------- 27 | 28 | ``gtabview.view()`` can be used to display simple Python types directly 29 | in tabulated form: 30 | 31 | .. code:: python 32 | 33 | from gtabview import view 34 | 35 | # view a file 36 | view("/path/to/file") 37 | 38 | # view a list 39 | view([1, 2, 3]) 40 | 41 | # view a dict (by columns) 42 | view({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}) 43 | 44 | # view a dict (by rows) 45 | view({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}, transpose=True) 46 | 47 | # view a simple list of lists 48 | view([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 49 | 50 | # view a simple list of lists (with headers) 51 | view([['a', 'b', 'c'], [1, 2, 3], [4, 5, 6], [7, 8, 9]], hdr_rows=1) 52 | 53 | `gtabview` includes native support for NumPy and all features of Pandas' 54 | DataFrames, such as MultiIndexes and level names: 55 | 56 | .. code:: python 57 | 58 | from gtabview import view 59 | 60 | # numpy arrays up to two dimensions are supported 61 | import numpy as np 62 | view(np.array([[1, 2, 3], [4, 5, 6]])) 63 | 64 | # view a DataFrame/Series/Panel 65 | import pandas as pd 66 | df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], 67 | columns=['a', 'b', 'c'], index=['x', 'y']) 68 | view(df) 69 | 70 | `gtabview` is designed to integrate correctly with `IPython`, `Jupyter` 71 | and `matplotlib`. 72 | 73 | When `matplotlib` is used, `gtabview` will automatically default to use 74 | mpl's ``interactive`` setting to determine the default behavior of the 75 | data window: when interactive, calls to ``view()`` will not block, and 76 | will keep recycling the same window. 77 | 78 | In `IPython` and `Jupyter` notebooks ``view()`` calls also default to 79 | non-blocking behavior, while in plain Python calls will halt until the 80 | window is closed. 81 | 82 | You can change this behavior with the ``view(..., wait=False)`` argument 83 | for each call, or by changing the module default:: 84 | 85 | import gtabview 86 | gtabview.WAIT = False 87 | 88 | In a `Jupyter` notebook a *separate* data window will always show. The 89 | window can be kept around or closed, but will only be refreshed when 90 | evaluating the cell again. 91 | 92 | Separate data windows can also be opened by using the ``view(..., 93 | recycle=False)`` argument, or again by setting the global 94 | ``gtabview.RECYCLE`` default. See the built-in documentation of 95 | ``gtabview.view`` for more details. 96 | 97 | 98 | Requirements and installation 99 | ----------------------------- 100 | 101 | `gtabview` is available directly on the `Python Package Index 102 | `_ and on `conda-forge 103 | `_. 104 | 105 | `gtabview` requires: 106 | 107 | - Python 3 or Python 2 108 | - PyQt5, PyQt4 or PySide 109 | - setuptools (install-only) 110 | 111 | Under Debian/Ubuntu, install the required dependencies with:: 112 | 113 | sudo apt-get install python3 python3-pyqt5 114 | sudo apt-get install python3-setuptools 115 | 116 | Then download and install simply via pip:: 117 | 118 | pip install gtabview 119 | 120 | Or with conda:: 121 | 122 | conda install -c conda-forge gtabview 123 | 124 | You explicitly need to install ``xlrd`` if direct reading of Excel files 125 | is desired:: 126 | 127 | pip install xlrd 128 | 129 | 130 | License 131 | ------- 132 | 133 | | gtabview is distributed under the MIT license (see ``LICENSE.txt``) 134 | | Copyright(c) 2014-2021: wave++ "Yuri D'Elia" 135 | | Copyright(c) 2014-2015: Scott Hansen 136 | -------------------------------------------------------------------------------- /gtabview/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | import inspect 5 | import sys 6 | import warnings 7 | 8 | from gtabview_cli import __version__ 9 | from .compat import * 10 | from .dataio import read_model 11 | from .viewer import QtGui, QtCore, QtWidgets 12 | from .viewer import Viewer 13 | 14 | 15 | # view defaults 16 | WAIT = None # When None, use matplotlib.is_interactive (if already imported) 17 | RECYCLE = True # Keep reusing the same window instead of creating new ones 18 | 19 | # Global ViewControler for instance recycling 20 | APP = None 21 | VIEW = None 22 | 23 | 24 | class ViewController(object): 25 | def __init__(self): 26 | super(ViewController, self).__init__() 27 | self._view = None 28 | 29 | def visible(self): 30 | if self._view is None: 31 | return False 32 | return self._view.isVisible() 33 | 34 | def wait(self): 35 | if self._view is None: 36 | return 37 | while self._view.isVisible(): 38 | APP.processEvents(QtCore.QEventLoop.AllEvents | 39 | QtCore.QEventLoop.WaitForMoreEvents) 40 | 41 | def view(self, data, view_kwargs, wait, recycle): 42 | global APP 43 | APP = QtWidgets.QApplication.instance() 44 | if APP is None: 45 | APP = QtWidgets.QApplication([]) 46 | if self._view is None or not recycle: 47 | self._view = Viewer() 48 | self._view.view(data, **view_kwargs) 49 | if wait: 50 | self.wait() 51 | 52 | 53 | def _varname_in_stack(var, skip): 54 | frame = inspect.currentframe().f_back 55 | while skip: 56 | frame = frame.f_back 57 | if not frame: return None 58 | skip -= 1 59 | for name in frame.f_locals: 60 | if frame.f_locals[name] is var: 61 | return name 62 | return None 63 | 64 | 65 | def view(data, enc=None, start_pos=None, delimiter=None, hdr_rows=None, 66 | idx_cols=None, sheet_index=0, transpose=False, wait=None, 67 | recycle=None, detach=None, metavar=None, title=None, sort=False): 68 | """View the supplied data in an interactive, graphical table widget. 69 | 70 | data: When a valid path or IO object, read it as a tabular text 71 | file. Any other supported datatype is visualized directly and 72 | incrementally *without copying*. 73 | 74 | enc: File encoding (such as "utf-8", normally autodetected). 75 | 76 | delimiter: Text file delimiter (normally autodetected). 77 | 78 | hdr_rows: For files or lists of lists, specify the number of header rows. 79 | For files only, a default of one header line is assumed. 80 | 81 | idx_cols: For files or lists of lists, specify the number of index columns. 82 | By default, no index is assumed. 83 | 84 | sheet_index: For multi-table files (such as xls[x]), specify the sheet 85 | index to read, starting from 0. Defaults to the first. 86 | 87 | start_pos: A tuple of the form (y, x) specifying the initial cursor 88 | position. Negative offsets count from the end of the dataset. 89 | 90 | transpose: Transpose the resulting view. 91 | 92 | sort: Request sorting of sets and keys of dicts where ordering is 93 | *normally* not meaningful. 94 | 95 | metavar: name of the variable being shown for display purposes (inferred 96 | automatically when possible). 97 | 98 | title: title of the data window. 99 | 100 | wait: Wait for the user to close the view before returning. By default, try 101 | to match the behavior of ``matplotlib.is_interactive()``. If 102 | matplotlib is not loaded, wait only if ``detach`` is also False. The 103 | default value can also be set through ``gtabview.WAIT``. 104 | 105 | recycle: Recycle the previous window instead of creating a new one. The 106 | default is True, and can also be set through ``gtabview.RECYCLE``. 107 | 108 | detach: Ignored for backward compatibility. 109 | """ 110 | global WAIT, RECYCLE, VIEW 111 | 112 | model = read_model(data, enc=enc, delimiter=delimiter, hdr_rows=hdr_rows, 113 | idx_cols=idx_cols, sheet_index=sheet_index, 114 | transpose=transpose, sort=sort) 115 | if model is None: 116 | warnings.warn("cannot visualize the supplied data type: {}".format(type(data)), 117 | category=RuntimeWarning) 118 | return None 119 | 120 | # install gui hooks in ipython/jupyter 121 | gui_support = False 122 | if 'IPython' in sys.modules: 123 | from IPython import get_ipython 124 | ip = get_ipython() 125 | if ip is not None: 126 | ip.enable_gui('qt') 127 | gui_support = True 128 | 129 | # setup defaults 130 | if wait is None: wait = WAIT 131 | if recycle is None: recycle = RECYCLE 132 | if wait is None: 133 | if 'matplotlib' in sys.modules: 134 | import matplotlib.pyplot as plt 135 | wait = not plt.isinteractive() 136 | else: 137 | wait = not gui_support 138 | 139 | # try to fetch the variable name in the upper stack 140 | if metavar is None: 141 | if isinstance(data, basestring): 142 | metavar = data 143 | else: 144 | metavar = _varname_in_stack(data, 1) 145 | 146 | # create a view controller 147 | if VIEW is None: 148 | VIEW = ViewController() 149 | 150 | # actually show the data 151 | view_kwargs = {'hdr_rows': hdr_rows, 'idx_cols': idx_cols, 152 | 'start_pos': start_pos, 'metavar': metavar, 'title': title} 153 | VIEW.view(model, view_kwargs, wait=wait, recycle=recycle) 154 | return VIEW 155 | -------------------------------------------------------------------------------- /gtabview/compat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import io, sys 3 | 4 | if sys.version_info.major < 3: 5 | # Python 2.7 shim 6 | str = unicode 7 | else: 8 | basestring = str 9 | file = io.FileIO 10 | -------------------------------------------------------------------------------- /gtabview/dataio.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | import io 5 | import os 6 | import sys 7 | import warnings 8 | 9 | from .compat import * 10 | from .models import as_model 11 | 12 | 13 | def _detect_encoding(data=None): 14 | """Return the default system encoding. If data is passed, try 15 | to decode the data with the default system encoding or from a short 16 | list of encoding types to test. 17 | 18 | Args: 19 | data - list of lists 20 | Returns: 21 | enc - system encoding 22 | """ 23 | import locale 24 | enc_list = ['utf-8', 'latin-1', 'iso8859-1', 'iso8859-2', 25 | 'utf-16', 'cp720'] 26 | code = locale.getpreferredencoding(False) 27 | if data is None: 28 | return code 29 | if code.lower() not in enc_list: 30 | enc_list.insert(0, code.lower()) 31 | for c in enc_list: 32 | try: 33 | for line in data: 34 | line.decode(c) 35 | except (UnicodeDecodeError, UnicodeError, AttributeError): 36 | continue 37 | return c 38 | print("Encoding not detected. Please pass encoding value manually") 39 | 40 | 41 | def _parse_lines(data, enc=None, delimiter=None): 42 | import csv 43 | if enc is None: 44 | enc = _detect_encoding(data) 45 | if delimiter is None: 46 | delimiter = csv.Sniffer().sniff(data[0].decode(enc)).delimiter 47 | csv_data = [] 48 | if sys.version_info.major < 3: 49 | csv_obj = csv.reader(data, delimiter=delimiter.encode(enc)) 50 | for row in csv_obj: 51 | row = [x.decode(enc) for x in row] 52 | csv_data.append(row) 53 | else: 54 | data = [i.decode(enc) for i in data] 55 | csv_obj = csv.reader(data, delimiter=delimiter) 56 | for row in csv_obj: 57 | csv_data.append(row) 58 | return csv_data 59 | 60 | 61 | 62 | def read_csv(fd_or_path, enc, delimiter, hdr_rows): 63 | if isinstance(fd_or_path, (io.IOBase, file)): 64 | return _parse_lines(fd_or_path.readlines(), enc, delimiter) 65 | with open(fd_or_path, 'rb') as fd: 66 | return _parse_lines(fd.readlines(), enc, delimiter) 67 | 68 | 69 | def read_xlrd(path, sheet_index): 70 | import xlrd 71 | with xlrd.open_workbook(path, on_demand=True, ragged_rows=True) as wb: 72 | sheet = wb.sheet_by_index(sheet_index) 73 | return [sheet.row_values(row) for row in range(sheet.nrows)] 74 | 75 | 76 | def read_table(fd_or_path, enc, delimiter, hdr_rows, sheet_index=0): 77 | data = None 78 | 79 | # read into a list of lists 80 | if not isinstance(fd_or_path, (io.IOBase, file)): 81 | _, ext = os.path.splitext(fd_or_path) 82 | if ext.lower() in ['.xls', '.xlsx']: 83 | try: 84 | import xlrd 85 | data = read_xlrd(fd_or_path, sheet_index) 86 | except ImportError: 87 | warnings.warn("xlrd module not installed") 88 | except xlrd.XLRDError: 89 | pass 90 | if data is None: 91 | data = read_csv(fd_or_path, enc, delimiter, hdr_rows) 92 | 93 | if hdr_rows is None and len(data) > 1: 94 | hdr_rows = 1 95 | 96 | # chop a leading '#' in the headers 97 | if hdr_rows and len(data) >= hdr_rows: 98 | for row in range(hdr_rows): 99 | if len(data[row]) \ 100 | and isinstance(data[row][0], basestring) \ 101 | and len(data[row][0]) > 1 \ 102 | and data[row][0][0] == '#': 103 | data[0][0] = data[0][0][1:] 104 | 105 | # skip an empty line after the header 106 | if hdr_rows and len(data) > hdr_rows + 1: 107 | empty = True 108 | for col in data[hdr_rows]: 109 | if col is not None and len(str(col)): 110 | empty = False 111 | break 112 | if empty: 113 | del data[hdr_rows] 114 | 115 | return data, hdr_rows 116 | 117 | 118 | def read_model(data, enc=None, delimiter=None, hdr_rows=None, idx_cols=None, 119 | sheet_index=0, transpose=False, sort=False): 120 | # if data is a uri/file/path, read it 121 | if isinstance(data, basestring) or isinstance(data, (io.IOBase, file)): 122 | data, hdr_rows = read_table(data, enc, delimiter, hdr_rows, sheet_index) 123 | 124 | # only assume an header when loading from a file 125 | if hdr_rows is None: hdr_rows = 0 126 | if idx_cols is None: idx_cols = 0 127 | 128 | return as_model(data, hdr_rows=hdr_rows, idx_cols=idx_cols, 129 | transpose=transpose, sort=sort) 130 | -------------------------------------------------------------------------------- /gtabview/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import, generators, division 3 | 4 | from .compat import * 5 | 6 | 7 | def getitem(lst, idx, default=None): 8 | return lst[idx] if idx < len(lst) else default 9 | 10 | def getitem2(lst, y, x, default=None): 11 | return getitem(getitem(lst, y, []), x, default) 12 | 13 | 14 | class ExtDataModel(object): 15 | @property 16 | def shape(self): 17 | raise Exception() 18 | 19 | @property 20 | def header_shape(self): 21 | raise Exception() 22 | 23 | def data(self, y, x): 24 | raise Exception() 25 | 26 | def header(self, axis, x, level): 27 | raise Exception() 28 | 29 | def name(self, axis, level): 30 | return 'L' + str(level) 31 | 32 | @property 33 | def chunk_size(self): 34 | return max(*self.shape()) 35 | 36 | def transpose(self): 37 | # TODO: remove from base model 38 | return TransposedExtDataModel(self) 39 | 40 | 41 | class TransposedExtDataModel(ExtDataModel): 42 | def __init__(self, model): 43 | super(TransposedExtDataModel, self).__init__() 44 | self._model = model 45 | 46 | @property 47 | def shape(self): 48 | x, y = self._model.shape 49 | return (y, x) 50 | 51 | @property 52 | def header_shape(self): 53 | x, y = self._model.header_shape 54 | return (y, x) 55 | 56 | def data(self, y, x): 57 | return self._model.data(x, y) 58 | 59 | def header(self, axis, x, level): 60 | return self._model.header(not axis, x, level) 61 | 62 | def name(self, axis, level): 63 | return self._model.name(not axis, level) 64 | 65 | def transpose(self): 66 | return self._model 67 | 68 | 69 | 70 | class ExtListModel(ExtDataModel): 71 | def __init__(self, data, hdr_rows=0, idx_cols=0): 72 | super(ExtListModel, self).__init__() 73 | self._header_shape = (hdr_rows, idx_cols) 74 | self._shape = (len(data) - hdr_rows, max(map(len, data)) - idx_cols) 75 | self._data = data 76 | 77 | @property 78 | def shape(self): 79 | return self._shape 80 | 81 | @property 82 | def header_shape(self): 83 | return self._header_shape 84 | 85 | def header(self, axis, x, level): 86 | if axis == 0: 87 | return getitem2(self._data, level, x + self._header_shape[1]) 88 | else: 89 | return getitem2(self._data, x + self._header_shape[0], level) 90 | 91 | def data(self, y, x): 92 | return getitem2(self._data, y + self._header_shape[0], 93 | x + self._header_shape[1]) 94 | 95 | 96 | class ExtMapModel(ExtDataModel): 97 | def __init__(self, data, sort=False): 98 | super(ExtMapModel, self).__init__() 99 | self._data = data 100 | self._keys = list(sorted(data.keys()) if sort else data.keys()) 101 | h = max([len(x) for x in data.values()]) if self._keys else 0 102 | self._shape = (h, len(self._keys)) 103 | 104 | @property 105 | def shape(self): 106 | return self._shape 107 | 108 | @property 109 | def header_shape(self): 110 | return (1, 0) 111 | 112 | def data(self, y, x): 113 | return getitem(self._data[self._keys[x]], y) 114 | 115 | def header(self, axis, x, level): 116 | return self._keys[x] 117 | 118 | 119 | class ExtVectorModel(ExtDataModel): 120 | def __init__(self, data): 121 | super(ExtVectorModel, self).__init__() 122 | self._data = data 123 | 124 | @property 125 | def shape(self): 126 | return (len(self._data), 1) 127 | 128 | @property 129 | def header_shape(self): 130 | return (0, 0) 131 | 132 | def data(self, y, x): 133 | return self._data[y] 134 | 135 | 136 | class ExtMatrixModel(ExtDataModel): 137 | def __init__(self, data): 138 | super(ExtMatrixModel, self).__init__() 139 | self._data = data 140 | 141 | @property 142 | def shape(self): 143 | return self._data.shape 144 | 145 | @property 146 | def header_shape(self): 147 | return (0, 0) 148 | 149 | def data(self, y, x): 150 | return self._data[y, x] 151 | 152 | 153 | class ExtFrameModel(ExtDataModel): 154 | def __init__(self, data): 155 | super(ExtFrameModel, self).__init__() 156 | self._data = data 157 | 158 | def _axis(self, axis): 159 | return self._data.columns if axis == 0 else self._data.index 160 | 161 | def _axis_levels(self, axis): 162 | ax = self._axis(axis) 163 | return 1 if not hasattr(ax, 'levels') \ 164 | else len(ax.levels) 165 | 166 | @property 167 | def shape(self): 168 | return self._data.shape 169 | 170 | @property 171 | def header_shape(self): 172 | return (self._axis_levels(0), self._axis_levels(1)) 173 | 174 | def data(self, y, x): 175 | return self._data.iat[y, x] 176 | 177 | def header(self, axis, x, level=0): 178 | ax = self._axis(axis) 179 | return ax.values[x] if not hasattr(ax, 'levels') \ 180 | else ax.values[x][level] 181 | 182 | def name(self, axis, level): 183 | ax = self._axis(axis) 184 | if hasattr(ax, 'levels'): 185 | return ax.names[level] 186 | if ax.name: 187 | return ax.name 188 | return super(ExtFrameModel, self).name(axis, level) 189 | 190 | 191 | def _data_lower(data, sort): 192 | if data.__class__.__name__ in ['Series', 'Panel']: 193 | # handle panels and series as frames 194 | return data.to_frame() 195 | if not hasattr(data, '__array__') and not hasattr(data, '__getitem__') and \ 196 | hasattr(data, '__iter__') and hasattr(data, '__len__'): 197 | # flatten iterables but non-indexables to lists (ie: sets) 198 | if sort and isinstance(data, (set, frozenset)): 199 | data = sorted(data) 200 | return list(data) 201 | 202 | return data 203 | 204 | 205 | def as_model(data, hdr_rows=0, idx_cols=0, transpose=False, sort=False): 206 | model = None 207 | if isinstance(data, ExtDataModel): 208 | model = data 209 | else: 210 | data = _data_lower(data, sort) 211 | 212 | if hasattr(data, '__array__') and hasattr(data, 'iat') and \ 213 | hasattr(data, 'index') and hasattr(data, 'columns'): 214 | model = ExtFrameModel(data) 215 | elif hasattr(data, '__array__') and len(data.shape) >= 2: 216 | model = ExtMatrixModel(data) 217 | elif hasattr(data, '__getitem__') and hasattr(data, '__len__') and \ 218 | hasattr(data, 'keys') and hasattr(data, 'values'): 219 | model = ExtMapModel(data, sort) 220 | elif hasattr(data, '__getitem__') and hasattr(data, '__len__') and len(data) and \ 221 | hasattr(data[0], '__getitem__') and hasattr(data[0], '__len__') and \ 222 | not isinstance(data[0], (bytes, str)): 223 | model = ExtListModel(data, hdr_rows=hdr_rows, idx_cols=idx_cols) 224 | elif hasattr(data, '__getitem__') and hasattr(data, '__len__'): 225 | model = ExtVectorModel(data) 226 | 227 | if transpose and model: 228 | model = model.transpose() 229 | return model 230 | -------------------------------------------------------------------------------- /gtabview/qtpy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # qtpy: wrapper to support PyQt5/PyQt4/PySide with either Python 2/3 3 | # Similar in spirit to QtPy, minus the dependency (as long as we can) 4 | import os, sys 5 | 6 | # Use existing Qt when previously loaded 7 | if 'QT_API' not in os.environ: 8 | if 'PyQt5' in sys.modules: 9 | os.environ['QT_API'] = 'pyqt5' 10 | elif 'PyQt4' in sys.modules: 11 | os.environ['QT_API'] = 'pyqt4' 12 | elif 'PySide' in sys.modules: 13 | os.environ['QT_API'] = 'pyside' 14 | 15 | # Autodetect what's available 16 | if 'QT_API' not in os.environ: 17 | try: 18 | import PyQt5 19 | os.environ['QT_API'] = 'pyqt5' 20 | except ImportError: 21 | pass 22 | if 'QT_API' not in os.environ: 23 | try: 24 | import PyQt4 25 | os.environ['QT_API'] = 'pyqt4' 26 | except ImportError: 27 | pass 28 | if 'QT_API' not in os.environ: 29 | try: 30 | import PySide 31 | os.environ['QT_API'] = 'pyside' 32 | except ImportError: 33 | pass 34 | 35 | # Actual module import 36 | if os.environ['QT_API'] == 'pyqt5': 37 | from PyQt5 import QtCore, QtGui, QtWidgets 38 | elif os.environ['QT_API'] == 'pyside': 39 | from PySide import QtCore, QtGui 40 | else: 41 | from PyQt4 import QtCore, QtGui 42 | 43 | # Qt5 stubs 44 | if os.environ['QT_API'] != 'pyqt5': 45 | QtWidgets = QtGui 46 | QtCore.QItemSelectionModel = QtGui.QItemSelectionModel 47 | -------------------------------------------------------------------------------- /gtabview/viewer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import, generators 3 | 4 | from .compat import * 5 | from .qtpy import QtCore, QtGui, QtWidgets 6 | 7 | import math 8 | import time 9 | import sys 10 | 11 | MAX_AUTOSIZE_MS = 150 # Milliseconds given (at most) to perform column auto-sizing 12 | MIN_TRUNC_CHARS = 8 # Minimum size (in characters) given to columns 13 | MAX_WIDTH_CHARS = 64 # Maximum size (in characters) given to columns 14 | 15 | 16 | # Clock source 17 | try: 18 | clock = time.monotonic 19 | except AttributeError: 20 | clock = time.clock 21 | 22 | 23 | # Support any missing value from Pandas efficiently 24 | def as_str_py(obj): 25 | if obj is None: return '' 26 | if isinstance(obj, float) and math.isnan(obj): return '' 27 | return str(obj) 28 | 29 | def get_as_str(): 30 | if 'pandas' in sys.modules: 31 | import pandas as pd 32 | return lambda x: '' if pd.isnull(x) else str(x) 33 | else: 34 | return as_str_py 35 | 36 | 37 | class Data4ExtModel(QtCore.QAbstractTableModel): 38 | def __init__(self, model): 39 | super(Data4ExtModel, self).__init__() 40 | self.model = model 41 | self._as_str = get_as_str() 42 | 43 | def rowCount(self, index=None): 44 | return max(1, self.model.shape[0]) 45 | 46 | def columnCount(self, index=None): 47 | return max(1, self.model.shape[1]) 48 | 49 | def data(self, index, role): 50 | if role != QtCore.Qt.DisplayRole: 51 | return None 52 | if index.row() >= self.model.shape[0] or \ 53 | index.column() >= self.model.shape[1]: 54 | return None 55 | return self._as_str(self.model.data(index.row(), index.column())) 56 | 57 | 58 | class Header4ExtModel(QtCore.QAbstractTableModel): 59 | def __init__(self, model, axis, palette): 60 | super(Header4ExtModel, self).__init__() 61 | self.model = model 62 | self.axis = axis 63 | self._palette = palette 64 | if self.axis == 0: 65 | self._shape = (self.model.header_shape[0], self.model.shape[1]) 66 | else: 67 | self._shape = (self.model.shape[0], self.model.header_shape[1]) 68 | self._as_str = get_as_str() 69 | 70 | def rowCount(self, index=None): 71 | return max(1, self._shape[0]) 72 | 73 | def columnCount(self, index=None): 74 | return max(1, self._shape[1]) 75 | 76 | def headerData(self, section, orientation, role): 77 | if role == QtCore.Qt.TextAlignmentRole: 78 | if orientation == QtCore.Qt.Horizontal: 79 | return QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom 80 | else: 81 | return QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter 82 | if role != QtCore.Qt.DisplayRole: 83 | return None 84 | orient_axis = 0 if orientation == QtCore.Qt.Horizontal else 1 85 | return section if self.axis == orient_axis else \ 86 | self.model.name(self.axis, section) 87 | 88 | def data(self, index, role): 89 | if not index.isValid() or \ 90 | index.row() >= self._shape[0] or \ 91 | index.column() >= self._shape[1]: 92 | return None 93 | row, col = (index.row(), index.column()) if self.axis == 0 \ 94 | else (index.column(), index.row()) 95 | if role == QtCore.Qt.BackgroundRole: 96 | prev = self.model.header(self.axis, col - 1, row) if col else None 97 | cur = self.model.header(self.axis, col, row) 98 | return self._palette.midlight() if prev != cur else None 99 | if role != QtCore.Qt.DisplayRole: 100 | return None 101 | return self._as_str(self.model.header(self.axis, col, row)) 102 | 103 | 104 | class Level4ExtModel(QtCore.QAbstractTableModel): 105 | def __init__(self, model, palette, font): 106 | super(Level4ExtModel, self).__init__() 107 | self.model = model 108 | self._background = palette.dark().color() 109 | if self._background.lightness() > 127: 110 | self._foreground = palette.text() 111 | else: 112 | self._foreground = palette.highlightedText() 113 | self._palette = palette 114 | font.setBold(True) 115 | self._font = font 116 | 117 | def rowCount(self, index=None): 118 | return max(1, self.model.header_shape[0]) 119 | 120 | def columnCount(self, index=None): 121 | return max(1, self.model.header_shape[1]) 122 | 123 | def headerData(self, section, orientation, role): 124 | if role == QtCore.Qt.TextAlignmentRole: 125 | if orientation == QtCore.Qt.Horizontal: 126 | return QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom 127 | else: 128 | return QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter 129 | if role != QtCore.Qt.DisplayRole: return None 130 | return 'L' + str(section) 131 | 132 | def data(self, index, role): 133 | if not index.isValid(): 134 | return None 135 | if role == QtCore.Qt.FontRole: 136 | return self._font 137 | if index.row() == self.model.header_shape[0] - 1: 138 | if role == QtCore.Qt.DisplayRole: 139 | return str(self.model.name(1, index.column())) 140 | elif role == QtCore.Qt.ForegroundRole: 141 | return self._foreground 142 | elif role == QtCore.Qt.BackgroundRole: 143 | return self._background 144 | elif index.column() == self.model.header_shape[1] - 1: 145 | if role == QtCore.Qt.DisplayRole: 146 | return str(self.model.name(0, index.row())) 147 | elif role == QtCore.Qt.ForegroundRole: 148 | return self._foreground 149 | elif role == QtCore.Qt.BackgroundRole: 150 | return self._background 151 | elif role == QtCore.Qt.BackgroundRole: 152 | return self._palette.window() 153 | return None 154 | 155 | 156 | class ExtTableView(QtWidgets.QWidget): 157 | def __init__(self): 158 | super(ExtTableView, self).__init__() 159 | self._selection_rec = False 160 | self._model = None 161 | 162 | # We manually set the inactive highlight color to differentiate the 163 | # selection between the data/index/header. To actually make use of the 164 | # palette though, we also have to manually assign a new stock delegate 165 | # to each table view 166 | palette = self.palette() 167 | tmp = palette.highlight().color() 168 | tmp.setHsv(tmp.hsvHue(), 100, palette.midlight().color().lightness()) 169 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, tmp) 170 | self.setPalette(palette) 171 | 172 | layout = QtWidgets.QGridLayout() 173 | layout.setSpacing(0) 174 | layout.setContentsMargins(0, 0, 0, 0) 175 | self.setLayout(layout) 176 | self.hscroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal) 177 | self.vscroll = QtWidgets.QScrollBar(QtCore.Qt.Vertical) 178 | 179 | self.table_level = QtWidgets.QTableView() 180 | self.table_level.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers) 181 | self.table_level.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 182 | self.table_level.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 183 | self.table_level.setFrameStyle(QtWidgets.QFrame.Plain) 184 | self.table_level.horizontalHeader().sectionResized.connect(self._index_resized) 185 | self.table_level.verticalHeader().sectionResized.connect(self._header_resized) 186 | self.table_level.setItemDelegate(QtWidgets.QItemDelegate()) 187 | layout.addWidget(self.table_level, 0, 0) 188 | 189 | self.table_header = QtWidgets.QTableView() 190 | self.table_header.verticalHeader().hide() 191 | self.table_header.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers) 192 | self.table_header.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 193 | self.table_header.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 194 | self.table_header.setHorizontalScrollMode(QtWidgets.QTableView.ScrollPerPixel) 195 | self.table_header.setHorizontalScrollBar(self.hscroll) 196 | self.table_header.setFrameStyle(QtWidgets.QFrame.Plain) 197 | self.table_header.horizontalHeader().sectionResized.connect(self._column_resized) 198 | self.table_header.setItemDelegate(QtWidgets.QItemDelegate()) 199 | layout.addWidget(self.table_header, 0, 1) 200 | 201 | self.table_index = QtWidgets.QTableView() 202 | self.table_index.horizontalHeader().hide() 203 | self.table_index.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers) 204 | self.table_index.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 205 | self.table_index.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 206 | self.table_index.setVerticalScrollMode(QtWidgets.QTableView.ScrollPerPixel) 207 | self.table_index.setVerticalScrollBar(self.vscroll) 208 | self.table_index.setFrameStyle(QtWidgets.QFrame.Plain) 209 | self.table_index.verticalHeader().sectionResized.connect(self._row_resized) 210 | self.table_index.setItemDelegate(QtWidgets.QItemDelegate()) 211 | layout.addWidget(self.table_index, 1, 0) 212 | 213 | self.table_data = QtWidgets.QTableView() 214 | self.table_data.verticalHeader().hide() 215 | self.table_data.horizontalHeader().hide() 216 | self.table_data.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers) 217 | self.table_data.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 218 | self.table_data.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 219 | self.table_data.setHorizontalScrollMode(QtWidgets.QTableView.ScrollPerPixel) 220 | self.table_data.setVerticalScrollMode(QtWidgets.QTableView.ScrollPerPixel) 221 | self.table_data.setHorizontalScrollBar(self.hscroll) 222 | self.table_data.setVerticalScrollBar(self.vscroll) 223 | self.table_data.setFrameStyle(QtWidgets.QFrame.Plain) 224 | self.table_data.setItemDelegate(QtWidgets.QItemDelegate()) 225 | layout.addWidget(self.table_data, 1, 1) 226 | self.setFocusProxy(self.table_data) 227 | 228 | layout.addWidget(self.hscroll, 2, 0, 2, 2) 229 | layout.addWidget(self.vscroll, 0, 2, 2, 2) 230 | 231 | # autosize columns on-demand 232 | self._autosized_cols = set() 233 | self._max_autosize_ms = None 234 | self.hscroll.sliderMoved.connect(self._resizeVisibleColumnsToContents) 235 | self.table_data.installEventFilter(self) 236 | 237 | avg_width = self.fontMetrics().averageCharWidth() 238 | self.min_trunc = avg_width * MIN_TRUNC_CHARS 239 | self.max_width = avg_width * MAX_WIDTH_CHARS 240 | 241 | 242 | def _select_columns(self, source, dest, deselect): 243 | if self._selection_rec: return 244 | self._selection_rec = True 245 | dsm = dest.selectionModel() 246 | ssm = source.selectionModel() 247 | dsm.clear() 248 | for col in (index.column() for index in ssm.selectedIndexes()): 249 | dsm.select(dest.model().index(0, col), 250 | QtCore.QItemSelectionModel.Select | QtCore.QItemSelectionModel.Columns) 251 | deselect.selectionModel().clear() 252 | self._selection_rec = False 253 | 254 | 255 | def _select_rows(self, source, dest, deselect): 256 | if self._selection_rec: return 257 | self._selection_rec = True 258 | dsm = dest.selectionModel() 259 | ssm = source.selectionModel() 260 | dsm.clear() 261 | for row in (index.row() for index in ssm.selectedIndexes()): 262 | dsm.select(dest.model().index(row, 0), 263 | QtCore.QItemSelectionModel.Select | QtCore.QItemSelectionModel.Rows) 264 | deselect.selectionModel().clear() 265 | self._selection_rec = False 266 | 267 | 268 | def model(self): 269 | return self._model 270 | 271 | def _column_resized(self, col, old_width, new_width): 272 | self.table_data.setColumnWidth(col, new_width) 273 | self._update_layout() 274 | 275 | def _row_resized(self, row, old_height, new_height): 276 | self.table_data.setRowHeight(row, new_height) 277 | self._update_layout() 278 | 279 | def _index_resized(self, col, old_width, new_width): 280 | self.table_index.setColumnWidth(col, new_width) 281 | self._update_layout() 282 | 283 | def _header_resized(self, row, old_height, new_height): 284 | self.table_header.setRowHeight(row, new_height) 285 | self._update_layout() 286 | 287 | def _update_layout(self): 288 | h_width = max(self.table_level.verticalHeader().sizeHint().width(), 289 | self.table_index.verticalHeader().sizeHint().width()) 290 | self.table_level.verticalHeader().setFixedWidth(h_width) 291 | self.table_index.verticalHeader().setFixedWidth(h_width) 292 | 293 | last_row = self._model.header_shape[0] - 1 294 | if last_row < 0: 295 | hdr_height = self.table_level.horizontalHeader().height() 296 | else: 297 | hdr_height = self.table_level.rowViewportPosition(last_row) + \ 298 | self.table_level.rowHeight(last_row) + \ 299 | self.table_level.horizontalHeader().height() 300 | self.table_header.setFixedHeight(hdr_height) 301 | self.table_level.setFixedHeight(hdr_height) 302 | 303 | last_col = self._model.header_shape[1] - 1 304 | if last_col < 0: 305 | idx_width = self.table_level.verticalHeader().width() 306 | else: 307 | idx_width = self.table_level.columnViewportPosition(last_col) + \ 308 | self.table_level.columnWidth(last_col) + \ 309 | self.table_level.verticalHeader().width() 310 | self.table_index.setFixedWidth(idx_width) 311 | self.table_level.setFixedWidth(idx_width) 312 | self._resizeVisibleColumnsToContents() 313 | 314 | 315 | def _reset_model(self, table, model): 316 | old_sel_model = table.selectionModel() 317 | table.setModel(model) 318 | if old_sel_model: 319 | del old_sel_model 320 | 321 | 322 | def setAutosizeLimit(self, limit_ms): 323 | self._max_autosize_ms = limit_ms 324 | 325 | 326 | def setModel(self, model, relayout=True): 327 | self._model = model 328 | self._reset_model(self.table_data, Data4ExtModel(model)) 329 | sel_model = self.table_data.selectionModel() 330 | sel_model.selectionChanged.connect( 331 | lambda *_: self._select_columns(self.table_data, self.table_header, self.table_level)) 332 | sel_model.selectionChanged.connect( 333 | lambda *_: self._select_rows(self.table_data, self.table_index, self.table_level)) 334 | sel_model.currentColumnChanged.connect(self._resizeCurrentColumnToContents) 335 | 336 | self._reset_model(self.table_level, Level4ExtModel(model, self.palette(), self.font())) 337 | sel_model = self.table_level.selectionModel() 338 | sel_model.selectionChanged.connect( 339 | lambda *_: self._select_columns(self.table_level, self.table_index, self.table_data)) 340 | sel_model.selectionChanged.connect( 341 | lambda *_: self._select_rows(self.table_level, self.table_header, self.table_data)) 342 | 343 | self._reset_model(self.table_header, Header4ExtModel(model, 0, self.palette())) 344 | sel_model = self.table_header.selectionModel() 345 | sel_model.selectionChanged.connect( 346 | lambda *_: self._select_columns(self.table_header, self.table_data, self.table_index)) 347 | sel_model.selectionChanged.connect( 348 | lambda *_: self._select_rows(self.table_header, self.table_level, self.table_index)) 349 | 350 | self._reset_model(self.table_index, Header4ExtModel(model, 1, self.palette())) 351 | sel_model = self.table_index.selectionModel() 352 | sel_model.selectionChanged.connect( 353 | lambda *_: self._select_rows(self.table_index, self.table_data, self.table_header)) 354 | sel_model.selectionChanged.connect( 355 | lambda *_: self._select_columns(self.table_index, self.table_level, self.table_header)) 356 | 357 | # needs to be called after setting all table models 358 | if relayout: self._update_layout() 359 | 360 | 361 | def setCurrentIndex(self, y, x): 362 | self.table_data.selectionModel().setCurrentIndex( 363 | self.table_data.model().index(y, x), 364 | QtCore.QItemSelectionModel.ClearAndSelect) 365 | 366 | def _sizeHintForColumn(self, table, col, limit_ms=None): 367 | # TODO: use current chunk boundaries, do not start from the beginning 368 | max_row = table.model().rowCount() 369 | lm_start = clock() 370 | lm_row = 64 if limit_ms else max_row 371 | max_width = 0 372 | for row in range(max_row): 373 | v = table.sizeHintForIndex(table.model().index(row, col)) 374 | max_width = max(max_width, v.width()) 375 | if row > lm_row: 376 | lm_now = clock() 377 | lm_elapsed = (lm_now - lm_start) * 1000 378 | if lm_elapsed >= limit_ms: 379 | break 380 | if lm_elapsed < 1: 381 | lm_row = lm_row * 2 382 | else: 383 | lm_row = int((row / lm_elapsed) * limit_ms) 384 | return max_width 385 | 386 | def _resizeColumnToContents(self, header, data, col, limit_ms): 387 | hdr_width = self._sizeHintForColumn(header, col, limit_ms) 388 | data_width = self._sizeHintForColumn(data, col, limit_ms) 389 | if data_width > hdr_width: 390 | width = min(self.max_width, data_width) 391 | elif hdr_width > data_width * 2: 392 | width = max(min(hdr_width, self.min_trunc), min(self.max_width, data_width)) 393 | else: 394 | width = min(self.max_width, hdr_width) 395 | header.setColumnWidth(col, width) 396 | 397 | def _resizeColumnsToContents(self, header, data, limit_ms): 398 | max_col = data.model().columnCount() 399 | if limit_ms is None: 400 | max_col_ms = None 401 | else: 402 | max_col_ms = limit_ms / max(1, max_col) 403 | for col in range(max_col): 404 | self._resizeColumnToContents(header, data, col, max_col_ms) 405 | 406 | def eventFilter(self, obj, event): 407 | if obj == self.table_data and event.type() == QtCore.QEvent.Resize: 408 | self._resizeVisibleColumnsToContents() 409 | return False 410 | 411 | def _resizeVisibleColumnsToContents(self): 412 | start = col = self.table_data.columnAt(self.table_data.rect().topLeft().x()) 413 | width = self._model.shape[1] 414 | end = self.table_data.columnAt(self.table_data.rect().bottomRight().x()) 415 | end = width if end == -1 else end + 1 416 | if self._max_autosize_ms is None: 417 | max_col_ms = None 418 | else: 419 | max_col_ms = self._max_autosize_ms / max(1, end - start) 420 | while col < end: 421 | resized = False 422 | if col not in self._autosized_cols: 423 | self._autosized_cols.add(col) 424 | resized = True 425 | self._resizeColumnToContents(self.table_header, self.table_data, 426 | col, max_col_ms) 427 | col += 1 428 | if resized: 429 | # as we resize columns, the boundary will change 430 | end = self.table_data.columnAt(self.table_data.rect().bottomRight().x()) 431 | end = width if end == -1 else end + 1 432 | if max_col_ms is not None: 433 | max_col_ms = self._max_autosize_ms / max(1, end - start) 434 | 435 | def _resizeCurrentColumnToContents(self, new_index, old_index): 436 | if new_index.column() not in self._autosized_cols: 437 | # ensure the requested column is fully into view after resizing 438 | self._resizeVisibleColumnsToContents() 439 | self.table_data.scrollTo(new_index) 440 | 441 | def resizeColumnsToContents(self): 442 | self._autosized_cols = set() 443 | self._resizeColumnsToContents(self.table_level, self.table_index, self._max_autosize_ms) 444 | self._update_layout() 445 | 446 | 447 | class Viewer(QtWidgets.QMainWindow): 448 | def __init__(self, *args, **kwargs): 449 | super(Viewer, self).__init__() 450 | self.table = ExtTableView() 451 | self.setCentralWidget(self.table) 452 | self.closed = False 453 | self.table.setAutosizeLimit(MAX_AUTOSIZE_MS) 454 | if args or kwargs: 455 | self.view(*args, **kwargs) 456 | 457 | def closeEvent(self, event): 458 | self.closed = True 459 | super(Viewer, self).closeEvent(event) 460 | 461 | def view(self, model, hdr_rows=None, idx_cols=None, start_pos=None, 462 | metavar=None, title=None, relayout=True): 463 | old_model = self.table.model() 464 | self.table.setModel(model, relayout=False) 465 | shape = model.shape 466 | 467 | if title is not None: 468 | self.setWindowTitle(title) 469 | else: 470 | title = "{} rows, {} columns".format(shape[0], shape[1]) 471 | if metavar: 472 | title = "{}: {}".format(metavar, title) 473 | self.setWindowTitle(title) 474 | 475 | if relayout or old_model is None: 476 | self.table.resizeColumnsToContents() 477 | 478 | self.table.setFocus() 479 | if start_pos: 480 | y = shape[0] + start_pos[0] if start_pos[0] < 0 else start_pos[0] 481 | x = shape[1] + start_pos[1] if start_pos[1] < 0 else start_pos[1] 482 | self.table.setCurrentIndex(y, x) 483 | 484 | self.showNormal() 485 | self.setWindowState(QtCore.Qt.WindowActive) 486 | self.closed = False 487 | -------------------------------------------------------------------------------- /gtabview_cli/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.10.1' 2 | -------------------------------------------------------------------------------- /gtabview_cli/gtabview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function, unicode_literals, absolute_import 4 | 5 | import os 6 | import sys 7 | import argparse 8 | 9 | from . import __version__ 10 | 11 | 12 | def arg_parse(): 13 | parser = argparse.ArgumentParser(description="View a tab-delimited file " 14 | "in a spreadsheet-like display. ") 15 | parser.add_argument('--version', action='version', version=__version__) 16 | parser.add_argument('filename', help="File to read. Use '-' to read from " 17 | "the standard input instead.") 18 | parser.add_argument('--encoding', '-e', help="Encoding, if required. " 19 | "If the file is UTF-8, Latin-1(iso8859-1) or a few " 20 | "other common encodings, it should be detected " 21 | "automatically. If not, you can pass " 22 | "'CP720', or 'iso8859-2', for example.") 23 | parser.add_argument('--delimiter', '-d', default=None, 24 | help="CSV delimiter. Not typically necessary since " 25 | "automatic delimiter sniffing is used.") 26 | parser.add_argument('--header', '-H', default=None, type=int, 27 | help="Set number of header rows (defaults to 1)") 28 | parser.add_argument('--index', '-I', default=None, type=int, 29 | help="Set number of index columns (defaults to 0)") 30 | parser.add_argument('--sheet', '-S', default=0, type=int, 31 | help="Set the sheet index to read (defaults to 0)") 32 | parser.add_argument('--transpose', '-T', action='store_true', 33 | help="Transpose the dataset.") 34 | parser.add_argument('--start_pos', '-s', 35 | help="Initial cursor display position. " 36 | "Single number for just y (row) position, or two " 37 | "comma-separated numbers (--start_pos 2,3) for both. " 38 | "Alternatively, you can pass the numbers in the more " 39 | "classic +y:[x] format without the --start_pos label. " 40 | "Like 'gtabview +5:10'. Negative offsets start " 41 | "from the end of the dataset.") 42 | return parser.parse_known_args() 43 | 44 | 45 | def start_position(start_norm, start_classic): 46 | """Given a string "[y, x, ...]" or a string "+[y]:[x]", return a tuple (y, x) 47 | for the start position 48 | 49 | Args: start_norm - string [y,x, ...] 50 | start_classic - string "+[y]:[x]" 51 | 52 | Returns: tuple (y, x) 53 | """ 54 | if start_norm is not None: 55 | start_pos = start_norm.split(',')[:2] 56 | if not start_pos[0]: 57 | start_pos[0] = 0 58 | start_pos = [int(i) for i in start_pos] 59 | elif start_classic: 60 | sp = start_classic[0].strip('+').split(':') 61 | if not sp[0]: 62 | sp[0] = 0 63 | try: 64 | start_pos = (int(sp[0]), int(sp[1])) 65 | except IndexError: 66 | start_pos = (int(sp[0]), 0) 67 | else: 68 | start_pos = (0, 0) 69 | return start_pos 70 | 71 | 72 | def fixup_stdin(): 73 | print("gtabview: Reading from stdin...", file=sys.stderr) 74 | data = os.fdopen(os.dup(0), 'rb') 75 | os.dup2(os.open("/dev/tty", os.O_RDONLY), 0) 76 | return data 77 | 78 | 79 | def main(): 80 | args, extra = arg_parse() 81 | pos_plus = [i for i in extra if i.startswith('+')] 82 | start_pos = start_position(args.start_pos, pos_plus) 83 | if args.filename != '-': 84 | data = args.filename 85 | else: 86 | args.filename = "" 87 | data = fixup_stdin() 88 | 89 | from gtabview import view 90 | try: 91 | view(data, enc=args.encoding, start_pos=start_pos, delimiter=args.delimiter, 92 | hdr_rows=args.header, idx_cols=args.index, sheet_index=args.sheet, 93 | transpose=args.transpose, metavar=args.filename) 94 | except KeyboardInterrupt: 95 | return 0 96 | except IOError as e: 97 | print("gtabview: {}".format(e)) 98 | return 1 99 | 100 | if __name__ == '__main__': 101 | sys.exit(main()) 102 | -------------------------------------------------------------------------------- /sample/data_ohlcv.csv: -------------------------------------------------------------------------------- 1 | Date,Open,High,Low,Close,Volume,Adj Close 2 | 2010-01-04,30.62,31.1,30.59,30.95,38409100,27.14 3 | 2010-01-05,30.85,31.1,30.64,30.96,49749600,27.14 4 | 2010-01-06,30.88,31.08,30.52,30.77,58182400,26.98 5 | 2010-01-07,30.63,30.7,30.19,30.45,50559700,26.7 6 | 2010-01-08,30.28,30.88,30.24,30.66,51197400,26.88 7 | 2010-01-11,30.71,30.76,30.12,30.27,68754700,26.54 8 | 2010-01-12,30.15,30.4,29.91,30.07,65912100,26.36 9 | 2010-01-13,30.26,30.52,30.01,30.35,51863500,26.61 10 | 2010-01-14,30.31,31.1,30.26,30.96,63228100,27.14 11 | 2010-01-15,31.08,31.24,30.71,30.86,79913200,27.06 12 | 2010-01-19,30.75,31.24,30.68,31.1,46575700,27.27 13 | 2010-01-20,30.81,30.94,30.31,30.59,54849500,26.82 14 | 2010-01-21,30.61,30.72,30.0,30.01,73086700,26.31 15 | 2010-01-22,30.0,30.2,28.84,28.96,102004600,25.39 16 | 2010-01-25,29.24,29.66,29.1,29.32,63373000,25.71 17 | 2010-01-26,29.2,29.85,29.09,29.5,66639900,25.86 18 | 2010-01-27,29.35,29.82,29.02,29.67,63949500,26.01 19 | 2010-01-28,29.84,29.87,28.89,29.16,117513700,25.57 20 | 2010-01-29,29.9,29.92,27.66,28.18,193888500,24.71 21 | 2010-02-01,28.39,28.48,27.92,28.41,85931100,24.91 22 | 2010-02-02,28.37,28.5,28.14,28.46,54413700,24.95 23 | 2010-02-03,28.26,28.79,28.12,28.63,61397900,25.1 24 | 2010-02-04,28.38,28.5,27.81,27.84,77850000,24.41 25 | 2010-02-05,28.0,28.28,27.57,28.02,80960100,24.57 26 | 2010-02-08,28.01,28.08,27.57,27.72,52820600,24.3 27 | 2010-02-09,27.97,28.34,27.75,28.01,59195800,24.56 28 | 2010-02-10,28.03,28.24,27.84,27.99,48591300,24.54 29 | 2010-02-11,27.93,28.4,27.7,28.12,65993700,24.65 30 | 2010-02-12,27.81,28.06,27.58,27.93,81117200,24.49 31 | 2010-02-16,28.13,28.37,28.02,28.35,51935600,24.97 32 | 2010-02-17,28.53,28.65,28.36,28.59,45882900,25.18 33 | 2010-02-18,28.59,29.03,28.51,28.97,42856500,25.52 34 | 2010-02-19,28.79,28.92,28.69,28.77,44451800,25.34 35 | 2010-02-22,28.84,28.94,28.65,28.73,36707100,25.31 36 | 2010-02-23,28.68,28.83,28.09,28.33,52266200,24.95 37 | 2010-02-24,28.52,28.79,28.38,28.63,43165900,25.22 38 | 2010-02-25,28.27,28.65,28.02,28.6,48735300,25.19 39 | 2010-02-26,28.65,28.85,28.51,28.67,40370600,25.25 40 | 2010-03-01,28.77,29.05,28.53,29.02,43805400,25.56 41 | 2010-03-02,29.08,29.3,28.24,28.46,93123900,25.07 42 | 2010-03-03,28.51,28.61,28.35,28.46,48442100,25.07 43 | 2010-03-04,28.46,28.65,28.27,28.63,42890600,25.22 44 | 2010-03-05,28.66,28.68,28.42,28.59,56001800,25.18 45 | 2010-03-08,28.52,28.93,28.5,28.63,39414500,25.22 46 | 2010-03-09,28.56,29.11,28.55,28.8,50271600,25.37 47 | 2010-03-10,28.86,29.11,28.8,28.97,44891400,25.52 48 | 2010-03-11,28.89,29.19,28.85,29.18,35349700,25.7 49 | 2010-03-12,29.32,29.38,29.04,29.27,31700200,25.78 50 | 2010-03-15,29.18,29.37,29.01,29.29,37512000,25.8 51 | 2010-03-16,29.42,29.49,29.2,29.37,36723500,25.87 52 | 2010-03-17,29.5,29.87,29.4,29.63,50385700,26.1 53 | 2010-03-18,29.63,29.72,29.5,29.61,43845200,26.08 54 | 2010-03-19,29.76,29.9,29.35,29.59,81332100,26.06 55 | 2010-03-22,29.5,29.7,29.39,29.6,37718200,26.07 56 | 2010-03-23,29.59,29.9,29.41,29.88,42026600,26.32 57 | 2010-03-24,29.72,29.85,29.6,29.65,33987700,26.12 58 | 2010-03-25,29.83,30.57,29.8,30.01,73168700,26.43 59 | 2010-03-26,30.09,30.2,29.59,29.66,55595500,26.13 60 | 2010-03-29,29.71,29.82,29.55,29.59,33336000,26.06 61 | 2010-03-30,29.63,29.86,29.5,29.77,34954800,26.22 62 | 2010-03-31,29.64,29.72,29.17,29.29,63760000,25.8 63 | 2010-04-01,29.35,29.54,28.62,29.16,74768100,25.69 64 | 2010-04-05,29.13,29.43,29.03,29.27,34331200,25.78 65 | 2010-04-06,29.15,29.58,28.98,29.32,47366800,25.83 66 | 2010-04-07,29.16,29.56,29.14,29.35,58318800,25.85 67 | 2010-04-08,29.32,29.98,29.3,29.92,63713800,26.35 68 | 2010-04-09,29.95,30.41,29.9,30.34,54752500,26.72 69 | 2010-04-12,30.25,30.49,30.21,30.32,37068800,26.71 70 | 2010-04-13,30.15,30.5,30.13,30.45,41374600,26.82 71 | 2010-04-14,30.79,31.0,30.66,30.82,68941200,27.15 72 | 2010-04-15,30.82,30.95,30.71,30.87,52745400,27.19 73 | 2010-04-16,30.79,30.98,30.6,30.67,88703100,27.02 74 | 2010-04-19,30.77,31.25,30.76,31.04,64970300,27.34 75 | 2010-04-20,31.22,31.44,31.13,31.36,52199500,27.62 76 | 2010-04-21,31.33,31.5,31.23,31.33,55343100,27.6 77 | 2010-04-22,31.04,31.53,30.9,31.39,84847600,27.65 78 | 2010-04-23,31.12,31.58,30.65,30.96,126766600,27.27 79 | 2010-04-26,31.0,31.28,30.86,31.11,63649300,27.4 80 | 2010-04-27,30.95,31.25,30.75,30.85,68730900,27.17 81 | 2010-04-28,30.92,31.0,30.62,30.91,64557900,27.23 82 | 2010-04-29,30.93,31.43,30.67,31.0,52665200,27.31 83 | 2010-04-30,31.07,31.08,30.52,30.54,63214800,26.9 84 | 2010-05-03,30.67,31.06,30.58,30.86,43989500,27.18 85 | 2010-05-04,30.52,30.55,29.75,30.13,82085600,26.54 86 | 2010-05-05,29.77,30.09,29.69,29.85,66833800,26.29 87 | 2010-05-06,29.59,29.88,27.91,28.98,128613000,25.53 88 | 2010-05-07,28.93,28.95,27.32,28.21,173718100,24.85 89 | 2010-05-10,29.01,29.48,28.71,28.94,86653300,25.49 90 | 2010-05-11,28.68,29.65,28.57,28.88,63789400,25.44 91 | 2010-05-12,28.98,29.58,28.92,29.44,47146800,25.93 92 | 2010-05-13,29.26,29.73,29.18,29.24,45188800,25.76 93 | 2010-05-14,29.2,29.21,28.64,28.93,63334000,25.48 94 | 2010-05-17,29.12,29.23,28.45,28.94,46053300,25.49 95 | 2010-05-18,28.87,29.0,28.4,28.6,52690600,25.31 96 | 2010-05-19,28.52,28.69,27.79,28.24,61746700,24.99 97 | 2010-05-20,27.65,27.84,27.04,27.11,87991100,23.99 98 | 2010-05-21,26.63,27.11,26.44,26.84,117596300,23.75 99 | 2010-05-24,26.85,26.86,26.26,26.27,73711700,23.24 100 | 2010-05-25,25.65,26.33,25.38,26.07,98373600,23.07 101 | 2010-05-26,26.23,26.61,24.56,25.01,176684100,22.13 102 | 2010-05-27,25.73,26.36,25.73,26.0,136433600,23.01 103 | 2010-05-28,25.84,26.12,25.66,25.8,67496900,22.83 104 | 2010-06-01,25.53,26.31,25.52,25.89,76152400,22.91 105 | 2010-06-02,26.06,26.48,25.73,26.46,65718800,23.41 106 | 2010-06-03,26.55,26.93,26.41,26.86,67837000,23.77 107 | 2010-06-04,26.1,26.57,25.62,25.79,89832200,22.82 108 | 2010-06-07,25.82,25.83,25.24,25.29,80456200,22.38 109 | 2010-06-08,25.25,25.26,24.65,25.11,87355000,22.22 110 | 2010-06-09,25.22,25.52,24.75,24.79,87794000,21.93 111 | 2010-06-10,25.13,25.15,24.78,25.0,78930900,22.12 112 | 2010-06-11,25.04,25.72,24.77,25.66,68057700,22.7 113 | 2010-06-14,25.86,25.96,25.47,25.5,50972400,22.56 114 | 2010-06-15,25.75,26.65,25.74,26.58,81641500,23.52 115 | 2010-06-16,26.47,26.58,26.23,26.32,48698000,23.29 116 | 2010-06-17,26.56,26.67,26.04,26.37,47995500,23.33 117 | 2010-06-18,26.37,26.53,26.17,26.44,52075600,23.39 118 | 2010-06-21,26.78,26.89,25.89,25.95,54625300,22.96 119 | 2010-06-22,26.16,26.45,25.76,25.77,55985400,22.8 120 | 2010-06-23,25.78,25.78,25.22,25.31,61466200,22.39 121 | 2010-06-24,25.46,25.72,24.93,25.0,85243400,22.12 122 | 2010-06-25,25.05,25.11,24.31,24.53,156256700,21.7 123 | 2010-06-28,24.51,24.61,24.12,24.31,73784800,21.51 124 | 2010-06-29,24.13,24.2,23.11,23.31,119882100,20.62 125 | 2010-06-30,23.3,23.68,22.95,23.01,81050500,20.36 126 | 2010-07-01,23.09,23.32,22.73,23.16,92239400,20.49 127 | 2010-07-02,23.36,23.48,23.05,23.27,62485100,20.59 128 | 2010-07-06,23.7,24.09,23.58,23.82,73592000,21.08 129 | 2010-07-07,23.82,24.32,23.61,24.3,79965300,21.5 130 | 2010-07-08,24.6,24.62,23.97,24.41,50758100,21.6 131 | 2010-07-09,24.33,24.41,24.15,24.27,53806100,21.47 132 | 2010-07-12,24.43,24.89,24.42,24.83,49854200,21.97 133 | 2010-07-13,25.14,25.3,24.9,25.13,61928700,22.24 134 | 2010-07-14,25.5,25.61,25.12,25.44,72808100,22.51 135 | 2010-07-15,25.5,25.59,24.98,25.51,56934700,22.57 136 | 2010-07-16,25.51,25.64,24.88,24.89,65064800,22.02 137 | 2010-07-19,24.96,25.3,24.91,25.23,38181800,22.32 138 | 2010-07-20,24.86,25.48,24.7,25.48,45530700,22.55 139 | 2010-07-21,25.6,25.65,24.98,25.12,73297300,22.23 140 | 2010-07-22,25.51,25.99,25.47,25.84,73016400,22.86 141 | 2010-07-23,25.84,26.02,25.25,25.81,108520100,22.84 142 | 2010-07-26,25.86,26.2,25.8,26.1,67249900,23.09 143 | 2010-07-27,26.14,26.24,25.96,26.16,60672100,23.15 144 | 2010-07-28,26.07,26.19,25.83,25.95,69704800,22.96 145 | 2010-07-29,26.13,26.41,25.6,26.03,69446200,23.03 146 | 2010-07-30,25.75,25.84,25.35,25.81,83534800,22.84 147 | 2010-08-02,25.99,26.38,25.75,26.33,55044600,23.3 148 | 2010-08-03,26.2,26.35,25.97,26.16,56877700,23.15 149 | 2010-08-04,26.15,26.24,25.44,25.73,78531900,22.77 150 | 2010-08-05,25.49,25.58,25.21,25.37,64922100,22.45 151 | 2010-08-06,25.18,25.56,25.02,25.55,55982100,22.61 152 | 2010-08-09,25.55,25.73,25.37,25.61,57096500,22.66 153 | 2010-08-10,25.33,25.34,24.88,25.07,87257700,22.18 154 | 2010-08-11,24.68,24.9,24.56,24.86,76746900,22.0 155 | 2010-08-12,24.42,24.68,24.36,24.49,70240500,21.67 156 | 2010-08-13,24.35,24.67,24.24,24.4,45263500,21.59 157 | 2010-08-16,24.36,24.61,24.3,24.5,40909700,21.68 158 | 2010-08-17,24.71,24.96,24.6,24.71,52912600,21.98 159 | 2010-08-18,24.68,24.95,24.41,24.82,46818900,22.08 160 | 2010-08-19,24.62,24.74,24.21,24.44,54064600,21.74 161 | 2010-08-20,24.31,24.4,24.2,24.23,49560100,21.55 162 | 2010-08-23,24.44,24.64,24.24,24.28,51643000,21.6 163 | 2010-08-24,24.09,24.35,24.0,24.04,66522500,21.38 164 | 2010-08-25,24.0,24.22,23.87,24.1,47404800,21.44 165 | 2010-08-26,24.09,24.19,23.79,23.82,49105300,21.19 166 | 2010-08-27,23.88,24.02,23.51,23.93,60939400,21.29 167 | 2010-08-30,23.74,23.82,23.6,23.64,45453100,21.03 168 | 2010-08-31,23.6,23.73,23.32,23.47,66074600,20.88 169 | 2010-09-01,23.67,23.95,23.54,23.9,65235900,21.26 170 | 2010-09-02,23.88,23.95,23.71,23.94,48837100,21.3 171 | 2010-09-03,24.24,24.45,24.2,24.29,64189100,21.61 172 | 2010-09-07,24.1,24.3,23.92,23.96,51928700,21.31 173 | 2010-09-08,24.07,24.2,23.74,23.93,65512400,21.29 174 | 2010-09-09,24.19,24.21,23.99,24.01,46028900,21.36 175 | 2010-09-10,23.98,24.03,23.79,23.85,58284300,21.22 176 | 2010-09-13,24.2,25.29,24.09,25.11,114680400,22.34 177 | 2010-09-14,25.04,25.35,24.89,25.03,87160400,22.27 178 | 2010-09-15,25.1,25.22,24.92,25.12,56201900,22.35 179 | 2010-09-16,25.06,25.37,25.05,25.33,44548300,22.53 180 | 2010-09-17,25.4,25.53,25.08,25.22,70341600,22.43 181 | 2010-09-20,25.28,25.52,25.11,25.43,49838700,22.62 182 | 2010-09-21,25.42,25.42,25.08,25.15,52675700,22.37 183 | 2010-09-22,24.89,24.97,24.36,24.61,94299400,21.89 184 | 2010-09-23,24.51,24.59,24.36,24.43,46201800,21.73 185 | 2010-09-24,24.64,24.8,24.58,24.78,51948800,22.04 186 | 2010-09-27,24.85,24.99,24.59,24.73,43603300,22.0 187 | 2010-09-28,24.8,24.9,24.35,24.68,56041200,21.95 188 | 2010-09-29,24.63,24.66,24.4,24.5,44318900,21.79 189 | 2010-09-30,24.61,24.83,24.36,24.49,61262700,21.78 190 | 2010-10-01,24.77,24.82,24.3,24.38,62672300,21.69 191 | 2010-10-04,23.96,23.99,23.78,23.91,98143400,21.27 192 | 2010-10-05,24.06,24.45,23.91,24.35,78152900,21.66 193 | 2010-10-06,24.32,24.54,24.13,24.43,50489700,21.73 194 | 2010-10-07,24.62,24.75,24.28,24.53,50096100,21.82 195 | 2010-10-08,24.62,24.65,24.37,24.57,41327800,21.86 196 | 2010-10-11,24.74,24.74,24.5,24.59,27587800,21.87 197 | 2010-10-12,24.65,24.93,24.43,24.83,50141500,22.09 198 | 2010-10-13,25.02,25.54,24.89,25.34,75336500,22.54 199 | 2010-10-14,25.29,25.34,25.0,25.23,51949100,22.44 200 | 2010-10-15,25.36,25.55,25.23,25.54,68954800,22.72 201 | 2010-10-18,25.59,25.95,25.45,25.82,48330500,22.97 202 | 2010-10-19,25.27,25.37,24.95,25.1,66150900,22.33 203 | 2010-10-20,25.26,25.4,25.1,25.31,56283600,22.51 204 | 2010-10-21,25.4,25.54,25.05,25.42,50032400,22.61 205 | 2010-10-22,25.52,25.54,25.27,25.38,25837900,22.58 206 | 2010-10-25,25.24,25.35,25.17,25.19,50912400,22.41 207 | 2010-10-26,25.12,25.97,25.06,25.9,69304200,23.04 208 | 2010-10-27,25.79,26.11,25.62,26.05,64805500,23.17 209 | 2010-10-28,26.21,26.38,25.92,26.28,80730300,23.38 210 | 2010-10-29,27.15,27.2,26.48,26.67,114193200,23.72 211 | 2010-11-01,26.88,27.22,26.7,26.95,61912100,23.97 212 | 2010-11-02,27.06,27.42,27.02,27.39,54402100,24.36 213 | 2010-11-03,27.46,27.49,26.96,27.03,110255300,24.04 214 | 2010-11-04,27.41,27.43,27.01,27.14,93599300,24.14 215 | 2010-11-05,27.17,27.19,26.53,26.85,110953700,23.88 216 | 2010-11-08,26.68,28.87,26.58,26.81,71670800,23.85 217 | 2010-11-09,26.81,27.11,26.71,26.95,58538600,23.97 218 | 2010-11-10,27.01,27.08,26.81,26.94,52277300,23.96 219 | 2010-11-11,26.68,26.72,26.28,26.68,62073100,23.73 220 | 2010-11-12,26.47,26.52,26.1,26.27,64962200,23.37 221 | 2010-11-15,26.33,26.5,26.17,26.2,51794600,23.31 222 | 2010-11-16,26.04,26.04,25.65,25.81,65339200,23.1 223 | 2010-11-17,25.9,25.91,25.55,25.57,58299700,22.89 224 | 2010-11-18,25.71,26.08,25.61,25.84,59514000,23.13 225 | 2010-11-19,25.8,25.83,25.6,25.69,52423200,22.99 226 | 2010-11-22,25.65,25.74,25.44,25.73,53350500,23.03 227 | 2010-11-23,25.57,25.6,25.09,25.12,69742500,22.48 228 | 2010-11-24,25.2,25.46,25.16,25.37,56825900,22.71 229 | 2010-11-26,25.21,25.41,25.17,25.25,21356500,22.6 230 | 2010-11-29,25.19,25.42,24.93,25.31,56603600,22.65 231 | 2010-11-30,25.05,25.47,25.0,25.26,75282100,22.61 232 | 2010-12-01,25.57,26.25,25.56,26.04,74123500,23.31 233 | 2010-12-02,26.24,26.98,26.2,26.89,91759200,24.07 234 | 2010-12-03,26.81,27.06,26.78,27.02,52622000,24.18 235 | 2010-12-06,26.93,26.98,26.76,26.84,36264200,24.02 236 | 2010-12-07,27.08,27.13,26.85,26.87,57860500,24.05 237 | 2010-12-08,26.83,27.24,26.8,27.23,41666800,24.37 238 | 2010-12-09,27.28,27.34,27.01,27.08,47148300,24.24 239 | 2010-12-10,27.19,27.4,27.11,27.34,37625800,24.47 240 | 2010-12-13,27.27,27.45,27.17,27.25,47943900,24.39 241 | 2010-12-14,27.31,27.75,27.26,27.62,64070500,24.72 242 | 2010-12-15,27.53,27.99,27.53,27.85,69634200,24.93 243 | 2010-12-16,27.76,27.99,27.66,27.99,57680200,25.05 244 | 2010-12-17,27.92,28.09,27.75,27.9,87456500,24.97 245 | 2010-12-20,27.95,27.99,27.68,27.81,52811000,24.89 246 | 2010-12-21,27.85,28.14,27.76,28.07,38153000,25.12 247 | 2010-12-22,28.01,28.4,27.98,28.19,42252300,25.23 248 | 2010-12-23,27.97,28.32,27.96,28.3,24902500,25.33 249 | 2010-12-27,28.12,28.2,27.88,28.07,21652800,25.12 250 | 2010-12-28,27.97,28.17,27.96,28.01,23042200,25.07 251 | 2010-12-29,27.94,28.12,27.88,27.97,19502500,25.03 252 | 2010-12-30,27.92,28.0,27.78,27.85,20786100,24.93 253 | 2010-12-31,27.8,27.92,27.63,27.91,24752000,24.98 254 | 2011-01-03,28.05,28.18,27.92,27.98,53443800,25.04 255 | 2011-01-04,27.94,28.17,27.85,28.09,54405600,25.14 256 | 2011-01-05,27.9,28.01,27.77,28.0,58998700,25.06 257 | 2011-01-06,28.04,28.85,27.86,28.82,88026300,25.79 258 | 2011-01-07,28.64,28.74,28.25,28.6,73762000,25.6 259 | 2011-01-10,28.26,28.4,28.04,28.22,57573600,25.26 260 | 2011-01-11,28.2,28.25,28.05,28.11,50298900,25.16 261 | 2011-01-12,28.12,28.59,28.07,28.55,52631100,25.55 262 | 2011-01-13,28.33,28.39,28.01,28.19,67077600,25.23 263 | 2011-01-14,28.08,28.38,27.91,28.3,62688400,25.33 264 | 2011-01-18,28.16,28.74,28.14,28.66,53322700,25.65 265 | 2011-01-19,28.46,28.68,28.27,28.47,50005900,25.48 266 | 2011-01-20,28.5,28.55,28.13,28.35,58613600,25.37 267 | 2011-01-21,28.4,28.43,28.02,28.02,58080300,25.08 268 | 2011-01-24,28.02,28.56,27.99,28.38,52047800,25.4 269 | 2011-01-25,28.14,28.45,28.12,28.45,42436600,25.46 270 | 2011-01-26,28.51,28.99,28.5,28.78,74628800,25.76 271 | 2011-01-27,28.75,29.46,28.49,28.87,146938600,25.84 272 | 2011-01-28,28.9,28.93,27.45,27.75,141249400,24.84 273 | 2011-01-31,27.77,27.9,27.42,27.73,65029000,24.82 274 | 2011-02-01,27.8,28.06,27.61,27.99,62810700,25.05 275 | 2011-02-02,27.93,28.11,27.88,27.94,45824000,25.01 276 | 2011-02-03,27.97,27.97,27.54,27.65,60340100,24.75 277 | 2011-02-04,27.7,27.84,27.51,27.77,40412200,24.85 278 | 2011-02-07,27.8,28.34,27.79,28.2,68980900,25.24 279 | 2011-02-08,28.1,28.34,28.05,28.28,34904200,25.31 280 | 2011-02-09,28.19,28.26,27.91,27.97,52905100,25.03 281 | 2011-02-10,27.93,27.94,27.29,27.5,76672400,24.61 282 | 2011-02-11,27.76,27.81,27.07,27.25,83939700,24.39 283 | 2011-02-14,27.21,27.27,26.95,27.23,56766200,24.37 284 | 2011-02-15,27.04,27.33,26.95,26.96,44116500,24.27 285 | 2011-02-16,27.05,27.07,26.6,27.02,70817900,24.33 286 | 2011-02-17,26.97,27.37,26.91,27.21,57207300,24.5 287 | 2011-02-18,27.13,27.21,26.99,27.06,68667800,24.36 288 | 2011-02-22,26.78,27.1,26.52,26.59,60889000,23.94 289 | 2011-02-23,26.53,26.86,26.43,26.59,60234100,23.94 290 | 2011-02-24,26.64,27.06,26.5,26.77,64494200,24.1 291 | 2011-02-25,26.91,26.95,26.5,26.55,53006300,23.9 292 | 2011-02-28,26.69,26.86,26.51,26.58,51379900,23.93 293 | 2011-03-01,26.6,26.78,26.15,26.16,60055000,23.55 294 | 2011-03-02,26.11,26.37,26.04,26.08,48658200,23.48 295 | 2011-03-03,26.26,26.4,26.18,26.2,68271500,23.59 296 | 2011-03-04,26.22,26.24,25.8,25.95,70437200,23.36 297 | 2011-03-07,26.13,26.27,25.55,25.72,64980400,23.16 298 | 2011-03-08,25.77,26.02,25.65,25.91,50549800,23.33 299 | 2011-03-09,25.81,25.98,25.66,25.89,39789100,23.31 300 | 2011-03-10,25.62,25.71,25.35,25.41,66549500,22.88 301 | 2011-03-11,25.41,25.85,25.36,25.68,49905800,23.12 302 | 2011-03-14,25.49,25.76,25.35,25.69,54473400,23.13 303 | 2011-03-15,25.08,25.47,25.0,25.39,76067300,22.86 304 | 2011-03-16,25.22,25.28,24.68,24.79,100725400,22.32 305 | 2011-03-17,25.06,25.22,24.75,24.78,62497000,22.31 306 | 2011-03-18,25.06,25.18,24.8,24.8,85486700,22.33 307 | 2011-03-21,25.18,25.58,25.15,25.33,46878100,22.8 308 | 2011-03-22,25.3,25.46,25.23,25.3,30895600,22.78 309 | 2011-03-23,25.23,25.61,25.18,25.54,43969000,22.99 310 | 2011-03-24,25.6,25.87,25.5,25.81,38696700,23.24 311 | 2011-03-25,25.93,25.95,25.59,25.62,57029800,23.07 312 | 2011-03-28,25.66,25.72,25.38,25.41,48973200,22.88 313 | 2011-03-29,25.34,25.52,25.3,25.49,40763500,22.95 314 | 2011-03-30,25.6,25.72,25.5,25.61,41999300,23.06 315 | 2011-03-31,25.6,25.68,25.34,25.39,63233700,22.86 316 | 2011-04-01,25.53,25.53,25.31,25.48,63114200,22.94 317 | 2011-04-04,25.45,25.66,25.41,25.55,35433700,23.0 318 | 2011-04-05,25.82,26.18,25.74,25.78,73651100,23.21 319 | 2011-04-06,25.98,26.31,25.86,26.15,65581400,23.54 320 | 2011-04-07,26.19,26.26,25.97,26.2,46134700,23.59 321 | 2011-04-08,26.17,26.28,25.96,26.07,39887600,23.47 322 | 2011-04-11,26.19,26.25,25.8,25.98,34286300,23.39 323 | 2011-04-12,25.83,25.85,25.55,25.64,36920400,23.08 324 | 2011-04-13,25.65,25.87,25.56,25.63,38144700,23.07 325 | 2011-04-14,25.42,25.44,25.09,25.42,55239900,22.89 326 | 2011-04-15,25.46,25.56,25.18,25.37,65080400,22.84 327 | 2011-04-18,25.1,25.28,24.72,25.08,58045100,22.58 328 | 2011-04-19,25.0,25.17,24.87,25.15,38892400,22.64 329 | 2011-04-20,25.54,26.0,25.51,25.76,61608600,23.19 330 | 2011-04-21,25.79,25.89,25.36,25.52,46892300,22.98 331 | 2011-04-25,25.56,25.62,25.34,25.61,33525100,23.06 332 | 2011-04-26,25.74,26.44,25.67,26.19,69200000,23.58 333 | 2011-04-27,26.3,26.39,26.13,26.38,52689000,23.75 334 | 2011-04-28,26.46,26.87,26.4,26.71,80200000,24.05 335 | 2011-04-29,26.55,26.64,25.36,25.92,319317900,23.34 336 | 2011-05-02,25.94,26.0,25.48,25.66,89825600,23.1 337 | 2011-05-03,25.6,25.85,25.49,25.81,71892900,23.24 338 | 2011-05-04,25.85,26.25,25.79,26.06,73292300,23.46 339 | 2011-05-05,26.05,26.08,25.68,25.79,55600000,23.22 340 | 2011-05-06,26.07,26.22,25.75,25.87,55993000,23.29 341 | 2011-05-09,25.8,25.96,25.67,25.83,38696400,23.25 342 | 2011-05-10,25.38,25.85,25.25,25.67,120798700,23.11 343 | 2011-05-11,25.65,25.66,25.21,25.36,78600000,22.83 344 | 2011-05-12,25.35,25.39,25.1,25.32,77400000,22.8 345 | 2011-05-13,25.28,25.32,24.95,25.03,66812300,22.53 346 | 2011-05-16,24.96,25.07,24.5,24.57,91350900,22.12 347 | 2011-05-17,24.4,24.7,24.27,24.52,82882100,22.22 348 | 2011-05-18,24.53,24.74,24.25,24.69,53931100,22.37 349 | 2011-05-19,24.85,24.88,24.5,24.72,37783600,22.4 350 | 2011-05-20,24.72,24.87,24.44,24.49,45451500,22.19 351 | 2011-05-23,24.21,24.25,24.03,24.17,52692500,21.9 352 | 2011-05-24,24.2,24.29,24.04,24.15,47691800,21.88 353 | 2011-05-25,24.17,24.31,24.16,24.19,34904200,21.92 354 | 2011-05-26,24.35,25.03,24.32,24.67,78016600,22.36 355 | 2011-05-27,24.68,24.9,24.65,24.76,50251000,22.44 356 | 2011-05-31,24.96,25.06,24.7,25.01,60196300,22.66 357 | 2011-06-01,24.99,25.1,24.37,24.43,74033500,22.14 358 | 2011-06-02,24.49,24.65,24.18,24.22,51487800,21.95 359 | 2011-06-03,24.05,24.14,23.84,23.91,60697700,21.67 360 | 2011-06-06,23.89,24.25,23.77,24.01,54778700,21.76 361 | 2011-06-07,24.09,24.17,23.9,24.06,41112600,21.8 362 | 2011-06-08,23.9,24.02,23.86,23.94,42205000,21.69 363 | 2011-06-09,24.01,24.04,23.82,23.96,42878700,21.71 364 | 2011-06-10,24.02,24.02,23.69,23.71,49327200,21.49 365 | 2011-06-13,23.79,24.19,23.7,24.04,47572500,21.78 366 | 2011-06-14,24.3,24.45,24.19,24.22,42894500,21.95 367 | 2011-06-15,24.0,24.01,23.67,23.74,49410200,21.51 368 | 2011-06-16,23.75,24.1,23.65,24.0,57184100,21.75 369 | 2011-06-17,24.22,24.3,23.98,24.26,83320400,21.98 370 | 2011-06-20,24.17,24.66,24.16,24.47,54338400,22.17 371 | 2011-06-21,24.52,24.86,24.4,24.76,49708700,22.44 372 | 2011-06-22,24.6,24.81,24.59,24.65,44287300,22.34 373 | 2011-06-23,24.44,24.65,24.2,24.63,59470400,22.32 374 | 2011-06-24,24.51,24.54,24.19,24.3,101387200,22.02 375 | 2011-06-27,24.23,25.46,24.23,25.2,92044200,22.84 376 | 2011-06-28,25.3,25.92,25.16,25.8,81032100,23.38 377 | 2011-06-29,25.71,25.71,25.36,25.62,66051000,23.22 378 | 2011-06-30,25.74,26.0,25.66,26.0,52535400,23.56 379 | 2011-07-01,25.93,26.17,25.84,26.02,52906200,23.58 380 | 2011-07-05,26.1,26.15,25.9,26.03,37805300,23.59 381 | 2011-07-06,25.97,26.37,25.96,26.33,48744200,23.86 382 | 2011-07-07,26.49,26.88,26.36,26.77,51946500,24.26 383 | 2011-07-08,26.54,26.98,26.51,26.92,58320700,24.39 384 | 2011-07-11,26.62,26.8,26.49,26.63,43999800,24.13 385 | 2011-07-12,26.55,26.79,26.34,26.54,47319300,24.05 386 | 2011-07-13,26.6,26.96,26.51,26.63,40861800,24.13 387 | 2011-07-14,26.62,27.01,26.36,26.47,46382300,23.99 388 | 2011-07-15,26.47,26.93,26.47,26.78,49132400,24.27 389 | 2011-07-18,26.63,26.9,26.26,26.59,44501900,24.1 390 | 2011-07-19,26.81,27.64,26.78,27.54,86730600,24.96 391 | 2011-07-20,27.28,27.35,26.98,27.06,49795400,24.52 392 | 2011-07-21,27.04,27.31,26.65,27.1,81737400,24.56 393 | 2011-07-22,26.86,27.55,26.68,27.53,76380600,24.95 394 | 2011-07-25,27.26,28.09,27.19,27.91,108482400,25.29 395 | 2011-07-26,27.82,28.15,27.78,28.08,74636500,25.45 396 | 2011-07-27,27.88,27.99,27.2,27.33,71488700,24.77 397 | 2011-07-28,27.29,28.07,27.21,27.72,83761400,25.12 398 | 2011-07-29,27.52,27.71,27.26,27.4,104394800,24.83 399 | 2011-08-01,27.51,27.69,26.75,27.27,61838400,24.71 400 | 2011-08-02,26.98,27.45,26.76,26.8,63883100,24.29 401 | 2011-08-03,26.83,27.0,26.48,26.92,64581200,24.39 402 | 2011-08-04,26.53,26.87,25.93,25.94,92949500,23.51 403 | 2011-08-05,25.97,26.1,25.23,25.68,112071700,23.27 404 | 2011-08-08,25.02,25.6,24.39,24.48,134257200,22.18 405 | 2011-08-09,24.71,25.62,24.03,25.58,126268900,23.18 406 | 2011-08-10,24.95,25.09,24.1,24.2,127819900,21.93 407 | 2011-08-11,24.5,25.38,24.4,25.19,90690100,22.83 408 | 2011-08-12,25.13,25.34,24.65,25.1,64787100,22.75 409 | 2011-08-15,25.24,25.58,25.15,25.51,56529400,23.12 410 | 2011-08-16,25.22,25.59,25.05,25.35,54251500,23.12 411 | 2011-08-17,25.25,25.7,24.93,25.25,50923700,23.03 412 | 2011-08-18,24.57,25.09,24.03,24.67,105714200,22.5 413 | 2011-08-19,24.41,24.62,23.91,24.05,77397900,21.93 414 | 2011-08-22,24.42,24.49,23.79,23.98,54721000,21.87 415 | 2011-08-23,24.03,24.75,24.03,24.72,59670600,22.54 416 | 2011-08-24,24.65,24.93,24.42,24.9,45329700,22.71 417 | 2011-08-25,25.08,25.16,24.5,24.57,48192000,22.41 418 | 2011-08-26,24.51,25.34,24.42,25.25,71957000,23.03 419 | 2011-08-29,25.53,25.86,25.37,25.84,38863200,23.56 420 | 2011-08-30,25.73,26.43,25.7,26.23,57341400,23.92 421 | 2011-08-31,26.29,26.71,26.26,26.6,59300800,24.26 422 | 2011-09-01,26.46,26.86,26.21,26.21,60510800,23.9 423 | 2011-09-02,25.78,26.0,25.66,25.8,43894400,23.53 424 | 2011-09-06,25.2,25.59,25.11,25.51,54929300,23.26 425 | 2011-09-07,25.69,26.0,25.57,26.0,41961000,23.71 426 | 2011-09-08,26.0,26.66,25.95,26.22,65811900,23.91 427 | 2011-09-09,26.0,26.18,25.5,25.74,64529200,23.47 428 | 2011-09-12,25.44,25.93,25.27,25.89,55046100,23.61 429 | 2011-09-13,25.92,26.19,25.81,26.04,48792300,23.75 430 | 2011-09-14,26.17,26.8,25.89,26.5,66739200,24.17 431 | 2011-09-15,26.73,27.03,26.31,26.99,67808300,24.61 432 | 2011-09-16,27.05,27.27,26.83,27.12,89681500,24.73 433 | 2011-09-19,26.8,27.31,26.6,27.21,52324900,24.81 434 | 2011-09-20,27.31,27.5,26.93,26.98,49211900,24.6 435 | 2011-09-21,27.05,27.06,25.97,25.99,72750700,23.7 436 | 2011-09-22,25.3,25.65,24.6,25.06,96278300,22.85 437 | 2011-09-23,24.9,25.15,24.69,25.06,64768100,22.85 438 | 2011-09-26,25.19,25.52,24.73,25.44,51057600,23.2 439 | 2011-09-27,25.66,25.92,25.45,25.67,55620700,23.41 440 | 2011-09-28,25.93,26.37,25.51,25.58,60736200,23.33 441 | 2011-09-29,25.98,26.17,25.09,25.45,63407300,23.21 442 | 2011-09-30,25.2,25.5,24.88,24.89,54060500,22.7 443 | 2011-10-03,24.72,25.34,24.52,24.53,64592500,22.37 444 | 2011-10-04,24.3,25.39,24.26,25.34,83485400,23.11 445 | 2011-10-05,25.42,26.16,25.16,25.89,94061300,23.61 446 | 2011-10-06,25.9,26.4,25.7,26.34,55111400,24.02 447 | 2011-10-07,26.34,26.51,26.2,26.25,52741600,23.94 448 | 2011-10-10,26.58,26.97,26.47,26.94,41815300,24.57 449 | 2011-10-11,26.86,27.07,26.72,27.0,38826200,24.62 450 | 2011-10-12,27.18,27.31,26.9,26.96,52489800,24.59 451 | 2011-10-13,26.76,27.2,26.62,27.18,43823500,24.79 452 | 2011-10-14,27.31,27.5,27.02,27.27,50947700,24.87 453 | 2011-10-17,27.11,27.42,26.85,26.98,39453300,24.6 454 | 2011-10-18,26.94,27.4,26.8,27.31,52487900,24.9 455 | 2011-10-19,27.37,27.47,27.01,27.13,42880000,24.74 456 | 2011-10-20,27.26,27.34,26.4,27.04,76300200,24.66 457 | 2011-10-21,27.15,27.19,26.8,27.16,76620600,24.77 458 | 2011-10-24,27.06,27.4,27.04,27.19,56897800,24.79 459 | 2011-10-25,27.08,27.23,26.72,26.81,53554600,24.45 460 | 2011-10-26,27.03,27.06,26.1,26.59,63029900,24.25 461 | 2011-10-27,27.13,27.4,26.65,27.25,74512400,24.85 462 | 2011-10-28,27.14,27.19,26.79,26.98,57712100,24.6 463 | 2011-10-31,26.76,27.0,26.62,26.63,46799000,24.28 464 | 2011-11-01,26.19,26.32,25.86,25.99,61182600,23.7 465 | 2011-11-02,26.1,26.2,25.7,26.01,53533100,23.72 466 | 2011-11-03,26.24,26.59,25.98,26.53,65836100,24.19 467 | 2011-11-04,26.38,26.4,26.0,26.25,36549200,23.94 468 | 2011-11-07,26.21,26.82,26.13,26.8,42589700,24.44 469 | 2011-11-08,27.01,27.2,26.69,27.16,47822500,24.77 470 | 2011-11-09,26.59,26.75,26.06,26.2,62950900,23.89 471 | 2011-11-10,26.47,26.5,26.12,26.28,32514400,23.96 472 | 2011-11-11,26.58,27.08,26.57,26.91,37903000,24.54 473 | 2011-11-14,26.88,27.0,26.65,26.76,34199200,24.4 474 | 2011-11-15,26.56,26.94,26.4,26.74,43874200,24.57 475 | 2011-11-16,26.47,26.51,26.04,26.07,53262800,23.95 476 | 2011-11-17,26.01,26.04,25.44,25.54,70977500,23.47 477 | 2011-11-18,25.48,25.5,25.15,25.3,47626200,23.25 478 | 2011-11-21,25.24,25.25,24.9,25.0,61882500,22.97 479 | 2011-11-22,24.89,24.96,24.65,24.79,49204500,22.78 480 | 2011-11-23,24.61,24.79,24.47,24.47,49099700,22.48 481 | 2011-11-25,24.38,24.67,24.3,24.3,26164600,22.33 482 | 2011-11-28,24.94,24.97,24.69,24.87,46766700,22.85 483 | 2011-11-29,24.82,25.04,24.75,24.84,40917100,22.82 484 | 2011-11-30,25.37,25.59,25.14,25.58,81350900,23.5 485 | 2011-12-01,25.56,25.63,25.2,25.28,48545400,23.23 486 | 2011-12-02,25.59,25.62,25.16,25.22,52293800,23.17 487 | 2011-12-05,25.78,25.8,25.5,25.7,56818400,23.61 488 | 2011-12-06,25.81,25.87,25.61,25.66,46175300,23.58 489 | 2011-12-07,25.67,25.76,25.34,25.6,62667000,23.52 490 | 2011-12-08,25.48,25.72,25.37,25.4,60522200,23.34 491 | 2011-12-09,25.52,25.87,25.5,25.7,53788500,23.61 492 | 2011-12-12,25.41,25.57,25.29,25.51,38945900,23.44 493 | 2011-12-13,25.75,26.1,25.65,25.76,54581100,23.67 494 | 2011-12-14,25.72,25.86,25.57,25.59,47926400,23.51 495 | 2011-12-15,25.72,25.88,25.54,25.56,46213900,23.48 496 | 2011-12-16,25.67,26.17,25.63,26.0,101408100,23.89 497 | 2011-12-19,26.02,26.12,25.46,25.53,52258300,23.46 498 | 2011-12-20,25.86,26.1,25.81,26.03,60767600,23.92 499 | 2011-12-21,26.01,26.19,25.44,25.76,64132500,23.67 500 | 2011-12-22,25.82,25.86,25.48,25.81,35794100,23.71 501 | 2011-12-23,25.91,26.04,25.73,26.03,23205800,23.92 502 | 2011-12-27,25.96,26.14,25.93,26.04,21287200,23.92 503 | 2011-12-28,26.11,26.15,25.76,25.82,29822500,23.72 504 | 2011-12-29,25.95,26.05,25.86,26.02,22616900,23.91 505 | 2011-12-30,26.0,26.12,25.91,25.96,27395700,23.85 506 | 2012-01-03,26.55,26.96,26.39,26.77,64731500,24.6 507 | 2012-01-04,26.82,27.47,26.78,27.4,80516100,25.17 508 | 2012-01-05,27.38,27.73,27.29,27.68,56081400,25.43 509 | 2012-01-06,27.53,28.19,27.53,28.11,99455500,25.83 510 | 2012-01-09,28.05,28.1,27.72,27.74,59706800,25.49 511 | 2012-01-10,27.93,28.15,27.75,27.84,60014400,25.58 512 | 2012-01-11,27.43,27.98,27.37,27.72,65582400,25.47 513 | 2012-01-12,27.87,28.02,27.65,28.0,49370800,25.73 514 | 2012-01-13,27.93,28.25,27.79,28.25,60196100,25.96 515 | 2012-01-17,28.4,28.65,28.17,28.26,72395300,25.96 516 | 2012-01-18,28.31,28.4,27.97,28.23,64860600,25.94 517 | 2012-01-19,28.16,28.44,28.03,28.12,74053500,25.84 518 | 2012-01-20,28.82,29.74,28.75,29.71,165902900,27.3 519 | 2012-01-23,29.55,29.95,29.35,29.73,76078100,27.32 520 | 2012-01-24,29.47,29.57,29.18,29.34,51703300,26.96 521 | 2012-01-25,29.07,29.65,29.07,29.56,59231700,27.16 522 | 2012-01-26,29.61,29.7,29.4,29.5,49102800,27.1 523 | 2012-01-27,29.45,29.53,29.17,29.23,44187700,26.86 524 | 2012-01-30,28.97,29.62,28.83,29.61,51114800,27.2 525 | 2012-01-31,29.66,29.7,29.23,29.53,50572400,27.13 526 | 2012-02-01,29.79,30.05,29.76,29.89,67409900,27.46 527 | 2012-02-02,29.9,30.17,29.71,29.95,52223300,27.52 528 | 2012-02-03,30.14,30.4,30.09,30.24,41838500,27.78 529 | 2012-02-06,30.04,30.22,29.97,30.2,28039700,27.75 530 | 2012-02-07,30.15,30.49,30.05,30.35,39242400,27.88 531 | 2012-02-08,30.26,30.67,30.22,30.66,49659100,28.17 532 | 2012-02-09,30.68,30.8,30.48,30.77,50481600,28.27 533 | 2012-02-10,30.64,30.8,30.36,30.5,44605300,28.02 534 | 2012-02-13,30.63,30.77,30.43,30.58,33319800,28.1 535 | 2012-02-14,30.33,30.46,29.85,30.25,59644000,27.98 536 | 2012-02-15,30.33,30.39,30.03,30.05,43311300,27.79 537 | 2012-02-16,30.31,31.55,30.3,31.29,94705100,28.94 538 | 2012-02-17,31.2,31.32,30.95,31.25,70036500,28.9 539 | 2012-02-21,31.18,31.61,31.15,31.44,50829900,29.08 540 | 2012-02-22,31.45,31.68,31.18,31.27,49253200,28.92 541 | 2012-02-23,31.2,31.59,31.0,31.37,35034700,29.01 542 | 2012-02-24,31.48,31.5,31.24,31.48,35575400,29.11 543 | 2012-02-27,31.24,31.5,31.1,31.35,34568400,28.99 544 | 2012-02-28,31.41,31.93,31.38,31.87,45230600,29.47 545 | 2012-02-29,31.89,32.0,31.61,31.74,59323600,29.35 546 | 2012-03-01,31.93,32.39,31.85,32.29,77344100,29.86 547 | 2012-03-02,32.31,32.44,32.0,32.08,47314200,29.67 548 | 2012-03-05,32.01,32.05,31.62,31.8,45240000,29.41 549 | 2012-03-06,31.54,31.98,31.49,31.56,51932900,29.19 550 | 2012-03-07,31.67,31.92,31.53,31.84,34340400,29.45 551 | 2012-03-08,32.04,32.21,31.9,32.01,36747400,29.6 552 | 2012-03-09,32.1,32.16,31.92,31.99,34628400,29.59 553 | 2012-03-12,31.97,32.2,31.82,32.04,34073600,29.63 554 | 2012-03-13,32.24,32.69,32.15,32.67,48951700,30.21 555 | 2012-03-14,32.53,32.88,32.49,32.77,41986900,30.31 556 | 2012-03-15,32.79,32.94,32.58,32.85,49068300,30.38 557 | 2012-03-16,32.91,32.95,32.5,32.6,65626400,30.15 558 | 2012-03-19,32.54,32.61,32.15,32.2,44789200,29.78 559 | 2012-03-20,32.1,32.15,31.74,31.99,41566800,29.59 560 | 2012-03-21,31.96,32.15,31.82,31.91,37928600,29.51 561 | 2012-03-22,31.81,32.09,31.79,32.0,31749500,29.59 562 | 2012-03-23,32.1,32.11,31.72,32.01,35912200,29.6 563 | 2012-03-26,32.19,32.61,32.15,32.59,36758300,30.14 564 | 2012-03-27,32.65,32.7,32.4,32.52,36274900,30.08 565 | 2012-03-28,32.52,32.7,32.04,32.19,41344800,29.77 566 | 2012-03-29,32.06,32.19,31.81,32.12,37038500,29.71 567 | 2012-03-30,32.4,32.41,32.04,32.26,31749400,29.83 568 | 2012-04-02,32.22,32.46,31.95,32.29,35853600,29.86 569 | 2012-04-03,32.16,32.19,31.66,31.94,42752100,29.54 570 | 2012-04-04,31.66,31.69,31.05,31.21,49455900,28.86 571 | 2012-04-05,31.15,31.63,31.05,31.52,50368600,29.15 572 | 2012-04-09,31.22,31.4,30.97,31.1,31056400,28.76 573 | 2012-04-10,31.06,31.19,30.3,30.47,54131300,28.18 574 | 2012-04-11,30.43,30.53,30.23,30.35,43014000,28.07 575 | 2012-04-12,30.48,31.04,30.42,30.98,38304000,28.65 576 | 2012-04-13,30.89,31.16,30.72,30.81,39749200,28.49 577 | 2012-04-16,30.99,31.19,30.77,31.08,38124800,28.74 578 | 2012-04-17,31.27,31.61,31.2,31.44,34361500,29.08 579 | 2012-04-18,31.28,31.31,31.04,31.14,40552900,28.8 580 | 2012-04-19,31.13,31.68,30.94,31.01,54781200,28.68 581 | 2012-04-20,32.15,32.89,32.05,32.42,106045000,29.98 582 | 2012-04-23,32.31,32.5,32.03,32.12,61398200,29.71 583 | 2012-04-24,32.21,32.52,31.83,31.92,40871100,29.52 584 | 2012-04-25,31.92,32.32,31.87,32.2,62495500,29.78 585 | 2012-04-26,32.12,32.23,31.92,32.11,40308100,29.7 586 | 2012-04-27,32.12,32.22,31.88,31.98,41419100,29.58 587 | 2012-04-30,31.98,32.11,31.92,32.02,35697200,29.61 588 | 2012-05-01,32.05,32.34,31.95,32.01,43832300,29.6 589 | 2012-05-02,31.85,31.93,31.64,31.8,37385300,29.41 590 | 2012-05-03,31.88,31.9,31.61,31.76,31501300,29.37 591 | 2012-05-04,31.45,31.57,30.92,30.98,57927200,28.65 592 | 2012-05-07,30.7,30.86,30.57,30.65,48641400,28.35 593 | 2012-05-08,30.48,30.78,30.17,30.5,46328300,28.21 594 | 2012-05-09,30.19,30.83,30.1,30.76,50309300,28.45 595 | 2012-05-10,30.86,31.02,30.45,30.74,43839200,28.43 596 | 2012-05-11,30.69,31.54,30.69,31.16,43459300,28.82 597 | 2012-05-14,30.82,31.04,30.64,30.68,40528900,28.37 598 | 2012-05-15,30.64,30.8,30.15,30.21,61822800,28.12 599 | 2012-05-16,30.31,30.32,29.74,29.9,60083700,27.83 600 | 2012-05-17,29.99,30.21,29.71,29.72,48484000,27.67 601 | 2012-05-18,29.79,29.81,29.17,29.27,56205300,27.25 602 | 2012-05-21,29.1,29.79,29.06,29.75,38787900,27.69 603 | 2012-05-22,29.69,29.88,29.5,29.76,39504900,27.7 604 | 2012-05-23,29.35,29.4,28.64,29.11,65171000,27.1 605 | 2012-05-24,29.16,29.3,28.76,29.07,52575000,27.06 606 | 2012-05-25,29.2,29.36,29.01,29.06,29507200,27.05 607 | 2012-05-29,29.38,29.72,29.22,29.56,37758800,27.52 608 | 2012-05-30,29.35,29.48,29.12,29.34,41585500,27.31 609 | 2012-05-31,29.3,29.42,28.94,29.19,39134000,27.17 610 | 2012-06-01,28.76,28.96,28.44,28.45,56634300,26.48 611 | 2012-06-04,28.62,28.78,28.32,28.55,47926300,26.58 612 | 2012-06-05,28.51,28.75,28.39,28.51,45715400,26.54 613 | 2012-06-06,28.88,29.37,28.81,29.35,46860500,27.32 614 | 2012-06-07,29.64,29.7,29.17,29.23,37792800,27.21 615 | 2012-06-08,29.21,29.68,29.05,29.65,42551100,27.6 616 | 2012-06-11,29.73,29.81,28.82,28.9,46361900,26.9 617 | 2012-06-12,29.1,29.3,28.84,29.29,35337900,27.27 618 | 2012-06-13,29.22,29.44,29.05,29.13,32984600,27.12 619 | 2012-06-14,29.33,29.46,28.88,29.34,39458900,27.31 620 | 2012-06-15,29.59,30.08,29.49,30.02,62314400,27.95 621 | 2012-06-18,29.99,30.03,29.71,29.84,58679900,27.78 622 | 2012-06-19,30.19,31.11,30.05,30.7,75725800,28.58 623 | 2012-06-20,30.93,31.05,30.64,30.93,36257100,28.79 624 | 2012-06-21,30.96,31.14,30.06,30.14,48456600,28.06 625 | 2012-06-22,30.3,30.73,30.03,30.7,45098100,28.58 626 | 2012-06-25,30.3,30.32,29.62,29.87,42217200,27.81 627 | 2012-06-26,30.0,30.27,29.94,30.02,38421300,27.95 628 | 2012-06-27,30.19,30.5,30.03,30.17,33781700,28.09 629 | 2012-06-28,29.98,30.05,29.42,29.91,45328400,27.84 630 | 2012-06-29,30.45,30.69,30.14,30.59,55227200,28.48 631 | 2012-07-02,30.62,30.62,30.21,30.56,30589100,28.45 632 | 2012-07-03,30.23,30.76,30.17,30.76,20938100,28.63 633 | 2012-07-05,30.59,30.78,30.38,30.7,28801900,28.58 634 | 2012-07-06,30.61,30.7,29.95,30.19,38294800,28.1 635 | 2012-07-09,30.12,30.23,29.78,30.0,30680800,27.93 636 | 2012-07-10,30.08,30.22,29.51,29.74,37534100,27.68 637 | 2012-07-11,29.71,29.74,29.11,29.3,39184900,27.28 638 | 2012-07-12,29.15,29.18,28.54,28.63,63523600,26.65 639 | 2012-07-13,28.76,29.48,28.72,29.39,39085000,27.36 640 | 2012-07-16,29.48,29.53,29.04,29.44,27900600,27.41 641 | 2012-07-17,29.64,29.86,29.2,29.66,33771300,27.61 642 | 2012-07-18,29.6,30.45,29.46,30.45,41090400,28.35 643 | 2012-07-19,30.51,30.8,30.38,30.67,46663200,28.55 644 | 2012-07-20,31.0,31.05,30.05,30.12,64021700,28.04 645 | 2012-07-23,29.57,29.58,29.01,29.28,55151900,27.26 646 | 2012-07-24,29.24,29.36,28.9,29.15,47723300,27.14 647 | 2012-07-25,29.24,29.33,28.78,28.83,45579500,26.84 648 | 2012-07-26,29.23,29.5,29.09,29.16,45301400,27.14 649 | 2012-07-27,29.48,29.85,29.18,29.76,44242600,27.7 650 | 2012-07-30,29.75,29.82,29.46,29.64,28905000,27.59 651 | 2012-07-31,29.48,29.71,29.33,29.47,37620900,27.43 652 | 2012-08-01,29.59,29.65,29.21,29.41,31721800,27.38 653 | 2012-08-02,29.21,29.53,28.97,29.19,39520500,27.17 654 | 2012-08-03,29.53,29.94,29.48,29.75,35859400,27.69 655 | 2012-08-06,30.0,30.11,29.81,29.95,27471800,27.88 656 | 2012-08-07,30.07,30.35,29.87,30.26,28002900,28.17 657 | 2012-08-08,30.21,30.47,30.11,30.33,26257600,28.23 658 | 2012-08-09,30.39,30.65,30.3,30.5,24920800,28.39 659 | 2012-08-10,30.5,30.62,30.25,30.42,27810300,28.32 660 | 2012-08-13,30.35,30.46,30.16,30.39,23049100,28.29 661 | 2012-08-14,30.3,30.39,30.01,30.13,34551400,28.23 662 | 2012-08-15,30.11,30.28,30.02,30.2,24351000,28.3 663 | 2012-08-16,30.36,30.94,30.26,30.78,35787200,28.84 664 | 2012-08-17,30.92,30.92,30.59,30.9,32589900,28.96 665 | 2012-08-20,30.82,30.85,30.58,30.74,23737700,28.81 666 | 2012-08-21,30.76,30.96,30.61,30.8,28822700,28.86 667 | 2012-08-22,30.59,30.76,30.47,30.54,33437400,28.62 668 | 2012-08-23,30.39,30.4,30.08,30.26,28355600,28.36 669 | 2012-08-24,30.25,30.63,30.18,30.56,22943300,28.64 670 | 2012-08-27,30.93,30.96,30.59,30.69,34691100,28.76 671 | 2012-08-28,30.7,30.8,30.52,30.63,23947900,28.7 672 | 2012-08-29,30.65,30.75,30.44,30.65,23346800,28.72 673 | 2012-08-30,30.53,30.61,30.22,30.32,23982100,28.41 674 | 2012-08-31,30.6,30.96,30.38,30.82,36590100,28.88 675 | 2012-09-04,30.45,30.66,30.15,30.39,48556700,28.48 676 | 2012-09-05,30.22,30.53,30.21,30.39,33650000,28.48 677 | 2012-09-06,30.5,31.36,30.46,31.35,48371700,29.38 678 | 2012-09-07,31.04,31.07,30.73,30.95,42649100,29.0 679 | 2012-09-10,30.83,30.9,30.51,30.72,40524000,28.79 680 | 2012-09-11,30.69,30.91,30.61,30.79,25191800,28.85 681 | 2012-09-12,30.94,31.18,30.73,30.78,32775800,28.84 682 | 2012-09-13,30.89,31.18,30.4,30.94,45047300,28.99 683 | 2012-09-14,31.01,31.25,30.81,31.21,51422800,29.25 684 | 2012-09-17,31.19,31.26,31.04,31.21,36488500,29.25 685 | 2012-09-18,31.1,31.21,31.03,31.18,34542700,29.22 686 | 2012-09-19,31.09,31.19,31.04,31.05,48871900,29.1 687 | 2012-09-20,30.95,31.48,30.91,31.45,45543000,29.47 688 | 2012-09-21,31.43,31.61,31.09,31.19,102348900,29.23 689 | 2012-09-24,31.0,31.07,30.64,30.78,46825900,28.84 690 | 2012-09-25,30.95,31.0,30.36,30.39,54266400,28.48 691 | 2012-09-26,30.28,30.6,30.04,30.17,54672000,28.27 692 | 2012-09-27,30.17,30.4,29.89,30.16,47129900,28.26 693 | 2012-09-28,30.18,30.26,29.74,29.76,54229300,27.89 694 | 2012-10-01,29.81,29.98,29.42,29.49,54042700,27.63 695 | 2012-10-02,29.68,29.89,29.5,29.66,43338900,27.79 696 | 2012-10-03,29.75,29.99,29.67,29.86,46655900,27.98 697 | 2012-10-04,29.97,30.03,29.57,30.03,43634900,28.14 698 | 2012-10-05,30.23,30.25,29.74,29.85,41133900,27.97 699 | 2012-10-08,29.64,29.92,29.55,29.78,29752000,27.91 700 | 2012-10-09,29.68,29.74,29.18,29.28,45121100,27.44 701 | 2012-10-10,29.15,29.31,28.95,28.98,47227100,27.16 702 | 2012-10-11,29.22,29.25,28.87,28.95,41488500,27.13 703 | 2012-10-12,28.97,29.32,28.8,29.2,46464700,27.36 704 | 2012-10-15,29.37,29.72,29.25,29.51,42440200,27.65 705 | 2012-10-16,29.45,29.74,29.32,29.49,47739400,27.63 706 | 2012-10-17,29.3,29.64,29.09,29.59,44206100,27.73 707 | 2012-10-18,29.65,29.73,29.26,29.5,59238500,27.64 708 | 2012-10-19,29.05,29.08,28.5,28.64,90470800,26.84 709 | 2012-10-22,28.73,28.83,27.83,28.0,83374000,26.24 710 | 2012-10-23,27.77,28.2,27.76,28.05,64414800,26.28 711 | 2012-10-24,28.16,28.2,27.87,27.9,53320400,26.14 712 | 2012-10-25,28.19,28.2,27.86,27.88,54084300,26.13 713 | 2012-10-26,27.86,28.34,27.84,28.21,57790000,26.43 714 | 2012-10-31,28.55,28.88,28.5,28.54,69464100,26.74 715 | 2012-11-01,28.84,29.56,28.82,29.52,72047900,27.66 716 | 2012-11-02,29.59,29.77,29.33,29.5,57131600,27.64 717 | 2012-11-05,29.62,29.74,29.33,29.63,38070800,27.77 718 | 2012-11-06,29.82,30.2,29.61,29.86,43401500,27.98 719 | 2012-11-07,29.53,29.83,29.05,29.08,57871800,27.25 720 | 2012-11-08,29.12,29.37,28.8,28.81,49841800,27.0 721 | 2012-11-09,28.88,29.19,28.81,28.83,43291200,27.02 722 | 2012-11-12,28.94,29.01,28.21,28.22,61112300,26.44 723 | 2012-11-13,27.02,27.3,26.75,27.09,131689200,25.59 724 | 2012-11-14,27.24,27.29,26.8,26.84,76086100,25.36 725 | 2012-11-15,26.88,26.97,26.63,26.66,50955600,25.19 726 | 2012-11-16,26.67,26.7,26.34,26.52,64083300,25.06 727 | 2012-11-19,26.8,26.8,26.47,26.73,57179300,25.25 728 | 2012-11-20,26.76,26.8,26.46,26.71,47070400,25.23 729 | 2012-11-21,26.71,27.17,26.67,26.95,66360300,25.46 730 | 2012-11-23,27.23,27.77,27.2,27.7,57845700,26.17 731 | 2012-11-26,27.54,27.58,27.17,27.39,85198700,25.88 732 | 2012-11-27,27.36,27.38,27.04,27.08,45018600,25.58 733 | 2012-11-28,27.01,27.39,26.77,27.36,53018400,25.85 734 | 2012-11-29,27.11,27.36,26.86,26.95,69551400,25.46 735 | 2012-11-30,27.05,27.13,26.49,26.62,83690200,25.15 736 | 2012-12-03,26.78,26.82,26.4,26.43,53173800,24.97 737 | 2012-12-04,26.5,26.63,26.34,26.37,49777500,24.91 738 | 2012-12-05,26.38,26.93,26.26,26.67,68283800,25.2 739 | 2012-12-06,26.81,26.98,26.61,26.73,39182300,25.25 740 | 2012-12-07,26.82,26.82,26.37,26.46,46162100,25.0 741 | 2012-12-10,26.56,26.97,26.52,26.94,47031100,25.45 742 | 2012-12-11,27.05,27.49,27.05,27.32,52282800,25.81 743 | 2012-12-12,27.53,27.62,27.08,27.24,43966300,25.74 744 | 2012-12-13,27.32,27.52,26.95,27.11,45080100,25.61 745 | 2012-12-14,27.11,27.13,26.7,26.81,42077500,25.33 746 | 2012-12-17,26.79,27.22,26.68,27.1,42046100,25.6 747 | 2012-12-18,27.25,27.63,27.14,27.56,50486900,26.04 748 | 2012-12-19,27.69,27.73,27.25,27.31,53519900,25.8 749 | 2012-12-20,27.36,27.68,27.15,27.68,52607300,26.15 750 | 2012-12-21,27.45,27.49,27.0,27.45,98776500,25.93 751 | 2012-12-24,27.2,27.25,27.0,27.06,20842400,25.57 752 | 2012-12-26,27.03,27.2,26.7,26.86,31631100,25.38 753 | 2012-12-27,26.89,27.09,26.57,26.96,39394000,25.47 754 | 2012-12-28,26.71,26.9,26.55,26.55,28239900,25.08 755 | 2012-12-31,26.59,26.77,26.37,26.71,42749500,25.23 756 | 2013-01-02,27.25,27.73,27.15,27.62,52899300,26.09 757 | 2013-01-03,27.63,27.65,27.16,27.25,48294400,25.74 758 | 2013-01-04,27.27,27.34,26.73,26.74,52521100,25.26 759 | 2013-01-07,26.77,26.88,26.64,26.69,37110400,25.22 760 | 2013-01-08,26.75,26.79,26.46,26.55,44703100,25.08 761 | 2013-01-09,26.72,26.75,26.56,26.7,49047900,25.23 762 | 2013-01-10,26.65,26.98,26.29,26.46,71431300,25.0 763 | 2013-01-11,26.49,26.93,26.28,26.83,55512100,25.35 764 | 2013-01-14,26.9,27.08,26.76,26.89,48324400,25.4 765 | 2013-01-15,26.83,27.29,26.83,27.21,48244500,25.71 766 | 2013-01-16,27.15,27.23,27.01,27.04,41077400,25.55 767 | 2013-01-17,27.19,27.47,27.06,27.25,51685900,25.74 768 | 2013-01-18,27.1,27.29,27.04,27.25,52167700,25.74 769 | 2013-01-22,27.3,27.45,27.0,27.15,58650600,25.65 770 | 2013-01-23,27.2,27.64,27.2,27.61,50387700,26.08 771 | 2013-01-24,27.7,28.07,27.47,27.63,101739300,26.1 772 | 2013-01-25,27.58,28.23,27.39,27.88,81847700,26.34 773 | 2013-01-28,28.01,28.23,27.76,27.91,56056500,26.37 774 | 2013-01-29,27.82,28.13,27.6,28.01,49242600,26.46 775 | 2013-01-30,28.01,28.19,27.76,27.85,43580500,26.31 776 | 2013-01-31,27.79,27.97,27.4,27.45,50530000,25.93 777 | 2013-02-01,27.67,28.05,27.55,27.93,55565900,26.39 778 | 2013-02-04,27.87,28.02,27.42,27.44,50540000,25.92 779 | 2013-02-05,27.62,27.66,27.36,27.5,35410400,25.98 780 | 2013-02-06,27.38,27.54,27.25,27.34,41889600,25.83 781 | 2013-02-07,27.35,27.39,27.1,27.28,38028300,25.77 782 | 2013-02-08,27.35,27.71,27.31,27.55,33318500,26.03 783 | 2013-02-11,27.65,27.92,27.5,27.86,32247700,26.32 784 | 2013-02-12,27.88,28.0,27.75,27.88,35990900,26.34 785 | 2013-02-13,27.93,28.11,27.88,28.03,41715600,26.48 786 | 2013-02-14,27.92,28.06,27.87,28.04,32663200,26.49 787 | 2013-02-15,28.04,28.16,27.88,28.01,49650900,26.46 788 | 2013-02-19,27.88,28.09,27.8,28.05,38781400,26.72 789 | 2013-02-20,28.13,28.2,27.83,27.87,44110200,26.55 790 | 2013-02-21,27.74,27.74,27.23,27.49,49078500,26.19 791 | 2013-02-22,27.68,27.76,27.48,27.76,31425900,26.44 792 | 2013-02-25,27.97,28.05,27.37,27.37,48011800,26.07 793 | 2013-02-26,27.38,27.6,27.34,27.37,49923300,26.07 794 | 2013-02-27,27.42,28.0,27.33,27.81,36394700,26.49 795 | 2013-02-28,27.88,27.97,27.74,27.8,35840200,26.48 796 | 2013-03-01,27.72,27.98,27.52,27.95,34849700,26.62 797 | 2013-03-04,27.85,28.15,27.7,28.15,38157500,26.82 798 | 2013-03-05,28.29,28.54,28.16,28.35,41432200,27.01 799 | 2013-03-06,28.21,28.23,27.78,28.09,51448500,26.76 800 | 2013-03-07,28.11,28.28,28.01,28.14,29196700,26.81 801 | 2013-03-08,28.25,28.33,27.96,28.0,37667800,26.67 802 | 2013-03-11,27.94,27.97,27.67,27.87,36627500,26.55 803 | 2013-03-12,27.84,27.95,27.64,27.91,39255200,26.59 804 | 2013-03-13,27.87,28.02,27.75,27.92,29093400,26.6 805 | 2013-03-14,28.0,28.16,27.93,28.14,55914800,26.81 806 | 2013-03-15,28.03,28.16,27.98,28.04,92710300,26.71 807 | 2013-03-18,27.88,28.28,27.81,28.1,44809400,26.77 808 | 2013-03-19,28.12,28.22,28.03,28.18,51901600,26.84 809 | 2013-03-20,28.34,28.49,28.18,28.32,35447800,26.98 810 | 2013-03-21,28.11,28.36,28.05,28.11,34233200,26.78 811 | 2013-03-22,28.19,28.34,28.1,28.25,28720900,26.91 812 | 2013-03-25,28.3,28.35,27.96,28.16,44154000,26.82 813 | 2013-03-26,28.24,28.34,28.11,28.16,27824300,26.82 814 | 2013-03-27,28.14,28.45,28.08,28.37,36047400,27.02 815 | 2013-03-28,28.32,28.66,28.26,28.61,55453800,27.25 816 | 2013-04-01,28.64,28.66,28.36,28.61,29201100,27.25 817 | 2013-04-02,28.59,28.85,28.52,28.8,28456500,27.43 818 | 2013-04-03,28.75,28.95,28.54,28.56,35062800,27.21 819 | 2013-04-04,28.39,28.61,28.27,28.6,45263200,27.24 820 | 2013-04-05,28.22,28.78,28.11,28.7,50927300,27.34 821 | 2013-04-08,28.73,28.73,28.47,28.59,34759500,27.23 822 | 2013-04-09,28.73,29.82,28.68,29.61,77733800,28.21 823 | 2013-04-10,29.57,30.32,29.52,30.28,71116700,28.84 824 | 2013-04-11,29.1,29.2,28.73,28.94,130923200,27.57 825 | 2013-04-12,28.85,29.02,28.66,28.79,62886300,27.42 826 | 2013-04-15,28.65,28.98,28.51,28.69,56332900,27.33 827 | 2013-04-16,28.9,29.14,28.7,28.97,52797300,27.6 828 | 2013-04-17,28.85,29.04,28.6,28.83,52840700,27.46 829 | 2013-04-18,28.95,28.98,28.5,28.79,56906600,27.42 830 | 2013-04-19,29.62,30.24,29.61,29.77,99790700,28.36 831 | 2013-04-22,30.3,31.18,30.27,30.83,137904000,29.37 832 | 2013-04-23,30.7,30.9,30.38,30.6,59126900,29.15 833 | 2013-04-24,30.62,31.92,30.6,31.76,90946600,30.25 834 | 2013-04-25,31.71,32.84,31.54,31.94,110700200,30.43 835 | 2013-04-26,31.9,31.98,31.45,31.79,47799300,30.28 836 | 2013-04-29,31.8,32.68,31.77,32.61,59116400,31.06 837 | 2013-04-30,32.56,33.11,32.28,33.1,75165200,31.53 838 | 2013-05-01,32.93,33.08,32.6,32.72,54330900,31.17 839 | 2013-05-02,32.63,33.17,32.39,33.16,46059500,31.59 840 | 2013-05-03,33.23,33.52,33.08,33.49,46784600,31.9 841 | 2013-05-06,33.42,33.91,33.25,33.75,40978300,32.15 842 | 2013-05-07,33.65,33.79,33.24,33.31,43078300,31.73 843 | 2013-05-08,33.07,33.24,32.65,32.99,51595700,31.43 844 | 2013-05-09,32.85,33.0,32.59,32.66,46417800,31.11 845 | 2013-05-10,32.67,32.72,32.32,32.69,36394900,31.14 846 | 2013-05-13,32.61,33.07,32.55,33.03,36027600,31.46 847 | 2013-05-14,32.86,33.53,32.8,33.53,56870100,32.16 848 | 2013-05-15,33.45,33.9,33.43,33.85,46303900,32.47 849 | 2013-05-16,33.64,34.15,33.55,34.08,59382900,32.69 850 | 2013-05-17,34.13,34.87,34.1,34.87,60666700,33.45 851 | 2013-05-20,34.73,35.1,34.68,35.08,54020800,33.65 852 | 2013-05-21,35.1,35.27,34.72,34.85,48702400,33.43 853 | 2013-05-22,34.79,34.84,34.36,34.61,66047500,33.2 854 | 2013-05-23,34.23,34.55,33.9,34.15,51102700,32.76 855 | 2013-05-24,33.92,34.28,33.9,34.27,33174400,32.87 856 | 2013-05-28,34.42,35.18,34.41,35.02,48212100,33.59 857 | 2013-05-29,34.74,35.02,34.57,34.88,38412200,33.46 858 | 2013-05-30,34.85,35.25,34.81,35.03,51131000,33.6 859 | 2013-05-31,34.82,35.28,34.79,34.9,56165700,33.48 860 | 2013-06-03,34.92,35.63,34.83,35.59,51252600,34.14 861 | 2013-06-04,35.62,35.74,34.77,34.99,65529500,33.56 862 | 2013-06-05,34.6,34.89,34.43,34.78,46025100,33.36 863 | 2013-06-06,34.84,35.11,34.49,34.96,37618500,33.54 864 | 2013-06-07,35.25,35.78,35.06,35.67,40757300,34.22 865 | 2013-06-10,35.51,35.65,35.14,35.47,35994500,34.03 866 | 2013-06-11,35.05,35.18,34.68,34.84,39435900,33.42 867 | 2013-06-12,35.14,35.27,34.85,35.0,37372700,33.57 868 | 2013-06-13,34.99,35.02,34.59,34.72,45654900,33.31 869 | 2013-06-14,34.55,34.69,34.25,34.4,53192600,33.0 870 | 2013-06-17,34.69,35.16,34.63,35.0,49670100,33.57 871 | 2013-06-18,34.97,35.17,34.9,34.98,28616500,33.55 872 | 2013-06-19,34.96,35.09,34.59,34.59,30816200,33.18 873 | 2013-06-20,34.26,34.33,33.37,33.49,54493700,32.13 874 | 2013-06-21,33.66,33.73,33.05,33.27,85338500,31.91 875 | 2013-06-24,32.94,34.2,32.57,33.72,56109000,32.35 876 | 2013-06-25,34.08,34.38,33.46,33.67,44073400,32.3 877 | 2013-06-26,34.12,34.48,33.89,34.35,48665900,32.95 878 | 2013-06-27,34.52,34.78,34.5,34.62,28993100,33.21 879 | 2013-06-28,34.38,34.79,34.34,34.54,65545500,33.13 880 | 2013-07-01,34.75,34.99,34.33,34.36,31055400,32.96 881 | 2013-07-02,34.41,34.44,33.63,33.94,37630000,32.56 882 | 2013-07-03,33.66,34.37,33.6,34.01,15994400,32.62 883 | 2013-07-05,34.09,34.24,33.58,34.21,26085900,32.82 884 | 2013-07-08,34.35,34.59,33.98,34.33,32396900,32.93 885 | 2013-07-09,34.58,34.6,34.14,34.35,25318500,32.95 886 | 2013-07-10,34.34,34.81,34.32,34.7,29658800,33.29 887 | 2013-07-11,35.0,35.77,34.9,35.69,53638300,34.24 888 | 2013-07-12,35.58,35.73,35.28,35.67,35501200,34.22 889 | 2013-07-15,35.66,36.22,35.58,36.17,34142600,34.7 890 | 2013-07-16,36.01,36.43,35.96,36.27,36378500,34.79 891 | 2013-07-17,36.34,36.39,35.49,35.74,37285100,34.28 892 | 2013-07-18,35.72,35.89,35.22,35.44,49547100,34.0 893 | 2013-07-19,32.4,32.67,31.02,31.4,248428500,30.12 894 | 2013-07-22,31.7,32.01,31.6,32.01,79040700,30.71 895 | 2013-07-23,31.91,32.04,31.71,31.82,65810400,30.52 896 | 2013-07-24,32.04,32.19,31.89,31.96,52803100,30.66 897 | 2013-07-25,31.62,31.65,31.25,31.39,63213000,30.11 898 | 2013-07-26,31.26,31.62,31.21,31.62,38633600,30.33 899 | 2013-07-29,31.47,31.6,31.4,31.54,28870700,30.26 900 | 2013-07-30,31.78,32.12,31.55,31.85,45799500,30.55 901 | 2013-07-31,31.97,32.05,31.71,31.84,43898400,30.54 902 | 2013-08-01,32.06,32.09,31.6,31.67,42557900,30.38 903 | 2013-08-02,31.69,31.9,31.57,31.89,29199900,30.59 904 | 2013-08-05,31.9,32.0,31.64,31.7,30984000,30.41 905 | 2013-08-06,31.55,31.67,31.38,31.58,36331500,30.29 906 | 2013-08-07,31.54,32.1,31.25,32.06,38078600,30.75 907 | 2013-08-08,32.24,33.07,32.05,32.89,59034400,31.55 908 | 2013-08-09,32.77,32.9,32.47,32.7,26800700,31.37 909 | 2013-08-12,32.46,32.97,32.46,32.87,25493700,31.53 910 | 2013-08-13,32.51,32.55,32.21,32.23,39464100,31.13 911 | 2013-08-14,32.14,33.36,31.7,32.35,48519600,31.25 912 | 2013-08-15,32.0,32.18,30.84,31.79,33338000,30.71 913 | 2013-08-16,31.79,31.99,31.66,31.8,32866300,30.72 914 | 2013-08-19,31.76,31.97,31.38,31.39,27902500,30.32 915 | 2013-08-20,31.44,31.9,31.37,31.62,22979600,30.55 916 | 2013-08-21,31.61,32.01,31.54,31.61,37409100,30.54 917 | 2013-08-22,32.19,32.49,32.1,32.39,31169900,31.29 918 | 2013-08-23,35.17,35.2,34.0,34.75,225493800,33.57 919 | 2013-08-26,34.4,34.67,34.03,34.15,72786800,32.99 920 | 2013-08-27,33.52,34.1,33.15,33.26,58522300,32.13 921 | 2013-08-28,33.39,33.6,33.0,33.02,44257400,31.9 922 | 2013-08-29,32.93,33.6,32.8,33.55,45284700,32.41 923 | 2013-08-30,33.37,33.48,33.09,33.4,42790200,32.27 924 | 2013-09-03,31.75,32.07,31.29,31.88,154507000,30.8 925 | 2013-09-04,31.39,31.47,31.11,31.2,142320600,30.14 926 | 2013-09-05,31.1,31.44,30.95,31.23,71644900,30.17 927 | 2013-09-06,31.31,31.39,31.13,31.15,75434900,30.09 928 | 2013-09-09,31.22,31.79,31.2,31.66,49628500,30.58 929 | 2013-09-10,31.9,32.4,31.79,32.39,56881200,31.29 930 | 2013-09-11,32.57,32.93,32.53,32.74,39087500,31.63 931 | 2013-09-12,32.72,32.78,32.59,32.69,32860200,31.58 932 | 2013-09-13,32.77,33.07,32.51,33.03,40899000,31.91 933 | 2013-09-16,33.38,33.5,32.73,32.8,52839700,31.69 934 | 2013-09-17,33.42,33.47,32.9,32.93,84716500,31.81 935 | 2013-09-18,32.99,33.4,32.83,33.32,64099900,32.19 936 | 2013-09-19,33.48,33.68,33.32,33.64,42026600,32.5 937 | 2013-09-20,33.41,33.48,32.69,32.79,102904900,31.68 938 | 2013-09-23,32.54,32.97,32.5,32.74,39826100,31.63 939 | 2013-09-24,32.87,32.87,32.15,32.45,40685000,31.35 940 | 2013-09-25,32.49,32.8,32.4,32.51,28907500,31.41 941 | 2013-09-26,32.64,33.0,32.59,32.77,28504000,31.66 942 | 2013-09-27,32.88,33.75,32.87,33.27,55348000,32.14 943 | 2013-09-30,33.0,33.31,32.7,33.28,39839500,32.15 944 | 2013-10-01,33.35,33.61,33.3,33.58,36718700,32.44 945 | 2013-10-02,33.36,34.03,33.29,33.92,46946800,32.77 946 | 2013-10-03,33.88,34.0,33.42,33.86,38703800,32.71 947 | 2013-10-04,33.69,33.99,33.62,33.88,33008100,32.73 948 | 2013-10-07,33.6,33.71,33.2,33.3,35069300,32.17 949 | 2013-10-08,33.31,33.33,32.8,33.01,41017600,31.89 950 | 2013-10-09,33.07,33.35,32.96,33.07,35878600,31.95 951 | 2013-10-10,33.31,33.89,33.26,33.76,42875100,32.61 952 | 2013-10-11,33.68,34.14,33.68,34.13,30033300,32.97 953 | 2013-10-14,33.9,34.5,33.78,34.45,27757900,33.28 954 | 2013-10-15,34.67,34.99,34.47,34.49,47097800,33.32 955 | 2013-10-16,34.6,34.9,34.56,34.64,35111600,33.46 956 | 2013-10-17,34.45,34.99,34.37,34.92,31359200,33.73 957 | 2013-10-18,34.82,34.99,34.33,34.96,41811700,33.77 958 | 2013-10-21,34.98,35.2,34.91,34.99,27433500,33.8 959 | 2013-10-22,35.02,35.1,34.52,34.58,40438500,33.41 960 | 2013-10-23,34.35,34.49,33.67,33.76,58600500,32.61 961 | 2013-10-24,33.82,34.1,33.57,33.72,53209700,32.57 962 | 2013-10-25,35.88,36.29,35.47,35.73,113494000,34.52 963 | 2013-10-28,35.61,35.73,35.27,35.57,38383600,34.36 964 | 2013-10-29,35.63,35.72,35.26,35.52,31702200,34.31 965 | 2013-10-30,35.53,35.79,35.43,35.54,36997700,34.33 966 | 2013-10-31,35.66,35.69,35.34,35.41,41682300,34.21 967 | 2013-11-01,35.67,35.69,35.39,35.53,40264600,34.32 968 | 2013-11-04,35.59,35.98,35.55,35.94,28060700,34.72 969 | 2013-11-05,35.79,36.71,35.77,36.64,51681900,35.4 970 | 2013-11-06,37.24,38.22,37.06,38.18,88948800,36.88 971 | 2013-11-07,37.96,38.01,37.43,37.5,60437400,36.23 972 | 2013-11-08,37.67,37.78,37.34,37.78,36737800,36.5 973 | 2013-11-11,37.69,37.78,37.35,37.59,26872500,36.31 974 | 2013-11-12,37.38,37.6,37.2,37.36,31651600,36.09 975 | 2013-11-13,36.98,38.16,36.9,38.16,44957600,36.86 976 | 2013-11-14,37.87,38.13,37.72,38.02,46183700,36.73 977 | 2013-11-15,37.95,38.02,37.72,37.84,50601300,36.55 978 | 2013-11-18,37.35,37.58,37.07,37.2,53277500,35.94 979 | 2013-11-19,36.85,37.23,36.67,36.74,44275000,35.76 980 | 2013-11-20,36.92,37.41,36.86,37.08,32229900,36.09 981 | 2013-11-21,37.27,37.53,37.26,37.4,23064700,36.4 982 | 2013-11-22,37.53,37.68,37.33,37.57,27982000,36.57 983 | 2013-11-25,37.93,37.95,37.57,37.64,30646800,36.64 984 | 2013-11-26,37.57,37.65,37.35,37.35,34465300,36.35 985 | 2013-11-27,37.57,37.76,37.49,37.6,26002100,36.6 986 | 2013-11-29,37.82,38.29,37.82,38.13,22090400,37.11 987 | 2013-12-02,38.09,38.78,38.06,38.45,42950400,37.43 988 | 2013-12-03,38.14,38.49,38.08,38.31,52109800,37.29 989 | 2013-12-04,38.21,38.98,38.12,38.94,51983600,37.9 990 | 2013-12-05,38.85,38.88,37.18,38.0,116305000,36.99 991 | 2013-12-06,38.42,38.55,37.99,38.36,36457300,37.34 992 | 2013-12-09,38.56,38.87,38.37,38.71,30286000,37.68 993 | 2013-12-10,38.61,38.9,38.02,38.11,37828600,37.09 994 | 2013-12-11,38.06,38.3,37.39,37.61,39853400,36.61 995 | 2013-12-12,37.64,37.64,37.18,37.22,36012800,36.23 996 | 2013-12-13,37.42,37.45,36.62,36.69,40066100,35.71 997 | 2013-12-16,36.73,37.0,36.54,36.89,31734200,35.91 998 | 2013-12-17,36.94,37.11,36.33,36.52,45687700,35.55 999 | 2013-12-18,36.36,36.6,35.53,36.58,63192100,35.61 1000 | 2013-12-19,36.51,36.55,36.08,36.25,34160100,35.28 1001 | 2013-12-20,36.2,36.93,36.19,36.8,62649100,35.82 1002 | 2013-12-23,36.81,36.89,36.55,36.62,25128700,35.64 1003 | 2013-12-24,36.72,37.17,36.64,37.08,14243000,36.09 1004 | 2013-12-26,37.2,37.49,37.17,37.44,17612800,36.44 1005 | 2013-12-27,37.58,37.62,37.17,37.29,14563000,36.3 1006 | 2013-12-30,37.22,37.38,36.9,37.29,16290500,36.3 1007 | 2013-12-31,37.4,37.58,37.22,37.41,17503500,36.41 1008 | 2014-01-02,37.35,37.4,37.1,37.16,30632200,36.17 1009 | 2014-01-03,37.2,37.22,36.6,36.91,31134800,35.93 1010 | 2014-01-06,36.85,36.89,36.11,36.13,43603700,35.17 1011 | 2014-01-07,36.33,36.49,36.21,36.41,35802800,35.44 1012 | 2014-01-08,36.0,36.14,35.58,35.76,59971700,34.81 1013 | 2014-01-09,35.88,35.91,35.4,35.53,36516300,34.58 1014 | 2014-01-10,35.9,36.15,35.75,36.04,40548800,35.08 1015 | 2014-01-13,35.99,36.02,34.83,34.98,45901900,34.05 1016 | 2014-01-14,34.73,35.88,34.63,35.78,41623300,34.83 1017 | 2014-01-15,35.9,36.79,35.85,36.76,44812600,35.78 1018 | 2014-01-16,36.69,37.0,36.31,36.89,38018700,35.91 1019 | 2014-01-17,36.83,36.83,36.15,36.38,46267500,35.41 1020 | 2014-01-21,36.82,36.82,36.06,36.17,31567300,35.21 1021 | 2014-01-22,36.26,36.32,35.75,35.93,21904300,34.97 1022 | 2014-01-23,36.09,36.13,35.52,36.06,43954000,35.1 1023 | 2014-01-24,37.45,37.55,36.53,36.81,76395500,35.83 1024 | 2014-01-27,36.87,36.89,35.98,36.03,44420800,35.07 1025 | 2014-01-28,36.12,36.39,35.75,36.27,36205500,35.3 1026 | 2014-01-29,35.98,36.88,35.9,36.66,52745900,35.68 1027 | 2014-01-30,36.79,36.88,36.23,36.86,35036300,35.88 1028 | 2014-01-31,36.95,37.89,36.56,37.84,93162300,36.83 1029 | 2014-02-03,37.74,37.99,36.43,36.48,64063100,35.51 1030 | 2014-02-04,36.97,37.19,36.25,36.35,54697900,35.38 1031 | 2014-02-05,36.29,36.47,35.8,35.82,55814400,34.87 1032 | 2014-02-06,35.8,36.25,35.69,36.18,35351800,35.22 1033 | 2014-02-07,36.32,36.59,36.01,36.56,33260500,35.59 1034 | 2014-02-10,36.63,36.8,36.29,36.8,26767000,35.82 1035 | 2014-02-11,36.88,37.26,36.86,37.17,32141400,36.18 1036 | 2014-02-12,37.35,37.6,37.3,37.47,27051800,36.47 1037 | 2014-02-13,37.33,37.86,37.33,37.61,37635500,36.61 1038 | 2014-02-14,37.39,37.78,37.33,37.62,31407500,36.62 1039 | 2014-02-18,37.63,37.78,37.41,37.42,32834000,36.7 1040 | 2014-02-19,37.22,37.75,37.21,37.51,29750400,36.78 1041 | 2014-02-20,37.57,37.87,37.4,37.75,27526100,37.02 1042 | 2014-02-21,37.94,38.35,37.86,37.98,38021300,37.24 1043 | 2014-02-24,37.69,37.98,37.54,37.69,32085100,36.96 1044 | 2014-02-25,37.61,37.85,37.35,37.54,30736500,36.81 1045 | 2014-02-26,37.58,37.74,37.19,37.47,41041800,36.74 1046 | 2014-02-27,37.45,37.89,37.23,37.86,33903400,37.13 1047 | 2014-02-28,37.98,38.46,37.82,38.31,41215000,37.57 1048 | 2014-03-03,37.92,38.13,37.49,37.78,29717500,37.05 1049 | 2014-03-04,38.2,38.48,38.07,38.41,26802400,37.67 1050 | 2014-03-05,38.25,38.27,37.93,38.11,20520100,37.37 1051 | 2014-03-06,38.14,38.24,37.89,38.15,23582200,37.41 1052 | 2014-03-07,38.28,38.36,37.69,37.9,26591600,37.17 1053 | 2014-03-10,37.99,38.01,37.72,37.82,19006600,37.09 1054 | 2014-03-11,37.87,38.23,37.72,38.02,25216400,37.28 1055 | 2014-03-12,37.8,38.43,37.79,38.27,30494100,37.53 1056 | 2014-03-13,38.42,38.45,37.64,37.89,32169700,37.16 1057 | 2014-03-14,37.65,38.14,37.51,37.7,27195600,36.97 1058 | 2014-03-17,37.9,38.41,37.79,38.05,20479600,37.31 1059 | 2014-03-18,38.26,39.9,38.22,39.55,64063900,38.78 1060 | 2014-03-19,39.47,39.55,38.91,39.27,35597200,38.51 1061 | 2014-03-20,39.25,40.65,39.24,40.33,59269800,39.55 1062 | 2014-03-21,40.72,40.94,40.01,40.16,80721800,39.38 1063 | 2014-03-24,40.34,40.64,39.86,40.5,46098400,39.72 1064 | 2014-03-25,40.66,40.99,39.96,40.34,43193100,39.56 1065 | 2014-03-26,40.48,40.71,39.6,39.79,41977500,39.02 1066 | 2014-03-27,39.74,39.97,39.34,39.36,35369200,38.6 1067 | 2014-03-28,39.79,40.64,39.68,40.3,43472700,39.52 1068 | 2014-03-31,40.43,41.5,40.4,40.99,46886300,40.2 1069 | 2014-04-01,41.15,41.59,41.07,41.42,32605000,40.62 1070 | 2014-04-02,41.44,41.66,41.17,41.35,28666700,40.55 1071 | 2014-04-03,41.29,41.29,40.71,41.01,30139600,40.22 1072 | 2014-04-04,41.25,41.39,39.64,39.87,51409600,39.1 1073 | 2014-04-07,39.96,40.27,39.74,39.8,37559600,39.03 1074 | 2014-04-08,39.75,39.93,39.2,39.82,35918600,39.05 1075 | 2014-04-09,39.93,40.55,39.88,40.47,27398700,39.69 1076 | 2014-04-10,40.44,40.69,39.09,39.36,45960800,38.6 1077 | 2014-04-11,39.0,39.79,39.0,39.21,34330200,38.45 1078 | 2014-04-14,39.11,39.41,38.9,39.18,32006600,38.42 1079 | 2014-04-15,39.34,39.96,39.05,39.75,33968700,38.98 1080 | 2014-04-16,40.06,40.42,39.91,40.4,30615800,39.62 1081 | 2014-04-17,40.01,40.2,39.51,40.01,36689400,39.24 1082 | 2014-04-21,40.13,40.15,39.79,39.94,22221200,39.17 1083 | 2014-04-22,39.96,40.14,39.83,39.99,27056700,39.22 1084 | 2014-04-23,39.99,39.99,39.47,39.69,24602800,38.92 1085 | 2014-04-24,39.74,39.97,39.3,39.86,42381600,39.09 1086 | 2014-04-25,40.29,40.68,39.75,39.91,56876800,39.14 1087 | 2014-04-28,40.14,41.29,40.09,40.87,50610200,40.08 1088 | 2014-04-29,41.1,41.19,40.39,40.51,29636200,39.73 1089 | 2014-04-30,40.4,40.5,40.17,40.4,35458700,39.62 1090 | 2014-05-01,40.24,40.36,39.95,40.0,28787400,39.23 1091 | 2014-05-02,40.31,40.34,39.66,39.69,43416600,38.92 1092 | 2014-05-05,39.52,39.64,39.3,39.43,22460900,38.67 1093 | 2014-05-06,39.29,39.35,38.95,39.06,27112400,38.3 1094 | 2014-05-07,39.22,39.51,38.51,39.42,41744500,38.66 1095 | 2014-05-08,39.34,39.9,38.97,39.64,32120400,38.87 1096 | 2014-05-09,39.54,39.85,39.37,39.54,29647600,38.77 1097 | 2014-05-12,39.74,40.02,39.65,39.97,22782600,39.2 1098 | 2014-05-13,39.92,40.5,39.85,40.42,27004800,39.92 1099 | 2014-05-14,40.3,40.45,40.05,40.24,18818700,39.74 1100 | 2014-05-15,40.09,40.4,39.51,39.6,37793200,39.11 1101 | 2014-05-16,39.67,39.84,39.27,39.83,29867100,39.33 1102 | 2014-05-19,39.61,39.82,39.46,39.75,24537400,39.26 1103 | 2014-05-20,39.68,39.94,39.46,39.68,21320900,39.19 1104 | 2014-05-21,39.8,40.35,39.74,40.35,22398700,39.85 1105 | 2014-05-22,40.29,40.35,39.85,40.1,20201800,39.6 1106 | 2014-05-23,40.37,40.37,40.0,40.12,18020000,39.62 1107 | 2014-05-27,40.26,40.26,39.81,40.19,26160600,39.69 1108 | 2014-05-28,40.14,40.19,39.82,40.01,25711500,39.51 1109 | 2014-05-29,40.15,40.35,39.91,40.34,19888200,39.84 1110 | 2014-05-30,40.45,40.97,40.25,40.94,34567600,40.43 1111 | 2014-06-02,40.95,41.09,40.68,40.79,18504300,40.28 1112 | 2014-06-03,40.6,40.68,40.25,40.29,18068900,39.79 1113 | 2014-06-04,40.21,40.37,39.86,40.32,23209000,39.82 1114 | 2014-06-05,40.59,41.25,40.4,41.21,31865200,40.7 1115 | 2014-06-06,41.48,41.66,41.24,41.48,24060500,40.96 1116 | 2014-06-09,41.39,41.48,41.02,41.27,15019200,40.76 1117 | 2014-06-10,41.03,41.16,40.86,41.11,15117700,40.6 1118 | 2014-06-11,40.93,41.07,40.77,40.86,18040000,40.35 1119 | 2014-06-12,40.81,40.88,40.29,40.58,29818900,40.08 1120 | 2014-06-13,41.1,41.57,40.86,41.23,26310000,40.72 1121 | 2014-06-16,41.04,41.61,41.04,41.5,24205300,40.98 1122 | 2014-06-17,41.29,41.91,40.34,41.68,22518600,41.16 1123 | 2014-06-18,41.61,41.74,41.18,41.65,27097000,41.13 1124 | 2014-06-19,41.57,41.77,41.33,41.51,19828200,40.99 1125 | 2014-06-20,41.45,41.83,41.38,41.68,47764900,41.16 1126 | 2014-06-23,41.73,42.0,41.69,41.99,18743900,41.47 1127 | 2014-06-24,41.83,41.94,41.56,41.75,26509100,41.23 1128 | 2014-06-25,41.7,42.05,41.46,42.03,20049100,41.51 1129 | 2014-06-26,41.93,41.94,41.43,41.72,23604400,41.2 1130 | 2014-06-27,41.61,42.29,41.51,42.25,74640000,41.72 1131 | 2014-06-30,42.17,42.21,41.7,41.7,30805500,41.18 1132 | 2014-07-01,41.86,42.15,41.69,41.87,26917000,41.35 1133 | 2014-07-02,41.73,41.9,41.53,41.9,20208100,41.38 1134 | 2014-07-03,41.91,41.99,41.56,41.8,15969300,41.28 1135 | 2014-07-07,41.75,42.12,41.71,41.99,21952400,41.47 1136 | 2014-07-08,41.87,42.0,41.61,41.78,31218200,41.26 1137 | 2014-07-09,41.98,41.99,41.53,41.67,18445900,41.15 1138 | 2014-07-10,41.37,42.0,41.05,41.69,21854700,41.17 1139 | 2014-07-11,41.7,42.09,41.48,42.09,24083000,41.57 1140 | 2014-07-14,42.22,42.45,42.04,42.14,21881100,41.62 1141 | 2014-07-15,42.33,42.47,42.03,42.45,28748700,41.92 1142 | 2014-07-16,42.51,44.31,42.48,44.08,63318000,43.53 1143 | 2014-07-17,45.45,45.71,44.25,44.53,82180300,43.98 1144 | 2014-07-18,44.65,44.84,44.25,44.69,43407500,44.13 1145 | 2014-07-21,44.56,45.16,44.22,44.84,37604400,44.28 1146 | 2014-07-22,45.0,45.15,44.59,44.83,43095800,44.27 1147 | 2014-07-23,45.45,45.45,44.62,44.87,52362900,44.31 1148 | 2014-07-24,44.93,45.0,44.32,44.4,30725300,43.85 1149 | 2014-07-25,44.3,44.66,44.3,44.5,26737700,43.95 1150 | 2014-07-28,44.36,44.51,43.93,43.97,29684200,43.42 1151 | 2014-07-29,43.91,44.09,43.64,43.89,27763100,43.34 1152 | 2014-07-30,44.07,44.1,43.29,43.58,31921400,43.04 1153 | 2014-07-31,43.38,43.69,43.08,43.16,31537500,42.62 1154 | 2014-08-01,43.21,43.25,42.6,42.86,31170300,42.33 1155 | 2014-08-04,42.97,43.47,42.81,43.37,34277400,42.83 1156 | 2014-08-05,43.31,43.46,42.83,43.08,26266400,42.54 1157 | 2014-08-06,42.74,43.17,42.21,42.74,24634000,42.21 1158 | 2014-08-07,42.84,43.45,42.65,43.23,30314900,42.69 1159 | 2014-08-08,43.23,43.32,42.91,43.2,28942700,42.66 1160 | 2014-08-11,43.26,43.45,43.02,43.2,20351600,42.66 1161 | 2014-08-12,43.04,43.59,43.0,43.52,21431100,42.98 1162 | 2014-08-13,43.68,44.18,43.52,44.08,22889500,43.53 1163 | 2014-08-14,44.08,44.42,44.01,44.27,19313200,43.72 1164 | 2014-08-15,44.58,44.9,44.4,44.79,41611300,44.23 1165 | 2014-08-18,44.94,45.11,44.68,45.11,26891100,44.55 1166 | 2014-08-19,44.97,45.34,44.83,45.33,28139500,45.05 1167 | 2014-08-20,45.34,45.4,44.9,44.95,24770500,44.67 1168 | 2014-08-21,44.84,45.25,44.83,45.22,22285500,44.94 1169 | 2014-08-22,45.35,45.47,45.07,45.15,18294500,44.87 1170 | 2014-08-25,45.4,45.44,45.04,45.17,16910000,44.89 1171 | 2014-08-26,45.31,45.4,44.94,45.01,14873100,44.73 1172 | 2014-08-27,44.9,45.0,44.76,44.87,21287900,44.59 1173 | 2014-08-28,44.75,44.98,44.61,44.88,17657600,44.6 1174 | 2014-08-29,45.09,45.44,44.86,45.43,21607600,45.15 1175 | 2014-09-02,45.43,45.46,44.85,45.09,22976800,44.81 1176 | 2014-09-03,44.53,45.11,44.53,44.96,33684500,44.68 1177 | 2014-09-04,44.74,45.27,44.72,45.26,26475500,44.98 1178 | 2014-09-05,45.11,45.93,45.11,45.91,36939400,45.62 1179 | 2014-09-08,46.02,46.8,45.99,46.47,45736700,46.18 1180 | 2014-09-09,46.47,46.97,46.42,46.76,40302400,46.47 1181 | 2014-09-10,46.82,46.94,46.28,46.84,27302400,46.55 1182 | 2014-09-11,46.74,47.0,46.47,47.0,29216400,46.71 1183 | 2014-09-12,46.91,47.02,46.6,46.7,38244700,46.41 1184 | 2014-09-15,46.54,46.71,46.1,46.24,37667600,45.95 1185 | 2014-09-16,46.39,46.85,46.29,46.76,27910600,46.47 1186 | 2014-09-17,46.26,46.69,46.23,46.52,38311900,46.23 1187 | 2014-09-18,46.59,46.83,46.46,46.68,35556600,46.39 1188 | 2014-09-19,46.81,47.57,46.6,47.52,202522400,47.22 1189 | 2014-09-22,47.3,47.38,46.98,47.06,38686100,46.77 1190 | 2014-09-23,46.85,46.98,46.47,46.56,33430300,46.27 1191 | 2014-09-24,46.63,47.11,46.34,47.08,26582700,46.78 1192 | 2014-09-25,46.88,47.09,46.03,46.04,33077400,45.75 1193 | 2014-09-26,45.93,46.62,45.76,46.41,27078800,46.12 1194 | 2014-09-29,45.98,46.56,45.76,46.44,26091000,46.15 1195 | 2014-09-30,46.37,46.48,46.01,46.36,33033100,46.07 1196 | 2014-10-01,46.27,46.53,45.85,45.9,38088400,45.61 1197 | 2014-10-02,45.83,46.1,45.64,45.76,25119400,45.47 1198 | 2014-10-03,45.98,46.3,45.61,46.09,32453200,45.8 1199 | 2014-10-06,46.12,46.3,45.92,46.09,20604000,45.8 1200 | 2014-10-07,45.86,45.93,45.42,45.53,25723700,45.24 1201 | 2014-10-08,45.48,46.89,45.34,46.78,33031000,46.49 1202 | 2014-10-09,46.5,46.8,45.74,45.85,34422800,45.56 1203 | 2014-10-10,45.6,46.12,43.95,44.03,51978100,43.75 1204 | 2014-10-13,43.82,44.56,43.49,43.65,37100200,43.38 1205 | 2014-10-14,43.87,44.38,43.56,43.73,38115700,43.46 1206 | 2014-10-15,43.0,43.39,42.1,43.22,60218700,42.95 1207 | 2014-10-16,42.53,43.08,42.22,42.74,49040400,42.47 1208 | 2014-10-17,43.2,43.94,42.79,43.63,40683300,43.36 1209 | 2014-10-20,43.06,44.14,42.81,44.08,34527900,43.8 1210 | 2014-10-21,44.36,44.98,44.19,44.88,36433800,44.6 1211 | 2014-10-22,45.0,45.07,44.23,44.38,33570900,44.1 1212 | 2014-10-23,44.62,45.45,44.53,45.02,45451900,44.74 1213 | 2014-10-24,46.83,46.9,45.18,46.13,61076700,45.84 1214 | 2014-10-27,45.71,46.1,45.71,45.91,30371300,45.62 1215 | 2014-10-28,45.86,46.5,45.77,46.49,29024600,46.2 1216 | 2014-10-29,46.44,46.7,46.34,46.62,30276100,46.33 1217 | 2014-10-30,46.32,46.32,45.77,46.05,30073900,45.76 1218 | 2014-10-31,46.94,46.97,46.48,46.95,35849700,46.66 1219 | 2014-11-03,46.89,47.46,46.73,47.44,23130400,47.14 1220 | 2014-11-04,47.3,47.73,47.25,47.57,21530800,47.27 1221 | 2014-11-05,47.8,47.9,47.26,47.86,22449600,47.56 1222 | 2014-11-06,47.86,48.86,47.79,48.7,33037800,48.39 1223 | 2014-11-07,48.92,48.92,48.29,48.68,28000600,48.37 1224 | 2014-11-10,48.65,49.15,48.55,48.89,36370100,48.58 1225 | 2014-11-11,48.85,48.95,48.65,48.87,23445200,48.56 1226 | 2014-11-12,48.56,48.92,48.52,48.78,22722000,48.47 1227 | 2014-11-13,48.81,49.65,48.71,49.61,26208800,49.3 1228 | 2014-11-14,49.74,50.05,49.39,49.58,29081700,49.27 1229 | 2014-11-17,49.41,49.71,49.14,49.46,30315500,49.15 1230 | 2014-11-18,49.13,49.33,48.7,48.74,23995500,48.74 1231 | 2014-11-19,48.66,48.75,47.93,48.22,26176800,48.22 1232 | 2014-11-20,48.0,48.7,47.87,48.7,21500700,48.7 1233 | 2014-11-21,49.02,49.05,47.57,47.98,42883100,47.98 1234 | 2014-11-24,47.99,48.0,47.39,47.59,35434200,47.59 1235 | 2014-11-25,47.66,47.97,47.45,47.47,28007900,47.47 1236 | 2014-11-26,47.49,47.99,47.28,47.75,27163600,47.75 1237 | 2014-11-28,47.95,48.2,47.61,47.81,21534400,47.81 1238 | 2014-12-01,47.88,48.78,47.71,48.62,31191600,48.62 1239 | 2014-12-02,48.84,49.05,48.2,48.46,25743000,48.46 1240 | 2014-12-03,48.44,48.5,47.81,48.08,23534800,48.08 1241 | 2014-12-04,48.39,49.06,48.2,48.84,30320400,48.84 1242 | 2014-12-05,48.82,48.97,48.38,48.42,27313400,48.42 1243 | 2014-12-08,48.26,48.35,47.45,47.7,26663100,47.7 1244 | 2014-12-09,47.11,47.92,47.05,47.59,24330500,47.59 1245 | 2014-12-10,47.58,47.66,46.7,46.9,30431800,46.9 1246 | 2014-12-11,47.08,47.74,46.68,47.17,29060400,47.17 1247 | 2014-12-12,46.78,47.73,46.67,46.95,34248400,46.95 1248 | 2014-12-15,47.2,47.67,46.55,46.67,29247800,46.67 1249 | 2014-12-16,45.9,46.34,45.13,45.16,47801400,45.16 1250 | 2014-12-17,45.05,45.95,44.9,45.74,34970900,45.74 1251 | 2014-12-18,46.58,47.52,46.34,47.52,40105600,47.52 1252 | 2014-12-19,47.63,48.1,47.17,47.66,64551200,47.66 1253 | 2014-12-22,47.78,48.12,47.71,47.98,26566000,47.98 1254 | 2014-12-23,48.37,48.8,48.13,48.45,23648100,48.45 1255 | 2014-12-24,48.64,48.64,48.08,48.14,11437800,48.14 1256 | 2014-12-26,48.41,48.41,47.82,47.88,13197800,47.88 1257 | 2014-12-29,47.7,47.78,47.26,47.45,14439500,47.45 1258 | 2014-12-30,47.44,47.62,46.84,47.02,16384700,47.02 1259 | 2014-12-31,46.73,47.44,46.45,46.45,21552500,46.45 1260 | 2015-01-02,46.66,47.42,46.54,46.76,27913900,46.76 1261 | 2015-01-05,46.37,46.73,46.25,46.33,39673900,46.33 1262 | 2015-01-06,46.38,46.75,45.54,45.65,35740000,45.65 1263 | -------------------------------------------------------------------------------- /sample/excel.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TabViewer/gtabview/a7a2cf9c9674f957347d5c5cc1e38ee7a3001e7a/sample/excel.xls -------------------------------------------------------------------------------- /sample/multiindex_H2_I4.csv: -------------------------------------------------------------------------------- 1 | lvl0,,,,a,a,b,b,c,c,d,d,e,e 2 | lvl1,,,,bar,foo,bar,foo,bar,foo,bar,foo,bar,foo 3 | ,,,,,,,,,,,,, 4 | A0,B0,C0,D0,1,0,3,2,5,4,7,6,9,8 5 | A0,B0,C0,D1,11,10,13,12,15,14,17,16,19,18 6 | A0,B0,C1,D0,21,20,23,22,25,24,27,26,29,28 7 | A0,B0,C1,D1,31,30,33,32,35,34,37,36,39,38 8 | A0,B0,C2,D0,41,40,43,42,45,44,47,46,49,48 9 | A0,B0,C2,D1,51,50,53,52,55,54,57,56,59,58 10 | A0,B0,C3,D0,61,60,63,62,65,64,67,66,69,68 11 | A0,B0,C3,D1,71,70,73,72,75,74,77,76,79,78 12 | A0,B1,C0,D0,81,80,83,82,85,84,87,86,89,88 13 | A0,B1,C0,D1,91,90,93,92,95,94,97,96,99,98 14 | A0,B1,C1,D0,101,100,103,102,105,104,107,106,109,108 15 | A0,B1,C1,D1,111,110,113,112,115,114,117,116,119,118 16 | A0,B1,C2,D0,121,120,123,122,125,124,127,126,129,128 17 | A0,B1,C2,D1,131,130,133,132,135,134,137,136,139,138 18 | A0,B1,C3,D0,141,140,143,142,145,144,147,146,149,148 19 | A0,B1,C3,D1,151,150,153,152,155,154,157,156,159,158 20 | A1,B0,C0,D0,161,160,163,162,165,164,167,166,169,168 21 | A1,B0,C0,D1,171,170,173,172,175,174,177,176,179,178 22 | A1,B0,C1,D0,181,180,183,182,185,184,187,186,189,188 23 | A1,B0,C1,D1,191,190,193,192,195,194,197,196,199,198 24 | A1,B0,C2,D0,201,200,203,202,205,204,207,206,209,208 25 | A1,B0,C2,D1,211,210,213,212,215,214,217,216,219,218 26 | A1,B0,C3,D0,221,220,223,222,225,224,227,226,229,228 27 | A1,B0,C3,D1,231,230,233,232,235,234,237,236,239,238 28 | A1,B1,C0,D0,241,240,243,242,245,244,247,246,249,248 29 | A1,B1,C0,D1,251,250,253,252,255,254,257,256,259,258 30 | A1,B1,C1,D0,261,260,263,262,265,264,267,266,269,268 31 | A1,B1,C1,D1,271,270,273,272,275,274,277,276,279,278 32 | A1,B1,C2,D0,281,280,283,282,285,284,287,286,289,288 33 | A1,B1,C2,D1,291,290,293,292,295,294,297,296,299,298 34 | A1,B1,C3,D0,301,300,303,302,305,304,307,306,309,308 35 | A1,B1,C3,D1,311,310,313,312,315,314,317,316,319,318 36 | A2,B0,C0,D0,321,320,323,322,325,324,327,326,329,328 37 | A2,B0,C0,D1,331,330,333,332,335,334,337,336,339,338 38 | A2,B0,C1,D0,341,340,343,342,345,344,347,346,349,348 39 | A2,B0,C1,D1,351,350,353,352,355,354,357,356,359,358 40 | A2,B0,C2,D0,361,360,363,362,365,364,367,366,369,368 41 | A2,B0,C2,D1,371,370,373,372,375,374,377,376,379,378 42 | A2,B0,C3,D0,381,380,383,382,385,384,387,386,389,388 43 | A2,B0,C3,D1,391,390,393,392,395,394,397,396,399,398 44 | A2,B1,C0,D0,401,400,403,402,405,404,407,406,409,408 45 | A2,B1,C0,D1,411,410,413,412,415,414,417,416,419,418 46 | A2,B1,C1,D0,421,420,423,422,425,424,427,426,429,428 47 | A2,B1,C1,D1,431,430,433,432,435,434,437,436,439,438 48 | A2,B1,C2,D0,441,440,443,442,445,444,447,446,449,448 49 | A2,B1,C2,D1,451,450,453,452,455,454,457,456,459,458 50 | A2,B1,C3,D0,461,460,463,462,465,464,467,466,469,468 51 | A2,B1,C3,D1,471,470,473,472,475,474,477,476,479,478 52 | A3,B0,C0,D0,481,480,483,482,485,484,487,486,489,488 53 | A3,B0,C0,D1,491,490,493,492,495,494,497,496,499,498 54 | A3,B0,C1,D0,501,500,503,502,505,504,507,506,509,508 55 | A3,B0,C1,D1,511,510,513,512,515,514,517,516,519,518 56 | A3,B0,C2,D0,521,520,523,522,525,524,527,526,529,528 57 | A3,B0,C2,D1,531,530,533,532,535,534,537,536,539,538 58 | A3,B0,C3,D0,541,540,543,542,545,544,547,546,549,548 59 | A3,B0,C3,D1,551,550,553,552,555,554,557,556,559,558 60 | A3,B1,C0,D0,561,560,563,562,565,564,567,566,569,568 61 | A3,B1,C0,D1,571,570,573,572,575,574,577,576,579,578 62 | A3,B1,C1,D0,581,580,583,582,585,584,587,586,589,588 63 | A3,B1,C1,D1,591,590,593,592,595,594,597,596,599,598 64 | A3,B1,C2,D0,601,600,603,602,605,604,607,606,609,608 65 | A3,B1,C2,D1,611,610,613,612,615,614,617,616,619,618 66 | A3,B1,C3,D0,621,620,623,622,625,624,627,626,629,628 67 | A3,B1,C3,D1,631,630,633,632,635,634,637,636,639,638 68 | -------------------------------------------------------------------------------- /sample/pandas-example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import pandas as pd 3 | import numpy as np 4 | import gtabview 5 | 6 | c_arr = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], 7 | ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] 8 | columns = pd.MultiIndex.from_tuples(list(zip(*c_arr)), names=['V1', 'V2']) 9 | 10 | i_arr = [['bar', 'bar', 'bar', 'bar', 'baz', 'baz', 'baz', 'baz'], 11 | ['foo', 'foo', 'qux', 'qux', 'foo', 'foo', 'qux', 'qux'], 12 | ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] 13 | index = pd.MultiIndex.from_tuples(list(zip(*i_arr)), names=['H1', 'H2', 'H3']) 14 | 15 | df = pd.DataFrame(np.random.randn(8, 8), columns=columns, index=index) 16 | gtabview.view(df) 17 | -------------------------------------------------------------------------------- /sample/test_latin-1.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TabViewer/gtabview/a7a2cf9c9674f957347d5c5cc1e38ee7a3001e7a/sample/test_latin-1.csv -------------------------------------------------------------------------------- /sample/unicode-example-utf8.txt: -------------------------------------------------------------------------------- 1 | Origin (English),Name (English),Origin (Native),Name (Native) 2 | Australia,Nicole Kidman,Australia,Nicole Kidman 3 | Austria,Johann Strauss,Österreich,Johann Strauß 4 | Belgium (Flemish),Rene Magritte,België,René Magritte 5 | Belgium (French),Rene Magritte,Belgique,René Magritte 6 | Belgium (German),Rene Magritte,Belgien,René Magritte 7 | Bhutan,Gonpo Dorji,འབྲུག་ཡུལ།,མགོན་པོ་རྡོ་རྗེ། 8 | Canada,Celine Dion,Canada,Céline Dion 9 | Canada - Nunavut (Inuktitut),Susan Aglukark,ᓄᓇᕗᒻᒥᐅᑦ,ᓱᓴᓐ ᐊᒡᓗᒃᑲᖅ 10 | Democratic People's Rep. of Korea,LEE Sol-Hee,조선 민주주의 인민 공화국,이설희 11 | Denmark,Soren Hauch-Fausboll,Danmark,Søren Hauch-Fausbøll 12 | Denmark,Soren Kierkegaard,Danmark,Søren Kierkegård 13 | Egypt,Abdel Halim Hafez,ﻣﺼﺮ,ﻋﺑﺪﺍﻠﺣﻟﻳﻢ ﺤﺎﻓﻅ 14 | Egypt,Om Kolthoum,ﻣﺼﺮ,ﺃﻡ ﻛﻟﺛﻭﻡ 15 | Eritrea,Berhane Zeray,ብርሃነ ዘርኣይ,ኤርትራ 16 | Ethiopia,Haile Gebreselassie,ኃይሌ ገብረሥላሴ,ኢትዮጵያ 17 | France,Gerard Depardieu,France,Gérard Depardieu 18 | France,Jean Reno,France,Jean Réno 19 | France,Camille Saint-Saens,France,Camille Saint-Saëns 20 | France,Mylene Demongeot,France,Mylène Demongeot 21 | France,Francois Truffaut,France,François Truffaut 22 | France (Braille),Louis Braille,⠋⠗⠁⠝⠉⠑,⠇⠕⠥⠊⠎⠀
⠃⠗⠁⠊⠇⠇⠑ 23 | Georgia,Eduard Shevardnadze,საქართველო,ედუარდ შევარდნაძე 24 | Germany,Rudi Voeller,Deutschland,Rudi Völler 25 | Germany,Walter Schultheiss,Deutschland,Walter Schultheiß 26 | Greece,Giorgos Dalaras,Ελλάς,Γιώργος Νταλάρας 27 | Iceland,Bjork Gudmundsdottir,Ísland,Björk Guðmundsdóttir 28 | India (Hindi),Madhuri Dixit,भारत,माधुरी दिछित 29 | Ireland,Sinead O'Connor,Éire,Sinéad O'Connor 30 | Israel,Yehoram Gaon,ישראל,יהורם גאון 31 | Italy,Fabrizio DeAndre,Italia,Fabrizio De André 32 | Japan,KUBOTA Toshinobu,日本,久保田    利伸 33 | Japan,HAYASHIBARA Megumi,日本,林原 めぐみ 34 | Japan,Mori Ogai,日本,森鷗外 35 | Japan,Tex Texin,日本,テクス テクサン 36 | Norway,Tor Age Bringsvaerd,Noreg,Tor Åge Bringsværd 37 | Pakistan (Urdu),Nusrat Fatah Ali Khan,پاکستان,نصرت فتح علی خان 38 | People's Rep. of China,ZHANG Ziyi,中国,章子怡 39 | People's Rep. of China,WONG Faye,中国,王菲 40 | Poland,Lech Walesa,Polska,Lech Wałęsa 41 | Puerto Rico,Olga Tanon,Puerto Rico,Olga Tañón 42 | Rep. of China,Hsu Chi,臺灣,舒淇 43 | Rep. of China,Ang Lee,臺灣,李安 44 | Rep. of Korea,AHN Sung-Gi,한민국,안성기 45 | Rep. of Korea,SHIM Eun-Ha,한민국,심은하 46 | Russia,Mikhail Gorbachev,Россия,Михаил Горбачёв 47 | Russia,Boris Grebenshchikov,Россия,Борис Гребенщиков 48 | Slovenia,"Frane ""Jezek"" Milcinski",Slovenija,Frane Milčinski - Ježek 49 | Syracuse (Sicily),Archimedes,Συρακούσα,Ἀρχιμήδης 50 | Thailand,Thongchai McIntai,ประเทศไทย,ธงไชย แม็คอินไตย์ 51 | U.S.A.,Brad Pitt,U.S.A.,Brad Pitt 52 | Yugoslavia (Cyrillic),Djordje Balasevic,Југославија,Ђорђе Балашевић 53 | Yugoslavia (Latin),Djordje Balasevic,Jugoslavija,Đorđe Balašević 54 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from setuptools import setup, find_packages 3 | import gtabview_cli 4 | 5 | # long description with latest release notes 6 | readme = open('README.rst').read() 7 | news = open('NEWS.rst').read() 8 | long_description = (readme + "\n\nLatest release notes\n====================\n" 9 | + '\n'.join(news.split('\n\n\n', 1)[0].splitlines()[2:])) 10 | 11 | # the actual setup 12 | setup(name='gtabview', version=gtabview_cli.__version__, 13 | description='A simple graphical tabular data viewer', 14 | 15 | author="Yuri D'Elia", 16 | author_email="wavexx@thregr.org", 17 | license="MIT", 18 | long_description=long_description, 19 | long_description_content_type='text/x-rst', 20 | url="https://github.com/TabViewer/gtabview", 21 | keywords='data spreadsheet view viewer csv comma separated values', 22 | classifiers=['Development Status :: 5 - Production/Stable', 23 | 'Environment :: Win32 (MS Windows)', 24 | 'Environment :: MacOS X', 25 | 'Environment :: X11 Applications :: Qt', 26 | 'Intended Audience :: Science/Research', 27 | 'License :: OSI Approved :: MIT License', 28 | 'Operating System :: OS Independent', 29 | 'Programming Language :: Python', 30 | 'Programming Language :: Python :: 2.7', 31 | 'Programming Language :: Python :: 3', 32 | 'Topic :: Office/Business :: Financial :: Spreadsheet', 33 | 'Topic :: Scientific/Engineering :: Visualization', 34 | 'Topic :: Software Development :: User Interfaces', 35 | 'Topic :: Software Development :: Widget Sets', 36 | 'Topic :: Utilities'], 37 | 38 | packages=find_packages(), 39 | setup_requires=['setuptools'], 40 | extras_require={'test': ['nose']}, 41 | test_suite='nose.collector', 42 | entry_points={ 43 | 'console_scripts': [ 44 | 'gtabview=gtabview_cli.gtabview:main', 45 | ], 46 | }, 47 | data_files=[('share/doc/gtabview', ['README.rst', 'NEWS.rst'])]) 48 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | import gtabview 5 | from gtabview import view 6 | 7 | import importlib 8 | import nose 9 | import os 10 | 11 | PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__)) 12 | SAMPLE_ROOT = os.path.join(PROJECT_ROOT, "sample") 13 | TDATA_ROOT = os.path.join(os.path.dirname(__file__), "data") 14 | 15 | 16 | class require(object): 17 | def __init__(self, module): 18 | self.module = module 19 | 20 | def __call__(self, func): 21 | def wrapper(): 22 | try: 23 | importlib.import_module(self.module) 24 | except ImportError: 25 | raise nose.SkipTest("requires {}".format(self.module)) 26 | return func() 27 | wrapper.__name__ = func.__name__ 28 | return wrapper 29 | 30 | 31 | def materialize(model): 32 | shape = model.shape 33 | return [[model.data(y, x) for x in range(shape[1])] for y in range(shape[0])] 34 | 35 | def materialize_header(model, axis): 36 | shape = model.shape 37 | header_shape = model.header_shape 38 | return [[model.header(axis, x, level) for x in range(shape[not axis])] 39 | for level in range(header_shape[axis])] 40 | 41 | def materialize_names(model, axis): 42 | shape = model.header_shape 43 | return [model.name(axis, x) for x in range(shape[axis])] 44 | -------------------------------------------------------------------------------- /tests/data/empty-line-1.txt: -------------------------------------------------------------------------------- 1 | a b c 2 | 3 | 1 2 3 4 | -------------------------------------------------------------------------------- /tests/data/empty-line-2.txt: -------------------------------------------------------------------------------- 1 | a,b,c 2 | ,, 3 | 1,2,3 4 | -------------------------------------------------------------------------------- /tests/data/hash-headers.txt: -------------------------------------------------------------------------------- 1 | #a b c 2 | 1 2 3 3 | -------------------------------------------------------------------------------- /tests/data/not-xls.xls: -------------------------------------------------------------------------------- 1 | a,b,c 2 | 1,2,3 3 | 4,5,6 4 | -------------------------------------------------------------------------------- /tests/data/simple.csv: -------------------------------------------------------------------------------- 1 | a,b,c 2 | 1,2,3 3 | 4,5,6 4 | -------------------------------------------------------------------------------- /tests/data/simple.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TabViewer/gtabview/a7a2cf9c9674f957347d5c5cc1e38ee7a3001e7a/tests/data/simple.xls -------------------------------------------------------------------------------- /tests/test_dataio.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | from . import * 5 | from gtabview.dataio import read_table 6 | 7 | 8 | def test_skip_empty_line_1(): 9 | data, _ = read_table(os.path.join(TDATA_ROOT, 'empty-line-1.txt'), None, None, 1) 10 | assert(data == [['a', 'b', 'c'], ['1', '2', '3']]) 11 | 12 | def test_skip_empty_line_2(): 13 | data, _ = read_table(os.path.join(TDATA_ROOT, 'empty-line-2.txt'), None, None, 1) 14 | assert(data == [['a', 'b', 'c'], ['1', '2', '3']]) 15 | 16 | def test_hash_headers(): 17 | data, _ = read_table(os.path.join(TDATA_ROOT, 'hash-headers.txt'), None, None, 1) 18 | assert(data == [['a', 'b', 'c'], ['1', '2', '3']]) 19 | 20 | def test_xls_fallback(): 21 | data, _ = read_table(os.path.join(TDATA_ROOT, 'not-xls.xls'), None, None, 1) 22 | assert(data == [['a', 'b', 'c'], ['1', '2', '3'], ['4', '5', '6']]) 23 | 24 | @require('xlrd') 25 | def test_xls_read(): 26 | data, _ = read_table(os.path.join(TDATA_ROOT, 'simple.xls'), None, None, 1) 27 | assert(data == [['a', 'b', 'c'], [1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) 28 | -------------------------------------------------------------------------------- /tests/test_models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | from . import * 5 | from gtabview.models import as_model 6 | 7 | 8 | def test_model_id(): 9 | model = as_model([1, 2, 3]) 10 | assert(as_model(model) is model) 11 | 12 | def test_model_vect(): 13 | model = as_model([1, 2, 3]) 14 | assert(model.header_shape == (0, 0)) 15 | assert(model.shape == (3, 1)) 16 | assert(materialize(model) == [[1], [2], [3]]) 17 | 18 | def test_model_vect_str(): 19 | model = as_model(['aaa', 'bbb', 'ccc']) 20 | assert(model.header_shape == (0, 0)) 21 | assert(model.shape == (3, 1)) 22 | assert(materialize(model) == [['aaa'], ['bbb'], ['ccc']]) 23 | 24 | def test_model_set(): 25 | model = as_model({'a', 'b', 'c'}) 26 | assert(model.header_shape == (0, 0)) 27 | assert(model.shape == (3, 1)) 28 | assert(sorted(materialize(model)) == [['a'], ['b'], ['c']]) 29 | 30 | def test_model_iterable(): 31 | model = as_model(sorted(['c', 'b', 'a'])) 32 | assert(model.header_shape == (0, 0)) 33 | assert(model.shape == (3, 1)) 34 | assert(materialize(model) == [['a'], ['b'], ['c']]) 35 | 36 | def test_model_dict(): 37 | model = as_model({'a': [1, 2, 3], 'b': [1, 2, 3]}) 38 | assert(model.header_shape == (1, 0)) 39 | assert(model.shape == (3, 2)) 40 | assert(materialize(model) == [[1, 1], [2, 2], [3, 3]]) 41 | assert(sorted(materialize_header(model, 0)) == [['a', 'b']]) 42 | assert(materialize_header(model, 1) == []) 43 | 44 | def test_model_ordered_dict(): 45 | from collections import OrderedDict 46 | model = as_model(OrderedDict([('b', [1, 2, 3]), ('a', [1, 2, 3])])) 47 | assert(model.header_shape == (1, 0)) 48 | assert(model.shape == (3, 2)) 49 | assert(materialize(model) == [[1, 1], [2, 2], [3, 3]]) 50 | assert(materialize_header(model, 0) == [['b', 'a']]) 51 | assert(materialize_header(model, 1) == []) 52 | 53 | def test_model_ordered_dict_sort(): 54 | from collections import OrderedDict 55 | model = as_model(OrderedDict([('b', [1, 2, 3]), ('a', [1, 2, 3])]), sort=True) 56 | assert(model.header_shape == (1, 0)) 57 | assert(model.shape == (3, 2)) 58 | assert(materialize(model) == [[1, 1], [2, 2], [3, 3]]) 59 | assert(materialize_header(model, 0) == [['a', 'b']]) 60 | assert(materialize_header(model, 1) == []) 61 | 62 | def test_model_dict_ragged(): 63 | model = as_model({'a': [1, 2], 'b': [1, 2, 3]}) 64 | assert(model.header_shape == (1, 0)) 65 | assert(model.shape == (3, 2)) 66 | assert(materialize(model) == [[1, 1], [2, 2], [None, 3]]) 67 | assert(materialize_header(model, 0) == [['a', 'b']]) 68 | assert(materialize_header(model, 1) == []) 69 | 70 | def test_model_list(): 71 | model = as_model([[1, 2, 3], [1, 2, 3]]) 72 | assert(model.header_shape == (0, 0)) 73 | assert(model.shape == (2, 3)) 74 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 75 | 76 | def test_model_list_hdr_idx(): 77 | model = as_model([[None, 'a', 'b', 'c'], ['x', 1, 2, 3], ['y', 1, 2, 3]], hdr_rows=1, idx_cols=1) 78 | assert(model.header_shape == (1, 1)) 79 | assert(model.shape == (2, 3)) 80 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 81 | assert(materialize_header(model, 0) == [['a', 'b', 'c']]) 82 | assert(materialize_header(model, 1) == [['x', 'y']]) 83 | 84 | def test_model_list_ragged(): 85 | model = as_model([[1, 2], [1, 2, 3]]) 86 | assert(model.header_shape == (0, 0)) 87 | assert(model.shape == (2, 3)) 88 | assert(materialize(model) == [[1, 2, None], [1, 2, 3]]) 89 | 90 | @require('pandas') 91 | def test_model_frame(): 92 | import pandas as pd 93 | model = as_model(pd.DataFrame([[1, 2, 3], [1, 2, 3]], 94 | columns=['a', 'b', 'c'], 95 | index=['x', 'y'])) 96 | assert(model.header_shape == (1, 1)) 97 | assert(model.shape == (2, 3)) 98 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 99 | assert(materialize_header(model, 0) == [['a', 'b', 'c']]) 100 | assert(materialize_header(model, 1) == [['x', 'y']]) 101 | 102 | @require('pandas') 103 | def test_model_frame_multiindex(): 104 | import pandas as pd 105 | col_index = pd.MultiIndex.from_tuples( 106 | list(zip(['A', 'B', 'C'], ['a', 'b', 'c'])), 107 | names=['CL0', 'CL1']) 108 | row_index = pd.MultiIndex.from_tuples( 109 | list(zip(['X', 'Y'], ['x', 'y'])), 110 | names=['RL0', 'RL1']) 111 | model = as_model(pd.DataFrame([[1, 2, 3], [1, 2, 3]], 112 | columns=col_index, 113 | index=row_index)) 114 | assert(model.header_shape == (2, 2)) 115 | assert(model.shape == (2, 3)) 116 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 117 | assert(materialize_header(model, 0) == [['A', 'B', 'C'], ['a', 'b', 'c']]) 118 | assert(materialize_header(model, 1) == [['X', 'Y'], ['x', 'y']]) 119 | assert(materialize_names(model, 0) == ['CL0', 'CL1']) 120 | assert(materialize_names(model, 1) == ['RL0', 'RL1']) 121 | 122 | @require('pandas') 123 | def test_model_transpose(): 124 | import pandas as pd 125 | col_index = pd.MultiIndex.from_tuples( 126 | list(zip(['A', 'B', 'C'], ['a', 'b', 'c'])), 127 | names=['CL0', 'CL1']) 128 | row_index = pd.MultiIndex.from_tuples( 129 | list(zip(['X', 'Y'], ['x', 'y'])), 130 | names=['RL0', 'RL1']) 131 | model = as_model(pd.DataFrame([[1, 2, 3], [1, 2, 3]], 132 | columns=col_index, 133 | index=row_index), 134 | transpose=True) 135 | assert(model.header_shape == (2, 2)) 136 | assert(model.shape == (3, 2)) 137 | assert(materialize(model) == [[1, 1], [2, 2], [3, 3]]) 138 | assert(materialize_header(model, 0) == [['X', 'Y'], ['x', 'y']]) 139 | assert(materialize_header(model, 1) == [['A', 'B', 'C'], ['a', 'b', 'c']]) 140 | assert(materialize_names(model, 0) == ['RL0', 'RL1']) 141 | assert(materialize_names(model, 1) == ['CL0', 'CL1']) 142 | 143 | @require('pandas') 144 | def test_model_series(): 145 | import pandas as pd 146 | model = as_model(pd.Series([1, 2, 3], name='serie', index=['x', 'y', 'z'])) 147 | assert(model.header_shape == (1, 1)) 148 | assert(model.shape == (3, 1)) 149 | assert(materialize(model) == [[1], [2], [3]]) 150 | assert(materialize_header(model, 0) == [['serie']]) 151 | assert(materialize_header(model, 1) == [['x', 'y', 'z']]) 152 | 153 | @require('numpy') 154 | def test_model_array(): 155 | import numpy as np 156 | model = as_model(np.array([[1, 2, 3], [1, 2, 3]])) 157 | assert(model.header_shape == (0, 0)) 158 | assert(model.shape == (2, 3)) 159 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 160 | 161 | @require('numpy') 162 | def test_model_matrix(): 163 | import numpy as np 164 | import warnings 165 | with warnings.catch_warnings(): 166 | warnings.simplefilter('ignore', PendingDeprecationWarning) 167 | model = as_model(np.matrix([[1, 2, 3], [1, 2, 3]])) 168 | assert(model.header_shape == (0, 0)) 169 | assert(model.shape == (2, 3)) 170 | assert(materialize(model) == [[1, 2, 3], [1, 2, 3]]) 171 | -------------------------------------------------------------------------------- /tests/test_view.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function, unicode_literals, absolute_import 3 | 4 | from . import * 5 | gtabview.WAIT = False 6 | 7 | 8 | def test_view_vect(): 9 | view([1, 2, 3]) 10 | 11 | def test_view_vect_empty(): 12 | view([]) 13 | 14 | def test_view_dict(): 15 | view({'a': [1, 2, 3], 'b': [1, 2, 3]}) 16 | 17 | def test_view_dict_empty(): 18 | view({}) 19 | 20 | def test_view_dict_empty_vect(): 21 | view({'a': []}) 22 | 23 | def test_view_list(): 24 | view([[1, 2, 3], [1, 2, 3]]) 25 | 26 | def test_view_list_empty(): 27 | view([[]]) 28 | 29 | def test_view_csv_latin1(): 30 | view(os.path.join(SAMPLE_ROOT, "test_latin-1.csv")) 31 | 32 | def test_view_csv_unicode(): 33 | view(os.path.join(SAMPLE_ROOT, "unicode-example-utf8.txt")) 34 | 35 | @require('pandas') 36 | def test_view_frame(): 37 | import pandas as pd 38 | view(pd.DataFrame([[1, 2, 3], [1, 2, 3]], 39 | columns=['a', 'b', 'c'], 40 | index=['x', 'y'])) 41 | 42 | @require('pandas') 43 | def test_view_frame_empty(): 44 | import pandas as pd 45 | view(pd.DataFrame()) 46 | --------------------------------------------------------------------------------