Skip to content

Instantly share code, notes, and snippets.

@mingca
Created October 1, 2018 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mingca/e18c5953a5228bc5f594ab1fa58dd58b to your computer and use it in GitHub Desktop.
Save mingca/e18c5953a5228bc5f594ab1fa58dd58b to your computer and use it in GitHub Desktop.
People parser
# File: app.rb
require 'date'
require 'test/unit'
CITY_ABBREVS = {
'LA' => 'Los Angeles',
'NYC' => 'New York City'
}.freeze
class ParserUndefined < StandardError; end
class AbbreviationMissing < StandardError; end
# General parser
class Parser
def initialize(row)
@row = row
end
def parse
@slices = @row.split(self.class::Delimiter).map(&:strip)
[first_name, city_name, birth_date].join(' ')
end
protected
def first_name
@slices[self.class::Order[:first_name]]
end
def city_name
slice = @slices[self.class::Order[:city_name]]
if city_name_abbrev?
raise AbbreviationMissing unless CITY_ABBREVS.key? slice
CITY_ABBREVS[slice]
else
slice
end
end
def birth_date
slice = @slices[self.class::Order[:birth_date]]
Date.strptime(slice, self.class::DateFormat)
.strftime('%m/%d/%Y')
end
def city_name_abbrev?
false
end
end
# Comma parser
class CommaParser < Parser
Delimiter = ','.freeze
Order = {
first_name: 0,
city_name: 1,
birth_date: 2
}.freeze
DateFormat = '%m/%d/%Y'.freeze
end
# Dollar parser
class DollarParser < Parser
Delimiter = '$'.freeze
Order = {
first_name: 3,
city_name: 0,
birth_date: 1
}.freeze
DateFormat = '%m-%d-%Y'.freeze
protected
def city_name_abbrev?
true
end
end
# People controller
class PeopleController
def self.normalize(request_params)
results = []
request_params.each do |k, v|
class_name = "#{k.capitalize}Parser"
raise ParserUndefined unless Object.const_defined?(class_name)
results << v.map { |e| Object.const_get(class_name).new(e).parse }
end
results
end
end
begin
result = PeopleController.normalize(
# Fields: first name, city name, birth date
comma: [
'Mckayla, Atlanta, 5/29/1986',
'Elliot, New York City, 4/3/1947'
],
# Fields: city abbreviation, birth date, last name, first name
dollar: [
'LA $ 10-4-1974 $ Nolan $ Rhiannon',
'NYC $ 12-1-1962 $ Bruen $ Rigoberto'
]
)
puts result
rescue AbbreviationMissing, ParserUndefined
puts 'There was an error while parsing'
end
# Expected return (order of entries doesn't matter):
# [
# 'Mckayla Atlanta 5/29/1986',
# 'Elliot New York City 4/3/1947',
# 'Rhiannon Los Angeles 10/4/1974',
# 'Rigoberto New York City 12/1/1962',
# ]
# Test PeopleController
class TestPeopleController < Test::Unit::TestCase
def setup
@parser = PeopleController.normalize(
dollar: ['LA $ 10-4-1974 $ Nolan $ Rhiannon']
)
end
def test_parser
assert_not_nil @parser
assert_raise ParserUndefined do
PeopleController.normalize(sharp: ['LA # 10-4-1974 # Nolan # Rhiannon'])
end
end
end
# Test DollarParser
class TestDollarParser < Test::Unit::TestCase
def setup
@parser = DollarParser.new('NONE $ 10-4-1974 $ Nolan $ Rhiannon')
end
def test_city_name
assert_raise AbbreviationMissing do
@parser.parse
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment