<commit_before>__author__ = 'Toby, refactor by Gabs'

from shapely.geometry import Point, LineString, Polygon
import networkx as nx
import cPickle
import scipy as sp
import numpy as np
from collections import defaultdict
import bisect as bs
import pysal as psl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.path import Path
from matplotlib.collections import PatchCollection
from matplotlib.colors import Normalize
from matplotlib.colorbar import ColorbarBase
import copy

class Edge(object):

    def __init__(self, street_net, orientation_pos=None, orientation_neg=None, fid=None, **kwargs):
        self.graph = street_net
        self.orientation_neg = orientation_neg
        self.orientation_pos = orientation_pos
        self.fid = fid

    # redefine __getattr__ so that any dict-style lookups on this object are redirected to look in the attributes
    def __getitem__(self, item):
        return self.attrs[item]

    def __repr__(self):
        return "<Edge {0} <-> {1} ({2})>".format(
            self.orientation_neg,
            self.orientation_pos,
            self.fid
        )

    @property
    def attrs(self):
        return self.graph.g.edge[self.orientation_neg][self.orientation_pos][self.fid]

    @property
    def linestring(self):
        return self.attrs['linestring']

    @property
    def length(self):
        return self.attrs['length']

    @property
    def centroid(self):
        """
        The line's central coordinate as a NetPoint.
        """
        node_dist = {
            self.orientation_neg: self.length / 2.0,
            self.orientation_pos: self.length / 2.0
        }
        return NetPoint(self.graph, self, node_dist)

    @property
    def centroid_xy(self):
        """
        The line's central coordinate in cartesian coordinates.
        """
        return self.centroid.cartesian_coords

    @property
    def node_pos_coords(self):
        return self.graph.g.node[self.orientation_pos]['loc']

    @property
    def node_neg_coords(self):
        return self.graph.g.node[self.orientation_neg]['loc']

    def __eq__(self, other):
        """
        Test for equality of two edges.
        If the underlying graph is undirected, then it doesn't matter which way around the nodes are defined.
        If it is directed, the node order is important.
        :param other:
        :return: Bool
        """
        if self.graph.directed:
            return (
                self.graph is other.graph and
                self.orientation_neg == other.orientation_neg and
                self.orientation_pos == other.orientation_pos and
                self.fid == other.fid
            )
        else:
            return (
                self.graph is other.graph and (
                    (self.orientation_neg == other.orientation_neg and self.orientation_pos == other.orientation_pos) or
                    (self.orientation_neg == other.orientation_pos and self.orientation_pos == other.orientation_neg)
                ) and
                self.fid == other.fid
            )


class NetPoint(object):

    def __init__(self, street_net, edge, node_dist):
        """
        :param street_net: A pointer to the network on which this point is defined
        :param edge: An edge ID referring to an edge in street_net
        :param node_dist: A dictionary containing the distance along this edge from both the positive and negative end
        The key gives the node ID, the value gives the distance from that end.
        """
        self.graph = street_net
        self.edge = edge
        self.node_dist = node_dist

    @property
    def cartesian_coords(self):
        return self.graph.network_point_to_xy(self)

    def test_compatible(self, other):
        if not self.graph is other.graph:
            raise AttributeError("The two points are defined on different graphs")

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            raise TypeError("Can only compare NetPoint with another NetPoint.")
        # don't use test_compatible here because we want such an operation to return False, not raise an exception
        return (
            self.graph is other.graph and
            self.edge == other.edge and
            self.node_dist == other.node_dist
        )

    def __sub__(self, other):
        # NetPoint - NetPoint -> NetPath
        self.test_compatible(other)
        if self.graph.directed:
            return self.graph.path_directed(self, other)
        else:
            return self.graph.path_undirected(self, other)
<commit_msg>Re-do the removal of TypeError in NetPoint equality check<commit_after>__author__ = 'Toby, refactor by Gabs'

from shapely.geometry import Point, LineString, Polygon
import networkx as nx
import cPickle
import scipy as sp
import numpy as np
from collections import defaultdict
import bisect as bs
import pysal as psl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.path import Path
from matplotlib.collections import PatchCollection
from matplotlib.colors import Normalize
from matplotlib.colorbar import ColorbarBase
import copy

class Edge(object):

    def __init__(self, street_net, orientation_pos=None, orientation_neg=None, fid=None, **kwargs):
        self.graph = street_net
        self.orientation_neg = orientation_neg
        self.orientation_pos = orientation_pos
        self.fid = fid

    # redefine __getattr__ so that any dict-style lookups on this object are redirected to look in the attributes
    def __getitem__(self, item):
        return self.attrs[item]

    def __repr__(self):
        return "<Edge {0} <-> {1} ({2})>".format(
            self.orientation_neg,
            self.orientation_pos,
            self.fid
        )

    @property
    def attrs(self):
        return self.graph.g.edge[self.orientation_neg][self.orientation_pos][self.fid]

    @property
    def linestring(self):
        return self.attrs['linestring']

    @property
    def length(self):
        return self.attrs['length']

    @property
    def centroid(self):
        """
        The line's central coordinate as a NetPoint.
        """
        node_dist = {
            self.orientation_neg: self.length / 2.0,
            self.orientation_pos: self.length / 2.0
        }
        return NetPoint(self.graph, self, node_dist)

    @property
    def centroid_xy(self):
        """
        The line's central coordinate in cartesian coordinates.
        """
        return self.centroid.cartesian_coords

    @property
    def node_pos_coords(self):
        return self.graph.g.node[self.orientation_pos]['loc']

    @property
    def node_neg_coords(self):
        return self.graph.g.node[self.orientation_neg]['loc']

    def __eq__(self, other):
        """
        Test for equality of two edges.
        If the underlying graph is undirected, then it doesn't matter which way around the nodes are defined.
        If it is directed, the node order is important.
        :param other:
        :return: Bool
        """
        if self.graph.directed:
            return (
                self.graph is other.graph and
                self.orientation_neg == other.orientation_neg and
                self.orientation_pos == other.orientation_pos and
                self.fid == other.fid
            )
        else:
            return (
                self.graph is other.graph and (
                    (self.orientation_neg == other.orientation_neg and self.orientation_pos == other.orientation_pos) or
                    (self.orientation_neg == other.orientation_pos and self.orientation_pos == other.orientation_neg)
                ) and
                self.fid == other.fid
            )


class NetPoint(object):

    def __init__(self, street_net, edge, node_dist):
        """
        :param street_net: A pointer to the network on which this point is defined
        :param edge: An edge ID referring to an edge in street_net
        :param node_dist: A dictionary containing the distance along this edge from both the positive and negative end
        The key gives the node ID, the value gives the distance from that end.
        """
        self.graph = street_net
        self.edge = edge
        self.node_dist = node_dist

    @property
    def cartesian_coords(self):
        return self.graph.network_point_to_xy(self)

    def test_compatible(self, other):
        if not self.graph is other.graph:
            raise AttributeError("The two points are defined on different graphs")

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        # don't use test_compatible here because we want such an operation to return False, not raise an exception
        return (
            self.graph is other.graph and
            self.edge == other.edge and
            self.node_dist == other.node_dist
        )

    def __sub__(self, other):
        # NetPoint - NetPoint -> NetPath
        self.test_compatible(other)
        if self.graph.directed:
            return self.graph.path_directed(self, other)
        else:
            return self.graph.path_undirected(self, other)

{'fraction_non_alphanumeric': 0.07639717851329354, 'fraction_numerical': 0.001519262072707542, 'mean_word_length': 2.2902534808996786, 'pattern_counts': {'":': 0, '<': 7, '<?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': '1010729', 'n_tokens_mistral': 2577, 'n_tokens_neox': 2460, 'n_words': 786}