<commit_before>from mereo import ORDER
from mereo.part import Part


class Inventory(object):
    """implemented as a fluent interface"""

    # -------------------------------------------------------------------------
    # Customization Methods

    def __init__(self):
        from collections import defaultdict
        self.inv = defaultdict(dict)

    def __len__(self):
        return len(self.inv)

    def __iter__(self):
        for key in ORDER:
            if key in self.inv:
                for part in self.inv[key].values():
                    yield key, part

    # -------------------------------------------------------------------------
    # Non-fluent methods

    def _mergePart(self, key, part):
        self.inv[key][part.ID] = part

    # -------------------------------------------------------------------------
    # I/O

    @staticmethod
    def load(filename):
        instance = Inventory()

        import json
        try:
            with open(filename, 'r') as f:
                d = json.load(f)
            for k, v in d.items():
                instance.inv[k] = v
        except IOError:
            pass

        return instance

    def save(self, filename):
        import json
        with open(filename, 'w') as f:
            json.dump(self.inv, f, sort_keys=True, indent=2,
                      separators=(',', ': '))
        return self

    # -------------------------------------------------------------------------
    # SVG I/O

    def updateFromSvg(self, filename):
        from svgpathtools import svg2paths2

        _, attributes, _ = svg2paths2(filename)

        for i, a in enumerate(attributes):
            if 'id' in a:
                tokens = a['id'].split('_')
                part = Part(a['d'])
                part.ID = tokens[1:]
                self._mergePart(tokens[0], part)

        return self

    def writeSvg(self, filename):
        from svgpathtools import wsvg, parse_path

        paths = []
        attributes = []
        svg_attributes = {
            'width': 2000,
            'height': 1800
        }

        for key, part in self:
            path = parse_path(part['d'])
            paths.append(path)
            att = {
                'id': key + part.ID,
                'stroke-width': 2,
                'stroke':  '#ff0000',  # encodeColor(key, part),
                'fill': 'none',
                'opacity': 1
            }
            attributes.append(att)

        wsvg(paths, attributes=attributes, svg_attributes=svg_attributes,
             filename=filename)

        return self

    # -------------------------------------------------------------------------
    # Predicate Logic

    def select(self, fn):
        clone = Inventory()
        for key, part in self:
            if fn(key, part):
                clone.inv[key].append(part)
        return clone

    # -------------------------------------------------------------------------
    # Actions<commit_msg>Add color encoding when writing SVG<commit_after>from mereo import ORDER
from mereo.part import Part


def encodeColor(key, part):
    rgb = [255, 16, 16]
    rgb[0] -= ORDER.index(key) + 1
    rgb[1] -= (part['y'] / 30)
    rgb[2] -= (part['z'] / 30)

    asHex = '#{0:02x}{1:02x}{2:02x}'.format(*rgb)
    return asHex


class Inventory(object):
    """implemented as a fluent interface"""

    # -------------------------------------------------------------------------
    # Customization Methods

    def __init__(self):
        from collections import defaultdict
        self.inv = defaultdict(dict)

    def __len__(self):
        return len(self.inv)

    def __iter__(self):
        for key in ORDER:
            if key in self.inv:
                for part in self.inv[key].values():
                    yield key, part

    # -------------------------------------------------------------------------
    # Non-fluent methods

    def _mergePart(self, key, part):
        self.inv[key][part.ID] = part

    # -------------------------------------------------------------------------
    # I/O

    @staticmethod
    def load(filename):
        instance = Inventory()

        import json
        try:
            with open(filename, 'r') as f:
                d = json.load(f)
            for k, v in d.items():
                instance.inv[k] = v
        except IOError:
            pass

        return instance

    def save(self, filename):
        import json
        with open(filename, 'w') as f:
            json.dump(self.inv, f, sort_keys=True, indent=2,
                      separators=(',', ': '))
        return self

    # -------------------------------------------------------------------------
    # SVG I/O

    def updateFromSvg(self, filename):
        from svgpathtools import svg2paths2

        _, attributes, _ = svg2paths2(filename)

        for i, a in enumerate(attributes):
            if 'id' in a:
                tokens = a['id'].split('_')
                part = Part(a['d'])
                part.ID = tokens[1:]
                self._mergePart(tokens[0], part)

        return self

    def writeSvg(self, filename):
        from svgpathtools import wsvg, parse_path

        paths = []
        attributes = []
        svg_attributes = {
            'width': 2000,
            'height': 1800
        }

        for key, part in self:
            path = parse_path(part['d'])
            paths.append(path)
            att = {
                'id': key + part.ID,
                'stroke-width': 2,
                'stroke':  encodeColor(key, part),
                'fill': 'none',
                'opacity': 1
            }
            attributes.append(att)

        wsvg(paths, attributes=attributes, svg_attributes=svg_attributes,
             filename=filename)

        return self

    # -------------------------------------------------------------------------
    # Predicate Logic

    def select(self, fn):
        clone = Inventory()
        for key, part in self:
            if fn(key, part):
                clone.inv[key].append(part)
        return clone

    # -------------------------------------------------------------------------
    # Actions
{'fraction_non_alphanumeric': 0.23598772411565175, 'fraction_numerical': 0.01001453723146503, 'mean_word_length': 1.0550945901095254, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '612227', 'n_tokens_mistral': 1657, 'n_tokens_neox': 1513, 'n_words': 407}