Решение на Четвърта задача от Евгений Бояджиев

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

Към профила на Евгений Бояджиев

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 7 успешни тест(а)
  • 4 неуспешни тест(а)

Код

module UI
module UIMethods
def label(text:, border:nil, style:nil)
label = Label.new(text)
style = @style if style == nil
label.style(style)
label.border(border)
@result.add(label)
end
def horizontal(border:nil, style:nil, &block)
style = @style if style == nil
group = HorizontalGroup.new(border: border, style: style, &block)
@result.add(group)
end
def vertical(border:nil, style:nil, &block)
style = @style if style == nil
group = VerticalGroup.new(border: border, style: style, &block)
@result.add(group)
end
end
class TextAccumulator
def initialize
@contents = []
end
def add(element)
@contents.push(element)
end
def sizes
@contents.dup.map(&:to_s).map(&:size)
end
def to_s(separator:"", outer_border:nil, inner_border:nil, width:0)
outer_border = "" if outer_border == nil
inner_border = "" if inner_border == nil
text_array = @contents.dup.map(&:to_s).map{|text| text.ljust(width)}
text_array = text_array.map{ |text| inner_border + text + inner_border}
outer_border + text_array.join(separator) + outer_border
end
end
class TextScreen
extend UIMethods
class << self
def draw(&block)
@result = TextAccumulator.new
class_eval &block
@result.add(Label.new("\n"))
@result
end
end
end
class Label
attr_reader :text
def initialize(text)
@text = text
end
def border (border, width:0)
return if border == nil
@text = @text.ljust(width)
@text = border + @text + border
end
def style (style)
return if style == nil
case style
when :upcase then @text = @text.upcase
when :downcase then @text = @text.downcase
end
end
def to_s
@text
end
end
class HorizontalGroup
include UIMethods
def initialize(border:nil, style:nil, &block)
@border = border
@style = style
@result = TextAccumulator.new
instance_eval &block
end
def to_s
@result.to_s(outer_border: @border)
end
end
class VerticalGroup
include UIMethods
def initialize(border:nil, style:nil, &block)
@border = border
@style = style
@result = TextAccumulator.new
instance_eval &block
end
def to_s
width = @result.sizes.max
@result.to_s(separator:"\n", width:width, inner_border: @border)
end
end
end

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

...F.F.F.F.

Failures:

  1) Command Line Toolkit handles complex group nestings
     Failure/Error: expect do
       expected #<Proc:0xb8b253c8@/tmp/d20141126-26053-kqfc6/spec.rb:56> to render as "      123\n        45\n         6\n      7\n"
     # /tmp/d20141126-26053-kqfc6/spec.rb:56: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) Command Line Toolkit handles borders correctly in complex group nestings
     Failure/Error: expect do
       expected #<Proc:0xb8b05c58@/tmp/d20141126-26053-kqfc6/spec.rb:99> to render as "      |||1||2|||3|       |||\n      ||      |||4|||5||||||\n      ||      ||   ||6||||||\n      ||7|                 |\n"
     # /tmp/d20141126-26053-kqfc6/spec.rb:99: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)>'

  3) Command Line Toolkit propagates upcase to child components
     Failure/Error: expect do
       expected #<Proc:0xb8ae60ec@/tmp/d20141126-26053-kqfc6/spec.rb:137> to render as "      someveryINTERESTINGget it?\n              TEXTGOES       \n                  HERE       \n"
     # /tmp/d20141126-26053-kqfc6/spec.rb:137: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)>'

  4) Command Line Toolkit propagates downcase to child components
     Failure/Error: expect do
       expected #<Proc:0xb8acc4e4@/tmp/d20141126-26053-kqfc6/spec.rb:172> to render as "      SOMEVERYinterestingGET IT?\n              textgoes       \n                  here       \n"
     # /tmp/d20141126-26053-kqfc6/spec.rb:172: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)>'

Finished in 0.02387 seconds
11 examples, 4 failures

Failed examples:

rspec /tmp/d20141126-26053-kqfc6/spec.rb:55 # Command Line Toolkit handles complex group nestings
rspec /tmp/d20141126-26053-kqfc6/spec.rb:98 # Command Line Toolkit handles borders correctly in complex group nestings
rspec /tmp/d20141126-26053-kqfc6/spec.rb:136 # Command Line Toolkit propagates upcase to child components
rspec /tmp/d20141126-26053-kqfc6/spec.rb:171 # Command Line Toolkit propagates downcase to child components

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

Евгений обнови решението на 25.11.2014 08:22 (преди почти 10 години)

+module UI
+ class TextScreen
+
+ class << self
+ :text
+
+ def draw &block
+ @text = ''
+ class_eval &block
+ @text
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style style
+ label.border border
+ @text += label.text
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ @text += group.text
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ @text += group.text
+ end
+ end
+ end
+
+ class Label
+ attr_reader :text
+
+ def initialize text
+ @text = text
+ end
+
+ def add text
+ @text += text
+ end
+
+ def border border
+ return if border == nil
+ @text = border + @text + border
+ end
+
+ def style style
+ return if style == nil
+
+ case style
+ when :upcase then @text = @text.upcase
+ when :downcase then @text = @text.downcase
+ end
+ end
+ end
+
+ class VerticalGroup
+ :block
+ :border
+ :style
+
+ :lines
+
+ def initialize (border: nil, style: nil, &block)
+ @block = block
+ @border = border
+ @style = style
+
+ @lines = []
+ instance_eval &block
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style (style != nil ? style : @style)
+ label.border border
+ @lines << label
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ label = Label.new group.text
+ @lines << label
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ label = Label.new group.text
+ @lines << label
+ end
+
+ def text
+ TextUtilities::add_border(@lines, @border)
+
+ result = ''
+ @lines.each {|label| result += label.text + "\n"}
+ result
+ end
+ end
+
+ class HorizontalGroup
+ :block
+ :border
+ :style
+
+ :text_container
+
+ def initialize (border: nil, style: nil, &block)
+ @block = block
+ @border = border
+ @style = style
+
+ @text_container = Label.new ""
+ instance_eval &block
+ end
+
+ def label (text:, border: nil, style: nil)
+ label = Label.new text
+ label.style (style != nil ? style : @style)
+ label.border border
+ @text_container.add (label.text)
+ end
+
+ def vertical (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = VerticalGroup.new(border: border, style: style, &block)
+ @text_container.add (group.text)
+ end
+
+ def horizontal (border: nil, style: nil, &block)
+ border = (border != nil ? border : @border)
+ style = (style != nil ? style : @style)
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ @text_container.add (group.text)
+ end
+
+ def text
+ if @border != nil
+ @border + @text_container.text + @border
+ else
+ @text_container.text
+ end
+ end
+ end
+
+ class TextUtilities
+ class << self
+ def add_border (labels, border)
+ return if border == nil
+
+ longest_line_size = biggest_line_size labels
+ labels.each do |label|
+ add_spaces label, (longest_line_size - label.text.size)
+ label.border border
+ end
+ end
+
+ def biggest_line_size labels
+ labels.max_by{|label| label.text.size}.text.size
+ end
+
+ def add_spaces (label, spaces_count)
+ label.add (" " * spaces_count)
+ end
+ end
+ end
+end

Прегледай примерите, които дискутираме тук.

Защо имаш символи в класовете? Какво постигаш с

class VerticalGroup
  :block
  ...

Не ми харесва това, че имаш код за horizontal, vertical и label на три места. Помисли как можеш да го рефакторираш, така че тези неща да са обособени на едно място.

Кодът ти не е форматиран правилно. Погледни style guide-а за това как се дефинира метод с аргументи. Също така на места ползваш 4 интервала, а не 2.

Евгений обнови решението на 26.11.2014 01:11 (преди почти 10 години)

module UI
- class TextScreen
+ module UIMethods
+ def label(text:, border:nil, style:nil)
+ label = Label.new(text)
- class << self
- :text
+ style = @style if style == nil
+ label.style(style)
- def draw &block
- @text = ''
- class_eval &block
- @text
- end
+ label.border(border)
- def label (text:, border: nil, style: nil)
- label = Label.new text
- label.style style
- label.border border
- @text += label.text
- end
+ @result.add(label)
+ end
- def vertical (border: nil, style: nil, &block)
- group = VerticalGroup.new(border: border, style: style, &block)
- @text += group.text
- end
+ def horizontal(border:nil, style:nil, &block)
+ style = @style if style == nil
+ group = HorizontalGroup.new(border: border, style: style, &block)
+ @result.add(group)
+ end
- def horizontal (border: nil, style: nil, &block)
- group = HorizontalGroup.new(border: border, style: style, &block)
- @text += group.text
- end
+ def vertical(border:nil, style:nil, &block)
+ style = @style if style == nil
+ group = VerticalGroup.new(border: border, style: style, &block)
+ @result.add(group)
end
end
- class Label
- attr_reader :text
-
- def initialize text
- @text = text
+ class TextAccumulator
+ def initialize
+ @contents = []
end
- def add text
- @text += text
+ def add(element)
+ @contents.push(element)
end
- def border border
- return if border == nil
- @text = border + @text + border
+ def sizes
+ @contents.dup.map(&:to_s).map(&:size)
end
- def style style
- return if style == nil
+ def to_s(separator:"", outer_border:nil, inner_border:nil, width:0)
+ outer_border = "" if outer_border == nil
+ inner_border = "" if inner_border == nil
+ text_array = @contents.dup.map(&:to_s).map{|text| text.ljust(width)}
- case style
- when :upcase then @text = @text.upcase
- when :downcase then @text = @text.downcase
- end
+ text_array = text_array.map{ |text| inner_border + text + inner_border}
+ outer_border + text_array.join(separator) + outer_border
end
end
- class VerticalGroup
- :block
- :border
- :style
- :lines
+ class TextScreen
- def initialize (border: nil, style: nil, &block)
- @block = block
- @border = border
- @style = style
+ extend UIMethods
- @lines = []
- instance_eval &block
+ class << self
+ def draw(&block)
+ @result = TextAccumulator.new
+ class_eval &block
+ @result.to_s + "\n"
+ end
end
+ end
- def label (text:, border: nil, style: nil)
- label = Label.new text
- label.style (style != nil ? style : @style)
- label.border border
- @lines << label
- end
+ class Label
+ attr_reader :text
- def vertical (border: nil, style: nil, &block)
- border = (border != nil ? border : @border)
- style = (style != nil ? style : @style)
- group = VerticalGroup.new(border: border, style: style, &block)
- label = Label.new group.text
- @lines << label
+ def initialize(text)
+ @text = text
end
- def horizontal (border: nil, style: nil, &block)
- border = (border != nil ? border : @border)
- style = (style != nil ? style : @style)
- group = HorizontalGroup.new(border: border, style: style, &block)
- label = Label.new group.text
- @lines << label
+ def border (border, width:0)
+ return if border == nil
+
+ @text = @text.ljust(width)
+ @text = border + @text + border
end
- def text
- TextUtilities::add_border(@lines, @border)
+ def style (style)
+ return if style == nil
- result = ''
- @lines.each {|label| result += label.text + "\n"}
- result
+ case style
+ when :upcase then @text = @text.upcase
+ when :downcase then @text = @text.downcase
+ end
end
+
+ def to_s
+ @text
+ end
end
class HorizontalGroup
- :block
- :border
- :style
+ include UIMethods
- :text_container
-
- def initialize (border: nil, style: nil, &block)
- @block = block
+ def initialize(border:nil, style:nil, &block)
@border = border
@style = style
-
- @text_container = Label.new ""
+ @result = TextAccumulator.new
instance_eval &block
end
- def label (text:, border: nil, style: nil)
- label = Label.new text
- label.style (style != nil ? style : @style)
- label.border border
- @text_container.add (label.text)
+ def to_s
+ @result.to_s(outer_border: @border)
end
+ end
- def vertical (border: nil, style: nil, &block)
- border = (border != nil ? border : @border)
- style = (style != nil ? style : @style)
- group = VerticalGroup.new(border: border, style: style, &block)
- @text_container.add (group.text)
- end
+ class VerticalGroup
+ include UIMethods
- def horizontal (border: nil, style: nil, &block)
- border = (border != nil ? border : @border)
- style = (style != nil ? style : @style)
- group = HorizontalGroup.new(border: border, style: style, &block)
- @text_container.add (group.text)
+ def initialize(border:nil, style:nil, &block)
+ @border = border
+ @style = style
+ @result = TextAccumulator.new
+ instance_eval &block
end
- def text
- if @border != nil
- @border + @text_container.text + @border
- else
- @text_container.text
- end
- end
- end
-
- class TextUtilities
- class << self
- def add_border (labels, border)
- return if border == nil
-
- longest_line_size = biggest_line_size labels
- labels.each do |label|
- add_spaces label, (longest_line_size - label.text.size)
- label.border border
- end
- end
-
- def biggest_line_size labels
- labels.max_by{|label| label.text.size}.text.size
- end
-
- def add_spaces (label, spaces_count)
- label.add (" " * spaces_count)
- end
+ def to_s
+ width = @result.sizes.max
+ @result.to_s(separator:"\n", width:width, inner_border: @border)
end
end
end

Евгений обнови решението на 26.11.2014 01:16 (преди почти 10 години)

module UI
module UIMethods
def label(text:, border:nil, style:nil)
label = Label.new(text)
style = @style if style == nil
label.style(style)
label.border(border)
@result.add(label)
end
def horizontal(border:nil, style:nil, &block)
style = @style if style == nil
group = HorizontalGroup.new(border: border, style: style, &block)
@result.add(group)
end
def vertical(border:nil, style:nil, &block)
style = @style if style == nil
group = VerticalGroup.new(border: border, style: style, &block)
@result.add(group)
end
end
class TextAccumulator
def initialize
@contents = []
end
def add(element)
@contents.push(element)
end
def sizes
@contents.dup.map(&:to_s).map(&:size)
end
def to_s(separator:"", outer_border:nil, inner_border:nil, width:0)
outer_border = "" if outer_border == nil
inner_border = "" if inner_border == nil
text_array = @contents.dup.map(&:to_s).map{|text| text.ljust(width)}
text_array = text_array.map{ |text| inner_border + text + inner_border}
outer_border + text_array.join(separator) + outer_border
end
end
class TextScreen
extend UIMethods
class << self
def draw(&block)
@result = TextAccumulator.new
class_eval &block
- @result.to_s + "\n"
+ @result.add(Label.new("\n"))
+ @result
end
end
end
class Label
attr_reader :text
def initialize(text)
@text = text
end
def border (border, width:0)
return if border == nil
@text = @text.ljust(width)
@text = border + @text + border
end
def style (style)
return if style == nil
case style
when :upcase then @text = @text.upcase
when :downcase then @text = @text.downcase
end
end
def to_s
@text
end
end
class HorizontalGroup
include UIMethods
def initialize(border:nil, style:nil, &block)
@border = border
@style = style
@result = TextAccumulator.new
instance_eval &block
end
def to_s
@result.to_s(outer_border: @border)
end
end
class VerticalGroup
include UIMethods
def initialize(border:nil, style:nil, &block)
@border = border
@style = style
@result = TextAccumulator.new
instance_eval &block
end
def to_s
width = @result.sizes.max
@result.to_s(separator:"\n", width:width, inner_border: @border)
end
end
end