# Path: liam2/compat.py
# PY2 = sys.version_info[0] == 2
# def with_metaclass(meta, *bases):
#         def __new__(cls, name, this_bases, d):
# def csv_open(filename, mode='r'):
#     class metaclass(meta):
# 
# Path: liam2/config.py



import ast
import itertools
import math
import re
import sys
import time
import warnings
import numpy as np
import numexpr as ne
import larray as la
from collections import defaultdict, deque, namedtuple
from textwrap import wrap
from liam2.compat import zip, basestring
from liam2 import config
    from liam2.data import ColumnArray
    from cutils import fromiter

def table2str(table, missing):
    """table is a list of lists"""
    if not table:
        return ''
    numcols = max(len(row) for row in table)
    # pad rows that have too few columns
    for row in table:
        if len(row) < numcols:
            row.extend([''] * (numcols - len(row)))
    formatted = [[format_value(value, missing) for value in row]
                 for row in table]
    colwidths = [get_col_width(formatted, i) for i in range(numcols)]

    total_width = sum(colwidths)
    sep_width = (len(colwidths) - 1) * 3
    if total_width + sep_width > 80:
        minwidths = [get_min_width(formatted, i) for i in range(numcols)]
        available_width = 80.0 - sep_width - sum(minwidths)
        ratio = available_width / total_width
        colwidths = [minw + max(int(width * ratio), 0)
                     for minw, width in zip(minwidths, colwidths)]

    lines = []
    for row in formatted:
        # this kills any existing newline character in value
        wrapped_row = [wrap(value, width)
                       for value, width in zip(row, colwidths)]
        maxheight = max(len(value) for value in wrapped_row)
        newlines = [[] for _ in range(maxheight)]

# Path: liam2/compat.py
# PY2 = sys.version_info[0] == 2
# def with_metaclass(meta, *bases):
#         def __new__(cls, name, this_bases, d):
# def csv_open(filename, mode='r'):
#     class metaclass(meta):
# 
# Path: liam2/config.py



# Path: liam2/utils.py
import ast
import itertools
import math
import re
import sys
import time
import warnings
import numpy as np
import numexpr as ne
import larray as la
from collections import defaultdict, deque, namedtuple
from textwrap import wrap
from liam2.compat import zip, basestring
from liam2 import config
    from liam2.data import ColumnArray
    from cutils import fromiter


def table2str(table, missing):
    """table is a list of lists"""
    if not table:
        return ''
    numcols = max(len(row) for row in table)
    # pad rows that have too few columns
    for row in table:
        if len(row) < numcols:
            row.extend([''] * (numcols - len(row)))
    formatted = [[format_value(value, missing) for value in row]
                 for row in table]
    colwidths = [get_col_width(formatted, i) for i in range(numcols)]

    total_width = sum(colwidths)
    sep_width = (len(colwidths) - 1) * 3
    if total_width + sep_width > 80:
        minwidths = [get_min_width(formatted, i) for i in range(numcols)]
        available_width = 80.0 - sep_width - sum(minwidths)
        ratio = available_width / total_width
        colwidths = [minw + max(int(width * ratio), 0)
                     for minw, width in zip(minwidths, colwidths)]

    lines = []
    for row in formatted:
        # this kills any existing newline character in value
        wrapped_row = [wrap(value, width)
                       for value, width in zip(row, colwidths)]
        maxheight = max(len(value) for value in wrapped_row)
        newlines = [[] for _ in range(maxheight)]

        for value, width in zip(wrapped_row, colwidths):