Ruby Koan 151 raising exceptions
Asked Answered
U

39

51

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.
Untouchable answered 30/9, 2010 at 19:39 Comment(4)
Hi Daniel - updated my question to be a little more clearUntouchable
Here's my minimal solution: gist.github.com/1126423Hogan
@ColonelPanic: The geometric definition of a triangle is secondary, and very nearly irrelevant, here; the goal is to write code that passes the test shown at the beginning of the question. You can do that without knowing anything about geometry. (The reason the :equilateral etc are returned, is that this test builds upon a previous test that defined what should be returned.)Informal
Not an answer to the question but your second if condition could be simplified by using elsif without any of the fancy ways in the answers . if a == b && b == c return :equilateral elsif a == b || b == c || a == c return :isosceles else return :scalene endAutomatism
I
58
  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.

Informal answered 30/9, 2010 at 19:53 Comment(9)
Hi cHao, thanks for your comment! I undestand when to raise the exceptions, I just dont understand what goes in the TriangleError classUntouchable
Doesn't the code itself say "No need to change this code"? It should just work.Informal
That was from part 1 of the class, in part 2 (this part) you do change the codeUntouchable
You sure? People don't normally say "you don't need to change this" if they require you to change it.Informal
I'm not 100% sure, I updated the question at the bottom. The koan won't let me proceed until I change something here.Untouchable
The problem is more likely that you're not throwing exceptions for the other 3 cases. Far as i see, the test is checking all 4 cases; even if you throw on the first one, the caller catches it and keeps going with the others. And all 4 cases should throw exceptions.Informal
even when adding exceptions for the other 3 cases, the koan message doesn't change. Its also saying there is an error with the line: " assert_raise(TriangleError) do triangle(0, 0, 0) end"Untouchable
You missed a criteria, "the length of the longest side must exceed the abosolute value of the difference between the lengths of the other two sides"Purington
@wmsmith: They weren't my criteria. I'm just explaining the conditions tested by the koan.Informal
T
34

You forgot the case when a,b, or c are negative:

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
Tigrinya answered 6/7, 2012 at 11:40 Comment(2)
More concise if you sort first then test once with condition x <= 0 || x + y <= z. Also no need to use fetch as [a,b,c].uniq.size will always be in (1..3) owing to the fact that a,b,c are required parameters.Samuelsamuela
Concise. But I'm not sure if this much of brevity makes up for the sacrificed readability (esp. for the people who will be reading this code later).Premises
K
16

Ended up doing this:

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

Thanks to commenters here :)

Kristinkristina answered 21/8, 2012 at 20:45 Comment(0)
A
15
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
Annunciation answered 21/1, 2013 at 19:9 Comment(1)
Such beautiful code!Iodoform
I
9

I like Cory's answer. But I wonder if there's any reason or anything to gain by having four tests, when you could have two:

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)
Interlink answered 2/4, 2011 at 14:45 Comment(3)
Should work fine. The only useful difference is the ability to specify different error messages for, say, zero vs negative lengths. Which i don't really see a need for either. People are just doing 4 checks cause there's explicitly 4 cases that the test is checking for, and they're coding to pass the test.Informal
True, although greater than zero implies positive doesn't it?Interlink
Yep. But there are 4 tests the code has to pass, and some people do a tunnel vision thing where they focus only on the current test, ignoring all the others. I imagine someone will argue it's more correct or something from a TDD perspective, but yeah. There's no reason not to condense it to 2 checks, IMO.Informal
H
9

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
Hasan answered 4/3, 2012 at 13:20 Comment(0)
C
5

I wanted a method that parsed all arguments effectively instead of relying on the order given in the test assertions.

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

Hopefully this helps other realize there is more than one way to skin a cat.

Chalybite answered 1/2, 2012 at 4:45 Comment(2)
Nice functional approach to classification. Could use a case statement instead of if/elsif chain at the end to avoid repeating calls to uniq and count.Himes
'return' isn't necessary at the endLara
F
4

After try to understand what I must to do with koan 151, I got it with the first posts, and get lot fun to check everyone solution :) ... here is the mine:

def triangle(a, b, c)
  array = [a, b, c].sort
  raise TriangleError if array.min <= 0 || array[0]+array[1] <= array[2]
  array.uniq!
  array.length == 1 ? :equilateral: array.length == 2 ? :isosceles : :scalene
end

