Computer Science Canada

String.insert Problem

Author:  Clayton [ Wed Jan 03, 2007 6:44 pm ]
Post subject:  String.insert Problem

I'm currently writing a method for Rubidium that is supposed to take a sender's name, along with their message, and output it in rows 80 characters wide (ie, if you type in a message 100 characters long, you will get a line ~80 characters long [to avoid cutting off words] and a line ~20 characters long plus an indent the length of the senders name). To do this, I simply insert a newline character ("\n") at the last space before the 80 character limit has been reached. For some reason though, my "last_space" method is not determining where the last space before 80 characters is. Here's my code, any help would be appreciated:

Ruby:

def last_space(beginning_char, last_char, message)
    if last_char > message.length then
        last_char = message.length
    end
    beginning_char.upto(last_char) do |i|
        if message[i] == " " then
            return_char = i
        end
    end
end

def message(sender, message)
    column_limit = 60
    if message.length < column_limit
        message
    else
        i = 1
        last_char = 0
        until message.length < column_limit * i do
            last_char = last_space(last_char, last_char + column_limit, message)
            message.insert(last_char, "\n" + " " * sender.length)
            i += 1
        end
        return message
    end
end

puts message("Freakman", "test")

puts "\n"

puts message("md", "This is my really long message, don't be discouraged by it or I will be severly annoyed with you!!! If you hate my typing so much, then screw you too. I'm simply doing this just to have this long enough to test my function :D")

Author:  Cervantes [ Wed Jan 03, 2007 8:24 pm ]
Post subject: 

A few problems.

First, conceptually, it'd be better to start at last_char and use Fixnum#downto to count down.
Second, the conditional for your if statement never succeeds. You've forgotten that a slice done like that returns an integer, which is the ASCII value of the character. To fix it, either change " " to a " "[0], or change message[i] to message[i, 1].
Third, it still doesn't work after this is done. You're little magic that you thought worked isn't working any more. It's not returning the value of 'return_char', but rather the value of the upto method. upto returns self, so 3.upto(5) {|x| puts x} would return 3.

Author:  Clayton [ Wed Jan 03, 2007 9:03 pm ]
Post subject: 

Thank you! It works just freakin' lovely now Very Happy About the message[i] thing, I realized that shortly after I posted the code, and it wasn't worth posting again. This is the last_space() method with all of the changes:

Ruby:

def last_space(beginning_char, last_char, message)
    if last_char > message.length then
        last_char = message.length
    end
    last_char.downto(beginning_char) do |i|
        if message[i, 1] == " " then
            return i
        end
      end
end


I e-mailed the whole thing to you Cervantes

Author:  wtd [ Thu Jan 04, 2007 12:12 am ]
Post subject: 

code:
def last_space(beginning_char, last_char, message)
    last_char = message.length if last_char > message.length

    last_char.downto(beginning_char) do |i|
        return i if message[i, 1] == " "
      end
end


Smile

Author:  Clayton [ Thu Jan 04, 2007 12:20 am ]
Post subject: 

Does that make a difference in regards to speed? If it doesn't, then I prefer my way, as after you start jamming more and more code onto one line, things start getting unreadable.

Author:  rdrake [ Thu Jan 04, 2007 12:37 am ]
Post subject: 

Freakman wrote:
Does that make a difference in regards to speed? If it doesn't, then I prefer my way, as after you start jamming more and more code onto one line, things start getting unreadable.
I don't believe so, it just looks neater. But if it makes code harder for you to understand, then I wouldn't bother shortening up the code that much.

Author:  Clayton [ Thu Jan 04, 2007 12:53 am ]
Post subject: 

Exactly, I could one line that method no problem, I just prefer not to. It just makes it that much harder to read when you try to cram all that code on to one line Confused

For those of you who don't believe me Razz

Ruby:

def last_space(beginning_char, last_char, message) last_char = message.length if last_char > message.length end last_char.downto(beginning_char) {|i| return i if message[i, 1] == " " end} end

Author:  Cervantes [ Thu Jan 04, 2007 1:58 pm ]
Post subject: 

You forgot semi-colons. That code won't execute.

Author:  ericfourfour [ Thu Jan 04, 2007 5:16 pm ]
Post subject: 

To me, both make equal sense so I prefer wtd's way because it is shorter.

code:
last_char = message.length if last_char > message.length
Assign the message length to the last character if the last character is greater than the message length.

code:
if last_char > message.length then
  last_char = message.length
end
If the last character is greater than the message length, assign the message length to the last character.

Do you really need "then" in there?

Author:  wtd [ Thu Jan 04, 2007 5:22 pm ]
Post subject: 

ericfourfour wrote:
Do you really need "then" in there?


No, it's not strictly necessary in this scenario.

Oh, and let me add another one:

code:
last_char > message.length and last_char = message.length

Author:  Clayton [ Thu Jan 04, 2007 7:28 pm ]
Post subject: 

Cervantes wrote:

You forgot semi-colons. That code won't execute.


Shhhh! No one else noticed, so let's leave it at that Razz

On-Topic: It's not even so much the way it makes sense, it's just that I don't like cramming different things on one line, I prefer to stick with one or two expressions/statements per line if I can help it, it just makes tracking the program easier for me.

Author:  wtd [ Thu Jan 04, 2007 8:33 pm ]
Post subject: 

It's just that, if you are only going to have the "if" branch, with no else, *and* only one thing happening if that condition is true (or if it's false, if "unless" is used), then by using the postfix "if" you avoid an unnecessary level of indentation and an unnecessary "end." These added pieces of syntax greatly increase the visual complexity of the code.

Author:  ericfourfour [ Fri Jan 05, 2007 1:05 am ]
Post subject: 

wtd wrote:
Oh, and let me add another one:

code:
last_char > message.length and last_char = message.length

I see how it works but why would it run? I thought you could only use "and" with booleans.

Author:  ericfourfour [ Fri Jan 05, 2007 3:20 am ]
Post subject: 

Well, I just figure out what it does and now I am actually finding it useful. Instead of having it return nil that makes it return false.

Author:  Cervantes [ Fri Jan 05, 2007 1:53 pm ]
Post subject: 

That's correct: you can only use "and" with booleans. However, what is a boolean? nil and false are defined to be false, and everything else is true.


Freakman, your last_space method is essentially String#rindex. Using that will make the code considerably nicer. Smile


: