RPCFN: Shift Subtitle (#1)

by Satish Talim on September 24, 2009

Ruby Programming Challenge For Newbies

RPCFN: Shift Subtitle (#1)

By Fabio Akita

After a very encouraging response to our poll from YOU, the readers of the RL blog, RL is happy to announce the first-ever fortnightly ( bi-weekly / every 14 days) “Ruby Programming Challenge For Newbies (RPCFN)” in Ruby. Thanks to YOU, the Ruby community, people like Fabio Akita and companies like Locaweb who make all of this possible.

About Fabio Akita

Fabio AkitaFabio Akita is a Brazilian Rails enthusiast, also known online as “AkitaOnRails”. He regularly write posts on his own blog and had published the very first book tailored for the Brazilian audience called “Repensando a Web com Rails”.

He is now a full-time Ruby on Rails developer working as Project Manager at Locaweb, Brazil. He’s also the creator of the “Rails Summit Latin America“, the largest international Rails event in South America.

Fabio has this to say about the challenge:

If you’re learning a new language such as Ruby, it is important that you practice it. And the best way to start is by scratching your own itch. Anything goes. It’s not unusual to start by writing simple command line scripts to help out your everyday routine. That’s why I thought of a very trivial exercise in the first challenge. It should demand that you know the basics for a variety of Ruby subjects such as regular expressions, file manipulation, time calculation and so on. The only way to achieve mastery is by practice. So let’s get started!

Sponsor

UK based Passenger Hosting

1st Easy Limited are delighted to have been given the opportunity to support the work of Satish Talim and his team at RubyLearning.

Taking part in the Ruby Programming Challenge? You’re welcome to take advantage of the free Ruby on Rails hosting trials that 1st Easy offer: simply register your details, and a full-featured account is yours to do with as you please for one month. Once the trial is over, you can transfer your work to a paid account, or walk away with no questions asked!

Prizes

  • The person with the best Ruby solution (if there is a tie between answers, then the one who posted first will be the winner) will be awarded any one of PeepCode’s Ruby on Rails screencasts.
  • The other prize, selected randomly amongst the remaining working Ruby solutions, will be awarded any one of Pragmatic’s The Ruby Object Model and Metaprogramming screencasts.

The two persons who win, can’t win again in the next immediate challenge but can still participate.

The Ruby Challenge

RPCFN

Difficulty: Ruby beginner.

Goals: Basic control over Ruby elements, specially command line scripting.

Description: There are several ways to subtitle a movie nowadays, and one of the most well known format is the SubRip format (http://en.wikipedia.org/wiki/SubRip). It has entries like these:

645
01:31:51,210 --> 01:31:54,893
the government is implementing a new policy...

646
01:31:54,928 --> 01:31:57,664
In connection with a dramatic increase
in crime in certain neighbourhoods,

Each line has an increasing integer identification, then comes the time range (start and end time) in the format “hours:minutes:seconds,milliseconds”. The decimal separator used is the comma. Finally there are the subtitles themselves and a line break marks the end of an entry.

Sometimes the timing is shifted for a small amount, 2 or 3 seconds. Then comes the trouble when you need to shift everything a few seconds back or ahead.

The goal is to create a small command line script in Ruby that will read an SRT file, and output another one with the new calculated times.

So, for example, if I want to shift everything 2,500 (2 seconds and 500 milliseconds) ahead, I would start with this:

01:32:04,283 --> 01:32:07,769

and end up with:

01:32:06,783 --> 01:32:10,269

The command line should accept arguments such as:

shift_subtitle --operation add --time 02,110 input_file output_file

This means “--operation” can accept either ‘add’ or ‘sub’ to add or subtract times. The “--time” will accept the amount of time to shift in the format 11,222 where “11″ is the amount of seconds and “222″ the amount of milliseconds.

Requirements: This has to be a pure Ruby script, using only the Ruby Standard Libraries (meaning, no external Gems).

It has to implement “optparse” to parse the command line arguments.

As an observation, bear in mind that the first thing that you might attempt will look like this:

a = Time.at(04,283)
b = a + 2.500
puts b.usec
=> 500283

This is wrong, the proper result should’ve been “783″ (as in the example in the previous section). So it means that you will have to find another way out.

Extras (Optional): If you want:

  • It would be interesting to exercise the process of a Gem creation. So you would have to package your script.
  • Another thing that would be good is to have RSpec unit tests covering your code, to exercise software development best practices.

(Note that the above two points are optional and not a requirement).

How to Enter the Challenge

It’s free and registration is not required. You can enter the challenge just by posting the following as a comment to this blog post:

  1. Your name:
  2. Email address (will not be published):
  3. Brief description of what you do (will not be published):
  4. Country of Residence:
  5. Your Solution (i.e. Ruby code): Prefix your code with <pre> tag and suffix it with </pre> tag.
  6. Code works with Ruby 1.8 / 1.9 / Both:
  7. Explanation (if any):
  8. Test cases (if any):

Note:

  • You may provide the URL of your source code, in case it is hosted on GitHub.
  • All solutions posted would be hidden to allow users to come up with their own solutions.
  • You should post your entries before midnight of 4th Oct. 2009 (Indian Standard Time). No new solutions will be accepted from 5th to 8th Oct. 2009.
  • On Monday, 5th Oct. 2009 all the solutions will be thrown open for everyone to see and comment upon.
  • The winning entries will be announced on this blog. The winners will be sent their prizes by email.

More details on the RPCFN?

Please refer to the RPCFN FAQ for answers to the following questions:

Donations

RPCFN is entirely financed by RubyLearning and sometimes sponsors, so if you enjoy solving Ruby problems and would like to give something back by helping with the running costs then any donations are gratefully received.

Click here to lend your support to: Support RubyLearning With Some Love and make a donation at www.pledgie.com !

Acknowledgements

Special thanks to:

Questions?

Contact Satish Talim at satish.talim@gmail.com OR if you have any doubts / questions about the challenge (the current problem statement), please post them as comments to this post and the author will reply asap.

The Participants

There are two categories of participants. Some are vying for the prize and some are participating for the fun of it. The participants were:

In the competition

  1. Felipe Giotto, Brazil
  2. Eduardo, Brazil
  3. Kalle Lindström, Sweden – declared winner
  4. Robison WR Santos, Brazil
  5. Aldric, USA
  6. Akshay Gupta, India
  7. Fabio Kreusch, Brazil
  8. Chris Jones, USA
  9. Chuck Ha, USA
  10. Milan Dobrota, Serbia
  11. Parag Shah, India
  12. Hugo Figueiredo, Brazil
  13. John McDonald, USA
  14. Felipe Elias Philipp, Brazil – declared winner
  15. Charles Feduke, USA
  16. Hari Rajagopal, USA
  17. Brad O’Connor, Australia
  18. Oliver, UK
  19. Jacob Lichner, USA
  20. Todd Huss, USA
  21. Antonio, Canada
  22. Sriram Varahan, India
  23. Giordano Scalzo, Italy
  24. Phil Kates, USA

Just for Fun

  1. Michael Kohl, Austria
  2. Rodrigo Rosenfeld Rosas, Brazil
  3. Dominik Honnef, Germany
  4. Mike Hodgson, Canada

The Winners

Winners

Congratulations to the winners of this Ruby Challenge. They are:

Next Challenge

RPCFN: Average Arrival Time For A Flight (#2) by Chris Strom.

Update

  • The Challenge is now closed. Fabio Akita has a working solution to this problem. This is not a “perfect” or the sole “correct” solution, but just one way of doing it. Fabio is thankful to Satoshi Asakawa for using one of his ideas in this implementation.

Technorati Tags: , , , , ,

Posted by Satish Talim

{ 126 comments… read them below or add one }

Charles Feduke October 5, 2009 at 5:08 pm

This was a really fun way to get into Ruby. I’ve crossed the line of “used once, it was great” into “hey I can solve that problem with Ruby… maybe!”

Looking at the solutions I learned a lot about project structure which is something I can get hung up on. I will definitely use github for future submissions, it just seems like the logical thing to do.

Thanks for the challenge and spending the time to post and review all of the entries. It really does help.

Reply

Brad O'Connor October 6, 2009 at 10:47 am

It’s a shame that my code became unusable when it was transferred to github as it did work at my end. It looks like the html escape codes were not handled correctly. Next time I will use github myself.

I’m starting to look through some of the other solutions and realising just how much I have to learn.

Anyway, despite my code biting the dust I really enjoyed this and hope it continues. I have a website that I want to build using Rails but my Ruby was not strong enough to really understand what I was doing and this is a great way of working on that. Seeing other people’s solutions to a problem you have attempted yourself is an extremely effective way of learning. Thanks!

Reply

William Blackerby October 6, 2009 at 8:56 pm

Really like Fabio’s working solution. I struggled with what to do about formatting the time string, so I’m going to spend some time studying what he did. Nice brain exercise.

Reply

Satish Talim October 14, 2009 at 8:32 am

Ruby’s default OptionParser class does its work well, but is quite verbose. Just defining four options will require 20 or so lines of code, and this is not ideal. It also requires you to remember how to use OptionParser, which is not something you may use regularly.

Trollop is a great library that solves these problems -
http://tinyurl.com/yjbxefc

Reply

Mike Bethany November 11, 2010 at 2:43 am

I have to say I was really surprised to see the horrible quality of code in the optparse.rb class. I’ve tried four times now to couch my dislike of that terribly witten class but bad code deserves to have it’s bad codeness pointed out. It’s clearly a C++ programmers terrible attempt at Ruby. It’s like that code raped my dog and now wants to take my cat on a weekend getaway. It’s bad; really, really bad.

It would be really bad form to complain about such bad code and not fix it so I’m working on my very own replacement I hope to present the Ruby team with (fat chance they’ll accept it but it’s good practice).

I haven’t released my option parser yet but you can download my fix to the existing OptionParser class, that allows required switches, by installing my pickled_optparse gem:
gem install pickled_optparse

I should have my cli switch class out by the end of the month (nov 2010).

Thanks for the great motivation to do something useful!

Reply

Leave a Comment

{ 22 trackbacks }

Previous post:

Next post: