<commit_before>import mathutils.geometry


class AttributeData:
    def __init__(self, mesh):
        self.positions = PositionsData(mesh)
        self.normals = NormalsData(mesh)
        self.color_layers = [ColorsData(c) for c in mesh.vertex_colors]
        self.uv_layers = [UvsData(l) for l in mesh.uv_layers]
        self.triangle_sets = [
            IndicesData(mesh, i, triangulate=True) for i, _ in enumerate(mesh.materials)
        ]
        self.polygon_sets = [IndicesData(mesh, i) for i, _ in enumerate(mesh.materials)]


class PositionsData:
    def __init__(self, mesh):
        self.mesh = mesh
        self.iterator = (v.co for v in self.mesh.vertices)

    def __len__(self):
        return len(self.mesh.vertices)


class NormalsData:
    def __init__(self, mesh):
        mesh.calc_normals()
        self.mesh = mesh
        self.iterator = (v.normal for v in self.mesh.vertices)

    def __len__(self):
        return len(self.mesh.vertices)


class ColorsData:
    def __init__(self, colors):
        self.layer = colors
        self.iterator = (c.color for c in self.layer.data)

    def __len__(self):
        return len(self.layer.data)


class UvsData:
    def __init__(self, uv_layer):
        self.layer = uv_layer
        self.iterator = (l.uv for l in self.layer.data)

    def __len__(self):
        return len(self.layer.data)


class IndicesData:
    def __init__(self, mesh, material_index, triangulate=False):
        self.mesh = mesh
        self.material = mesh.materials[material_index]
        self._faces = [f for f in mesh.polygons if f.material_index == material_index]
        if triangulate:
            self._len = sum([max(len(f.vertices) - 2, 1) for f in self._faces])
            self.iterator = self._create_iter()
        else:<commit_msg>Reduce code duplication when building AttributeData<commit_after>import mathutils.geometry


class AttributeData:
    def __init__(self, mesh):
        self.positions = PositionsData(mesh)
        self.normals = NormalsData(mesh)
        self.color_layers = [ColorsData(c) for c in mesh.vertex_colors]
        self.uv_layers = [UvsData(l) for l in mesh.uv_layers]
        self.triangle_sets = [
            IndicesData(mesh, i, triangulate=True) for i, _ in enumerate(mesh.materials)
        ]
        self.polygon_sets = [IndicesData(mesh, i) for i, _ in enumerate(mesh.materials)]


class CollectionData:
    def __init__(self, source, map_function):
        self.source = source
        self.iterator = (map_function(i) for i in source)

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


class PositionsData(CollectionData):
    def __init__(self, mesh):
        super().__init__(mesh.vertices, lambda v: v.co)


class NormalsData(CollectionData):
    def __init__(self, mesh):
        mesh.calc_normals()
        super().__init__(mesh.vertices, lambda v: v.normal)


class ColorsData(CollectionData):
    def __init__(self, colors):
        super().__init__(colors.data, lambda data: data.color)
        self.layer = colors


class UvsData(CollectionData):
    def __init__(self, uv_layer):
        super().__init__(uv_layer.data, lambda data: data.uv)
        self.layer = uv_layer


class IndicesData:
    def __init__(self, mesh, material_index, triangulate=False):
        self.mesh = mesh
        self.material = mesh.materials[material_index]
        self._faces = [f for f in mesh.polygons if f.material_index == material_index]
        if triangulate:
            self._len = sum([max(len(f.vertices) - 2, 1) for f in self._faces])
            self.iterator = self._create_iter()
        else:
{'fraction_non_alphanumeric': 0.10441544015551235, 'fraction_numerical': 0.0011108025548458762, 'mean_word_length': 2.736514522821577, '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': '4520740', 'n_tokens_mistral': 1149, 'n_tokens_neox': 1105, 'n_words': 274}