Rubeque string substitution

 

 

 

 

I’ve decided to start sharing how I solve problems occasionally on this blog. I think this will be helpful for potential employers to see how I work.

The following picture is of a Rubeque.com problem

Screen Shot 2013-08-22 at 1.57.57 PM

So we want to substitute the matched pattern of a string within the main string, for a new string. Lets start with making the pattern and actual regular expression.

pattern = Regexp.new(pattern)

This Regexp will be used in Strings sub method(String#sub) in order to replace the matched contents of a string into the replacement parameters value,

self.sub(pattern,replace)

Well that was easy, the first case passes, but the second one doesn’t. This is because sub only replaces the first matched instance it finds. Instead we’ll use String#gsub, for global sub. This will replace all instances of the matched data.

self.gsub(pattern,replace)

That makes the next test pass, however, we’re having issues with getting the string “??” to work like we want it to as a regular expression. This is because ? is a special character used inside regular expressions(It matches either one or none of the preceding character). http://rubular.com/ is a great way to check and or just reference ruby regular expressions. So we need to escape these characters.  We can do this with Regexp.escape(pattern), this “Escapes any characters that would have special meaning in a regular expression. Returns a new escaped string” (taken from ruby-docs). So instead of .new we will use .escape right? No, if you look closely at that definition, .escape returns a string, we still need pattern to be a regexp. So we will make it work like this:

pattern = Regexp.new(Regexp.escape(pattern))

That’s a lot better, now we only have the last test case to solve. our last test case replaces the matched data with a string that contains special substitution cases. ex: \1, \2, \3. These cases will return the exact Match data returned from the regexp. \1 return the first matched case, \2 return the second, and so on. How do we get this to just return \2. we can’t escape the use Regexp.escape(replace), that will just return silly backslashes all over the place. Instead we have to look closer at String#sub and String#gsub. “The problem is that when using sub (and gsub), without a block, ruby interprets special character sequences in the replacement parameter” this quote was taken from two-bit-fool’s answer on Stack Overflow. So when ruby sees the replacement parameter it just INTERPRETS the \1\2\3 and does some magic. We don’t want that, so lets put the replacement string into a block instead of letting it be a paramter.

self.gsub(pattern) { replace}

Now everything is passing! So this is how I solved that question. However, Lets do some recursion on this and  shorten this up a bit with regexp interpolation. With pattern we could do what we did, or we could just create a regexp and interpolate the string returned from .escape like so

pattern = /#{Regexp.escape(pattern)}/

That’s easy enough to understand, and its short enough that I think it could go on the same line, and we can skip redefining the pattern variable all together. So to sum it all up, my final answer was this:

self.gsub(/#{Regexp.escape(pattern)}/ ) {replace}  

I simplified this a little better, I skipped some steps in my head but thought this would clear up how I solved each assertion.

Advertisements

Chris Pine’s “Learn to Program” review

It’s a little over due and I’ve gotten a couple other books I’ve read since then, but I will try my best to recall my experiences with this book.

 

First off, I wasn’t a total noob to Ruby before starting this book. I’d read why’s poignant guide and I’d also done the tryruby.com work alongs. Chris Pine has a silly sense of humor that helps make light of this daunting task that all programmers go through. There is a line in my programming career that I crossed while reading this book that make me realize how programmers think. In the simplest way to explain it, breaking complex problems down to their simplest form. Chris makes you build your own .sort and .shuffle. In order to make this happen I had to look through a lot of Ruby-Doc.org documentation and that in itself really helped me learn some new words in the ruby language. I highly recommend this book. The author is fun to listen to, the material is well structured, and the examples are challenging enough to make you feel like a real programmer but not so challenging that you will give up. 

Side note: There will be times these examples make you want to call this whole programming thing quits. “It’s not for me, this is too hard”. Remember, programming is always hard, no matter what you experience level is. If it isn’t hard then you aren’t challenging yourself. and if you aren’t challenging yourself, then programming itself will speed right passed you. In conclusion: don’t give up and if you have no hair left on your head, step back and do something you enjoy with programming.

Learn to Program Example by Chris Pine

Here is a program I through together this morning. The only thing I haven’t gotten working is validating the month can be value.dowcase or value.upcase or value.capitalize

 

mo = {1 => “Jan”, 2 => “Feb”, 3 => “Mar”, 4 => “Apr”, 5 => “May”, 6 => “Jun”,

7 => “Jul”, 8 => “Aug”, 9 => “Sep”, 10 => “Oct”, 11 => “Nov”, 12 => “Dec”}

def ask string
  puts ‘What ‘ + string + ‘ were you born?’
end

ask “year”
year = gets.chomp
while (year.to_i > Time.now.year) || (year.to_i < Time.at(1875).year )
  puts ‘Please enter a 4 digit year between 1875 and ‘ + Time.now.year.to_s
  year = gets.chomp
end

 # need to get month working so that value, value.downcase, and value.upcase are working

ask “month”
month = gets.chomp
while (month.to_i<1) or (month.to_i > 12)
  puts ‘Please enter a month between 1 and 12’
  month = gets.chomp
end

ask “day”
day = gets.chomp
while (day.to_i < 1) or (day.to_i > 31)
  puts ‘Please enter a day of the month’
  day = gets.chomp
end

def spank (year, month, day)
  birthday = Time.local(year, month, day)
  years_old = (Time.now – birthday) / 3600 / 24 / 365.25
  puts ‘You get ‘ + years_old.floor.to_s + ‘ spankings!!!’
  puts “SPANK!!!\n” * years_old.floor
end

spank year, month, day