# Path: feemodel/util.py
# class Function(object):
#     '''A (math) function object with interpolation methods.'''
# 
#     def __init__(self, x, y):
#         '''y and x are lists s.t. y_i = f(x_i) and x is sorted.'''
#         self._x = x
#         self._y = y
# 
#     def __call__(self, x0, use_upper=False, use_lower=False):
#         '''Evaluate the function at x0, by linear interpolation.
# 
#         use_upper and use_lower specifies what to do if x is outside
#         the domain of the function [min(self._x), max(self._x)).
# 
#         if use_upper is True, then if all([x >= xi for xi in self._x]),
#         return f(max(self._x)).
# 
#         if use_lower is True, then if all([x < xi for xi in self._x]),
#         return f(min(self._x)).
# 
#         Otherwise return None, if x is outside the domain.
#         '''
#         y0, xidx = interpolate(x0, self._x, self._y)
#         if xidx == 0:
#             return y0 if use_lower else None
#         if xidx == len(self._x):
#             return y0 if use_upper or x0 == self._x[-1] else None
#         return y0
# 
#     def inv(self, y0, use_upper=False, use_lower=False):
#         '''Evaluate the inverse function at y0 by linear interpolation.
# 
#         use_upper and use_lower have the same meaning as in self.__call__.
# 
#         We don't check that the function is 1-to-1: if you call this method,
#         it is assumed so.
#         '''
#         _y = self._y[:]
#         _x = self._x[:]
#         if _y[-1] < _y[0]:
#             _y.reverse()
#             _x.reverse()
#         x0, yidx = interpolate(y0, _y, _x)
#         if yidx == 0:
#             return x0 if use_lower else None
#         if yidx == len(_y):
#             return x0 if use_upper or y0 == _y[-1] else None
#         return x0
# 
#     def addpoint(self, xi, yi):
#         if xi in self._x:
#             return
#         self._x, self._y = map(list, zip(*sorted(list(self) + [(xi, yi)])))
# 
#     def __getitem__(self, idx):
#         return self._x[idx], self._y[idx]
# 
#     def __str__(self):
#         headers = ['x', 'y']
#         table = list(self)
#         return tabulate(table, headers=headers)
# 
#     def __len__(self):
#         return len(self._y)
# 
#     def __iter__(self):
#         return izip(self._x, self._y)
# 
#     def __copy__(self):
#         return Function(list(self._x), list(self._y))
# 
# Path: feemodel/config.py
# DIFF_RETARGET_INTERVAL = 2016
# PRIORITYTHRESH = 57600000
# EXPECTED_BLOCK_INTERVAL = 600
# MINRELAYTXFEE = 5000
# def read_default_config():


import os
import logging
import sqlite3
from bisect import bisect
from math import ceil
from tabulate import tabulate
from feemodel.util import Function
from feemodel.config import datadir
        self._x = [0] + waitpercentiles
        self.median_waittime = waitpercentiles[WAIT_MEDIAN_IDX]
        self.feerate = feerate
        self.entrytime = entrytime
        self.waittime = None
        self.pval = None

    def calc_pval(self, blocktime):
        '''Calculate the p-value of the tx.

        blocktime is the timestamp of the block that included the tx.
        '''
        self.waittime = blocktime - self.entrytime
        self.pval = self(self.waittime, use_upper=True, use_lower=True)
        return self.pval

    def _get_attr_tuple(self):
        '''For writing to db.'''
        attr_tuple = (
            self.feerate,
            self.entrytime,
            self.median_waittime,
            self.waittime,
            self.pval)
        return attr_tuple

    def __eq__(self, other):
        return self.__dict__ == other.__dict__



# Path: feemodel/util.py
# class Function(object):
#     '''A (math) function object with interpolation methods.'''
# 
#     def __init__(self, x, y):
#         '''y and x are lists s.t. y_i = f(x_i) and x is sorted.'''
#         self._x = x
#         self._y = y
# 
#     def __call__(self, x0, use_upper=False, use_lower=False):
#         '''Evaluate the function at x0, by linear interpolation.
# 
#         use_upper and use_lower specifies what to do if x is outside
#         the domain of the function [min(self._x), max(self._x)).
# 
#         if use_upper is True, then if all([x >= xi for xi in self._x]),
#         return f(max(self._x)).
# 
#         if use_lower is True, then if all([x < xi for xi in self._x]),
#         return f(min(self._x)).
# 
#         Otherwise return None, if x is outside the domain.
#         '''
#         y0, xidx = interpolate(x0, self._x, self._y)
#         if xidx == 0:
#             return y0 if use_lower else None
#         if xidx == len(self._x):
#             return y0 if use_upper or x0 == self._x[-1] else None
#         return y0
# 
#     def inv(self, y0, use_upper=False, use_lower=False):
#         '''Evaluate the inverse function at y0 by linear interpolation.
# 
#         use_upper and use_lower have the same meaning as in self.__call__.
# 
#         We don't check that the function is 1-to-1: if you call this method,
#         it is assumed so.
#         '''
#         _y = self._y[:]
#         _x = self._x[:]
#         if _y[-1] < _y[0]:
#             _y.reverse()
#             _x.reverse()
#         x0, yidx = interpolate(y0, _y, _x)
#         if yidx == 0:
#             return x0 if use_lower else None
#         if yidx == len(_y):
#             return x0 if use_upper or y0 == _y[-1] else None
#         return x0
# 
#     def addpoint(self, xi, yi):
#         if xi in self._x:
#             return
#         self._x, self._y = map(list, zip(*sorted(list(self) + [(xi, yi)])))
# 
#     def __getitem__(self, idx):
#         return self._x[idx], self._y[idx]
# 
#     def __str__(self):
#         headers = ['x', 'y']
#         table = list(self)
#         return tabulate(table, headers=headers)
# 
#     def __len__(self):
#         return len(self._y)
# 
#     def __iter__(self):
#         return izip(self._x, self._y)
# 
#     def __copy__(self):
#         return Function(list(self._x), list(self._y))
# 
# Path: feemodel/config.py
# DIFF_RETARGET_INTERVAL = 2016
# PRIORITYTHRESH = 57600000
# EXPECTED_BLOCK_INTERVAL = 600
# MINRELAYTXFEE = 5000
# def read_default_config():


# Path: feemodel/app/predict.py
import os
import logging
import sqlite3
from bisect import bisect
from math import ceil
from tabulate import tabulate
from feemodel.util import Function
from feemodel.config import datadir

        self._x = [0] + waitpercentiles
        self.median_waittime = waitpercentiles[WAIT_MEDIAN_IDX]
        self.feerate = feerate
        self.entrytime = entrytime
        self.waittime = None
        self.pval = None

    def calc_pval(self, blocktime):
        '''Calculate the p-value of the tx.

        blocktime is the timestamp of the block that included the tx.
        '''
        self.waittime = blocktime - self.entrytime
        self.pval = self(self.waittime, use_upper=True, use_lower=True)
        return self.pval

    def _get_attr_tuple(self):
        '''For writing to db.'''
        attr_tuple = (
            self.feerate,
            self.entrytime,
            self.median_waittime,
            self.waittime,
            self.pval)
        return attr_tuple

    def __eq__(self, other):
        return self.__dict__ == other.__dict__



class PValECDF(Function):