Skip to content

Commit

Permalink
Merge pull request #30 from microsoft/fix-graph-from-dataset
Browse files Browse the repository at this point in the history
topologic.io.from_dataset ignoring empty directed graphs and creating undirected instead
  • Loading branch information
Dwayne Pryce committed Feb 27, 2020
2 parents a0c1d07 + 337e00e commit 0c9ed07
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
4 changes: 4 additions & 0 deletions docs/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Notes

## 0.1.1
- [Issue 29](https://github.com/microsoft/topologic/issues/29) Fixed bug in `topologic.io.from_dataset` where an empty networkx graph object (Graph, DiGraph, etc) was being treated as if no networkx Graph object were provided at all.
- Added `is_digraph` parameter to `topologic.io.from_file`. This parameter defaults to False for original behavior. Setting it to True will create a networkx DiGraph object instead.

## 0.1.0
- Initial release

23 changes: 23 additions & 0 deletions tests/io/test_csv_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import unittest

import csv
import networkx as nx
from topologic.io import CsvDataset, from_dataset, from_file, load
from topologic import projection
from ..utils import data_file
Expand Down Expand Up @@ -141,6 +142,15 @@ def test_edge_then_vertex(self):
graph.nodes["frank"]["attributes"][0]
)

def test_digraph_from_dataset(self):
digraph = nx.DiGraph()
with open(data_file("tiny-graph.csv")) as edge_file:
dataset = CsvDataset(edge_file, True, "excel")
proj = projection.edge_ignore_metadata(1, 2, 4)
graph = from_dataset(dataset, proj, digraph)

self.assertEqual(digraph, graph)


class TestCsvLoaderFromFile(unittest.TestCase):
def test_invalid_projection_values(self):
Expand Down Expand Up @@ -313,3 +323,16 @@ def test_vertex_single_projection(self):
{"lastName": "redhot", "sandwichPreference": "buffalo chicken"},
graph.nodes["frank"]["attributes"][0]
)

def test_digraph_from_file(self):
with open(data_file("tiny-graph.csv")) as edge_file:
graph = from_file(
edge_csv_file=edge_file,
source_column_index=1,
target_column_index=2,
weight_column_index=4,
edge_csv_has_headers=True,
is_digraph=True
)

self.assertTrue(graph.is_directed())
9 changes: 6 additions & 3 deletions topologic/io/csv_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def from_dataset(
:return: the graph object
:rtype: nx.Graph
"""
if not graph:
if graph is None:
graph = nx.Graph()

projection_function = projection_function_generator(graph)
Expand All @@ -72,7 +72,8 @@ def from_file(
vertex_csv_use_headers: Optional[List[str]] = None,
vertex_metadata_behavior: str = "single",
vertex_ignored_values: Optional[List[str]] = None,
sample_size: int = 50
sample_size: int = 50,
is_digraph: bool = False,
) -> nx.Graph:
"""
This function weaves a lot of graph materialization code into a single call.
Expand Down Expand Up @@ -160,6 +161,7 @@ def from_file(
Please note that this sample_size does NOT advance your underlying iterator, nor is there any guarantee that
the csv Sniffer class will use every row extracted via sample_size. Setting this above 50 may not have the
impact you hope for due to the csv.Sniffer.has_header function - it will use at most 20 rows.
:param bool is_digraph: If the data represents an undirected graph or a directed graph. Default is `False`.
:return: The graph populated graph
:rtype: nx.Graph
"""
Expand Down Expand Up @@ -197,7 +199,8 @@ def from_file(
if edge_projection_function is None:
raise ValueError('edge_metadata_behavior must be "none", "collection", or "single"')

graph = from_dataset(edge_dataset, edge_projection_function)
graph = nx.DiGraph() if is_digraph else nx.Graph()
graph = from_dataset(edge_dataset, edge_projection_function, graph)

if vertex_csv_file:
if vertex_column_index is None:
Expand Down

0 comments on commit 0c9ed07

Please sign in to comment.