Пример #1
0
def _adaptiveAggregation(V, n, yIntervals, weightF, param, freq):
    '''Apply adaptive aggregation algorithm to the given vocabulary.
    Algorithm 2 from paper.
    '''
    # Initialize returned parameters
    finalVocabs = SortedDict()
    periodGroups = SortedDict()

    # Select weighting function
    f = _selectWeightingFunction(weightF, param)

    # Iterate over time frames
    for t in _arrangeIntervals(V, yIntervals, freq):
        mu_t = getRangeMiddle(t[0], t[-1])
        V_prime = SortedDict({tx: V[tx] for tx in t})

        score = defaultdict(float)
        for years_v, words_v in V_prime.iteritems():
            mu_v = getRangeMiddle(years_v)
            fvt = f(mu_v, mu_t)
            for word, score_wv in words_v:
                score[word] += fvt * score_wv

        # Top n terms w sorted by score_w
        scoreList = [(k, v) for k, v in score.iteritems()]
        scoreList = sorted(scoreList, key=lambda pair: pair[1], reverse=True)
        topN = scoreList[:n]

        finalVocabs[str(int(mu_t))] = topN
        periodGroups[str(int(mu_t))] = t
    return finalVocabs, periodGroups
Пример #2
0
def signal_crosses(short_moving_averages, long_moving_averages):
    short_moving_averages = SortedDict(short_moving_averages)
    long_moving_averages = SortedDict(long_moving_averages)

    short_len = len(short_moving_averages.values())
    long_len  = len(long_moving_averages.values())

    if(short_len != long_len):
        print "[Error] signal_crosses: inputs must be same size"
        return {}

    signal_crosses = {}
    last_diff_dir = 0
    for date, short_average in short_moving_averages.iteritems():
        long_average = long_moving_averages[date]
        diff = short_average - long_average

        if(last_diff_dir == 0):
            signal_crosses[date] = HOLD
            if(diff != 0):
                last_diff_dir = sign(diff)
            continue

        if(sign(diff) != last_diff_dir):
            signal_crosses[date] = BUY if last_diff_dir < 0 else SELL
            last_diff_dir = -last_diff_dir
        else:
            signal_crosses[date] = HOLD

    return SortedDict(signal_crosses)
Пример #3
0
def signal_crosses(short_moving_averages, long_moving_averages):
    short_moving_averages = SortedDict(short_moving_averages)
    long_moving_averages = SortedDict(long_moving_averages)

    short_len = len(short_moving_averages.values())
    long_len = len(long_moving_averages.values())

    if (short_len != long_len):
        print "[Error] signal_crosses: inputs must be same size"
        return {}

    signal_crosses = {}
    last_diff_dir = 0
    for date, short_average in short_moving_averages.iteritems():
        long_average = long_moving_averages[date]
        diff = short_average - long_average

        if (last_diff_dir == 0):
            signal_crosses[date] = HOLD
            if (diff != 0):
                last_diff_dir = sign(diff)
            continue

        if (sign(diff) != last_diff_dir):
            signal_crosses[date] = BUY if last_diff_dir < 0 else SELL
            last_diff_dir = -last_diff_dir
        else:
            signal_crosses[date] = HOLD

    return SortedDict(signal_crosses)
Пример #4
0
def _adaptiveAggregation(V, n, yIntervals, weightF, param, freq):
    '''Apply adaptive aggregation algorithm to the given vocabulary.
    Algorithm 2 from paper.
    '''
    # Initialize returned parameters
    finalVocabs = SortedDict()
    periodGroups = SortedDict()

    # Select weighting function
    f = _selectWeightingFunction(weightF, param)

    # Iterate over time frames
    for t in _arrangeIntervals(V, yIntervals, freq):
        mu_t = getRangeMiddle(t[0], t[-1])
        V_prime = SortedDict({tx: V[tx] for tx in t})

        score = defaultdict(float)
        for years_v, words_v in V_prime.iteritems():
            mu_v = getRangeMiddle(years_v)
            fvt = f(mu_v, mu_t)
            for word, score_wv in words_v:
                score[word] += fvt * score_wv

        # Top n terms w sorted by score_w
        scoreList = [(k, v) for k, v in score.iteritems()]
        scoreList = sorted(scoreList, key=lambda pair: pair[1], reverse=True)
        topN = scoreList[:n]

        finalVocabs[str(int(mu_t))] = topN
        periodGroups[str(int(mu_t))] = t
    return finalVocabs, periodGroups
class TransactionRepository:
    def __init__(self):
        self.__accounts = SortedDict()

    def add_amount(self, account, amount):
        account = int(account)
        amount = float(amount)
        self.__accounts[account] = self.__accounts.get(account, 0) + float(amount)

    def get_account_amount(self, account):
        return self.__accounts[int(account)]

    def get_formatted_transactions(self):
        return self.__accounts.iteritems()

    def clear(self):
        self.__accounts.clear()
Пример #6
0
def simulation(prices, signal_crosses, budget):
    simulation = {}
    prices = SortedDict(prices)
    cash_on_hand = budget
    shares = 0
    for date, price in prices.iteritems():
        signal = signal_crosses[date]
        if(signal == SELL):
            shares += cash_on_hand / price
            cash_on_hand = 0
        elif(signal == BUY):
            cash_on_hand += shares * price
            shares = 0
        simulation[date] = { 'shares': shares, 'cash_on_hand': cash_on_hand }
    final_value = max(cash_on_hand, shares * prices.values()[-1])
    earnings = final_value - budget
    return simulation, earnings
Пример #7
0
def simulation(prices, signal_crosses, budget):
    simulation = {}
    prices = SortedDict(prices)
    cash_on_hand = budget
    shares = 0
    for date, price in prices.iteritems():
        signal = signal_crosses[date]
        if (signal == SELL):
            shares += cash_on_hand / price
            cash_on_hand = 0
        elif (signal == BUY):
            cash_on_hand += shares * price
            shares = 0
        simulation[date] = {'shares': shares, 'cash_on_hand': cash_on_hand}
    final_value = max(cash_on_hand, shares * prices.values()[-1])
    earnings = final_value - budget
    return simulation, earnings
def test_init():
    sdict = SortedDict()
    sdict._check()

    sdict = SortedDict(load=17)
    sdict._check()

    sdict = SortedDict((val, -val) for val in range(10000))
    sdict._check()
    assert all(key == -val for key, val in sdict.iteritems())

    sdict.clear()
    sdict._check()
    assert len(sdict) == 0

    sdict = SortedDict.fromkeys(range(1000), None)
    assert all(sdict[key] == None for key in range(1000))
def test_init():
    sdict = SortedDict()
    sdict._check()

    sdict = SortedDict(load=17)
    sdict._check()

    sdict = SortedDict((val, -val) for val in range(10000))
    sdict._check()
    assert all(key == -val for key, val in sdict.iteritems())

    sdict.clear()
    sdict._check()
    assert len(sdict) == 0

    sdict = SortedDict.fromkeys(range(1000), None)
    assert all(sdict[key] == None for key in range(1000))
class TransactionRepository:
    def __init__(self):
        self.__accounts = SortedDict()

    def add_amount(self, account, amount):
        account = int(account)
        amount = float(amount)
        self.__accounts[account] = self.__accounts.get(account,
                                                       0) + float(amount)

    def get_account_amount(self, account):
        return self.__accounts[int(account)]

    def get_formatted_transactions(self):
        return self.__accounts.iteritems()

    def clear(self):
        self.__accounts.clear()
Пример #11
0
class KeyedRegion(object):
    """
    KeyedRegion keeps a mapping between stack offsets and all variables covering that offset. It assumes no variable in
    this region overlap with another variable in this region.

    Registers and function frames can all be viewed as a keyed region.
    """
    def __init__(self, tree=None):
        self._storage = SortedDict() if tree is None else tree

    def _get_container(self, offset):
        try:
            base_offset = next(
                self._storage.irange(maximum=offset, reverse=True))
        except StopIteration:
            return offset, None
        else:
            container = self._storage[base_offset]
            if container.includes(offset):
                return base_offset, container
            return offset, None

    def __contains__(self, offset):
        """
        Test if there is at least one varaible covering the given offset.

        :param offset:
        :return:
        """

        return self._get_container(offset)[1] is not None

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

    def __iter__(self):
        return self._storage.itervalues()

    def __eq__(self, other):
        if set(self._storage.keys()) != set(other._storage.keys()):
            return False

        for k, v in self._storage.iteritems():
            if v != other._storage[k]:
                return False

        return True

    def copy(self):
        if not self._storage:
            return KeyedRegion()

        kr = KeyedRegion()
        for key, ro in self._storage.iteritems():
            kr._storage[key] = ro.copy()
        return kr

    def merge(self, other, make_phi_func=None):
        """
        Merge another KeyedRegion into this KeyedRegion.

        :param KeyedRegion other: The other instance to merge with.
        :return: None
        """

        # TODO: is the current solution not optimal enough?
        for _, item in other._storage.iteritems():  # type: RegionObject
            for loc_and_var in item.objects:
                self.__store(loc_and_var,
                             overwrite=False,
                             make_phi_func=make_phi_func)

        return self

    def dbg_repr(self):
        """
        Get a debugging representation of this keyed region.
        :return: A string of debugging output.
        """
        keys = self._storage.keys()
        offset_to_vars = {}

        for key in sorted(keys):
            ro = self._storage[key]
            variables = [obj.variable for obj in ro.objects]
            offset_to_vars[key] = variables

        s = []
        for offset, variables in offset_to_vars.iteritems():
            s.append("Offset %#x: %s" % (offset, variables))
        return "\n".join(s)

    def add_variable(self, start, variable):
        """
        Add a variable to this region at the given offset.

        :param int start:
        :param SimVariable variable:
        :return: None
        """

        self._store(start, variable, overwrite=False)

    def set_variable(self, start, variable):
        """
        Add a variable to this region at the given offset, and remove all other variables that are fully covered by
        this variable.

        :param int start:
        :param SimVariable variable:
        :return: None
        """

        self._store(start, variable, overwrite=True)

    def get_base_addr(self, addr):
        """
        Get the base offset (the key we are using to index variables covering the given offset) of a specific offset.

        :param int addr:
        :return:
        :rtype:  int or None
        """

        base_addr, container = self._get_container(addr)
        if container is None:
            return None
        else:
            return base_addr

    def get_variables_by_offset(self, start):
        """
        Find variables covering the given region offset.

        :param int start:
        :return: A list of stack variables.
        :rtype:  set
        """

        base_addr, container = self._get_container(start)
        if container is None:
            return []
        else:
            return container.variables

    #
    # Private methods
    #

    def _store(self, start, variable, overwrite=False):
        """
        Store a variable into the storage.

        :param int start: The beginning address of the variable.
        :param variable: The variable to store.
        :param bool overwrite: Whether existing variables should be overwritten or not.
        :return: None
        """

        loc_and_var = LocationAndVariable(start, variable)
        self.__store(loc_and_var, overwrite=overwrite)

    def __store(self, loc_and_var, overwrite=False, make_phi_func=None):
        """
        Store a variable into the storage.

        :param LocationAndVariable loc_and_var: The descriptor describing start address and the variable.
        :param bool overwrite: Whether existing variables should be overwritten or not.
        :return: None
        """

        start = loc_and_var.start
        variable = loc_and_var.variable
        variable_size = variable.size if variable.size is not None else 1
        end = start + variable_size

        # region items in the middle
        overlapping_items = list(self._storage.irange(start, end - 1))

        # is there a region item that begins before the start and overlaps with this variable?
        floor_key, floor_item = self._get_container(start)
        if floor_item is not None and floor_key not in overlapping_items:
            # insert it into the beginningq
            overlapping_items.insert(0, (floor_key, self._storage[floor_key]))

        # scan through the entire list of region items, split existing regions and insert new regions as needed
        to_update = {start: RegionObject(start, variable_size, {loc_and_var})}
        last_end = start

        for floor_key in overlapping_items:
            item = self._storage[floor_key]
            if item.start < start:
                # we need to break this item into two
                a, b = item.split(start)
                if overwrite:
                    b.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(b,
                                                 loc_and_var,
                                                 make_phi_func=make_phi_func)
                to_update[a.start] = a
                to_update[b.start] = b
                last_end = b.end
            elif item.start > last_end:
                # there is a gap between the last item and the current item
                # fill in the gap
                new_item = RegionObject(last_end, item.start - last_end,
                                        {loc_and_var})
                to_update[new_item.start] = new_item
                last_end = new_item.end
            elif item.end > end:
                # we need to split this item into two
                a, b = item.split(end)
                if overwrite:
                    a.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(a,
                                                 loc_and_var,
                                                 make_phi_func=make_phi_func)
                to_update[a.start] = a
                to_update[b.start] = b
                last_end = b.end
            else:
                if overwrite:
                    item.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(item,
                                                 loc_and_var,
                                                 make_phi_func=make_phi_func)
                to_update[loc_and_var.start] = item

        self._storage.update(to_update)

    def _is_overlapping(self, start, variable):

        if variable.size is not None:
            # make sure this variable does not overlap with any other variable
            end = start + variable.size
            try:
                prev_offset = next(
                    self._storage.irange(maximum=end - 1, reverse=True))
            except StopIteration:
                prev_offset = None

            if prev_offset is not None:
                if start <= prev_offset < end:
                    return True
                prev_item = self._storage[prev_offset][0]
                prev_item_size = prev_item.size if prev_item.size is not None else 1
                if start < prev_offset + prev_item_size < end:
                    return True
        else:
            try:
                prev_offset = next(
                    self._storage.irange(maximum=start, reverse=True))
            except StopIteration:
                prev_offset = None

            if prev_offset is not None:
                prev_item = self._storage[prev_offset][0]
                prev_item_size = prev_item.size if prev_item.size is not None else 1
                if prev_offset <= start < prev_offset + prev_item_size:
                    return True

        return False

    def _add_object_or_make_phi(self, item, loc_and_var, make_phi_func=None):  #pylint:disable=no-self-use
        if not make_phi_func or len({loc_and_var.variable}
                                    | item.variables) == 1:
            item.add_object(loc_and_var)
        else:
            # make a phi node
            item.set_object(
                LocationAndVariable(
                    loc_and_var.start,
                    make_phi_func(loc_and_var.variable, *item.variables)))
def test_iteritems():
    mapping = [(val, pos) for pos, val in enumerate(string.ascii_lowercase)]
    temp = SortedDict(mapping)
    assert list(temp.iteritems()) == mapping
Пример #13
0
def test_iteritems():
    mapping = [(val, pos) for pos, val in enumerate(string.ascii_lowercase)]
    temp = SortedDict(mapping)
    assert list(temp.iteritems()) == mapping
Пример #14
0
            bywhat = int(input("Type in a number (1-2): "))
        except ValueError:
            bywhat = int(
                input(
                    "Menu choice must be entered as an integer. Type in a number (1-2): "
                ))
        if bywhat == 1:
            name = input("Name: ")
            if name in usernames:
                del usernames[name]
            else:
                print("Name not found.")
        elif bywhat == 2:
            usname = input("Username: "******"Username not found.")
        else:
            print("Invalid choice. Returning to main menu.")

    # view user name
    elif menu_choice == 4:
        print("Lookup User")
        name = input("Name: ")
        if name in usernames:
            print("Username is " + str(usernames[name]))
        else:
            print("User not found.")
Пример #15
0
class Model(object):
  '''
  The model of a Stranbeest. The Model consists of a set of nodes, edges and boundary
  conditions. Each node has a unique name and a x and y position which may change
  whenever the simuation is incremented. Each node introduces two degrees of freedom.
  The edges are specified by the nodes they are connecting. The edges are the push/pull
  rods which connect the edges whith one another. An edges keeps the distances between
  two nodes constant and therefore constrains exactly one degree of freedom in the system.
  '''

  def __init__(self):
    '''
    Constructor
    '''
    self._nodes = SortedDict()
    self._edges = defaultdict(set)

  def addNode(self,name,x,y):
    if not isinstance(name,str  ): raise Exception("The 1st argument must be the node's name as str.")
    if not isinstance(x   ,float): raise Exception("The 2nd argument must be the node's x position as float.")
    if not isinstance(y   ,float): raise Exception("The 2nd argument must be the node's y position as float.")
    if name in self._nodes: raise Exception( 'There already exists a node by the name of "%(name)s"' % locals() )
    self._nodes[name] = x,y
    self.__t = 0.0
    for listener in self.onNodeAddListeners:
      listener(name,x,y)

  def addEdge(self,node1,node2):
    if node1 == node2:
      raise Exception('"node1" cannot be equal to "node2".')
    self._edges[node1].add(node2)
    self._edges[node2].add(node1)
    for listener in self.onEdgeAddListeners:
      listener( min(node1,node2), max(node1,node2) )

  def pos(self,name):
    return self._nodes[name]

  def move(self,name,x,y):
    self._nodes[name] = x,y
    for listener in self.onNodeMoveListeners:
      listener(name,x,y)

  def state(self):
    return fromiter( chain.from_iterable( self._nodes.values() ), float )

  def setState(self,state):
    for i,(x,y) in enumerate( zip(state[::2],state[1::2]) ):
      self.move(self._nodes.keys()[i],x,y)

  @property
  def t(self):
    return self.__t

  def increment(self,dt):
    v = self.v
    t0 = self.__t
    x0 = self.state()
    # https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#The_Runge.E2.80.93Kutta_method
    k0 = v(x0,           t0)
    k1 = v(x0+k0*(dt/2), t0+dt/2)
    k2 = v(x0+k1*(dt/2), t0+dt/2)
    k3 = v(x0+k2*(dt),   t0+dt)
    self.setState( x0 + dt/6 * (k0+k1+k2+k3) )
    self.__t += dt

  def v(self,x,t):
    lhs = zeros( 2*[len(x)] )
    rhs = zeros( len(x) )
    iRows = iter( range( len(x) ) )
    for start,end in self.edges():
      iStart = 2*self._nodes.index(start)
      iEnd   = 2*self._nodes.index(end)
      iRow = next(iRows)
      dx = x[iEnd+0] - x[iStart+0] 
      dy = x[iEnd+1] - x[iStart+1]
      lhs[iRow,iStart+0] = dx; lhs[iRow,iEnd+0] = -dx
      lhs[iRow,iStart+1] = dy; lhs[iRow,iEnd+1] = -dy
      rhs[iRow] = 0
    for bc in self.bcs:
      bc.addEquations(x,t,iRows,lhs,rhs)
    return linalg.solve(lhs,rhs)

  def nodes(self):
    return self._nodes.iteritems()

  def edges(self):
    for node1,neighbors in self._edges.items():
      for node2 in neighbors:
        if node1 < node2:
          yield node1,node2

  bcs = []

  onEdgeAddListeners = set() # <- FIXME should be a multiset
  onNodeAddListeners = set() # <- FIXME should be a multiset
  onNodeMoveListeners = set() # <- FIXME should be a multiset
Пример #16
0
class KeyedRegion(object):
    """
    KeyedRegion keeps a mapping between stack offsets and all variables covering that offset. It assumes no variable in
    this region overlap with another variable in this region.

    Registers and function frames can all be viewed as a keyed region.
    """
    def __init__(self, tree=None):
        self._storage = SortedDict() if tree is None else tree

    def _get_container(self, offset):
        try:
            base_offset = next(self._storage.irange(maximum=offset, reverse=True))
        except StopIteration:
            return offset, None
        else:
            container = self._storage[base_offset]
            if container.includes(offset):
                return base_offset, container
            return offset, None

    def __contains__(self, offset):
        """
        Test if there is at least one varaible covering the given offset.

        :param offset:
        :return:
        """

        return self._get_container(offset)[1] is not None

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

    def __iter__(self):
        return self._storage.itervalues()

    def __eq__(self, other):
        if set(self._storage.keys()) != set(other._storage.keys()):
            return False

        for k, v in self._storage.iteritems():
            if v != other._storage[k]:
                return False

        return True

    def copy(self):
        if not self._storage:
            return KeyedRegion()

        kr = KeyedRegion()
        for key, ro in self._storage.iteritems():
            kr._storage[key] = ro.copy()
        return kr

    def merge(self, other, make_phi_func=None):
        """
        Merge another KeyedRegion into this KeyedRegion.

        :param KeyedRegion other: The other instance to merge with.
        :return: None
        """

        # TODO: is the current solution not optimal enough?
        for _, item in other._storage.iteritems():  # type: RegionObject
            for loc_and_var in item.objects:
                self.__store(loc_and_var, overwrite=False, make_phi_func=make_phi_func)

        return self

    def dbg_repr(self):
        """
        Get a debugging representation of this keyed region.
        :return: A string of debugging output.
        """
        keys = self._storage.keys()
        offset_to_vars = { }

        for key in sorted(keys):
            ro = self._storage[key]
            variables = [ obj.variable for obj in ro.objects ]
            offset_to_vars[key] = variables

        s = [ ]
        for offset, variables in offset_to_vars.iteritems():
            s.append("Offset %#x: %s" % (offset, variables))
        return "\n".join(s)

    def add_variable(self, start, variable):
        """
        Add a variable to this region at the given offset.

        :param int start:
        :param SimVariable variable:
        :return: None
        """

        self._store(start, variable, overwrite=False)

    def set_variable(self, start, variable):
        """
        Add a variable to this region at the given offset, and remove all other variables that are fully covered by
        this variable.

        :param int start:
        :param SimVariable variable:
        :return: None
        """

        self._store(start, variable, overwrite=True)

    def get_base_addr(self, addr):
        """
        Get the base offset (the key we are using to index variables covering the given offset) of a specific offset.

        :param int addr:
        :return:
        :rtype:  int or None
        """

        base_addr, container = self._get_container(addr)
        if container is None:
            return None
        else:
            return base_addr

    def get_variables_by_offset(self, start):
        """
        Find variables covering the given region offset.

        :param int start:
        :return: A list of stack variables.
        :rtype:  set
        """

        base_addr, container = self._get_container(start)
        if container is None:
            return []
        else:
            return container.variables

    #
    # Private methods
    #

    def _store(self, start, variable, overwrite=False):
        """
        Store a variable into the storage.

        :param int start: The beginning address of the variable.
        :param variable: The variable to store.
        :param bool overwrite: Whether existing variables should be overwritten or not.
        :return: None
        """

        loc_and_var = LocationAndVariable(start, variable)
        self.__store(loc_and_var, overwrite=overwrite)

    def __store(self, loc_and_var, overwrite=False, make_phi_func=None):
        """
        Store a variable into the storage.

        :param LocationAndVariable loc_and_var: The descriptor describing start address and the variable.
        :param bool overwrite: Whether existing variables should be overwritten or not.
        :return: None
        """

        start = loc_and_var.start
        variable = loc_and_var.variable
        variable_size = variable.size if variable.size is not None else 1
        end = start + variable_size

        # region items in the middle
        overlapping_items = list(self._storage.irange(start, end-1))

        # is there a region item that begins before the start and overlaps with this variable?
        floor_key, floor_item = self._get_container(start)
        if floor_item is not None and floor_key not in overlapping_items:
                # insert it into the beginningq
                overlapping_items.insert(0, (floor_key, self._storage[floor_key]))

        # scan through the entire list of region items, split existing regions and insert new regions as needed
        to_update = { start: RegionObject(start, variable_size, { loc_and_var }) }
        last_end = start

        for floor_key in overlapping_items:
            item = self._storage[floor_key]
            if item.start < start:
                # we need to break this item into two
                a, b = item.split(start)
                if overwrite:
                    b.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(b, loc_and_var, make_phi_func=make_phi_func)
                to_update[a.start] = a
                to_update[b.start] = b
                last_end = b.end
            elif item.start > last_end:
                # there is a gap between the last item and the current item
                # fill in the gap
                new_item = RegionObject(last_end, item.start - last_end, { loc_and_var })
                to_update[new_item.start] = new_item
                last_end = new_item.end
            elif item.end > end:
                # we need to split this item into two
                a, b = item.split(end)
                if overwrite:
                    a.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(a, loc_and_var, make_phi_func=make_phi_func)
                to_update[a.start] = a
                to_update[b.start] = b
                last_end = b.end
            else:
                if overwrite:
                    item.set_object(loc_and_var)
                else:
                    self._add_object_or_make_phi(item, loc_and_var, make_phi_func=make_phi_func)
                to_update[loc_and_var.start] = item

        self._storage.update(to_update)

    def _is_overlapping(self, start, variable):

        if variable.size is not None:
            # make sure this variable does not overlap with any other variable
            end = start + variable.size
            try:
                prev_offset = next(self._storage.irange(maximum=end-1, reverse=True))
            except StopIteration:
                prev_offset = None

            if prev_offset is not None:
                if start <= prev_offset < end:
                    return True
                prev_item = self._storage[prev_offset][0]
                prev_item_size = prev_item.size if prev_item.size is not None else 1
                if start < prev_offset + prev_item_size < end:
                    return True
        else:
            try:
                prev_offset = next(self._storage.irange(maximum=start, reverse=True))
            except StopIteration:
                prev_offset = None

            if prev_offset is not None:
                prev_item = self._storage[prev_offset][0]
                prev_item_size = prev_item.size if prev_item.size is not None else 1
                if prev_offset <= start < prev_offset + prev_item_size:
                    return True

        return False

    def _add_object_or_make_phi(self, item, loc_and_var, make_phi_func=None):  #pylint:disable=no-self-use
        if not make_phi_func or len({loc_and_var.variable} | item.variables) == 1:
            item.add_object(loc_and_var)
        else:
            # make a phi node
            item.set_object(LocationAndVariable(loc_and_var.start,
                                                make_phi_func(loc_and_var.variable, *item.variables)
                                                )
                            )
Пример #17
0
class Book(object):
    '''| TODO
    | Keep track of the active orders. It is constructed by using unordered_map, map, and vector data-structures.
    | Unordered map is used to keep pointers to all active orders. In this implementation, it is used to check whether an order already
    | exists in the book. Sorted maps are used to represent the bid and ask depths of the book using the price as a key. For efficiency,
    | the price is represented as (scaled) uint64_t. The insert operation inserts the element at the correct place implementing the
    | price priority in the book. Each element of the maps is a price level (see Level.hpp). Note that the best bid is the last element, i.e.,
    | the last price level, of the bid map; best ask is the first element (price level) of the ask map.
    |________'''
    def __init__(self):
        self.bid = SortedDict(
            neg)  # Key is price as int, value is Level (in descending order)
        self.ask = SortedDict()  # Key is price as int, value is Level

        # Uniqueness of the keys is guaranteed only for active orders, i.e., if an order is removed, another order with the same key can be added
        self.activeOrders = {
        }  # Unordered map of active orders; Key is order Id, value is Order. Used for quick search of orders.
        # Otherwise, we need to iterate over the levels (bid and ask) and to check the orders for the orderId in question

    def isBidEmpty(self):
        return len(self.bid) == 0

    def isAskEmpty(self):
        return len(self.ask) == 0

    def isEmpty(self):
        return len(self.activeOrders) == 0

    def isPresent(self, anOrderId):
        return anOrderId in self.activeOrders

    def addOrder(self,
                 isBuy=None,
                 orderId=None,
                 price=None,
                 qty=None,
                 peakSize=None,
                 order=None):
        '''| TODO 
        | Creates and adds an order to the map of orders. In addition, pointer to the order is added to the proper map (bid/ask) and
        | vector (price level). The maps are ordered, therefore, inserting elements with price as keys, automatically builds a correct
        | depth of the book.
        | Note: best bid is the last element (price level) of the bid map; best ask is the first element (price level) of the ask map.
        |________'''

        # Already checked that an order with the same Id is not present in the book
        myOrder = Order(isBuy, orderId, price, qty,
                        peakSize) if order == None else order

        self.activeOrders[myOrder.orderId] = myOrder

        # TODO: Where do we deal with int*100 price as keys?
        key_price = int(myOrder.price * 100)

        level = self.bid if myOrder.isBuy else self.ask

        if key_price not in level:
            level[key_price] = Level()

        level[key_price].addOrder(myOrder)

    def removeOrder(self, orderId):
        '''| TODO 
        | Removes an active order from the book if present (return false if order not found).
        | In case of icebergs, removes both the visible and hidden parts.
        |________'''
        if orderId in self.activeOrders:
            isBuy = self.activeOrders[orderId].isBuy
            key_price = int(self.activeOrders[orderId].price * 100)

            level = self.bid if isBuy else self.ask
            level[key_price].remove(orderId)

            del self.activeOrders[orderId]
            return True

        return False

    def removeActiveOrder(self, orderId):
        '''| TODO 
        |________'''
        if orderId in self.activeOrders:
            del self.activeOrders[orderId]
            return True

        return False

    def removeEmptyLevels(self):
        '''| TODO 
        | If an incoming order executes and matches with all active orders of the best level
        | including visible and invisible part of the orders, the level is considered empty
        | and the matching continues with the next price level. After the execution, before
        | adding an order and processing a new incoming order, this function is used to remove
        | all empty levels. The book state is updated with new best (bid/ask) levels.
        |________'''
        for price in self.bid.keys():
            if self.bid[price].isEmpty():
                del self.bid[price]

        for price in self.ask.keys():
            if self.ask[price].isEmpty():
                del self.ask[price]

    def clear(self):
        self.activeOrders.clear()
        self.bid.clear()
        self.ask.clear()

    def show(self):
        '''| TODO 
        | Called as a result of command 's'
        | Since the best price is listed first, and the maps used to store the levels are ordered,
        | this function outputs the bid levels by traversing the bid map in reverse (highest price first)
        |________'''

        if self.isEmpty():
            print "Book --- EMPTY ---"

        else:
            if len(self.bid) == 0:
                print "Bid depth --- EMPTY ---"
            else:
                print "Bid depth (highest priority at top):"
                print "Price     ", "Order Id  ", "Quantity  ", "Iceberg"

                # Highest price first
                for _, level in self.bid.iteritems():
                    level.show()
                print

            if len(self.ask) == 0:
                print "Ask depth --- EMPTY ---"
            else:
                print "Ask depth (highest priority at top):"
                print "Price     ", "Order Id  ", "Quantity  ", "Iceberg"

                # Lowest price first
                for _, level in self.ask.iteritems():
                    level.show()
        print
Пример #18
0
class AccessList:
    MIN_SEQUENCE_NUM = 1
    MAX_SEQUENCE_NUM = 2147483647

    def __init__(self, name, seq_step=10):
        if len(name) > 64:
            raise ValueError("Name {} is too long.".format(name))

        self._name = name
        self._seq_step = seq_step
        self._statements = SortedDict()
        self._fs_start = None
        self._fs_end = None

        self._changes = []

    @property
    def title(self):
        return 'ipv4 access-list {}'.format(self._name)

    @property
    def name(self):
        return self._name

    def _remove_statement(self, seq):
        statement = self._statements.pop(seq, None)
        if statement:
            self._changes.append('no {}'.format(seq))

    def apply_flowspec(self, fs_ace_list, fs_start_seq=None):
        self.remove_flowspec()

        if not fs_ace_list:
            return

        to_apply = [AccessListEntry.create_remark(FLOWSPEC_START_REMARK).rule]
        to_apply.extend(fs_ace_list)
        to_apply.append(
            AccessListEntry.create_remark(FLOWSPEC_END_REMARK).rule)

        if len(self._statements):
            last_seq, last_statement = self._statements.peekitem()
            next_free_seq = last_seq + self._seq_step
        else:
            last_statement = None
            next_free_seq = self._seq_step

        permit_all_statement = 'permit ipv4 any any'
        if last_statement == permit_all_statement:
            self._remove_statement(last_seq)
            next_free_seq = last_seq

        to_apply.append(permit_all_statement)

        if fs_start_seq is None or fs_start_seq < next_free_seq:
            fs_start_seq = next_free_seq

        after_apply_last_seq = fs_start_seq + len(to_apply)
        if after_apply_last_seq > self.MAX_SEQUENCE_NUM:
            raise IndexError(
                "Added sequence {} exceed maximum allowed {}".format(
                    after_apply_last_seq, self.MAX_SEQUENCE_NUM))

        cur_seq = fs_start_seq
        for statement in to_apply:
            self._add_statement(statement, cur_seq)
            cur_seq += 1

    def _add_statement(self, statement, seq=None, save_change=True):
        self._statements.update({seq: statement})
        if save_change:
            self._changes.append('{} {}'.format(seq, statement))

    def add_statement(self, statement, seq=None):
        statement_pat = re.compile(r'(deny|remark|permit) .+')
        if not statement_pat.match(statement):
            raise ValueError('Wrong statement format: {}'.format(statement))

        if seq is None:
            if self.is_empty():
                seq = self._seq_step
            else:
                seq = self._statements.peekitem()[0] + self._seq_step

        seq = int(seq)

        if seq > self.MAX_SEQUENCE_NUM:
            raise IndexError(
                'Sequence index is out of range: {}. Max: {}'.format(
                    seq, self.MAX_SEQUENCE_NUM))

        self._add_statement(statement, seq)

    def is_empty(self):
        return len(self._statements) == 0

    def is_flowspec_applied(self):
        return bool(self._fs_start)

    @classmethod
    def from_config(cls, raw_config_list):
        if len(raw_config_list) <= 1:
            raise ValueError('Passed empty config list.')

        acl_name_pat = re.compile(r'ipv4 access-list ([^\s]{1,64})')
        acls = []
        cur_acl = None
        for line in raw_config_list:
            acl_title = acl_name_pat.match(line)
            if acl_title:
                cur_acl = cls(acl_title.group(1))
            elif line == '!' and cur_acl is not None:
                acls.append(cur_acl)
                cur_acl = None
            elif cur_acl is not None:
                seq, statement = line.split(' ', 1)
                seq = int(seq)
                if FLOWSPEC_START_REMARK in statement and cur_acl._fs_start is None:
                    cur_acl._fs_start = seq
                elif FLOWSPEC_END_REMARK in statement:
                    cur_acl._fs_end = seq
                cur_acl._add_statement(statement, seq, save_change=False)
        return acls

    def remove_flowspec(self):
        if self._fs_start is None:
            return None

        fs_iter = self._statements.irange(minimum=self._fs_start,
                                          maximum=self._fs_end)
        for seq in list(fs_iter):
            self._remove_statement(seq)

        # TODO: change this logic: need to find and move only 'permit any any' statement,
        #  which is located after flowspec, if there is no such ace, then skip
        last_seq, last_statement = self._statements.peekitem()
        if last_seq > self._fs_start:
            self._remove_statement(last_seq)
            self._add_statement(last_statement, self._fs_start)

        self._fs_start = None
        self._fs_end = None

    def reset_changes(self):
        self._changes = []

    def get_changes_config(self):
        if not self._changes:
            return None
        changes_config = '\n'.join(self._changes)
        changes_config = '\n'.join([self.title, changes_config])
        return changes_config

    def get_config(self):
        if self.is_empty():
            return None
        config = '\n'.join([
            '{} {}'.format(seq, statement)
            for seq, statement in self._statements.iteritems()
        ])
        config = '\n'.join([self.title, config])
        return config