answer-factory 0.0.13 → 0.0.14

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/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