<commit_before># -*- coding: utf-8 -*-
""" Formatting and displaying output """
from __future__ import unicode_literals

import locale
import os
import stat
import sys

import contextlib
import json
import six
import subprocess
import tempfile
from decimal import Decimal
from .monitor import getmaxyx


def truncate(string, length, ellipsis='…'):
    """ Truncate a string to a length, ending with '...' if it overflows """
    if len(string) > length:
        return string[:length - len(ellipsis)] + ellipsis
    return string


def wrap(string, length, indent):
    """ Wrap a string at a line length """
    newline = '\n' + ' ' * indent
    return newline.join((string[i:i + length]
                         for i in xrange(0, len(string), length)))


def serialize_json_var(obj):
    """ Serialize custom types to JSON """
    if isinstance(obj, Decimal):
        return str(obj)
    else:
        raise TypeError("%r is not JSON serializable" % obj)


def format_json(json_object, indent):
    """ Pretty-format json data """
    indent_str = '\n' + ' ' * indent
    json_str = json.dumps(json_object, indent=2, default=serialize_json_var)
    return indent_str.join(json_str.split('\n'))


class BaseFormat(object):

    """ Base class for formatters """

    def __init__(self, results, ostream, width='auto', pagesize='auto'):
        self._results = list(results)
        self._ostream = ostream
        self._width = width
        self._pagesize = pagesize

    @property
    def width(self):
        """ The display width """
        if self._width == 'auto':
            return getmaxyx()[1]
        return self._width

    @property
    def pagesize(self):
        """ The number of results to display at a time """
        if self._pagesize == 'auto':
            return getmaxyx()[0] - 6
        return self._pagesize

    def display(self):
        """ Write results to an output stream """
        count = 0
        num_results = len(self._results)
        for result in self._results:
            self.write(result)
            count += 1
            if (count >= self.pagesize and self.pagesize > 0 and count <
                    num_results):
                self.wait()

    def wait(self):
        """ Block for user input """
        text = raw_input("Press return for next %d results:" % self.pagesize)
        if text:
            if text.lower() in ['a', 'all']:
                self._pagesize = 0
            elif text.isdigit():
                self._pagesize = int(text)

    def write(self, result):
        """ Write a single result and stick it in an output stream """
        raise NotImplementedError

    def format_field(self, field):
        """ Format a single Dynamo value """
        if isinstance(field, Decimal):
            if field % 1 == 0:
                return unicode(int(field))
            return unicode(float(field))
        pretty = repr(field)
        if pretty.startswith("u'"):
            return pretty[1:]
        return pretty


class ExpandedFormat(BaseFormat):

    """ A layout that puts item attributes on separate lines """

    @property
    def pagesize(self):
        if self._pagesize == 'auto':
            return 1
        return self._pagesize

    def write(self, result):
        self._ostream.write(self.width * '-' + '\n')
        max_key = max((len(k) for k in result.keys()))
        for key, val in sorted(result.items()):
            # If the value is json, try to unpack it and format it better.
            if isinstance(val, six.string_types) and val.startswith("{"):
                try:
                    data = json.loads(val)
                except ValueError:
                    pass
                else:
                    val = format_json(data, max_key + 3)
            elif isinstance(val, dict) or isinstance(val, list):
                val = format_json(val, max_key + 3)
            else:
                val = wrap(self.format_field(val), self.width - max_key - 3,
                           max_key + 3)
            self._ostream.write("{0} : {1}\n".format(key.rjust(max_key), val))


class ColumnFormat(BaseFormat):

    """ A layout that puts item attributes in columns """
    def __init__(self, *args, **kwargs):
        super(ColumnFormat, self).__init__(*args, **kwargs)
        col_width = {}
        for result in self._results:
            for key, value in six.iteritems(result):
                col_width.setdefault(key, len(key))
                col_width[key] = max(col_width[key], len(self.format_field(value)))
        self._all_columns = six.viewkeys(col_width)
        self.width_requested = 3 + len(col_width) + sum(six.itervalues(col_width))
        if self.width_requested > self.width:
            even_width = int((self.width - 1) / len(self._all_columns)) - 3
            for key in col_width:
                col_width[key] = even_width
        self._col_width = col_width

        header = '|'
        for col in self._all_columns:
            width = self._col_width[col]
            header += ' '
            header += truncate(col.center(width), width)
            header += ' |'
        self._header = header

    def _write_header(self):
        """ Write out the table header """
        self._ostream.write(len(self._header) * '-' + '\n')
        self._ostream.write(self._header)
        self._ostream.write('\n')
        self._ostream.write(len(self._header) * '-' + '\n')

    def _write_footer(self):
        """ Write out the table footer """
        self._ostream.write(len(self._header) * '-' + '\n')

    def display(self):
        self._write_header()<commit_msg>Fix bad formatting when no results found<commit_after># -*- coding: utf-8 -*-
""" Formatting and displaying output """
from __future__ import unicode_literals

import locale
import os
import stat
import sys

