├── .gitignore ├── session6 ├── 5-solved │ ├── 1.rb │ └── 1_build_an_app │ │ ├── config.ru │ │ ├── Gemfile │ │ ├── views │ │ ├── decrypt.erb │ │ ├── encrypt.erb │ │ ├── layout.erb │ │ └── home.erb │ │ ├── Gemfile.lock │ │ ├── main.rb │ │ └── lib │ │ └── caesar_cipher.rb └── 1-notes │ ├── .rvmrc │ ├── 11-heroku-example │ ├── .rvmrc │ ├── spec │ │ └── username_spec.rb │ └── notes.rb │ ├── 09-static-files-and-bundler │ ├── .rvmrc │ ├── public │ │ └── dependencies.png │ ├── Gemfile │ ├── config.ru │ └── Gemfile.lock │ ├── 08-rack-and-reloading │ ├── main.rb │ └── config.ru │ ├── 06-sinatra-views-layouts-params-and-variables │ ├── views │ │ ├── home_page.erb │ │ ├── cart.erb │ │ └── layout.erb │ └── main.rb │ ├── 07-sinatra-routes.rb │ ├── 02-servers-and-rack.rb │ ├── 05-erb.rb │ ├── 10-git │ └── notes.rb │ ├── 01-web-introduction.rb │ ├── 03-framework-introduction.rb │ └── 04-sinatra.rb ├── session1 ├── 5-solved │ ├── 1.rb │ ├── 3.rb │ ├── 5.rb │ ├── 2.rb │ ├── 6.rb │ ├── 4.rb │ └── 7.rb ├── 3-challenge │ ├── 3_simple_logic.rb │ ├── 2_arithmetic.rb │ ├── 1_arithmetic.rb │ ├── 5_string.rb │ ├── 7_string.rb │ ├── 6_string.rb │ └── 4_logic.rb ├── 2-examples │ ├── 1_first_program.rb │ ├── 3_rememberer.rb │ ├── 2_check_odd.rb │ └── 4_rememberer2.rb ├── 1-notes │ ├── 19-nil.rb │ ├── 14-operators-on-strings.rb │ ├── 10-introducing-strings.rb │ ├── 13-single-vs-double-quotes.rb │ ├── 05-methods.rb │ ├── 03-object-definition.rb │ ├── 02-conventions.rb │ ├── 15-interpolation.rb │ ├── 22-if-else.rb │ ├── 12-puts.rb │ ├── 18-keywords.rb │ ├── 20-logic.rb │ ├── 16-p.rb │ ├── 04-variables.rb │ ├── 23-if-returns-a-value.rb │ ├── 08-operators.rb │ ├── 07-method-arguments.rb │ ├── 21-true-and-false.rb │ ├── 06-method-scope.rb │ ├── 09-numbers.rb │ ├── 11-stdin-and-stdout.rb │ ├── 24-go-do-the-challenges.rb │ └── 17-naming-conventions.rb └── 4-spec │ ├── 1.rb │ ├── 3.rb │ ├── 2.rb │ ├── 5.rb │ ├── 7.rb │ └── 4.rb ├── session5 ├── 5-solved │ ├── 6.rb │ ├── 5.rb │ ├── 7.rb │ ├── 8.rb │ ├── 4.rb │ ├── 1.rb │ ├── 2.rb │ └── 9.rb ├── .rvmrc ├── 3-challenge │ ├── 6_regex.rb │ ├── 3_modules.rb │ ├── 8_rubygems.rb │ ├── 9_regex.rb │ └── 5_exceptions_regex_reflection.rb ├── 1-notes │ ├── 16-rubygems-updating.rb │ ├── 18-gems-using-sinatra.rb │ ├── 11-regex-repetition.rb │ ├── 19-go-do-the-challenges.rb │ ├── 12-regex-boundaries.rb │ ├── 15-rubygems-introduction.rb │ ├── 02-modules-including.rb │ ├── 13-regex-groups.rb │ ├── 17-gems-installing.rb │ ├── 01-modules-introduction.rb │ ├── 14-gems-introduction.rb │ ├── 03-modules-extending.rb │ ├── 10-regex-characters.rb │ ├── 05-nesting-classes-and-modules.rb │ ├── 09-regex-how-to-match.rb │ ├── 08-regex-introduction.rb │ ├── 06-modules-namespacing.rb │ ├── 07-extending-main.rb │ └── 04-modules-example.rb └── 4-spec │ ├── 5.rb │ ├── 6.rb │ ├── 8.rb │ └── 3.rb ├── session4 ├── 5-solved │ ├── 4.rb │ ├── 7.rb │ ├── 3.rb │ ├── 5.rb │ ├── 9.rb │ ├── 6.rb │ ├── 2.rb │ ├── 1.rb │ └── 8.rb ├── 1-notes │ ├── 08.b-require.rb │ ├── 17-raising-your-own.rb │ ├── 12-super-to-invoke-inherited.rb │ ├── 10-subclasses-inherit-methods.rb │ ├── 11-overriding-inherited-methods.rb │ ├── 09-inheritance-introduction.rb │ ├── 14-ancestors.rb │ ├── 02-oror-return-values.rb │ ├── 15-exceptions-introduction.rb │ ├── 01-andand-return-values.rb │ ├── 04-introspection.rb │ ├── 08.a-require.rb │ ├── 05-ranges.rb │ ├── 13-inheritance-example.rb │ ├── 16-exceptions-rescuing.rb │ ├── 03-ororequals.rb │ ├── 07-working-dir-vs-file-dir.rb │ └── 06-files.rb ├── resources │ └── 8.1.template ├── 3-challenge │ ├── 7_introspection.rb │ ├── 4_oror.rb │ ├── 5_file.rb │ ├── 2_subclassing_require.rb │ ├── 9_exceptions.rb │ ├── 8_exceptions.rb │ ├── 3_inject_blocks_enumerable.rb │ └── 6_singleton_class_string.rb └── 4-spec │ ├── 4.rb │ ├── 7.rb │ ├── 5.rb │ ├── 8.rb │ ├── 1.rb │ ├── 6.rb │ └── 3.rb ├── session3 ├── 5-solved │ ├── 1.rb │ ├── 16.rb │ ├── 11.rb │ ├── 3.rb │ ├── 17.rb │ ├── 4.rb │ ├── 15.rb │ ├── 2.rb │ ├── 6.rb │ ├── 13.rb │ ├── 8.rb │ ├── 10.rb │ ├── 9.rb │ ├── 12.rb │ ├── 14.rb │ ├── 5.rb │ └── 7.rb ├── 3-challenge │ ├── 1_blocks.rb │ ├── 3_hashes.rb │ ├── 4_hashes.rb │ ├── 17_hashes.rb │ ├── 2_hashes.rb │ ├── 5_blocks.rb │ ├── 16_hash.rb │ ├── 8_blocks.rb │ ├── 6_arguments.rb │ ├── 14_var_args_and_hash.rb │ ├── 10_hashes.rb │ ├── 11_blocks_or_procs.rb │ └── 9_hashes.rb ├── 1-notes │ ├── 03-hash-introduction.rb │ ├── 06-hash-keys.rb │ ├── 19-putting-it-all-together.rb │ ├── 10-blocks-introduction.rb │ ├── 15-forwarding-blocks.rb │ ├── 04-hash-literals.rb │ ├── 11-block-params-and-return.rb │ ├── 20-last-words.rb │ ├── 07-hash-iterating.rb │ ├── 09-procs-can-see-their-environment.rb │ ├── 08-proc-introduction.rb │ ├── 13-difference-between-block-syntaxes.rb │ ├── 14-storing-blocks-for-later.rb │ ├── 02-symbols-always-the-same.rb │ ├── 12-all-methods-take-blocks.rb │ ├── 01-symbols-introduction.rb │ ├── 16-optional-params.rb │ ├── 05-hash-setting-and-getting.rb │ ├── 18-hash-params.rb │ └── 17-variable-lengthed-params.rb ├── 4-spec │ ├── 15.rb │ ├── 2.rb │ ├── helper.rb │ ├── 16.rb │ ├── 17.rb │ ├── 1.rb │ ├── 11.rb │ ├── 5.rb │ └── 10.rb └── 2-examples │ ├── 4_recursion.rb │ ├── 2_blocks.rb │ └── 3_stack.rb ├── .travis.yml ├── session2 ├── 5-solved │ ├── 4.rb │ ├── 5.rb │ ├── 1.rb │ ├── 8.rb │ ├── 3.rb │ ├── 10.rb │ ├── 6.rb │ ├── 9.rb │ ├── 7.rb │ ├── 2.rb │ ├── 12.rb │ ├── 13.rb │ └── 11.rb ├── 2-examples │ ├── 2_gets.rb │ ├── 1_output.rb │ └── 3_array.rb ├── 3-challenge │ ├── 8_array.rb │ ├── 3_array.rb │ ├── 1_input_output.rb │ ├── 10_classes.rb │ ├── 4_array.rb │ ├── 5_array.rb │ ├── 7_array.rb │ ├── 6_array.rb │ ├── 2_input_output_control.rb │ ├── 11_classes.rb │ ├── 9_input_output_logic_string.rb │ └── 12_classes.rb ├── 1-notes │ ├── 07-class-examples.rb │ ├── 09-class-questions.rb │ ├── 08-methods-go-in-classes.rb │ ├── 19-last-words.rb │ ├── 11-naming-methods.rb │ ├── 15-more-on-method-scope.rb │ ├── 12-attr_accessor.rb │ ├── 04-array-filtering.rb │ ├── 13-initializing.rb │ ├── 06-classes.rb │ ├── 05-other-useful-array-methods.rb │ ├── 01-a-quick-word-about-blocks.rb │ ├── 16-THIS-IS-GONNA-TRIP-YOU-UP.rb │ ├── 10-instance-variables.rb │ ├── 03-array-iterating.rb │ ├── 14-self.rb │ ├── 02-arrays.rb │ ├── 17-singleton-classes.rb │ └── 18-class-instance-variables.rb └── 4-spec │ ├── helper.rb │ ├── 3.rb │ ├── 1.rb │ ├── 10.rb │ ├── 8.rb │ └── 9.rb ├── Gemfile ├── cheatsheets └── general.txt ├── MIT-LICENSE.txt └── Gemfile.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | -------------------------------------------------------------------------------- /session6/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | # Here is my solution to the app. 2 | -------------------------------------------------------------------------------- /session1/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | def arithmetic1(n) 2 | n * 5 - 20 3 | end -------------------------------------------------------------------------------- /session5/5-solved/6.rb: -------------------------------------------------------------------------------- 1 | def bar_regex 2 | /\b[bB]ar\b/ 3 | end 4 | -------------------------------------------------------------------------------- /session5/.rvmrc: -------------------------------------------------------------------------------- 1 | rvm use ruby-1.9.2-p180@cleaned_for_rks_session_5 2 | 3 | -------------------------------------------------------------------------------- /session6/1-notes/.rvmrc: -------------------------------------------------------------------------------- 1 | rvm 1.9.2-p180@ruby-kickstart-example-requests 2 | -------------------------------------------------------------------------------- /session4/5-solved/4.rb: -------------------------------------------------------------------------------- 1 | def first_object(a, b, c) 2 | a || b || c || nil 3 | end 4 | -------------------------------------------------------------------------------- /session3/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | def reverse_map(*args, &block) 2 | args.reverse.map(&block) 3 | end -------------------------------------------------------------------------------- /session6/1-notes/11-heroku-example/.rvmrc: -------------------------------------------------------------------------------- 1 | rvm 1.9.2-p180@ruby-kickstart-heroku-example 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.5.0 4 | script: 5 | - "bundle exec rake {1,2}:all" 6 | -------------------------------------------------------------------------------- /session6/1-notes/09-static-files-and-bundler/.rvmrc: -------------------------------------------------------------------------------- 1 | rvm 1.9.2-p180@ruby-kickstart-bundler-example 2 | -------------------------------------------------------------------------------- /session4/5-solved/7.rb: -------------------------------------------------------------------------------- 1 | def longest_method(object) 2 | object.methods.max_by { |meth| meth.length } 3 | end 4 | -------------------------------------------------------------------------------- /session5/5-solved/5.rb: -------------------------------------------------------------------------------- 1 | def list_of_errors_and_exceptions 2 | Object.constants.grep(/exception|error/i) 3 | end -------------------------------------------------------------------------------- /session1/5-solved/3.rb: -------------------------------------------------------------------------------- 1 | def ten_twenty(n) 2 | if n % 2 == 0 3 | 10 4 | else 5 | 20 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /session1/5-solved/5.rb: -------------------------------------------------------------------------------- 1 | def add_more_ruby(string) 2 | string.gsub('sad', 'happy').gsub('Sad', 'Happy') 3 | end 4 | -------------------------------------------------------------------------------- /session2/5-solved/4.rb: -------------------------------------------------------------------------------- 1 | def get_squares(numbers) 2 | numbers.select { |n| numbers.include? n*n }.sort 3 | end 4 | -------------------------------------------------------------------------------- /session4/1-notes/08.b-require.rb: -------------------------------------------------------------------------------- 1 | # This code will be required by 08.a 2 | 3 | def there 4 | 'from 08.b' 5 | end 6 | -------------------------------------------------------------------------------- /session6/1-notes/08-rack-and-reloading/main.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | 3 | get "/" do 4 | "Hello, world" 5 | end 6 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/config.ru: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + "/main" 2 | run Sinatra::Application 3 | -------------------------------------------------------------------------------- /session1/5-solved/2.rb: -------------------------------------------------------------------------------- 1 | def arithmetic2(a, b) 2 | if a < b 3 | a / 2.0 4 | else 5 | b / 2.0 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /session2/5-solved/5.rb: -------------------------------------------------------------------------------- 1 | def mod_three(numbers) 2 | numbers.select { |number| number % 3 != 0 }.map { |number| number % 3 } 3 | end -------------------------------------------------------------------------------- /session3/5-solved/16.rb: -------------------------------------------------------------------------------- 1 | def print_list(list) 2 | while list 3 | puts list[:data] 4 | list = list[:next] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem "sinatra", "~> 1.4" 3 | gem "rack-test", "~> 0.6" 4 | -------------------------------------------------------------------------------- /session3/5-solved/11.rb: -------------------------------------------------------------------------------- 1 | def array_init(size=5, &block) 2 | block ||= Proc.new { |i| (100 * i).to_s } 3 | Array.new(size, &block) 4 | end 5 | -------------------------------------------------------------------------------- /session3/5-solved/3.rb: -------------------------------------------------------------------------------- 1 | def word_count(str) 2 | words = Hash.new { 0 } 3 | str.split.each { |word| words[word.downcase] += 1 } 4 | words 5 | end 6 | -------------------------------------------------------------------------------- /session2/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | def sum_difference_product 2 | a , b = gets.split.map { |num| num.to_i } 3 | puts a + b 4 | puts a - b 5 | puts a * b 6 | end -------------------------------------------------------------------------------- /session3/5-solved/17.rb: -------------------------------------------------------------------------------- 1 | def print_list_in_reverse(list) 2 | return unless list 3 | print_list_in_reverse list[:next] 4 | puts list[:data] 5 | end 6 | -------------------------------------------------------------------------------- /session2/5-solved/8.rb: -------------------------------------------------------------------------------- 1 | def got_three?(elements) 2 | elements.each_cons 3 do |a, b, c| 3 | return true if a == b && b == c 4 | end 5 | false 6 | end 7 | -------------------------------------------------------------------------------- /session3/5-solved/4.rb: -------------------------------------------------------------------------------- 1 | def first_pos(str) 2 | to_return = {} 3 | str.split.each_with_index do |word, index| 4 | to_return[word] ||= index 5 | end 6 | to_return 7 | end 8 | -------------------------------------------------------------------------------- /session4/resources/8.1.template: -------------------------------------------------------------------------------- 1 | 406 217 799 116 45 651 808 780 2 | 205 919 474 567 712 3 | 776 170 681 86 822 9 100 540 812 4 | 602 117 181 169 876 336 5 | 434 165 725 187 974 48 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '2.5.0' 4 | 5 | gem 'rspec' 6 | gem 'rake' 7 | gem 'helloworld' 8 | gem 'sinatra' 9 | gem 'nokogiri' 10 | gem 'capybara' 11 | -------------------------------------------------------------------------------- /session4/5-solved/3.rb: -------------------------------------------------------------------------------- 1 | def passthrough(enumerable, to_pass, &block) 2 | enumerable.each do |element| 3 | to_pass = block.call(to_pass, element) 4 | end 5 | to_pass 6 | end 7 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/views/decrypt.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= @encrypted.inspect %> decrypts to <%= @decrypted.inspect %> 3 |

4 | 5 |

6 | Back 7 |

8 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/views/encrypt.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= @decrypted.inspect %> encrypts to <%= @encrypted.inspect %> 3 |

4 | 5 |

6 | Back 7 |

8 | -------------------------------------------------------------------------------- /session2/2-examples/2_gets.rb: -------------------------------------------------------------------------------- 1 | puts "Hello, start typing!" 2 | 3 | while line = gets 4 | puts "You submitted #{line.inspect}" 5 | break if line.chomp == 'exit' 6 | end 7 | 8 | puts "Goodbye!" 9 | -------------------------------------------------------------------------------- /session5/3-challenge/6_regex.rb: -------------------------------------------------------------------------------- 1 | # We want to find out how many times the word "bar" appears in some text. 2 | # Have the method below return the right regex: 3 | 4 | def bar_regex 5 | 6 | end 7 | -------------------------------------------------------------------------------- /session6/1-notes/09-static-files-and-bundler/public/dependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makersacademy/ruby-kickstart/HEAD/session6/1-notes/09-static-files-and-bundler/public/dependencies.png -------------------------------------------------------------------------------- /session4/5-solved/5.rb: -------------------------------------------------------------------------------- 1 | def line_sums(filename) 2 | File.readlines(filename).inject 0 do |sum, line| 3 | numbers = line.split.map { |number| number.to_i } 4 | sum + numbers.max 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /session2/5-solved/3.rb: -------------------------------------------------------------------------------- 1 | class String 2 | def every_other_char 3 | to_return = '' 4 | each_char.with_index do |char, index| 5 | to_return << char if index.even? 6 | end 7 | to_return 8 | end 9 | end -------------------------------------------------------------------------------- /session5/5-solved/7.rb: -------------------------------------------------------------------------------- 1 | def tree_parser(trees) 2 | results = [] 3 | trees.each_line do |line| 4 | /^(.*)[,;] which ships (at|@) (.*), cost:? (.*)$/i =~ line 5 | results << [$1, $3, $4] 6 | end 7 | results 8 | end 9 | -------------------------------------------------------------------------------- /session2/5-solved/10.rb: -------------------------------------------------------------------------------- 1 | class Person 2 | attr_accessor 'name', 'age' 3 | 4 | def initialize(name, age) 5 | @name = name 6 | @age = age 7 | end 8 | 9 | def birthday 10 | @age += 1 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /session6/1-notes/09-static-files-and-bundler/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' # where to look for gems 2 | gem "sinatra", "~> 1.2.6" # our web framework 3 | gem "rdiscount", "~> 1.6.8" # allows Sinatra to render markdown 4 | -------------------------------------------------------------------------------- /session4/5-solved/9.rb: -------------------------------------------------------------------------------- 1 | def full_name(person) 2 | begin 3 | "#{person.first_name} #{person.last_name}" 4 | rescue FirstNameError 5 | person.last_name 6 | rescue LastNameError 7 | person.first_name 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /session6/1-notes/06-sinatra-views-layouts-params-and-variables/views/home_page.erb: -------------------------------------------------------------------------------- 1 |
2 | List the items you want to buy: 3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/views/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Caesar Cipher 5 | 6 | 7 |

Caesar Cipher

8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /session6/1-notes/09-static-files-and-bundler/config.ru: -------------------------------------------------------------------------------- 1 | #Don't forget that since you have a different gemset now, you need to run bundle before you do rackup config.ru 2 | 3 | require File.dirname(__FILE__) + "/main" 4 | run Sinatra::Application 5 | -------------------------------------------------------------------------------- /session6/1-notes/06-sinatra-views-layouts-params-and-variables/views/cart.erb: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /session3/5-solved/15.rb: -------------------------------------------------------------------------------- 1 | def list_size(list) 2 | return 0 unless list 3 | 1 + list_size(list[:next]) 4 | end 5 | 6 | def middle(list, distance=list_size(list)/2) 7 | return list[:data] if distance == 0 8 | middle list[:next], (distance - 1) 9 | end 10 | -------------------------------------------------------------------------------- /session1/5-solved/6.rb: -------------------------------------------------------------------------------- 1 | def odds_and_evens(string, return_odds) 2 | to_return = "" 3 | string.size.times do |index| 4 | next if return_odds && index.even? 5 | next if !return_odds && index.odd? 6 | to_return << string[index] 7 | end 8 | to_return 9 | end 10 | -------------------------------------------------------------------------------- /session1/3-challenge/3_simple_logic.rb: -------------------------------------------------------------------------------- 1 | # remember, you can test this file with 2 | # $ rake 1:3 3 | 4 | 5 | # Given a number, n, return 10 if it is even, and 20 if it is odd 6 | # 7 | # ten_twenty(5) # => 20 8 | # ten_twenty(6) # => 10 9 | 10 | def ten_twenty(n) 11 | end 12 | -------------------------------------------------------------------------------- /session5/1-notes/16-rubygems-updating.rb: -------------------------------------------------------------------------------- 1 | # RubyGems has a command line tool that lets you install the gems 2 | # You've already got got it, run "$ gem -v" to see what version 3 | # you have. 4 | 5 | # If your RubyGems is old, you might update it with 6 | # "$ gem update --system" 7 | 8 | -------------------------------------------------------------------------------- /session2/5-solved/6.rb: -------------------------------------------------------------------------------- 1 | class Integer 2 | def prime? 3 | return false if self < 2 4 | 2.upto Math.sqrt(self) do |i| 5 | return false if self % i == 0 6 | end 7 | true 8 | end 9 | end 10 | 11 | def prime_chars?(strings) 12 | strings.join.length.prime? 13 | end 14 | -------------------------------------------------------------------------------- /session3/5-solved/2.rb: -------------------------------------------------------------------------------- 1 | def staircase(n) 2 | to_return = {} 3 | 1.upto n do |crnt_size| 4 | next if crnt_size.even? 5 | all = Array.new(crnt_size) { |i| i + 1 } 6 | evens = all.select { |i| i.even? } 7 | to_return[crnt_size] = evens 8 | end 9 | to_return 10 | end 11 | -------------------------------------------------------------------------------- /session1/2-examples/1_first_program.rb: -------------------------------------------------------------------------------- 1 | # run me by using cd to get to my directory 2 | # then type $ ruby 1_first_program.rb 3 | 4 | puts "Hello reader." 5 | puts "Welcome to Ruby" 6 | 7 | puts "Lets demonstrate a simple calculation" 8 | answer = 2 + 2 9 | puts "2 plus 2 is #{answer}" 10 | 11 | -------------------------------------------------------------------------------- /session4/3-challenge/7_introspection.rb: -------------------------------------------------------------------------------- 1 | # Given an object, return the name of its longest method 2 | # o = Object.new 3 | # def o.this_is_a_really_really_really_really_really_long_method_name 4 | # end 5 | # 6 | # longest_method o # => :this_is_a_really_really_really_really_really_long_method_name 7 | 8 | -------------------------------------------------------------------------------- /session4/5-solved/6.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController 2 | def body_class 3 | return @body_class if @body_class 4 | @body_class = String.new 5 | def @body_class.<<(str) 6 | concat ' ' unless length.zero? 7 | concat str 8 | end 9 | @body_class 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /session1/5-solved/4.rb: -------------------------------------------------------------------------------- 1 | def grade(num_books, reads_books) 2 | if reads_books 3 | return "C" if num_books < 10 4 | return "B" if num_books <= 20 5 | return "A" 6 | else 7 | return "D" if num_books < 10 8 | return "C" if num_books <= 20 9 | return "B" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /session3/3-challenge/1_blocks.rb: -------------------------------------------------------------------------------- 1 | # Write a method, reverse_map, which invokes a block on each of the elements in reverse order, 2 | # and returns an array of their results. 3 | # 4 | # reverse_map(1, 2, 3) { |i| i * 2 } # => [6, 4, 2] 5 | # reverse_map(1, 2, 3) { |i| i * 2 } # => [6, 4, 2] 6 | 7 | -------------------------------------------------------------------------------- /session6/1-notes/06-sinatra-views-layouts-params-and-variables/views/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example Application 5 | 6 | 7 | 8 | <%= yield %> 9 | 10 | -------------------------------------------------------------------------------- /session5/1-notes/18-gems-using-sinatra.rb: -------------------------------------------------------------------------------- 1 | # We can require Sinatra just like any other library 2 | # (in Ruby 1.8, you first have to `require "rubygems"`) 3 | require 'sinatra' 4 | 5 | # Run this file, then go to "http://localhost:4567/" to try it out. 6 | get '/' do 7 | "Hello, world!" 8 | end 9 | 10 | -------------------------------------------------------------------------------- /session5/5-solved/8.rb: -------------------------------------------------------------------------------- 1 | # First go to the terminal (any dir) and install the gems 2 | # $ gem install helloworld 3 | # $ gem install sinatra 4 | # $ gem install nokogiri 5 | 6 | require 'rubygems' # not necessary if you're on 1.9 7 | require 'hello_world' 8 | require 'sinatra' 9 | require 'nokogiri' 10 | -------------------------------------------------------------------------------- /session1/1-notes/19-nil.rb: -------------------------------------------------------------------------------- 1 | # There is a special object named nil 2 | nil.class # => NilClass 3 | 4 | # It's the object you use when you need to represent that you don't have an object! 5 | array = [1,5,7] 6 | array.find { |number| number * 2 == 10 } # => 5 7 | array.find { |number| number * 2 == 11 } # => nil 8 | 9 | -------------------------------------------------------------------------------- /session2/3-challenge/8_array.rb: -------------------------------------------------------------------------------- 1 | # Given an array of elements, return true if any element shows up three times in a row 2 | # 3 | # Examples: 4 | # got_three? [1, 2, 2, 2, 3] # => true 5 | # got_three? ['a', 'a', 'b'] # => false 6 | # got_three? ['a', 'a', 'a'] # => true 7 | # got_three? [1, 2, 1, 1] # => false 8 | 9 | -------------------------------------------------------------------------------- /session1/1-notes/14-operators-on-strings.rb: -------------------------------------------------------------------------------- 1 | # You can use basic operators on Strings, just like other objects: 2 | 3 | my_string = "Face" 4 | your_string = "book" 5 | 6 | my_string + your_string # => "Facebook" 7 | 8 | my_string == your_string # => false 9 | my_string = "book" 10 | my_string == your_string # => true 11 | 12 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/views/home.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 |
10 | -------------------------------------------------------------------------------- /session2/3-challenge/3_array.rb: -------------------------------------------------------------------------------- 1 | # Write a method named every_other_char for strings that, 2 | # returns a string containing every other character 3 | # 4 | # example: 5 | # "abcdefg".every_other_char # => "aceg" 6 | # "".every_other_char # => "" 7 | 8 | class String 9 | def every_other_char 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /session3/1-notes/03-hash-introduction.rb: -------------------------------------------------------------------------------- 1 | # A hash table is a data structure that allows you to keep track of 2 | # data in key / value pairs. 3 | # 4 | # Where arrays access elements by their index, hashes access 5 | # elements by their keys, and a key can be any object. 6 | # 7 | # Hashes are very fast, with near constant time to look up an element. 8 | -------------------------------------------------------------------------------- /session5/1-notes/11-regex-repetition.rb: -------------------------------------------------------------------------------- 1 | # * to match zero or more 2 | "aabc"[/x*/] # => "" 3 | "aabc"[/a*/] # => "aa" 4 | 5 | # + to match one or more 6 | "aabc"[/x+/] # => nil 7 | "aabc"[/a+/] # => "aa" 8 | 9 | # ? to match 0 or 1 10 | "abcde abde".scan(/bc?d/) # => ["bcd", "bd"] 11 | -------------------------------------------------------------------------------- /session3/1-notes/06-hash-keys.rb: -------------------------------------------------------------------------------- 1 | # Symbols are commonly used as keys because of their efficiency, 2 | # but you can use any object you like. 3 | 4 | hash = Hash.new 5 | hash[0] = 'zero' 6 | hash['nine'] = 9 7 | hash[/regex/] = ['array', 'of', 'strings'] 8 | hash # => {0=>"zero", "nine"=>9, /regex/=>["array", "of", "strings"]} 9 | 10 | -------------------------------------------------------------------------------- /session3/1-notes/19-putting-it-all-together.rb: -------------------------------------------------------------------------------- 1 | # We've seen a lot of things we can do with method parameters. 2 | # But how do they all work together? 3 | def meth(ordinal, optional=true, *variable_length, &block) 4 | end 5 | 6 | # Probably you don't need to use them all in one method like this, 7 | # it is up to you to find the right fit for your use case :). 8 | -------------------------------------------------------------------------------- /session5/1-notes/19-go-do-the-challenges.rb: -------------------------------------------------------------------------------- 1 | # Okay go try out the challenges now. Don't forget, there's 2 | # cheatsheets for regular expressions 3 | # https://github.com/JoshCheek/ruby-kickstart/blob/master/cheatsheets/regular_expressions.rb 4 | # and for RubyGems 5 | # https://github.com/JoshCheek/ruby-kickstart/blob/master/cheatsheets/rubygems.rb 6 | # 7 | -------------------------------------------------------------------------------- /session1/3-challenge/2_arithmetic.rb: -------------------------------------------------------------------------------- 1 | # fill out the method below, then run the tests with 2 | # $ rake 1:2 3 | 4 | 5 | # Given two numbers, a and b, return half of whichever is smallest, as a float 6 | # 7 | # arithmetic2(1, 2) # => 0.5 8 | # arithmetic2(19, 10) # => 5.0 9 | # arithmetic2(-6, -7) # => -3.5 10 | 11 | def arithmetic2(a, b) 12 | end 13 | -------------------------------------------------------------------------------- /session2/1-notes/07-class-examples.rb: -------------------------------------------------------------------------------- 1 | # Here are some examples of classes: 2 | String # => String 3 | Hash # => Hash 4 | Array # => Array 5 | Fixnum # => Fixnum 6 | 7 | 8 | # Here are some examples of instances of these classes 9 | "abc".class # => String 10 | {1 => 2}.class # => Hash 11 | [1, 2, 3].class # => Array 12 | 123456789.class # => Fixnum 13 | -------------------------------------------------------------------------------- /session6/1-notes/07-sinatra-routes.rb: -------------------------------------------------------------------------------- 1 | # You can also match variables in routes. Precede them with a colon 2 | # Sinatra will use regular expressions to find the variable and put it 3 | # in the params hash under the name you have specified. 4 | 5 | require 'sinatra' 6 | get '/hello/:first_name' do 7 | "Hello, #{params[:first_name]}, glad you could join us." 8 | end 9 | -------------------------------------------------------------------------------- /session3/3-challenge/3_hashes.rb: -------------------------------------------------------------------------------- 1 | # Write a method that takes a string and returns an array 2 | # whose keys are all the downcased words in the string, 3 | # and values are the number of times these words were seen. 4 | # 5 | # No punctuation will appear in the strings. 6 | # 7 | # Example: 8 | # word_count "The dog and the cat" # => {"the" => 2, "dog" => 1, "and" => 1, "cat" => 1} -------------------------------------------------------------------------------- /session1/3-challenge/1_arithmetic.rb: -------------------------------------------------------------------------------- 1 | # fill out the method below 2 | # then test tho see if you did them correctly with 3 | # $ rake 1:1 4 | 5 | # Given a number, return 20 less than, that number multiplied by 5 6 | # 7 | # arithmetic1(10) # => 30 8 | # arithmetic1(10.5) # => 32.5 9 | # arithmetic1(-6) # => -50 10 | 11 | def arithmetic1(n) 12 | 13 | end 14 | -------------------------------------------------------------------------------- /session1/3-challenge/5_string.rb: -------------------------------------------------------------------------------- 1 | # Given a string, replace every instance of sad to happy 2 | # 3 | # add_more_ruby("The clowns were sad.") # => "The clowns were happy." 4 | # add_more_ruby("The sad dad said sad stuff.") # => "The happy dad said happy stuff." 5 | # add_more_ruby("Sad times are ahead!") # => "Happy times are ahead!" 6 | 7 | def add_more_ruby(string) 8 | end -------------------------------------------------------------------------------- /session2/2-examples/1_output.rb: -------------------------------------------------------------------------------- 1 | number = 5 2 | other_number = 12 3 | 4 | puts "first line" , "second line" 5 | 6 | puts "The number we have is #{number} and the sum of our numbers is #{number + other_number}" 7 | # >> The number we have is 5 and the sum of our numbers is 17 8 | 9 | print "this will all be " 10 | print "on the same line" 11 | 12 | puts # an empty newline 13 | -------------------------------------------------------------------------------- /session4/5-solved/2.rb: -------------------------------------------------------------------------------- 1 | # 1's solution requires the actual file we are interested in 2 | require File.dirname(__FILE__) + "/1" 3 | 4 | class StackInDisguise < Stack 5 | def inspect 6 | ary = [] 7 | current = @head 8 | while current 9 | ary << current.data 10 | current = current.next_node 11 | end 12 | ary.reverse.inspect 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /session1/3-challenge/7_string.rb: -------------------------------------------------------------------------------- 1 | # given a string, return the character after every letter "r" 2 | # 3 | # pirates_say_arrrrrrrrr("are you really learning Ruby?") # => "eenu" 4 | # pirates_say_arrrrrrrrr("Katy Perry is on the radio!") # => "rya" 5 | # pirates_say_arrrrrrrrr("Pirates say arrrrrrrrr") # => "arrrrrrrr" 6 | 7 | def pirates_say_arrrrrrrrr(string) 8 | 9 | end 10 | -------------------------------------------------------------------------------- /session5/5-solved/4.rb: -------------------------------------------------------------------------------- 1 | module OperatorGeneratorFromSpace 2 | def <(other) 3 | (self <=> other) < 0 4 | end 5 | 6 | def >(other) 7 | (self <=> other) > 0 8 | end 9 | 10 | def ==(other) 11 | (self <=> other) == 0 12 | end 13 | 14 | def <=(other) 15 | !(self > other) 16 | end 17 | 18 | def >=(other) 19 | !(self < other) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | rack (1.3.0) 5 | rack-test (0.6.0) 6 | rack (>= 1.0) 7 | sinatra (1.2.6) 8 | rack (~> 1.1) 9 | tilt (< 2.0, >= 1.2.2) 10 | tilt (1.3.2) 11 | 12 | PLATFORMS 13 | ruby 14 | 15 | DEPENDENCIES 16 | rack-test (~> 0.6.0) 17 | sinatra (~> 1.2.6) 18 | -------------------------------------------------------------------------------- /session2/5-solved/9.rb: -------------------------------------------------------------------------------- 1 | def deaf_grandma 2 | while line = gets 3 | line.chomp! 4 | break if line == "BYE" 5 | if line == line.upcase && line != "" 6 | puts "NO, NOT SINCE 1938!" 7 | else 8 | puts "HUH?! SPEAK UP, SONNY!" 9 | end 10 | end 11 | end 12 | 13 | deaf_grandma if $0 == __FILE__ # this will call your code so you can run it from the terminal 14 | -------------------------------------------------------------------------------- /session3/1-notes/10-blocks-introduction.rb: -------------------------------------------------------------------------------- 1 | # Blocks are what we call a proc when we pass it into a method. 2 | # They are defined with "{ }" or "do end" 3 | ary = [3,2,1] # => [3, 2, 1] 4 | 5 | ary.map! { |num| num * 2 } 6 | ary # => [6, 4, 2] 7 | 8 | ary.map! do |num| 9 | num * 2 10 | end 11 | ary # => [12, 8, 4] 12 | 13 | -------------------------------------------------------------------------------- /session3/5-solved/6.rb: -------------------------------------------------------------------------------- 1 | def match_maker(opposites_attract, *elements) 2 | to_return = [] 3 | elements.each_slice 2 do |first, last| 4 | first = !!first 5 | last = !!last 6 | result = if opposites_attract 7 | first != last 8 | else 9 | first == last 10 | end 11 | to_return << result 12 | end 13 | to_return 14 | end 15 | -------------------------------------------------------------------------------- /session2/5-solved/7.rb: -------------------------------------------------------------------------------- 1 | def alternate_words(sentence) 2 | # this will get better when we learn regular expressions :) 3 | '!@$#%^&*()-=_+[]:;,./<>?\\|'.split(//).each do |char| 4 | sentence = sentence.gsub(char, ' ') 5 | end 6 | words = sentence.split 7 | solution = [] 8 | words.each_with_index do |word, index| 9 | solution << word if index.even? 10 | end 11 | solution 12 | end 13 | -------------------------------------------------------------------------------- /session3/3-challenge/4_hashes.rb: -------------------------------------------------------------------------------- 1 | # Write first_pos, a method which takes a string and , returns a hash 2 | # whose keys are all the words in the string, and values are the 3 | # earliest position they were seen in the string. 4 | # 5 | # There will be no punctuation in the strings. 6 | # 7 | # first_pos "The dog and the cat and the cow" # => {"The" => 0, "dog" => 1, "and" => 2, "the" => 3, "cat" => 4, "cow" => 7} 8 | 9 | -------------------------------------------------------------------------------- /session2/3-challenge/1_input_output.rb: -------------------------------------------------------------------------------- 1 | # Remember you can test this code with 2 | # $ rake 2:1 3 | 4 | # Write a program that reads in two integers typed on the keybaord 5 | # and outputs their sum, difference, and product 6 | # 7 | # Standard input will be like "9 2\n" and will expect you to print 8 | # "11\n7\n18\n" to standard output. 9 | 10 | def sum_difference_product 11 | # your code goes here 12 | 13 | end -------------------------------------------------------------------------------- /session1/3-challenge/6_string.rb: -------------------------------------------------------------------------------- 1 | # You'll get a string and a boolean. 2 | # When the boolean is true, return a new string containing all the odd characters. 3 | # When the boolean is false, return a new string containing all the even characters. 4 | # 5 | # If you have no idea where to begin, remember to check out the cheatsheets for string and logic/control 6 | # 7 | 8 | def odds_and_evens(string, return_odds) 9 | 10 | end -------------------------------------------------------------------------------- /session2/1-notes/09-class-questions.rb: -------------------------------------------------------------------------------- 1 | # Between Yankees and Baseball team 2 | # which is a class and which is an instance? 3 | 4 | # Between Person and Enoch 5 | # which is a class and which is an instance? 6 | 7 | # Can you think of another class and several instances? 8 | 9 | 10 | 11 | # Are classes objects? 12 | # If no, where do you think their methods are stored? 13 | # If yes, what class are they instances of? 14 | -------------------------------------------------------------------------------- /session4/1-notes/17-raising-your-own.rb: -------------------------------------------------------------------------------- 1 | # You can raise an existing exception by passing it to raise 2 | begin 3 | raise Exception.new("We made this!") 4 | rescue Exception => e 5 | e # => # 6 | end 7 | 8 | 9 | # If you pass a string to raise, it will be a RuntimeError 10 | begin 11 | raise "Fix your shit" 12 | rescue RuntimeError => e 13 | e # => # 14 | end 15 | -------------------------------------------------------------------------------- /session6/1-notes/09-static-files-and-bundler/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | backports (3.6.4) 5 | rack (1.4.5) 6 | rdiscount (1.6.8) 7 | sinatra (1.2.9) 8 | backports 9 | rack (~> 1.1, < 1.5) 10 | tilt (>= 1.2.2, < 2.0) 11 | tilt (1.4.1) 12 | 13 | PLATFORMS 14 | ruby 15 | 16 | DEPENDENCIES 17 | rdiscount (~> 1.6.8) 18 | sinatra (~> 1.2.6) 19 | -------------------------------------------------------------------------------- /session3/1-notes/15-forwarding-blocks.rb: -------------------------------------------------------------------------------- 1 | # Another common thing is to forward blocks to other methods 2 | def meth1(&block) 3 | "(meth1: #{block.call})" 4 | end 5 | 6 | 7 | # Use the & notation when calling a method to put a block into 8 | # the method's block slot. 9 | def meth2(&block) 10 | "#{meth1(&block)} (meth2: #{block.call})" 11 | end 12 | 13 | counter = 0 14 | meth2 { counter += 10 } # => "(meth1: 10) (meth2: 20)" 15 | -------------------------------------------------------------------------------- /session2/1-notes/08-methods-go-in-classes.rb: -------------------------------------------------------------------------------- 1 | # When we say "abc".length, the length method 2 | # is stored in the String class. 3 | length = String.instance_method 'length' 4 | length # => # 5 | 6 | 7 | # So if we want to make a new method on strings, 8 | # we would put it in the String class 9 | class String 10 | def half_length 11 | length / 2 12 | end 13 | end 14 | "abcdef".half_length # => 3 15 | -------------------------------------------------------------------------------- /session1/1-notes/10-introducing-strings.rb: -------------------------------------------------------------------------------- 1 | # For historical reasons, text in programming languages, is called a "string" 2 | # think of it like you're stringing characters along a clothesline 3 | # question: if 10.to_f converts 10 to a float, how would you convert 10 to a string? 4 | 5 | "text".class # => String 6 | 7 | # You can identify strings because they are surrounded in quotes 8 | 9 | "abc" # => "abc" 10 | 'abc' # => "abc" 11 | 12 | -------------------------------------------------------------------------------- /session2/3-challenge/10_classes.rb: -------------------------------------------------------------------------------- 1 | # Make a person class that has a name, age, and birthday 2 | # 3 | # josh = Person.new 'Josh', 28 4 | # 5 | # josh.name # => "Josh" 6 | # josh.age # => 28 7 | # 8 | # josh.name = 'Joshua' 9 | # josh.name # => "Joshua" 10 | # 11 | # josh.birthday # => 29 12 | # josh.age # => 29 13 | # 14 | # josh.birthday # => 30 15 | # josh.age # => 30 16 | # 17 | 18 | class Person 19 | 20 | end 21 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/main.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | require File.dirname(__FILE__)+'/lib/caesar_cipher' 3 | 4 | get '/' do 5 | erb :home 6 | end 7 | 8 | post '/encrypt' do 9 | @decrypted = params[:message] 10 | @encrypted = CaesarCipher.encrypt @decrypted 11 | erb :encrypt 12 | end 13 | 14 | post '/decrypt' do 15 | @encrypted = params[:message] 16 | @decrypted = CaesarCipher.decrypt @encrypted 17 | erb :decrypt 18 | end 19 | -------------------------------------------------------------------------------- /session1/4-spec/1.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "arithmetic1" do 2 | it 'returns 30 when passed 10' do 3 | expect(arithmetic1 10).to eq 30 4 | end 5 | 6 | it 'returns 32.5 when passed 10.5' do 7 | expect(arithmetic1 10.5).to eq 32.5 8 | end 9 | 10 | it 'returns -50 when passed -6' do 11 | expect(arithmetic1 -6).to eq -50 12 | end 13 | 14 | it 'returns 480 when passed 100' do 15 | expect(arithmetic1 100).to eq 480 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /session1/5-solved/7.rb: -------------------------------------------------------------------------------- 1 | def pirates_say_arrrrrrrrr(string) 2 | to_return = "" 3 | add_next = false 4 | string.size.times do |index| 5 | current_char = string[index,1] # the second param here tells it to get a str of length 1. This is only necessary on 1.8. If you are on 1.9, just go with string[index] 6 | to_return << current_char if add_next 7 | add_next = (current_char == "r" || current_char == "R") 8 | end 9 | to_return 10 | end 11 | -------------------------------------------------------------------------------- /session3/1-notes/04-hash-literals.rb: -------------------------------------------------------------------------------- 1 | # Where Arrays are represented with brackets, 2 | # Hashes are represented in curly braces 3 | [].class # => Array 4 | {}.class # => Hash 5 | 6 | 7 | # Keys are separated from their values with a hash rocket => 8 | # with the key on the left, and the value on the right 9 | {0 => 'first', 1 => 'second'} # => {0=>"first", 1=>"second"} 10 | 11 | key = :one 12 | value = "two" 13 | {key => value} # => {:one=>"two"} 14 | -------------------------------------------------------------------------------- /session3/4-spec/15.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'middle' do 2 | it 'is a toplevel method' do 3 | method :middle # will raise an error if it can't find the method 4 | end 5 | 6 | list = nil 7 | 8 | 1.upto 10 do |i| 9 | head = {:data => i, :next => list} 10 | list = head 11 | expected = (i/2.0).ceil 12 | it "finds #{expected} for #{head.inspect}" do 13 | expect(middle head).to eq expected 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /session3/5-solved/13.rb: -------------------------------------------------------------------------------- 1 | def your_sort( array , &orderer ) 2 | # if it is nil, then it hasn't been set, default to spaceship operator for comparison result 3 | orderer ||= Proc.new { |a, b| a <=> b } 4 | 5 | array.each_index do |index1| 6 | array.each_index do |index2| 7 | order = orderer.call(array[index1], array[index2]) 8 | array[index1], array[index2] = array[index2], array[index1] if order < 0 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /session4/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | # load the stack code in 2 | require File.expand_path("../../challenge/1_stack_classes_inspect", __FILE__) 3 | 4 | 5 | class Stack 6 | def inspect 7 | current = @head 8 | to_return = "(" 9 | while current 10 | to_return << current.data.inspect 11 | to_return << ")" 12 | current = current.next_node 13 | end 14 | to_return << ")" if to_return == "(" 15 | to_return 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /session2/1-notes/19-last-words.rb: -------------------------------------------------------------------------------- 1 | # Okay, ready for challenges ^_^ 2 | # I spent a long time on these, hopefully you'll enjoy them! 3 | 4 | 5 | 6 | # A USEFUL HINT! 7 | # You can return from a method early with the keyword return 8 | def method(condition) 9 | return 1 if condition 10 | 2 11 | end 12 | method true # => 1 13 | method false # => 2 14 | 15 | # Check out cheatsheet for arrays: 16 | # https://github.com/JoshCheek/ruby-kickstart/blob/master/cheatsheets/arrays.rb -------------------------------------------------------------------------------- /session4/1-notes/12-super-to-invoke-inherited.rb: -------------------------------------------------------------------------------- 1 | # When you override a method, you can call the method 2 | # you're overriding, with the keyword `super`. 3 | class Superclass 4 | def self.class_method 5 | 'class_method from Superclass' 6 | end 7 | end 8 | 9 | class Subclass < Superclass 10 | def self.class_method 11 | super + " | through Subclass" 12 | end 13 | end 14 | 15 | Subclass.class_method # => "class_method from Superclass | through Subclass" 16 | 17 | -------------------------------------------------------------------------------- /session3/2-examples/4_recursion.rb: -------------------------------------------------------------------------------- 1 | def append(array, n) 2 | return array if n < 0 3 | array << n 4 | append(array, n-1) 5 | end 6 | 7 | def reverse_append(array, n) 8 | return array if n < 0 9 | reverse_append(array, n-1) 10 | array << n 11 | end 12 | 13 | def fib(n) 14 | return 0 if n == 0 15 | return 1 if n == 1 16 | fib(n-1) + fib(n-2) 17 | end 18 | 19 | p append([], 5) #=> [0,1,2,3,4,5] 20 | p reverse_append([], 5) #=> [5,4,3,2,1,0] 21 | p fib(3) #=> 55 22 | 23 | -------------------------------------------------------------------------------- /session3/3-challenge/17_hashes.rb: -------------------------------------------------------------------------------- 1 | # DO NOT SPEND MORE THAN 30-40 MINUTES STRUGGLING THROUGH THIS BEFORE MOVING ON! 2 | 3 | # Print to stdout, each element in a hash based linked list, in reverse. 4 | # If you don't know what that is, go check out the previous problem. 5 | # 6 | # EXAMPLES: 7 | # head = {:data => 1, :next => nil} 8 | # head = {:data => 2, :next => head} 9 | # 10 | # print_list_in_reverse head # >> "1\n2\n" 11 | 12 | def print_list_in_reverse list 13 | 14 | end 15 | -------------------------------------------------------------------------------- /session3/3-challenge/2_hashes.rb: -------------------------------------------------------------------------------- 1 | # Given a nonnegative integer, return a hash whose keys are all the odd nonnegative integers up to it 2 | # and each key's value is an array containing all the even non negative integers up to it. 3 | # 4 | # Examples: 5 | # staircase 1 # => {1 => []} 6 | # staircase 2 # => {1 => []} 7 | # staircase 3 # => {1 => [], 3 => [2]} 8 | # staircase 4 # => {1 => [], 3 => [2]} 9 | # staircase 5 # => {1 => [], 3 => [2], 5 =>[2, 4]} 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /session4/5-solved/8.rb: -------------------------------------------------------------------------------- 1 | class RubyKickstartException < Exception 2 | end 3 | 4 | def exception_raiser(num) 5 | if num == 1 then raise "No 1s allowed!" 6 | elsif num == 2 then raise ArgumentError, "No 2s allowed!" 7 | elsif num == 3 then raise Exception, "No 3s allowed!" 8 | elsif num == 4 then raise SyntaxError, "No 4s allowed!" 9 | elsif num == 5 then raise RubyKickstartException, "No 5s allowed!" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /session3/1-notes/11-block-params-and-return.rb: -------------------------------------------------------------------------------- 1 | # Methods will raise an error if you give them the wrong number 2 | # of arguments. But blocks will not. 3 | [1,2,3].map { 0 } # => [0, 0, 0] 4 | 5 | 6 | # A return statement in a method will return from it. But a return 7 | # statement in a proc will return **from the enclosing environment**. 8 | def first_even(nums) 9 | nums.each do |num| 10 | return num if num.even? 11 | end 12 | nil 13 | end 14 | first_even [1,5,7,4,19,8] # => 4 15 | -------------------------------------------------------------------------------- /session4/1-notes/10-subclasses-inherit-methods.rb: -------------------------------------------------------------------------------- 1 | class Superclass 2 | def self.class_method 3 | 'class_method from Superclass' 4 | end 5 | 6 | def instance_method 7 | 'instance_method from Superclass' 8 | end 9 | end 10 | 11 | class Subclass < Superclass 12 | end 13 | 14 | # Subclasses inherit methods from their superclass 15 | Subclass.class_method # => "class_method from Superclass" 16 | Subclass.new.instance_method # => "instance_method from Superclass" 17 | 18 | -------------------------------------------------------------------------------- /session5/1-notes/12-regex-boundaries.rb: -------------------------------------------------------------------------------- 1 | # To match the beginning of a line, use the caret (outside of the 2 | # brackets) and to match the end, use the dollar sign. 3 | "a b"[/^./] # => "a" 4 | "a b"[/.$/] # => "b" 5 | 6 | 7 | # You can match the boundaries between alphanumeric 8 | # and non-alphanumeric with \b 9 | dijkstra = "Elegance is not a dispensable luxury but a factor that decides between success and failure." 10 | dijkstra.scan(/\bd[a-z]*/) # => ["dispensable", "decides"] 11 | 12 | -------------------------------------------------------------------------------- /session1/1-notes/13-single-vs-double-quotes.rb: -------------------------------------------------------------------------------- 1 | # There are two ways to represent a literal String in Ruby: With double quotes ( "" ) or single quotes ( '' ). 2 | # With double quotes, you can place special sequences, like newlines (\n) in the string that will be converted. 3 | # With single quotes, the string comes out just as it's typed. 4 | 5 | puts "Here's\nTwo lines." 6 | puts 'This will\nonly be one line' 7 | 8 | # Output: 9 | # Here's 10 | # Two lines. 11 | # This will\nonly be one line 12 | 13 | -------------------------------------------------------------------------------- /session2/1-notes/11-naming-methods.rb: -------------------------------------------------------------------------------- 1 | # Using set_whatever and get_whatever is kind of 2 | # distracting. It's better to name your setters 3 | # and getters the same as the variable they represent. 4 | 5 | class Car 6 | def miles=(miles) 7 | @miles = miles 8 | end 9 | 10 | def miles 11 | @miles 12 | end 13 | end 14 | 15 | Car.instance_methods false # => [:miles=, :miles] 16 | 17 | car = Car.new 18 | car.miles = 1000 # Ruby knows this is the miles= method 19 | car.miles # => 1000 20 | -------------------------------------------------------------------------------- /session2/3-challenge/4_array.rb: -------------------------------------------------------------------------------- 1 | # Write a method named get_squares that takes an array of numbers 2 | # and returns a sorted array containing only the numbers whose square is also in the array 3 | # 4 | # get_squares [9] # => [] 5 | # get_squares [9,3] # => [3] 6 | # get_squares [9,3,81] # => [3, 9] 7 | # get_squares [25, 4, 9, 6, 50, 16, 5] # => [4, 5] 8 | 9 | # This time you will have to define the method, it's called: get_squares 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /session3/5-solved/8.rb: -------------------------------------------------------------------------------- 1 | class Person 2 | attr_accessor :name, :age, :quote 3 | 4 | def initialize(options=Hash.new, &initializer) 5 | self.name = options[:name] 6 | self.age = options[:age] 7 | self.quote = options[:quote] 8 | @initializer = (initializer || Proc.new { |person| }) # this way, it always has a proc, and code like reinit doesn't have to worry that it might not be there 9 | reinit 10 | end 11 | 12 | def reinit 13 | @initializer.call(self) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /session4/1-notes/11-overriding-inherited-methods.rb: -------------------------------------------------------------------------------- 1 | class Superclass 2 | def self.class_method 3 | 'class_method from Superclass' 4 | end 5 | 6 | def instance_method 7 | 'instance_method from Superclass' 8 | end 9 | end 10 | 11 | class Subclass < Superclass 12 | def self.class_method 13 | 'class_method from Subclass' 14 | end 15 | end 16 | 17 | Subclass.class_method # => "class_method from Subclass" 18 | Subclass.new.instance_method # => "instance_method from Superclass" 19 | 20 | -------------------------------------------------------------------------------- /session2/1-notes/15-more-on-method-scope.rb: -------------------------------------------------------------------------------- 1 | # So methods being their own little world is totally a lie 2 | # They can actually see instance variables and methods 3 | # on their object. 4 | 5 | class Example 6 | 7 | def method1 8 | self # => # 9 | @var = 123 10 | method2 11 | @var # => 500 12 | end 13 | 14 | def method2 15 | self # => # 16 | @var # => 123 17 | @var = 500 18 | end 19 | 20 | end 21 | 22 | Example.new.method1 23 | -------------------------------------------------------------------------------- /session2/5-solved/2.rb: -------------------------------------------------------------------------------- 1 | def prompt 2 | puts 'Enter a number or bye' 3 | end 4 | 5 | def hi_hi_goodbye 6 | prompt 7 | while (line = gets) && (line !~ /bye/) # first is an assignment statement that returns a line or nil, and is thus boolean 8 | line.to_i.times { print 'hi ' } 9 | puts 10 | prompt 11 | end 12 | puts "Goodbye!" 13 | end 14 | 15 | 16 | 17 | 18 | 19 | hi_hi_goodbye if $0 == __FILE__ # a little magic so that you can run with "$ ruby 2_input_output_control.rb" but it will still work for our tests 20 | -------------------------------------------------------------------------------- /session1/1-notes/05-methods.rb: -------------------------------------------------------------------------------- 1 | # The way you modify objects is through sequences of instructions called methods. 2 | # For example, there is a set of instructions that know how to capitalize text. We group them into a method named capitalize. 3 | 4 | "josh".capitalize # => "Josh" 5 | 6 | 7 | # You can make methods, too! 8 | 9 | def is_this_a_method? 10 | "Yes, it is!" # "Yes, it is!" is an object. Because this is the last object in the method, its address will be returned. 11 | end 12 | 13 | is_this_a_method? # => "Yes, it is!" 14 | 15 | -------------------------------------------------------------------------------- /session1/2-examples/3_rememberer.rb: -------------------------------------------------------------------------------- 1 | # This program uses things you haven't seen yet. 2 | # Can you look at it and figure out what it is doing? 3 | 4 | lines_seen = [] 5 | 6 | 7 | loop do 8 | 9 | # Why do we chomp? Can you use irb to figure out the difference between gets, and gets.chomp ? 10 | line = gets.chomp 11 | break if line == "exit" 12 | 13 | if lines_seen.include? line 14 | puts "Yes, I've seen #{line} before" 15 | else 16 | puts "No, I haven't seen #{line} before" 17 | lines_seen << line 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /session1/1-notes/03-object-definition.rb: -------------------------------------------------------------------------------- 1 | # Ruby organizes related data, and the ways of manipulating it, into an abstract idea called an object. 2 | # For example, the data that defines a number, and the methods on that number, define that number object. 3 | 4 | # At a computer level, the data for the number 5 are just ones and zeros, probably looking like this 5 | "%032b" % 5 # => "00000000000000000000000000000101" 6 | 7 | # and since five is an object, it also has methods on it 8 | 5.even? # => false 9 | 5.odd? # => true 10 | 5.next # => 6 11 | 12 | -------------------------------------------------------------------------------- /session3/1-notes/20-last-words.rb: -------------------------------------------------------------------------------- 1 | # Check out the cheatsheet for Hashes 2 | # https://github.com/JoshCheek/ruby-kickstart/blob/master/cheatsheets/hashes.rb 3 | # 4 | # The material we went over in this section covers almost everything 5 | # else that I think you should know about the topics, so I'm not going 6 | # to bother with any cheatsheet this time. 7 | # 8 | # But if you want to see the docs, they're at 9 | # http://ruby-doc.org/core/classes/Symbol.html 10 | # http://ruby-doc.org/core/classes/Hash.html 11 | # http://ruby-doc.org/core/classes/Proc.html 12 | -------------------------------------------------------------------------------- /session4/1-notes/09-inheritance-introduction.rb: -------------------------------------------------------------------------------- 1 | # Sometimes you have a generic idea of your class, but it can be 2 | # realized in several specific ways. Sometimes, in Object Oriented 3 | # Programming, we will subclass the generic class, called the 4 | # superclass, and write more specific implementations. (Note that 5 | # this has largely fallen out of favour in the Ruby community). 6 | 7 | class Superclass 8 | end 9 | 10 | # Use the < to indicate inheritance 11 | class Subclass < Superclass 12 | end 13 | 14 | Subclass.superclass # => Superclass 15 | 16 | -------------------------------------------------------------------------------- /session1/1-notes/02-conventions.rb: -------------------------------------------------------------------------------- 1 | # In the notes, examples and cheat sheets provided, we use a few conventions in our code to make it easy 2 | # to see the results of expressions. To show the results of a line, we use the following notation 3 | 4 | 3 + 9 # => 12 5 | my_var = 4 6 | my_var # => 4 7 | 8 | # This shows what that line evaluates to, and in the case of a line with just a variable on it, shows the value 9 | # of the object it refers to. 10 | 11 | # For more complicated output, such as from a print statement, it'll be placed below the code. 12 | 13 | -------------------------------------------------------------------------------- /session2/3-challenge/5_array.rb: -------------------------------------------------------------------------------- 1 | # Write a function named mod_three which takes an array of numbers, 2 | # and return a new array consisting of their remainder when divided by three. 3 | # Exclude any numbers which are actually dividible by three. 4 | # 5 | # EXAMPLES: 6 | # mod_three [0] # => [] 7 | # mod_three [1] # => [1] 8 | # mod_three [2] # => [2] 9 | # mod_three [3] # => [] 10 | # mod_three [4] # => [1] 11 | # mod_three [5] # => [2] 12 | # mod_three [6] # => [] 13 | # mod_three [7] # => [1] 14 | # 15 | # mod_three [0,1,2,3,4,5,6,7] # => [1, 2, 1, 2, 1] 16 | 17 | -------------------------------------------------------------------------------- /session3/5-solved/10.rb: -------------------------------------------------------------------------------- 1 | def pathify(paths=Hash.new) 2 | # base step 3 | return paths.map { |path| '/' + path } if paths.is_a? Array 4 | 5 | # recursive step 6 | to_return = [] 7 | paths.each do |parent_path, child_dirs| 8 | parent_path = '/' + parent_path # paths begin with a / 9 | child_paths = pathify child_dirs # convert child directories to paths 10 | child_paths.each do |child_path| # join each child path to it's parent path 11 | to_return << (parent_path + child_path) 12 | end 13 | end 14 | to_return 15 | end 16 | -------------------------------------------------------------------------------- /session2/4-spec/helper.rb: -------------------------------------------------------------------------------- 1 | require 'stringio' 2 | 3 | RSpec.configure do |config| 4 | config.disable_monkey_patching! 5 | 6 | test_helpers = Module.new do 7 | def input_output(mock_stdin_with_this_str=String.new) 8 | ARGV.clear # -.0 9 | stdout , stdin = $stdout , $stdin 10 | $stdin = StringIO.new mock_stdin_with_this_str 11 | to_return = $stdout = StringIO.new 12 | yield 13 | $stdout , $stdin = stdout , stdin 14 | to_return.rewind 15 | to_return.read 16 | end 17 | end 18 | 19 | config.include test_helpers 20 | end 21 | -------------------------------------------------------------------------------- /session3/4-spec/2.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'staircase' do 2 | it 'is defined' do 3 | expect(method :staircase).to be 4 | end 5 | 6 | [ [1, { 1 => [] }], 7 | [2, { 1 => [] }], 8 | [3, { 1 => [], 3 => [2] }], 9 | [4, { 1 => [], 3 => [2] }], 10 | [5, { 1 => [], 3 => [2], 5 => [2, 4] }], 11 | [6, { 1 => [], 3 => [2], 5 => [2, 4] }], 12 | [7, { 1 => [], 3 => [2], 5 => [2, 4], 7 => [2, 4, 6] }], 13 | ].each do |n, result| 14 | specify "staircase(#{n}) # => #{result.inspect}" do 15 | expect(staircase n).to eq result 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /session3/4-spec/helper.rb: -------------------------------------------------------------------------------- 1 | require 'stringio' 2 | 3 | RSpec.configure do |config| 4 | config.disable_monkey_patching! 5 | 6 | test_helpers = Module.new do 7 | def input_output(mock_stdin_with_this_str=String.new) 8 | ARGV.clear # -.0 9 | stdout , stdin = $stdout , $stdin 10 | $stdin = StringIO.new mock_stdin_with_this_str 11 | to_return = $stdout = StringIO.new 12 | yield 13 | $stdout , $stdin = stdout , stdin 14 | to_return.rewind 15 | to_return.read 16 | end 17 | end 18 | 19 | config.include test_helpers 20 | end 21 | -------------------------------------------------------------------------------- /session4/1-notes/14-ancestors.rb: -------------------------------------------------------------------------------- 1 | # The chain of superclasses are called ancestors. 2 | class Superclass 3 | end 4 | 5 | class Subclass < Superclass 6 | end 7 | 8 | Subclass.ancestors # => [Subclass, Superclass, Object, Kernel, BasicObject] 9 | Subclass # => Subclass 10 | Subclass.superclass # => Superclass 11 | Superclass.superclass # => Object 12 | Object.superclass # => BasicObject 13 | BasicObject.superclass # => nil 14 | 15 | # Kernel doesn't fit in, that's because it's not a class, 16 | # it's a module. We'll talk about modules next time. 17 | -------------------------------------------------------------------------------- /session2/5-solved/12.rb: -------------------------------------------------------------------------------- 1 | class Fraction 2 | attr_accessor :numerator, :denominator 3 | 4 | def initialize(numerator, denominator) 5 | self.numerator, self.denominator = numerator, denominator 6 | end 7 | 8 | def to_s 9 | "#{numerator}/#{denominator}" 10 | end 11 | 12 | def to_f 13 | numerator / denominator.to_f 14 | end 15 | 16 | def gcd(a, b) 17 | return a if b == 0 18 | gcd b, (a % b) 19 | end 20 | 21 | def lowest 22 | divisor = gcd(numerator, denominator) 23 | Fraction.new(numerator/divisor, denominator/divisor) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /session3/4-spec/16.rb: -------------------------------------------------------------------------------- 1 | require_relative 'helper' 2 | 3 | RSpec.describe 'print_list' do 4 | it 'is a toplevel method' do 5 | method :print_list # will raise an error if it can't find the method 6 | end 7 | 8 | list = nil 9 | 10 | 1.upto 10 do |i| 11 | head = { :data => i, :next => list } 12 | list = head 13 | expected = (1..i).to_a.reverse.join("\n") + "\n" 14 | it "prints #{expected.inspect} for #{head.inspect}" do 15 | printed = input_output { print_list head } 16 | expect(printed).to eq expected 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /session4/1-notes/02-oror-return-values.rb: -------------------------------------------------------------------------------- 1 | # The same short circuit principle applies to ||. 2 | 3 | 4 | 5 | # When the LHS is true, returns the LHS 6 | 1 || nil # => 1 7 | "abc" || false # => "abc" 8 | 9 | 10 | 11 | # When the LHS is false, returns the LHS 12 | nil || 1 # => 1 13 | false || "abc" # => "abc" 14 | 15 | 16 | 17 | # How could this be used? The Sinatra gem, a web "microframework" 18 | # uses it to find the current mime type, or if there isn't one, 19 | # then use the default (http://goo.gl/cVDMK) 20 | mime_type = mime_type(type) || default 21 | -------------------------------------------------------------------------------- /session4/1-notes/15-exceptions-introduction.rb: -------------------------------------------------------------------------------- 1 | # Errors and Exceptions are used to say "something something happend 2 | # that I don't know how to deal with". They halt evaluation, and 3 | # return to where they were called from, incrementally making their 4 | # way up the stack (the series of methods that were called to get to 5 | # wherever the exception was raised) until they are either either 6 | # rescued, or cause the program to crash. 7 | 8 | # You raise exceptions with the raise method 9 | raise "This will now die!" 10 | # ~> -:9:in `
': This will now die! (RuntimeError) 11 | -------------------------------------------------------------------------------- /session2/1-notes/12-attr_accessor.rb: -------------------------------------------------------------------------------- 1 | # In fact, this naming convention for setters and 2 | # getters is so common that there is a method that 3 | # will write them for you. 4 | 5 | class Car 6 | attr_accessor 'miles' 7 | end 8 | 9 | Car.instance_methods false # => [:miles, :miles=] 10 | 11 | car = Car.new 12 | car.miles = 1000 13 | car.miles # => 1000 14 | 15 | car.instance_variables # => [:@miles] 16 | car.instance_variable_get '@miles' # => 1000 17 | 18 | 19 | # attr_accessor is an example of metaprogramming, 20 | # You can write methods yourself like attr_accessor 21 | -------------------------------------------------------------------------------- /session2/1-notes/04-array-filtering.rb: -------------------------------------------------------------------------------- 1 | numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | 4 | # Use select to make a new array of only the elements 5 | # you want if the block returns a truthy value then 6 | # that element will be in the result. 7 | evens = numbers.select { |number| number.even? } 8 | evens # => [0, 2, 4, 6, 8] 9 | 10 | 11 | # Reject is the opposite 12 | odds = numbers.reject { |number| number.even? } 13 | odds # => [1, 3, 5, 7, 9] 14 | 15 | 16 | # None of these modify the original array 17 | # They all return new arrays 18 | numbers # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 19 | -------------------------------------------------------------------------------- /session3/2-examples/2_blocks.rb: -------------------------------------------------------------------------------- 1 | class Person 2 | 3 | attr_accessor :name 4 | 5 | def initialize( &initializer ) 6 | @initializer = initializer 7 | initializer.call self 8 | end 9 | 10 | def reinit 11 | @initializer.call self 12 | end 13 | 14 | end 15 | 16 | 17 | 18 | artist = Person.new do |person| 19 | person.name = 'Prince' 20 | end 21 | 22 | artist.name # => "Prince" 23 | artist.name = 'The Artist Formerly Known As Prince' 24 | artist.name # => "The Artist Formarly Known As Prince" 25 | artist.reinit 26 | artist.name # => "Prince" 27 | -------------------------------------------------------------------------------- /session3/4-spec/17.rb: -------------------------------------------------------------------------------- 1 | require_relative 'helper' 2 | 3 | RSpec.describe 'print_list_in_reverse' do 4 | it 'is a toplevel method' do 5 | method :print_list_in_reverse # will raise an error if it can't find the method 6 | end 7 | 8 | list = nil 9 | 10 | 1.upto 10 do |i| 11 | head = { :data => i, :next => list } 12 | list = head 13 | expected = (1..i).to_a.join("\n") + "\n" 14 | it "prints #{expected.inspect} for #{head.inspect}" do 15 | printed = input_output { print_list_in_reverse head } 16 | expect(printed).to eq expected 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /session1/1-notes/15-interpolation.rb: -------------------------------------------------------------------------------- 1 | # Double quotes have even more power. By using a special sequence of characters, you can interpolate code 2 | # into your String. That code will be ran and its results placed into the string. 3 | 4 | small_number = 5 5 | neg_number = -97 6 | 7 | puts "1 + 3 is #{1 + 3}" 8 | puts "My two numbers are #{small_number} and #{neg_number.abs} (all positive here)" 9 | 10 | # Output: 11 | # 1 + 3 is 4 12 | # My two numbers are 5 and 97 (all positive here) 13 | # 14 | 15 | # Notice we can do anything inside of the #{} we want, including referencing objects and calling methods on them. 16 | 17 | -------------------------------------------------------------------------------- /session4/3-challenge/4_oror.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solutions file, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # Write a method first_object, that takes three parameters 4 | # and returns the first one that is true. 5 | # 6 | # EXAMPLES: 7 | # first_object 1, nil, nil # => 1 8 | # first_object nil, 1, nil # => 1 9 | # first_object nil, nil, 1 # => 1 10 | # first_object nil, 1, 2 # => 1 11 | # first_object nil, nil, nil # => nil 12 | 13 | def first_object(arg1, arg2, arg3) 14 | 15 | end 16 | -------------------------------------------------------------------------------- /session3/1-notes/07-hash-iterating.rb: -------------------------------------------------------------------------------- 1 | # in 1.8, HASHES ARE NOT ORDERED, if you iterate through them, 2 | # you don't know what order they will be passed 3 | # in 1.9, they will passed to your block in the order they were inserted. 4 | 5 | 6 | # When you iterate over the hash, you pass it a block, just like 7 | # arrays. But this block takes two arguments, the key and value 8 | student_ids = {'Bill' => 25, 'Danya' => 15, 'Mei' => 12} 9 | 10 | student_ids.each do |student, id| 11 | puts "#{student}'s student id is #{id}" 12 | end 13 | # >> Bill's student id is 25 14 | # >> Danya's student id is 15 15 | # >> Mei's student id is 12 16 | -------------------------------------------------------------------------------- /session5/1-notes/15-rubygems-introduction.rb: -------------------------------------------------------------------------------- 1 | # So gems sound great, everyone can share their code with each other. 2 | # Just one problem, _how_ do we share it? 3 | 4 | # Well, for that, there is RubyGems! http://rubygems.org a giant 5 | # repository of gems that anyone can upload their gems to, or get 6 | # their gems back from. 7 | 8 | # You can peruse RubyGems, or check out http://ruby-toolbox.com/ 9 | # for a compilation of gems based on the types of tools you need. 10 | # This is a great place to get ideas and see what tools the rest of 11 | # the community think are useful for addressing certain types of 12 | # problems. 13 | 14 | -------------------------------------------------------------------------------- /session3/1-notes/09-procs-can-see-their-environment.rb: -------------------------------------------------------------------------------- 1 | # Unlike methods, procs can see the environment they're defined in. 2 | count = 0 3 | incrementer = Proc.new { count += 1 } 4 | 5 | count # => 0 6 | incrementer.call 7 | count # => 1 8 | incrementer.call 9 | count # => 2 10 | 11 | 12 | # They keep the environment they were defined in 13 | # even if they get passed into a new scope. 14 | def invoke_10_times(proc) 15 | 10.times { proc.call } 16 | end 17 | 18 | count # => 2 19 | invoke_10_times incrementer 20 | count # => 12 21 | -------------------------------------------------------------------------------- /session2/1-notes/13-initializing.rb: -------------------------------------------------------------------------------- 1 | # When you instantiate an object (make an instance 2 | # of a class), you use the new method. After doing all 3 | # the things necessary to make an object, the new method 4 | # will invoke a method named initialize, and pass it 5 | # any arguments you passed to new. This allows you to 6 | # put your object into an initial state. 7 | 8 | class Instrument 9 | def initialize(name, price) 10 | @name = name 11 | @price = price 12 | end 13 | 14 | attr_accessor 'name', 'price' 15 | end 16 | 17 | clarinet = Instrument.new 'Clarinet', 250 18 | clarinet.name # => "Clarinet" 19 | clarinet.price # => 250 20 | 21 | -------------------------------------------------------------------------------- /session1/4-spec/3.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "ten_twenty" do 2 | it 'returns 20 when passed 5' do 3 | expect(ten_twenty 5).to eq 20 4 | end 5 | 6 | it 'returns 10 when passed 6' do 7 | expect(ten_twenty 6).to eq 10 8 | end 9 | 10 | it 'returns 10 when passed 0' do 11 | expect(ten_twenty 0).to eq 10 12 | end 13 | 14 | 1_000_000.step(-1_000_000, -101_275) do |i| 15 | if i % 2 == 0 16 | it "returns #{10} when passed #{i}" do 17 | expect(ten_twenty i).to eq 10 18 | end 19 | else 20 | it "returns #{20} when passed #{i}" do 21 | expect(ten_twenty i).to eq 20 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /session1/1-notes/22-if-else.rb: -------------------------------------------------------------------------------- 1 | # Lets say you actually want to do something conditionally 2 | 3 | if 4 == (2 + 2) 4 | "I get evaluated" # => "I get evaluated" 5 | else 6 | "I don't :(" # => 7 | end 8 | 9 | 10 | my_number = 56 11 | 12 | if my_number < 12 13 | puts "Fewer than a dozen" 14 | elsif my_number < 64 15 | puts "You could hold me in 6 bits" 16 | else 17 | puts "That's a pretty big number" 18 | end 19 | 20 | # Output: 21 | # You could hold me in 6 bits 22 | # 23 | 24 | 25 | 'one line if statement' if true # => "one line if statement" 26 | 'one line unless statement' unless false # => "one line unless statement" 27 | 28 | -------------------------------------------------------------------------------- /session2/1-notes/06-classes.rb: -------------------------------------------------------------------------------- 1 | # We've explained what an object is, data packaged 2 | # together with methods. But how do we define 3 | # what data our object should have, and how do we 4 | # associate methods with that data? 5 | # 6 | # For that, we use classes :) 7 | 8 | 9 | # Classes are containers for methods. 10 | # 11 | # When you have an object that uses those methods, we 12 | # say it is an *instance* of that class. 13 | # 14 | # The instance keeps track of its class, then when you 15 | # invoke a method on it, it finds the method by looking 16 | # it up in the class. 17 | 18 | # So, objects have methods, and those methods are 19 | # defined in its class. 20 | -------------------------------------------------------------------------------- /session5/5-solved/1.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController 2 | def body_class 3 | return @body_class if @body_class 4 | @body_class = String.new 5 | 6 | class << @body_class 7 | def <<(str) 8 | return self if self[/\b#{str}\b/] 9 | concat ' ' unless length.zero? 10 | concat str 11 | end 12 | 13 | def +(str) raise_exception end 14 | def *(str) raise_exception end 15 | def []=(o,n) raise_exception end 16 | 17 | private 18 | 19 | def raise_exception 20 | raise RuntimeError.new("use << method instead") 21 | end 22 | end 23 | 24 | @body_class 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /session3/1-notes/08-proc-introduction.rb: -------------------------------------------------------------------------------- 1 | # A Proc is just a way of storing code in an object 2 | # It's just like a method in that it takes parameters, evaluates 3 | # code, and then returns a result. 4 | square_it_proc = Proc.new { |num| num * num } 5 | 6 | 7 | # Its parameters are given in the pipes, so the above |num| is 8 | # the parameter that the proc receives. 9 | 10 | 11 | # You tell it to execute with the call method 12 | square_it_proc.call 5 # => 25 13 | square_it_proc.call 10 # => 100 14 | 15 | 16 | # Compare it to a method 17 | def square_it_method(num) 18 | num * num 19 | end 20 | square_it_method 5 # => 25 21 | square_it_method 10 # => 100 22 | -------------------------------------------------------------------------------- /session3/5-solved/9.rb: -------------------------------------------------------------------------------- 1 | def shared(a, b) 2 | # union = Hash.new do |hash, key| 3 | # hash[key] = [(a.include?(key)||nil), # include returns true or false, when false, it goes to the RHS of the ||, and becomes nil 4 | # (b.include?(key)||nil)] 5 | # end 6 | 7 | union = {} 8 | a.each do |element| 9 | 10 | union[element] ||= [nil, nil] 11 | union[element][0] = true 12 | end 13 | 14 | b.each do |element| 15 | union[element] ||= [nil, nil] 16 | union[element][1] = true 17 | end 18 | 19 | result = union.select { |key, value| value == [true, true] }.map { |key, value| key } 20 | 21 | return union, result.sort 22 | end 23 | -------------------------------------------------------------------------------- /session1/1-notes/12-puts.rb: -------------------------------------------------------------------------------- 1 | # Ruby has several methods for sending text to stdout, the most common of which is 'puts': 2 | puts "Welcome to the program!" 3 | 4 | # Output: 5 | # Welcome to the program! 6 | # 7 | 8 | 9 | # Notice that puts places a newline after whatever it prints. And puts can print any object, not just strings: 10 | puts 45 11 | 12 | # Output: 13 | # 45 14 | # 15 | 16 | 17 | # puts can output other objects by using their to_s method to convert them into Strings 18 | # and then outputs the strings. It works like this: 19 | number = 56 20 | thing_to_print = number.to_s 21 | puts thing_to_print 22 | 23 | # Output: 24 | # 56 25 | # 26 | 27 | -------------------------------------------------------------------------------- /session4/4-spec/4.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'first_object' do 2 | def self.assert_first(first, args) 3 | example "first_object(#{args.map(&:inspect).join(", ")}) # => #{first.inspect}" do 4 | obj = first_object(*args) 5 | expect(obj).to eq first 6 | end 7 | end 8 | 9 | assert_first 1, [1, nil, nil] 10 | assert_first 1, [nil, 1, nil] 11 | assert_first 1, [nil, nil, 1] 12 | assert_first 1, [nil, 1, 2] 13 | assert_first nil, [nil, nil, nil] 14 | assert_first nil, [false, false, false] 15 | assert_first true, [false, false, true] 16 | assert_first 5, [5, 4, 3] 17 | assert_first 5, [5, nil, 3] 18 | assert_first 5, [5, 4, nil] 19 | end 20 | -------------------------------------------------------------------------------- /session1/1-notes/18-keywords.rb: -------------------------------------------------------------------------------- 1 | # We care about keywords, because they have special meaning to Ruby. 2 | # This means that we can't use them as variable names. 3 | # 4 | # You will know if you've used one, because the interpreter will 5 | # If your text editor highlights it, don't use it. :) 6 | # 7 | # If you _really_ want a list, its at http://www.google.com/search?&q=ruby+keywords+list 8 | 9 | 10 | 11 | 12 | # def is a keyword used for defining methods. It has special meaning, you can't use it. 13 | 14 | def = 3 # !> useless use of a literal in void context 15 | # ~> -:14: syntax error, unexpected '=' 16 | # ~> def = 3 # !> useless use of a literal in void context 17 | # ~> ^ 18 | 19 | -------------------------------------------------------------------------------- /session3/1-notes/13-difference-between-block-syntaxes.rb: -------------------------------------------------------------------------------- 1 | def block_checker(array, &block) 2 | [array.to_a, !!block] 3 | end 4 | 5 | # { ... } blocks bind to the method immediately to their left. 6 | # do ... end blocks will bind to the furthest left method. 7 | 8 | # The block is passed to map 9 | block_checker [1,2,3].map { 1 } # => [[1, 1, 1], false] 10 | 11 | # The block is passed to block_checker 12 | block_checker([1,2,3].map) { 1 } # => [[1, 2, 3], true] 13 | 14 | # The block is passed to block_checker 15 | block_checker [1,2,3].map do 1 end # => [[1, 2, 3], true] 16 | 17 | 18 | # This makes { ... } ideal for inline blocks, and 19 | # do ... end ideal for mutli line blocks 20 | -------------------------------------------------------------------------------- /session1/3-challenge/4_logic.rb: -------------------------------------------------------------------------------- 1 | # A grad student at a local university thinks he has discovered a formula to 2 | # predict what kind of grades a person will get. He says if you own less than 3 | # 10 books, you will get a "D". If you own 10 to 20 books, you will get a "C", 4 | # and if you own more than 20 books, you will get a "B". 5 | # He further hypothesizes that if you actually read your books, then you will 6 | # get a full letter grade higher in every case. 7 | # 8 | # grade(4, false) # => "D" 9 | # grade(4, true) # => "C" 10 | # grade(15, true) # => "B" 11 | 12 | # <10 books => D, 10..20 books => C, >20 book =>B 13 | 14 | 15 | def grade(num_books, has_read_books) 16 | end 17 | 18 | 19 | -------------------------------------------------------------------------------- /session4/3-challenge/5_file.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solutions file, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # you will be given a file name 4 | # inside the file will be a series of numbers 5 | # find the largest number on each line 6 | # return their sum 7 | # 8 | # EXAMPLE 9 | # file: nums.txt 10 | # 406 217 799 116 45 651 808 780 11 | # 205 919 474 567 712 12 | # 776 170 681 86 822 9 100 540 812 13 | # 602 117 181 169 876 336 14 | # 434 165 725 187 974 48 15 | # 16 | # line_sums('nums.txt') # => 808 + 919 + 822 + 876 + 974 # => 4399 17 | 18 | -------------------------------------------------------------------------------- /session3/5-solved/12.rb: -------------------------------------------------------------------------------- 1 | def pay_by(order) 2 | order.compute_cost 3 | order.compute_shipping 4 | order.compute_tax 5 | yield 6 | order.ship_goods 7 | end 8 | 9 | def pay_by_visa(order, ccn) 10 | pay_by order do 11 | order.payment :type => :visa, :ccn => ccn 12 | order.verify_payment 13 | end 14 | end 15 | 16 | def pay_by_check(order) 17 | pay_by(order) { order.payment :type => :check, :signed => true } 18 | end 19 | 20 | def pay_by_cash(order) 21 | pay_by(order) { order.payment :type => :cash } 22 | end 23 | 24 | def pay_by_store_credit(order,current_user) 25 | pay_by order do 26 | order.payment :type => :store_credit 27 | current_user.store_credit -= order.cost 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /session5/4-spec/5.rb: -------------------------------------------------------------------------------- 1 | errors = Module.constants.grep(/error|exception/i) 2 | 3 | RSpec.describe 'list_of_errors_and_exceptions' do 4 | %w( 5 | Lowercaseerror 6 | Lowercaseexception 7 | Errorerr 8 | Exceptionatstart 9 | ExceptionAtStart 10 | ExcEPtion 11 | Abcexceptiondef 12 | ).each do |error_to_find| 13 | # changed between 1.8 and 1.9 14 | if Module.constants.first.kind_of? Symbol 15 | error_to_find = error_to_find.to_sym 16 | end 17 | 18 | Object.const_set error_to_find, Class.new(StandardError) 19 | 20 | example "finds the added #{error_to_find}" do 21 | expect(list_of_errors_and_exceptions).to include error_to_find 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /session2/3-challenge/7_array.rb: -------------------------------------------------------------------------------- 1 | # Given a sentence, return an array containing every other word. 2 | # Punctuation is not part of the word unless it is a contraction. 3 | # In order to not have to write an actual language parser, there won't be any punctuation too complex. 4 | # There will be no "'" that is not part of a contraction. 5 | # Assume each of these charactsrs are not to be considered: ! @ $ # % ^ & * ( ) - = _ + [ ] : ; , . / < > ? \ | 6 | # 7 | # Examples 8 | # alternate_words("Lorem ipsum dolor sit amet.") # => ["Lorem", "dolor", "amet"] 9 | # alternate_words("Can't we all get along?") # => ["Can't", "all", "along"] 10 | # alternate_words("Elementary, my dear Watson!") # => ["Elementary", "dear"] 11 | 12 | -------------------------------------------------------------------------------- /session2/1-notes/05-other-useful-array-methods.rb: -------------------------------------------------------------------------------- 1 | chars = ['a', 'b', 'c'] 2 | 3 | 4 | # Concatenate with + 5 | chars + ['d', 'e'] # => ["a", "b", "c", "d", "e"] 6 | 7 | 8 | # Append to an array 9 | chars # => ["a", "b", "c"] 10 | chars << 'd' 11 | chars # => ["a", "b", "c", "d"] 12 | 13 | 14 | # Replace 15 | chars[1] = 'Bee' 16 | chars # => ["a", "Bee", "c", "d"] 17 | 18 | 19 | # Delete index 20 | chars.delete_at 1 21 | chars # => ["a", "c", "d"] 22 | 23 | 24 | # Delete object 25 | chars.delete 'c' 26 | chars # => ["a", "d"] 27 | 28 | 29 | # Insert 30 | index = 1 31 | chars.insert index, 'b' , 'c' 32 | chars # => ["a", "b", "c", "d"] 33 | 34 | 35 | # Sorting 36 | ['c', 'b', 'd', 'a'].sort # => ["a", "b", "c", "d"] 37 | -------------------------------------------------------------------------------- /session4/3-challenge/2_subclassing_require.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solutions file, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # Require the stack code from challenge 1 4 | # The code you added causes it to do this 5 | # 6 | # stack = Stack.new 7 | # stack.push 1 8 | # stack.push 2 9 | # stack # => (2)1) 10 | 11 | 12 | # But sometimes you want it to inspect like an array. 13 | # stack # => [1, 2] 14 | # 15 | # Subclass the Stack class and override its inspect 16 | # so that we can do this: 17 | # 18 | # stack = StackInDisguise.new 19 | # stack.push 1 20 | # stack.push 2 21 | # stack # => [1, 2] 22 | 23 | -------------------------------------------------------------------------------- /session2/1-notes/01-a-quick-word-about-blocks.rb: -------------------------------------------------------------------------------- 1 | #Watch this video - https://vimeo.com/24365612 - these notes are supplementary as per the last section 2 | 3 | # We'll talk about blocks more later, but for now just know 4 | # that you declare a parameter in pipes (this is just 5 | # like a method declaring parameters) 6 | 7 | def mah_method!(method_param) 8 | end 9 | 10 | 11 | # This is the syntax for single line blocks 12 | # note that you need parens around that 1, 13 | # we'll discuss why later 14 | mah_method!(1) { |block_parameter| block_parameter * 2 } 15 | 16 | 17 | # you also have multiline syntax 18 | # here you don't need parens around the 1 19 | mah_method! 1 do |param1, param2| 20 | param1 + param2 21 | end 22 | 23 | -------------------------------------------------------------------------------- /session5/1-notes/02-modules-including.rb: -------------------------------------------------------------------------------- 1 | # Modules have the feel of a class in that you define methods in them. 2 | # But since they cannot be instantiated, you must declare that the 3 | # methods in the module should be included in a class, and the module 4 | # will be added to the inheritance chain, making its methods available. 5 | module OurModule 6 | def meth 7 | 'method from OurModule' 8 | end 9 | end 10 | 11 | # When we include OurModule in a class, it becomes an ancestor 12 | class OurClass 13 | include OurModule 14 | end 15 | OurClass.ancestors # => [OurClass, OurModule, Object, Kernel, BasicObject] 16 | 17 | # This means its instances can invoke OurModule's methods 18 | OurClass.new.meth # => "meth from M" 19 | 20 | -------------------------------------------------------------------------------- /session1/4-spec/2.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "arithmetic2" do 2 | let(:test_array) { 3 | [ -7, -6, -3.5, 4 | 1, -1, -0.5, 5 | -1, 1, -0.5, 6 | -1, -1, -0.5, 7 | 0, 0, 0.0, 8 | 0, 100, 0.0, 9 | ] 10 | } 11 | 12 | it 'returns 0.5 when give 1 , 2' do 13 | expect(arithmetic2 1, 2).to eq 0.5 14 | end 15 | 16 | it 'returns 5.0 when given 19 , 10' do 17 | expect(arithmetic2 19, 10).to eq 5.0 18 | end 19 | 20 | it 'returns -3.5 when given -6 , -7' do 21 | expect(arithmetic2 -6, -7).to eq -3.5 22 | end 23 | 24 | it 'returns pass the test array' do 25 | test_array.each_slice 3 do |a, b, result| 26 | expect(arithmetic2 a, b).to eq result 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /session2/3-challenge/6_array.rb: -------------------------------------------------------------------------------- 1 | # Write a method named prime_chars? which takes array of strings 2 | # and returns true if the sum of the characters is prime. 3 | # 4 | # Remember that a number is prime if the only integers that can divide it with no remainder are 1 and itself. 5 | # 6 | # Examples of length three 7 | # prime_chars? ['abc'] # => true 8 | # prime_chars? ['a', 'bc'] # => true 9 | # prime_chars? ['ab', 'c'] # => true 10 | # prime_chars? ['a', 'b', 'c'] # => true 11 | # 12 | # Examples of length four 13 | # prime_chars? ['abcd'] # => false 14 | # prime_chars? ['ab', 'cd'] # => false 15 | # prime_chars? ['a', 'bcd'] # => false 16 | # prime_chars? ['a', 'b', 'cd'] # => false 17 | 18 | -------------------------------------------------------------------------------- /session3/5-solved/14.rb: -------------------------------------------------------------------------------- 1 | # This can be handled in a much cleaner way in 1.9, without the params fiddling 2 | 3 | def problem_14(*params) 4 | problem = params.pop[:problem] if params.last.is_a? Hash 5 | problem ||= :count_clumps 6 | 7 | return count_clumps(*params) if problem == :count_clumps 8 | return same_ends(*params) if problem == :same_ends 9 | end 10 | 11 | def count_clumps(*numbers) 12 | clumps = 0 13 | previous = nil 14 | two_before = nil 15 | 16 | numbers.each do |number| 17 | clumps += 1 if (previous == number) && (previous != two_before) 18 | two_before = previous 19 | previous = number 20 | end 21 | clumps 22 | end 23 | 24 | def same_ends(n, *params) 25 | params[0, n] == params[-n, n] 26 | end 27 | -------------------------------------------------------------------------------- /session4/1-notes/01-andand-return-values.rb: -------------------------------------------------------------------------------- 1 | #Watch this video - https://vimeo.com/24972005 - these notes are supplementary to the 2nd video as per the last section 2 | 3 | # Remember, everything in Ruby is true except for false and nil. 4 | # This means that (1 && 5) returning 5 works just as well 5 | # as if it had returned true. And in fact, that's what it does 6 | # && returns the last object it looks at before making its decision. 7 | 8 | # The LHS is true, so always returns the RHS. 9 | 1 && 5 # => 5 10 | 1 && nil # => nil 11 | 1 && false # => false 12 | 1 && true # => true 13 | 1 && 'abc' # => "abc" 14 | 15 | # The LHS is false, so just returns the LHS 16 | nil && 1 # => nil 17 | false && 1 # => false 18 | 19 | 20 | -------------------------------------------------------------------------------- /session5/1-notes/13-regex-groups.rb: -------------------------------------------------------------------------------- 1 | # You can logically group multiple characters with parentheses 2 | # Each will be captured according in variables $1, $2, ... 3 | regex = /(.).(.).(.)/ 4 | "abcde" =~ regex 5 | $1 # => "a" 6 | $2 # => "c" 7 | $3 # => "e" 8 | 9 | 10 | # A pipe acts as an "or" 11 | regex = /big (dog|boy)/ 12 | 13 | "I bought a big truck today"[regex] # => nil 14 | 15 | "He is a big boy now."[regex] # => "big boy" 16 | $1 # => "boy" 17 | 18 | "That is one big dog over there."[regex] # => "big dog" 19 | $1 # => "dog" 20 | 21 | -------------------------------------------------------------------------------- /session5/1-notes/17-gems-installing.rb: -------------------------------------------------------------------------------- 1 | # Lets say we want to write a web application. There are a ton of 2 | # gems to help you do this 3 | # http://ruby-toolbox.com/categories/web_app_frameworks.html 4 | 5 | 6 | # I like Sinatra a lot. In fact, that's what ruby-kickstart.com uses! 7 | # Lets go check out its RubyGems page http://rubygems.org/gems/sinatra 8 | 9 | 10 | # Looks good, lets install it. We just need to tell RubyGems that 11 | # we want it, and it will take care of everything involved. 12 | # "$ gem install sinatra" 13 | 14 | 15 | # If you have difficulty, it could be that your RubyGems is installed 16 | # somewhere that requires you to be a superuser to make changes. In 17 | # that case, try running "$ sudo gem install sinatra". 18 | 19 | -------------------------------------------------------------------------------- /session1/4-spec/5.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "add_more_ruby" do 2 | it 'changes sad to happy' do 3 | expect(add_more_ruby "The clowns were sad.").to eq "The clowns were happy." 4 | end 5 | 6 | it 'changes sad at the end' do 7 | expect(add_more_ruby "abc sad").to eq("abc happy") 8 | end 9 | 10 | it 'changes sad every time it sees it' do 11 | expect(add_more_ruby "The sad dad said sad stuff.").to eq "The happy dad said happy stuff." 12 | end 13 | 14 | it 'makes Happy uppercase if Sad is uppercase' do 15 | expect(add_more_ruby "Sad times are ahead!").to eq "Happy times are ahead!" 16 | end 17 | 18 | it 'changes lots of sads in a row' do 19 | expect(add_more_ruby "sadSadsadsad").to eq "happyHappyhappyhappy" 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /session3/3-challenge/5_blocks.rb: -------------------------------------------------------------------------------- 1 | # DO NOT STRUGGLE ON THIS PROBLEM FOR MORE THAN 30 MINUTES!! IT'S A TOUGH ONE :) 2 | 3 | # Write a method, spiral_access, that takes a 2d square array (an array of arrays) 4 | # and a block, and calls the block for each of the elements, in spiral order. 5 | # 6 | # HINT: This method is probably best sovled recursively 7 | # 8 | # Example: 9 | # two_d = [ 10 | # [ 1, 2, 3, 4, 5], 11 | # [16, 17, 18, 19, 6], 12 | # [15, 24, 25, 20, 7], 13 | # [14, 23, 22, 21, 8], 14 | # [13, 12, 11, 10, 9], 15 | # ] 16 | # order = [] 17 | # spiral_access two_d do |i| 18 | # order << i 19 | # end 20 | # order # => [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] 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /session1/1-notes/20-logic.rb: -------------------------------------------------------------------------------- 1 | # In your life, when you need to conditionally do something, you use logic. 2 | # Logic has two values: true and false. 3 | # You say things like "if it's raining and I have an umbrella I'll go outside, otherwise I'll stay inside." 4 | # This is a logical statement. 5 | # 6 | # Ruby has logic, too, so you can totally write a program to see if you should go outside, in fact, lets do it! 7 | 8 | def go_outside?(raining, umbrella) 9 | raining && umbrella 10 | end 11 | 12 | go_outside?(true, true) # => true 13 | go_outside?(true , false) # => false 14 | go_outside?(false, true ) # => false 15 | go_outside?(false, false) # => false 16 | 17 | # Look, the go_outside? method knows exactly what to do, because it knows about logic! 18 | 19 | -------------------------------------------------------------------------------- /session3/1-notes/14-storing-blocks-for-later.rb: -------------------------------------------------------------------------------- 1 | # Now that we know to use &block, we can do cool things like 2 | # Store the block for later. 3 | class CollegeStudent 4 | 5 | attr_accessor :do_when_twenty_one 6 | 7 | def initialize(age, &block) 8 | @age = age 9 | @do_when_twenty_one = block 10 | end 11 | 12 | def birthday! 13 | @age += 1 14 | return "#{@age}: study :(" unless @age == 21 15 | do_when_twenty_one.call @age 16 | end 17 | 18 | end 19 | 20 | 21 | pam = CollegeStudent.new 18 do |age| 22 | "#{age}: GET SAUCED!" 23 | end 24 | 25 | pam.birthday! # => "19: study :(" 26 | pam.birthday! # => "20: study :(" 27 | pam.birthday! # => "21: GET SAUCED!" 28 | pam.birthday! # => "22: study :(" 29 | pam.birthday! # => "23: study :(" 30 | -------------------------------------------------------------------------------- /session4/1-notes/04-introspection.rb: -------------------------------------------------------------------------------- 1 | # See the cheatsheet for more info (http://goo.gl/7lsJk). 2 | 3 | 4 | # The most important ones are (we'll talk more about 5 | # what ancestors and superclasses are in a little bit). 6 | "abc".class # => String 7 | String.ancestors # => [String, Comparable, Object, Kernel, BasicObject] 8 | Fixnum.superclass # => Integer 9 | 10 | 11 | # puts calls to_s, it returns a string for end users 12 | # p calls inspect, it returns a string for developers 13 | # Strings for example, get quotes placed around them. 14 | "abc".inspect # => "\"abc\"" 15 | "abc".to_s # => "abc" 16 | 17 | 18 | require 'date' 19 | Date.today.inspect # => "#" 20 | Date.today.to_s # => "2011-06-11" 21 | -------------------------------------------------------------------------------- /session4/1-notes/08.a-require.rb: -------------------------------------------------------------------------------- 1 | # When you have code in one file that you want to use in another 2 | # file, you load it by using require. 3 | defined? Date # => nil 4 | require 'date' 5 | defined? Date # => "constant" 6 | 7 | # In this case, Ruby looks in several different places to see a 8 | # list of locations to look for the file you required. It contains 9 | # things like the standard library, a set of files with useful 10 | # things like Date. 11 | 12 | # When you want to load a file that you've written, it won't be 13 | # in that path variable, so you must give Ruby an absolute path 14 | # to the file. 15 | require File.dirname(__FILE__) + '/08.b-require' 16 | 17 | def here 18 | 'from 08.a' 19 | end 20 | 21 | here # => "from 08.a" 22 | there # => "from 08.b" 23 | -------------------------------------------------------------------------------- /session1/2-examples/2_check_odd.rb: -------------------------------------------------------------------------------- 1 | # Invoke this program with a number 2 | # $ ruby 2_check_odd.rb number 3 | 4 | 5 | # when a user passes an argument to a ruby program 6 | # it is stored in the ARGV array 7 | unless ARGV.first 8 | puts "You need to submit a number to check" 9 | exit(1) # Use exit(0) to exit the program early. 10 | end # If you're exiting because something went wrong, pass a different number like 1 11 | 12 | 13 | # Unix is too dumb to know the argument is a number, so it passes it in as text. 14 | # We'll have to turn it into a number ourselves with to_i (what if the user didn't pass a number?) 15 | number = ARGV.first.to_i 16 | 17 | if number.odd? 18 | puts "Yes, #{number} is odd" 19 | else 20 | puts "No, #{number} is not odd" 21 | end 22 | 23 | -------------------------------------------------------------------------------- /session6/1-notes/02-servers-and-rack.rb: -------------------------------------------------------------------------------- 1 | # Ruby web applications usually use an interface called Rack that 2 | # will present the server's data to our program us in the form of 3 | # a hash table like this: 4 | 5 | { 6 | "REQUEST_METHOD" => "GET", # The type of request 7 | "REQUEST_PATH" => "/", # Where to go on my application 8 | "REMOTE_ADDR" => "127.0.0.1", # This is my IP address 9 | "SERVER_PORT" => "3000", # This is my port 10 | "SERVER_SOFTWARE" => "Mongrel 1.2.0.pre2", # This is my server 11 | "HTTP_USER_AGENT" => "Mozilla/5.0 [...]", # This was the browser I made the request with 12 | "HTTP_COOKIE" => "BAh7CU3[...]", # My cookie: an encrypted string 13 | # ... and so on ... 14 | } 15 | -------------------------------------------------------------------------------- /session2/1-notes/16-THIS-IS-GONNA-TRIP-YOU-UP.rb: -------------------------------------------------------------------------------- 1 | # When calling a setter method, always use an explicit 2 | # receiver. Otherwise it looks like you're setting a 3 | # local variable. 4 | 5 | class Flight 6 | attr_accessor 'arrival_time' 7 | 8 | def reset 9 | arrival_time # => 1100 10 | arrival_time = 0 11 | 12 | # Wait, wtf is this? 13 | arrival_time # => 0 14 | self.arrival_time # => 1100 15 | 16 | # Oh, it thought we wanted to make a local variable 17 | # named arrival_time 18 | local_variables # => [:arrival_time] 19 | 20 | # We should have made it explicit by specifying that 21 | # arrival_time= is a method on self 22 | self.arrival_time = 0 23 | end 24 | end 25 | 26 | f = Flight.new 27 | f.arrival_time = 1100 28 | f.reset 29 | -------------------------------------------------------------------------------- /session4/4-spec/7.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | RSpec.describe 'longest_method' do 4 | [ 1, 5 | 2, 6 | 2**1000, 7 | "abc", 8 | /abc/, 9 | Object.new, 10 | Object, 11 | Class, 12 | Class.new, 13 | Date.today, 14 | Pathname.new('.'), 15 | Time.now, 16 | Object.new.instance_eval { def this_is_a_really_really_really_really_really_long_method_name; end; self }, 17 | ].each do |object| 18 | # This might be cheating, but I'm hesitant to hard code something in here, 19 | # given that it could change as Ruby changes. 20 | expected = object.methods.max_by(&:length) 21 | it "returns #{expected.inspect} for #{object.inspect}" do 22 | actual = longest_method(object) 23 | expect(actual).to eq expected 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /session5/1-notes/01-modules-introduction.rb: -------------------------------------------------------------------------------- 1 | #Watch this video - https://vimeo.com/25294157 - these notes are supplementary as per the last section 2 | 3 | # Modules are just like classes in that they contain methods. But 4 | # unlike classes, you can't instantiate them. Instead, we include 5 | # their methods in some other class, and then its instances get 6 | # the module's methods. 7 | 8 | # A class can only inherit from one other class, but it can include 9 | # as many modules as it likes (this is commonly called a mix-in) 10 | 11 | # Because of this (among other things), mixing modules in is usually 12 | # preferred in the Ruby community, rather than subclassing. 13 | # Now, people usually prefer to get functionality by mixing in a 14 | # module rather than subclassing another class. 15 | 16 | -------------------------------------------------------------------------------- /session1/1-notes/16-p.rb: -------------------------------------------------------------------------------- 1 | # One other important output method is the 'p' method. p outputs an object's internal representation: 2 | # think of it as how the object looks in code. This kind of output is what we've been putting to the right of 3 | # lines of code in these notes. 4 | 5 | puts "Rain and lightning" 6 | p "Rain and lightning" 7 | 8 | # Output of puts: 9 | # Rain and lightning 10 | 11 | # Output of p: 12 | # "Rain and lightning" 13 | 14 | 15 | # Notice how the p method puts quote ( "" ) around the string. Here's one more example. 16 | # (in Ruby, a list of objects is called an array. We'll talk about arrays later) 17 | 18 | array = [1, 2, 3] 19 | 20 | puts array 21 | p array 22 | 23 | # Output: 24 | 25 | # puts: 26 | # 1 27 | # 2 28 | # 3 29 | 30 | # p: 31 | # [1, 2, 3] 32 | 33 | -------------------------------------------------------------------------------- /session2/1-notes/10-instance-variables.rb: -------------------------------------------------------------------------------- 1 | # Objects store their state in instance variables 2 | # Those are the ones that begin with the @asperand 3 | 4 | # Before, we said methods are their own little world. 5 | # That was a lie, they can see instance variables. 6 | # We'll talk more about that in a bit. 7 | class Car 8 | # we call methods like this a "setter" 9 | def set_miles(miles) 10 | @miles = miles 11 | end 12 | 13 | # we call methods like this a "getter" 14 | def get_miles 15 | @miles 16 | end 17 | end 18 | 19 | car = Car.new 20 | car.set_miles 1000 21 | car.get_miles # => 1000 22 | 23 | car.instance_variables # => [:@miles] 24 | car.instance_variable_get '@miles' # => 1000 25 | 26 | 27 | # Question: We create our car by calling Car.new 28 | # where is the new method defined? 29 | -------------------------------------------------------------------------------- /session3/5-solved/5.rb: -------------------------------------------------------------------------------- 1 | def spiral_access(arrays, iteration=0, &block) 2 | y_max = arrays.length - 1 3 | x_max = arrays.first.length - 1 4 | 5 | # base step 6 | return if y_max/2 < iteration || x_max/2 < iteration 7 | 8 | # top row 9 | iteration.upto x_max-iteration do |x| 10 | block.call arrays[iteration][x] 11 | end 12 | 13 | # right column 14 | (iteration + 1).upto y_max-iteration do |y| 15 | block.call arrays[y][x_max-iteration] 16 | end 17 | 18 | # bottom row 19 | (x_max - 1 - iteration).downto iteration do |x| 20 | block.call arrays[y_max-iteration][x] 21 | end 22 | 23 | # left column 24 | (y_max - 1 - iteration).downto iteration+1 do |y| 25 | block.call arrays[y][iteration] 26 | end 27 | 28 | # recursive step 29 | spiral_access arrays, iteration+1, &block 30 | end 31 | -------------------------------------------------------------------------------- /session4/3-challenge/9_exceptions.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solutions file, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # You need to write a method that will take a person and 4 | # generate their full name. A full name is just a first_name 5 | # and a last_name separated by a space. 6 | # 7 | # Sometimes, though, the code will raise a FirstNameError 8 | # In these cases, just return their last name. 9 | # 10 | # Other times, the code will raise a LastNameError 11 | # In these cases, just return their first name. 12 | # 13 | # And sometimes, it will raise other unexpected errors. 14 | # In these cases, don't do anything, because we don't know 15 | # why that error was raised. 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /session1/1-notes/04-variables.rb: -------------------------------------------------------------------------------- 1 | # The data for the objects exist in a part of memory called the "heap" 2 | # When Ruby wants to store an object, it goes to the heap, finds available memory, and then puts the object's data there. 3 | # But how will we know where we put our object? We need something to keep track of that location (called its address). 4 | # 5 | # Variables are like little fingers that point to memory addresses! 6 | # They let us keep track of where our objects are -- so you can access objects through variables. 7 | 8 | five = 5 # five is a variable, 5 is the object it is pointing to 9 | 10 | five.even? # => false 11 | five.odd? # => true 12 | five.next # => 6 13 | 14 | 15 | # Variables can be set to point to new values 16 | 17 | five # => 5 18 | five = "five" 19 | five # => "five" 20 | 21 | -------------------------------------------------------------------------------- /session5/1-notes/14-gems-introduction.rb: -------------------------------------------------------------------------------- 1 | # So you can do pretty much anything with Ruby. But you will have 2 | # to build all the tools yourself. When you write code that is 3 | # intended to be used as a tool by other software, that is called 4 | # a library. 5 | 6 | # In Ruby, the tool that knows how to work with dates is a library. 7 | # If I want to work with dates, I just require that library, and 8 | # now I magically have all of its functionality! What a treasure 9 | # trove of useful code, libraries are ^_^ 10 | require 'date' 11 | Date.today # => # 12 | 13 | 14 | # Date comes with Ruby, in something called the standard library 15 | # http://ruby-doc.org/stdlib/ 16 | 17 | # But there are other libraries, libraries written by people like 18 | # you and me. We call these libraries gems. 19 | 20 | -------------------------------------------------------------------------------- /session6/5-solved/1_build_an_app/lib/caesar_cipher.rb: -------------------------------------------------------------------------------- 1 | module CaesarCipher 2 | 3 | # Hash where you give it a character and it returns the 4 | # encrypted or decrypted value (will be built up below) 5 | ENCRYPT_MAP = Hash.new { |hash, key| key } 6 | DECRYPT_MAP = Hash.new { |hash, key| key } 7 | 8 | lowercase = ('a'..'z').to_a 9 | uppercase = ('A'..'Z').to_a 10 | numerical = ('0'..'9').to_a 11 | 12 | # now, for each group, map the appropriate characters 13 | [lowercase, uppercase, numerical].each do |chars| 14 | ENCRYPT_MAP.merge! Hash[chars.zip(chars.rotate 3)] 15 | DECRYPT_MAP.merge! Hash[chars.zip(chars.rotate -3)] 16 | end 17 | 18 | def self.encrypt(message) 19 | message.gsub /./, ENCRYPT_MAP 20 | end 21 | 22 | def self.decrypt(message) 23 | message.gsub /./, DECRYPT_MAP 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /session1/1-notes/23-if-returns-a-value.rb: -------------------------------------------------------------------------------- 1 | # Anywhere you can write code in Ruby returns a value, including if statements. 2 | 3 | result = if true 4 | "yep, it's true" 5 | else 6 | "nope, it's not true" 7 | end 8 | 9 | result # => "yep, it's true" 10 | 11 | 12 | 13 | # Lets put that in a method 14 | def if_returns_value(bool) 15 | if bool 16 | "yep it's true" 17 | else 18 | "nope, it's not true" 19 | end 20 | end 21 | 22 | if_returns_value true # => "yep it's true" 23 | if_returns_value false # => "nope, it's not true" 24 | 25 | 26 | 27 | # So does unless 28 | def unless_returns_value(bool) 29 | unless bool 30 | "nope, it's not true" 31 | else 32 | "yep, it's true" 33 | end 34 | end 35 | 36 | unless_returns_value true # => "yep, it's true" 37 | unless_returns_value false # => "nope, it's not true" 38 | 39 | -------------------------------------------------------------------------------- /session3/1-notes/02-symbols-always-the-same.rb: -------------------------------------------------------------------------------- 1 | # Every instance of the symbol is the same object, 2 | # notice they have the same object id. 3 | :this_is_a_symbol.object_id # => 212668 4 | :this_is_a_symbol.object_id # => 212668 5 | 6 | # Whereas each String is a new object, 7 | # notice they have different object ids. 8 | 'this is a string'.object_id # => 2149403240 9 | 'this is a string'.object_id # => 2149402020 10 | 11 | 12 | # This makes them easy to test equality. For a symbol you just check 13 | # if it is the same object, but for a String, you must check that 14 | # each character is the same character (iterate through the entire 15 | # string) this gives symbols a performance boost for checking 16 | # equality. 17 | 18 | 19 | # you typically use symbols in a situation where you wish to use 20 | # a constant, but want it to be named, like a String 21 | -------------------------------------------------------------------------------- /session5/4-spec/6.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'bar_regex' do 2 | def self.assert_finds(str, result) 3 | example "#{str.inspect}[bar_regex] # => #{result.inspect}" do 4 | result = str[bar_regex] 5 | expect(result).to eq result 6 | end 7 | end 8 | 9 | def self.assert_size(str, size) 10 | example "#{str.inspect}.scan(bar_regex).size # => #{size}" do 11 | matches = str.scan(bar_regex) 12 | expect(matches.size).to eq size 13 | end 14 | end 15 | 16 | assert_finds "bar", 'bar' 17 | assert_size "bar at the bar", 2 18 | assert_finds "ba\nr", nil 19 | assert_finds "Bar", 'Bar' 20 | assert_finds "bAr", nil 21 | assert_finds "BAR", nil 22 | assert_finds "Barrier", nil 23 | assert_finds "lowbar", nil 24 | assert_size "bar Bar bar.bar", 4 25 | end 26 | -------------------------------------------------------------------------------- /session5/1-notes/03-modules-extending.rb: -------------------------------------------------------------------------------- 1 | # Sometimes we want to give the module's functionality to just one 2 | # object. In this case, we include it in the object's singleton class. 3 | module OurModule 4 | def meth 5 | 'method from M' 6 | end 7 | end 8 | 9 | obj = Object.new 10 | class << obj 11 | include OurModule 12 | end 13 | obj.singleton_class.ancestors # => [OurModule, Object, Kernel, BasicObject] 14 | obj.meth # => "method from M" 15 | 16 | 17 | # Unfortunately, that's a little bit annoying to write, so there 18 | # is a shortcut syntax. Extending an object with a module is the 19 | # same as including the module in its singleton class. 20 | obj = Object.new 21 | obj.extend OurModule 22 | obj.singleton_class.ancestors # => [OurModule, Object, Kernel, BasicObject] 23 | obj.meth # => "method from M" 24 | 25 | -------------------------------------------------------------------------------- /session3/3-challenge/16_hash.rb: -------------------------------------------------------------------------------- 1 | # DO NOT SPEND MORE THAN 30-40 MINUTES STRUGGLING THROUGH THIS BEFORE MOVING ON! 2 | 3 | # Print to stdout, each element in a hash based linked list. 4 | # If you don't know what that is, go check out the previous problem. 5 | # 6 | # EXAMPLES: 7 | # head = {:data => 1, :next => nil} 8 | # print_list head # >> "1\n" 9 | # head = {:data => 2, :next => head} 10 | # print_list head # >> "2\n1\n" 11 | # head = {:data => 3, :next => head} 12 | # print_list head # >> "3\n2\n1\n" 13 | # head = {:data => 4, :next => head} 14 | # print_list head # >> "4\n3\n2\n1\n" 15 | # head = {:data => 5, :next => head} 16 | # print_list head # >> "5\n4\n3\n2\n1\n" 17 | # head = {:data => 6, :next => head} 18 | # print_list head # >> "6\n5\n4\n3\n2\n1\n" 19 | 20 | -------------------------------------------------------------------------------- /session2/4-spec/3.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'String#every_other_char' do 2 | specify '"" -> ""' do 3 | expect("".every_other_char).to eq "" 4 | end 5 | 6 | input = 'Four score and seven years ago...' 7 | output = 'Fu cr n ee er g..' 8 | specify "#{input.inspect} -> #{output.inspect}" do 9 | expect(input.every_other_char).to eq output 10 | end 11 | 12 | %w( 13 | abcdefg aceg 14 | 0101010 0000 15 | 1010101 1111 16 | !@#$%^& !#%& 17 | 1 1 18 | 12 1 19 | 123 13 20 | 1234 13 21 | 12345 135 22 | 123456 135 23 | 1234567 1357 24 | lksjdafoijdsfioewutwekgnsdsoihblskjdklsgjoiuewyghowbnwoeincwe lsdfidfowtegssibsjksjieyhwnoice 25 | ).each_slice 2 do |input, output| 26 | specify "#{input.inspect} -> #{output.inspect}" do 27 | expect(input.every_other_char).to eq output 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /session5/4-spec/8.rb: -------------------------------------------------------------------------------- 1 | gemlist = %x(gem list) 2 | 3 | RSpec.describe 'gem installation' do 4 | specify "rubygems is running (if you're on 1.8, try `require 'rubygems'`)" do 5 | expect { Gem }.to_not raise_error 6 | end 7 | 8 | specify 'helloworld gem is installed' do 9 | expect(gemlist).to match /\bhelloworld\b/ 10 | end 11 | 12 | specify 'helloworld gem is required' do 13 | expect { HelloWorld }.to_not raise_error 14 | end 15 | 16 | specify 'sinatra gem is installed' do 17 | expect(gemlist).to match /\bsinatra\b/ 18 | end 19 | 20 | specify 'sinatra gem is required' do 21 | expect { Sinatra }.to_not raise_error 22 | end 23 | 24 | specify 'nokogiri gem is installed' do 25 | expect(gemlist).to match /\bnokogiri\b/ 26 | end 27 | 28 | specify 'nokogiri gem is required' do 29 | expect { Nokogiri }.to_not raise_error 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /session2/1-notes/03-array-iterating.rb: -------------------------------------------------------------------------------- 1 | numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 | 3 | # Use each to iterate, and pass a block 4 | # We'll cover blocks more later 5 | sum = 0 6 | numbers.each { |number| sum += number } 7 | sum # => 45 8 | 9 | 10 | # Use map to make a new array out of the elements 11 | # returned by the block 12 | squares = numbers.map { |number| number * number } 13 | squares # => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 14 | numbers # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 15 | 16 | 17 | # iterate over the array two at a time 18 | result = [] 19 | numbers.each_slice(2) { |a, b| result << [a, b] } 20 | result # => [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] 21 | 22 | 23 | # iterate over the array in groups of two 24 | # hitting each group as we go 25 | result = [] 26 | numbers[0..5].each_cons(2) { |a, b| result << [a, b] } 27 | result # => [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]] 28 | -------------------------------------------------------------------------------- /session4/3-challenge/8_exceptions.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solutions file, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # Write a method that receives a number 1 through 5. 4 | # Depending on the value of the number, it will raise 5 | # some particular type of exception. 6 | # 7 | # HINT: 8 | # All exceptions and errors are descendants of Exception. 9 | # (Exception is listed as an ancestor) 10 | # 11 | # Examples: 12 | # exception_raiser 1 # => # 13 | # exception_raiser 2 # => # 14 | # exception_raiser 3 # => # 15 | # exception_raiser 4 # => # 16 | # exception_raiser 5 # => # 17 | 18 | -------------------------------------------------------------------------------- /session1/1-notes/08-operators.rb: -------------------------------------------------------------------------------- 1 | # There are some special methods called operators. 2 | # They are special because the Ruby interpreter lets you use them in pretty ways, even though they are just methods. 3 | # That's called syntactic sugar! 4 | 5 | # there is a method named + 6 | 3.+(5) # => 8 7 | 8 | # but that's ugly, *ick*, Ruby is beautiful, so it lets you say 9 | 3 + 5 # => 8 10 | 2 - 4 # => -2 11 | 10 / 3 # => 3 12 | 10 % 3 # => 1 13 | 14 | # See, it knows what to do :) 15 | # (% tells you the remainder) 16 | 17 | # Ruby wants to help you, but syntactic sugar wouldn't be much help 18 | # if it changed the semantics of math, so Ruby respects order of operations. 19 | 2 * 3 + 10 # => 16 20 | 2 + 3 * 10 # => 32 21 | 22 | # Question: If operators are just methods on objects, can other objects have operators? 23 | # Lets open up irb and try it out! 24 | 25 | -------------------------------------------------------------------------------- /session2/1-notes/14-self.rb: -------------------------------------------------------------------------------- 1 | # At any given time in Ruby, you are in the context 2 | # of some object. Right now we're in the main object. 3 | 4 | # You can see what object you're in by looking at self. 5 | self # => main 6 | 7 | class String 8 | self # => String 9 | end 10 | 11 | class String 12 | def existential 13 | self # => "abc" 14 | end 15 | end 16 | "abc".existential 17 | 18 | 19 | # For a given context, you can always see your instance 20 | # variables and your methods. 21 | 22 | class Example 23 | self # => Example 24 | 25 | @abc = 123 26 | @abc # => 123 27 | 28 | # These will all work, because they all invoke new on 29 | # Example. Explicitly in the first two cases, implicitly 30 | # in the third. 31 | Example.new # => # 32 | self.new # => # 33 | new # => # 34 | end 35 | 36 | -------------------------------------------------------------------------------- /session1/1-notes/07-method-arguments.rb: -------------------------------------------------------------------------------- 1 | # You know how you and I can go to the same website, but even though we both see it in our browser, 2 | # is there only one website? 3 | # 4 | # Objects are the same way, when you pass one in, you can access it from the variable outside 5 | # and inside the method, but there is still just one object. 6 | 7 | def browser_goto(website) 8 | website.object_id # => 2151945040, 2151945040 9 | "Direct your browser towards #{website}" 10 | end 11 | 12 | # the same object id means they are the same object 13 | website = "ruby-kickstart.com" 14 | website.object_id # => 2151945040 15 | browser_goto(website) # => "Direct your browser towards ruby-kickstart.com" 16 | 17 | # Ruby likes to be beautiful, it doesn't make you put parentheses where it can figure out what you meant. 18 | browser_goto website # => "Direct your browser towards ruby-kickstart.com" 19 | 20 | -------------------------------------------------------------------------------- /session4/4-spec/5.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | RSpec.describe 'line_sums' do 4 | expected_answers = { 5 | '8.1' => 4399, 6 | '8.2' => 0, 7 | '8.3' => 4399, 8 | '8.4' => 12, 9 | '8.5' => 3, 10 | '8.6' => 5, 11 | '8.7' => 23793343701, 12 | '8.8' => 880754605216, 13 | '8.9' => 2987648672, 14 | } 15 | 16 | template_pattern = File.expand_path "../../resources/*.template", __FILE__ 17 | Dir[template_pattern].each do |template_path| 18 | real_path = template_path.sub /\.template$/, '' 19 | expected_answer = expected_answers.fetch real_path[/(\d+\.\d+$)/] 20 | 21 | example "#{real_path} sums to #{expected_answer}" do 22 | begin 23 | FileUtils.cp template_path, real_path 24 | expect(line_sums real_path).to eq expected_answer 25 | ensure 26 | FileUtils.rm real_path 27 | end 28 | end 29 | 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /session2/5-solved/13.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | 3 | class User 4 | attr_accessor :username, :blogs 5 | 6 | def initialize(username) 7 | self.username = username 8 | self.blogs = [] 9 | end 10 | 11 | def add_blog(date, text) 12 | added_blog = Blog.new(date, self, text) 13 | blogs << added_blog 14 | self.blogs = blogs.sort_by { |blog| blog.date }.reverse 15 | added_blog 16 | end 17 | end 18 | 19 | 20 | 21 | class Blog 22 | attr_accessor :date, :user, :text 23 | 24 | def initialize(date, user, text) 25 | self.date = date 26 | self.user = user 27 | self.text = text 28 | end 29 | 30 | def summary 31 | text.split[0..9].join(' ') 32 | end 33 | 34 | def entry 35 | "#{user.username} #{date}\n#{text}" 36 | end 37 | 38 | def ==(other) 39 | date == other.date && 40 | user == other.user && 41 | text == other.text 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /cheatsheets/general.txt: -------------------------------------------------------------------------------- 1 | Terminal: 2 | Make Directory: mkdir directory_name 3 | Change Directories: cd directory_name 4 | Go to Parent Directory: cd .. 5 | List Directory Contents: ls -l 6 | Print Working Directory: pwd 7 | Check for Program: which program_name 8 | Display Contents of File: cat file_name 9 | 10 | Ruby: 11 | Run a Ruby Script: ruby program_name.rb 12 | Stop a Ruby Script: Control + c 13 | See Command Line Options: ruby -h 14 | Install a Gem: [sudo] gem install gem_name 15 | See All Rake Tasks: rake -T 16 | See All Rake Tasks For Ch 2: rake -T ^2 17 | 18 | git: 19 | pull down most recent code: 20 | git add -A 21 | git commit -m "getting ready to pull" 22 | git pull origin master 23 | ( if there is a problem, call me and I'll walk you through it ) -------------------------------------------------------------------------------- /session5/3-challenge/3_modules.rb: -------------------------------------------------------------------------------- 1 | # If you struggle on this question for ~30 minutes and aren't getting anywhere, look at the solution, try to understand the code, then close the file, come back here, and try again to solve it. 2 | 3 | # Write a list class. Implementation doesn't matter. 4 | # 5 | # list = List.new 6 | # list << 1 7 | # list << 5 8 | # list << 3 9 | # list << 4 10 | # list << 2 11 | # list # => # 12 | # 13 | # 14 | # Then give it an each method that iterates over its items in the order they were inserted 15 | # ary = [] 16 | # ff.each do |crnt| 17 | # ary << crnt 18 | # end 19 | # ary # => [1, 5, 3, 4, 2] 20 | # 21 | # 22 | # Then use the Enumerable module http://ruby-doc.org/core/classes/Enumerable.html to give 23 | # your class its methods. 24 | # ff.max # => 5 25 | # ff.min # => 1 26 | # ff.select { |num| num.odd? } # => [1, 5, 3] 27 | 28 | 29 | -------------------------------------------------------------------------------- /session5/1-notes/10-regex-characters.rb: -------------------------------------------------------------------------------- 1 | # Any alphanumeric character will match itself. 2 | "abc"[/b/] # => "b" 3 | 4 | 5 | # Use brackets to declare a set of characters to match 6 | # Match any character not in the set by leading it with a caret. 7 | "proud pink pandas".scan(/p[aeiou]/) # => ["pi", "pa"] 8 | "proud pink pandas".scan(/p[^aeiou]/) # => ["pr"] 9 | 10 | 11 | # The dot will match any character except newlines. 12 | "proud pink pandas".scan(/pr/) # => ["pr"] 13 | "proud pink pandas".scan(/pi/) # => ["pi"] 14 | "proud pink pandas".scan(/pa/) # => ["pa"] 15 | "proud pink pandas".scan(/p./) # => ["pr", "pi", "pa"] 16 | 17 | 18 | # You can give character ranges inside of brackets. 19 | alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 20 | alphabet.scan(/[a-cmnoy-z]/) # => ["a", "b", "c", "m", "n", "o", "y", "z"] 21 | -------------------------------------------------------------------------------- /session1/1-notes/21-true-and-false.rb: -------------------------------------------------------------------------------- 1 | # Logic in Ruby operates on "boolean" objects. If I'm not lying, then they're named after the guy who invented logic! 2 | # A boolean object is just an object that can be considered true or false. 3 | 4 | # the true object: 5 | true.class # => TrueClass 6 | 'yep, its true' if true # => "yep, its true" 7 | 8 | # the false object: 9 | false.class # => FalseClass 10 | 'nope, its not true' if false # => nil 11 | 12 | # you can flip them with a leading bang 13 | !true # => false 14 | !false # => true 15 | !!true # => true 16 | !!false # => false 17 | 18 | 19 | # But what about all the other objects? They want to be boolean too! 20 | # Turns out they can! (except nil, he can go sit in the corner with false) 21 | 22 | [0, 1, "two", :three, Object.new, nil].each do |object| 23 | !!object # => true, true, true, true, true, false 24 | end 25 | 26 | -------------------------------------------------------------------------------- /session5/1-notes/05-nesting-classes-and-modules.rb: -------------------------------------------------------------------------------- 1 | # You can declare classes and modules inside of each other. 2 | class A 3 | 4 | class B 5 | end 6 | 7 | module C 8 | module D 9 | class C 10 | def self.deep_in_the_hole 11 | "The further down I go, pulls the strings on my violin bow" 12 | end 13 | end 14 | end 15 | end 16 | 17 | end 18 | 19 | # You can then access them with :: 20 | A # => A 21 | A::B # => A::B 22 | A::C # => A::C 23 | A::C::D # => A::C::D 24 | A::C::D::C # => A::C::D::C 25 | A::C::D::C.deep_in_the_hole # => "The further down I go, pulls the strings on my violin bow" 26 | 27 | 28 | # Note that even though they're named the same, these are different, 29 | # like similarly named files in different directories 30 | A::C == A::C::D::C # => false 31 | -------------------------------------------------------------------------------- /session5/3-challenge/8_rubygems.rb: -------------------------------------------------------------------------------- 1 | # Install the following gems: 2 | # helloworld https://rubygems.org/gems/helloworld 3 | # sinatra https://rubygems.org/gems/sinatra 4 | # nokogiri https://rubygems.org/gems/nokogiri 5 | # 6 | # Nokogiri has C code that it needs to compile, if this doesn't work for you, it's probably because you need a compiler: 7 | # 8 | # Mac: You need to install XCode http://developer.apple.com/xcode/ 9 | # Linux: Probably gcc, I'm not sure how to get it, because I don't use Linux, but there 10 | # should be some sort of package manager like Synaptic or apt-get that will do it. 11 | # Windows: You probably need the devkit: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit 12 | # 13 | # Then require them in this document 14 | # Note: Even though you install helloworld, the name of the file you need to require is hello_world (with an underscore) 15 | 16 | -------------------------------------------------------------------------------- /session1/1-notes/06-method-scope.rb: -------------------------------------------------------------------------------- 1 | # When you make a method, remember that it is its own little world, 2 | # it doesn't know about anything outside of itself, this is called scope. 3 | 4 | defined? twelve # => nil 5 | twelve = 12 6 | defined? twelve # => "local-variable" 7 | 8 | def my_own_little_world 9 | defined? twelve # => nil 10 | end 11 | 12 | my_own_little_world # => nil 13 | defined? twelve # => "local-variable" 14 | 15 | 16 | # Well that seems pretty useless, eh? Fortunately, there is an Internet connection on this world! 17 | # You can pass objects, into the method. When we pass an object in, the variable that points to it 18 | # is called an argument or a parameter 19 | 20 | # person1 and person2 are arguments or parameters 21 | def beam_me_up(person1, person2) 22 | "The away team consists of #{person1} and #{person2}." 23 | end 24 | 25 | beam_me_up("Ryker", "Data") # => "The away team consists of Ryker and Data." 26 | 27 | -------------------------------------------------------------------------------- /session4/1-notes/05-ranges.rb: -------------------------------------------------------------------------------- 1 | # ranges look like this 2 | 1..5 # => 1..5 3 | 1...5 # => 1...5 4 | 5 | # 2 dots includes the end 6 | (1..3).to_a # => [1, 2, 3] 7 | 8 | # 3 dots excludes the end 9 | (1...3).to_a # => [1, 2] 10 | 11 | 12 | 13 | # They are iterable, using the methods in by Enumerable module 14 | iterated = Array.new 15 | (1..5).each { |n| iterated << n } 16 | iterated # => [1, 2, 3, 4, 5] 17 | 18 | (1...5).map { |n| n * 5 } # => [5, 10, 15, 20] 19 | ('a'..'c').to_a # => ["a", "b", "c"] 20 | 21 | 22 | # They make good arguments to things like arrays 23 | [1,2,3,4,5][1..3] # => [2, 3, 4] 24 | 25 | 26 | # You can use variables also 27 | start = 10 28 | stop = 15 29 | start..stop # => 10..15 30 | 31 | 32 | # They're mostly useless, but you'll see them every now and 33 | # then, so just be aware of what they are. 34 | -------------------------------------------------------------------------------- /session1/4-spec/7.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "pirates_say_arrrrrrrrr" do 2 | it 'returns "eeu" when given "are you really learning Ruby?"' do 3 | expect(pirates_say_arrrrrrrrr 'are you really learning Ruby?').to eq 'eenu' 4 | end 5 | 6 | it 'returns "rya" when given "Katy Perry is on the radio!"' do 7 | expect(pirates_say_arrrrrrrrr 'Katy Perry is on the radio!').to eq 'rya' 8 | end 9 | 10 | it 'returns "arrrrrrrr" when given "Pirates say arrrrrrrrr"' do 11 | expect(pirates_say_arrrrrrrrr 'Pirates say arrrrrrrrr').to eq 'arrrrrrrr' 12 | end 13 | 14 | it 'returns "12" when given "r1r2r"' do 15 | expect(pirates_say_arrrrrrrrr 'r1r2r').to eq '12' 16 | end 17 | 18 | it 'returns "" when given ""' do 19 | expect(pirates_say_arrrrrrrrr '').to eq '' 20 | end 21 | 22 | it 'returns "" when given "Quickly she consumed the apple."' do 23 | expect(pirates_say_arrrrrrrrr 'Quickly she consumed the apple.').to eq '' 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /session1/2-examples/4_rememberer2.rb: -------------------------------------------------------------------------------- 1 | # Did you understand the last one? 2 | # This is the same one, but we abstracted the tasks 3 | # into methods that are easier to test, 4 | # and can be reused easily. They also let us talk 5 | # about a task based on the method name, which is 6 | # much simpler than the piece of code behind it. 7 | 8 | 9 | def get_line 10 | gets.chomp 11 | end 12 | 13 | def finished?(line) 14 | line == "exit" 15 | end 16 | 17 | def user_message(lines_seen, line) 18 | if lines_seen.include? line 19 | "Yes, I've seen #{line} before" 20 | else 21 | "No, I haven't seen #{line} before" 22 | end 23 | end 24 | 25 | def record_observation(lines_seen, line) 26 | unless lines_seen.include? line 27 | lines_seen << line 28 | end 29 | end 30 | 31 | 32 | lines_seen = [] 33 | 34 | loop do 35 | line = get_line 36 | break if finished?(line) 37 | puts user_message(lines_seen, line) 38 | record_observation(lines_seen, line) 39 | end 40 | 41 | -------------------------------------------------------------------------------- /session4/1-notes/13-inheritance-example.rb: -------------------------------------------------------------------------------- 1 | # This will be our superclass. There are many kinds of employees but 2 | # they all have wages, and each type makes a certain dollars per hour. 3 | class Employee 4 | class << self 5 | attr_accessor :dollars_per_hour 6 | end 7 | 8 | attr_accessor :hours_worked 9 | 10 | def initialize( hours_worked ) 11 | self.hours_worked = hours_worked 12 | end 13 | 14 | def wages 15 | self.class.dollars_per_hour * hours_worked 16 | end 17 | end 18 | 19 | 20 | # Bill is a clerk, he makes 160 hours * $20 per hour = $3200 21 | class Clerk < Employee 22 | self.dollars_per_hour = 20 23 | end 24 | bill = Clerk.new 160 25 | bill.wages # => 3200 26 | 27 | 28 | # Ayaan is an engineer, she makes 29 | # 160 hours * $30 per hour + $500 per month = $5300 30 | class Engineer < Employee 31 | self.dollars_per_hour = 30 32 | def wages 33 | super + 500 34 | end 35 | end 36 | ayaan = Engineer.new 160 37 | ayaan.wages # => 5300 38 | -------------------------------------------------------------------------------- /session3/4-spec/1.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'reverse_map' do 2 | it 'defined a reverse_map method' do 3 | expect(method :reverse_map).to be 4 | end 5 | 6 | specify 'reverse_map(1, 2, 3) { |i| i * 2 } # => [6, 4, 2]' do 7 | times_2 = reverse_map(1, 2, 3) { |i| i * 2 } 8 | expect(times_2).to eq [6, 4, 2] 9 | end 10 | 11 | specify 'reverse_map {} # => []' do 12 | expect(reverse_map {}).to eq [] 13 | end 14 | 15 | specify 'reverse_map # => []' do 16 | expect(reverse_map.to_a).to eq [] 17 | end 18 | 19 | specify 'reverse_map("a", "b", "c") { |char| char * 3 } # => ["ccc", "bbb", "aaa"]' do 20 | expect(reverse_map("a", "b", "c") { |char| char * 3 }).to eq ["ccc", "bbb", "aaa"] 21 | end 22 | 23 | specify 'reverse_map(*1..1000) { |i| i * i } # => [1000000, 998001, ..., 9, 4, 1]' do 24 | expected = (1..1000).to_a.reverse.map { |i| i * i } 25 | actual = reverse_map(*1..1000) { |i| i * i } 26 | expect(actual).to eq expected 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /session5/5-solved/2.rb: -------------------------------------------------------------------------------- 1 | # it goes in ApplicationController so that everyone who inherits from it will have it available 2 | class ApplicationController 3 | 4 | # because we invoke it from the context of the class definition, and not from any particular instance, 5 | # it must be a class method, so goes in class << self 6 | def self.css_classes(*body_classes) 7 | options = body_classes.pop if body_classes.last.is_a? Hash # remove the last argument if it is the options hash 8 | options ||= Hash.new # if the above didn't happen, set options anyway 9 | 10 | # invoke the before filter and pass it the options 11 | before_filter options do |controller| 12 | 13 | # for each of the css classes passed in, add them to the controller's body_class method that you wrote in challenge 1 14 | body_classes.each do |css_body_class| 15 | controller.body_class << css_body_class 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /session2/3-challenge/2_input_output_control.rb: -------------------------------------------------------------------------------- 1 | # Prompt the user for a number, then read it in and print out "hi" that many times 2 | # 3 | # Repeat this process until the user submits "bye", then say "goodbye" and end the program 4 | # HINT: Check out example 2 if you get stuck 5 | 6 | # example: 7 | # PROGRAM: Enter a number 8 | # USER: 4 9 | # PROGRAM: hi hi hi hi 10 | # PROGRAM: Enter a number 11 | # USER: 2 12 | # PROGRAM: hi hi 13 | # PROGRAM: Enter a number 14 | # USER: bye 15 | # PROGRAM: goodbye 16 | 17 | 18 | # remember you can try your program out with $ ruby 2_input_output_control.rb 19 | # and when you think it is correct, you can test it with $ rake 2:2 20 | 21 | def hi_hi_goodbye 22 | # your code here 23 | 24 | end 25 | 26 | 27 | 28 | 29 | # This will just invoke the method if you run this program directly 30 | # This way you can try it out by running "$ ruby 2_input_output_control.rb" 31 | # but it will still work for our tests 32 | hi_hi_goodbye if $0 == __FILE__ -------------------------------------------------------------------------------- /session6/1-notes/05-erb.rb: -------------------------------------------------------------------------------- 1 | # Web sites use a language called HTML to organize what a site 2 | # should look like on a page (I'm not going to cover HTML, if you 3 | # want to learn about it, consider http://htmldog.com). 4 | 5 | # The best way to write HTML that needs to be dynamic is to use a 6 | # templating language like ERB, this lets us embed our Ruby right 7 | # into the html. 8 | shopping_cart = ['lamp', 'desk', 'pencils'] 9 | template = " 10 |
    11 | <% shopping_cart.each do |item| %> 12 |
  • <%= item %>
  • 13 | <% end %> 14 |
15 | " 16 | 17 | # For lines where you don't want to keep the output, like the line 18 | # that iterates over the shopping cart, you put your Ruby inside <% %> 19 | # tags. For lines where you want to embed the output, put your code 20 | # inside of <%= %> tags. 21 | 22 | require 'erb' 23 | puts ERB.new(template).result 24 | # >> 25 | # >>
    26 | # >> 27 | # >>
  • lamp
  • 28 | # >> 29 | # >>
  • desk
  • 30 | # >> 31 | # >>
  • pencils
  • 32 | # >> 33 | # >>
34 | -------------------------------------------------------------------------------- /session5/1-notes/09-regex-how-to-match.rb: -------------------------------------------------------------------------------- 1 | # There are several common ways of matching regular expressions. 2 | # The most common is the =~ operator. This is the only place you 3 | # will see that operator, it is the choice for mostly historical 4 | # reasons (inherited notation from Perl and somewhat from Awk) 5 | # This operator returns the first index of the first match, or nil. 6 | "Sal Khan" =~ /S/ # => 0 7 | "Sal Khan" =~ /a/ # => 1 8 | "Sal Khan" =~ /l/ # => 2 9 | "Sal Khan" =~ /W/ # => nil 10 | "Sal Khan" =~ /s/ # => nil 11 | 12 | # If you pass a regular expression to a String's [] method, 13 | # then it will return where it matches 14 | "bobbling babbling bubbles"[/b.b/] # => "bob" 15 | "bobbling babbling bubbles"[/B.b/] # => nil 16 | 17 | # If you pass it to the scan method, it will return an array 18 | # of all the matches. 19 | "bobbling babbling bubbles".scan(/b.b/) # => ["bob", "bab", "bub"] 20 | 21 | -------------------------------------------------------------------------------- /session6/1-notes/06-sinatra-views-layouts-params-and-variables/main.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | 3 | # VIEWS: 4 | # Sinatra makes using ERB simpler for you. It will look in a directory 5 | # called views, for files named after the view you tell it you want. 6 | # 7 | # By default, it will also look for a file views/layout.erb, which it 8 | # will render content into. 9 | 10 | get '/' do 11 | erb :home_page # tells Sinatra to render views/home_page.erb 12 | end 13 | 14 | 15 | 16 | # PARAMS: 17 | # The contents of the form we submitted on the home_page comes in 18 | # in a hash Sinatra makes available to us through the params method. 19 | # Since the form was named cart_items, that is the key its contents 20 | # are available through. 21 | 22 | post '/cart' do 23 | # Each time someone makes an HTTP request, we get a new Sinatra 24 | # object to handle that request. So if we use instance variables 25 | # then they will be available everywhere, including inside our views 26 | @cart_items = params[:cart_items].split 27 | erb :cart 28 | end 29 | -------------------------------------------------------------------------------- /session5/1-notes/08-regex-introduction.rb: -------------------------------------------------------------------------------- 1 | # Regular expressions are one of those things that look really scary, 2 | # and take some time to get used to, but they are not that difficult 3 | # to use, and they are _very_ useful. These are probably the things 4 | # that are most useful to a non programmer, their job is to help you 5 | # process Strings. They are patterns that strings can fit into. 6 | # And they are mostly pretty easy :). You just have to learn a few 7 | # rules, and have a cheatsheet until you get to know them. 8 | 9 | 10 | # First, go check out rubular.com where you can put in a String and 11 | # a regular expression, and you can see all the places it matches 12 | # For the regular expression enter "b.b" and for the String, 13 | # "bobbling babbling bubbles" Notice that it has highlighted "bob", 14 | # "bab", and "bub". These are the areas where your regular expression 15 | # matches the String (the dot matches any character). 16 | 17 | # Strings begin and end with quotes, regexes with slashes 18 | /this is a regular expression/ 19 | 20 | -------------------------------------------------------------------------------- /session2/1-notes/02-arrays.rb: -------------------------------------------------------------------------------- 1 | # Arrays are ordered lists of objects. 2 | array = ['zero', 'one', 'two'] 3 | 4 | 5 | # You access a given element by its index, 6 | # beginning at zero 7 | array[0] # => "zero" 8 | array[1] # => "one" 9 | array[2] # => "two" 10 | 11 | 12 | # If you go past the end, you get back nil 13 | array[3] # => nil 14 | 15 | 16 | # Negative indexes backwards from the end 17 | array[-1] # => "two" 18 | array[-2] # => "one" 19 | array[-3] # => "zero" 20 | 21 | 22 | # Arrays know where the elements at their indexes are this 23 | # means it is just as cheap to look up an element really 24 | # deep as it is for an element right at the beginning. 25 | array = (0...5000).to_a # the numbers 1 to 5k 26 | 27 | 28 | # about half a second to access element at index 2500 29 | start_time = Time.now 30 | 5_000_000.times { array[2500] } 31 | Time.now - start_time # => 0.545612 32 | 33 | 34 | # about half a second to access element at index 0 35 | start_time = Time.now 36 | 5_000_000.times { array[0] } 37 | Time.now - start_time # => 0.545922 38 | -------------------------------------------------------------------------------- /session6/1-notes/11-heroku-example/spec/username_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../main' 2 | require 'rack/test' 3 | 4 | set :environment, :test 5 | 6 | RSpec.describe 'The HelloWorld App' do 7 | include Rack::Test::Methods 8 | 9 | def app 10 | Sinatra::Application 11 | end 12 | 13 | context 'get "/Cheek/Joshua"' do 14 | before { get '/Cheek/Joshua' } 15 | specify { expect(last_response).to be_ok } 16 | specify { expect(last_response.body).to include "Joshua Cheek's username is jcheek" } 17 | end 18 | 19 | context 'get "/Cheek/Joshua/Jay"' do 20 | before { get '/Cheek/Joshua/Jay' } 21 | specify { expect(last_response).to be_ok } 22 | specify { expect(last_response.body).to include "Joshua Jay Cheek's username is jjcheek" } 23 | end 24 | 25 | context 'get "/Matsumoto/Yukihiro"' do 26 | before { get '/Matsumoto/Yukihiro' } 27 | specify { expect(last_response).to be_ok } 28 | specify { expect(last_response.body).to include "Yukihiro Matsumoto's username is ymatsu" } 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /session3/1-notes/12-all-methods-take-blocks.rb: -------------------------------------------------------------------------------- 1 | # When you pass a block as a parameter, the block gets put into 2 | # a special slot that every method has, whether they use the 3 | # block or not. 4 | def method 5 | "result" 6 | end 7 | method {} # => "result" 8 | method # => "result" 9 | 10 | 11 | # To access the block, use the ampersand, this will 12 | # give it to you as a proc that you can use. 13 | def method2(&block) 14 | block.call.upcase 15 | end 16 | method2 { 'from the block' } # => "FROM THE BLOCK" 17 | 18 | 19 | # If you didn't pass a block, it will be set to nil. 20 | def method3(&block) 21 | if block 22 | "The block evaluates to #{block.call}" 23 | else 24 | "No block." 25 | end 26 | end 27 | method3 { ":)" } # => "The block evaluates to :)" 28 | method3 # => "No block." 29 | 30 | 31 | # Like with any proc, you can pass arguments to it 32 | def heres_six(&block) 33 | block.call 6 34 | end 35 | result = heres_six { |num| "#{num*2} is Josh's favourite number"} 36 | result # => "12 is Josh's favourite number" 37 | 38 | -------------------------------------------------------------------------------- /session5/5-solved/9.rb: -------------------------------------------------------------------------------- 1 | # We've already solved the problem of extracting the data, no need to do it again 2 | require File.dirname(__FILE__) + '/7' 3 | 4 | 5 | # In reality, I'd use a templating language like ERB, 6 | # but we haven't talked about those yet. 7 | def trees_to_html(trees) 8 | # the first part of the html skeleton 9 | result = ' 10 | 11 | 12 | Green Thumb Nursery 13 | 14 |

Catalog

15 | 16 | 17 | 18 | 19 | 20 | 21 | ' 22 | 23 | # for each record, add it to the html 24 | tree_parser(trees).each do |type, size, price| 25 | result << " 26 | 27 | 28 | 29 | 30 | 31 | " 32 | end 33 | 34 | # close off the html 35 | result << ' 36 |
Type of treeSize of the treePrice of the tree
#{type}#{size}#{price}
37 | 38 | 39 | ' 40 | 41 | result 42 | end 43 | -------------------------------------------------------------------------------- /session3/3-challenge/8_blocks.rb: -------------------------------------------------------------------------------- 1 | # This problem is based off of example 2 2 | # Modify it so that it also tracks a person's age and a quote 3 | # Allow any of these to be set with a hash as well, but the block should overwrite the hash 4 | # 5 | # 6 | # EXAMPLE: 7 | # 8 | # artist = Person.new :name => 'Prince' do |person| 9 | # person.age = 47 10 | # person.quote = "Why don't you purify yourself in the waters of Lake Minnetonka?" 11 | # end 12 | # 13 | # artist.name # => "Prince" 14 | # artist.age # => 47 15 | # 16 | # artist.name = 'The Artist Formarly Known As Prince' 17 | # artist.age = 1999 18 | # 19 | # artist.name # => "The Artist Formarly Known As Prince" 20 | # artist.age # => 1999 21 | # 22 | # artist.reinit 23 | # 24 | # artist.name # => "The Artist Formarly Known As Prince" 25 | # artist.age # => 47 26 | 27 | 28 | class Person 29 | 30 | attr_accessor :name 31 | 32 | def initialize( &initializer ) 33 | @initializer = initializer 34 | initializer.call self 35 | end 36 | 37 | def reinit 38 | @initializer.call self 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /session6/1-notes/10-git/notes.rb: -------------------------------------------------------------------------------- 1 | # Git is a source code management tool. It will keep track of all 2 | # your changes. It will also let you interact with remote code. 3 | # All of this code, for example, is maintained by git, and I can 4 | # put it on GitHub so that everyone else can download it or even 5 | # make changes and send them to me. 6 | 7 | # In the same way my code is on GitHub, my code is also on Heroku. 8 | # Heroku doesn't let anyone else see it like GitHub does, but 9 | # when I use git to push my code to Heroku, my web application 10 | # will automatically update. 11 | 12 | 13 | # Lets initialize a new git repo in this directory with `$ git init`. 14 | 15 | # We want to commit the contents into our git repository. So 16 | # we add them to the staging area with `$ git add .` (remember 17 | # the dot stands for the current directory) And then commit 18 | # with `$ git commit "initial commit"`. 19 | 20 | 21 | # Hooray, now our code is being managed by git. Lets make a 22 | # change. You can see the change with `$ git status`. 23 | 24 | # Go ahead and add it to the source code repository again. 25 | -------------------------------------------------------------------------------- /session3/1-notes/01-symbols-introduction.rb: -------------------------------------------------------------------------------- 1 | #Watch this video - https://vimeo.com/24673123 - these notes are supplementary as per the last section 2 | 3 | # Symbols look like this: 4 | :this_is_a_symbol # => :this_is_a_symbol 5 | :this_is_a_symbol.class # => Symbol 6 | 7 | 8 | # Symbols are Strings that are immutable, meaning they can never 9 | # change, like numbers. They are never garbage collected, so if 10 | # you use one, it will last until your program ends. 11 | 12 | 13 | # They are most commonly used as hash keys, because their hash 14 | # value can be cached, making them as efficient as a number for 15 | # this purpose. They are also used frequently in place of enum types, 16 | # and used internally in Ruby to refer to things like method names. 17 | 18 | 19 | # For example, it is common to declare attr_accessor with a symbol. 20 | # And instance_methods returns back symbols representing the methods, 21 | # because that's what Ruby uses internally. 22 | class Example 23 | instance_methods(false) # => [] 24 | attr_accessor :my_method 25 | instance_methods(false) # => [:my_method, :my_method=] 26 | end 27 | -------------------------------------------------------------------------------- /session3/1-notes/16-optional-params.rb: -------------------------------------------------------------------------------- 1 | # You have already seen ordinal parameters, they have a name and 2 | # are mandatory. But you can make them optional by giving them 3 | # an equal sign, and listing a default value. 4 | def same_case(str, upcase = true) 5 | return str.upcase if upcase 6 | str.downcase 7 | end 8 | 9 | same_case 'UPPER lower' # => "UPPER LOWER" 10 | same_case 'UPPER lower' , false # => "upper lower" 11 | 12 | 13 | # optional parameters must go to the right of ordinal parameters, 14 | # and are filled in from the left 15 | def what_are_filled_in(a=5, b=4, c=3, d=2, e=1) 16 | "#{a} #{b} #{c} #{d} #{e}" 17 | end 18 | 19 | what_are_filled_in # => "5 4 3 2 1" 20 | what_are_filled_in :A # => "A 4 3 2 1" 21 | what_are_filled_in :A , :B # => "A B 3 2 1" 22 | what_are_filled_in :A , :B , :C # => "A B C 2 1" 23 | what_are_filled_in :A , :B , :C , :D # => "A B C D 1" 24 | what_are_filled_in :A , :B , :C , :D , :E # => "A B C D E" 25 | 26 | # what will this return? 27 | what_are_filled_in :A , :E # => 28 | -------------------------------------------------------------------------------- /session4/4-spec/8.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe 'exception_raiser' do 2 | it 'when given 1, it raises #' do 3 | expect { exception_raiser 1 }.to raise_error(RuntimeError, "No 1s allowed!") 4 | end 5 | 6 | it 'when given 2, it raises #' do 7 | expect { exception_raiser 2 }.to raise_error(ArgumentError, "No 2s allowed!") 8 | end 9 | 10 | it 'when given 3, it raises #' do 11 | expect { exception_raiser 3 }.to raise_error(Exception, "No 3s allowed!") 12 | end 13 | 14 | it 'when given 4, it raises #' do 15 | expect { exception_raiser 4 }.to raise_error(SyntaxError, "No 4s allowed!") 16 | end 17 | 18 | it 'when given 5, it raises #' do 19 | expect { exception_raiser 5 }.to raise_error(RubyKickstartException, "No 5s allowed!") 20 | end 21 | 22 | [-1, 0, "abc", /abc/].each do |object| 23 | it "doesn't raise an error when it receives #{object.inspect}" do 24 | expect { exception_raiser object }.to_not raise_error 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /session5/1-notes/06-modules-namespacing.rb: -------------------------------------------------------------------------------- 1 | # A great use for modules is as namespaces: You can do all sorts 2 | # of stuff in a module, and it keeps it contained within that 3 | # module. This prevents conflicts with similarly named things 4 | # in other places. 5 | 6 | # Example: 7 | # Maybe you want to try the same problem several days in a row, 8 | # to see how your approach changes over time. 9 | module Day1Solutions 10 | class MinFinder 11 | def initialize(a, b) 12 | @a = a 13 | @b = b 14 | end 15 | def solve 16 | if @a < @b then @a else @b end 17 | end 18 | end 19 | end 20 | 21 | module Day2Solutions 22 | class MinFinder 23 | def initialize(a, b) 24 | @elements = [a, b] 25 | end 26 | def solve 27 | @elements.min 28 | end 29 | end 30 | end 31 | 32 | day1 = Day1Solutions::MinFinder.new 10, 5 33 | day2 = Day2Solutions::MinFinder.new 10, 5 34 | day1 # => # 35 | day2 # => # 36 | day1.solve # => 5 37 | day2.solve # => 5 38 | 39 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Joshua Cheek 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /session6/1-notes/01-web-introduction.rb: -------------------------------------------------------------------------------- 1 | #Watch this video - https://vimeo.com/25814869 - these notes are supplementary as per the last section 2 | 3 | # Every building in America has an address so you can send letters 4 | # to people who live there. In the same way, every computer on the 5 | # internet has an address so you can send data to programs that 6 | # are running there. This address is called an IP address and looks 7 | # like 74.125.91.103 8 | 9 | # When you send a letter to a building, there can be many people who 10 | # live there, so you write the apartment number, or the person's 11 | # name on the envelope. In the same way, when you send data to a 12 | # computer, there can be many programs that are running there, so 13 | # you specify which one you want to talk to by providing a port 14 | # number. The port is just an address that programs can reside at, 15 | # on the computer. 16 | 17 | # Your web application will use a program called a server to watch 18 | # the port for incoming data. The server will take the data, and 19 | # provide it to your application in a way that your application 20 | # can do something with it. 21 | 22 | -------------------------------------------------------------------------------- /session4/1-notes/16-exceptions-rescuing.rb: -------------------------------------------------------------------------------- 1 | def method_with_one_parameter(n) 2 | end 3 | 4 | 5 | # Code that might raise an error goes in begin/rescue/end blocks. 6 | begin 7 | method_with_one_parameter(1,2,3) 8 | # This code won't be executed because it happened after the exception. 9 | 1 + 2 # => 10 | rescue ArgumentError => e 11 | # We've rescued the Error, and are storing it in 12 | # the variable e. Errors are objects just like anything else. 13 | e # => # 14 | e.class # => ArgumentError 15 | e.class.ancestors # => [ArgumentError, StandardError, Exception, Object, Kernel, BasicObject] 16 | end 17 | 18 | 19 | 20 | # You can rescue specific exceptions if you like 21 | begin 22 | method_with_one_parameter(1,2,3) 23 | rescue ZeroDivisionError => e 24 | e # => 25 | rescue ArgumentError => e 26 | e # => # 27 | end 28 | 29 | 30 | begin 31 | 1 / 0 32 | rescue ZeroDivisionError => e 33 | e # => # 34 | rescue ArgumentError => e 35 | e # => 36 | end 37 | 38 | -------------------------------------------------------------------------------- /session5/1-notes/07-extending-main.rb: -------------------------------------------------------------------------------- 1 | # Lets say that we want to escape html output. This prevents someone 2 | # from submitting html to a form and having it mess up our page's 3 | # html when we put it in there gets displayed. Well, there is a method 4 | # to do this in ERB::Util, which we can get from the standard library 5 | require 'erb' 6 | 7 | ERB::Util.h "