Skip to content

Commit

Permalink
Refactor to pass the target directory, rather than set a global const…
Browse files Browse the repository at this point in the history
…ant.
  • Loading branch information
Clay Shentrup committed Jul 2, 2012
1 parent cc6aaaf commit 9667922
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 137 deletions.
15 changes: 15 additions & 0 deletions lib/add_ranking_to_candidate_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class AddRankingToCandidateList < Struct.new(:ranking_lines, :candidate_list)
def self.process(*args)
new(*args).add_ranking
end

def add_ranking
candidate_list.add_ranking(*ranked_candidates)
end

private

def ranked_candidates
ranking_lines.map {|ranking_line| BallotImageLine.new(ranking_line, candidate_list).candidate}
end
end
19 changes: 8 additions & 11 deletions lib/ballot_image_line.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
class BallotImageLine
class BallotImageLine < Struct.new(:line, :candidate_list)
CANDIDATE_ID_START_INDEX = 36
CANDIDATE_ID_LENGTH = 7

def initialize(line, candidate_list)
@line = line
@candidate_list = candidate_list
end

def record_id
@line[CANDIDATE_ID_START_INDEX, CANDIDATE_ID_LENGTH]
end

def candidate
return nil if record_id == '0000000'
@candidate_list.find(record_id)
candidate_list.find(record_id)
end

private

def record_id
line[CANDIDATE_ID_START_INDEX, CANDIDATE_ID_LENGTH]
end
end
16 changes: 8 additions & 8 deletions lib/ballot_image_reader.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
require 'ballot_image_vote'

class BallotImageReader
class BallotImageReader < Struct.new(:candidate_list, :directory_reader)
BALLOT_IMAGE_PATH = '*-BallotImage.txt'
RANKINGS_PER_VOTER = 3

def initialize(candidate_list)
@candidate_list = candidate_list
def self.process(*args)
new(*args).process
end

def process
calculate_preferences
end

private

def calculate_preferences
SFBP.file_from_path(BALLOT_IMAGE_PATH).handle_file do |file|
directory_reader.handle_file(BALLOT_IMAGE_PATH) do |file|
process_rankings(file)
end
end

def process_rankings(file)
file.each_slice(RANKINGS_PER_VOTER) do |lines|
# maybe change this to ask, rather than tell?
BallotImageVote.new(lines, @candidate_list)
AddRankingToCandidateList.process(lines, candidate_list)
end
end
end
22 changes: 0 additions & 22 deletions lib/ballot_image_vote.rb

This file was deleted.

40 changes: 29 additions & 11 deletions lib/conductor.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
require 'sfbp'
require 'candidate'
require 'master_lookup'
require 'ballot_image_reader'
require 'present_results'
require File.join(File.dirname(__FILE__), 'file_reader')
require File.join(File.dirname(__FILE__), 'directory_reader')
require File.join(File.dirname(__FILE__), 'candidate')
require File.join(File.dirname(__FILE__), 'candidate_list')
require File.join(File.dirname(__FILE__), 'master_lookup_line')
require File.join(File.dirname(__FILE__), 'master_lookup')
require File.join(File.dirname(__FILE__), 'ballot_image_line')
require File.join(File.dirname(__FILE__), 'add_ranking_to_candidate_list')
require File.join(File.dirname(__FILE__), 'ballot_image_reader')
require File.join(File.dirname(__FILE__), 'present_results')

class Conductor
class Conductor < Struct.new(:source_directory_path_from_root)
attr_reader :candidates

def print_matchups
present_results.print_matchups
def self.conduct(source_dir_path_from_root)
new(source_dir_path_from_root).conduct
end

def conduct
calculate_preferences
print_matchups
end

def calculate_preferences
BallotImageReader.new(candidate_list)
BallotImageReader.process(candidate_list, directory_reader)
end

private


def print_matchups
present_results.print_matchups
end

def present_results
PresentResults.new(candidate_list)
end
Expand All @@ -30,6 +44,10 @@ def candidates
end

def master_lookup
@master_lookup ||= MasterLookup.new
@master_lookup ||= MasterLookup.new(directory_reader)
end

def directory_reader
@directory_reader ||= DirectoryReader.new(source_directory_path_from_root)
end
end
9 changes: 9 additions & 0 deletions lib/directory_reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class DirectoryReader < Struct.new(:source_directory_path_from_root)
def file_from_path(source_directory_path_from_root)
new(source_directory_path_from_root)
end

def handle_file(filename, &block)
FileReader.process(source_directory_path_from_root, filename, &block)
end
end
31 changes: 31 additions & 0 deletions lib/file_reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class FileReader < Struct.new(:source_directory_path_from_root, :filename)
def self.process(source_directory_path_from_root, filename, &block)
new(source_directory_path_from_root, filename).process(&block)
end

def process
File.open(path) { |file| yield file }
end

private

def path
Dir::glob(glob).first
end

def glob
File.expand_path(unexpanded_glob)
end

def unexpanded_glob
File.join(source_dir_path_from_here, filename)
end

def source_dir_path_from_here
source_directory_path_from_root
end

def this_dir
File.dirname(__FILE__)
end
end
8 changes: 2 additions & 6 deletions lib/master_lookup.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
require 'master_lookup_line'
require 'candidate_list'

class MasterLookup
class MasterLookup < Struct.new(:directory_reader)
MASTER_LOOKUP_PATH = '*-MasterLookup.txt'

def candidate_list
@candidate_list ||= SFBP.file_from_path(MASTER_LOOKUP_PATH).handle_file do |file|
@candidate_list ||= directory_reader.handle_file(MASTER_LOOKUP_PATH) do |file|
candidates_from_master_lookup(file)
end
end
Expand All @@ -14,7 +11,6 @@ def candidate_list

def candidates_from_master_lookup(file)
candidate_list = CandidateList.new
line_count = 0
while line = file.gets
lookup_line = MasterLookupLine.new(line)
break unless lookup_line.is_candidate?
Expand Down
1 change: 0 additions & 1 deletion lib/master_lookup_line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ class MasterLookupLine
RECORD_DESCRIPTION_START_INDEX = 17
RECORD_DESCRIPTION_LENGTH = 50


def initialize(line)
@line = line
end
Expand Down
39 changes: 0 additions & 39 deletions lib/sfbp.rb

This file was deleted.

4 changes: 3 additions & 1 deletion sfbparse.rb
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
require './lib/conductor'
require File.join('./', File.dirname(__FILE__), 'lib/conductor')

Conductor.conduct(ARGV[0])
47 changes: 9 additions & 38 deletions spec/lib/conductor_spec.rb
Original file line number Diff line number Diff line change
@@ -1,48 +1,19 @@
require 'conductor'

describe Conductor do
SFBP::SOURCE_DIR_PATH_FROM_ROOT = 'spec/fixtures/2012-mayor'

def get_candidate_by_name(name)
subject.send(:candidates).find {|candidate| candidate.name == name }
end

describe '#calculate_preferences' do
it 'sets the preference counts' do
avalos = get_candidate_by_name('JOHN AVALOS')
yee = get_candidate_by_name('LELAND YEE')
chiu = get_candidate_by_name('DAVID CHIU')
lee = get_candidate_by_name('ED LEE')

subject.calculate_preferences

avalos.pref_count(yee).should == 1
avalos.pref_count(chiu).should == 1
lee.pref_count(yee).should == 1
yee.pref_count(lee).should == 0
yee.pref_count(chiu).should == 1
end
end

describe '#print_matchups' do
before do
subject.calculate_preferences
end

describe '.conduct' do
it 'prints results for all matchups' do
checked_lines = [
["JOHN AVALOS", "LELAND YEE", 1],
["JOHN AVALOS", "DAVID CHIU", 1]
].map do |subject, opponent, pref_count|
"#{subject} is preferred to #{opponent} by #{pref_count} voter(s).\n"
end
checked_lines = []

$stdout.stub(:puts) do |string|
checked_lines -= [string]
checked_lines << string
end
subject.print_matchups

checked_lines.should be_empty

Conductor.conduct('spec/fixtures/2012-mayor')

checked_lines.should include "LELAND YEE is preferred to DAVID CHIU by 1 voter(s).\n"
checked_lines.should include "LELAND YEE is preferred to EMIL LAWRENCE by 1 voter(s).\n"
checked_lines.should include "TERRY JOAN BAUM is preferred to WRITE-IN JOHN EDWARD FITCH by 1 voter(s).\n"
end
end
end

0 comments on commit 9667922

Please sign in to comment.