2

For personal homework I am trying out a digital clock program to display 'big' numbers.

A ruby program that has parts of the clock that come from strings stored in an array and then a routine (not yet fully written) that can display any numbers as 'big numbers'.
This is to help me learn more about manipulating hashes and iterating through arrays, concatenating string, etc.

I am stuck right now with this:

all_nums=''
(0..3).each do |num|
    all_nums+= (line_parts[num][0].values).to_s
    #puts line_parts[num][0].values
end 
puts all_nums

because I am getting back array elements that I can't convert to strings, i.e.

ruby digital_clock,rb
[" ==  "]["|  | "]["|  | "][" ==  "]

but when I just puts them (commented out 3rd line from the bottom) it is OK but, I get strings, i.e.

ruby digital_clock.rb
 ==  
|  | 
|  | 
 ==  

I want to be able to build up the string (big 0 in this case) but I can only puts out the pieces and I've been unable to assign them to a variable and print it. How could I do that?

The full program is:

top=          ' ==      |   ==    ==   |  |   ==   |      ==    ==    == '
top_middle=   '|  |     |   __|   __|  |__|  |__   |__      |  |__|  |__|'
bottom_middle='|  |     |  |        |     |     |  |  |     |  |  |     |'
bottom=       ' ==      |   ==    ==      |   ==    ==      |   ==      |'

number_parts=[{},{},{},{},{},{},{},{},{},{}]
line_parts=[[],[],[],[]]

['top','top_middle','bottom_middle','bottom'].each_with_index do |one_line, i|
  number_parts=[{},{},{},{},{},{},{},{},{},{}]
  (0..9).each do |the_num|
    number_parts[the_num] = {one_line.to_sym => eval(one_line)[the_num*5,5].to_s}
  end
  line_parts[i]= number_parts
end

all_nums=''
(0..3).each do |num|
    all_nums+= (line_parts[num][0].values).to_s
    #puts line_parts[num][0].values
end 
puts all_nums
4

1 回答 1

1

I think this will fix your immediate problem -- namely, printing a big "0".

all_nums = []
(0..3).each do |num|
  all_nums.push(line_parts[num][0].values)
end 
puts all_nums.join("\n")

A better way to do that would be with map:

all_nums = (0..3).map { |num| line_parts[num][0].values }
puts all_nums.join("\n")

Another issue: you don't need to use eval. In fact, one almost never needs to use eval.

# Use variables rather than the strings 'top', 'top_middle', etc.
[top,top_middle,bottom_middle,bottom].each_with_index do |one_line, i|
    ...
    # Then the eval() is unnecessary.
    number_parts[the_num] = {one_line.to_sym => one_line[the_num*5,5]}
    ....

But you can really simplify the code along the following lines:

# Use an array, not a set of specifically named variables.
# This makes it a lot easier to iterate over the data.
rows = [
  '  --     |  --   --  |  |  --  |     --   --   -- ',
  ' |  |    |  __|  __| |__| |__  |__     | |__| |__|',
  ' |  |    | |       |    |    | |  |    | |  |    |',
  '  --     |  --   --     |  --   --     |  --     |',
]

# Create an array-of-arrays.
# num_parts[NUMBER] = [an array of four strings]
width = 5
num_parts = (0..9).map { |n| rows.map { |r| r[n * width, width] } }

# Inspect.
num_parts.each do |np|
  puts
  puts np.join("\n")
end

You might also take a look at the Unix command called banner, which will inspire you to make the numbers EVEN BIGGER. That would allow you to start adding curves and other design touches.

于 2013-06-16T14:19:50.837 回答