Ruby Koan 151 maakt uitzonderingen

Ik ga door de ruby ​​koans, ik zit op 151 en ik bots gewoon tegen een bakstenen muur.

Hier is de 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

Dan hebben we in driehoek.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

Ik ben meer dan in de war – alle hulp wordt zeer op prijs gesteld!

EDIT: om deze koan te voltooien, moet ik iets in de TriangleError-klasse zetten – maar ik heb geen idee wat

UPDATE: Dit is wat het koan karma-ding zegt:

<TriangleError> exception expected but none was thrown.

Antwoord 1, autoriteit 100%

  1. Een driehoek mag geen zijden met lengte 0 hebben. Als dat zo is, is het een lijnstuk of een punt, afhankelijk van het aantal zijden 0.
  2. Negatieve lengte heeft geen zin.
  3. Elke twee zijden van een driehoek moeten optellen tot meer dan de derde zijde.
  4. Zie 3 en focus op het “meer”.

Het zou niet nodig moeten zijn om de TriangleError-code, AFAICS, te wijzigen. Het lijkt erop dat je syntaxis een beetje gek is. Probeer te veranderen

raise new.TriangleError

naar

raise TriangleError, "why the exception happened"

Je moet ook de waarden testen (en uitzonderingen maken) voordat je er iets mee doet. Verplaats de uitzonderingsdingen naar het begin van de functie.


Antwoord 2, autoriteit 56%

Je bent het geval vergeten als a,b of c negatief zijn:

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

Antwoord 3, autoriteit 24%

Eindelijk dit gedaan:

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

Met dank aan de reageerders hier 🙂


Antwoord 4, autoriteit 16%

Ik hou van Cory’s antwoord. Maar ik vraag me af of er een reden of iets is om te winnen door vier tests te doen, terwijl je er twee zou kunnen hebben:

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)

Antwoord 5, autoriteit 15%

U hoeft de uitzondering niet te wijzigen. Zoiets zou moeten werken;

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

Antwoord 6, autoriteit 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

Antwoord 7, autoriteit 7%

Ik wilde een methode die alle argumenten effectief ontleedde in plaats van te vertrouwen op de volgorde die in de testbeweringen werd gegeven.

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

Hopelijk helpt dit anderen te beseffen dat er meer dan één manier is om een ​​kat te villen.


Antwoord 8, autoriteit 7%

Nadat ik had geprobeerd te begrijpen wat ik met Koan 151 moest doen, kreeg ik het met de eerste berichten en kreeg ik veel plezier om iedereen de oplossing te controleren 🙂 … hier is de mijn:

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 een zeer interessante manier om Ruby te leren


Antwoord 9, autoriteit 5%

Je werkt de TriangleError-klasse absoluut niet bij – ik zit zelf vast op 152. Ik denk dat ik de stelling van pythag hier moet gebruiken.

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

Antwoord 10, autoriteit 5%

In feite is in de volgende code de voorwaarde a <= 0 overbodig. a + b is altijd kleiner dan c als a < 0 en we weten dat b < c

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

Antwoord 11, autoriteit 5%

Ik denk dat ik deze hier nog niet zie.

Ik geloof dat alle illegale driehoeksvoorwaarden impliceren dat de langste zijde niet meer dan de helft van het totaal kan zijn. dat wil zeggen:

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

Antwoord 12, autoriteit 4%

Deze kostte wel wat hersentijd. Maar hier is mijn oplossing

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

Antwoord 13, autoriteit 4%

Ik kreeg deze 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 

Ik hou niet van de tweede conditie / raise, maar ik weet niet zeker hoe ik het verder kan verbeteren.


Antwoord 14, autoriteit 2%

 #(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

Antwoord 15, autoriteit 2%

Niet dat deze vraag een ander antwoord nodig had; ik denk echter dat dit de eenvoudigste en meest leesbare oplossing is. Dank aan allen die voor mij waren.

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

Antwoord 16, autoriteit 2%

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

Antwoord 17, autoriteit 2%

je vorige driehoeksmethode zou hier moeten verschijnen

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

Antwoord 18, autoriteit 2%

Mijn oplossing, ik denk dat het een van de beter leesbare is:

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

Antwoord 19, autoriteit 2%

Leon wint op chique elegantie, Benji vanwege zijn kennis van de Array API. Hier is mijn brute elegante antwoord:

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

Antwoord 20

Het is niet nodig om de TriangleError-code voor beide uitdagingen te wijzigen. U hoeft alleen te controleren op ongeldige driehoeken en de fout te verhogen als de driehoek dat niet is.

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

Antwoord 21

Er zijn een aantal absoluut briljante mensen op StackOverflow… daar word ik elke keer aan herinnerd als ik bezoek 😀
Gewoon om bij te dragen aan het gesprek, hier is de oplossing die ik bedacht:

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 

Antwoord 22

Hier is mijn oplossing… eerlijk gezegd kan ik geen kortere en leesbarere oplossing bedenken!

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

Antwoord 23

Regels:

  1. grootte moet > zijn 0

  2. Totaal van 2 zijden, moet groter zijn dan de derde

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)

Other episodes