Doing chris pine learn to program - chapter 7 challenge feedback

Hi, I'm totally new to ruby and web development (with only
html/css/javascript and some php experience).

I want to get into RoR development but would like to get a good
understanding of ruby before doing railstutorial.org.

I'm following Chris Pine's online tutorial for ruby and just spent a few
hours on this one challenge at chapter 7.. you take
input from a user, store it all into an array then have to print it back
out in alphabetical order. But without the sort method.

I purposely didn't look up any other methods or for help, to see if this
could be accomplished only with what was taught up to that point (no
writing def, or using other methods/loops that weren't covered)

Here's the resulting code, it looks messy.. but feedback would be
appreciated.

words = []
endProg = nil

while endProg != ''
    words.push gets.chomp
    endProg = words.last
end

words.pop
num1 = -1
num2 = 0
more = 0
value1 = nil
value2 = nil

while more < words.length
    words.each do |sort|
      if num1 < (words.length - 1)
        if value1 != 'reset'
          value2 = value1
          value1 = sort
            if value2 != nil and value1 != nil and value1 != value2
              if value2 > value1
                words[num1] = value1
                words[num2] = value2
                #Here, I skip over the rest of the each loop and do the
                #while loop again
                #so I don't over write any of the old values
                num1 = num1 + words.length
                # reducing the more because we need an extra iteration
                more = more - 1
              end
            end
        else
          value1 = sort
        end
          num1 = num1 + 1
          num2 = num2 + 1
      end
    end
    words = words
    num1 = -1
    num2 = 0
    sort = nil
    value1 = 'reset'
    value2 = 'reset'
    more = more + 1
end

puts
puts words
puts

Obviously this could be done more efficiently with more operators and
methods, but could this have been done better by using only the basics
(do, while, if, else, pop, push, last)

Thanks

···

--
Posted via http://www.ruby-forum.com/.

Hi, I'm totally new to ruby and web development (with only
html/css/javascript and some php experience).

Hi, Mark! Welcome!

I want to get into RoR development but would like to get a good
understanding of ruby before doing railstutorial.org.

This is a good way to do things.

I'm following Chris Pine's online tutorial for ruby and just spent a few
hours on this one challenge at chapter 7.. you take
input from a user, store it all into an array then have to print it back
out in alphabetical order. But without the sort method.

I purposely didn't look up any other methods or for help, to see if this
could be accomplished only with what was taught up to that point (no
writing def, or using other methods/loops that weren't covered)

Here's the resulting code, it looks messy.. but feedback would be
appreciated.

The first question is: does it work? That's the most important part.

My advice looking at your code is pretty minimal. Given the constraints you've outlined, you've done a pretty good job. The one thing I would strongly recommend is make your variables more clear as to their purpose. num1, num2, value1, value2 are not actually descriptive, although marginally better than i,j or n,m as you see in most algorithm descriptions. Terseness isn't necessarily a virtue in naming things (unless it's hard to type). Also, giving a variable the name 'sort' can end up being problematic for a couple of reasons: (a) it's a verb, therefore doesn't really make sense as a noun (b) there is a well-known method called sort (which you can't use) but sometimes a variable name given the same name as a method can block the method when you want it. A better name might be 'sorting_word' as that's what it appears to be.

words =
endProg = nil

while endProg != ''
   words.push gets.chomp
   endProg = words.last
end

words.pop
num1 = -1
num2 = 0
more = 0
value1 = nil
value2 = nil

while more < words.length
   words.each do |sort|
     if num1 < (words.length - 1)
       if value1 != 'reset'
         value2 = value1
         value1 = sort
           if value2 != nil and value1 != nil and value1 != value2
             if value2 > value1
               words[num1] = value1
               words[num2] = value2
               #Here, I skip over the rest of the each loop and do the
               #while loop again
               #so I don't over write any of the old values
               num1 = num1 + words.length
               # reducing the more because we need an extra iteration
               more = more - 1
             end
           end
       else
         value1 = sort
       end
         num1 = num1 + 1
         num2 = num2 + 1
     end
   end
   words = words
   num1 = -1
   num2 = 0
   sort = nil
   value1 = 'reset'
   value2 = 'reset'
   more = more + 1
end

puts
puts words
puts

Obviously this could be done more efficiently with more operators and
methods, but could this have been done better by using only the basics
(do, while, if, else, pop, push, last)

I notice you are using .each in there — which is a looping mechanism — does this violate your constraint on only using basics?

I haven't gone through Pine's tutorial, so I am not sure about this.

To me, one of the biggest issues around learning to program is learning how to break a problem down into it's parts. Back in the day we used to refer to this as Top Down Design (TDD has taken a different meaning today). But without being able to define methods, it seems like you end up not actually learning how to implement that. It generally can make for much more readable and understandable code (as long as it isn't hard to find the methods).

