Решение на Шеста задача от Станимир Богданов

Обратно към всички решения

Към профила на Станимир Богданов

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 8 успешни тест(а)
  • 6 неуспешни тест(а)

Код

module TurtleGraphics
DIRECTIONS = {
right: [1, 0],
down: [0, 1],
left: [-1, 0],
up: [0, -1]
}.freeze
class Turtle
def initialize(width, height)
@width = width
@height = height
@canvas = Array.new(height) { Array.new(width) { 0 } }
spawn_at(0, 0)
@orientation = :right
end
def draw(canvas = nil, &block)
instance_eval(&block) if block_given?
@canvas = canvas.convert(@canvas) if canvas
@canvas
end
def move
@x = (@x + DIRECTIONS[@orientation].first) % @width
@y = (@y + DIRECTIONS[@orientation].last) % @height
@canvas[@y][@x] += 1
end
def turn_left
index_of_left_direction = (DIRECTIONS.keys.index(@orientation) - 1) % 4
@orientation = DIRECTIONS.keys[index_of_left_direction]
end
def turn_right
index_of_right_direction = (DIRECTIONS.keys.index(@orientation) + 1) % 4
@orientation = DIRECTIONS.keys[index_of_right_direction]
end
def spawn_at(row, column)
@x = column
@y = row
@canvas[@y][@x] += 1
end
def look(orientation)
@orientation = orientation
end
end
module Canvas
class ASCII
def initialize(characters)
@characters = characters
end
def convert(canvas)
max_steps_on_cell = canvas.map { |row| row.max }.max.to_f
canvas.map do |row|
row.map do |col|
intensity = (col.to_f / max_steps_on_cell)
char_index = (intensity / (1.0 / (@characters.size - 1))).floor
@characters[char_index]
end
end
end
end
class HTML
def initialize(physical_pixel_size)
@physical_pixel_size = physical_pixel_size
end
def convert(canvas)
html = %{<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@physical_pixel_size}px;
height: #{@physical_pixel_size}px;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
}
max_steps = canvas.map { |row| row.max }.max.to_f
canvas.each do |row|
html += "<tr>\n"
row.each do |col|
html += "<td style=\"opacity: #{(col.to_f / max_steps).round(2)}\"></td>"
end
html += "</tr>\n"
end
html += %{
</table>
</body>
</html>
}
end
end
end
end

Лог от изпълнението

F......F.FFF.F

Failures:

  1) TurtleGraphics renders a complex shape
     Failure/Error: expect(canvas).to eq [
       
       expected: [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
            got: [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
       
       (compared using ==)
     # /tmp/d20151203-5272-de1k34/spec.rb:284:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) TurtleGraphics Turtle #draw #spawn_at moves the turtle to an exact location in the start
     Failure/Error: expect(canvas).to eq [[0, 0], [1, 0]]
       
       expected: [[0, 0], [1, 0]]
            got: [[1, 0], [1, 0]]
       
       (compared using ==)
     # /tmp/d20151203-5272-de1k34/spec.rb:93:in `block (5 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) TurtleGraphics Canvas::ASCII renders the proper symbols depending on the intensity
     Failure/Error: expect(ascii.sub(/\n\z/, '')).to eq [
     NoMethodError:
       undefined method `sub' for [["3", "2", "0"], ["1", "1", "0"], ["0", "0", "0"]]:Array
     # /tmp/d20151203-5272-de1k34/spec.rb:128:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) TurtleGraphics Canvas::ASCII can render with a different number of symbols
     Failure/Error: expect(ascii.sub(/\n\z/, '')).to eq [
     NoMethodError:
       undefined method `sub' for [["t", "o", "z"], ["z", "z", "z"], ["z", "z", "z"]]:Array
     # /tmp/d20151203-5272-de1k34/spec.rb:151:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) TurtleGraphics Canvas::HTML renders the proper template
     Failure/Error: expect(canvas.gsub(/\s+/, '')).to eq <<-HTML.gsub(/\s+/, '')
       
       expected: "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:1.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr></table></body></html>"
            got: "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle=\"opacity:1.0\"></td><tdstyle=\"opacity:1.0\"></td><tdstyle=\"opacity:1.0\"></td></tr><tr><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td></tr><tr><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td></tr></table></body></html>"
       
       (compared using ==)
     # /tmp/d20151203-5272-de1k34/spec.rb:171:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) TurtleGraphics Canvas::HTML changes the opacity of a cell based on the times we have passed
     Failure/Error: expect(canvas.gsub(/\s+/, '')).to include <<-HTML.gsub(/\s+/, '')
       expected "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle=\"opacity:1.0\"></td><tdstyle=\"opacity:0.67\"></td><tdstyle=\"opacity:0.0\"></td></tr><tr><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.0\"></td></tr><tr><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td><tdstyle=\"opacity:0.0\"></td></tr></table></body></html>" to include "<table><tr><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:0.67\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr></table>"
     # /tmp/d20151203-5272-de1k34/spec.rb:242:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01339 seconds
14 examples, 6 failures

Failed examples:

rspec /tmp/d20151203-5272-de1k34/spec.rb:264 # TurtleGraphics renders a complex shape
rspec /tmp/d20151203-5272-de1k34/spec.rb:91 # TurtleGraphics Turtle #draw #spawn_at moves the turtle to an exact location in the start
rspec /tmp/d20151203-5272-de1k34/spec.rb:112 # TurtleGraphics Canvas::ASCII renders the proper symbols depending on the intensity
rspec /tmp/d20151203-5272-de1k34/spec.rb:135 # TurtleGraphics Canvas::ASCII can render with a different number of symbols
rspec /tmp/d20151203-5272-de1k34/spec.rb:165 # TurtleGraphics Canvas::HTML renders the proper template
rspec /tmp/d20151203-5272-de1k34/spec.rb:227 # TurtleGraphics Canvas::HTML changes the opacity of a cell based on the times we have passed

История (1 версия и 1 коментар)

Станимир обнови решението на 29.11.2015 10:49 (преди над 8 години)

+module TurtleGraphics
+ DIRECTIONS = {
+ right: [1, 0],
+ down: [0, 1],
+ left: [-1, 0],
+ up: [0, -1]
+ }.freeze
+
+ class Turtle
+ def initialize(width, height)
+ @width = width
+ @height = height
+ @canvas = Array.new(height) { Array.new(width) { 0 } }
+
+ spawn_at(0, 0)
+ @orientation = :right
+ end
+
+ def draw(canvas = nil, &block)
+ instance_eval(&block) if block_given?
+ @canvas = canvas.convert(@canvas) if canvas
+ @canvas
+ end
+
+ def move
+ @x = (@x + DIRECTIONS[@orientation].first) % @width
+ @y = (@y + DIRECTIONS[@orientation].last) % @height
+ @canvas[@y][@x] += 1
+ end
+
+ def turn_left
+ index_of_left_direction = (DIRECTIONS.keys.index(@orientation) - 1) % 4
+ @orientation = DIRECTIONS.keys[index_of_left_direction]
+ end
+
+ def turn_right
+ index_of_right_direction = (DIRECTIONS.keys.index(@orientation) + 1) % 4
+ @orientation = DIRECTIONS.keys[index_of_right_direction]
+ end
+
+ def spawn_at(row, column)
+ @x = column
+ @y = row
+ @canvas[@y][@x] += 1
+ end
+
+ def look(orientation)
+ @orientation = orientation
+ end
+ end
+
+ module Canvas
+ class ASCII
+ def initialize(characters)
+ @characters = characters
+ end
+
+ def convert(canvas)
+ max_steps_on_cell = canvas.map { |row| row.max }.max.to_f
+ canvas.map do |row|
+ row.map do |col|
+ intensity = (col.to_f / max_steps_on_cell)
+ char_index = (intensity / (1.0 / (@characters.size - 1))).floor
+ @characters[char_index]
+ end
+ end
+ end
+ end
+
+ class HTML
+ def initialize(physical_pixel_size)
+ @physical_pixel_size = physical_pixel_size
+ end
+
+ def convert(canvas)
+ html = %{<!DOCTYPE html>
+<html>
+<head>
+ <title>Turtle graphics</title>
+
+ <style>
+ table {
+ border-spacing: 0;
+ }
+
+ tr {
+ padding: 0;
+ }
+
+ td {
+ width: #{@physical_pixel_size}px;
+ height: #{@physical_pixel_size}px;
+
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+</head>
+<body>
+ <table>
+}
+ max_steps = canvas.map { |row| row.max }.max.to_f
+ canvas.each do |row|
+ html += "<tr>\n"
+ row.each do |col|
+ html += "<td style=\"opacity: #{(col.to_f / max_steps).round(2)}\"></td>"
+ end
+ html += "</tr>\n"
+ end
+ html += %{
+ </table>
+</body>
+</html>
+}
+ end
+ end
+ end
+end

Изглежда добре, но имаш някои грешки. Провери си пак условието и си направи няколко теста.

Стилови коментари:

  • Конкатенирането на низове, особено in-place не е добра практика в Ruby. Опитай да го направиш без += на низове.
  • Метода convert в по-голямата си част съдържа низ с html. Изкарай този текст като константа и само замени динамичните части после. Също, по-подходящ начин за записване на низа би бил heredoc. С него няма опасност да затвориш %{ преждевременно с някоя друга }.
  • Харесва ми, че си freeze-нал DIRECTIONS. В такъв случай би било хубаво да freeze-неш и стойностите му, защото в момента те могат да се променят.