-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b8c2b80
commit e02565e
Showing
3 changed files
with
141 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
module BrighterPlanet | ||
module Flight | ||
module ImpactModel | ||
class FuelUseEquation | ||
class Derived < FuelUseEquation | ||
def initialize(flight_segments) | ||
@where_sql = flight_segments.where_sql | ||
end | ||
|
||
def m3 | ||
calculate! | ||
@m3 | ||
end | ||
|
||
def m2 | ||
calculate! | ||
@m2 | ||
end | ||
|
||
def m1 | ||
calculate! | ||
@m1 | ||
end | ||
|
||
def b | ||
calculate! | ||
@b | ||
end | ||
|
||
private | ||
|
||
def calculate! | ||
return if @calculated == true | ||
@calculated = true | ||
raise ArgumentError if @where_sql.blank? | ||
|
||
# - Create a temporary table to hold the values we need | ||
c = ::ActiveRecord::Base.connection | ||
|
||
table_name = "flight_fuel_use_coefficients_#{::Kernel.rand(1e11)}" | ||
|
||
create_table_sql = %{ | ||
CREATE TEMPORARY TABLE #{table_name} ( | ||
description VARCHAR(255), | ||
m3 FLOAT, | ||
m2 FLOAT, | ||
m1 FLOAT, | ||
b FLOAT, | ||
passengers INT | ||
) | ||
} | ||
|
||
# make this run faster if you're on mysql | ||
create_table_sql << 'ENGINE=MEMORY' if c.adapter_name =~ /mysql/i | ||
|
||
c.execute create_table_sql | ||
|
||
# - Look up the unique aircraft descriptions in `@where_sql` | ||
aircraft_descriptions = c.select_values %{ | ||
SELECT DISTINCT aircraft_description | ||
FROM #{::FlightSegment.quoted_table_name} | ||
#{@where_sql} | ||
} | ||
|
||
# - For each unique aircraft description: | ||
# - 1. look up all the aircraft it refers to | ||
# - 2. average those aircraft's fuel use coefficients | ||
# - 3. store the resulting values in the temporary table along with the unique aircraft_description | ||
c.execute %{ | ||
INSERT INTO #{table_name} (description, m3, m2, m1, b) | ||
SELECT t1.b, AVG(t2.m3), AVG(t2.m2), AVG(t2.m1), AVG(t2.b) | ||
FROM #{::FuzzyMatch::CachedResult.quoted_table_name} AS t1 | ||
INNER JOIN #{::Aircraft.quoted_table_name} AS t2 | ||
ON t1.a = t2.description | ||
WHERE t1.b IN ('#{aircraft_descriptions.join("', '")}') | ||
GROUP BY t1.b | ||
} | ||
|
||
# - For each unique aircraft description: | ||
# - 1. look up all the flight segments in `@where_sql` that match the aircraft description | ||
# - 2. sum passengers across those flight segments | ||
# - 3. store the resulting value in the temporary table | ||
c.execute %{ | ||
UPDATE #{table_name} | ||
SET passengers = ( | ||
SELECT SUM(passengers) | ||
FROM #{::FlightSegment.quoted_table_name} | ||
#{@where_sql} AND #{::FlightSegment.quoted_table_name}.aircraft_description = #{table_name}.description | ||
) | ||
} | ||
|
||
# - Calculate the average of the coefficients in the temporary table, weighted by passengers | ||
row = c.select_one %{ | ||
SELECT | ||
SUM(1.0 * m3 * passengers)/SUM(passengers) AS a_m3, | ||
SUM(1.0 * m2 * passengers)/SUM(passengers) AS a_m2, | ||
SUM(1.0 * m1 * passengers)/SUM(passengers) AS a_m1, | ||
SUM(1.0 * b * passengers)/SUM(passengers) AS a_b | ||
FROM #{table_name} | ||
WHERE | ||
m3 IS NOT NULL | ||
AND m2 IS NOT NULL | ||
AND m1 IS NOT NULL | ||
AND b IS NOT NULL | ||
AND passengers > 0 | ||
} | ||
|
||
@m3, @m2, @m1, @b = row['a_m3'], row['a_m2'], row['a_m1'], row['a_b'] | ||
|
||
c.execute %{ | ||
DROP TABLE #{table_name} | ||
} | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module BrighterPlanet | ||
module Flight | ||
module ImpactModel | ||
class FuelUseEquation | ||
class Given < FuelUseEquation | ||
attr_reader :m3, :m2, :m1, :b | ||
def initialize(m3, m2, m1, b) | ||
@m3 = m3 | ||
@m2 = m2 | ||
@m1 = m1 | ||
@b = b | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |