Commit 9978f619 authored by Coraline Ehmke's avatar Coraline Ehmke

Mercilessly pruning unused code

parent 99cf024d
......@@ -5,9 +5,7 @@ require 'fileutils'
require 'haml'
require_relative "snuffle/version"
require_relative "snuffle/analysis"
require_relative "snuffle/cohort"
require_relative "snuffle/cohort_detector"
require_relative "snuffle/cli"
require_relative "snuffle/formatters/base"
require_relative "snuffle/formatters/csv"
......@@ -16,11 +14,8 @@ require_relative "snuffle/formatters/html_index"
require_relative "snuffle/formatters/text"
require_relative "snuffle/node"
require_relative "snuffle/source_file"
require_relative "snuffle/source_parser"
require_relative "snuffle/summary"
require_relative "snuffle/elements/hash"
require_relative "snuffle/elements/string"
require_relative "snuffle/util/correlation"
require_relative "snuffle/util/histogram"
module Snuffle
......
module Snuffle
class Analysis
include PoroPlus
attr_accessor :source_file, :cohorts
end
end
\ No newline at end of file
......@@ -5,25 +5,28 @@ module Snuffle
include PoroPlus
attr_accessor :element, :neighbors
MAX_NEIGHBOR_DISTANCE = 3.0
def self.from(nodes)
Element::Hash.materialize(nodes.hashes.to_a).inject([]) do |cohorts, element|
cohort = Cohort.new(element: element)
cohorts << cohort if cohort.values.count > 1 && cohort.near_neighbors.count > 0
cohorts
end
end
def has_near_neighbors?
near_neighbors.present?
end
def near_neighbors
@near_neighbors ||= neighbors.select{|n| n.distance <= MAX_NEIGHBOR_DISTANCE && n.distance > 0}
@near_neighbors ||= neighbors.select{ |n| (n.values & values).size == values.size }
end
def neighbors
@neighbors ||= element.node.siblings.map do |sibling|
sibling_element = Element::Hash.materialize([sibling]).first
neighbor.new(sibling_element, distance(element.matrix, sibling_element.matrix))
end
@neighbors ||= element.node.siblings.map{|sibling| Element::Hash.materialize([sibling]).first}
end
def values
self.element.values.map(&:to_s).sort
@values ||= self.element.values
end
def neighbor
......
module Snuffle
class CohortDetector
attr_accessor :nodes
def initialize(input_nodes)
self.nodes = input_nodes
end
def cohorts
@cohorts ||= clusters.select{|cluster| cluster.has_near_neighbors?}.uniq(&:values)
end
private
def elements
@elements ||= [hashes, strings].flatten.compact
end
def clusters
clusters = []
elements.to_a.each do |outer_element|
cohort = Cohort.new(element: outer_element)
next unless cohort.values.count > 1
clusters << cohort if cohort.near_neighbors.count > 1
end
clusters
end
def hashes
Element::Hash.materialize(self.nodes.where(type: :hash).to_a.compact)
end
def strings
Element::String.materialize(self.nodes.where(type: :dstr).to_a.compact)
end
end
end
......@@ -15,7 +15,7 @@ module Snuffle
end
def pairs
@pairs ||= values.zip(keys).inject({}){|hash, pair| hash[pair[0]] = pair[1]; hash}
@pairs ||= keys.zip(values).inject({}){|hash, pair| hash[pair[0]] = pair[1]; hash}
end
def keys
......@@ -23,19 +23,11 @@ module Snuffle
end
def values
node.children.map{ |child| child.children.last && child.children.last.name }
end
def matrix
keys.map(&:to_s).sort.map(&:bytes).flatten
end
def sorted_pairs
keys.map(&:to_s).sort.inject({}) { |h, k| h[k] = pairs[k]; h}
node.children.map{ |child| child.children.last && child.children.last.name }.map(&:to_s).sort
end
def inspect
sorted_pairs
pairs
end
end
......
module Snuffle
module Element
class String
attr_accessor :node
def self.materialize(nodes=[])
nodes.each.map{|string_node| new(string_node) }
end
def initialize(node)
self.node = node
end
def values
node.children.map{ |child| child.children.last.name }.select{|v| v.is_a?(Symbol)}
end
def matrix
values.sort.map(&:hash)
end
def inspect
values
end
end
end
end
\ No newline at end of file
......@@ -14,7 +14,7 @@ module Snuffle
def export
table = ::Text::Table.new
table.head = header
table.rows = rows.present? && (rows.size == 3) && rows || [["", "", ""]]
table.rows = rows
table.to_s
end
......
......@@ -8,26 +8,19 @@ module Snuffle
attr_accessor :id, :name, :type, :child_ids, :parent_id
scope :by_id, lambda{|id| where(:id => id)}
scope :by_type, lambda{|type| where(:type => type) }
scope :by_type, lambda{|type| where(:type => type)}
scope :with_parent, lambda{|parent_id| where(parent_id: parent_id) }
scope :hashes, {type: :hash}
def self.nil
new(type: :nil)
end
def initialize(*args, &block)
@id = id
@id = SecureRandom.uuid
super
end
def id
@id ||= SecureRandom.uuid
end
def name
@name ||= @name.to_s.gsub(/[^a-zA-Z0-9\_]/,'').gsub(/[ ]+/, ' ').gsub(/\_+, '_'/, '_')
end
def parent
Snuffle::Node.where(id: self.parent_id).first
end
......
......@@ -19,7 +19,7 @@ module Snuffle
end
def object_candidates
@object_candidates ||= cohorts && cohorts.map(&:values) || []
@object_candidates ||= Cohort.from(self.nodes).map(&:values)
end
def summary
......@@ -56,13 +56,8 @@ module Snuffle
end
end
def cohorts
@cohorts ||= CohortDetector.new(self.nodes).cohorts
end
def ast
@ast ||= Parser::CurrentRuby.parse(source)
@ast
end
def extract_nodes_from(ast_node, nodes=Ephemeral::Collection.new("Snuffle::Node"), parent_id=:root)
......@@ -91,7 +86,7 @@ module Snuffle
return node unless node.respond_to?(:children)
if node.respond_to?(:loc) && node.loc.respond_to?(:name)
name_coords = node.loc.name
name = source[name_coords.begin_pos, [name_coords.end_pos - 1, 20].max]
name = source[name_coords.begin_pos, name_coords.end_pos - 1]
return unless name =~ /[a-zA-Z]/
return name
else
......
module Snuffle
class SourceParser
attr_accessor :source_files, :reports
def initialize(files=[])
@source_files = [files].flatten.map{ |file| Snuffle::SourceFile.new(path_to_file: file) }
end
def cohorts_from(source_file)
CohortDetector.new(source_file.nodes).cohorts
end
def report
@reports ||= source_files.map do |source_file|
{
source_file: source_file.path_to_file,
object_candidates: cohorts_from(source_file).map(&:values)
}
end
end
end
end
\ No newline at end of file
module Snuffle
class Summary
include PoroPlus
attr_accessor :class_name, :path_to_file, :object_candidates, :source
def class_filename
self.class_name.downcase.gsub(/[^a-zA-Z0-9]/, '_').gsub('__', '_')
end
attr_accessor :class_name, :path_to_file, :object_candidates
end
end
\ No newline at end of file
module Snuffle
module Util
module Correlation
def self.distance(primary, secondary)
sum = 0.0
primary.each_index{ |i| sum += primary[i] * (secondary[i] || 0) }
xymean = sum / primary.size.to_f
xmean = mean(primary)
ymean = mean(secondary)
xsigma = sigma(primary)
ysigma = sigma(secondary)
(xymean - (xmean * ymean)) / (xsigma * ysigma)
end
def self.mean(x=[])
return 0 if x.size == 0
x.reduce(:+).to_f / x.size
end
def self.sigma(x)
Math.sqrt(variance(x))
end
def self.variance(x)
m = mean(x)
sum = 0.0
x.each{ |v| sum += (v-m)**2 }
sum / x.size
end
end
end
end
\ No newline at end of file
......@@ -20,7 +20,7 @@ class Customer
end
def neighborhood
# make_neighborhood_api_call(state: self.state, city: self.city, postal_code: self.postal_code)
make_neighborhood_api_call(state: self.state, city: self.city, postal_code: self.postal_code)
end
def something_else
......
require 'spec_helper'
require 'pry'
describe Snuffle::Element::Hash do
let(:hash) { Snuffle::Element::Hash.new(nil) }
describe "#pairs" do
it "creates hash pairs from its keys and values" do
expect(hash).to receive(:keys) {[:foo, :bar]}
expect(hash).to receive(:values) {[1, 2]}
expect(hash.pairs).to eq({foo: 1, bar: 2})
end
end
end
\ No newline at end of file
......@@ -18,7 +18,6 @@ describe Snuffle::SourceFile do
it "does not match hash values with non-hash values" do
args = ['city', 'postal_code', 'state']
values = program_2.summary.object_candidates
p values
expect(values.include?(args)).to be_falsey
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment