Skip to content

Commit

Permalink
Added huffman encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielleSucher committed May 11, 2012
1 parent 7814fce commit efddae7
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 17 deletions.
35 changes: 22 additions & 13 deletions honeytree-lib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
require 'pp'

class Honeytree
attr_accessor :client
attr_accessor :client, :trees, :percentages, :encoded

def initialize
@client = Mysql2::Client.new :host => "localhost", :username => "honey",
:password => "esther", :database => "honeytree"
@trees = {}
@percentages = {}
@encoded = []
end

def create_census_table
Expand Down Expand Up @@ -74,33 +77,39 @@ def find_nearby_trees(point, miles)
p.map! { |x| x = x.to_f }
m = miles.to_f
results = find_trees_in_square(p, m)
trees = {}
results.each do |row|
# puts row
pt = row["AsText(trees.latlong)"].gsub(/[^\d\s\.-]/, "").split(" ").map! { |x| x = x.to_f }
dist = haversine(p,pt)
if dist <= m
trees[row['name']] ||= 0
trees[row['name']] += 1
@trees[row['name']] ||= 0
@trees[row['name']] += 1
end
end
return trees
end

def radians(degrees)
degrees * Math::PI / 180
end

def find_tree_percentages(trees)
def find_tree_percentages
total = 0
percentages = {}
trees.each { |k,v| total += v }
trees.each do |k,v|
@trees.each { |k,v| total += v }
@trees.each do |k,v|
p = ((v * 100.0) / total).round(2)
percentages[k] = p if p >= 1
@percentages[k] = p if p >= 1
end
percentages['other'] = (100 - percentages.inject(0) { |res,(k,v)| res + v }).round(2)
return percentages
@percentages['other'] = (100 - @percentages.inject(0) { |res,(k,v)| res + v }).round(2)
end
end

def huffman_encode_trees
@encoded = @percentages.sort_by { |k,v| v }
until @encoded.length == 1
a,b = @encoded.shift, @encoded.shift
branch = [a, b, (a[-1] + b[-1]).round(2)]
@encoded.push branch
@encoded.sort! { |a,b| a[-1] <=> b[-1] }
end
@encoded = @encoded[0]
end
end
92 changes: 92 additions & 0 deletions honeytree-sample.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@

<html>
<head>
<link rel="stylesheet" type="text/css" href="honeytree.css" />
<script src="http://d3js.org/d3.v2.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<title>Honey!</title>
</head>
<body>
<script>
function codeAddress() {
var address = document.getElementById("address").value;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results[0]['geometry']['location']['$a']);
console.log(results[0]['geometry']['location']['ab']);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}

function inputFocus(i){
if(i.value=="enter your hive's NYC street address"){ i.value="";}
}
</script>
<div id="banner">
<a href="http://daniellesucher.com"><img src="banner.png" /></a>
</div>
<div>
<input id="address" type="textbox" value="enter your hive's NYC street address" onFocus="inputFocus(this)">
<input type="button" value="Geocode" onclick="codeAddress()">
</div>
<div id="chart"></div>
<script>
var data = [
{name: "Norway Maple", val: 23.6},
{name: "Callery Pear", val: 6.39},
{name: "Ginkgo", val: 2.72},
{name: "London Planetree", val: 17.84},
{name: "American Linden", val: 2.14},
{name: "Zelkova", val: 4.4},
{name: "Red Maple", val: 1.81},
{name: "Littleleaf Linden", val: 6.31},
{name: "Silver Maple", val: 2.66},
{name: "Green Ash", val: 3.05},
{name: "Honeylocust", val: 6.3},
{name: "Pin Oak", val: 6.16},
{name: "Flowering Cherry", val: 1.67},
{name: "Northern Red Oak", val: 1.37},
{name: "Japanese Pagoda Tree", val: 1.46},
{name: "Silver Linden", val: 1.6},
{name: "other", val: 10.52}
];

var w = 400,
h = 400,
r = Math.min(w, h) / 2,
labelr = r + 30, // radius for label anchor
color = d3.scale.category20c(),
donut = d3.layout.pie(),
arc = d3.svg.arc().innerRadius(r * 0.6).outerRadius(r),
pos = d3.svg.arc().innerRadius(r + 38).outerRadius(r + 38);

var vis = d3.select("#chart")
.append("svg:svg")
.data([data])
.attr("width", w + 300)
.attr("height", h + 50);

var arcs = vis.selectAll("g.arc")
.data(donut.value(function(d) { return d.val }))
.enter().append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (r + 150) + "," + r + ")");

arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);

arcs.append("text")
.attr("transform", function(d) { return "translate(" + pos.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("display", function(d) { return d.value > 3.0 ? null : "none"; })
.text(function(d, i) {
return d.data.name;
});
</script>
</body>
</html>
8 changes: 5 additions & 3 deletions honeytree-web.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
params = cgi.params

ht = Honeytree.new
percentages = ht.find_tree_percentages(ht.find_nearby_trees(params['address'][0], "1"))
ht.find_nearby_trees params['address'][0], "1"
ht.find_tree_percentages
ht.huffman_encode_trees

results = "["
percentages.each do |k,v|
ht.percentages.each do |k,v|
results.concat("{name: '#{k}', val: #{v}},")
end
results = results[0...-1] + "]"
Expand All @@ -35,4 +37,4 @@
<script type='text/javascript'>create_graph(#{results});</script>"
}
}
}
}
5 changes: 4 additions & 1 deletion honeytree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@

ht = Honeytree.new

pp ht.find_tree_percentages(ht.find_nearby_trees("40.6223262 -73.955483", "1")) # EMJC, of course
ht.find_nearby_trees("40.6223262 -73.955483", "1") # EMJC, of course
ht.find_tree_percentages
ht.huffman_encode_trees
pp ht.encoded
30 changes: 30 additions & 0 deletions spec/honeytree_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
$:.unshift File.expand_path('.')
require 'honeytree-lib'

def depth(tree)
if tree.class == Array
tree.map! do |node|
depth(node)
end
return 1 + tree.max
else
return -1
end
end

describe "Huffman encode trees" do
before :each do
@ht = Honeytree.new
@ht.find_nearby_trees "40.6223262 -73.955483", "1" # EMJC, of course
@ht.find_tree_percentages
@ht.huffman_encode_trees
end

it "should be 6 levels deep" do
depth(@ht.encoded).should == 6
end

it "should account for 100% of the trees at its root" do
@ht.encoded[-1].should == 100.0
end
end

0 comments on commit efddae7

Please sign in to comment.