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 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
- if ((has_ext.length == 1) || (has_ext[-1] == 'yml'))
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+'.yml', 'w')
93
+ f = open(filename, 'w')
68
94
  f.write(data)
69
95
  f.close
70
96
  else
71
- ext = has_ext[-1]
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
- def _write_gdf(filename, opts=nil)
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
- # read the value of a node|edge field, and return the value's type (String)
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 (node|edge)def, and return ['label', 'type of value']
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.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-02 00:00:00.000000000 Z
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