<commit_before>"""
ALL THE UTILS!
"""
# silly python2
import copy
import re

from spock.vector import Vector3

try:
    string_types = unicode
except NameError:
    string_types = str


class Info(object):
    def set_dict(self, data):
        for key in data:
            if hasattr(self, key):
                setattr(self, key, data[key])

    def get_dict(self):
        return self.__dict__

    def __repr__(self):
        return repr(self.get_dict()).replace('dict', self.__class__.__name__)

    def __str__(self):
        return str(self.get_dict())


class Position(Vector3, Info):
    """
    Used for things that require encoding position for the protocol,
    but also require higher level vector functions.
    """

    def get_dict(self):
        d = self.__dict__.copy()
        del d['vector']
        d['x'], d['y'], d['z'] = self
        return d


class BoundingBox(Vector3):
    def __init__(self, w, h, d=None):
        d = w if d is None else d
        super(BoundingBox, self).__init__(w, h, d)
        self.w = self.x
        self.h = self.y
        self.d = self.z


class BufferUnderflowException(Exception):
    pass


class BoundBuffer(object):
    buff = b''
    cursor = 0

    def __init__(self, data=b""):
        self.write(data)

    def read(self, length):
        if length > len(self):
            raise BufferUnderflowException()

        out = self.buff[self.cursor:self.cursor+length]
        self.cursor += length
        return out

    def write(self, data):
        self.buff += data

    def flush(self):
        return self.read(len(self))

    def save(self):
        self.buff = self.buff[self.cursor:]
        self.cursor = 0

    def revert(self):
        self.cursor = 0

    def tell(self):
        return self.cursor

    def __len__(self):
        return len(self.buff) - self.cursor

    def __repr__(self):
        return "<BoundBuffer '%s'>" % repr(self.buff[self.cursor:])

    recv = read
    append = write


def pl_announce(*args):
    def inner(cl):
        cl.pl_announce = args
        return cl

    return inner


def pl_event(*args):
    def inner(cl):
        cl.pl_event = args
        return cl

    return inner


def get_settings(defaults, settings):
    return dict(copy.deepcopy(defaults), **settings)


def mapshort2id(data):
    return data >> 4, data & 0x0F


def byte_to_hex(byte_str):
    return ''.join(["%02X " % x for x in byte_str]).strip()


def snake_case(word):
    # from http://stackoverflow.com/a/1176023
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', word)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()

upper_camel_case = lambda word: ''.join(map(str.capitalize, word.split()))
<commit_msg>Fix camel_case and snake_case by using split_words<commit_after>"""
ALL THE UTILS!
"""
# silly python2
import copy
import re

from spock.vector import Vector3

try:
    string_types = unicode
except NameError:
    string_types = str


class Info(object):
    def set_dict(self, data):
        for key in data:
            if hasattr(self, key):
                setattr(self, key, data[key])

    def get_dict(self):
        return self.__dict__

    def __repr__(self):
        return repr(self.get_dict()).replace('dict', self.__class__.__name__)

    def __str__(self):
        return str(self.get_dict())


class Position(Vector3, Info):
    """
    Used for things that require encoding position for the protocol,
    but also require higher level vector functions.
    """

    def get_dict(self):
        d = self.__dict__.copy()
        del d['vector']
        d['x'], d['y'], d['z'] = self
        return d


class BoundingBox(Vector3):
    def __init__(self, w, h, d=None):
        d = w if d is None else d
        super(BoundingBox, self).__init__(w, h, d)
        self.w = self.x
        self.h = self.y
        self.d = self.z


class BufferUnderflowException(Exception):
    pass


class BoundBuffer(object):
    buff = b''
    cursor = 0

    def __init__(self, data=b""):
        self.write(data)

    def read(self, length):
        if length > len(self):
            raise BufferUnderflowException()

        out = self.buff[self.cursor:self.cursor+length]
        self.cursor += length
        return out

    def write(self, data):
        self.buff += data

    def flush(self):
        return self.read(len(self))

    def save(self):
        self.buff = self.buff[self.cursor:]
        self.cursor = 0

    def revert(self):
        self.cursor = 0

    def tell(self):
        return self.cursor

    def __len__(self):
        return len(self.buff) - self.cursor

    def __repr__(self):
        return "<BoundBuffer '%s'>" % repr(self.buff[self.cursor:])

    recv = read
    append = write


def pl_announce(*args):
    def inner(cl):
        cl.pl_announce = args
        return cl

    return inner


def pl_event(*args):
    def inner(cl):
        cl.pl_event = args
        return cl

    return inner


def get_settings(defaults, settings):
    return dict(copy.deepcopy(defaults), **settings)


def mapshort2id(data):
    return data >> 4, data & 0x0F


def byte_to_hex(byte_str):
    return ''.join(["%02X " % x for x in byte_str]).strip()


# from http://stackoverflow.com/a/12867228
re_spaced_caps = re.compile(r'((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))')


def split_words(text):  # TODO lacking a better name
    if '_' in text:
        return [w.lower() for w in text.split('_')]
    if ' ' not in text:
        text = re_spaced_caps.sub(r' \1', text)
    return [w.lower() for w in text.split(' ')]

snake_case = lambda text: '_'.join(split_words(text))
camel_case = lambda text: ''.join(map(str.capitalize, split_words(text)))

{'fraction_non_alphanumeric': 0.1327683615819209, 'fraction_numerical': 0.009180790960451978, 'mean_word_length': 2.4542682926829267, 'pattern_counts': {'":': 0, '<': 6, '<?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': '1946880', 'n_tokens_mistral': 1937, 'n_tokens_neox': 1837, 'n_words': 492}