# Path: partycrasher/crash.py
# class Stackframe(PCDict):
# class Stacktrace(PCList):
# class Crash(PCDict):
# class TestCrash(unittest.TestCase):
#     def jsonify(self):
#     def jsonify(self):
#     def get_bucket_id(self, threshold):
#     def load_from_file(cls, path):
#     def make_id(project, database_id):
#     def id(self):
#     def jsonify(self):
#     def fromjson(cls, s):
#     def test_serdes(self):
#     def test_desser(self):
# 
# Path: partycrasher/threshold.py
# class Threshold(object):
#     """
#     A wrapper for a bucket threshold value. Ensures proper serialization
#     between ElasticSearch and the JSON API eloggingndpoints.
#     """
#     __slots__ = ('_value',)
#     
#     def __init__(self, value):
#         if isinstance(value, Threshold):
#             assert isinstance(value._value, Decimal)
#             # Clone the other Threshold.
#             self._value = value._value
#             return
#         elif isinstance(value, Decimal):
#             self._value = value
#             return
#         elif isinstance(value, string_types):
#             value = value.replace('_', '.')
#         elif isinstance(value, float):
#             pass
#         else:
#             raise TypeError("Expected type %s but got %s" % (text_type, repr(value)))
# 
#         self._value = Decimal(value).quantize(Decimal('0.1'))
# 
#     def __str__(self):
#         result = str(self._value)
#         assert '_' not in result
#         # Ensure that rounded values are always displayed with at least one
#         # decimal, for aesthetics.
#         if '.' not in result:
#             return result + '.0'
#         return result
# 
#     def __repr__(self):
#         return "Threshold('" + str(self) + "')"
# 
#     def to_float(self):
#         return float(self)
# 
#     def __float__(self):
#         """
#         Convert the threshold to a floating point number, for comparisons.
#         Note that this should NOT be converted back to a threshold, as there
#         may be a loss of data by doing the round trip.
#         """
#         return float(self._value)
# 
#     def __getattr__(self, attr):
#         # Delegate everything (i.e, comparisons) to the actual Threshold
#         # value.
#         return getattr(self._value, attr)
# 
#     def __hash__(self):
#         return self._value.__hash__()+1
# 
#     def __eq__(self, otter):
#         if not isinstance(otter, Threshold):
#             return False
#         return self._value == otter._value
# 
#     def to_elasticsearch(self):
#         """
#         Converts the threshold to a string, suitable for serialization as an
#         ElasticSearch field name. Note that full stops ('.') are verbotten in
#         ElasticSearch field names.
#         """        #elif isinstance(o, Bucket):
#             #o.check()
#             #return o.as_dict()
#         #elif isinstance(o, TopMatch):
#             #return o.as_dict()
# 
#         str_value = str(self)
#         assert isinstance(self._value, Decimal)
#         assert str_value.count('.') == 1, 'Invalid decimal number'
#         return str_value.replace('.', '_')
#     
#     def __lt__(self, other):
#         return float(self._value) < float(other._value)
#     
#     def __deepcopy__(self, memo):
#         return Threshold(copy(self._value))
#     
#     def jsonify(self):
#         return text_type(self._value)


import json
import operator
from multiprocessing import Pool
from partycrasher.crash import Crash, pretty
from partycrasher.rest_client import RestClient
from partycrasher.threshold import Threshold
              client)
            )
    p = Pool(8)
    results = reduce(operator.add, p.map(get_similarity, tocompute))
    for crash, other, similarity in results:
        if crash not in similaritys:
            similaritys[crash] = {}
        similaritys[crash][other] = similarity
        #if crash == other:
            #print("%s self: %f" % (crash, similarity))
    # ES computes asymmetric similaritys so lets average them
    for ci in similaritys:
        for cj in similaritys[ci]:
            ij = similaritys[ci][cj]
            ji = similaritys[cj][ci]
            if (ij != ji):
                avg = (ij + ji)/2
                similaritys[ci][cj] = avg
                similaritys[cj][ci] = avg
    return similaritys
        

def compute_metrics(date_range_start, rest_service_url):
    client = RestClient(rest_service_url)
    crashes = client.get_a_bunch_of_crashes(date_range_start, 500)
    similaritys = get_similaritys(crashes, client)
    #print(pretty(similaritys))
    #print(pretty(crashes))
    for i in sorted(crashes[0]['buckets']):
        try:

# Path: partycrasher/crash.py
# class Stackframe(PCDict):
# class Stacktrace(PCList):
# class Crash(PCDict):
# class TestCrash(unittest.TestCase):
#     def jsonify(self):
#     def jsonify(self):
#     def get_bucket_id(self, threshold):
#     def load_from_file(cls, path):
#     def make_id(project, database_id):
#     def id(self):
#     def jsonify(self):
#     def fromjson(cls, s):
#     def test_serdes(self):
#     def test_desser(self):
# 
# Path: partycrasher/threshold.py
# class Threshold(object):
#     """
#     A wrapper for a bucket threshold value. Ensures proper serialization
#     between ElasticSearch and the JSON API eloggingndpoints.
#     """
#     __slots__ = ('_value',)
#     
#     def __init__(self, value):
#         if isinstance(value, Threshold):
#             assert isinstance(value._value, Decimal)
#             # Clone the other Threshold.
#             self._value = value._value
#             return
#         elif isinstance(value, Decimal):
#             self._value = value
#             return
#         elif isinstance(value, string_types):
#             value = value.replace('_', '.')
#         elif isinstance(value, float):
#             pass
#         else:
#             raise TypeError("Expected type %s but got %s" % (text_type, repr(value)))
# 
#         self._value = Decimal(value).quantize(Decimal('0.1'))
# 
#     def __str__(self):
#         result = str(self._value)
#         assert '_' not in result
#         # Ensure that rounded values are always displayed with at least one
#         # decimal, for aesthetics.
#         if '.' not in result:
#             return result + '.0'
#         return result
# 
#     def __repr__(self):
#         return "Threshold('" + str(self) + "')"
# 
#     def to_float(self):
#         return float(self)
# 
#     def __float__(self):
#         """
#         Convert the threshold to a floating point number, for comparisons.
#         Note that this should NOT be converted back to a threshold, as there
#         may be a loss of data by doing the round trip.
#         """
#         return float(self._value)
# 
#     def __getattr__(self, attr):
#         # Delegate everything (i.e, comparisons) to the actual Threshold
#         # value.
#         return getattr(self._value, attr)
# 
#     def __hash__(self):
#         return self._value.__hash__()+1
# 
#     def __eq__(self, otter):
#         if not isinstance(otter, Threshold):
#             return False
#         return self._value == otter._value
# 
#     def to_elasticsearch(self):
#         """
#         Converts the threshold to a string, suitable for serialization as an
#         ElasticSearch field name. Note that full stops ('.') are verbotten in
#         ElasticSearch field names.
#         """        #elif isinstance(o, Bucket):
#             #o.check()
#             #return o.as_dict()
#         #elif isinstance(o, TopMatch):
#             #return o.as_dict()
# 
#         str_value = str(self)
#         assert isinstance(self._value, Decimal)
#         assert str_value.count('.') == 1, 'Invalid decimal number'
#         return str_value.replace('.', '_')
#     
#     def __lt__(self, other):
#         return float(self._value) < float(other._value)
#     
#     def __deepcopy__(self, memo):
#         return Threshold(copy(self._value))
#     
#     def jsonify(self):
#         return text_type(self._value)


# Path: partycrasher/metrics.py
import json
import operator
from multiprocessing import Pool
from partycrasher.crash import Crash, pretty
from partycrasher.rest_client import RestClient
from partycrasher.threshold import Threshold

              client)
            )
    p = Pool(8)
    results = reduce(operator.add, p.map(get_similarity, tocompute))
    for crash, other, similarity in results:
        if crash not in similaritys:
            similaritys[crash] = {}
        similaritys[crash][other] = similarity
        #if crash == other:
            #print("%s self: %f" % (crash, similarity))
    # ES computes asymmetric similaritys so lets average them
    for ci in similaritys:
        for cj in similaritys[ci]:
            ij = similaritys[ci][cj]
            ji = similaritys[cj][ci]
            if (ij != ji):
                avg = (ij + ji)/2
                similaritys[ci][cj] = avg
                similaritys[cj][ci] = avg
    return similaritys
        

def compute_metrics(date_range_start, rest_service_url):
    client = RestClient(rest_service_url)
    crashes = client.get_a_bunch_of_crashes(date_range_start, 500)
    similaritys = get_similaritys(crashes, client)
    #print(pretty(similaritys))
    #print(pretty(crashes))
    for i in sorted(crashes[0]['buckets']):
        try:

            i = Threshold(i)