Created
May 25, 2011 06:04
-
-
Save alloy-d/990435 to your computer and use it in GitHub Desktop.
Programmer requests complete data from large number of people regarding T-shirt sales.
This file contains hidden or 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
#!/usr/bin/env ruby | |
require 'net/smtp' | |
require 'time' | |
require 'yaml' | |
size_map = { | |
'S' => 'small', | |
'M' => 'medium', | |
'L' => 'large', | |
'XL' => 'extra large', | |
} | |
number_map = { | |
2 => 'two', | |
} | |
def wrap_text(s, width=72) | |
s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n") | |
end | |
if ARGV.length < 2 then | |
STDERR.puts "Give me an operation and a YAML file!" | |
exit(-1) | |
end | |
people = YAML.load_file ARGV[1] | |
verify = lambda do | |
people.each do |p| | |
shirt_string = '' | |
if not p['shirts'].nil? then | |
grammatical_items = p['shirts'].length | |
p['shirts'].each_with_index do |s, i| | |
quantity = (s['quantity'] if not s['quantity'].nil?) || 1 | |
known = { | |
:size => (not s['size'].nil?), | |
:color => (not s['color'].nil?), | |
} | |
if quantity > 1 then | |
shirt_string += number_map[s['quantity']] + ' ' | |
else | |
if grammatical_items > 1 then | |
shirt_string += 'one ' | |
# Call me crazy, but explicitly saying "one" when | |
# someone only wants one shirt total seems really | |
# stiff and awkward, but it makes perfect sense | |
# if they want more than that... | |
elsif known[:size] and size_map[s['size']][0] == 'e' then | |
shirt_string += 'an ' | |
else | |
shirt_string += 'a ' | |
end | |
end | |
shirt_string += size_map[s['size']] + ' ' if known[:size] | |
shirt_string += s['color'] + ' ' if known[:color] | |
shirt_string += 'shirt' | |
shirt_string += 's' if quantity > 1 | |
case | |
when (not known[:size] and not known[:color]) | |
shirt_string += ' of unknown size and color' | |
when (not known[:size]) | |
shirt_string += ' of unknown size' | |
when (not known[:color]) | |
shirt_string += ' of unknown color' | |
end | |
if i < grammatical_items-1 then | |
if grammatical_items > 2 then | |
shirt_string += ', ' | |
shirt_string += 'and ' if i == grammatical_items - 2 | |
else | |
shirt_string += ' and ' | |
end | |
end | |
end | |
else | |
shirt_string = 'a shirt' | |
end | |
out = p['given'] + ' ' + p['family'] + ' ' | |
out += "<#{p['email']}> " if p['email'] | |
out += 'wants ' + shirt_string + '.' | |
puts wrap_text(out) + "\n" | |
end | |
end | |
mail = lambda do | |
people.each do |p| | |
message = <<EOF | |
From: Adam Lloyd <[email protected]> | |
To: #{p['given']} #{p['family']} <#{p['email']}> | |
Subject: 2011 Congress of Jugglers T-shirts | |
Date: #{Time.now.rfc2822} | |
Hi, #{p['given']}! | |
We are putting together an order for more 2011 Congress shirts. | |
EOF | |
shirt_string = '' | |
unknown_string = '' | |
if not p['shirts'].nil? then | |
grammatical_items = p['shirts'].length | |
p['shirts'].each_with_index do |s, i| | |
quantity = (s['quantity'] if not s['quantity'].nil?) || 1 | |
known = { | |
:size => (not s['size'].nil?), | |
:color => (not s['color'].nil?), | |
} | |
if quantity > 1 then | |
shirt_string += number_map[s['quantity']] + ' ' | |
else | |
if grammatical_items > 1 then | |
shirt_string += 'one ' | |
# Call me crazy, but explicitly saying "one" when | |
# someone only wants one shirt total seems really | |
# stiff and awkward, but it makes perfect sense | |
# if they want more than that... | |
elsif known[:size] and size_map[s['size']][0] == 'e' then | |
shirt_string += 'an ' | |
else | |
shirt_string += 'a ' | |
end | |
end | |
shirt_string += size_map[s['size']] + ' ' if known[:size] | |
shirt_string += s['color'] + ' ' if known[:color] | |
shirt_string += 'shirt' | |
shirt_string += 's' if quantity > 1 | |
case | |
when (not known[:size] and not known[:color]) | |
if (quantity == 1) then | |
unknown_string += 'size and color' | |
else | |
unknown_string += 'sizes and colors' | |
end | |
when (not known[:size]) | |
unknown_string += 'size' | |
when (not known[:color]) | |
unknown_string += 'color' | |
end | |
if i < grammatical_items-1 then | |
if grammatical_items > 2 then | |
shirt_string += ', ' | |
shirt_string += 'and ' if i == grammatical_items - 2 | |
else | |
shirt_string += ' and ' | |
end | |
end | |
end | |
else | |
shirt_string = 'a shirt' | |
unknown_string = 'size and color' | |
end | |
if unknown_string != '' then | |
message += wrap_text <<EOF | |
At Congress, you signed up for #{shirt_string}, but we need to know what #{unknown_string} you'd like. | |
EOF | |
else | |
message += wrap_text <<EOF | |
At Congress, you signed up for #{shirt_string}. I'd just like to make sure this is correct before we send off the order. | |
EOF | |
end | |
message += "\n" | |
message += wrap_text <<EOF | |
If you'd like to take another look at the shirts, there are pictures available at <http://studentorg.umd.edu/juggling/congress/2011/#shirts>. | |
EOF | |
message += "\n" + <<EOF | |
Thank you! | |
-Adam Lloyd, UMD Juggling Club | |
EOF | |
if (not p['email'].nil?) then | |
Net::SMTP.start('127.0.0.1', 25) do |smtp| | |
smtp.send_message(message, | |
'[email protected]', | |
p['email']) | |
end | |
else | |
STDERR.puts "#{p['given']} #{p['family']} has no email address!" | |
end | |
end | |
end | |
if ARGV[0] == "verify" then | |
verify.call | |
elsif ARGV[0] == "mail" then | |
mail.call | |
end |
This file contains hidden or 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
- given: John | |
family: Example | |
email: [email protected] | |
shirts: | |
- color: brown | |
size: M | |
- color: blue | |
size: S | |
quantity: 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Given the amount of data that needs to be passed around to make sure that sentences are composed to be grammatically correct (or even sensible), "smaller utility methods" would (I think) do more to clutter up the code than make it clearer.
Also, the goal of this is just to get emails out to people. Adding code for "unknown size" and "unknown color" isn't just some goofy attempt at robustness, it's necessary code to account for the fact that, astoundingly, not everyone who wants a shirt supplies the information required to get one. (But to answer your question, the "test" is the actual list of shirt requests, in combination with my proofreading of the final emails.)