graphs 0.1.1-x86-linux → 0.1.2-x86-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/graph.rb +30 -10
- data/lib/graphs/gdf.rb +24 -3
- data/tests/tests_graph.rb +31 -2
- metadata +2 -2
data/lib/graph.rb
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
|
+
# A graph with nodes and edges
|
5
6
|
class Graph
|
6
7
|
|
8
|
+
# An array of nodes, each node is an hash of label/value paires
|
7
9
|
class NodeArray < Array
|
8
10
|
|
9
11
|
def initialize(*args)
|
@@ -11,6 +13,10 @@ class Graph
|
|
11
13
|
@defaults = {}
|
12
14
|
end
|
13
15
|
|
16
|
+
# Set some default values for current elements.
|
17
|
+
# @note This method can be called multiple times.
|
18
|
+
# @example Set all nodes's 'created-at' value to '2012-05-03'
|
19
|
+
# myNodeList.set_default({'created-at'=>'2012-05-03'})
|
14
20
|
def set_default(dict)
|
15
21
|
@defaults.update(dict)
|
16
22
|
self.map! { |e| e.update(@defaults) }
|
@@ -22,20 +28,26 @@ class Graph
|
|
22
28
|
end
|
23
29
|
o2 = o.clone
|
24
30
|
o2.update(@defaults)
|
25
|
-
super
|
31
|
+
super(o2)
|
26
32
|
end
|
27
33
|
end
|
28
34
|
|
35
|
+
# An array of edges, each edge is an hash of label/value paires
|
29
36
|
class EdgeArray < NodeArray
|
30
37
|
end
|
31
38
|
|
32
39
|
attr_accessor :nodes, :edges
|
33
40
|
|
41
|
+
# @param nodes [Array] Nodes of the graph
|
42
|
+
# @param edges [Array] Edges of the graph
|
34
43
|
def initialize(nodes=nil, edges=nil)
|
35
44
|
@nodes = NodeArray.new(nodes || [])
|
36
45
|
@edges = EdgeArray.new(edges || [])
|
37
46
|
end
|
38
47
|
|
48
|
+
# Test if current graph has same nodes and edges as the other
|
49
|
+
# graph.
|
50
|
+
# @param other [Graph]
|
39
51
|
def ==(other)
|
40
52
|
if (!other.is_a?(Graph))
|
41
53
|
return false
|
@@ -43,6 +55,10 @@ class Graph
|
|
43
55
|
(self.nodes === other.nodes) && (self.edges == other.edges)
|
44
56
|
end
|
45
57
|
|
58
|
+
# Perform an intersection between the current graph and the other.
|
59
|
+
# Returns a new Graph which nodes are both in the current graph and
|
60
|
+
# the other (idem for edges).
|
61
|
+
# @param other [Graph]
|
46
62
|
def &(other)
|
47
63
|
if (!other.is_a?(Graph))
|
48
64
|
return nil
|
@@ -54,27 +70,31 @@ class Graph
|
|
54
70
|
Graph.new(nodes, edges)
|
55
71
|
end
|
56
72
|
|
73
|
+
# Write the current Graph into a file.
|
74
|
+
# @param filename [String] A valid filename
|
75
|
+
# @param opts [Hash] A customizable set of options
|
76
|
+
# @option opts [Boolean] :gephi Should be <tt>true</tt> if the file will be used with Gephi.
|
57
77
|
def write(filename, opts=nil)
|
58
78
|
|
59
79
|
has_ext = filename.split('.')
|
80
|
+
ext = (has_ext.length>1) ? has_ext[-1] : 'unknow'
|
60
81
|
|
61
|
-
|
82
|
+
m = (self.methods - Object.methods).map {|e| e.to_s}
|
83
|
+
|
84
|
+
if (m.include? 'write_'+ext.downcase)
|
85
|
+
self.send('write_'+ext.downcase, filename, opts)
|
86
|
+
|
87
|
+
elsif (ext == 'unknow' || ext == 'yml')
|
62
88
|
# YAML (default)
|
63
89
|
nodes = self.nodes.to_a
|
64
90
|
edges = self.edges.to_a
|
65
91
|
|
66
92
|
data = {'nodes'=>nodes, 'edges'=>edges}.to_yaml
|
67
|
-
f = open(filename
|
93
|
+
f = open(filename, 'w')
|
68
94
|
f.write(data)
|
69
95
|
f.close
|
70
96
|
else
|
71
|
-
ext
|
72
|
-
|
73
|
-
m = (self.methods - Object.methods).map {|e| e.to_s}
|
74
|
-
|
75
|
-
if (m.include? '_write_'+ext.downcase)
|
76
|
-
self.send('_write_'+ext.downcase, filename, opts)
|
77
|
-
end
|
97
|
+
raise NoMethodError.new("No method to handle #{ext} file extension.")
|
78
98
|
end
|
79
99
|
|
80
100
|
end
|
data/lib/graphs/gdf.rb
CHANGED
@@ -3,11 +3,18 @@
|
|
3
3
|
require_relative '../graph'
|
4
4
|
|
5
5
|
class Graph
|
6
|
+
# Returns a GDF version of the current graph
|
7
|
+
# @param opts [Hash] A customizable set of options
|
8
|
+
# @see GDF::unparse
|
6
9
|
def to_gdf(opts=nil)
|
7
10
|
GDF::unparse(self, opts)
|
8
11
|
end
|
9
12
|
|
10
|
-
|
13
|
+
# Write the current graph into a GDF file. This method is used internally,
|
14
|
+
# use Graph#write instead.
|
15
|
+
# @param filename [String] a valid filename
|
16
|
+
# @see GDF::unparse
|
17
|
+
def write_gdf(filename, opts=nil)
|
11
18
|
gdf = GDF::unparse(self, opts)
|
12
19
|
f = File.open(filename, 'w')
|
13
20
|
f.write(gdf)
|
@@ -15,12 +22,20 @@ class Graph
|
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
25
|
+
# GDF-related functions
|
18
26
|
module GDF
|
19
27
|
|
28
|
+
# Loads a GDF file and return a new Graph object
|
29
|
+
# @param filename [String] a valid filename
|
30
|
+
# @see GDF::parse
|
20
31
|
def self.load(filename)
|
21
32
|
self.parse(File.read(filename))
|
22
33
|
end
|
23
34
|
|
35
|
+
# Parse some GDF text and return a new Graph object
|
36
|
+
# @param content [String] a valid GDF String
|
37
|
+
# @see GDF::load
|
38
|
+
# @see GDF::unparse
|
24
39
|
def self.parse(content)
|
25
40
|
|
26
41
|
if (content.nil? || content.length == 0)
|
@@ -99,6 +114,10 @@ module GDF
|
|
99
114
|
Graph.new(nodes, edges)
|
100
115
|
end
|
101
116
|
|
117
|
+
# Return a GDF String which describe the given Graph
|
118
|
+
# @param graph [Graph]
|
119
|
+
# @param opts [Hash] A customizable set of options
|
120
|
+
# @see Graph#write
|
102
121
|
def self.unparse(graph, opts=nil)
|
103
122
|
|
104
123
|
# nodes
|
@@ -138,7 +157,8 @@ module GDF
|
|
138
157
|
|
139
158
|
private
|
140
159
|
|
141
|
-
#
|
160
|
+
# Read the value of a node/edge field, and return the value's
|
161
|
+
# type (String)
|
142
162
|
def self.get_type(v, opts=nil)
|
143
163
|
opts = opts || {}
|
144
164
|
|
@@ -155,7 +175,8 @@ module GDF
|
|
155
175
|
end
|
156
176
|
end
|
157
177
|
|
158
|
-
# read a
|
178
|
+
# read a node/edge def, and return a list which first element is the
|
179
|
+
# label of the field, and the second is its type
|
159
180
|
def self.read_def(s)
|
160
181
|
*label, value_type = s.split /\s+/
|
161
182
|
if /((tiny|small|medium|big)?int|integer)/i.match(value_type)
|
data/tests/tests_graph.rb
CHANGED
@@ -21,6 +21,19 @@ class Graph_test < Test::Unit::TestCase
|
|
21
21
|
]
|
22
22
|
)
|
23
23
|
|
24
|
+
@@sample_graph_1 = Graph.new(
|
25
|
+
[
|
26
|
+
{'label'=>'bar', 'num'=>3},
|
27
|
+
{'label'=>'foo', 'num'=>42},
|
28
|
+
{'label'=>'chuck', 'num'=>78}
|
29
|
+
],
|
30
|
+
[
|
31
|
+
{'node1'=>'foo', 'node2'=>'bar', 'time'=>1.0},
|
32
|
+
{'node1'=>'bar', 'node2'=>'foo', 'time'=>2.5},
|
33
|
+
{'node1'=>'foo', 'node2'=>'chuck', 'time'=>3.1}
|
34
|
+
]
|
35
|
+
)
|
36
|
+
|
24
37
|
def test_new_empty_graph
|
25
38
|
g = Graph.new
|
26
39
|
|
@@ -102,8 +115,7 @@ class Graph_test < Test::Unit::TestCase
|
|
102
115
|
end
|
103
116
|
|
104
117
|
def test_edgearray_set_default_existing_property_before_push
|
105
|
-
g = Graph.new([],
|
106
|
-
[{'node1'=>'foo', 'node2'=>'bar', 'directed'=>true}])
|
118
|
+
g = Graph.new([], [{'node1'=>'foo', 'node2'=>'bar', 'directed'=>true}])
|
107
119
|
g.edges.set_default 'node2' => 'foo'
|
108
120
|
g.edges.push({'node1' => 'bar', 'node2' => 'foo'})
|
109
121
|
|
@@ -159,6 +171,14 @@ class Graph_test < Test::Unit::TestCase
|
|
159
171
|
assert_equal(nil, g & 'foo')
|
160
172
|
end
|
161
173
|
|
174
|
+
def test_AND_2_graphs_same_nodes_different_labels
|
175
|
+
g1 = @@sample_graph
|
176
|
+
g2 = @@sample_graph_1
|
177
|
+
empty = Graph.new
|
178
|
+
|
179
|
+
assert_equal(empty, g1 & g2)
|
180
|
+
end
|
181
|
+
|
162
182
|
# == Graph#write == #
|
163
183
|
|
164
184
|
def test_graph_write_no_ext
|
@@ -171,4 +191,13 @@ class Graph_test < Test::Unit::TestCase
|
|
171
191
|
assert_equal(g.nodes, dict['nodes'])
|
172
192
|
assert_equal(g.edges, dict['edges'])
|
173
193
|
end
|
194
|
+
|
195
|
+
def test_graph_write_unknow_ext
|
196
|
+
g = @@sample_graph
|
197
|
+
f = '/tmp/_graph_test.foo'
|
198
|
+
assert_raise(NoMethodError) do
|
199
|
+
g.write(f)
|
200
|
+
end
|
201
|
+
assert_equal(false, File.exists?(f))
|
202
|
+
end
|
174
203
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: x86-linux
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Provide functions to (un)parse GDF files and generate graphs
|
15
15
|
email: batifon@yahoo.fr
|