Skip to content

Instantly share code, notes, and snippets.

@yoshprogrammer
Last active August 29, 2015 14:01
Show Gist options
  • Save yoshprogrammer/bc1f5adc69987a9fdfcf to your computer and use it in GitHub Desktop.
Save yoshprogrammer/bc1f5adc69987a9fdfcf to your computer and use it in GitHub Desktop.
35-Count-In-List-Attempt-JoshuaBrown
# Method name: count_in_list(list, item_to_count)
# Inputs: 1. a list of anything, 2. an item for us to count in the list
# Returns: The number of times our item is contained in the input list
# Prints: Nothing
#
# For example,
# count_in_list([1,2,3], 1) == 1
# count_in_list([1,2,3], -1) == 0
# count_in_list([1,1,1], 1) == 3
# You'll need three things:
# 1. A running total of the number of times you've seen the item
# 2. A way to loop/iterate through the list
# 3. A way to add to the running total as you see the item
def count_in_list(list, item_to_count) # start of the defining the method
running_total = 0 # telling the variable running_total where to start or 'inialitzing'
for item in list # For each item in the list do the following:
if item == item_to_count then # Used an If/then. If present item equals the item_to_count then do the following
running_total = running_total + 1 #if item is the item we are lookign for, add one to the running_total
end
end
running_total # give me the running total
end
p count_in_list([1,1,1], 1)
p count_in_list([2,2,5], 2)
p count_in_list([5,2,5,3,55,223,3525,2514], 5)
p count_in_list([5,2,5,3,55,223,3525,2514], 5) == 2
p count_in_list([5,2,5,3,55,223,3525,2514], 5) == 23
# Question #1:
#-In Ruby or programming in general, do I need to include an else statement? In this instance all I wanted to have else do
# is nothing or add zero to the running total. How would I implement it to do nothing? I know I can add another line
# saying, else running_total = running_total + 0
# Question #2:
# It seems there are multiple ways to approach each problem. Is there a rule to which method you use as you progress in
# programming? Is it just whatever makes sense to you or is there downfalls to some methods?
#Side-note, I found it extremely helpful to actually write out in a notebook what I was trying to accomplish.
# I wrote, 'for each item in list, if item = item_to_count then add (1) to running total. If not then add (0). Print running
# total. I'm going to do this for future exercises and see if it helps more. I also thought like a computer, and how I would
# look at each list, circle the number and add it to the total thus far.
@jfarmer
Copy link

jfarmer commented May 26, 2014

Answers!

In Ruby or programming in general, do I need to include an else statement? In this instance all I wanted to have else do is nothing or add zero to the running total.

Conceptually, never, and in terms of Ruby and most programming languages, almost never. It works like English, for the most part. "If I am hungry then eat." There's no "else, don't eat" or "else" anything, for that matter.

If you have no else, nothing happens.

It seems there are multiple ways to approach each problem. Is there a rule to which method you use as you progress in programming? Is it just whatever makes sense to you or is there downfalls to some methods?

As much as it might be frustrating to hear, there's no right answer to this. :)

More important than understanding the 50 tools in the toolshed is really, really understanding the problem and being comfortable with a small number of simple, adaptable tools. Every new tool is built from these simpler tools.

Here are the simple tools you should be focusing on now (I'm using _ as a dummy placeholder):

  1. Core data types (numbers, strings, booleans)
  2. Composite data types (arrays/, hashes)
  3. Variables and variable assignment
  4. Branching — if _, elsif _, else, &&, ||, etc.
  5. Looping —while, for _ in _, _.each do |_|, etc.
  6. Defining and calling methods

These 6 are enough for you to write any program you can think of. The programs will be longer than Ruby written using "more advanced" tools, but those more advanced tools are both more situational and built from these fundamental building blocks.

In a short while, we'll add three new fundamental constructs to round things out:

  1. Objects
  2. Classes
  3. Blocks

These 9 things encompass every piece of Ruby code you can possibly write. The entirety of Rails is built using these 9 core tools, tools built from those core tools, tools built from tools built from those core tools, and so on.

That said, there is often a "right" answer or at least a "right enough" answer depending on your overall objectives and constraints. We might favor different solutions depending on the those constraints. For example, we might care about things like...

  1. Learning goals — important in our case!
  2. How long a program takes to run (CPU usage)
  3. How much memory a program consumes (memory/RAM usage)
  4. How much power our program consumes (battery/power usage)
  5. How much disk space our program consumes (disk usage)
  6. How much bandwidth our program consumes (network usage)
  7. How quickly we can get something to market
  8. The time and financial costs of our software
  9. How maintainable/readable/intelligible our code is
  10. External, non-technical requirements, e.g., a customer demands something, a law requires something, etc.
  11. External, technical requirements, e.g., the limitations of an API we have to use
  12. ...and many more

For example, getting in "deliberate practice" is a major goal/constraint of what we're doing here. If we were optimizing for how quickly we can get something to market, it'd be irresponsible to not look for pre-built solutions. When we care more about practicing and developing fundamental programming skills, it'd be irresponsible to always look for pre-built solutions.

As an example, arrays in Ruby actually have a built-in count method that can do everything your count_in_list method does (and more). You can read the Array#count documentation yourself, if only to get used to looking at technical documentation.

Here's a screenshot of it in action: http://cl.ly/image/3b0a2a1U2C3e

That means count_in_list could be implemented thus:

def count_in_list(list, item_to_count)
  list.count do |item|
    item == item_to_count
  end
end
# Remember: the "do |item| ... end" syntax and the "{ |item| ... }" syntax
# mean exactly the same thing in Ruby.  Conventionally, we use "do |item| ... end"
# when we have multiple lines inside the "..." and use "{ |item| ... }"
# when we have one, simple line.

Well, gee! That's easy. But is this the "right" answer or a "better" answer? It's better from the perspective of idiomatic Ruby as a professional would write it, but much, much worse from the perspective of a student learning the fundamentals. Your count_in_list is actually an implementation of a bit of what Array#count does, so what would have seemed like a magic spell

list.count { |n| n == item_to_count }

is hopefully a wee bit less mysterious.

Side-note, I found it extremely helpful to actually write out in a notebook what I was trying to accomplish.

I wrote, 'for each item in list, if item = item_to_count then add (1) to running total. If not then add (0). Print running total. I'm going to do this for future exercises and see if it helps more. I also thought like a computer, and how I would look at each list, circle the number and add it to the total thus far.

Awesome! Yes! Keep doing this. That style of writing code is often called pseudocode and professionals use it all the time, whether writing in a notebook, on a whiteboard, or in their text editor of choice. When you watch either John or I building something from scratch, you'll see us doing this extensively.

It's also closely related to test-driven development, which in its most basic form is first writing the code you "wish you had" and then working from the outside in until your wishful code fulfills your wish.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment