answer-factory 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.13
1
+ 0.0.14
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{answer-factory}
8
- s.version = "0.0.13"
8
+ s.version = "0.0.14"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bill Tozier", "Trek Glowacki", "Jesse Sielaff"]
@@ -5,7 +5,7 @@ module AnswerFactory
5
5
  attr_reader :name
6
6
  attr_reader :nudge_instructions
7
7
  attr_reader :nudge_types
8
- attr_reader :couchdb_server
8
+ attr_reader :couchdb_server, :couchdb_name
9
9
  attr_accessor :workstation_names
10
10
  attr_reader :original_options_hash
11
11
 
@@ -21,11 +21,17 @@ module AnswerFactory
21
21
  configatron.factory.retrieve(:workstation_names, nil) ||
22
22
  Array.new
23
23
 
24
+
24
25
  # CouchDB settings
25
26
  @couchdb_server = options[:couchdb_server] ||
26
27
  configatron.factory.couchdb.retrieve(:server, nil) ||
27
28
  "http://127.0.0.1:5984"
28
29
 
30
+ @couchdb_name = options[:couchdb_name] ||
31
+ configatron.factory.couchdb.retrieve(:name, nil) ||
32
+ @name
33
+
34
+
29
35
  # Nudge language settings
30
36
  @nudge_instructions = options[:nudge_instructions] ||
31
37
  configatron.nudge.instructions.retrieve(:all, nil) ||
@@ -47,10 +53,11 @@ module AnswerFactory
47
53
  configatron.nudge.types.all = @nudge_types
48
54
  configatron.factory.workstation_names = @workstation_names
49
55
  configatron.factory.couchdb.server = @couchdb_server
56
+ configatron.factory.couchdb.name = @couchdb_name
50
57
  end
51
58
 
52
59
 
53
- def couch_available?
60
+ def self.couch_available?
54
61
  open(configatron.factory.couchdb.server).status
55
62
  true
56
63
  rescue StandardError
@@ -1,19 +1,16 @@
1
1
  module AnswerFactory
2
2
 
3
3
  class Workstation
4
- attr_reader :name, :capacity, :couchdb_uri, :factory_name
4
+ attr_reader :name, :capacity, :factory_name
5
5
  attr_accessor :downstream_stations
6
6
  attr_accessor :answers
7
- attr_accessor :build_sequence
8
7
 
9
8
 
10
9
  def initialize(name, options = {})
11
10
  raise ArgumentError, "#{name} is not a Symbol" unless name.kind_of?(Symbol)
12
11
  @name = name
13
- @factory_name = options[:factory_name] || 'factory_name'
14
- @couchdb_uri = options[:couchdb_uri] || "http://127.0.0.1:5984/#{@factory_name}"
12
+ @factory_name = configatron.factory.name
15
13
  @capacity = options[:capacity] || 100
16
- @build_sequence = options[:build_sequence] || Array.new
17
14
  @downstream_stations = Array.new
18
15
  @answers = Batch.new
19
16
  end
@@ -25,9 +22,21 @@ module AnswerFactory
25
22
  which.add_tag(where)
26
23
  end
27
24
 
25
+ def couchdb_uri
26
+ "#{configatron.factory.couchdb.server}/#{configatron.factory.couchdb.name}"
27
+ end
28
+
29
+
30
+ def receive!
31
+ # Workstation is a superclass; the default behavior (doing nothing)
32
+ # should be overridden in a subclass definition
33
+ end
34
+
28
35
 
29
36
  def gather_mine
30
- @answers += Batch.load_from_couch(@couchdb_uri, "#{name}/current")
37
+ gathered = Batch.load_from_couch(couchdb_uri, "#{name}/current")
38
+ puts "gathered: #{gathered.class}"
39
+ @answers = gathered
31
40
  end
32
41
 
33
42
 
@@ -72,11 +81,17 @@ module AnswerFactory
72
81
  end
73
82
 
