Archive for the 'RPCFN: Challenge #1' Category

06
Oct
09

Shift Subtitle, Results

The first round is finally over! I received some great feedback from several people on the RPCFN comments section. AkitaOnRails says “Worked right off the bat, correct results, but it was just too brute force for my taste.” Michael Kohl says “A bit too complicated and repetitive for my personal taste, but definitely not bad for a Python coder coming over to Ruby-land.” And ashbb says “Ran the code with Ruby 1.9.1 and got the output file well. It was converted correctly. With Ruby 1.8.6, need to treat the message – undefined method ‘each_char’” These are all helpful comments and a good starting point. Now I know that each_char was called something else (or didn’t exist) pre Ruby 1.8.6. The other comments are a helpful starting place to learn what to look for in other code. Look for elegance and DRY principles. I don’t think I know enough Ruby to be elegant quite yet, but hopefully there will be improvement in round two.

Looking at AkitaOnRail’s last post congratulating everyone, he summarizes what the common problems were and styles of coding. Overall what I took away from that post to use in the next challenge is

  1. Naming conventions
  2. Gists on GitHub
  3. Project folder structure
  4. Attempt “Ruby-like” code

So I’m going to need to look up Ruby naming conventions when the next challenge starts/I have more time. All I’ve seen in Ruby code is an excess of underscores and verbose names, but I’m sure there are cases to learn when to use what. Honestly, I thought the goal was to make it all be in one file and not have a project structure, but now that I know that is what they are looking for, that is what I will do. Hmm I’ll have to look into gem specs as well. I think that will answer my question about executable programs.

Taking a look at other solutions I can clearly see a good project structure. Keep class files in the lib/, the binaries in the bin/ and the tests in spec/. I also picked up some ruby syntax, the delimited input! There are a ton of functions I need to look up, they seem like pretty basic ones. I’m liking the general feel of the Ruby code I’m looking at. I’ve only had a chance to read through a couple of solutions and would like to read through more before attempting to comment on any ones that I particularly like.

Definitely looking forward to the next challenge! This is a fun way to learn Ruby. Thanks to all people who are reading/test/judging the code. It seems like a lot of work and you guys are doing a great job!

Advertisements
01
Oct
09

to RSpec or not to RSpec

I took another look at RSpec today. I tried to re-write the script using a test driven development method but am finding it harder to use than expected. I think I just have to shift my brain into programming TDD style. I really didn’t come up with any good code, I must have started over at least 10 times. I started with things like it “should accept a parameter –operation that takes either ‘add’ or ‘sub’ as it’s value” Then I would read RSpec docs and try to test tha…needless to say it’s a good way to learn about RSpec albeit rather slow. Hopefully I can move my brain to this new style of thinking. It seemed so easy at first but once you try it, it’s actually kind of difficult to do.

Here is the list of requirements I’m going to be working off of.

  • it “should accept two parameters, an operation that is either add or sub and a time value formatted at least with one digit. It should also accept two arguments, an in_file and na out_file”
  • it “should add or subtract time based on the set operation”
  • it “should modify the time by the amount passed in as a parameter of –time”
  • it “should read times and all other lines from the first file”
  • it “should write modified times and unmodified other lines to the second file”

IF you can get these tests to pass, then you’ve got yourself a working program and RSpec test to go with it as well as some documentation!

Until next time…

29
Sep
09

Shift Subtitle, RSpec

Sometimes it’s just nice to have everything you need in your apartment and you can just sit around and code :]

I decided today to try my hand at some unit testing using RSpec, as was suggested at the end of the challenge. I haven’t done much testing before so this seems like a good way to get started. The code I submitted includes a class definition as well as some imperative programming all in one. It would have been nice to separate that out, but this was supposed to be one script that works using the standard library. However, since this is beyond the challenge I’m going to test the class I’ve made, SubtitleTime. You can see it in the pastebin. It takes two parameters, a string in the format of HH:MM:SS,mmm and a ‘modifier’ that is either add or sub.

So starting off with RSpec first you have to ‘describe’ the class. Then you use a function named ‘it’ and write what the class should do. For example:

describe SubtitleTime do
    it "should be able to add another timestamp to itself" do
    end
end

Once that part of the code is written, then you just have to add some filler lines to actually test the code. This code above could be expanded to look like this:

describe SubtitleTime do
    it "should be able to add another timestamp to itself" do
        subtitletime.should add_time(another_timestamp)
    end
end # note: this has been crossed out as after reading more about RSpec, this just doesn't make sense.

Well after having written a few test cases and finally understanding what RSpec is all about, I feel like I should do this the right way and see what happens to my class if I built it using TDD (Test Driven Design). It initially seems very difficult to build up a test suite on an already existing piece of code. So let’s get started with some test cases.

First off we want the class to have a time that, before altered, is equal to the initial time. The code for that would look like this:

describe SubtitleTime do
    it "should have time equal to the initial time before the class is altered" do
        subtime = Subtitletime.new(:initial)
        subtitle.time.should == :initial
    end
done

Then When you run this test with the command <spec subtitletime_spec.rb> it will fail saying there is no class SubtitleTime. Simple. The idea behind TDD is that you make a test case, have it break, then fix it. An occasional (or after each iteration) step of refactoring your code should also be included in this process. So now I’ll make a class SubtitleTime

class SubtitleTime
end

This fixes the first error but we still get another error as the test is run. But that’s all I have time for right now, I was using an ibm guide to rspec. That should make things fairly clear. There is a lot to go over and a lot to do, but I’ll get back to this hopefully sooner rather than later and then finish up this challenge’s extras!

28
Sep
09

Shift Subtitle, part 4

Well now it’s just a matter of debugging my code. I suppose writing tests would be the ideal thing to do, but I think there is just a stupid typo in there somewhere that I’ll have to look for.

Ok. I had some ideas while I started working. It pretty much went like this:

  1. Reading in the times is working but assumes they are always in full format (ie 00:00:00,000) and does not handle 00,000 situations.
  2. the to_s method is terrible, I’ve only used sprintf once or twice in PHP so it’s no wonder I didn’t think of it right off. That cleaned it up quite a bit.

So after figuring out a way to read in the times and account for partial time entries, I did a bit of refactoring and testing and found out that it’s working now, horray!
I just thought of another, probably easier way this could have been accomplished. If I had taken the file times, converted them to milliseconds and then added/subtracted the converted input times then spit them back out as HH:MM:SS,mmm it might have been less verbose code, but I think this was a good exercise to learn a bit about Ruby classes. And anyways, my code works and that’s all that counts, right?

http://charpcfn.pastebin.com/f594e4212

That’s my submitted code!

Can’t wait for the next challenge :]

edit: If I find myself with some extra time I will probably go back and write some unit tests and maybe try making it a Gem as practice since there is still a while before the next challenge starts.

27
Sep
09

Shift Subtitle, part 3

Back again for the third time in one day…clearly it’s been a lazy Sunday :]

I decided to implement a SubtitleTime class in order to parse the times for me. This is the class I came up with. There’s probably a cleaner way to split the initial string, but I think this works just fine:

http://charpcfn.pastebin.com/f410f2574

With that class implemented all that’s left is to instantiate the objects and then manipulate them, but wait, there’s a huge problem here. I’ve only accounted for addition to subtitle time. I haven’t even considered subtraction! That’s not good at all. This class is becoming rather verbose, but it’s working well so I’ll just keep going with it. It will get the job done.

Ok at first I had add_hour, add_min, add_sec etc as well as equivalent subtraction methods. But, this would make the main file loop pretty ugly and unreadable. However, the way I have it set up is really inefficient to continuously check the @modifier variable of the class. This will work, it’s just unnecessary steps.

SO after this is all implemented and vaguely tested and broken, my current code is this

http://charpcfn.pastebin.com/f1644cce3

What is wrong with this code:

It pretty much destroys DRY concepts, but I find that’s pretty unavoidable when you first start using a language. Hopefully it will be apparent as I progress in the Ruby language that I follow DRY more closely. This code is pretty verbose and not very well documented. But it’s really not doing anything terribly complicated. Also when you use the params -o add -t 01,001 it will add the milliseconds but not the seconds. I’d figure it out now, but I’m pretty tired.

Things I’ve learned this iteration: I like how easy Ruby classes are. For some reason I just get them more than Python classes. I like the attr_accessor and how that works, it’s pretty neat and useful. The initialize method makes perfect sense and the syntax isn’t terrible. I’d much prefer seeing @var than self.var all over the place.

Until tomorrow!

27
Sep
09

Shift Subtitle, part 2

I find myself with some more free time today so I’ll forge ahead with this challenge!

The first thing I’m going to do here is add functionality to the options and arguments and make sure they are being read in correctly. Here is my resulting code:

http://charpcfn.pastebin.com/f454f0012

Now that those are all set I can start working on file I/O. I have no idea how Ruby handles this, but it’s probably pretty easy. Time for more google!

As I expected File I/O is pretty easy. infile is going to be read in line by line and then as the times are updated each line will be written to the outfile. I’m thinking about making a class SubtitleTime and have that handle the conversion from HH:MM:SS,mmm to an object, but I’m gonna sit on that idea for a while before implementing it.

I’m spending a lot of my time looking up specific syntax here. I made sure the ternary operator was normal as well as looking up lambdas which, apparently, you have to do function.call in order for it to work…That one was a stumper. I also really like how Ruby does regular expressions. My first introduction to REs were in Perl so this is a great throwback seeing the =~ operator again.

Anyway, I’m finished programming for now, here is the code I ended up with:

http://charpcfn.pastebin.com/f1e1b9214

Overall I spent more time looking up syntax than I did library function calls but am definitely learning a lot about the Ruby language.

27
Sep
09

Shift Subtitle, part 1

RPCFN: Shift Subtitle (#1)

Outline: The goal for this problem is to create a command line program that will take a subtitle file, specifically an .srt file, and shift the timings either forwards or backwards by any amount of time. The example command line operation given is:

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

My initial thoughts are not so much about how the algorithm will work, but on how to create a command line operation. I would normally just have a script do_something.rb and then just run it with the interpreter, ruby do_something.rb parameters.

Well, as it turns out, making a command line application in Ruby is pretty straightforward. All you really need to do is include the line #!/usr/bin/env ruby at the top of your script and change the permissions. I can’t seem to make it run properly without the ./ in front of it, but that seems like a minor thing that I’ll figure out later. I’d really like to start with the code.

Since this problem is pretty well presented I know what the options are going to be so I’ll start by looking at how Ruby handles arguments and options first since I’d like to get that out of the way. It looks like I’ll be needing the ‘optparse’ class from the Ruby standard library.

This is the initial code I just wrote up (essentially copy/paste) to parse options and flags. I’ll be using charpcfn.pastebin.com for larger snippets of code, but eventually I’d like to integrate them into the blog.. http://charpcfn.pastebin.com/d3b3fe761

So it looks like I’ll be doing this in parts. I feel like this is a good start to the program, get the basic stuff out of the way and think about the algorithm for a while. I’ll probably be back soon, learning a new language is pretty fun.

edit: One should fully read the problem before starting. ‘optparse’ was mentioned, and in fact required for the actual problem, and I didn’t even realize. Always read the whole problem before starting :]




Challenges

How often I post

November 2017
M T W T F S S
« Dec    
 12345
6789101112
13141516171819
20212223242526
27282930  

This is everything