Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

population state models and after save

  • Loading branch information...
commit 2a8248244572f8ba58b035658a2ea0b2919347f1 1 parent 8021c20
@felixtsai authored
View
14 app/models/person.rb
@@ -1,3 +1,17 @@
class Person < ActiveRecord::Base
attr_accessible :height, :name, :sex, :weight
+
+ after_create :population_update
+
+
+ end
+
+ after_update
+
+ def population_update
+ @pop_state = PopulationState.first
+ if self.sex == "M"
+ pop_state.total_males += 1
+ end
+
end
View
43 app/models/population_state.rb
@@ -1,19 +1,46 @@
class PopulationState < ActiveRecord::Base
- attr_accessible :total_female_height, :total_female_weight, :total_females, :total_male_height, :total_male_weight, :total_males, :variance_height, :variance_weight
+ attr_accessible :total_female_height, :total_female_weight, :total_females, :total_male_height, :total_male_weight, :total_males
+ population_data = {male: {total: total_males, height: total_male_height, weight: total_male_weight},
+ female: {total: total_females, height: total_female_height, weight: total_female_weight}}
-
- def total_probability_male
- total_males/Person.count
+ def mean(gender, attribute)
+ population_data[gender][attribute]/attributes[gender][:total]
end
- def variance_height_male
- heights_male = Person.all.collect {|person| Person.height}
- 1/(total_males - 1) * heights_male.inject {|sum, height| sum + (height - total_male_height/total_males)**2}
+ def overall_prob(gender)
+ gender == :male ? total_males/Person.count : total_females/Person.count
end
- def probability_height_male
+ def variance(gender, attribute)
+ attribute_collection = []
+ Person.all.each do |person|
+ if person.sex == gender.to_s
+ attribute_collection << person.send(:attribute)
+ end
+ end
+ 1/(population_data[gender][:total] - 1) * attribute_collection.inject(0) {|sum, attrib| sum + (attrib - mean(gender, attribute))**2}
+ end
+ def attr_prob(gender, attribute)
+ (1/Math.sqrt(2*Math::PI*variance(gender, attribute)))**((-(6-mean(gender, attribute))**2)/2*variance(gender, attribute))
+ end
+
+ def posterior(gender)
+ overall_prob(gender)*attr_prob(gender, :height)*attr_prob(gender, :weight)
+ end
+ def guess
+ if total_males <= 1 || total_females <= 1
+ "Not enough information. Please enter more person data."
+ elsif posterior(:male) > posterior(:female)
+ "Our guess is male."
+ elsif
+ posterior(:female) > posterior(:male)
+ "Our guess is female."
+ else
+ "Equal probability. Flip a coin."
+ end
+ end
end
View
25 db/migrate/20121005215756_remove_total_female_height_from_population_state.rb
@@ -0,0 +1,25 @@
+class RemoveTotalFemaleHeightFromPopulationState < ActiveRecord::Migration
+ def up
+ remove_column :population_states, :total_female_height
+ remove_column :population_states, :total_male_height
+ remove_column :population_states, :total_female_weight
+ remove_column :population_states, :total_male_weight
+ remove_column :population_states, :total_females
+ remove_column :population_states, :total_males
+ remove_column :population_states, :variance_height
+ remove_column :population_states, :variance_weight
+
+ end
+
+ def down
+ add_column :population_states, :total_female_height, :integer
+ add_column :population_states, :total_male_height, :integer
+ add_column :population_states, :total_female_weight, :integer
+ add_column :population_states, :total_male_weight, :integer
+ add_column :population_states, :total_females, :integer
+ add_column :population_states, :total_males, :integer
+ add_column :population_states, :variance_height, :float
+ add_column :population_states, :variance_weight, :float
+
+ end
+end
View
10 db/migrate/20121005220654_add_total_females_to_population_state.rb
@@ -0,0 +1,10 @@
+class AddTotalFemalesToPopulationState < ActiveRecord::Migration
+ def change
+ add_column :population_states, :total_females, :integer, :default => 0
+ add_column :population_states, :total_males, :integer, :default => 0
+ add_column :population_states, :total_female_height, :integer, :default => 0
+ add_column :population_states, :total_male_height, :integer, :default => 0
+ add_column :population_states, :total_female_weight, :integer, :default => 0
+ add_column :population_states, :total_male_weight, :integer, :default => 0
+ end
+end
View
20 db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20121005020913) do
+ActiveRecord::Schema.define(:version => 20121005220654) do
create_table "guesses", :force => true do |t|
t.datetime "created_at", :null => false
@@ -32,16 +32,14 @@
end
create_table "population_states", :force => true do |t|
- t.integer "total_males"
- t.integer "total_females"
- t.integer "total_male_height"
- t.integer "total_female_height"
- t.integer "total_male_weight"
- t.integer "total_female_weight"
- t.float "variance_height"
- t.float "variance_weight"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.integer "total_females", :default => 0
+ t.integer "total_males", :default => 0
+ t.integer "total_female_height", :default => 0
+ t.integer "total_male_height", :default => 0
+ t.integer "total_female_weight", :default => 0
+ t.integer "total_male_weight", :default => 0
end
end
View
2  db/seeds.rb
@@ -5,3 +5,5 @@
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
+
+# @pop_state = PopulationState.find_or_create_by_id(1)
View
18 spec/models/population_state_spec.rb
@@ -1,5 +1,21 @@
require 'spec_helper'
describe PopulationState do
- pending "add some examples to (or delete) #{__FILE__}"
+
+ before :each do
+ Person.create(name: "Felix", height: 72, weight: 180)
+ Person.create(name: "David", height: 71, weight: 190)
+ Person.create(name: "Noah", height: 67, weight: 170)
+ Person.create(name: "Ivan", height: 71, weight: 165)
+ Person.create(name: "Jackie", height: 60, weight: 100)
+ Person.create(name: "Natasha", height: 65, weight: 150)
+ Person.create(name: "Khara", height: 65, weight: 130)
+ Person.create(name: "Jessie", height: 69, weight: 150)
+
+
+
+
+
+ it "should calculate mean"
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.