├── .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 |
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 |
2 |
3 | <% @cart_items.each do |item| %>
4 | - <%= item %>
5 | <% end %>
6 |
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 |
5 |
6 |
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 | | Type of tree |
18 | Size of the tree |
19 | Price of the tree |
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 | | #{type} |
28 | #{size} |
29 | #{price} |
30 |
31 | "
32 | end
33 |
34 | # close off the html
35 | result << '
36 |
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 "