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 ]

1 голос
/ 28 июля 2014
  #(1)Any zero or -ve values
  if [a,b,c].any? { |side_length| side_length <= 0 }
    raise TriangleError
  end

  #(2)Any side of a triangle must be less than the sum of the other two sides
  # a <  b+c, b <  a+c  and c <  a+b  a  valid   triangle
  # a >= b+c, b >= a+c  and c >= a+b  an invalid triangle

  total_of_side_lengths = [a,b,c].inject {|total,x| total += x}

  if [a,b,c].any? { |side_length| side_length >= (total_of_side_lengths - side_length)}
    raise TriangleError
  end
1 голос
/ 28 июня 2016

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

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
1 голос
/ 21 мая 2013

Вот мой элегантный ответ, с большой помощью из комментариев выше

def triangle(a, b, c)

   test_tri = [a,b,c]

   if test_tri.min <=0
     raise TriangleError
   end

   test_tri.sort!

   if test_tri[0]+ test_tri[1] <= test_tri[2]
     raise TriangleError
   end

   if a == b and b == c
     :equilateral
   elsif a != b and b != c and a != c 
     :scalene   
   else
     :isosceles     
   end
end
1 голос
/ 30 июня 2013

Ваш предыдущий метод треугольника должен появиться здесь

class TriangleError < StandardError
end

def triangle(x,y,z)
  if(x>=y+z||y>=x+z||z>=x+y)
    raise TriangleError,"impossible triangle"
  elsif(x==0&&y==0&&z==0)||(x<0||y<0||z<0)
    raise TriangleError,"length cannot be zero or negative"
  elsif(x==y&&x==z)
    :equilateral
  elsif(x==y||y==z||x==z)
    :isosceles
  else
    :scalene
  end
end
0 голосов
/ 06 февраля 2018

Это мое решение: -

def triangle(a, b, c)
  if a <= 0 || b <= 0 || c <= 0 || a + b <= c  || a + c <= b ||  b + c <= a
    raise TriangleError
  elsif (a == b) &&( a==c) && (b==c)
    return :equilateral
  elsif (a==b) || (b==c) || (a==c)
    return :isosceles
  else
    return :scalene
  end
end

Надеюсь, это поможет.

0 голосов
/ 06 января 2016

При проверке ошибок пытается получить критерии для треугольника:

if (a <= 0 || b <= 0 || c <= 0)
    raise TriangleError,"All lengths must be positive"
end 

args=[a,b,c].sort #this lets us get at the longest side of the triangle

unless ( args[0]+args[1] > args[2] )
    raise TriangleError,"Longest length may not be greater than the sum of the other lengths"
end 

if (args[0]-args[1] > args[2])
    raise TriangleError,"Longest length must be greater than the difference of the other two lengths"
end 

Существуют более элегантные и лаконичные способы проверки ошибок, но я думаю, что должно быть ясно, как проверять 4 основных критерия. Я фактически свернул 2 критерия в одну проверку. Например. никакие стороны не могут быть отрицательными и никакие стороны не могут быть 0.

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

0 голосов
/ 30 октября 2015

Наименьшее решение, которое я мог придумать.

Это пройдет тесты, однако не будет жаловаться, если массив длиннее, чем должен быть. Легко проверить, но, похоже, не совсем нужно.

  1. def(sides*) splat (превратить вход в массив)
  2. raise TriangleError if ... or ... Поднимите ошибку, если любое из них истинно
  3. sides.sort! отсортировать список на месте. Это важно, поскольку два оператора полагаются на сортируемый список, и это означает, что это делается только один раз.
  4. sides.sort![0] <=0 получить наименьший элемент, если он больше 0, все остальные будут.
  5. sides.reverse.reduce(:-) >=0 самый большой элемент минус два меньших, если это больше 0, то самая большая сторона была больше двух других.
  6. sides.uniq.size-1 получить количество уникальных сторон (минус одна)
  7. [:e,:i,:s].fetch(sides.uniq.size-1) получить соответствующий элемент из массива (и вернуть).

    def triangle(*sides)
      raise TriangleError if sides.sort![0] <=0 or sides.reverse.reduce(:-) >=0
      [:equilateral, :isosceles, :scalene].fetch(sides.uniq.size - 1)
    end
    
0 голосов
/ 12 сентября 2015
def triangle(a, b, c)
  raise TriangleError if [a, b, c].min <= 0
  raise TriangleError if [a, b, c].max * 2 >= [a, b, c].reduce(:+)
  if a == b && b == c
    :equilateral
  elsif a == b || b == c || c == a
    :isosceles
  else
    :scalene
  end
end
0 голосов
/ 11 апреля 2014

Правила:

  1. размер должен быть> 0

  2. Общее количество любых 2 сторон должно быть больше 3-го

Код:

raise TriangleError if ( [a,b,c].any? {|x| (x <= 0)} ) or ( ((a+b)<=c) or ((b+c)<=a) or ((a+c)<=b))
[:equilateral, :isosceles, :scalene].fetch([a,b,c].uniq.size - 1)
0 голосов
/ 13 декабря 2013

Вот мое решение ... честно говоря, я не могу придумать более краткого и удобочитаемого!

def triangle(a, b, c)
  raise TriangleError unless a > 0 && b > 0 && c > 0
  raise TriangleError if a == b && a + b <= c
  raise TriangleError if a == c && a + c <= b
  return :equilateral if a == b && b == c
  return :isosceles   if a == b || b == c || c == a
  :scalene
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...