diff --git a/cheatsheets/arrays.rb b/cheatsheets/arrays.rb new file mode 100644 index 000000000..e1d795df4 --- /dev/null +++ b/cheatsheets/arrays.rb @@ -0,0 +1,207 @@ +# ===== Initializing ===== +[1, 2, 3] # => [1, 2, 3] +Array.new(2) # => [nil, nil] +Array.new(5) { |i| i * 5 } # => [0, 5, 10, 15, 20] +Array.new(2) { Array.new(2) } # => [[nil, nil], [nil, nil]] +ary = [] # => [] +ary = Array.new # => [] +# initializing an array of strings on whitespace +%w[this that, and the other] # => ["this", "that,", "and", "the", "other"] + +# ===== Accessing and assigning ===== +ary = %w[ruby python perl php javascript c] +ary[0] # => "ruby" +ary[1] # => "python" +ary[2] # => "perl" +ary[3] # => "php" +ary[4] = "ecmascript" +ary # => ["ruby", "python", "perl", "php", "ecmascript", "c"] + +# negative indexes are applied from the end +ary[-1] # => "c" +ary[-2] # => "ecmascript" +ary[-3] # => "php" + +# first and last (unfortunately can't do ary.first = 'abc' , for reasons that will become clearer when we talk more about the object model) +ary.first # => "ruby" +ary.last # => "c" + +# subarrays, give a range of indexes, or a start index and length +ary # => ["ruby", "python", "perl", "php", "ecmascript", "c"] +ary[0..2] # => ["ruby", "python", "perl"] +ary[-3..-1] # => ["php", "ecmascript", "c"] +ary[2, 3] # => ["perl", "php", "ecmascript"] + +# can replace a range of indexes with elements from an array (size doesn't need to match) +ary # => ["ruby", "python", "perl", "php", "ecmascript", "c"] +ary[1..2] = [9, 8, 7, 6, 5, 4, 3, 2, 1] +ary # => ["ruby", 9, 8, 7, 6, 5, 4, 3, 2, 1, "php", "ecmascript", "c"] + +ary = Array(0..10) # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +ary.insert(5, "five") +ary # => [0, 1, 2, 3, 4, "five", 5, 6, 7, 8, 9, 10] + +# ===== Sorting ===== +before = [3, 6, 3, 0, 8, 235, -3] +after = before.sort +before # => [3, 6, 3, 0, 8, 235, -3] +after # => [-3, 0, 3, 3, 6, 8, 235] + +# a bang on the end of a method means "watch out", many methods have a "safe" version which will return a new object +# and a "dangerous" version, which will mutate the current object. (this is not it's only use, so check the docs ;) +before # => [3, 6, 3, 0, 8, 235, -3] +before.sort! +before # => [-3, 0, 3, 3, 6, 8, 235] + +# you can sort based on your own criteria, your block must simply evaluate to -1 , 0 , or 1 +# This is the same as Java's compareTo method. We have a method like that already, our spaceship operator +# if this example is too confusing, let me know (or if it's cake, you can brag) +after = + before.sort do |a, b| + b <=> a # sort such that larger elements come first + end +before # => [-3, 0, 3, 3, 6, 8, 235] +after # => [235, 8, 6, 3, 3, 0, -3] + +# An object with a name and age +class Person + attr_accessor "name", "age" + def initialize(name, age) + @name, @age = name, age + end + def inspect + "<#{name}(#{age})>" + end +end + +# whatever the block returns will be used to sort the object +people = [ + Person.new("Ernie", 20), + Person.new("Sara", 50), + Person.new("Monique", 10), + Person.new("Mohammed", 60) +] +people.sort_by { |person| person.age } # => [, , , ] + +# ===== Adding / removing / replacing / finding elements ===== + +# appending / pushing / popping (never have to write a stack again) +ary = [1, 2, 3] +ary << 4 +ary # => [1, 2, 3, 4] +ary.push 5 +ary # => [1, 2, 3, 4, 5] +ary.pop # => 5 +ary # => [1, 2, 3, 4] + +# if you want to push / pop from the beginning, it's called unshifting and shifting +# to help you remember which is which, it might help to associate shift with the assembly command shl +ary = [1, 2, 3] +ary.unshift 0 +ary # => [0, 1, 2, 3] +ary.shift # => 0 +ary # => [1, 2, 3] + +# removing items +ary = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +ary.delete 5 +ary # => [1, 2, 3, 4, 6, 7, 8, 9, 10] + +ary = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +ary.reject { |i| i % 2 == 0 } # => [1, 3, 5, 7, 9] +ary.select { |i| i % 2 == 0 } # => [2, 4, 6, 8, 10] + +# checking for an object +ary = Array(3..10) # => [3, 4, 5, 6, 7, 8, 9, 10] +ary.include?(5) # => true +ary.index(5) # => 2 +ary.include?(11) # => false +ary.index(11) # => nil + +# ===== Iterating ===== + +# iterate over each element +sum, ary = 0, [1, 2, 3] +ary.each { |num| sum += num } +sum # => 6 + +# iterating over each index , capture results in a new Array +results = Array.new +%w[a b c].each_index { |i| results.push i } +results # => [0, 1, 2] + +# what if you care about both elements and indexes? +results = Array.new +%w[a b c].each_with_index do |character, index| + results.push "index #{index} holds element #{character}" +end +results # => ["index 0 holds element a", "index 1 holds element b", "index 2 holds element c"] + +# create a new array, where each element is derived from the original array +# whatever the block returns (its last line) will be at that index in the new array +ary = [0, 1, 1, 1, 1, 3] +ary.map { |num| num * 2 } # => [0, 2, 2, 2, 2, 6] +ary.map { |num| %w[zero one two three][num] } # => ["zero", "one", "one", "one", "one", "three"] + +# iterate over multiple elements +result = [] +Array(1..10).each_slice(2) { |a, b| result << [a, b] } +result # => [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] + +result = [] +Array(1..10).each_cons(2) { |a, b| result << [a, b] } +result # => [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]] + +# ===== Miscellaneous useful shit ===== +# equality +[1, 2, 3] == [1, 2, 3] # => true +[1, 2, 3] == [3, 2, 1] # => false + +# repetition +[1, 22] * 3 # => [1, 22, 1, 22, 1, 22] + +# concatenation +[1, 2] + %w[3 4] # => [1, 2, "3", "4"] + +# difference +[1, 2, 3, 4] - [3, 5] # => [1, 2, 4] + +# max and min +[3, 4, 13, 2, -3, 7].max # => 13 +[3, 4, 13, 2, -3, 7].min # => -3 + +# intersection +[1, 3, 4] & [0, 3, 4, 5] # => [3, 4] + +# union (order is not guaranteed) +[1, 3, 4] | [0, 3, 4, 5] # => [1, 3, 4, 0, 5] + +# convert each element to a string, and join them together +[1, 2, 3].join(" and ") # => "1 and 2 and 3" + +# length / size (get tired of trying to remember which is correct? In Ruby, they both are ^_^) +[1, 2, 3].length # => 3 +[1, 2, 3].size # => 3 + +# reverse +[1, 2, 3].reverse # => [3, 2, 1] + +# transpose +a = [1, 2, 3] +b = %w[one two three] +[a, b].transpose # => [[1, "one"], [2, "two"], [3, "three"]] +a.zip b # => [[1, "one"], [2, "two"], [3, "three"]] + +# assigning to variables +a = [1, 2, 3] +num1, num2, num3 = a +num1 # => 1 +num2 # => 2 +num3 # => 3 + +# "removing" the brackets to feed as arguments +def sum(x, y, z) + x + y + z +end +a = [1, 2, 3] +sum(*a) # => 6 diff --git a/cheatsheets/hashes.rb b/cheatsheets/hashes.rb new file mode 100644 index 000000000..feca56ee6 --- /dev/null +++ b/cheatsheets/hashes.rb @@ -0,0 +1,118 @@ +# http://ruby-doc.org/core/classes/Hash.html + +# ===== Initializing ===== +# populated +{ 1 => "one", 2 => "two" } # => {1=>"one", 2=>"two"} +Hash[1, "one", 2, "two"] # => {1=>"one", 2=>"two"} + +# empty +{} # => {} +Hash.new # => {} + +# ===== Nonexistent Keys ===== +# by default, nonexistent keys return nil +hash = Hash.new # => {} +hash[:josh] # => nil + +# to change this behaviour, you can pass new a block that receives the hash and the nonexistent key +# and then adds it to the hash in the way that you would like +aliases = Hash.new { |this_hash, key| this_hash[key] = Array.new } +aliases # => {} +aliases[:josh] # => [] +aliases # => {:josh=>[]} +aliases[:jeff] << "the dude" << "his dudeness" << "duder" << "el duderino" +aliases # => {:josh=>[], :jeff=>["the dude", "his dudeness", "duder", "el duderino"]} + +# ===== Access and Assign ===== +# generally access and assign like ths +hash = Hash.new +hash # => {} +hash["my key"] = "my value" +hash # => {"my key"=>"my value"} +hash["my key"] # => "my value" + +# access multiple values at once +hash = Hash[*[Array("a".."j"), Array(1..10)].transpose.flatten] # just populating +hash # => {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, "g"=>7, "h"=>8, "i"=>9, "j"=>10} +hash.values_at "j", "e", "i", :x # => [10, 5, 9, nil] + +# more interesting options with fetch (think how this might be helpful in param default values) +hash = { "a" => 100, "b" => 200 } +hash.fetch "a" # => 100 +hash.fetch "z", "go fish" # => "go fish" +hash.fetch("z") { |el| "go fish, #{el}" } # => "go fish, z" + +# sometimes you might use has_key to check for a key, for example, if you're using an init block +hash = Hash.new { true } +hash[:a] = :b +hash[1000] # => true +hash.has_key? 1000 # => false + +hash = { 12 => nil } +hash[12] # => nil +hash[13] # => nil +hash.has_key? 12 # => true +hash.has_key? 13 # => false + +# and the converse +hash = { "a" => 100, "b" => 200 } +hash.has_value?(100) # => true +hash.has_value?(999) # => false + +# ===== Removal ===== +# delete accepts a key and returns its value. You can give a block that will be invoked and returned +# in the event that the keyt o delete was not seen +hash = Hash[*Array(1..10)] # => {1=>2, 3=>4, 5=>6, 7=>8, 9=>10} +hash.delete 1 # => 2 +hash.delete 100 # => nil +hash # => {3=>4, 5=>6, 7=>8, 9=>10} +hash.delete(3) { |n| "#{n} not found" } # => 4 +hash.delete(100) { |n| "#{n} not found" } # => "100 not found" + +# delete_if to remove all pairs from a hash +# that cause the block to evaluate to true +hash = Hash[*Array(1..10)] # => {1=>2, 3=>4, 5=>6, 7=>8, 9=>10} +hash.delete_if { |key, value| key % 5 == 0 || value % 5 == 0 } +hash # => {1=>2, 3=>4, 7=>8} + +# ===== Iterating ===== +# pass a block that receives the key and the value +cities = { Chicago: :USA, Paris: :France, Ramstein: :Germany } +results = Array.new +cities.each { |city, country| results << "#{city} is in #{country}" } +results # => ["Chicago is in USA", "Paris is in France", "Ramstein is in Germany"] + +# ===== Other Useful Methods ===== + +# there is also a self mutator version: merge! +defaults = { color: :red, city: "Wichita" } +custom = { city: "Boston" } +merged = defaults.merge custom +defaults # => {:color=>:red, :city=>"Wichita"} +custom # => {:city=>"Boston"} +merged # => {:color=>:red, :city=>"Boston"} + +cities = { Chicago: :USA, Paris: :France, Ramstein: :Germany } +cities.keys # => [:Chicago, :Paris, :Ramstein] +cities.values # => [:USA, :France, :Germany] +cities.length # => 3 +cities.size # => 3 +cities.empty? # => false +Hash.new.empty? # => true + +hash = Hash[*Array(1..10)] +hash # => {1=>2, 3=>4, 5=>6, 7=>8, 9=>10} +hash.clear +hash # => {} + +# get a key for a given value (remember, there could be more than one key with the same value) +hash = { "a" => 100, "b" => 200 } +hash.index(200) # => "b" # !> Hash#index is deprecated; use Hash#key +hash.index(999) # => nil # !> Hash#index is deprecated; use Hash#key + +# swap keys with values +hash = { n: 1, m: 1, o: 2 } # n and m have the same value, n ends up getting squashed +hash.invert # => {1=>:m, 2=>:o} + +# convert to an array +{ Chicago: :USA, Paris: :France, Ramstein: :Germany }.to_a # => [[:Chicago, :USA], [:Paris, :France], [:Ramstein, :Germany]] diff --git a/cheatsheets/logic_and_control.rb b/cheatsheets/logic_and_control.rb new file mode 100644 index 000000000..a0dda69d6 --- /dev/null +++ b/cheatsheets/logic_and_control.rb @@ -0,0 +1,104 @@ +# ===== Logical Operators ===== +a, b, c = 1, 2, 3 +a == b && a == c # logical and +a == b || a == c # logical or + +# less than, greater than +4 < 5 # => true +4 < 3 # => false + +4 > 3 # => true +4 > 5 # => false + +# less/greater than or equal to +4 <= 3 # => false +4 <= 4 # => true +4 <= 5 # => true + +4 >= 3 # => true +4 >= 4 # => true +4 >= 5 # => false + +# equal to +4 == 3 # => false +4 == 4 # => true + +# ===== General syntax of an if statement ===== +def one_two_or_three(n) + if n == 1 + return "one" + elsif n == 2 + return "two" + else + return "three" + end +end + +one_two_or_three 1 # => "one" +one_two_or_three 2 # => "two" +one_two_or_three 3 # => "three" + +# ===== Single line ===== +result = "set" +result = "modified once" if 1 == 1 +result # => "modified once" +result = "modified twice" if 1 != 1 +result # => "modified once" + +# ===== ! to negate ===== +result = "set" +result = "modified once" if !false +result # => "modified once" +result = "modified twice" if !true +result # => "modified once" + +# ===== False and nil are false, everything else is true ===== +!!false # => false +!!true # => true +!!nil # => false +!!Array.new # => true +!!String.new # => true +!!Regexp.new("") # => true + +# ===== Unless ===== +result = "set" +result = "modified once" unless 1 == 2 +result # => "modified once" +result = "modified twice" unless 1 == 1 +result # => "modified once" + +# ===== While ===== +i = 0 +ary = Array.new +while i < 5 + ary << i + i += 1 +end +ary # => [0, 1, 2, 3, 4] + +# ===== Loops ===== +ary = Array.new +5.times { |current| ary << current } +ary # => [0, 1, 2, 3, 4] + +ary = Array.new +1.step 10, 2 do |current| + ary << current +end +ary # => [1, 3, 5, 7, 9] + +# ===== Skip this iteration / Stop iterating ===== +ary = Array.new +10.times do |current| + next if current % 2 == 1 + ary << current +end +ary # => [0, 2, 4, 6, 8] + +# break out of a loop +ary = Array.new +10.times do |current| + break if current >= 5 + ary << current +end +ary # => [0, 1, 2, 3, 4] diff --git a/cheatsheets/strings.rb b/cheatsheets/strings.rb new file mode 100644 index 000000000..fff5cfad1 --- /dev/null +++ b/cheatsheets/strings.rb @@ -0,0 +1,66 @@ +# This should get you started. +# But to see all the cool things you can do, check out the documentation +# +# http://ruby-doc.org/core/classes/String.html + +# Make a new string +"Can interpolate #{1 + 1}" # => "Can interpolate 2" +'Cannot interpolate #{1+1}' # => "Cannot interpolate \#{1+1}" + +string = < " THIS IS A HERE DOCUMENT, I CAN INTERPOLATE 1\n IT WILL CONTINUE UNTIL IT FINDS, THE LINE END_OF_DOC BY ITSELF.\n NOTICE I CAN CONTINUE DOING THINGS ON THE LINE THE HERE DOCUMENT IS DEFINED IN.\n HERE I CALLED STRING#UPCASE ON IT.\n" + +# Useful methods +"abc".length # => 3 +"abc" == "abc" # => true +"abc" == "def" # => false +"AbCd".downcase # => "abcd" +"AbCd".upcase # => "ABCD" +" abc ".strip # => "abc" + +# concatenation +"hello" + "world" # => "helloworld" +"hello" << "world" # => "helloworld" +# wait O.o why two methods for this? +s = "abc" +s + "def" # => "abcdef" +s # => "abc" +s << "def" # => "abcdef" +s # => "abcdef" + +# Access parts of the string (-1 counts backwards from the end) +"abc"[-1] # => "c" +"abc"[0] # => "a" +"abc"[1] # => "b" +"abc"[2] # => "c" +"abc"[3] # => nil +"abcdefg"[2..4] # => "cde" +"abcdefg"[4..-1] # => "efg" + +# Changing parts of a string +message = "Josh said" +message["Josh"] = "dom" +message # => "dom said" +message += ' "Howdy"' +message # => "dom said \"Howdy\"" +message.capitalize # => "Dom said \"howdy\"" +message # => "dom said \"Howdy\"" +message[-2] = "e" +message # => "dom said \"Howde\"" +message[-2] = "y!" +message # => "dom said \"Howdy!\"" + +# Other useful methods (some of these use regular expressions, we'll talk about them more later) +"abc" * 3 # => "abcabcabc" +" abc \n".chomp # => " abc " +"trite".gsub("t", "b") # => "bribe" +"Their IDs are 11, and 492".scan(/\d+/) # => ["11", "492"] +"Jack and Jill ran up the hill".split # => ["Jack", "and", "Jill", "ran", "up", "the", "hill"] +"/usr/bin:/opt/local:/Users/josh".split(":") # => ["/usr/bin", "/opt/local", "/Users/josh"] +"abcdefg hi".split(//) # => ["a", "b", "c", "d", "e", "f", "g", " ", "h", "i"] diff --git a/session1/3-challenge/1_arithmetic.rb b/session1/3-challenge/1_arithmetic.rb index 049ece773..7f4a3ddd2 100644 --- a/session1/3-challenge/1_arithmetic.rb +++ b/session1/3-challenge/1_arithmetic.rb @@ -9,5 +9,5 @@ # arithmetic1(-6) # => -50 def arithmetic1(n) - + n * 5 - 20 end diff --git a/session1/3-challenge/2_arithmetic.rb b/session1/3-challenge/2_arithmetic.rb index 21445b427..14afd38d4 100644 --- a/session1/3-challenge/2_arithmetic.rb +++ b/session1/3-challenge/2_arithmetic.rb @@ -1,7 +1,6 @@ # fill out the method below, then run the tests with # $ rake 1:2 - # Given two numbers, a and b, return half of whichever is smallest, as a float # # arithmetic2(1, 2) # => 0.5 @@ -9,4 +8,5 @@ # arithmetic2(-6, -7) # => -3.5 def arithmetic2(a, b) + a < b ? a.to_f / 2 : b.to_f / 2 end diff --git a/session1/3-challenge/3_simple_logic.rb b/session1/3-challenge/3_simple_logic.rb index 29f8c5037..419f05fd8 100644 --- a/session1/3-challenge/3_simple_logic.rb +++ b/session1/3-challenge/3_simple_logic.rb @@ -1,11 +1,15 @@ # remember, you can test this file with # $ rake 1:3 - # Given a number, n, return 10 if it is even, and 20 if it is odd # # ten_twenty(5) # => 20 # ten_twenty(6) # => 10 def ten_twenty(n) + if n.even? + return 10 + else + return 20 + end end diff --git a/session1/3-challenge/4_logic.rb b/session1/3-challenge/4_logic.rb index 015c11bac..764f7da21 100644 --- a/session1/3-challenge/4_logic.rb +++ b/session1/3-challenge/4_logic.rb @@ -11,8 +11,13 @@ # <10 books => D, 10..20 books => C, >20 book =>B - def grade(num_books, has_read_books) -end - - + if has_read_books + return "C" if num_books < 10 + return "B" if num_books <= 20 + return "A" + else + return "D" if num_books < 10 + return "C" if num_books <=20 + return "B" + end \ No newline at end of file diff --git a/session1/3-challenge/5_string.rb b/session1/3-challenge/5_string.rb index ed15e87ad..cfa605f5c 100644 --- a/session1/3-challenge/5_string.rb +++ b/session1/3-challenge/5_string.rb @@ -1,8 +1,9 @@ # Given a string, replace every instance of sad to happy -# +# # add_more_ruby("The clowns were sad.") # => "The clowns were happy." # add_more_ruby("The sad dad said sad stuff.") # => "The happy dad said happy stuff." # add_more_ruby("Sad times are ahead!") # => "Happy times are ahead!" def add_more_ruby(string) -end \ No newline at end of file + string.gsub("sad", "happy").gsub("Sad", "Happy") +end diff --git a/session1/3-challenge/6_string.rb b/session1/3-challenge/6_string.rb index 4dc3a4e83..30cd9780b 100644 --- a/session1/3-challenge/6_string.rb +++ b/session1/3-challenge/6_string.rb @@ -2,9 +2,30 @@ # When the boolean is true, return a new string containing all the odd characters. # When the boolean is false, return a new string containing all the even characters. # -# If you have no idea where to begin, remember to check out the cheatsheets for string and logic/control -# +# If you have no idea where to begin, remember to check out the cheatsheets for string and logic/control. def odds_and_evens(string, return_odds) + even = + string + .split("") + .select + .each_with_index { |character, index| index.even? } + .join + + # split string then select each char with the index of even. + + odd = + string + .split("") + .select + .each_with_index { |character, index| index.odd? } + .join + + # split string then select each char with the index of odd. -end \ No newline at end of file + if return_odds == true + return odd + else + return even + end +end diff --git a/session1/3-challenge/7_string.rb b/session1/3-challenge/7_string.rb index 841278b6a..11952890c 100644 --- a/session1/3-challenge/7_string.rb +++ b/session1/3-challenge/7_string.rb @@ -5,5 +5,24 @@ # pirates_say_arrrrrrrrr("Pirates say arrrrrrrrr") # => "arrrrrrrr" def pirates_say_arrrrrrrrr(string) + string_split = string.split("") + new_array = [] + # split characters from string. + # create new array for storing edited string. + + string_split.each_with_index do |l, i| + # p "#{i}: #{l}" if l.include?("r") + new_array.push(string_split[i + 1]) if l =~ /[Rr]/ + end + + # find index of each string in split array. + # able to print index: letter. + # able to print index: letter if l.include?("r"). + # can push letters to new_array if contain [rR]. + # can push letters[index + 1] to new_array if contain [rR]. + + return new_array.join end + +p pirates_say_arrrrrrrrr("are you really learning Ruby?")