def compute_metrics(self):
        # the number of buckets for the curves
        num = int(1.0 /self.resolution) + 1
        logger.debug('num = {}'.format(num))
        self.PRCs = None
        self.ROCs = None
        PRCn = np.zeros(num, dtype=int)
        ROCn = np.zeros(num, dtype=int)
        for user in self.scores:
            if user is DEFAULT_MONITOR_USER:
                continue
            # initialize basic metrics
            tp = self.totalPos[user]
            tn = 0
            fp = self.totalNeg[user]
            fn = 0
            totalP = tp
            totalN = fp
            logger.debug('totalP={}, totalN={}'.format(totalP, totalN))
            # ignore incomplete user
            if totalP == 0 or totalN == 0:
                continue
            # sort the scores
            score = self.scores[user]
            logger.info('scores for {} : {}'.format(score, user))
            score.sort()
            logger.info('scores for {} : {}'.format(score, user))
            # initialize PRC and ROC
            PRC = np.zeros(num)
            ROC = np.zeros(num)
            PRCn.fill(0)
            ROCn.fill(0)
            # loop through scores
            for s, label in score:
                if label > 0: # positive example
                    fn += 1
                    tp -= 1
                else:   # negative example
                    tn += 1
                    fp -= 1
                recall = float(tp) / float(totalP)
                # precision value
                if tp + fp == 0:
                    precision = 1
                else:
                    precision = float(tp) / float(tp + fp)
                v = int(precision / self.resolution)
                PRC[v] += recall
                PRCn[v] += 1
                # false positive rate value
                fpr = float(fp) / float(totalN)
                v = int(self.resolution / fpr)
                ROC[v] += recall
                ROCn[v] += 1
            logger.info('PRC {}'.format(PRC))
            logger.info('PRCn {}'.format(PRCn))
            logger.info('ROC {}'.format(ROC))
            logger.info('ROCn {}'.format(ROCn))
            
            # averaging ROC and PRC since multiple recalls might fall into the same bucket
            # fill the missing buckets
            for v in reversed(range(num-1)):
                if PRCn[v] == 0:
                    # fill the missing values from high precision
                    # precision == 1 is assumed to exist all the time
                    PRC[v] = PRC[v+1]
                else:
                    # average over all recalls at this precision
                    PRC[v] /= PRCn[v]
            for v in range(2,num):
                if ROCn[v] == 0:
                    # fill the missing values from low fpr
                    # fpr == 0 is assumed to exist all the time
                    ROC[v] = ROC[v-1]
                else:
                    # average over all recalls at this fpr
                    ROC[v] /= ROCn[v]
            if self.ROCs is None:
                self.ROCs = ROC
            else:
                self.ROCs = np.vstack((self.ROCs, ROC))
            if self.PRCs is None:
                self.PRCs = PRC
            else:
                self.PRCs = np.vstack((self.PRCs, PRC))
        self.ROCs.sort(axis=0)
        self.PRCs.sort(axis=0)
        logger.info('ROCs {}'.format(self.ROCs))
        logger.info('PRCs {}'.format(self.PRCs))
        self.invalid = False
dataset/ETHPy150Open xumiao/pymonk/monk/roles/monitor.py/Measurer.compute_metrics/swapped operands of `/`