Ruby Koan 151 raising exceptions

2019-03-08 23:44发布

I'm going through the ruby koans, I'm on 151 and I just hit a brick wall.

Here is the koan:

# You need to write the triangle method in the file 'triangle.rb'
require 'triangle.rb'

class AboutTriangleProject2 < EdgeCase::Koan
  # The first assignment did not talk about how to handle errors.
  # Let's handle that part now.
  def test_illegal_triangles_throw_exceptions
    assert_raise(TriangleError) do triangle(0, 0, 0) end
    assert_raise(TriangleError) do triangle(3, 4, -5) end
    assert_raise(TriangleError) do triangle(1, 1, 3) end
    assert_raise(TriangleError) do triangle(2, 4, 2) end
 end
end

Then in triangle.rb we have:

def triangle(a, b, c)
  # WRITE THIS CODE
  if a==b && a==c
    return :equilateral
  end
  if (a==b && a!=c) || (a==c && a!=b) || (b==c && b!=a)
    return :isosceles
  end
  if a!=b && a!=c && b!=c
    return :scalene
  end
  if a==0 && b==0 && c==0
    raise new.TriangleError
  end



end

# Error class used in part 2.  No need to change this code.
class TriangleError < StandardError

end

I am beyond confused - any help at all would be much appreciated!

EDIT: To complete this koan, I need to put something in the TriangleError class - but I have no idea what

UPDATE: Here is what the koan karma thing is saying:

<TriangleError> exception expected but none was thrown.

标签: ruby geometry
30条回答
劫难
2楼-- · 2019-03-09 00:21

I ended up with this code:

def triangle(a, b, c)
    raise TriangleError, "impossible triangle" if [a,b,c].min <= 0
    x, y, z = [a,b,c].sort
    raise TriangleError, "no two sides can be < than the third" if x + y <= z

    if a == b && b == c # && a == c # XXX: last check implied by previous 2
        :equilateral
    elsif a == b || b == c || c == a
        :isosceles
    else
        :scalene
    end
end 

I don't like the second condition/raise, but I'm unsure how to improve it further.

查看更多
放荡不羁爱自由
3楼-- · 2019-03-09 00:21

Here is my version... :-)

def triangle(a, b, c)

  if a <= 0 ||  b <= 0 || c <= 0
    raise TriangleError
  end 

  if a + b <= c  || a + c <= b ||  b + c <= a
    raise TriangleError
  end 

  return :equilateral if a == b && b == c
  return :isosceles   if a == b || a == c ||  b == c
  return :scalene     if a != b && a != c &&  b != c 

end
查看更多
Ridiculous、
4楼-- · 2019-03-09 00:21

Not that this question needed another answer; however, I think this is the simplest and most readable solution. Thanks to all those before me.

def triangle(a, b, c)
  a, b, c = [a, b, c].sort
  raise TriangleError, "all sides must > 0" unless [a, b, c].min > 0
  raise TriangleError, "2 smaller sides together must the > 3rd side" unless a + b > c
  return :equilateral if a == b && a == c
  return :isosceles if a == b || a == c || b == c
  return :scalene
end

# Error class used in part 2.  No need to change this code.
class TriangleError < StandardError
end
查看更多
Fickle 薄情
5楼-- · 2019-03-09 00:23
  1. A triangle should not have any sides of length 0. If it does, it's either a line segment or a point, depending on how many sides are 0.
  2. Negative length doesn't make sense.
  3. Any two sides of a triangle should add up to more than the third side.
  4. See 3, and focus on the "more".

You shouldn't need to change the TriangleError code, AFAICS. Looks like your syntax is just a little wacky. Try changing

raise new.TriangleError

to

raise TriangleError, "why the exception happened"

Also, you should be testing the values (and throwing exceptions) before you do anything with them. Move the exception stuff to the beginning of the function.

查看更多
仙女界的扛把子
6楼-- · 2019-03-09 00:25

You don't need to modify the Exception. Something like this should work;

def triangle(*args)
  args.sort!
  raise TriangleError if args[0] + args[1] <= args[2] || args[0] <= 0
  [nil, :equilateral, :isosceles, :scalene][args.uniq.length]
end
查看更多
唯我独甜
7楼-- · 2019-03-09 00:26

This one did take some brain time. But here's my solution

def triangle(a, b, c)
  # WRITE THIS CODE
  raise TriangleError, "All sides must be positive number" if a <= 0 || b <= 0 || c <= 0
  raise TriangleError, "Impossible triangle" if ( a + b + c - ( 2 *  [a,b,c].max ) <= 0  )

  if(a == b && a == c)
      :equilateral
  elsif (a == b || b == c || a == c)
      :isosceles
  else
    :scalene
  end
end
查看更多
登录 后发表回答