import contextlib
import json
import six
import subprocess
import tempfile
from decimal import Decimal
from .monitor import getmaxyx


def truncate(string, length, ellipsis='…'):
    """ Truncate a string to a length, ending with '...' if it overflows """
    if len(string) > length:
        return string[:length - len(ellipsis)] + ellipsis
    return string


def wrap(string, length, indent):
    """ Wrap a string at a line length """
    newline = '\n' + ' ' * indent
    return newline.join((string[i:i + length]
                         for i in xrange(0, len(string), length)))


def serialize_json_var(obj):
    """ Serialize custom types to JSON """
    if isinstance(obj, Decimal):
        return str(obj)
    else:
        raise TypeError("%r is not JSON serializable" % obj)


def format_json(json_object, indent):
    """ Pretty-format json data """
    indent_str = '\n' + ' ' * indent
    json_str = json.dumps(json_object, indent=2, default=serialize_json_var)
    return indent_str.join(json_str.split('\n'))


class BaseFormat(object):

    """ Base class for formatters """

    def __init__(self, results, ostream, width='auto', pagesize='auto'):
        self._results = list(results)
        self._ostream = ostream
        self._width = width
        self._pagesize = pagesize

    @property
    def width(self):
        """ The display width """
        if self._width == 'auto':
            return getmaxyx()[1]
        return self._width

    @property
    def pagesize(self):
        """ The number of results to display at a time """
        if self._pagesize == 'auto':
            return getmaxyx()[0] - 6
        return self._pagesize

    def display(self):
        """ Write results to an output stream """
        if len(self._results) == 0:
            self._ostream.write('No results\n')
            return
        count = 0
        num_results = len(self._results)
        for result in self._results:
            self.write(result)
            count += 1
            if (count >= self.pagesize and self.pagesize > 0 and count <
                    num_results):
                self.wait()

    def wait(self):
        """ Block for user input """
        text = raw_input("Press return for next %d results:" % self.pagesize)
        if text:
            if text.lower() in ['a', 'all']:
                self._pagesize = 0
            elif text.isdigit():
                self._pagesize = int(text)

    def write(self, result):
        """ Write a single result and stick it in an output stream """
        raise NotImplementedError

    def format_field(self, field):
        """ Format a single Dynamo value """
        if isinstance(field, Decimal):
            if field % 1 == 0:
                return unicode(int(field))
            return unicode(float(field))
        pretty = repr(field)
        if pretty.startswith("u'"):
            return pretty[1:]
        return pretty


class ExpandedFormat(BaseFormat):

    """ A layout that puts item attributes on separate lines """

    @property
    def pagesize(self):
        if self._pagesize == 'auto':
            return 1
        return self._pagesize

    def write(self, result):
        self._ostream.write(self.width * '-' + '\n')
        max_key = max((len(k) for k in result.keys()))
        for key, val in sorted(result.items()):
            # If the value is json, try to unpack it and format it better.
            if isinstance(val, six.string_types) and val.startswith("{"):
                try:
                    data = json.loads(val)
                except ValueError:
                    pass
                else:
                    val = format_json(data, max_key + 3)
            elif isinstance(val, dict) or isinstance(val, list):
                val = format_json(val, max_key + 3)
            else:
                val = wrap(self.format_field(val), self.width - max_key - 3,
                           max_key + 3)
            self._ostream.write("{0} : {1}\n".format(key.rjust(max_key), val))


class ColumnFormat(BaseFormat):

    """ A layout that puts item attributes in columns """
    def __init__(self, *args, **kwargs):
        super(ColumnFormat, self).__init__(*args, **kwargs)
        col_width = {}
        for result in self._results:
            for key, value in six.iteritems(result):
                col_width.setdefault(key, len(key))
                col_width[key] = max(col_width[key], len(self.format_field(value)))
        self._all_columns = six.viewkeys(col_width)
        self.width_requested = 3 + len(col_width) + sum(six.itervalues(col_width))
        if self.width_requested > self.width:
            even_width = int((self.width - 1) / len(self._all_columns)) - 3
            for key in col_width:
                col_width[key] = even_width
        self._col_width = col_width

        header = '|'
        for col in self._all_columns:
            width = self._col_width[col]
            header += ' '
            header += truncate(col.center(width), width)
            header += ' |'
        self._header = header

    def _write_header(self):
        """ Write out the table header """
        self._ostream.write(len(self._header) * '-' + '\n')
        self._ostream.write(self._header)
        self._ostream.write('\n')
        self._ostream.write(len(self._header) * '-' + '\n')

    def _write_footer(self):
        """ Write out the table footer """
        self._ostream.write(len(self._header) * '-' + '\n')

    def display(self):
        if len(self._results) == 0:
            self._ostream.write('No results\n')
            return
        self._write_header()
{'fraction_non_alphanumeric': 0.11892080677551733, 'fraction_numerical': 0.0041910416484763815, 'mean_word_length': 2.04384799362211, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2521667', 'n_tokens_mistral': 3328, 'n_tokens_neox': 3196, 'n_words': 919}