graphs 0.1.1-x86-linux → 0.1.2-x86-linux
Sign up to get free protection for your applications and to get access to all the features.
- 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
|