module ClockSegment
ClockSegment — render digital clock times as seven-segment ASCII art. Public: normalize_lines, clamp_lines, render Depends: ClockFlip Tests: test/lib/clock_segment_test.rb
Constants
- DEFAULT_LINES
- FILLER
- GLYPHS_2
-
Compact two-row glyphs for a short LED block.
- GLYPHS_3
-
Traditional three-row seven-segment glyphs.
- MAX_LINES
- MIN_LINES
Public Instance Methods
Source
# File lib/clock/segment.rb, line 55 def clamp_lines(lines) value = lines.to_i raise ArgumentError, "lines must be #{MIN_LINES}-#{MAX_LINES}" unless (MIN_LINES..MAX_LINES).cover?(value) value end
Source
# File lib/clock/segment.rb, line 76 def compose_segment_rows(time_text, glyphs: GLYPHS_3) chars = time_text.to_s.chars rows = Array.new(glyphs.values.first.length) { +"" } chars.each_with_index do |char, index| glyph = glyphs[char] || Array.new(rows.length, "???") glyph.each_with_index do |row, row_index| rows[row_index] << dotize_segment(row) rows[row_index] << FILLER unless index == chars.length - 1 end end rows end
Source
# File lib/clock/segment.rb, line 72 def dotize_segment(text) text.to_s.tr(" ", FILLER) end
Source
# File lib/clock/segment.rb, line 48 def normalize_lines(lines) value = lines.to_i value = DEFAULT_LINES if value < MIN_LINES value = MAX_LINES if value > MAX_LINES value end
Source
# File lib/clock/segment.rb, line 62 def render(hour, minute, lines: DEFAULT_LINES) count = normalize_lines(lines) return [ClockFlip.format_time(hour, minute)] if count == 1 time_text = ClockFlip.format_time(hour, minute) glyphs = count == 2 ? GLYPHS_2 : GLYPHS_3 segment_rows = compose_segment_rows(time_text, glyphs: glyphs) stretch_rows(segment_rows, count) end
Source
# File lib/clock/segment.rb, line 89 def stretch_rows(segment_rows, target_lines) base = segment_rows.length return segment_rows if target_lines == base return segment_rows.first(target_lines) if target_lines < base extras = target_lines - base counts = Array.new(base, 1) extras.times { |index| counts[index % base] += 1 } segment_rows.each_with_index.flat_map { |row, index| Array.new(counts[index], row) } end