Ruby Koan 151 поднимает исключения - PullRequest
45 голосов
/ 30 сентября 2010

Я прохожу рубиновые коаны, я на 151, и я просто ударился о кирпичную стену.

Вот этот коан:

# 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

Затем в triangle.rbу нас есть:

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

Я не в замешательстве - любая помощь будет высоко ценится!

РЕДАКТИРОВАТЬ: Чтобы завершить этот коан, мне нужно поместить что-то в класс TriangleError - ноЯ понятия не имею, что

ОБНОВЛЕНИЕ: Вот что говорит вещь о кар-каре:

<TriangleError> exception expected but none was thrown.

Ответы [ 36 ]

50 голосов
/ 30 сентября 2010
  1. У треугольника не должно быть сторон длины 0. Если это так, то это либо отрезок, либо точка, в зависимости от того, сколько сторон равно 0.
  2. Отрицательная длина не даетСмысл.
  3. Любые две стороны треугольника должны составлять в целом больше, чем третья сторона.
  4. См. 3 и сосредоточиться на «больше».Вам не нужно менять код TriangleError, AFAICS.Похоже, ваш синтаксис немного странный.Попробуйте изменить
    raise new.TriangleError
    

    на

    raise TriangleError, "why the exception happened"
    

    Кроме того, вы должны проверить значения (и выбросить исключения), прежде чем что-либо делать с ними.Переместите материал исключения в начало функции.

30 голосов
/ 06 июля 2012

Вы забыли случай, когда a, b или c отрицательны:

def triangle(a, b, c)
  raise TriangleError if [a,b,c].min <= 0
  x, y, z = [a,b,c].sort
  raise TriangleError if x + y <= z
  [:equilateral,:isosceles,:scalene].fetch([a,b,c].uniq.size - 1)
end
13 голосов
/ 22 августа 2012

Закончилось так:

def triangle(a, b, c)
  a, b, c = [a, b, c].sort
  raise TriangleError if a <= 0 || a + b <= c
  [nil, :equilateral, :isosceles, :scalene][[a, b, c].uniq.size]
end

Спасибо комментаторам здесь:)

9 голосов
/ 02 апреля 2011

Мне нравится ответ Кори. Но мне интересно, есть ли какая-то причина или что-нибудь выиграть, если у вас будет четыре теста, а у вас может быть два:

raise TriangleError, "Sides must by numbers greater than zero" if (a <= 0) || (b <= 0) || (c <= 0)
raise TriangleError, "No two sides can add to be less than or equal to the other side" if (a+b <= c) || (a+c <= b) || (b+c <= a)
7 голосов
/ 04 марта 2012

Вам не нужно изменять исключение.Нечто подобное должно работать;

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
6 голосов
/ 21 января 2013
def triangle(a, b, c)
  [a, b, c].permutation do |sides|
    raise TriangleError unless sides[0] + sides[1] > sides[2]
  end
  case [a,b,c].uniq.size
    when 3; :scalene
    when 2; :isosceles
    when 1; :equilateral
  end
end
4 голосов
/ 30 мая 2013

После попытки понять, что я должен делать с коаном 151, я получил это с первыми постами, и получаю много удовольствия, чтобы проверить каждое решение :) ... вот мое:* Koan - очень интересный способ изучения Ruby

3 голосов
/ 25 октября 2013

Я не думаю, что пока вижу это здесь.

Я полагаю, что все условия нелегального треугольника подразумевают, что самая длинная сторона не может быть больше половины от общей. то есть:

def triangle(a, b, c)

  fail TriangleError, "Illegal triangle: [#{a}, #{b}, #{c}]" if
    [a, b, c].max >= (a + b + c) / 2.0

  return :equilateral if a == b and b == c
  return :isosceles if a == b or b == c or a == c
  return :scalene

end
3 голосов
/ 01 февраля 2012

Я хотел метод, который бы эффективно анализировал все аргументы, а не полагался на порядок, указанный в проверочных утверждениях.

def triangle(a, b, c)
  # WRITE THIS CODE
  [a,b,c].permutation { |p| 
     if p[0] + p[1] <= p[2]
       raise TriangleError, "Two sides of a triangle must be greater than the remaining side."
     elsif p.count { |x| x <= 0} > 0
       raise TriangleError, "A triangle cannot have sides of zero or less length."
     end
  }

  if [a,b,c].uniq.count == 1
    return :equilateral
  elsif [a,b,c].uniq.count == 2
    return :isosceles
  elsif [a,b,c].uniq.count == 3
    return :scalene
  end
end

Надеюсь, это поможет другим понять, что существует более одного способа кожи кошки.

3 голосов
/ 11 октября 2010

Вы определенно не обновляете класс TriangleError - я сам застрял на 152.Я думаю, что мне нужно использовать теорему Пифаг здесь.

def triangle(a, b, c)
  # WRITE THIS CODE

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

  # The sum of two sides should be less than the other side
  if((a+b < c) || (a+c < b) || (b+c < a))
    raise TriangleError
  end
  if a==b && b==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


end

# Error class used in part 2.  No need to change this code.
class TriangleError < StandardError
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...