-
Notifications
You must be signed in to change notification settings - Fork 0
/
Graph.py
180 lines (137 loc) · 6.31 KB
/
Graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import Node
import Programmer
import Edge
import NodeWeightCalculator
import EdgeCalculator
import EdgeWeightCalculator
import GraphSimplification
#class that represents the social graph,
#contains a node and edge list
class Graph:
#@param listOfProgrammers is a list of Programmer objects
def __init__(self,listOfProgrammers,listOfCommits,nodeIterator):
self.nodeslist = []
self.edgeslist = []
self.clusterNodeslist = []
self.clusterEdgeslist = []
self.nodeIterator = nodeIterator
self.constructGraph(listOfProgrammers,listOfCommits)
def getNodesList(self):
return self.nodeslist
def getEdgesList(self):
return self.edgeslist
def getClusterNodesList(self):
return self.clusterNodeslist
def getClusterEdgesList(self):
return self.clusterEdgeslist
def getNodeIterator(self):
return self.nodeIterator
def setNodeIterator(self,newIterator):
if(newIterator > self.nodeIterator):
self.nodeIterator = newIterator
def addNodeToList(self,node):
self.nodeslist.append(node)
def addEdgeToList(self,edge):
self.edgeslist.append(edge)
#searches for node with that ID in the nodelist and returns it
#@param ID = the id of the node you're searching for
#@returns the node
def getNodeByID(self,id):
node = [target for target in self.nodeslist if target.getID()==id]
return node[0]
def getEdgeByID(self,sourceNodeID,targetNodeID):
#edge could be (source,target) or (target,source)
for edge in self.edgeslist:
sID = edge.getSourceNodeID()
tID = edge.getTargetNodeID()
if(((sID == sourceNodeID)and(tID == targetNodeID))or((sID == targetNodeID)and(tID == sourceNodeID))):
return edge
#build the nodes list
def buildNodesList(self,programmers):
#include all programmers and set the weight default at 1
#build the list
for prog in programmers:
self.addNodeToList(Node.Node(prog,1))
#build the edges list
def buildEdgesList(self,commits,programmers):
#build the pair programming edges
edgecalc = EdgeCalculator.EdgeCalculator(commits,programmers)
#returns dictionary with source and target nodes IDs as key + weight as value
print(" Building the pair programming edges")
edgeDict = edgecalc.getPairProgrammingEdges()
self.addPairProgrammingEdgesToList(edgeDict)
#build all other edges apart from pair programming
print(" Building the disjunct collaboration edges")
edgeDict2 = edgecalc.getDisjunctColloborationEdges()
self.addDisjunctCollaborationEdgesToList(edgeDict2)
#creates edges for the pairprogramming pairs
def addPairProgrammingEdgesToList(self,pairs):
for IDs, info in pairs.items():
edge = Edge.Edge(self.getNodeByID(IDs[0]),self.getNodeByID(IDs[1]))
edge.setPairProgrammingWeight(info['weight'])
edge.setPairProgCommitList(info['commits'])
self.addEdgeToList(edge)
def addDisjunctCollaborationEdgesToList(self,pairs):
for IDs, info in pairs.items():
#check first if edge already exists
edge = self.getEdgeByID(IDs[0],IDs[1])
if not isinstance(edge,Edge.Edge):
#edge does not exist yet, make one
edge = Edge.Edge(self.getNodeByID(IDs[0]),self.getNodeByID(IDs[1]))
self.addEdgeToList(edge)
else:
#it's possible that source & target node are switched, so make sure it is set right
#this is to make sure that the order of commit tuples is correct
edge.resetSourceAndTargetNodes(self.getNodeByID(IDs[0]),self.getNodeByID(IDs[1]))
edge.setDisjunctCollabCommitList(info['commits'])
edge.setDistinctProgramming()
#calculates the weights for the nodes using adapted versions of:
#frequency significance
#betweenness centrality
#eigenvector centrality
#degree centrality
def calculateNodeWeights(self):
nodecalc = NodeWeightCalculator.NodeWeightCalculator(self.nodeslist,self.edgeslist)#,self.totalImportanceAllFiles)
nodecalc.calculateNodeWeights()
#calculates the weights for the edges, making use of
#frequency significance
#proximity correlation
def calculateEdgeWeights(self):
edgecalc = EdgeWeightCalculator.EdgeWeightCalculator(self.edgeslist)
edgecalc.calculateEdgeWeights()
#Clean up the edges: delete edges with a weight of 0
self.cleanUpEdges()
#Function that deletes all edges with a weight of 0
def cleanUpEdges(self):
self.edgeslist = [edge for edge in self.edgeslist if edge.getWeight() != 0]
#constructs the graph: builds node & edges list
def constructGraph(self,programmers,commits):
#build the base graph
print("Building the nodes list")
self.buildNodesList(programmers)
print("Building the edges list")
self.buildEdgesList(commits,programmers)
#calculate the weights
print("Calculating the edge weights")
self.calculateEdgeWeights()
print("Calculating the node weights")
self.calculateNodeWeights()
#simplyfiy the graph
print("Simplifying the graph")
self.graphSimplification()
#simplify the graph
def graphSimplification(self):
simplifier = GraphSimplification.GraphSimplification(self.nodeslist,self.edgeslist)
simplifier.simplifyGraph()
self.nodeslist = simplifier.getNodesList()
self.edgeslist = simplifier.getEdgesList()
self.clusterNodeslist = simplifier.getClusterNodesList()
self.clusterEdgeslist = simplifier.getClusterEdgesList()
#function that deletes the node from the graph,
#including its incident links
def deleteNodeFromGraph(self,nodeID):
node = self.getNodeByID(nodeID)
#delete now all incident edges
self.edgeslist = [edge for edge in self.edgeslist if not edge.containsNode(node)]
#delete the node from the nodeslist
self.nodeslist.remove(node)