Iterate through hash issues

Hey all, my first post.

ruby 1.8.7 on RHEL 6.

Trying to build a hash, populate it, and then print it in a particular
order. The output is not what I'm looking for. Some hash keys look odd
and some puts statements fail. Since I'm new to Ruby my guess is
"operator error". Would appreciate being pointed in the right
direction. Sample output is below the code.

···

####

#!/usr/bin/env ruby

def roll2
  return 2 + rand(6) + rand(6)
end

def hexconvert(num)
  if num > 9
    makecap = true
  end

  num = num.to_s(16)

  if makecap
    num = num.capitalize
  end

  return num
end

def make_stat
  roll = roll2
  return hexconvert(roll)
end

stats = {
        'Str' => nil,
        'Dex' => nil,
        'End' => nil,
        'Int' => nil,
        'Edu' => nil,
        'Soc' => nil
        }

stats.each do |stat|
  stats[stat] = make_stat
  puts "#{stat} is #{stats[stat]}."
end

puts "." * 10

stats_names = ['Str', 'Dex', 'End', 'Int', 'Edu', 'Soc']
stats_names.each { |stat| puts "#{stat} is #{stats[stat]}."}

puts "." * 10

####

# Sample output
./exercises.rb
Soc is 3.
Int is 8.
End is A.
Dex is 3.
Dex3 is 4.
Str is 7.
Soc3 is 8.
Soc38 is 7.
Edu is 5.
..........
Str is .
Dex is .
End is .
Int is .
Edu is .
Soc is .
..........

####

# Desired output

Str is 7
Dex is 3
End is A
Int is 8
Edu is 5
Soc is 7

####

--
Mind on a Mission

stats.each should be replaced with stats.each_key.

···

On Fri, Oct 3, 2014 at 11:42 AM, leam hall <leamhall@gmail.com> wrote:

Hey all, my first post.

ruby 1.8.7 on RHEL 6.

Trying to build a hash, populate it, and then print it in a particular
order. The output is not what I'm looking for. Some hash keys look odd
and some puts statements fail. Since I'm new to Ruby my guess is
"operator error". Would appreciate being pointed in the right
direction. Sample output is below the code.

####

#!/usr/bin/env ruby

def roll2
  return 2 + rand(6) + rand(6)
end

def hexconvert(num)
  if num > 9
    makecap = true
  end

  num = num.to_s(16)

  if makecap
    num = num.capitalize
  end

  return num
end

def make_stat
  roll = roll2
  return hexconvert(roll)
end

stats = {
        'Str' => nil,
        'Dex' => nil,
        'End' => nil,
        'Int' => nil,
        'Edu' => nil,
        'Soc' => nil
        }

stats.each do |stat|
  stats[stat] = make_stat
  puts "#{stat} is #{stats[stat]}."
end

puts "." * 10

stats_names = ['Str', 'Dex', 'End', 'Int', 'Edu', 'Soc']
stats_names.each { |stat| puts "#{stat} is #{stats[stat]}."}

puts "." * 10

####

# Sample output
./exercises.rb
Soc is 3.
Int is 8.
End is A.
Dex is 3.
Dex3 is 4.
Str is 7.
Soc3 is 8.
Soc38 is 7.
Edu is 5.
..........
Str is .
Dex is .
End is .
Int is .
Edu is .
Soc is .
..........

####

# Desired output

Str is 7
Dex is 3
End is A
Int is 8
Edu is 5
Soc is 7

####

--
Mind on a Mission

hash.each is actually "each_pair" so you get the keys and values. You can do it this way:

     stats.each do |name, count|
       puts "#{name} is #{count}"
     end

If you don't give a pair of arguments to the block like above, you will get them as an array of [key, value].

Andrew Vit

···

On 14-10-03, 11:42, leam hall wrote:

Hey all, my first post.

ruby 1.8.7 on RHEL 6.

Trying to build a hash, populate it, and then print it in a particular
order. The output is not what I'm looking for. Some hash keys look odd
and some puts statements fail. Since I'm new to Ruby my guess is
"operator error". Would appreciate being pointed in the right
direction. Sample output is below the code.

John, thanks! That did it.

···

On Fri, Oct 3, 2014 at 2:53 PM, John W Higgins <wishdev@gmail.com> wrote:

stats.each should be replaced with stats.each_key.

--
Mind on a Mission

Hey all, my first post.

ruby 1.8.7 on RHEL 6.

Trying to build a hash, populate it, and then print it in a particular
order. The output is not what I'm looking for. Some hash keys look odd
and some puts statements fail. Since I'm new to Ruby my guess is
"operator error". Would appreciate being pointed in the right
direction. Sample output is below the code.

####

#!/usr/bin/env ruby

def roll2
return 2 + rand(6) + rand(6)
end

This could be:
def roll(spec)
  number, sides = spec.split('d',2).map {|n|n.to_i}
  result = 0
  number.times { result += 1 + rand(sides) }
  result
end

Then you could do:

roll('2d6')

irb1.8.7> Array.new(50) { roll('2d6') }
#1.8.7 => [6, 4, 5, 3, 8, 8, 9, 5, 11, 3, 3, 8, 7, 4, 6, 7, 4, 8, 10, 10, 8, 5, 6, 10, 6, 4, 10, 9, 6, 9, 4, 7, 8, 4, 5, 8, 6, 9, 8, 7, 2, 5, 9, 6, 7, 7, 11, 8, 12, 6]

def hexconvert(num)
if num > 9
   makecap = true
end

num = num.to_s(16)

if makecap
   num = num.capitalize
end

return num
end

Try this, it's much simpler.
def hexconvert(num)
  num.to_s(16).upcase
end

def make_stat
roll = roll2
return hexconvert(roll)
end

Converting make_stat I'll leave as an exercise for you :slight_smile:

stats = {
       'Str' => nil,
       'Dex' => nil,
       'End' => nil,
       'Int' => nil,
       'Edu' => nil,
       'Soc' => nil
       }

stats.each do |stat|

This is your problem. Hash#each returns the key and the value. You're capturing something like ['Soc',nil] the first time through and then assign stats[['Soc',nil]]=3 but the output looks kinda OK because ['Soc',nil].to_s is just "Soc"
Try using either:
stats.each do |stat,value|
or, probably better:
stats.keys.each do |stat|
as that also avoids changing the Hash while it is still being iterated.

stats[stat] = make_stat
puts "#{stat} is #{stats[stat]}."
end

puts "." * 10

stats_names = ['Str', 'Dex', 'End', 'Int', 'Edu', 'Soc']

If you initialized stats={} and then did stats_names.each do |stat| above, you'd really avoid problems. If you want the output in a particular order, you should do this anyway. (If you update your Ruby version, 1.9+ Hash maintains insertion order even though a Hash is inherently unordered.)

stats_names.each { |stat| puts "#{stat} is #{stats[stat]}."}

puts "." * 10

####

# Sample output
./exercises.rb
Soc is 3.
Int is 8.
End is A.
Dex is 3.
Dex3 is 4.
Str is 7.
Soc3 is 8.
Soc38 is 7.
Edu is 5.
..........
Str is .
Dex is .
End is .
Int is .
Edu is .
Soc is .
..........

####

# Desired output

Str is 7
Dex is 3
End is A
Int is 8
Edu is 5
Soc is 7

####

--
Mind on a Mission

Try that and you should also get familiar with irb (or, later, one of it's cousins like 'pry' available as a gem) to run code interactively.

-Rob

···

On 2014-Oct-3, at 14:42 , leam hall <leamhall@gmail.com> wrote: