"""
Tests for degree centrality.
"""
from nose.tools import *
import networkx as nx


class TestClosenessCentrality:
    def setUp(self):
        self.K = nx.krackhardt_kite_graph()
        self.P3 = nx.path_graph(3)
        self.P4 = nx.path_graph(4)
        self.K5 = nx.complete_graph(5)

        self.C4 = nx.cycle_graph(4)
        self.T = nx.balanced_tree(r=2, h=2)
        self.Gb = nx.Graph()
        self.Gb.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3),
                                (2, 4), (4, 5), (3, 5)])

        F = nx.florentine_families_graph()
        self.F = F

        self.LM = nx.les_miserables_graph()

    def test_wf_improved(self):
        G = nx.union(self.P4, nx.path_graph([4, 5, 6]))
        c = nx.closeness_centrality(G)
        cwf = nx.closeness_centrality(G, wf_improved=False)
        res = {0: 0.25, 1: 0.375, 2: 0.375, 3: 0.25,
               4: 0.222, 5: 0.333, 6: 0.222}
        wf_res = {0: 0.5, 1: 0.75, 2: 0.75, 3: 0.5,
                  4: 0.667, 5: 1.0, 6: 0.667}
        for n in G:
            assert_almost_equal(c[n], res[n], places=3)
            assert_almost_equal(cwf[n], wf_res[n], places=3)

    def test_digraph(self):
        G = nx.path_graph(3, create_using=nx.DiGraph())
        c = nx.closeness_centrality(G)
        cr = nx.closeness_centrality(G.reverse())
        d = {0: 0.0, 1: 0.500, 2: 0.667}
        dr = {0: 0.667, 1: 0.500, 2: 0.0}
        for n in sorted(self.P3):
            assert_almost_equal(c[n], d[n], places=3)
            assert_almost_equal(cr[n], dr[n], places=3)

    def test_k5_closeness(self):
        c = nx.closeness_centrality(self.K5)
        d = {0: 1.000,
             1: 1.000,
             2: 1.000,
             3: 1.000,
             4: 1.000}
        for n in sorted(self.K5):
            assert_almost_equal(c[n], d[n], places=3)

    def test_p3_closeness(self):
        c = nx.closeness_centrality(self.P3)
        d = {0: 0.667,
             1: 1.000,
             2: 0.667}
        for n in sorted(self.P3):
            assert_almost_equal(c[n], d[n], places=3)

    def test_krackhardt_closeness(self):
        c = nx.closeness_centrality(self.K)
        d = {0: 0.529,
             1: 0.529,
             2: 0.500,
             3: 0.600,
             4: 0.500,
             5: 0.643,
             6: 0.643,
             7: 0.600,
             8: 0.429,
             9: 0.310}
        for n in sorted(self.K):
            assert_almost_equal(c[n], d[n], places=3)

    def test_florentine_families_closeness(self):
        c = nx.closeness_centrality(self.F)
        d = {'Acciaiuoli':    0.368,
             'Albizzi':       0.483,
             'Barbadori':     0.4375,
             'Bischeri':      0.400,
             'Castellani':    0.389,
             'Ginori':        0.333,
             'Guadagni':      0.467,
             'Lamberteschi':  0.326,
             'Medici':        0.560,
             'Pazzi':         0.286,
             'Peruzzi':       0.368,
             'Ridolfi':       0.500,
             'Salviati':      0.389,
             'Strozzi':       0.4375,
             'Tornabuoni':    0.483}
        for n in sorted(self.F):
            assert_almost_equal(c[n], d[n], places=3)

    def test_les_miserables_closeness(self):
        c = nx.closeness_centrality(self.LM)
        d = {'Napoleon': 0.302,
             'Myriel': 0.429,
             'MlleBaptistine': 0.413,
             'MmeMagloire': 0.413,
             'CountessDeLo': 0.302,
             'Geborand': 0.302,
             'Champtercier': 0.302,
             'Cravatte': 0.302,
             'Count': 0.302,
             'OldMan': 0.302,
             'Valjean': 0.644,
             'Labarre': 0.394,
             'Marguerite': 0.413,
             'MmeDeR': 0.394,
             'Isabeau': 0.394,
             'Gervais': 0.394,
             'Listolier': 0.341,
             'Tholomyes': 0.392,
             'Fameuil': 0.341,
             'Blacheville': 0.341,
             'Favourite': 0.341,
             'Dahlia': 0.341,
             'Zephine': 0.341,
             'Fantine': 0.461,
             'MmeThenardier': 0.461,
             'Thenardier': 0.517,
             'Cosette': 0.478,
             'Javert': 0.517,
             'Fauchelevent': 0.402,
             'Bamatabois': 0.427,
             'Perpetue': 0.318,
             'Simplice': 0.418,
             'Scaufflaire': 0.394,
             'Woman1': 0.396,
             'Judge': 0.404,
             'Champmathieu': 0.404,
             'Brevet': 0.404,
             'Chenildieu': 0.404,
             'Cochepaille': 0.404,
             'Pontmercy': 0.373,
             'Boulatruelle': 0.342,
             'Eponine': 0.396,
             'Anzelma': 0.352,
             'Woman2': 0.402,
             'MotherInnocent': 0.398,
             'Gribier': 0.288,
             'MmeBurgon': 0.344,
             'Jondrette': 0.257,
             'Gavroche': 0.514,
             'Gillenormand': 0.442,
             'Magnon': 0.335,
             'MlleGillenormand': 0.442,
             'MmePontmercy': 0.315,
             'MlleVaubois': 0.308,
             'LtGillenormand': 0.365,
             'Marius': 0.531,
             'BaronessT': 0.352,
             'Mabeuf': 0.396,
             'Enjolras': 0.481,
             'Combeferre': 0.392,
             'Prouvaire': 0.357,
             'Feuilly': 0.392,
             'Courfeyrac': 0.400,
             'Bahorel': 0.394,
             'Bossuet': 0.475,
             'Joly': 0.394,
             'Grantaire': 0.358,
             'MotherPlutarch': 0.285,
             'Gueulemer': 0.463,
             'Babet': 0.463,
             'Claquesous': 0.452,
             'Montparnasse': 0.458,
             'Toussaint': 0.402,
             'Child1': 0.342,
             'Child2': 0.342,
             'Brujon': 0.380,
             'MmeHucheloup': 0.353}
        for n in sorted(self.LM):
            assert_almost_equal(c[n], d[n], places=3)

    def test_weighted_closeness(self):
        edges = ([('s', 'u', 10), ('s', 'x', 5), ('u', 'v', 1),
                  ('u', 'x', 2), ('v', 'y', 1), ('x', 'u', 3),
                  ('x', 'v', 5), ('x', 'y', 2), ('y', 's', 7), ('y', 'v', 6)])
        XG = nx.Graph()
        XG.add_weighted_edges_from(edges)
        c = nx.closeness_centrality(XG, distance='weight')
        d = {'y': 0.200,
             'x': 0.286,
             's': 0.138,
             'u': 0.235,
             'v': 0.200}
        for n in sorted(XG):
            assert_almost_equal(c[n], d[n], places=3)
