Module olivia.coupling
Olivia coupling functions.
Coupling characterizes the local structure of the transitive dependency relation between packages.
Expand source code
"""
Olivia coupling functions.
Coupling characterizes the local structure of the transitive dependency relation between packages.
"""
import networkx as nx
def coupling_interface(olivia_model, n, m):
"""
Compute the coupling interface of one package over another.
The coupling interface of a network package n over another package m is the set of direct dependencies of m
potentially compromised by a defect in n.
Parameters
----------
olivia_model: OliviaNetwork
Input network.
n: package
Source package.
m: package
Target package.
Returns
-------
coup: set
Coupling interface of n over m.
Notes
-----
For computing the coupling interface of all transitive dependencies over a package use ~coupling_profile() instead
as it is much faster.
"""
return set(olivia_model.network.predecessors(m)) & (nx.descendants(olivia_model.network, n) | {n})
def transitive_coupling(olivia_model, n, m):
"""
Compute the transitive coupling of one package over another.
The transitive coupling is the size of the transitive interface of n over m.
Parameters
----------
olivia_model: OliviaNetwork
Input network.
n: package
Source package.
m: package
Target package.
Returns
-------
tcoup: int
Transitive coupling of n over m.
"""
return len(coupling_interface(olivia_model, n, m))
def coupling_profile(olivia_model, m):
"""
Compute the coupling profile of a package.
The coupling profile is the set of all the coupling interfaces of transitive dependencies of m over m.
Parameters
----------
olivia_model: OliviaNetwork
Input network.
m: package
Target package.
Returns
-------
profile: dict
Dictionary with transitive dependencies of m as keys and their transitive interface over n as values.
"""
# Surface (transitive predecessors) of each direct dependency of m
surface = {p: nx.ancestors(olivia_model.network, p) | {p} for p in olivia_model.network.predecessors(m)}
# For each ancestor check if it is in the surface of each direct dependency of m
# and add it to the coupling interface.
return {a: {p for p in olivia_model.network.predecessors(m) if a in surface[p]}
for a in nx.ancestors(olivia_model.network, m)}
Functions
def coupling_interface(olivia_model, n, m)
-
Compute the coupling interface of one package over another.
The coupling interface of a network package n over another package m is the set of direct dependencies of m potentially compromised by a defect in n.
Parameters
olivia_model
:OliviaNetwork
- Input network.
n
:package
- Source package.
m
:package
- Target package.
Returns
coup
:set
- Coupling interface of n over m.
Notes
For computing the coupling interface of all transitive dependencies over a package use ~coupling_profile() instead as it is much faster.
Expand source code
def coupling_interface(olivia_model, n, m): """ Compute the coupling interface of one package over another. The coupling interface of a network package n over another package m is the set of direct dependencies of m potentially compromised by a defect in n. Parameters ---------- olivia_model: OliviaNetwork Input network. n: package Source package. m: package Target package. Returns ------- coup: set Coupling interface of n over m. Notes ----- For computing the coupling interface of all transitive dependencies over a package use ~coupling_profile() instead as it is much faster. """ return set(olivia_model.network.predecessors(m)) & (nx.descendants(olivia_model.network, n) | {n})
def coupling_profile(olivia_model, m)
-
Compute the coupling profile of a package.
The coupling profile is the set of all the coupling interfaces of transitive dependencies of m over m.
Parameters
olivia_model
:OliviaNetwork
- Input network.
m
:package
- Target package.
Returns
profile
:dict
- Dictionary with transitive dependencies of m as keys and their transitive interface over n as values.
Expand source code
def coupling_profile(olivia_model, m): """ Compute the coupling profile of a package. The coupling profile is the set of all the coupling interfaces of transitive dependencies of m over m. Parameters ---------- olivia_model: OliviaNetwork Input network. m: package Target package. Returns ------- profile: dict Dictionary with transitive dependencies of m as keys and their transitive interface over n as values. """ # Surface (transitive predecessors) of each direct dependency of m surface = {p: nx.ancestors(olivia_model.network, p) | {p} for p in olivia_model.network.predecessors(m)} # For each ancestor check if it is in the surface of each direct dependency of m # and add it to the coupling interface. return {a: {p for p in olivia_model.network.predecessors(m) if a in surface[p]} for a in nx.ancestors(olivia_model.network, m)}
def transitive_coupling(olivia_model, n, m)
-
Compute the transitive coupling of one package over another.
The transitive coupling is the size of the transitive interface of n over m.
Parameters
olivia_model
:OliviaNetwork
- Input network.
n
:package
- Source package.
m
:package
- Target package.
Returns
tcoup
:int
- Transitive coupling of n over m.
Expand source code
def transitive_coupling(olivia_model, n, m): """ Compute the transitive coupling of one package over another. The transitive coupling is the size of the transitive interface of n over m. Parameters ---------- olivia_model: OliviaNetwork Input network. n: package Source package. m: package Target package. Returns ------- tcoup: int Transitive coupling of n over m. """ return len(coupling_interface(olivia_model, n, m))