USE RUBY PROGRAMMING LANGUAGE: Write a PhoneNumber class that gets initialized w
ID: 3883363 • Letter: U
Question
USE RUBY PROGRAMMING LANGUAGE:
Write a PhoneNumber class that gets initialized with a 10-digit phone number. In the call PhoneNumber.new(ph), the input ph take any of these possible formats:
• a 10-digit integer
• a string of 10 digits
• (ddd) ddd-dddd where d is any digit [parenthesis format]
• ddd-ddd-dddd where d is any digit [hyphen format]
Wherever whitespace appears in a string format, we can have a string of zero or more whitespace characters (including before and after the string as a whole). A PhoneNumber object responds to the to_s message which returns the number as a string in parenthesis format, and the area_code, prefix, and root messages which return the parts of the number in string format, as illustrated here:
a = PhoneNumber.new(1234567890)
puts a # (123) 456-7890
puts a.area_code # 123
puts a.prefix # 456
puts a.root # 7890
puts PhoneNumber.new(' 7778889999 ') # (777) 888-9999
puts PhoneNumber.new(' (555)444-3333') # (555) 444-3333
PhoneNumber.new('1234')
# ArgumentError: Improper phone number syntax
PhoneNumber.new('(12) 333-4444')
# ArgumentError: Improper phone number syntax
PhoneNumber.new('123- 456- 7890')
# ArgumentError: Improper phone number syntax
Explanation / Answer
main.rb
class PhoneBook
def initialize
@entries = Hash.new
end
def add(name, phone_number, label)
if @entries.has_key?(name)
# Instead of creating a new key, we just need to add the
# new contact info to the entry objects
@entries[name].add_contact(phone_number, label)
else
# Create a hash consisting of name and new entry.
@entries[name] = Entry.new(phone_number, label)
end
end
def find(name)
# Here we check to see if name exists, if so print their contact info
if @entries.has_key?(name)
puts @entries[name]
else
puts "Whoops, looks like '#{name}' does not exist."
end
end
def find_contact(name, label)
# Here we are checking for a contact with a particular label
if @entries.has_key?(name)
if @entries[name].has_label(label.to_s)
@entries[name].find_label(label)
else
puts "Whoops, looks like the label '#{label}' does not exist for '#{name}'."
end
else
puts "Whoops, looks like '#{name}' does not exist."
end
end
def delete(name)
@entries.delete_if { |x, y| x == name }
end
def delete_contact(name, label)
if @entries.has_key?(name)
if @entries[name].has_label(label.to_s)
@entries[name].delete_label(label)
else
puts "Whoops, looks like the label '#{label}' does not exist for '#{name}'."
end
else
puts "Whoops, looks like '#{name}' does not exist."
end
# If that was the last contact for the entry, then remove the entry from the phonebook
delete(name) if @entries[name].contacts.length == 0
end
def to_s
# Display the phonebook
@entries.each do |name, contact|
puts "#{name}:"
contact.print_format
end
end
end
# Create an Entry class
class Entry
attr_reader :contacts
def initialize(phone_number, label)
@contacts = []
# Create the new contact
add_contact(phone_number, label)
end
def add_contact(phone_number, label)
# Add the new contact to the array, if it doesn't already exist
if not has_label(label)
@contacts << PhoneContact.new(phone_number, label)
else
puts "Sorry, that label already exists for this contact. Try again."
end
end
def to_s
@contacts.each { |contact| puts contact }
end
# This is used for displaying the phonebook....
def print_format
@contacts.each { |contact| puts " #{contact}" }
end
# This method checks to see if the requested label exists already.
def has_label(label)
@contacts.each do |contact|
if contact.label == label.to_s
return true
end
end
return false
end
# This method prints the contact info for the given label
def find_label(label)
@contacts.each { |contact| contact if contact.label == label.to_s }
end
# This method deletes a contact with the given label
def delete_label(label)
@contacts.delete_if { |lab| lab.label == label.to_s }
end
end
class PhoneContact
attr_reader :phone_number, :label
def initialize(phone_number, label)
@phone_number = PhoneNumber.new(phone_number)
@label = label.to_s
end
def to_s
phone_number.to_s + ' (' + label + ')'
end
end
class PhoneNumber
def initialize(phone_number)
@phone_number = normalize(phone_number)
end
def normalize(phone_number)
ph = phone_number.to_s
patterns = [/^s*(d{10})s*$/,
/^s*(d{3})-(d{3})-(d{4})s*$/,
/^s*((d{3}))s*(d{3})-(d{4})s*$/]
matches = patterns.map {|pat| pat.match(ph)}
match = matches.find {|m| m.is_a?(MatchData)}
if match then
match.captures.join
else
raise ArgumentError, "Improper phone number syntax"
end
end
def phone_number
@phone_number
end
def area_code
phone_number.slice(0,3)
end
def prefix
phone_number.slice(3,3)
end
def root
phone_number.slice(6,4)
end
def to_s
'(' + area_code + ') ' + prefix + '-' + root
end
end
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.