from nose.tools import *
import networkx as nx
from networkx.algorithms import bipartite

class TestBipartiteCentrality(object):

    def setUp(self):
        self.P4 = nx.path_graph(4)
        self.K3 = nx.complete_bipartite_graph(3,3)
        self.C4 = nx.cycle_graph(4)
        self.davis = nx.davis_southern_women_graph()
        self.top_nodes = [n for n,d in self.davis.nodes(data=True) 
                          if d['bipartite']==0]

    def test_degree_centrality(self):
        d = bipartite.degree_centrality(self.P4, [1,3])
        answer = {0: 0.5, 1: 1.0,  2: 1.0, 3:  0.5}
        assert_equal(d, answer)
        d = bipartite.degree_centrality(self.K3, [0,1,2])
        answer = {0: 1.0, 1: 1.0, 2: 1.0, 3: 1.0, 4: 1.0, 5: 1.0}
        assert_equal(d, answer)
        d = bipartite.degree_centrality(self.C4, [0,2])
        answer = {0: 1.0, 1: 1.0, 2: 1.0, 3: 1.0}
        assert_equal(d,answer)

    def test_betweenness_centrality(self):
        c = bipartite.betweenness_centrality(self.P4, [1,3])
        answer = {0: 0.0, 1: 1.0, 2: 1.0, 3: 0.0}
        assert_equal(c, answer)
        c = bipartite.betweenness_centrality(self.K3, [0,1,2])
        answer = {0: 0.125, 1: 0.125, 2: 0.125, 3: 0.125, 4: 0.125, 5: 0.125}
        assert_equal(c, answer)
        c = bipartite.betweenness_centrality(self.C4, [0,2])
        answer = {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25}
        assert_equal(c, answer)

    def test_closeness_centrality(self):
        c = bipartite.closeness_centrality(self.P4, [1,3])
        answer = {0: 2.0/3, 1: 1.0, 2: 1.0, 3:2.0/3}
        assert_equal(c, answer)
        c = bipartite.closeness_centrality(self.K3, [0,1,2])
        answer = {0: 1.0, 1: 1.0, 2: 1.0, 3: 1.0, 4: 1.0, 5: 1.0}
        assert_equal(c, answer)
        c = bipartite.closeness_centrality(self.C4, [0,2])
        answer = {0: 1.0, 1: 1.0, 2: 1.0, 3: 1.0}
        assert_equal(c, answer)

    def test_davis_degree_centrality(self):
        G = self.davis
        deg = bipartite.degree_centrality(G, self.top_nodes)
        answer = {'E8':0.78,
                'E9':0.67,
                'E7':0.56,
                'Nora Fayette':0.57,
                'Evelyn Jefferson':0.57,
                'Theresa Anderson':0.57,
                'E6':0.44,
                'Sylvia Avondale':0.50,
                'Laura Mandeville':0.50,
                'Brenda Rogers':0.50,
                'Katherina Rogers':0.43,
                'E5':0.44,
                'Helen Lloyd':0.36,
                'E3':0.33,
                'Ruth DeSand':0.29,
                'Verne Sanderson':0.29,
                'E12':0.33,
                'Myra Liddel':0.29,
                'E11':0.22,
                'Eleanor Nye':0.29,
                'Frances Anderson':0.29,
                'Pearl Oglethorpe':0.21,
                'E4':0.22,
                'Charlotte McDowd':0.29,
                'E10':0.28,
                'Olivia Carleton':0.14,
                'Flora Price':0.14,
                'E2':0.17,
                'E1':0.17,
                'Dorothy Murchison':0.14,
                'E13':0.17,
                'E14':0.17}
        for node, value in answer.items():
            assert_almost_equal(value, deg[node], places=2)

    def test_davis_betweenness_centrality(self):
        G = self.davis
        bet = bipartite.betweenness_centrality(G, self.top_nodes)
        answer = {'E8':0.24,
                'E9':0.23,
                'E7':0.13,
                'Nora Fayette':0.11,
                'Evelyn Jefferson':0.10,
                'Theresa Anderson':0.09,
                'E6':0.07,
                'Sylvia Avondale':0.07,
                'Laura Mandeville':0.05,
                'Brenda Rogers':0.05,
                'Katherina Rogers':0.05,
                'E5':0.04,
                'Helen Lloyd':0.04,
                'E3':0.02,
                'Ruth DeSand':0.02,
                'Verne Sanderson':0.02,
                'E12':0.02,
                'Myra Liddel':0.02,
                'E11':0.02,
                'Eleanor Nye':0.01,
                'Frances Anderson':0.01,
                'Pearl Oglethorpe':0.01,
                'E4':0.01,
                'Charlotte McDowd':0.01,
                'E10':0.01,
                'Olivia Carleton':0.01,
                'Flora Price':0.01,
                'E2':0.00,
                'E1':0.00,
                'Dorothy Murchison':0.00,
                'E13':0.00,
                'E14':0.00}
        for node, value in answer.items():
            assert_almost_equal(value, bet[node], places=2)

    def test_davis_closeness_centrality(self):
        G = self.davis
        clos = bipartite.closeness_centrality(G, self.top_nodes)
        answer = {'E8':0.85,
                'E9':0.79,
                'E7':0.73,
                'Nora Fayette':0.80,
                'Evelyn Jefferson':0.80,
                'Theresa Anderson':0.80,
                'E6':0.69,
                'Sylvia Avondale':0.77,
                'Laura Mandeville':0.73,
                'Brenda Rogers':0.73,
                'Katherina Rogers':0.73,
                'E5':0.59,
                'Helen Lloyd':0.73,
                'E3':0.56,
                'Ruth DeSand':0.71,
                'Verne Sanderson':0.71,
                'E12':0.56,
                'Myra Liddel':0.69,
                'E11':0.54,
                'Eleanor Nye':0.67,
                'Frances Anderson':0.67,
                'Pearl Oglethorpe':0.67,
                'E4':0.54,
                'Charlotte McDowd':0.60,
                'E10':0.55,
                'Olivia Carleton':0.59,
                'Flora Price':0.59,
                'E2':0.52,
                'E1':0.52,
                'Dorothy Murchison':0.65,
                'E13':0.52,
                'E14':0.52}
        for node, value in answer.items():
            assert_almost_equal(value, clos[node], places=2)