74
83
 
84
+ def after_cycle!
85
+ @answers.bulk_save!(couchdb_uri)
86
+ @answers = Batch.new
87
+ end
88
+
75
89
  def cycle
76
90
  self.receive!
77
91
  self.build!
78
92
  self.ship!
79
93
  self.scrap!
94
+ self.after_cycle!
80
95
  end
81
96
  end
82
97
  end
@@ -1,4 +1,5 @@
1
1
  module AnswerFactory
2
+
2
3
  class AllDuplicatedGenomesSampler < Sampler
3
4
  def generate(crowd)
4
5
  result = Batch.new
@@ -11,4 +12,5 @@ module AnswerFactory
11
12
  return result
12
13
  end
13
14
  end
15
+
14
16
  end
@@ -1,5 +1,6 @@
1
1
  module AnswerFactory
2
2
  class ProgramPointEvaluator < Evaluator
3
+
3
4
  def evaluate(batch)
4
5
  raise(ArgumentError, "Can only evaluate a Batch of Answers") if !batch.kind_of?(Batch)
5
6
  batch.each do |i|
@@ -10,5 +11,8 @@ module AnswerFactory
10
11
  end
11
12
  end
12
13
  end
14
+
15
+ alias generate evaluate
16
+
13
17
  end
14
18
  end
@@ -9,6 +9,10 @@ describe "Factory" do
9
9
  end
10
10
 
11
11
  describe "Factory.new should have reasonable default values" do
12
+ before(:each) do
13
+ configatron.reset!
14
+ end
15
+
12
16
  it "should use 'my_factory' for #name" do
13
17
  f1 = Factory.new
14
18
  f1.name.should == "my_factory"
@@ -24,6 +28,12 @@ describe "Factory" do
24
28
  f1.couchdb_server.should == 'http://127.0.0.1:5984'
25
29
  end
26
30
 
31
+ it "should use self.name for #couchdb_name" do
32
+ f1 = Factory.new(name:"bob")
33
+ f1.couchdb_name.should == f1.name
34
+ end
35
+
36
+
27
37
  it "should use Nudge::Instruction.all_instructions for #nudge_instructions" do
28
38
  f1 = Factory.new
29
39
  f1.nudge_instructions.should == Instruction.all_instructions
@@ -77,6 +87,13 @@ describe "Factory" do
77
87
  end
78
88
  end
79
89
 
90
+ it "should hit configatron for #couchdb_name" do
91
+ configatron.temp do
92
+ configatron.factory.couchdb.name = "succotash"
93
+ f1 = Factory.new
94
+ f1.couchdb_name.should == "succotash"
95
+ end
96
+ end
80
97
  end
81
98
 
82
99
 
@@ -106,6 +123,11 @@ describe "Factory" do
106
123
  Factory.new(couchdb_server:"http://127.0.0.1:9999")
107
124
  configatron.factory.couchdb.server.should == "http://127.0.0.1:9999"
108
125
  end
126
+
127
+ it "should overwrite #factory.couchdb.server" do
128
+ Factory.new(couchdb_name:"miss_jackson")
129
+ configatron.factory.couchdb.name.should == "miss_jackson"
130
+ end
109
131
  end
110
132
  end
111
133
 
@@ -120,14 +142,14 @@ describe "Factory" do
120
142
 
121
143
  it "should have a method to check that couchDB is accessible" do
122
144
  f1 = Factory.new(name:"boo")
123
- lambda{f1.couch_available?}.should_not raise_error
145
+ lambda{Factory.couch_available?}.should_not raise_error
124
146
  end
125
147
 
126
148
  it "should return true if the uri is reachable" do
127
149
  uri = "http://mycouch.db/boo"
128
150
  f1 = Factory.new(name:"boo", couchdb_server:uri)
129
151
  FakeWeb.register_uri(:any, uri, :body => "We are here!", :status => [200, "OK"])
130
- f1.couch_available?.should == true
152
+ Factory.couch_available?.should == true
131
153
  end
132
154
 
133
155
  it "should return false if the uri is offline or 404's out" do
@@ -135,23 +157,10 @@ describe "Factory" do
135
157
  f1 = Factory.new(name:"boo", couchdb_server:uri)
136
158
  FakeWeb.register_uri(:any, "http://mycouch.db/boo",
137
159
  :body => "Go away!", :status => [404, "Not Found"])
138
- f1.couch_available?.should == false
160
+ Factory.couch_available?.should == false
139
161
 
140
162
  f1 = Factory.new(name:"boo", couchdb_server:"http://127.0.0.1:9991/place")
141
- f1.couch_available?.should == false
142
- end
143
- end
144
-
145
-
146
- describe "database setup" do
147
- describe "paths" do
148
- it "should have reasonable defaults"
149
-
150
- describe "setting from file" do
151
- it "should populate configatron.main_database.db_root"
152
-
153
- it "should populate configatron.main_database.db_name"
154
- end
163
+ Factory.couch_available?.should == false
155
164
  end
156
165
  end
157
166
  end
@@ -2,8 +2,7 @@ require File.join(File.dirname(__FILE__), "./../spec_helper")
2
2
 
3
3
 
4
4
  describe "Workstation" do
5
-
6
- describe "names" do
5
+ describe "#name" do
7
6
  it "should have a name" do
8
7
  Workstation.new(:my_workthing).name.should == :my_workthing
9
8
  end
@@ -14,26 +13,14 @@ describe "Workstation" do
14
13
  end
15
14
 
16
15
  it "should have a factory_name" do
17
- Workstation.new(:ws).factory_name.should be_a_kind_of(String)
18
- end
19
-
20
- it "should have a default factory_name of 'factory_name'" do
21
- Workstation.new(:ws).factory_name.should == 'factory_name'
22
- end
23
-
24
- it "should be possible to set the factory_name via an initialization option" do
25
- Workstation.new(:ws, factory_name:'foo').factory_name.should == 'foo'
26
- end
27
- end
28
-
29
-
30
- describe "database" do
31
- it "should have a URI for a CouchDB instance" do
32
- Workstation.new(:ws).couchdb_uri.should be_a_kind_of(String)
16
+ Workstation.new(:ws).should respond_to(:factory_name)
33
17
  end
34
18
 
35
- it "should default to http://127.0.0.1:5984/\#{@factory_name}" do
36
- Workstation.new(:ws).couchdb_uri.should == "http://127.0.0.1:5984/factory_name"
19
+ it "should get factory_name from configatron" do
20
+ configatron.temp do
21
+ configatron.factory.name = 'somewhere_lovely'
22
+ Workstation.new(:ws).factory_name.should == 'somewhere_lovely'
23
+ end
37
24
  end
38
25
  end
39
26
 
@@ -93,22 +80,42 @@ describe "Workstation" do
93
80
 
94
81
 
95
82
  describe "#cycle" do
83
+ before(:each) do
84
+ FakeWeb.register_uri(:any, "http://127.0.0.1:5984/this_factory/_bulk_docs",
85
+ :body => @canned, :status => [200, "OK"])
86
+ end
96
87
 
97
88
  describe "the #before_cycle method" do
98
89
  it "should empty @answers"
99
90
  end
100
91
 
101
92
  it "should invoke #receive!, #build!, #ship! and #scrap!" do
102
- w1 = Workstation.new(:place)
103
- w1.should_receive(:receive!)
104
- w1.should_receive(:build!)
105
- w1.should_receive(:ship!)
106
- w1.should_receive(:scrap!)
107
- w1.cycle
93
+ configatron.temp do
94
+ configatron.factory.couchdb.server = "http://127.0.0.1:5984"
95
+ configatron.factory.couchdb.name = "this_factory"
96
+
97
+ w1 = Workstation.new(:this_factory)
98
+ w1.stub!(:after_cycle!)
99
+ w1.should_receive(:receive!)
100
+ w1.should_receive(:build!)
101
+ w1.should_receive(:ship!)
102
+ w1.should_receive(:scrap!)
103
+ w1.cycle
104
+ end
108
105
  end
109
106
 
110
107
  describe "the #after_cycle method" do
111
- it "should save everything in @answers to the persistent store"
108
+ it "should save everything in @answers to the persistent store" do
109
+ configatron.temp do
110
+ configatron.factory.couchdb.server = "http://127.0.0.1:5984"
111
+ configatron.factory.couchdb.name = "this_factory"
112
+
113
+ FakeWeb.allow_net_connect = false
114
+ @w1 = Workstation.new(:ws1, factory_name:"this_factory")
115
+ @w1.answers.should_receive(:bulk_save!)
116
+ @w1.after_cycle!
117
+ end
118
+ end
112
119
  end
113
120
 
114
121
  describe "#receive!" do
@@ -119,6 +126,7 @@ describe "Workstation" do
119
126
  describe "gather_mine" do
120
127
  before(:each) do
121
128
  @w1 = Workstation.new(:ws1, factory_name:"this_factory")
129
+
122
130
  @uri = "http://127.0.0.1:5984/this_factory"
123
131
  @design_doc = "ws1/current" # we'll assume this has been set up!
124
132
  @view_uri = "http://127.0.0.1:5984/this_factory/_design/ws1/_view/current"
@@ -127,17 +135,27 @@ describe "Workstation" do
127
135
  end
128
136
 
129
137
  it "should use the Batch#load_from_couch method" do
130
- FakeWeb.register_uri(:any, @view_uri, :body => @canned, :status => [200, "OK"])
131
- Batch.should_receive(:load_from_couch).with(@uri,@design_doc).and_return(Batch.new)
132
- @w1.gather_mine
138
+ configatron.temp do
139
+ configatron.factory.couchdb.server = "http://127.0.0.1:5984"
140
+ configatron.factory.couchdb.name = "this_factory"
141
+
142
+ FakeWeb.register_uri(:any, @view_uri, :body => @canned, :status => [200, "OK"])
143
+ Batch.should_receive(:load_from_couch).with(@uri,@design_doc).and_return(Batch.new)
144
+ @w1.gather_mine
145
+ end
133
146
  end
134
147
 
135
148
  it "should add that Batch into self#answers" do
136
- FakeWeb.register_uri(:any, @view_uri, :body => @canned, :status => [200, "OK"])
137
- @w1.answers.length.should == 0
138
- @w1.gather_mine
139
- @w1.answers.length.should == 1
140
- @w1.answers[0].scores[:badness].should == 12.345
149
+ configatron.temp do
150
+ configatron.factory.couchdb.server = "http://127.0.0.1:5984"
151
+ configatron.factory.couchdb.name = "this_factory"
152
+
153
+ FakeWeb.register_uri(:any, @view_uri, :body => @canned, :status => [200, "OK"])
154
+ @w1.answers.length.should == 0
155
+ @w1.gather_mine
156
+ @w1.answers.length.should == 1
157
+ @w1.answers[0].scores[:badness].should == 12.345
158
+ end
141
159
  end
142
160
  end
143
161
 
@@ -39,5 +39,10 @@ describe ProgramPointEvaluator do
39
39
  @ppe.evaluate(@dudes)
40
40
  @dudes.each {|dude| origIDs.should include(dude.object_id)}
41
41
  end
42
+
43
+ it "should return a Batch" do
44
+ @ppe.evaluate(@dudes).should be_a_kind_of(Batch)
45
+ end
46
+
42
47
  end
43
48
  end
@@ -56,5 +56,10 @@ describe "PointCrossoverOperator" do
56
56
  babies = @myXover.generate([@dude1, @dude2],10)
57
57
  babies.each {|baby| [8,12].should include(baby.progress)}
58
58
  end
59
+
60
+ it "should return a Batch" do
61
+ babies = @myXover.generate(Batch.[](@dude1, @dude2))
62
+ babies.should be_a_kind_of(Batch)
63
+ end
59
64
  end
60
65
  end
@@ -1,4 +1,6 @@
1
1
  require 'answer-factory'
2
+ include Nudge
3
+ include AnswerFactory
2
4
 
3
5
  ####
4
6
  ####
@@ -6,16 +8,91 @@ require 'answer-factory'
6
8
  ####
7
9
  ####
8
10
 
9
- # Nudge language extensions:
11
+
12
+ #### CouchDB access:
13
+ configatron.factory.couchdb.server = 'http://127.0.0.1:5984'
14
+
15
+ #### Factory settings:
16
+ configatron.factory.name = 'my_factory'
17
+
18
+ #### Workstation definitions:
19
+ configatron.project.workstations.path = '/lib/factory/workstations/*'
20
+
21
+ #### Nudge language extensions:
10
22
  configatron.project.nudge.instructions.path = '/lib/nudge/instructions/*'
11
23
  configatron.project.nudge.types.path = '/lib/nudge/types/*'
12
24
 
13
25
 
26
+
27
+ #### normally these should be in /lib/factory/workstations/**
28
+
29
+ class GeneratorStation < Workstation
30
+ attr_reader :random_program_maker
31
+
32
+ def initialize(name, options = {})
33
+ super
34
+ @random_program_maker = RandomGuessOperator.new(how_many:10)
35
+ end
36
+
37
+ def build!
38
+ process_with @random_program_maker
39
+ end
40
+
41
+ def ship!
42
+ ship_to(:breeder) {|answer| true}
43
+ end
44
+ end
45
+
46
+
47
+ class EvolverStation < Workstation
48
+ attr_reader :my_crossover_operator
49
+ attr_reader :my_length_evaluator
50
+
51
+ def initialize(name, options = {})
52
+ super
53
+ @my_crossover_operator = PointCrossoverOperator.new
54
+ @my_length_evaluator = ProgramPointEvaluator.new(score_label:"length")
55
+ end
56
+
57
+ def receive!
58
+ gather_mine
59
+ end
60
+
61
+ def build!
62
+ process_with @my_crossover_operator
63
+ # process_with @my_length_evaluator
64
+ end
65
+
66
+ def scrap!
67
+ @highest_progress = (@answers.collect {|a| a.progress}).max
68
+ scrap_if("too_old") {|a| a.progress < @highest_progress}
69
+ end
70
+ end
71
+
72
+
14
73
  ####
15
74
  ####
16
- #### DON'T EDIT PAST THIS POINT
75
+ #### DON'T EDIT BEYOND THIS POINT
17
76
  ####
18
77
  ####
19
78
 
79
+ # extend Nudge
20
80
  Dir.glob(File.dirname(__FILE__) + configatron.project.nudge.instructions.path) {|file| require file}
21
- Dir.glob(File.dirname(__FILE__) + configatron.project.nudge.types.path) {|file| require file}
81
+ Dir.glob(File.dirname(__FILE__) + configatron.project.nudge.types.path) {|file| require file}
82
+
83
+ # confirm database access
84
+ raise "CouchDB not available at #{configatron.factory.couchdb.server}" unless
85
+ Factory.couch_available?()
86
+
87
+ # extend Workstation
88
+ Dir.glob(File.dirname(__FILE__) + configatron.project.workstations.path) {|file| require file}
89
+
90
+
91
+ project = Factory.new
92
+ workstations = [GeneratorStation.new(:maker), EvolverStation.new(:breeder)]
93
+
94
+ 10.times do
95
+ workstations.each do |ws|
96
+ ws.cycle
97
+ end
98
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 13
9
- version: 0.0.13
8
+ - 14
9
+ version: 0.0.14
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bill Tozier