Koan is a very interesting way to learn Ruby

Fungoid answered 29/5, 2013 at 20:2 Comment(0)
F
3

You definately do not update the TriangleError class - I am stuck on 152 myself. I think I need to use the pythag theorem here.

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
Floating answered 10/10, 2010 at 20:37 Comment(2)
What you've done is fine, but it's not the Pythagorean theorem ;) Pythagorean theorem states c^2 = a^2 + b^2 and is only valid for right-angled triangles.Ebba
If you start by doing a, b, c = [a, b, c].sort you'll find the rest of your code becomes much simpler. ;)Gist
H
3

In fact in the following code the condition a <= 0 is redundant. a + b will always be less than c if a < 0 and we know that b < c

    raise TriangleError if a <= 0 || a + b <= c
Harrisonharrod answered 14/9, 2012 at 5:11 Comment(0)
C
3

I don't think I see this one here, yet.

I believe all the illegal triangle conditions imply that the longest side can't be more than half the total. i.e:

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
Caulescent answered 24/10, 2013 at 20:47 Comment(0)
C
2

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
Casimir answered 29/1, 2012 at 16:7 Comment(0)
S
2

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.

Scurrile answered 30/1, 2012 at 0:38 Comment(0)
Q
2

You could also try to instance the exception with:

raise TriangleError.new("All sides must be greater than 0") if a * b * c <= 0
Quadragesima answered 18/3, 2012 at 20:59 Comment(1)
This doesn't work, two negative sides will pass this test.Antoniettaantonin
A
2

My solution, I think it's one of the more readable ones:

def triangle(a, b, c)
  a, b, c = [a, b, c].sort
  if a <= 0 or c >= a + b
    raise TriangleError
  end
  case [a, b, c].uniq.length
  when 1
    :equilateral
  when 2
    :isosceles
  when 3
    :scalene
  end
end
Antoniettaantonin answered 29/8, 2018 at 13:58 Comment(0)
F
1

Here is what I wrote and it all worked fine.

def triangle(a, b, c)
  # WRITE THIS CODE
  raise TriangleError, "Sides have to be greater than zero" if (a == 0) | (b == 0) | (c == 0)
  raise TriangleError, "Sides have to be a postive number" if (a < 0) | (b < 0) | (c < 0)
  raise TriangleError, "Two sides can never be less than the sum of one side" if ((a + b) < c) | ((a + c) < b) | ((b + c) < a)
  raise TriangleError, "Two sides can never be equal one side" if ((a + b) ==  c) | ((a + c) ==  b) | ((b + c) ==  a)
  return :equilateral if (a == b) & (a == c) & (b == 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
Franni answered 23/2, 2011 at 20:44 Comment(2)
Any reason to do four tests when you can do this: ` 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) `Interlink
Why are you using a single pipe (|)?Animate
S
1

You have to check that the new created triangle don't break the "Triangle inequality". You can ensure this by this little formula.

if !((a-b).abs < c && c < a + b)
  raise TriangleError
end

When you get the Error:

<TriangleError> exception expected but none was thrown.

Your code is probably throwing an exception while creating a regular triangle in this file. about_triangle_project.rb

Scissel answered 12/5, 2011 at 10:20 Comment(1)
You'd need to make sure a, b, and c are in a certain order, lest your test only cover 1/3 of the possible cases.Informal
T
1

For the Koan about_triangle_project_2.rb there's no need to change TriangleError class. Insert this code before your triangle algorithm to pass all tests:

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

if ((a+b<=c) || (b+c<=a) || (a+c<=b))
    raise TriangleError
end
Tanner answered 12/8, 2011 at 0:45 Comment(0)
D
1

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
Derayne answered 6/5, 2012 at 11:34 Comment(0)
M
1

This is what I ended up with. It is sort of a combination of a few of the above examples with my own unique take on the triangle inequality exception (it considers the degenerate case as well). Seems to work.

def triangle(a, b, c)

  raise TriangleError if [a,b,c].min <= 0 
  raise TriangleError if [a,b,c].sort.reverse.reduce(:-) >= 0

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

end
Manhood answered 7/8, 2012 at 23:26 Comment(0)
S
1

Leon wins on fancy elegance, Benji for his knowledge of the Array API. Here's my brute elegant answer:

def triangle(a, b, c)
   [a, b, c].each { | side | raise TriangleError, "Sides must be positive" unless side > 0 }
   raise TriangleError, "Two sides can never be less than or equal to third side" if ((a + b) <= c) | ((a + c) <= b) | ((b + c) <= a)

   return :equilateral if (a == b) && (b == c)
   return :isosceles if (a == b) || (b == c) || (a == c)
   return :scalene
end
Slaton answered 3/1, 2013 at 0:15 Comment(0)
A
1

Here is my elegant answer, with a lot of help from the comments above

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
Arredondo answered 21/5, 2013 at 10:50 Comment(0)
R
1

your previous triangle method should appear here

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
Radley answered 30/6, 2013 at 9:43 Comment(1)
hmm ... if this is an answer, please format the code to make it readableAnodize
U
1
  #(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
Ursine answered 27/7, 2014 at 23:35 Comment(0)
G
1

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
Gulledge answered 28/6, 2016 at 16:17 Comment(0)
L
1
def triangle(a, b, c)

  sides = a, b, c # Assigns variable signs (array) to all arguments.
  begin

  raise TriangleError if sides.inject(:+) <= 0 # Raise an error if all sides added together are less than or equal to 0. (the triangle would be invalid).
  raise TriangleError if sides.any?(&:negative?) #Raise an error if there are any negative sides.
  sides.each {|side| (side < (sides.inject(:+) - side) ? nil : (raise TriangleError))} # For the final check, Raise an error if any single side is greater than the other two sides added together. It can be broken down like this if side is less than (remaining sides - side we're comparing) raise an error, else, nil. 

  return :equilateral if sides.uniq.length == 1
  return :isosceles   if sides.uniq.length == 2
  return :scalene     if sides.uniq.length == 3

  resuce TriangleError
  end
end
Lobachevsky answered 5/3, 2017 at 22:42 Comment(2)
I second @morten.c 's comment. It will also be helpful if you have comments in the code.Carlettacarley
I added comments, let me know if it makes more sense!Lobachevsky
G
0

No Need to change the TriangleError code for either challenge. You just need to check for invalid triangles and raise the error if the triangle isn't.

def triangle(a, b, c)
  if a==0 && b==0 && c==0
    raise TriangleError, "This isn't a triangle"
  end
  if a <0 or b < 0 or c <0
    raise TriangleError, "Negative length - thats not right"
  end
  if a + b <= c  or a + c <= b or  b + c <= a
    raise TriangleError, "One length can't be more (or the same as) than the other two added together.  If it was the same, the whole thing would be a line.  If more, it wouldn't reach. "
  end    
  # WRITE THIS CODE
  if a == b and b == c 
    return :equilateral    
  end      
  if (a==b or b == c or a == c) 
    return :isosceles
  end 
  :scalene      
end
Gobioid answered 4/1, 2013 at 18:38 Comment(0)
V
0

There are some absolutely brilliant people on StackOverflow...I'm reminded of that every time I visit :D Just to contribute to the conversation, here's the solution I came up with:

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

    equal_sides = 0
    equal_sides +=1 if a == b
    equal_sides +=1 if a == c
    equal_sides +=1 if b == c

    # Note that equal_sides will never be 2.  If it hits 2 
    # of the conditions, it will have to hit all 3 by the law
    # of associativity
    return [:scalene, :isosceles, nil, :equilateral][equal_sides] 
end 
Vano answered 12/5, 2013 at 19:54 Comment(0)
J
0

Here's my solution... honestly I can't think of a more concise and readable one!

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
Jerrodjerrol answered 13/12, 2013 at 12:35 Comment(0)
J
0

Rules:

  1. size must be > 0

  2. Total of any 2 sides, must be bigger that the 3rd

Code:

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)
Jugal answered 11/4, 2014 at 19:13 Comment(0)
E
0

No need to write the TriangleError method. It says 'No need to change this code', so I won't change it at all. Stubborn as I am.

4lines shot it, nice nd clean.

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


# Error class used in part 2.  No need to change this code.
class TriangleError < StandardError
end
Enosis answered 25/12, 2014 at 9:30 Comment(0)
M
0
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
Magnetic answered 12/9, 2015 at 19:23 Comment(0)
M
0

Smallest solution I could come up with.

This will pass the tests, however, it will not complain if the array is longer than it should be. Easy to test for but didn't seem entirely needed.

  1. def(sides*) splat (turn the input into an array)
  2. raise TriangleError if ... or ... Raise the error if either are true
  3. sides.sort! sort the list in place. This is important as two statements rely on the list being sorted and this means it is only done once.
  4. sides.sort![0] <=0 get the smallest element, if this is greater than 0 all the others will be.
  5. sides.reverse.reduce(:-) >=0 biggest element minus the smaller two, if this is over 0 then the largest side was bigger than the other two.
  6. sides.uniq.size-1 get the number of unique sides (minus one)
  7. [:e,:i,:s].fetch(sides.uniq.size-1) get the appropriate element from the array (and return).

    def triangle(*sides)
      raise TriangleError if sides.sort![0] <=0 or sides.reverse.reduce(:-) >=0
      [:equilateral, :isosceles, :scalene].fetch(sides.uniq.size - 1)
    end
    
Metatarsal answered 30/10, 2015 at 10:51 Comment(0)
P
0

The error checking is trying to get at the criteria for a triangle:

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 

There are more elegant and concise ways to do this error checking but I think it should make clear how to check for the 4 major criteria are. I actually rolled 2 criteria into a single check. E.g. no sides may be negative and no sides may be 0.

Using a splat operator for the arguments is a nice way to make sure you have an array without explicitly forming one, but I dislike it here because it means you should also add a check to make sure that there are exactly 3 arguments, which is implicit right now.

Purington answered 6/1, 2016 at 1:35 Comment(0)
S
0

This is my solution:-

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

Hope it helps.

Shackleton answered 6/2, 2018 at 20:54 Comment(0)
D
0

You can use this formula and validate all cases:

  • a + b > c
  • a + c > b
  • b + c > a

and you code like:

def triangle(a, b, c)
  # Validate the triangle
 raise TriangleError, "The triangle is not valid" unless (a + b) > c && (a + c) > b && (b + c) > a

 if a === b && b === c
  :equilateral
 elsif a === b || a === c || b === c
  :isosceles
 else
  :scalene
 end
end
Dystrophy answered 23/2, 2018 at 18:53 Comment(0)
W
0

SIMPLEST SOLUTION!

  def triangle(a, b, c)
  #This would check for if the numbers are negative or 0.
  if a <= 0 || b <= 0 || c <= 0 
    raise TriangleError
  end
  #This would check if the two sides of a triangle are greater than the remaining side.
  if a + b <= c  || a + c <= b ||  b + c <= a
    raise TriangleError
  end 

  if a == b && b = c
    :equilateral
  elsif a == b || a == c || b == c 
    :isosceles
  else 
    :scalene
  end
end

Thanks to all the beautiful people for their answer I have checked them all and I would say no need to change the TriangleError code. we need to check for invalid triangles and raise the error if the triangle is not.

Winer answered 18/7, 2021 at 20:47 Comment(0)
T
0

The triangle.rb file need these update to work.

def triangle(a, b, c)
    # If length is Less Then or equal to 0 the triangle not possible
    # it raise error. If the length of any two sum is less or equal to other-
    # Again the triangle not possible.
    raise TriangleError if (a <= 0 || b <= 0 || c <= 0) || (a+b <= c || b+c <= a || c+a <= b)  

    # If the size of each equal its Equilateral Triangle.       
    return :equilateral if (a == b && a == c)

    # If any two lenght is equal than it Isosceles Triangle.
    return :isosceles if (a == b || b == c || a == c)

    # If each lenght is different than its Scalene Triangle.
    return :scalene if (a != b) && (b != c) && (a != c)
end  

class TriangleError < StandardError
end
Thetes answered 16/2, 2022 at 12:20 Comment(0)
G
0

I would like to see a reason for each TriangleError exception, so each failure case has a nice text message for the reason it failed. Also, each line or block of code is handling one workflow only for legibility. The three return cases are very clearly read and understood. I want to make it easy on myself or someone else who looks at this code later.

def triangle(a, b, c)
  
  t = [a, b, c].sort
  
  raise TriangleError, "side cannot be 0" if t.any?(0)

  t.each do |x|
   raise TriangleError, "side cannot be negative" if x < 0
  end
    
  raise TriangleError, "two sides added cannot be less than or equal to one side" if t[0] + t[1] <= t[2]

  return :equilateral if (a == b) && (b == c)
  return :scalene if (a != b) && (a != c) && (b != c)
  return :isosceles
end
Ganoid answered 20/2, 2023 at 19:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.