Skip to content

Commit f4b50ce

Browse files
committed
do some koans and some chris pine exercises
1 parent 3db8020 commit f4b50ce

11 files changed

Lines changed: 478 additions & 33 deletions

File tree

koans/.path_progress

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0,0,0,1,2,3,5,6,6,6,6,7,7,7,8,8,9,10,11,11,11,12,13,13,14,13,13,14,14,15,16,17,18,18,18,18,18,18,19,20,21,21,22,23,27,27,29,31,32,33,34,34,35,36,36,37,38,39,39,40,41,41,41,42,43,45,46,47,49,49,50,50,50,51,51,52,56,59,59,60,62,64,65,65,65,65,65,66,68,70,73,74,74,74,74,74,74,74,74,74,74,75,76,77,78,79,80,81,81,82,83,83,83,84,85,85,87,88,89,90,91,92,93,94,95,96,97,98,98,99,100,102,104,105,106,106,106,107,108,108,110,111,111,113,113,113,113,114,115,116,119,120,121,121,121,121,122,124,124,125,126,129,130,132,133,136,138,141,142,143,145,148,152
1+
0,0,0,1,2,3,5,6,6,6,6,7,7,7,8,8,9,10,11,11,11,12,13,13,14,13,13,14,14,15,16,17,18,18,18,18,18,18,19,20,21,21,22,23,27,27,29,31,32,33,34,34,35,36,36,37,38,39,39,40,41,41,41,42,43,45,46,47,49,49,50,50,50,51,51,52,56,59,59,60,62,64,65,65,65,65,65,66,68,70,73,74,74,74,74,74,74,74,74,74,74,75,76,77,78,79,80,81,81,82,83,83,83,84,85,85,87,88,89,90,91,92,93,94,95,96,97,98,98,99,100,102,104,105,106,106,106,107,108,108,110,111,111,113,113,113,113,114,115,116,119,120,121,121,121,121,122,124,124,125,126,129,130,132,133,136,138,141,142,143,145,148,152,152,152,152,153,152,155,155,155,155,155,155,156,156,156,156,156,156,156,157,157,157,158,158,159,160,161,162,162,165,165,166,168,169,170,173,175

koans/about_blocks.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ def method_with_block
88

99
def test_methods_can_take_blocks
1010
yielded_result = method_with_block { 1 + 2 }
11-
assert_equal __, yielded_result
11+
assert_equal 3, yielded_result
1212
end
1313

1414
def test_blocks_can_be_defined_with_do_end_too
1515
yielded_result = method_with_block do 1 + 2 end
16-
assert_equal __, yielded_result
16+
assert_equal 3, yielded_result
1717
end
1818

1919
# ------------------------------------------------------------------
@@ -24,7 +24,7 @@ def method_with_block_arguments
2424

2525
def test_blocks_can_take_arguments
2626
method_with_block_arguments do |argument|
27-
assert_equal __, argument
27+
assert_equal "Jim", argument
2828
end
2929
end
3030

@@ -40,7 +40,7 @@ def many_yields
4040
def test_methods_can_call_yield_many_times
4141
result = []
4242
many_yields { |item| result << item }
43-
assert_equal __, result
43+
assert_equal [:peanut, :butter, :and, :jelly], result
4444
end
4545

4646
# ------------------------------------------------------------------
@@ -54,8 +54,8 @@ def yield_tester
5454
end
5555

5656
def test_methods_can_see_if_they_have_been_called_with_a_block
57-
assert_equal __, yield_tester { :with_block }
58-
assert_equal __, yield_tester
57+
assert_equal :with_block, yield_tester { :with_block }
58+
assert_equal :no_block, yield_tester
5959
end
6060

6161
# ------------------------------------------------------------------

koans/about_exceptions.rb

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ class MySpecialError < RuntimeError
66
end
77

88
def test_exceptions_inherit_from_Exception
9-
assert_equal __, MySpecialError.ancestors[1]
10-
assert_equal __, MySpecialError.ancestors[2]
11-
assert_equal __, MySpecialError.ancestors[3]
12-
assert_equal __, MySpecialError.ancestors[4]
9+
assert_equal RuntimeError, MySpecialError.ancestors[1]
10+
assert_equal StandardError, MySpecialError.ancestors[2]
11+
assert_equal Exception, MySpecialError.ancestors[3]
12+
assert_equal Object, MySpecialError.ancestors[4]
1313
end
1414

1515
def test_rescue_clause
@@ -20,15 +20,15 @@ def test_rescue_clause
2020
result = :exception_handled
2121
end
2222

23-
assert_equal __, result
23+
assert_equal :exception_handled, result
2424

25-
assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error"
26-
assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error"
25+
assert_equal true, ex.is_a?(StandardError), "Should be a Standard Error"
26+
assert_equal true, ex.is_a?(RuntimeError), "Should be a Runtime Error"
2727

2828
assert RuntimeError.ancestors.include?(StandardError),
2929
"RuntimeError is a subclass of StandardError"
3030

31-
assert_equal __, ex.message
31+
assert_equal "Oops", ex.message
3232
end
3333

3434
def test_raising_a_particular_error
@@ -40,8 +40,8 @@ def test_raising_a_particular_error
4040
result = :exception_handled
4141
end
4242

43-
assert_equal __, result
44-
assert_equal __, ex.message
43+
assert_equal :exception_handled, result
44+
assert_equal "My Message", ex.message
4545
end
4646

4747
def test_ensure_clause
@@ -54,13 +54,13 @@ def test_ensure_clause
5454
result = :always_run
5555
end
5656

57-
assert_equal __, result
57+
assert_equal :always_run, result
5858
end
5959

6060
# Sometimes, we must know about the unknown
6161
def test_asserting_an_error_is_raised
6262
# A do-end is a block, a topic to explore more later
63-
assert_raise(___) do
63+
assert_raise(MySpecialError) do
6464
raise MySpecialError.new("New instances can be raised directly.")
6565
end
6666
end

koans/about_iteration.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def as_name(name)
2424
# -------------------------------------------------------------------
2525

2626
def test_each_is_a_method_on_arrays
27-
assert_equal __, [].methods.include?(as_name(:each))
27+
assert_equal true, [].methods.include?(as_name(:each))
2828
end
2929

3030
def test_iterating_with_each
@@ -33,14 +33,14 @@ def test_iterating_with_each
3333
array.each do |item|
3434
sum += item
3535
end
36-
assert_equal __, sum
36+
assert_equal 6, sum
3737
end
3838

3939
def test_each_can_use_curly_brace_blocks_too
4040
array = [1, 2, 3]
4141
sum = 0
4242
array.each { |item| sum += item }
43-
assert_equal __, sum
43+
assert_equal 6, sum
4444
end
4545

4646
def test_break_works_with_each_style_iterations
@@ -50,42 +50,42 @@ def test_break_works_with_each_style_iterations
5050
break if item > 3
5151
sum += item
5252
end
53-
assert_equal __, sum
53+
assert_equal 6, sum
5454
end
5555

5656
def test_collect_transforms_elements_of_an_array
5757
array = [1, 2, 3]
5858
new_array = array.collect { |item| item + 10 }
59-
assert_equal __, new_array
59+
assert_equal [11, 12, 13], new_array
6060

6161
# NOTE: 'map' is another name for the 'collect' operation
6262
another_array = array.map { |item| item + 10 }
63-
assert_equal __, another_array
63+
assert_equal [11, 12, 13], another_array
6464
end
6565

6666
def test_select_selects_certain_items_from_an_array
6767
array = [1, 2, 3, 4, 5, 6]
6868

6969
even_numbers = array.select { |item| (item % 2) == 0 }
70-
assert_equal __, even_numbers
70+
assert_equal [2, 4, 6], even_numbers
7171

7272
# NOTE: 'find_all' is another name for the 'select' operation
7373
more_even_numbers = array.find_all { |item| (item % 2) == 0 }
74-
assert_equal __, more_even_numbers
74+
assert_equal [2, 4, 6], more_even_numbers
7575
end
7676

7777
def test_find_locates_the_first_element_matching_a_criteria
7878
array = ["Jim", "Bill", "Clarence", "Doug", "Eli"]
7979

80-
assert_equal __, array.find { |item| item.size > 4 }
80+
assert_equal "Clarence", array.find { |item| item.size > 4 }
8181
end
8282

8383
def test_inject_will_blow_your_mind
8484
result = [2, 3, 4].inject(0) { |sum, item| sum + item }
85-
assert_equal __, result
85+
assert_equal 9, result
8686

8787
result2 = [2, 3, 4].inject(1) { |product, item| product * item }
88-
assert_equal __, result2
88+
assert_equal 24, result2
8989

9090
# Extra Credit:
9191
# Describe in your own words what inject does.
@@ -94,12 +94,12 @@ def test_inject_will_blow_your_mind
9494
def test_all_iteration_methods_work_on_any_collection_not_just_arrays
9595
# Ranges act like a collection
9696
result = (1..3).map { |item| item + 10 }
97-
assert_equal __, result
97+
assert_equal [11, 12, 13], result
9898

9999
# Files act like a collection of lines
100100
File.open("example_file.txt") do |file|
101101
upcase_lines = file.map { |line| line.strip.upcase }
102-
assert_equal __, upcase_lines
102+
assert_equal %w(THIS IS A TEST), upcase_lines
103103
end
104104

105105
# NOTE: You can create your own collections that work with each,

koans/triangle.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,21 @@
1414
# about_triangle_project_2.rb
1515
#
1616
def triangle(a, b, c)
17-
# WRITE THIS CODE
17+
sides = [a, b, c]
18+
if sides.min <= 0
19+
raise TriangleError, "One or more sides is not > 0"
20+
elsif sides.max >= sides.inject(:+).fdiv(2)
21+
raise TriangleError, "One side longer than sum of others"
22+
end
23+
24+
case sides.uniq.count
25+
when 1
26+
:equilateral
27+
when 2
28+
:isosceles
29+
when 3
30+
:scalene
31+
end
1832
end
1933

2034
# Error class used in part 2. No need to change this code.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Learn to Program - Second Edition
2+
# Exercise from Chapter 13 - Creating New Classes, Changing Existing Ones
3+
# Sam Gerber
4+
5+
# Make and OrangeTree class that has a height method that retursn
6+
# its height and a one_year_passes method that, when called, ages the tree one
7+
# year. Each year the tree grows taller (however much you think an orange
8+
# tree should grow in a year), and after some number of years (again, your
9+
# call) the tree shoud die. For the first few years, it should not produce
10+
# fruit, but after a while it should, and I guess that older trees produce
11+
# more each year than younger trees....whatever you think makes the most
12+
# sense. And, of course, you should be able to count_the_oranges (which returns
13+
# the number of oranges on the tree) and pick_an_orange (which reduces the
14+
# @orange_count by 1 and returns a string telling you how delicious the orange
15+
# was, or else it just tells you that there are no more oranges to pick this
16+
# year). Make sure any oranges you don't pick one year fall off before the
17+
# next year.
18+
19+
class OrangeTree
20+
def initialize
21+
@age = 0
22+
@orange_count = 0
23+
@height = 0
24+
end
25+
26+
def one_year_passes
27+
@age += 1
28+
die if @age > 10
29+
@height = 10 * @age
30+
puts "#{@orange_count} oranges fall off the tree." unless @orange_count == 0
31+
puts "winter"
32+
puts "spring"
33+
@orange_count = @age * 5
34+
display
35+
end
36+
37+
def display
38+
puts "The orange tree is now #{@height} tall with #{@orange_count} oranges."
39+
end
40+
41+
def count_the_oranges
42+
@orange_count
43+
end
44+
45+
def pick_an_orange
46+
case @orange_count
47+
when 0
48+
puts "There are no more oranges on the tree this year."
49+
else
50+
@orange_count -= 1
51+
puts "You eat a delicious orange."
52+
end
53+
end
54+
55+
def die
56+
puts "The tree whithers and dies."
57+
exit
58+
end
59+
end
60+
61+
tree = OrangeTree.new
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Learn to Program - Second Edition
2+
# Exercise from Chapter 14 - Blocks and Procs
3+
# Sam Gerber
4+
5+
# After you do your profiling, see the slow parts of your program, and either
6+
# make them faster or learn to love them as they are, you probably
7+
# don't want to see all of that profiling anymore. But (I hope) you're too
8+
# lazy to go back and delete it all...especially because you might want to use
9+
# it again someday. Modify the profile method so you can turn all profiling
10+
# on and off by changing just one line of code. Just one word!
11+
12+
PROFILING = false
13+
14+
def profile block_description, &block
15+
if PROFILING
16+
start_time = Time.new
17+
block.call
18+
duration = Time.new - start_time
19+
puts "#{block_description}: #{duration} seconds"
20+
else
21+
block.call
22+
end
23+
end
24+
25+
26+
profile '25000 doublings ' do
27+
number = 1
28+
29+
25000.times do
30+
number += number
31+
end
32+
33+
puts "#{number.to_s.length} digits"
34+
# That's the number of digits in thie HUGE number.
35+
end
36+
37+
profile 'count to a million' do
38+
number = 0
39+
1_000_000.times do
40+
number += 1
41+
end
42+
end
43+
# => 7526 digits
44+
# => 25000 doublings : 0.042777 seconds
45+
# => count to a million: 0.060863 seconds
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Learn to Program - Second Edition
2+
# Exercise from Chapter 14 - Blocks and Procs
3+
# Sam Gerber
4+
5+
# Write a method that takes a block and calls it once for each hour that has
6+
# passed today. That way, if I were to pass in the block:
7+
# do
8+
# puts "dong!"
9+
# end
10+
# it would chime (sort of) like a grandfather clock. Test your method out with
11+
# a few different blocks.
12+
13+
#HINT: You can use Time.new.hour to get the current hour. However, this returns
14+
# a number between 0 and 23, so you will have to alter those numbers in order
15+
# to get ordinary clock-face numbers (1 to 12)
16+
17+
def grandfather_clock(&block)
18+
(Time.new.hour % 12).times do
19+
block.call
20+
end
21+
end
22+
23+
chime = Proc.new {puts "dong!"}
24+
grandfather_clock(&chime)
25+
26+
hour = 0
27+
grandfather_clock do
28+
hour += 1
29+
end
30+
puts hour
31+
# => dong!
32+
# => dong!
33+
# => dong!
34+
# => dong!
35+
# => dong!
36+
# => 5

0 commit comments

Comments
 (0)