Skip to content

Instantly share code, notes, and snippets.

@cnocon
Last active March 8, 2022 00:47
Show Gist options
  • Select an option

  • Save cnocon/6743550 to your computer and use it in GitHub Desktop.

Select an option

Save cnocon/6743550 to your computer and use it in GitHub Desktop.
Birthday helper exercise from Chris Pine's book, Learn to Program
# Write a program to read in names and birth dates from a text file.
# It should then ask you for a name. You type one in, and it tells you
# when that person’s next birthday will be (and, for the truly adventur-
# ous, how old they will be). The input file should look something like this:
# Christopher Alexander, Oct 4, 1936
# Christopher Lambert, Mar 29, 1957
# Christopher Lee, May 27, 1922
# Christopher Lloyd, Oct 22, 1938
# Christopher Pine, Aug 3, 1976
# Christopher Plummer, Dec 13, 1927
# Christopher Walken, Mar 31, 1943
# The King of Spain, Jan 5, 1938
#
# You’ll probably want to break each line up and put it in a hash,
# using the name as your key and the date as your value.
# In other words: words:
# birth_dates['The King of Spain'] = 'Jan 5, 1938'
# (You can store the date in some other format if you prefer.)
#
# Though you can do it without this tip, your program might look prettier
# if you use the each_line method for strings. It works pretty much like
# each does for arrays, but it returns each line of the multiline
# string one at a time (but with the line endings,
# so you might need to chomp them). Just thought I’d mention it....
require 'yaml'
file = File.open("birthdaylist.txt")
contents = file.read
lines_array = contents.split("\n");
birthdays = {}
#here we clean up the contents of the text file so we can manipulate it as a hash
lines_array.each do |l|
date = l[-12..-1].to_s
man_date = date.split(', ')
year = man_date[1].to_i
month = man_date[0][0..2]
months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
#convert month string to month number for time calcs later
months.each do |m|
if m == month
month = months.index(m) + 1
end
end
#remove leading whitespace from date numbers
day = man_date[0][4..5]
if day[0] == ' '
day = day[1].to_i
else
day = day[0..1].to_i
end
nameline = l.split(date).to_s
name_array = nameline.split(',')
name = name_array[0]
name = name[2..-1]
birthdays[name] = [year, month, day]
end
puts "Who's birthday would you like to know?"
input_name = gets.chomp
birthdays.each do |n,d|
if n == input_name
birthtime = Time.new(d[0].to_i,d[1].to_i,d[2].to_i)
time = Time.new
current_year = time.year
test_date = Time.local(current_year,d[1].to_i,d[2].to_i)
diff = test_date - Time.now
if diff > 0
next_birthday_age = current_year - birthtime.year
puts "#{n}'s next birthday is #{d[1]}/#{d[2]} #{time.year}. They will be #{next_birthday_age} years old."
else
next_birthday_age = 1 + current_year - birthtime.year
puts "#{n}'s next birthday is #{d[1]}/#{d[2]} of #{time.year + 1}. They will be #{next_birthday_age} years old."
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment