Решение на Осма задача от Мария Османлиева

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

Към профила на Мария Османлиева

Резултати

  • 2 точки от тестове
  • 0 бонус точки
  • 2 точки общо
  • 10 успешни тест(а)
  • 30 неуспешни тест(а)

Код

class Spreadsheet
class Error < StandardError
def initialize(type, object = nil)
message = errors(type, object)
super(message)
end
private
def errors(type, object)
error_text = {cell_index: "Invalid cell index #{object}",
out_of_bounds: "Cell '#{object}' does not exist",
unknown_function: "Unknown function '#{object}'",
syntax_error: "Invalid expression '#{object}'",
arguments_error: "Wrong number of arguments for '#{object}"}
error_text[type]
end
end
module Validation
FORMULA = {"ADD" => :+ ,
"MULTIPLY" => :* ,
"SUBTRACT" => :- ,
"DIVIDE" => :/ ,
"MOD" => :% }
def valid(cell_index)
raise Error.new(:cell_index, cell_index) unless
is_valid_index?(cell_index)
raise Error.new(:out_of_bounds, cell_index) if out_of_bounds(cell_index)
end
def is_valid_index?(cell_index)
(/^[A-Z]+\d+$/).match(cell_index) != nil
end
def is_valid_formula?(formula)
return true if (/^\d+$/).match(formula) || is_valid_index?(formula)
current_function = function(formula)
raise Error.new(:unknown, formula) if FORMULA[current_function].nil?
syntax_error = (/\(( *\d *, *)+\d\)/).match(formula).nil?
raise Error.new(:syntax_error, formula) if syntax_error
validate_number_of_arguments(formula)
end
private
def function(formula)
(/[A-Z]+/).match(formula)[0]
end
def validate_number_of_arguments(formula)
output = process_number_of_arguments(formula)
return true if output == :ok
count, maximum_arguments = output[:are], output[:maximum_arguments]
expected = maximum_arguments == :any ? "at least 2" : "2"
text = "#{function(formula)}': expected #{expected}, got #{count.to_s}"
raise Error.new(:arguments_error, text)
end
def out_of_bounds(cell_index)
position = cell_position(cell_index)
row, column = position[:row], position[:column]
error_row = row < 0 or row >= @sheet.length
exceeds_columns = @sheet.length > 0 and column >= @sheet.first.length
column_error = column < 0 or exceeds_columns
error_row or column_error
end
def process_number_of_arguments(formula)
function, count = function(formula), arguments(formula).count
add, multiply = function == "ADD", function == "MULTIPLY"
maximum_count = :any if( add or multiply)
condition = maximum_count == :any or count <= 2
return :ok if count > 1 and condition
{are: count, maximum_arguments: maximum_count}
end
def arguments(formula)
string_array = (/\(.*?\)/).match(formula)[0].tr("()", '').split(/ *, */)
string_array.map { |number| number.to_f }
end
end
module ParseModule
def get_cells(row_string)
cells = row_string.split(/\t|[ ]{2,}/)
@sheet.push(cells)
end
def cell_position(string_index)
row_and_column = string_index.split(/(\d+)/)
column_string = row_and_column.first
row_string = row_and_column.last
row = row_string.to_i - 1
column = string_to_column(column_string)
{:row => row, :column => column}
end
def string_to_column(string)
codes = string.chars.map { |letter| letter.ord - 'A'.ord }
calculated, length = [], codes.length
codes.each_with_index do |value, index|
position = position_for_letter(value, index, length)
calculated.push(position)
end
calculated.reduce(:+)
end
def position_for_letter(value, index, length)
return value if length == 1
position = value + (value + 1) * (length - 1 - index) * 26
position -= value if index == 0
return position
end
end
include Validation
include ParseModule
def initialize(table_string = "")
@sheet = []
if table_string != ""
rows_string = table_string.split("\n")
rows_string.each { |row| get_cells(row) }
end
end
def empty?
@sheet.empty?
end
def cell_at(cell_index)
valid(cell_index)
position = cell_position(cell_index)
row = position[:row]
column = position[:column]
@sheet[row][column]
end
def to_s
table_array = []
@sheet.each do |row|
cells = row.join('\t')
table_array.push(cells)
end
table_array.join("\n")
end
def is_formula(cell)
return true if cell[0] == '='
return false
end
def [](cell_index)
cell = cell_at(cell_index)
cell_value = is_formula(cell) ? calculate_formula(cell[1 .. -1]) : cell
cell_value
end
def format(number)
format_string = number % 1 == 0 ? "%.i" : "%.2f"
format_string % number
end
def calculate_formula(formula)
return format(formula.to_f) if (/\d+\.?\d+$/).match(formula)
if is_valid_index?(formula)
valid(formula)
return self[formula]
end
is_valid_formula?(formula)
format(arguments(formula).reduce(FORMULA[function(formula)]))
end
end

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

......FFFFFFFF....FFFFFFFFFFFFFFFFFFFFFF

Failures:

  1) Spreadsheet#to_s returns multi-cell, oneline tables as a string
     Failure/Error: expect(Spreadsheet.new("foo\tbar\tbaz").to_s).to eq "foo\tbar\tbaz"
       
       expected: "foo\tbar\tbaz"
            got: "foo\\tbar\\tbaz"
       
       (compared using ==)
     # /tmp/d20160121-5693-19pwo3a/spec.rb:32: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)>'

  2) Spreadsheet#to_s returns multi-cell, multiline tables as a string
     Failure/Error: expect(Spreadsheet.new("foo\tbar\nbaz\tlarodi").to_s).to eq "foo\tbar\nbaz\tlarodi"
       
       expected: "foo\tbar\nbaz\tlarodi"
            got: "foo\\tbar\nbaz\\tlarodi"
       
       (compared using ==)
       
       Diff:
       @@ -1,3 +1,3 @@
       -foo	bar
       -baz	larodi
       +foo\tbar
       +baz\tlarodi
     # /tmp/d20160121-5693-19pwo3a/spec.rb:36: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)>'

  3) Spreadsheet#to_s splits cells by two or more spaces
     Failure/Error: expect(Spreadsheet.new("foo  bar   42\nbaz    larodi  100").to_s).to eq "foo\tbar\t42\nbaz\tlarodi\t100"
       
       expected: "foo\tbar\t42\nbaz\tlarodi\t100"
            got: "foo\\tbar\\t42\nbaz\\tlarodi\\t100"
       
       (compared using ==)
       
       Diff:
       @@ -1,3 +1,3 @@
       -foo	bar	42
       -baz	larodi	100
       +foo\tbar\t42
       +baz\tlarodi\t100
     # /tmp/d20160121-5693-19pwo3a/spec.rb:40: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) Spreadsheet#to_s returns the evaluated spreadsheet as a table
     Failure/Error: expect(sheet.to_s).to eq \
       
       expected: "foo\t10\t2.1\t15\nbar\t11\t2.2\t5\nbaz\t12\t2.3\t27.60"
            got: "\\tfoo\\t10\\t2.1\\t=ADD(B1, C1, 2.9)\n\\tbar\\t11\\t2.2\\t=DIVIDE(B2, C2)\n\\tbaz\\t12\\t2.3\\t=MULTIPLY(C3, B3)"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -foo	10	2.1	15
       -bar	11	2.2	5
       -baz	12	2.3	27.60
       +\tfoo\t10\t2.1\t=ADD(B1, C1, 2.9)
       +\tbar\t11\t2.2\t=DIVIDE(B2, C2)
       +\tbaz\t12\t2.3\t=MULTIPLY(C3, B3)
     # /tmp/d20160121-5693-19pwo3a/spec.rb:50: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) Spreadsheet#cell_at raises and exception for non-existant cells
     Failure/Error: expect { Spreadsheet.new('foo')['B10'] }.to raise_error(Spreadsheet::Error, /Cell 'B10' does not exist/)
       expected Spreadsheet::Error with message matching /Cell 'B10' does not exist/, got #<NoMethodError: undefined method `[]' for nil:NilClass> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:141:in `cell_at'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:159:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:59:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:59: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:59: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) Spreadsheet#cell_at returns the raw value of existing cells
     Failure/Error: expect(sheet.cell_at('A1')).to eq 'foo'
       
       expected: "foo"
            got: ""
       
       (compared using ==)
     # /tmp/d20160121-5693-19pwo3a/spec.rb:68: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)>'

  7) Spreadsheet#[] raises an exception for non-existant cells
     Failure/Error: expect { Spreadsheet.new()['A1'] }.to raise_error(Spreadsheet::Error, /Cell 'A1' does not exist/)
       expected Spreadsheet::Error with message matching /Cell 'A1' does not exist/, got #<NoMethodError: undefined method `[]' for nil:NilClass> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:141:in `cell_at'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:159:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:75:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:75: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:75: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)>'

  8) Spreadsheet#[] returns the value of existing cells for simple cell indexes
     Failure/Error: expect(sheet['A1']).to eq 'foo'
       
       expected: "foo"
            got: ""
       
       (compared using ==)
     # /tmp/d20160121-5693-19pwo3a/spec.rb:84: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)>'

  9) Spreadsheet#[] raises an exception for less than two arguments passed to ADD
     Failure/Error: expect { Spreadsheet.new('=ADD(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'ADD': expected at least 2, got 1/, got #<Spreadsheet::Error: Invalid expression 'ADD(1)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:119:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:119: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:119: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)>'

  10) Spreadsheet#[] adds numbers from cell references and as immediate arguments with ADD
     Failure/Error: expect(sheet['B1']).to eq('55')
     Spreadsheet::Error:
       Invalid expression 'ADD(1, A1, 2, C1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:131: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)>'

  11) Spreadsheet#[] adds numbers only from cell references with ADD
     Failure/Error: expect(sheet['D1']).to eq('10')
     Spreadsheet::Error:
       Invalid expression 'ADD(B1, A1, C1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:137: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)>'

  12) Spreadsheet#[] multiplies numbers with MULTIPLY
     Failure/Error: expect(sheet2['E1']).to eq('120')
     Spreadsheet::Error:
       Invalid expression 'MULTIPLY(A1, B1, C1, D1, 5)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:145: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)>'

  13) Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY
     Failure/Error: expect { Spreadsheet.new('=MULTIPLY(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'MULTIPLY': expected at least 2, got 1/, got #<Spreadsheet::Error: Invalid expression 'MULTIPLY(1)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:149:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:149: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:149: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)>'

  14) Spreadsheet#[] subtracts two numbers with SUBTRACT
     Failure/Error: expect(sheet['A1']).to eq('2')
     Spreadsheet::Error:
       Wrong number of arguments for 'SUBTRACT': expected 2, got 2
     # /tmp/d20160121-5693-19pwo3a/solution.rb:58:in `validate_number_of_arguments'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:44:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:161: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)>'

  15) Spreadsheet#[] subtracts numbers via cell references
     Failure/Error: expect(sheet['D1']).to eq('4')
     Spreadsheet::Error:
       Invalid expression 'SUBTRACT(C1, 1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:167: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)>'

  16) Spreadsheet#[] raises an exception when SUBTRACT is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=SUBTRACT(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'SUBTRACT': expected 2, got 1/, got #<Spreadsheet::Error: Invalid expression 'SUBTRACT(1)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:171:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/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)>'
     # /tmp/d20160121-5693-19pwo3a/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)>'

  17) Spreadsheet#[] divides two numbers with DIVIDE
     Failure/Error: expect(sheet['A1']).to eq('42')
     Spreadsheet::Error:
       Invalid expression 'DIVIDE(84, 2)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:183: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)>'

  18) Spreadsheet#[] divides numbers via cell references
     Failure/Error: expect(sheet1['C1']).to eq('42')
     Spreadsheet::Error:
       Invalid expression 'DIVIDE(B1, A1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:190: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)>'

  19) Spreadsheet#[] raises an exception when DIVIDE is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=DIVIDE(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'DIVIDE': expected 2, got 1/, got #<Spreadsheet::Error: Invalid expression 'DIVIDE(1)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:195:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:195: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:195: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)>'

  20) Spreadsheet#[] calculates the modulo of two numbers with MOD
     Failure/Error: expect(Spreadsheet.new('=MOD(42, 5)')['A1']).to eq('2')
     Spreadsheet::Error:
       Invalid expression 'MOD(42, 5)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:205: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)>'

  21) Spreadsheet#[] calculates the modulo of two numbers with MOD via cell references
     Failure/Error: expect(sheet1['C1']).to eq('4')
     Spreadsheet::Error:
       Invalid expression 'MOD(B1, A1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:214: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)>'

  22) Spreadsheet#[] raises an exception when MOD is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=MOD(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'MOD': expected 2, got 1/, got #<Spreadsheet::Error: Invalid expression 'MOD(1)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:219:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:219: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:219: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)>'

  23) Spreadsheet#[] adds floating point numbers with ADD
     Failure/Error: expect(Spreadsheet.new('10  =ADD(A1, 1.1)')['B1']).to eq '11.10'
     Spreadsheet::Error:
       Invalid expression 'ADD(A1, 1.1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:229: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)>'

  24) Spreadsheet#[] subtracts floating point numbers with SUBTRACT
     Failure/Error: expect(Spreadsheet.new('10  =SUBTRACT(A1, 1.1)')['B1']).to eq '8.90'
     Spreadsheet::Error:
       Invalid expression 'SUBTRACT(A1, 1.1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:234: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)>'

  25) Spreadsheet#[] multiplies floating point numbers with MULTIPLY
     Failure/Error: expect(Spreadsheet.new('10  =MULTIPLY(A1, 1.1)')['B1']).to eq '11'
     Spreadsheet::Error:
       Invalid expression 'MULTIPLY(A1, 1.1)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:239: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)>'

  26) Spreadsheet#[] divides floating point numbers with DIVIDE
     Failure/Error: expect(Spreadsheet.new('10  =DIVIDE(A1, 4)')['B1']).to eq '2.50'
     Spreadsheet::Error:
       Invalid expression 'DIVIDE(A1, 4)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:244: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)>'

  27) Spreadsheet#[] evaluates deeply-nested cell references
     Failure/Error: expect(Spreadsheet.new('10  =ADD(5, A1)  3  =DIVIDE(B1, C1)  =MOD(D1, 4)')['E1']).to eq '1'
     Spreadsheet::Error:
       Invalid expression 'MOD(D1, 4)'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
     # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:250: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)>'

  28) Spreadsheet#[] raises an exception for unknown functions
     Failure/Error: expect { Spreadsheet.new('=FOO(42)  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Unknown function 'FOO'/, got #<Spreadsheet::Error: Spreadsheet::Error> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:40:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:254:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:254: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:254: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)>'

  29) Spreadsheet#[] raises an exception for missing cells passed as function arguments
     Failure/Error: expect { Spreadsheet.new('=ADD(1, B4)  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Cell 'B4' does not exist/, got #<Spreadsheet::Error: Invalid expression 'ADD(1, B4)'> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:43:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:260:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:260: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:260: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)>'

  30) Spreadsheet#[] raises an exception for invalid expressions
     Failure/Error: expect { Spreadsheet.new('=FOO  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Invalid expression 'FOO'/, got #<Spreadsheet::Error: Spreadsheet::Error> with backtrace:
         # /tmp/d20160121-5693-19pwo3a/solution.rb:40:in `is_valid_formula?'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:175:in `calculate_formula'
         # /tmp/d20160121-5693-19pwo3a/solution.rb:160:in `[]'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:266:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-19pwo3a/spec.rb:266: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)>'
     # /tmp/d20160121-5693-19pwo3a/spec.rb:266: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.03948 seconds
40 examples, 30 failures

Failed examples:

rspec /tmp/d20160121-5693-19pwo3a/spec.rb:31 # Spreadsheet#to_s returns multi-cell, oneline tables as a string
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:35 # Spreadsheet#to_s returns multi-cell, multiline tables as a string
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:39 # Spreadsheet#to_s splits cells by two or more spaces
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:43 # Spreadsheet#to_s returns the evaluated spreadsheet as a table
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:58 # Spreadsheet#cell_at raises and exception for non-existant cells
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:62 # Spreadsheet#cell_at returns the raw value of existing cells
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:74 # Spreadsheet#[] raises an exception for non-existant cells
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:78 # Spreadsheet#[] returns the value of existing cells for simple cell indexes
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:118 # Spreadsheet#[] raises an exception for less than two arguments passed to ADD
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:128 # Spreadsheet#[] adds numbers from cell references and as immediate arguments with ADD
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:134 # Spreadsheet#[] adds numbers only from cell references with ADD
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:140 # Spreadsheet#[] multiplies numbers with MULTIPLY
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:148 # Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:158 # Spreadsheet#[] subtracts two numbers with SUBTRACT
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:164 # Spreadsheet#[] subtracts numbers via cell references
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:170 # Spreadsheet#[] raises an exception when SUBTRACT is called with a wrong number of arguments
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:180 # Spreadsheet#[] divides two numbers with DIVIDE
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:186 # Spreadsheet#[] divides numbers via cell references
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:194 # Spreadsheet#[] raises an exception when DIVIDE is called with a wrong number of arguments
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:204 # Spreadsheet#[] calculates the modulo of two numbers with MOD
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:210 # Spreadsheet#[] calculates the modulo of two numbers with MOD via cell references
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:218 # Spreadsheet#[] raises an exception when MOD is called with a wrong number of arguments
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:228 # Spreadsheet#[] adds floating point numbers with ADD
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:233 # Spreadsheet#[] subtracts floating point numbers with SUBTRACT
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:238 # Spreadsheet#[] multiplies floating point numbers with MULTIPLY
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:243 # Spreadsheet#[] divides floating point numbers with DIVIDE
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:249 # Spreadsheet#[] evaluates deeply-nested cell references
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:253 # Spreadsheet#[] raises an exception for unknown functions
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:259 # Spreadsheet#[] raises an exception for missing cells passed as function arguments
rspec /tmp/d20160121-5693-19pwo3a/spec.rb:265 # Spreadsheet#[] raises an exception for invalid expressions

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

Мария обнови решението на 11.01.2016 17:03 (преди над 8 години)

+class Spreadsheet
+
+ class Error < StandardError
+ def initialize(type, object = nil)
+ message = errors(type, object)
+ super(message)
+ end
+
+ private
+ def errors(type, object)
+ error_text = {cell_index: "Invalid cell index #{object}",
+ out_of_bounds: "Cell '#{object}' does not exist",
+ unknown_function: "Unknown function '#{object}'",
+ syntax_error: "Invalid expression '#{object}'",
+ arguments_error: "Wrong number of arguments for '#{object}"}
+ error_text[type]
+ end
+ end
+
+ module ValidationModule
+ FORMULA = {"ADD" => :+ ,
+ "MULTIPLY" => :* ,
+ "SUBTRACT" => :- ,
+ "DIVIDE" => :/ ,
+ "MOD" => :% }
+
+ def valid(cell_index)
+ raise Error.new(:cell_index, cell_index) unless
+ is_valid_index?(cell_index)
+ raise Error.new(:out_of_bounds, cell_index) if out_of_bounds(cell_index)
+ end
+
+ def is_valid_index?(cell_index)
+ (/^[A-Z]+\d+$/).match(cell_index) != nil
+ end
+
+ def is_valid_formula?(formula)
+ return true if (/^\d+$/).match(formula) || is_valid_index?(formula)
+ current_function = function(formula)
+ raise Error.new(:unknown, formula) if FORMULA[current_function].nil?
+
+ syntax_error = (/\(( *\d *, *)+\d\)/).match(formula).nil?
+ raise Error.new(:syntax_error, formula) if syntax_error
+ validate_number_of_arguments(formula)
+ end
+
+ private
+ def function(formula)
+ (/[A-Z]+/).match(formula)[0]
+ end
+
+ def validate_number_of_arguments(formula)
+ output = process_number_of_arguments(formula)
+ return true if output == :ok
+ count, maximum_arguments = output[:are], output[:maximum_arguments]
+ expected = maximum_arguments == :any ? "at least 2" : "2"
+ text = "#{function(formula)}': expected #{expected}, got #{count.to_s}"
+ raise Error.new(:arguments_error, text)
+ end
+
+ def out_of_bounds(cell_index)
+ position = cell_position(cell_index)
+ row, column = position[:row], position[:column]
+
+ error_row = row < 0 or row >= @sheet.length
+ exceeds_columns = @sheet.length > 0 and column >= @sheet.first.length
+ column_error = column < 0 or exceeds_columns
+
+ error_row or column_error
+ end
+
+ def process_number_of_arguments(formula)
+ function, count = function(formula), arguments(formula).count
+
+ add, multiply = function == "ADD", function == "MULTIPLY"
+ maximum_count = :any if( add or multiply)
+ condition = maximum_count == :any or count <= 2
+ return :ok if count > 1 and condition
+ {are: count, maximum_arguments: maximum_count}
+ end
+
+ def arguments(formula)
+ string_array = (/\(.*?\)/).match(formula)[0].tr("()", '').split(/ *, */)
+ string_array.map { |number| number.to_f }
+ end
+
+ end
+
+ module ParseModule
+ def get_cells(row_string)
+ cells = row_string.split(/\t|[ ]{2,}/)
+ @sheet.push(cells)
+ end
+
+ def cell_position(string_index)
+ row_and_column = string_index.split(/(\d+)/)
+ column_string = row_and_column.first
+ row_string = row_and_column.last
+ row = row_string.to_i - 1
+ column = string_to_column(column_string)
+ {:row => row, :column => column}
+ end
+
+ def string_to_column(string)
+ codes = string.chars.map { |letter| letter.ord - 'A'.ord }
+ calculated, length = [], codes.length
+ codes.each_with_index do |value, index|
+ position = position_for_letter(value, index, length)
+ calculated.push(position)
+ end
+ calculated.reduce(:+)
+ end
+
+ def position_for_letter(value, index, length)
+ return value if length == 1
+ position = value + (value + 1) * (length - 1 - index) * 26
+ position -= value if index == 0
+ return position
+ end
+ end
+
+ include Validation
+ include ParseModule
+ def initialize(table_string = "")
+ @sheet = []
+ if table_string != ""
+ rows_string = table_string.split("\n")
+ rows_string.each { |row| get_cells(row) }
+ end
+ end
+
+ def empty?
+ @sheet.empty?
+ end
+
+ def cell_at(cell_index)
+ valid(cell_index)
+ position = cell_position(cell_index)
+ row = position[:row]
+ column = position[:column]
+ @sheet[row][column]
+ end
+
+ def to_s
+ table_array = []
+ @sheet.each do |row|
+ cells = row.join('\t')
+ table_array.push(cells)
+ end
+ table_array.join("\n")
+ end
+
+ def is_formula(cell)
+ return true if cell[0] == '='
+ return false
+ end
+
+ def [](cell_index)
+ cell = cell_at(cell_index)
+ cell_value = is_formula(cell) ? calculate_formula(cell[1 .. -1]) : cell
+ cell_value
+ end
+
+ def format(number)
+ format_string = number % 1 == 0 ? "%.i" : "%.2f"
+ format_string % number
+ end
+
+ def calculate_formula(formula)
+ return format(formula.to_f) if (/\d+\.?\d+$/).match(formula)
+ if is_valid_index?(formula)
+ valid(formula)
+ return self[formula]
+ end
+ is_valid_formula?(formula)
+ format(arguments(formula).reduce(FORMULA[function(formula)]))
+ end
+
+end

Мария обнови решението на 11.01.2016 17:07 (преди над 8 години)

class Spreadsheet
class Error < StandardError
def initialize(type, object = nil)
message = errors(type, object)
super(message)
end
private
def errors(type, object)
error_text = {cell_index: "Invalid cell index #{object}",
out_of_bounds: "Cell '#{object}' does not exist",
unknown_function: "Unknown function '#{object}'",
syntax_error: "Invalid expression '#{object}'",
arguments_error: "Wrong number of arguments for '#{object}"}
error_text[type]
end
end
- module ValidationModule
+ module Validation
FORMULA = {"ADD" => :+ ,
"MULTIPLY" => :* ,
"SUBTRACT" => :- ,
"DIVIDE" => :/ ,
"MOD" => :% }
def valid(cell_index)
raise Error.new(:cell_index, cell_index) unless
is_valid_index?(cell_index)
raise Error.new(:out_of_bounds, cell_index) if out_of_bounds(cell_index)
end
def is_valid_index?(cell_index)
(/^[A-Z]+\d+$/).match(cell_index) != nil
end
def is_valid_formula?(formula)
return true if (/^\d+$/).match(formula) || is_valid_index?(formula)
current_function = function(formula)
raise Error.new(:unknown, formula) if FORMULA[current_function].nil?
syntax_error = (/\(( *\d *, *)+\d\)/).match(formula).nil?
raise Error.new(:syntax_error, formula) if syntax_error
validate_number_of_arguments(formula)
end
private
def function(formula)
(/[A-Z]+/).match(formula)[0]
end
def validate_number_of_arguments(formula)
output = process_number_of_arguments(formula)
return true if output == :ok
count, maximum_arguments = output[:are], output[:maximum_arguments]
expected = maximum_arguments == :any ? "at least 2" : "2"
text = "#{function(formula)}': expected #{expected}, got #{count.to_s}"
raise Error.new(:arguments_error, text)
end
def out_of_bounds(cell_index)
position = cell_position(cell_index)
row, column = position[:row], position[:column]
error_row = row < 0 or row >= @sheet.length
exceeds_columns = @sheet.length > 0 and column >= @sheet.first.length
column_error = column < 0 or exceeds_columns
error_row or column_error
end
def process_number_of_arguments(formula)
function, count = function(formula), arguments(formula).count
add, multiply = function == "ADD", function == "MULTIPLY"
maximum_count = :any if( add or multiply)
condition = maximum_count == :any or count <= 2
return :ok if count > 1 and condition
{are: count, maximum_arguments: maximum_count}
end
def arguments(formula)
string_array = (/\(.*?\)/).match(formula)[0].tr("()", '').split(/ *, */)
string_array.map { |number| number.to_f }
end
end
module ParseModule
def get_cells(row_string)
cells = row_string.split(/\t|[ ]{2,}/)
@sheet.push(cells)
end
def cell_position(string_index)
row_and_column = string_index.split(/(\d+)/)
column_string = row_and_column.first
row_string = row_and_column.last
row = row_string.to_i - 1
column = string_to_column(column_string)
{:row => row, :column => column}
end
def string_to_column(string)
codes = string.chars.map { |letter| letter.ord - 'A'.ord }
calculated, length = [], codes.length
codes.each_with_index do |value, index|
position = position_for_letter(value, index, length)
calculated.push(position)
end
calculated.reduce(:+)
end
def position_for_letter(value, index, length)
return value if length == 1
position = value + (value + 1) * (length - 1 - index) * 26
position -= value if index == 0
return position
end
end
include Validation
include ParseModule
def initialize(table_string = "")
@sheet = []
if table_string != ""
rows_string = table_string.split("\n")
rows_string.each { |row| get_cells(row) }
end
end
def empty?
@sheet.empty?
end
def cell_at(cell_index)
valid(cell_index)
position = cell_position(cell_index)
row = position[:row]
column = position[:column]
@sheet[row][column]
end
def to_s
table_array = []
@sheet.each do |row|
cells = row.join('\t')
table_array.push(cells)
end
table_array.join("\n")
end
def is_formula(cell)
return true if cell[0] == '='
return false
end
def [](cell_index)
cell = cell_at(cell_index)
cell_value = is_formula(cell) ? calculate_formula(cell[1 .. -1]) : cell
cell_value
end
def format(number)
format_string = number % 1 == 0 ? "%.i" : "%.2f"
format_string % number
end
def calculate_formula(formula)
return format(formula.to_f) if (/\d+\.?\d+$/).match(formula)
if is_valid_index?(formula)
valid(formula)
return self[formula]
end
is_valid_formula?(formula)
format(arguments(formula).reduce(FORMULA[function(formula)]))
end
end