Code for Thought

Changing the Way I Think About Complex Problems

I knew that doing the Flatiron Web-Immersion program would push me in many ways. The expectations are to go from zero programming skills to 100 in 12 short weeks. This means that every single day we are introduced to new concepts that seem so big, so important and so impossible to learn. It is overwhelming and can make you feel like you can’t accomplish any of it. Over the past three weeks I have mostly felt like a failure. Why can’t I understand these concepts? In the first week I understood a lot of what was going on. Simple ruby concepts like how to access values in a hash or in an array or how a conditional statement worked, I could understand, but the moment you asked me to do something more complex, I froze.

About half way through this past week I realized what one of the things that was holding me back was my mentality. I was spending so much energy on “I can’t” instead of telling myself “you can, just go one simple step at a time”. When working on more complex problems, I started telling myself, “Start with what you know. I can access these values in a hash, and then use binding.pry to figure out the rest one step at a time.” This mentality shift has helped in so many ways. Number one, I am spending less energy on “I can’t do this” and more on learning how to actually do it. And number two, I feel less paralyzed when hard concepts are introduced to me.

Break Down Each Task to Things I Understand

One example of my new outlook to understand more complex concepts (breaking things down to the concepts I do get and moving forward from there) can be seen when looking at our NYC Pigeon’s Lab that asked us to take a hash that looked like this…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pigeon_data = {
  :color => {
    :purple => ["Theo", "Peter Jr.", "Lucky"],
    :grey => ["Theo", "Peter Jr.", "Ms. K"],
    :white => ["Queenie", "Andrew", "Ms. K", "Alex"],
    :brown => ["Queenie", "Alex"]
  },
  :gender => {
    :male => ["Alex", "Theo", "Peter Jr.", "Andrew", "Lucky"],
    :female => ["Queenie", "Ms. K"]
  },
  :lives => {
    "Subway" => ["Theo", "Queenie"],
    "Central Park" => ["Alex", "Ms. K", "Lucky"],
    "Library" => ["Peter Jr."],
    "City Hall" => ["Andrew"]
  }
} 

And create one that looked like this…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
pigeon_list = {
  "Theo" => {
    :color => ["purple", "grey"],
    :gender => ["male"],
    :lives => ["Subway]"
  },
  "Peter Jr." => {
    :color => ["purple", "grey"],
    :gender => ["male"],
    :lives => ["Library]"
  },
  "Lucky" => {
    :color => ["purple"],
    :gender => ["male"],
    :lives => ["Central Park"]
  },
  "Ms. K" => {
    :color => ["grey", "white"],
    :gender => ["female"],
    :lives => ["Central Park"]
  },
  "Queenie" => {
    :color => ["white", "brown"],
    :gender => ["female"],
    :lives => ["Subway"]
  },
  "Andrew" => {
    :color => ["white"],
    :gender => ["male"],
    :lives => ["City Hall"]
  },
  "Alex" => {
    :color => ["white", "brown"],
    :gender => ["male"],
    :lives => ["Central Park"]
  }
} 

At first I froze. This seems impossible, how the heck can I switch values for keys and vise versa!? However, after I took a step back and remembered that accessing values is the same in this case as it is in one of our easier labs, I was able to breathe and start iterating through the hash, getting out the values I needed and setting up my new hash.

1
2
3
4
5
6
7
8
9
10
11
12
13
def nyc_pigeon_organizer(pigeon_data)
  new_hash = {}
  pigeon_data.each do |trait_group, trait_hash|
    trait_hash.each do |trait_details, names_array|
      names_array.each do |name|
      new_hash[name] ||= {}
      new_hash[name][trait_group] ||= []
      new_hash[name][trait_group] << trait_details.to_s
    end
  end
end
new_hash
end 

Helper Methods

Another helpful way to break down tasks is with helper methods. A helper method is a method that helps another method to perform its task. These are typically used when a method has to perform a complicated task that is composed of several smaller tasks. These methods can reduce confusion and help make our tasks more clear.

We saw helper methods come to the rescue one of the more complex hash labs - Hashketball. In this lab we broke down methods like how to find the number of points scored into two different methods. This let us organize the data into a simpler form and make solving the problem easier.

1
2
3
def num_points_scored(player_name)
  find_player_name(player_name)[:stats][:points] 
end
1
2
3
4
5
6
7
8
#helper method 
def find_player_name(player_name) 
  game_hash.each do |location, team_hash| 
    if team_hash[:players][player_name] 
      return team_hash[:players][player_name] 
    end
  end
end

I realized that code is code - a method used to do a certain task will always do that task. This part of code will alway be the same, but what a developer has control over is how they solve the problem. The logic they use, the specific methods they know that will help them solve the problem, and as in my case, their overall mindset in tackling a particularly complex problem. What I really learned this week was that aspect of coding. That the way I approach a problem may make it harder or easier to solve. I obviously need to understand the code behind solving the problem but I can get to those solutions easier when I take it slow, think about what I know, find out what I do not know and move in an orderly manner through any particular problem.