Great work so far! Your code looks clean, the operation is clear, you included some comments of the sort I would find useful.

···

On Aug 13, 2013, at 9:40 PM, mark ducasi <lists@ruby-forum.com> wrote:

Thanks

--
Posted via http://www.ruby-forum.com/\.

Hi Mark,

I hope you don't be angry but I took your question as an exercise for myself.
I created a repo to log the changes on your code step-by-step.
Take a look at it

I'll have to stop working on it by now (because it's work/job time now).
I'll come back to it at night.

Some things of note that is already commited on the repo.

1) What happens if the user enters "reset" as one of the words to be sorted?
2) What the "words = words" assignment really do?
3) To change an Array inside its iteration can be dangerous as you do
in "words[num1] = value1"

OBS: I couldn't find the "original" tutorial url. Can you show me?

By the way, congratulations, your code works!
Keep going on Ruby!

Let's see if somebody else fork the repo and join us in this exercise.

Abinoam Jr.

···

On Tue, Aug 13, 2013 at 11:40 PM, mark ducasi <lists@ruby-forum.com> wrote:

Hi, I'm totally new to ruby and web development (with only
html/css/javascript and some php experience).

I want to get into RoR development but would like to get a good
understanding of ruby before doing railstutorial.org.

I'm following Chris Pine's online tutorial for ruby and just spent a few
hours on this one challenge at chapter 7.. you take
input from a user, store it all into an array then have to print it back
out in alphabetical order. But without the sort method.

I purposely didn't look up any other methods or for help, to see if this
could be accomplished only with what was taught up to that point (no
writing def, or using other methods/loops that weren't covered)

Here's the resulting code, it looks messy.. but feedback would be
appreciated.

words =
endProg = nil

while endProg != ''
    words.push gets.chomp
    endProg = words.last
end

words.pop
num1 = -1
num2 = 0
more = 0
value1 = nil
value2 = nil

while more < words.length
    words.each do |sort|
      if num1 < (words.length - 1)
        if value1 != 'reset'
          value2 = value1
          value1 = sort
            if value2 != nil and value1 != nil and value1 != value2
              if value2 > value1
                words[num1] = value1
                words[num2] = value2
                #Here, I skip over the rest of the each loop and do the
                #while loop again
                #so I don't over write any of the old values
                num1 = num1 + words.length
                # reducing the more because we need an extra iteration
                more = more - 1
              end
            end
        else
          value1 = sort
        end
          num1 = num1 + 1
          num2 = num2 + 1
      end
    end
    words = words
    num1 = -1
    num2 = 0
    sort = nil
    value1 = 'reset'
    value2 = 'reset'
    more = more + 1
end

puts
puts words
puts

Obviously this could be done more efficiently with more operators and
methods, but could this have been done better by using only the basics
(do, while, if, else, pop, push, last)

Thanks

--
Posted via http://www.ruby-forum.com/\.

Hi Abinoam,

Thanks for taking the time to look at the code. I have no problems with
you putting it onto github.

the original tutorial is here:
http://pine.fm/LearnToProgram/
and the chapter that contains this challenge I posted about in this
thread:
http://pine.fm/LearnToProgram/?Chapter=07
at the bottom.

2) In my mind, the words = words should be trying to save the changes
made to the words array with what was reconstructed during the each
loop. I wasn't sure if doing the words[num1] = value1 would
permanently change the words array, or just change it for the duration
of the each loop but then when the while loop ran once again, it'd use
the old words array.

I will take a look at your code, thanks!

···

--
Posted via http://www.ruby-forum.com/.

I think you should take a look at some methods of sorting and choose
which you think is the best.


I chose bubble because it is the simplest and I came up with this, what
do you think?:

  1 class WordList
  2 @words
  3
  4 def initialize
  5 @words = []
  6 end
  7
  8 def add word
  9 @words.push word
10 end
11
12 def show
13 @words
14 end
15
16 def sort
17 sorted = @words
18 length = sorted.length
19
20 begin
21 swap = false
22
23 sorted.each_index do |e|
24 next_key = e + 1
25
26 next if next_key >= length
27
28 if sorted[e] > sorted[next_key]
29 sorted[e], sorted[next_key] = sorted[next_key], sorted[e]
30 swap = true
31 end
32 end
33 end while swap
34
35 sorted
36 end
37 end
38
39 class Main
40 @words
41
42 def initialize
43 @words = WordList.new
44
45 write_some_words
46 show_words
47 show_sorted
48 end
49
50 def write_some_words
51 msg = "Type something:"
52
53 puts msg
54
55 while((word = gets.chomp) != '') do
56 puts msg
57 @words.add word
58 end
59 end
60
61 def show_words
62 p @words.show
63 end
64
65 def show_sorted
66 p @words.sort
67 end
68 end
69
70 Main.new

···

--
Posted via http://www.ruby-forum.com/.

@Abinoam Jr
Nice, pretty elegant code!

···

--
Posted via http://www.ruby-forum.com/.

Hi Mark,

Just committed and pushed (my) exercise.
I modified your code step by step in each commit and left comments so
that you can follow the reasoning of each modification.

Your code turned into a pure bubble sort implementation bellow.
Believe me... this is a patch to your initial code! :slight_smile:
It behaves (almost) exactly the same as your initial code.

words =

words.push gets.chomp while words.last != ''

words.pop

begin
  more = false
  1.upto(words.length-1) do |word_ix|
    if words[word_ix-1] > words[word_ix]
      words[word_ix-1], words[word_ix] = words[word_ix], words[word_ix-1]
      more = true
    end
  end
end while more

puts
puts words
puts

It's pushed to GitHub - abinoam/word_sort: In reply to https://www.ruby-forum.com/topic/4416380

Abinoam Jr.

Hint: (as Rafael said)

···

On Wed, Aug 14, 2013 at 1:47 PM, Rafael M. <lists@ruby-forum.com> wrote:

I think you should take a look at some methods of sorting and choose
which you think is the best.
Sorting algorithm - Wikipedia
http://www.youtube.com/watch?v=kgBjXUE_Nwc

I chose bubble because it is the simplest and I came up with this, what
do you think?:

  1 class WordList
  2 @words
  3
  4 def initialize
  5 @words =
  6 end
  7
  8 def add word
  9 @words.push word
10 end
11
12 def show
13 @words
14 end
15
16 def sort
17 sorted = @words
18 length = sorted.length
19
20 begin
21 swap = false
22
23 sorted.each_index do |e|
24 next_key = e + 1
25
26 next if next_key >= length
27
28 if sorted[e] > sorted[next_key]
29 sorted[e], sorted[next_key] = sorted[next_key], sorted[e]
30 swap = true
31 end
32 end
33 end while swap
34
35 sorted
36 end
37 end
38
39 class Main
40 @words
41
42 def initialize
43 @words = WordList.new
44
45 write_some_words
46 show_words
47 show_sorted
48 end
49
50 def write_some_words
51 msg = "Type something:"
52
53 puts msg
54
55 while((word = gets.chomp) != '') do
56 puts msg
57 @words.add word
58 end
59 end
60
61 def show_words
62 p @words.show
63 end
64
65 def show_sorted
66 p @words.sort
67 end
68 end
69
70 Main.new

--
Posted via http://www.ruby-forum.com/\.