8 Replies - 2111 Views - Last Post: 19 March 2019 - 11:55 PM Rate Topic: -----

#1 Gh05t_97   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 10
  • Joined: 11-March 19

How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 06:40 AM

I have a horrendous nested hash as part of an exercise. The whole code is below. I want to iterate through the hash using a method and return the number of rebounds associated with the person with the highest shoe size in the hash. The actual hash consists of 4 levels, it is the 4th level I am trying to access in order to return the number of rebounds associated with the highest shoe size of the person. When I try to run this code I get an error of

> Traceback (most recent call last): 1: from main.rb:150:in `<main>'
> main.rb:137:in `big_shoe_rebounds': undefined local variable or method
> `each' for main:Object (NameError)

Anyways, the code is below. I would appreciate any advice on why I get this error and any improvements to this code. Thank you

    def game_hash 
    	game_hash = {
    		:home => 
    		{
    			:team_name => "Brooklyn Nets",
    			:colors => ["Black", "White"],
    			:players => {
    				:player1 => {
    					:name => "Alan Anderson",
    					:number => 0,
    					:shoe_size => 16,
    					:points => 22,
    					:rebounds => 12,
    					:assists => 12,
    					:steals => 3,
    					:blocks => 1,
    					:slam_dunks => 1
    				},
    				:player2 => {
    					:name => "Reggie Evans",
    					:number => 30,
    					:shoe_size => 14,
    					:points => 12,
    					:rebounds => 12,
    					:assists => 12,
    					:steals => 12,
    					:blocks => 12,
    					:slam_dunks => 7
    				},
    				:player3 => {
    					:name => "Brook Lopez",
    					:number => 11,
    					:shoe_size => 17,
    					:points => 17,
    					:rebounds => 19,
    					:assists => 10,
    					:steals => 3,
    					:blocks => 1,
    					:slam_dunks => 15
    				},
    				:player4 => {
    					:name => "Mason Plumlee",
    					:number => 1,
    					:shoe_size => 19,
    					:points => 26,
    					:rebounds => 12,
    					:assists => 6,
    					:steals => 3,
    					:blocks => 8,
    					:slam_dunks => 5
    				},
    				:player5 => {
    					:name => "Jason Terry",
    					:number => 31,
    					:shoe_size => 15,
    					:points => 19,
    					:rebounds => 2,
    					:assists => 2,
    					:steals => 4,
    					:blocks => 11,
    					:slam_dunks => 1
    		
    				}
    		},		
    
    		:away =>
    		{
    			:team_name => "Charlotte Hornets",
    			:colors => ["Turquoise", "Purple"],
    			:players => {
    				:player1 => {
    					:name => "Jeff Adrien",
    					:number => 4,
    					:shoe_size => 18,
    					:points => 10,
    					:rebounds => 1,
    					:assists => 1,
    					:steals => 2,
    					:blocks => 7,
    					:slam_dunks => 2
    				},
    				:player2 => {
    					:name => "Bismak Biyombo",
    					:number => 0,
    					:shoe_size => 16,
    					:points => 12,
    					:rebounds => 4,
    					:assists => 7,
    					:steals => 7,
    					:blocks => 15,
    					:slam_dunks => 10
    				},
    				:player3 => {
    					:name => "DeSagna Diop",
    					:number => 2,
    					:shoe_size => 14,
    					:points => 24,
    					:rebounds => 12,
    					:assists => 12,
    					:steals => 4,
    					:blocks => 5,
    					:slam_dunks => 5
    				},
    				:player4 => {
    					:name => "Ben Gordon",
    					:number => 8,
    					:shoe_size => 15,
    					:points => 33,
    					:rebounds => 3,
    					:assists => 2,
    					:steals => 1,
    					:blocks => 1,
    					:slam_dunks => 0
    				},
    				:player5 => {
    					:name => "Brendon Haywood",
    					:number => 33,
    					:shoe_size => 15,
    					:points => 6,
    					:rebounds => 12,
    					:assists => 12,
    					:steals => 22,
    					:blocks => 5,
    					:slam_dunks => 12
    				}
    			}
    		}
    	}
    }
    end 
    
    
    
    def big_shoe_rebounds(hash) 
      #will return the number of rebounds associated with the player that has the largest shoe size
    	# STEP 1: find the player with the biggest shoe size
    	#STEP 2: return that players number of rebounds
      game_hash each do |team, data|
        data.each do |attribute, values|
          if attribute == :players
            values.each do |player_number, player_data|
              if player_data == [:shoe_size].max
                return game_hash[teams_playing][attribute][player_number][:rebounds]
              end 
            end 
          end 
        end 
      end
    end 
    
    big_shoe_rebounds(game_hash)


Is This A Good Question/Topic? 0
  • +

Replies To: How do I select the largest key: value pair in a nested hash?

#2 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,229
  • Joined: 12-December 12

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 06:48 AM

You are passing in game_hash as parameter 'hash' but then try to refer to it as 'game_hash' within the method.
Was This Post Helpful? 0
  • +
  • -

#3 Gh05t_97   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 10
  • Joined: 11-March 19

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 06:58 AM

View Postandrewsw, on 15 March 2019 - 06:48 AM, said:

You are passing in game_hash as parameter 'hash' but then try to refer to it as 'game_hash' within the method.


I still get the same error after I rectify that mistake
Was This Post Helpful? 0
  • +
  • -

#4 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,229
  • Joined: 12-December 12

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 07:00 AM

Post your rectification. (If it is exactly the same error then it probably has not been rectified ;))

Actually, you have defined game_hash as both a method and a hash. Clarify it by using different, appropriate, names, or remove the function entirely.
Was This Post Helpful? 0
  • +
  • -

#5 Gh05t_97   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 10
  • Joined: 11-March 19

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 07:10 AM

View Postandrewsw, on 15 March 2019 - 07:00 AM, said:

Post your rectification. (If it is exactly the same error then it probably has not been rectified ;)/>)

Actually, you have defined game_hash as both a method and a hash. Clarify it by using different, appropriate, names, or remove the function entirely.


game_hash = {
		:home => 
		{
			:team_name => "Brooklyn Nets",
			:colors => ["Black", "White"],
			:players => {
				:player1 => {
					:name => "Alan Anderson",
					:number => 0,
					:shoe_size => 16,
					:points => 22,
					:rebounds => 12,
					:assists => 12,
					:steals => 3,
					:blocks => 1,
					:slam_dunks => 1
				},
				:player2 => {
					:name => "Reggie Evans",
					:number => 30,
					:shoe_size => 14,
					:points => 12,
					:rebounds => 12,
					:assists => 12,
					:steals => 12,
					:blocks => 12,
					:slam_dunks => 7
				},
				:player3 => {
					:name => "Brook Lopez",
					:number => 11,
					:shoe_size => 17,
					:points => 17,
					:rebounds => 19,
					:assists => 10,
					:steals => 3,
					:blocks => 1,
					:slam_dunks => 15
				},
				:player4 => {
					:name => "Mason Plumlee",
					:number => 1,
					:shoe_size => 19,
					:points => 26,
					:rebounds => 12,
					:assists => 6,
					:steals => 3,
					:blocks => 8,
					:slam_dunks => 5
				},
				:player5 => {
					:name => "Jason Terry",
					:number => 31,
					:shoe_size => 15,
					:points => 19,
					:rebounds => 2,
					:assists => 2,
					:steals => 4,
					:blocks => 11,
					:slam_dunks => 1
		
				}
		},		

		:away =>
		{
			:team_name => "Charlotte Hornets",
			:colors => ["Turquoise", "Purple"],
			:players => {
				:player1 => {
					:name => "Jeff Adrien",
					:number => 4,
					:shoe_size => 18,
					:points => 10,
					:rebounds => 1,
					:assists => 1,
					:steals => 2,
					:blocks => 7,
					:slam_dunks => 2
				},
				:player2 => {
					:name => "Bismak Biyombo",
					:number => 0,
					:shoe_size => 16,
					:points => 12,
					:rebounds => 4,
					:assists => 7,
					:steals => 7,
					:blocks => 15,
					:slam_dunks => 10
				},
				:player3 => {
					:name => "DeSagna Diop",
					:number => 2,
					:shoe_size => 14,
					:points => 24,
					:rebounds => 12,
					:assists => 12,
					:steals => 4,
					:blocks => 5,
					:slam_dunks => 5
				},
				:player4 => {
					:name => "Ben Gordon",
					:number => 8,
					:shoe_size => 15,
					:points => 33,
					:rebounds => 3,
					:assists => 2,
					:steals => 1,
					:blocks => 1,
					:slam_dunks => 0
				},
				:player5 => {
					:name => "Brendon Haywood",
					:number => 33,
					:shoe_size => 15,
					:points => 6,
					:rebounds => 12,
					:assists => 12,
					:steals => 22,
					:blocks => 5,
					:slam_dunks => 12
				}
			}
		}
	}
}




def big_shoe_rebounds(h)
  #will return the number of rebounds associated with the player that has the largest shoe size
	# STEP1: find the player with the biggest shoe size
	#STEP 2: return that players number of rebounds
  h.each do |team, data|
    data.each do |attribute, values|
      if attribute == :players
        values.each do |player_number, player_data|
          if player_data == [:shoe_size].max
            return game_hash[teams_playing][attribute][player_number][:rebounds]
          end 
        end 
      end 
    end 
  end
end 

big_shoe_rebounds(game_hash) 


Now, I get no output from this code
Was This Post Helpful? 0
  • +
  • -

#6 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,229
  • Joined: 12-December 12

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 07:12 AM

Where are you expecting it to produce/display some output?
Was This Post Helpful? 0
  • +
  • -

#7 Gh05t_97   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 10
  • Joined: 11-March 19

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 07:49 AM

View Postandrewsw, on 15 March 2019 - 07:12 AM, said:

Where are you expecting it to produce/display some output?


I'm expecting it to display the number of rebounds associated with the largest shoe sizes from both teams. I also found some more errors and decided to fix it, now I get no output from my code. Heres the updated version.

def big_shoe_rebounds(h)
  	#will return the number of rebounds associated with the player that has the largest shoe size
	# STEP1: find the player with the biggest shoe size
	#STEP 2: return that players number of rebounds
  h.each do |team, data|
    data.each do |attribute, values|
      if attribute == :players
        values.each do |player_number, player_data|
          if player_data == [:shoe_size].max
            return h[team][attribute][player_number][:rebounds]
          end 
        end 
      end 
    end 
  end
end 

big_shoe_rebounds(game_hash)


Was This Post Helpful? 0
  • +
  • -

#8 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,229
  • Joined: 12-December 12

Re: How do I select the largest key: value pair in a nested hash?

Posted 15 March 2019 - 07:54 AM

Again, you are are not outputting or displaying anything. There are no puts statements, just looping, if, etc..

(Ruby has a tendency to resolve to the last value, as I recall, but this doesn't necessarily mean that it will be displayed in a console or terminal.)
Was This Post Helpful? 0
  • +
  • -

#9 BobRodes   User is offline

  • Product Manager
  • member icon

Reputation: 603
  • View blog
  • Posts: 3,085
  • Joined: 19-May 09

Re: How do I select the largest key: value pair in a nested hash?

Posted 19 March 2019 - 11:55 PM

You've taken a solid crack at this, so I'll give you a code review and help you fix it.

First, your less-than-meticulous approach to indenting and bracketing has caused you to leave out a curly brace. So, :home is one, :players is two, and :player5 is three. You'll notice only two closing brackets between :player5 and :away, which causes :away to be on the same level as :players rather than :home. Messy, messy. :)

Many of the unpredictable results you've been getting have been due to this. I ran your hash through rubocop (you should install and use it, just google) with the -a switch. Trust me, I didn't do all that cleaning up by hand:

Now. This screams out for using #map rather than #each. #each returns the original hash, which isn't a heck of a lot of help. #map returns what you tell it to. So use #map. Ignore the keys, use the values. The values are hashes, so you can drill down by working with them. So you map the :home and :away, and inside the block, you map the :players. Then you can get the shoe size and the rebounds in an array of arrays, find the max value, return the rebounds, and, as the Brits say, Bob's your uncle.

Have a look at the notes I put in the method, and be more careful with indenting and bracketing. And get rubocop. Also, you need to know very well how Ruby returns values from method calls, and the differences between the behaviors of #each, #map and #select. You do those few things, and you'll find that "newbie" feeling is pretty much gone.

game_hash = {
  home: {
    team_name: 'Brooklyn Nets',
    colors: %w(Black White),
    players: {
      player1: {
        name: 'Alan Anderson',
        number: 0,
        shoe_size: 16,
        points: 22,
        rebounds: 12,
        assists: 12,
        steals: 3,
        blocks: 1,
        slam_dunks: 1
      },
      player2: {
        name: 'Reggie Evans',
        number: 30,
        shoe_size: 14,
        points: 12,
        rebounds: 12,
        assists: 12,
        steals: 12,
        blocks: 12,
        slam_dunks: 7
      },
      player3: {
        name: 'Brook Lopez',
        number: 11,
        shoe_size: 17,
        points: 17,
        rebounds: 19,
        assists: 10,
        steals: 3,
        blocks: 1,
        slam_dunks: 15
      },
      player4: {
        name: 'Mason Plumlee',
        number: 1,
        shoe_size: 19,
        points: 26,
        rebounds: 12,
        assists: 6,
        steals: 3,
        blocks: 8,
        slam_dunks: 5
      },
      player5: {
        name: 'Jason Terry',
        number: 31,
        shoe_size: 15,
        points: 19,
        rebounds: 2,
        assists: 2,
        steals: 4,
        blocks: 11,
        slam_dunks: 1
      }
    }
  },
  away:   {
    team_name: 'Charlotte Hornets',
    colors: %w(Turquoise Purple),
    players: {
      player1: {
        name: 'Jeff Adrien',
        number: 4,
        shoe_size: 18,
        points: 10,
        rebounds: 1,
        assists: 1,
        steals: 2,
        blocks: 7,
        slam_dunks: 2
      },
      player2: {
        name: 'Bismak Biyombo',
        number: 0,
        shoe_size: 16,
        points: 12,
        rebounds: 4,
        assists: 7,
        steals: 7,
        blocks: 15,
        slam_dunks: 10
      },
      player3: {
        name: 'DeSagna Diop',
        number: 2,
        shoe_size: 14,
        points: 24,
        rebounds: 12,
        assists: 12,
        steals: 4,
        blocks: 5,
        slam_dunks: 5
      },
      player4: {
        name: 'Ben Gordon',
        number: 8,
        shoe_size: 15,
        points: 33,
        rebounds: 3,
        assists: 2,
        steals: 1,
        blocks: 1,
        slam_dunks: 0
      },
      player5: {
        name: 'Brendon Haywood',
        number: 33,
        shoe_size: 15,
        points: 6,
        rebounds: 12,
        assists: 12,
        steals: 22,
        blocks: 5,
        slam_dunks: 12
      }
    }
  }
}

def big_shoe_rebounds(game_hash) 
  # First level, :home and :away. (Underscore because we are ignoring the key.)
  game_hash.map do |_, venue|
    # Next level, :players. (You need to say return here or you'll return the outer map.)
    return venue[:players].map do |_, player|
      # return value is an array of arrays, each one with the shoe size and the rebounds.
      [player[:shoe_size], player[:rebounds]]
    # You can tack the #max_by method right on the end of the block.
    # Find the max value of the first array element, which is the shoe size.
    # You can also tack the other index reference right on the block, too.
    # That's the rebounds.
    end.max_by { |e| e[0] }[1] 
  end
end 

# As Andrew pointed out, you didn't do anything with the return value.
puts big_shoe_rebounds(game_hash)



This post has been edited by BobRodes: 20 March 2019 - 12:08 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1