<commit_before>#!/usr/bin/python3
from collections import defaultdict
from dataclasses import dataclass,field,InitVar,FrozenInstanceError
from itertools import chain
from typing import (
    Union, Any, List, Optional, 
    cast, Callable, Iterable
)

from .exceptions import (
    StrandError, 
    ChromosomeError,
    MissingLocusError
)
from .subloci import SubLoci
from .locusattrs import LocusAttrs

import re
import math
import locuspocus
import dataclasses

import pandas as pd
import numpy as np

__all__ = ['Locus']


@dataclass()
class Locus:

    def __init__(
        self,
        chromosome: str,
        start: int,
        end: int,
        source: str = 'locuspocus',
        feature_type: str = 'locus',
        strand: str = '+',
        frame: int = None,
        name: str = None,
        # Extra locus stuff
        attrs: LocusAttrs = None,
        subloci: SubLoci  = None

    ):
        self.chromosome = str(chromosome)
        self.start = int(start)
        self.end   = int(end)
        self.source = str(source)
        self.feature_type = str(feature_type)
        self.strand = str(strand)
        self.frame = frame
        self.name = str(name)

        self.attrs = LocusAttrs(attrs)
        self.subloci = SubLoci(subloci)

    def __eq__(self,other):
        if (self.chromosome == other.chromosome
            and self.start == other.start
            and self.end == other.end
            and self.source == other.source
            and self.feature_type == other.feature_type
            and self.strand == other.strand
            and self.frame == other.frame
            and self.name == other.name
            and self.attrs == other.attrs
            and self.subloci == other.subloci
        ):
            return True
        else:
            return False


    def __len__(self):
        return abs(self.end - self.start) + 1

    def __lt__(self,locus):
        if self.chromosome == locus.chromosome:
            return self.start < locus.start
        else:
            return self.chromosome < locus.chromosome

    def __le__(self,locus):
        if (self.chromosome,self.coor) == (locus.chromosome,locus.coor):
            return True
        else:
            return self < locus

    def __ge__(self,locus):
        if (self.chromosome,self.coor) == (locus.chromosome,locus.coor):
            return True
        else:
            return self > locus

    def __gt__(self,locus):
        if self.chromosome == locus.chromosome:
            return self.start > locus.start
        else:
            return self.chromosome > locus.chromosome

    def __repr__(self):
        return (
            f"Locus("
            f"{self.chromosome},{self.start},{self.end},source={self.source},"
            f"feature_type='{self.feature_type}',"
            f"strand='{self.strand}',"
            f"frame='{self.frame}',"
            f"name='{self.name}',"
            f"attrs={self.attrs},"
            f"subloci={self.subloci}"<commit_msg>add back hash method and update repr<commit_after>#!/usr/bin/python3

import re
import math
import hashlib
import locuspocus

import numpy as np

from typing import (
    Union, Any, List, Optional, 
    cast, Callable, Iterable
)

from .exceptions import (
    StrandError, 
    ChromosomeError,
    MissingLocusError
)
from .subloci import SubLoci
from .locusattrs import LocusAttrs


__all__ = ['Locus']

class Locus:

    def __init__(
        self,
        chromosome: str,
        start: int,
        end: int,
        source: str = 'locuspocus',
        feature_type: str = 'locus',
        strand: str = '+',
        frame: int = None,
        name: str = None,
        # Extra locus stuff
        attrs: LocusAttrs = None,
        subloci: SubLoci  = None

    ):
        self.chromosome = str(chromosome)
        self.start = int(start)
        self.end   = int(end)
        self.source = str(source)
        self.feature_type = str(feature_type)
        self.strand = str(strand)
        self.frame = frame
        self.name = name

        self.attrs = LocusAttrs(attrs)
        self.subloci = SubLoci(subloci)

    def __eq__(self,other):
        if (self.chromosome == other.chromosome
            and self.start == other.start
            and self.end == other.end
            and self.source == other.source
            and self.feature_type == other.feature_type
            and self.strand == other.strand
            and self.frame == other.frame
            and self.name == other.name
            and self.attrs == other.attrs
            and self.subloci == other.subloci
        ):
            return True
        else:
            return False

    def __hash__(self):
        '''
            Convert the locus to a hash, uses md5. The hash
            is computed using the *core* properties of the 
            Locus, i.e. changing any attrs will not change 
            the hash value.

            Parameters
            ----------
            None
            Returns
            -------
            int : md5 hash of locus
        '''
        field_list = [str(x) for x in (
            self.chromosome,
            self.start,
            self.end,
            self.source,
            self.feature_type,
            self.strand,
            self.frame,
            self.name
        )]
        subloci_list = [str(hash(x)) for x in self.subloci]
        # Create a full string
        loc_string  = "_".join(field_list + subloci_list) # attr_list + subloci_list)
        digest = hashlib.md5(str.encode(loc_string)).hexdigest()
        return int(digest, base=16)


    def __len__(self):
        return abs(self.end - self.start) + 1

    def __lt__(self,locus):
        if self.chromosome == locus.chromosome:
            return self.start < locus.start
        else:
            return self.chromosome < locus.chromosome

    def __le__(self,locus):
        if (self.chromosome,self.coor) == (locus.chromosome,locus.coor):
            return True
        else:
            return self < locus

    def __ge__(self,locus):
        if (self.chromosome,self.coor) == (locus.chromosome,locus.coor):
            return True
        else:
            return self > locus

    def __gt__(self,locus):
        if self.chromosome == locus.chromosome:
            return self.start > locus.start
        else:
            return self.chromosome > locus.chromosome

    def __repr__(self):
        return (
            f"Locus("
            f"{self.chromosome},{self.start},{self.end},source={self.source},"
            f"feature_type='{self.feature_type}',"
            f"strand='{self.strand}',"
            f"frame='{self.frame}',"
            f"name='{self.name}',"
            f"attrs={self.attrs},"
            f"subloci=[{len(self.subloci)} subloci]"
{'fraction_non_alphanumeric': 0.10518540404786526, 'fraction_numerical': 0.0013295907815039148, 'mean_word_length': 1.7883031301482701, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '766086', 'n_tokens_mistral': 2143, 'n_tokens_neox': 1981, 'n_words': 481}