tui_calc.rb
# Takes a valid math expresion (string) and returns the result as a float
# or nil if expression is invalid
# The elements of the expresion should be seperated by spaces
# If verbose, prints the new expression after each intermediary calculation
Takes a valid math expresion (string) and returns the result as a float
or nil if expression is invalid
The elements of the expresion should be seperated by spaces
If verbose, prints the new expression after each intermediary calculation
Takes a valid math expresion ( string ) and returns the result as a float or nil if expression is invalid The elements of the expresion should be seperated by spaces If verbose prints the new expression after each intermediary calculation
def calc(expr, verbose=false)
  ops_hash = {'+': method(:add), '-': method(:subt),
              '*': method(:mult), '/': method(:div),
              '**': method(:pow), '^': method(:pow)}
  expr.strip!
  expr_arr = expr.split
  unless check_expr(expr_arr, false)
    return nil
  end
  j = 0  
  while j < (expr_arr.length - 1) do
    nest = check_parens(expr_arr)
    unless nest
      return nil
    end
    match_j = nil  
    if PAIRS.key?(expr_arr[j])
      nest.each do |info_arr|
        if info_arr[2] == j
        match_j = info_arr[3]
        end
      end
      temp_expr = expr_arr[j+1...match_j].join(' ')
      temp_result = calc(temp_expr, verbose)
      unless temp_result
        return nil
      end
      expr_arr[j..match_j] = temp_result
      j = 0  
    else
      j += 1
    end
  end
  if expr_arr.length == 1
    return expr_arr[0].to_f
  end
  result = 0  
  OPS.each do |op_set|
    i = 0
    while i < (expr_arr.length - 1) do
      if op_set.include?(expr_arr[i])
        op = expr_arr[i]
        x = expr_arr[i-1]
        y = expr_arr[i+1]
        result = ops_hash[op.to_sym].(x.to_f, y.to_f)
        expr_arr[i-1..i+1] = result
        i = 0  
        if verbose and not expr_arr.length == 1
          puts expr_arr.join(" ")
        end
      else
        i += 1
      end
    end
  end
  return result
end
def calc ( expr , verbose = false ) ops_hash = { '+' : method ( :add ) , '-' : method ( :subt ) , '*' : method ( :mult ) , '/' : method ( :div ) , '**' : method ( :pow ) , '^' : method ( :pow ) } expr . strip! expr_arr = expr . split unless check_expr ( expr_arr , false ) return nil end j = 0 while j < ( expr_arr . length - 1 ) do nest = check_parens ( expr_arr ) unless nest return nil end match_j = nil if PAIRS . key? ( expr_arr [ j ] ) nest . each do | info_arr | if info_arr [ 2 ] == j match_j = info_arr [ 3 ] end end temp_expr = expr_arr [ j + 1 ... match_j ] . join ( ' ' ) temp_result = calc ( temp_expr , verbose ) unless temp_result return nil end expr_arr [ j .. match_j ] = temp_result j = 0 else j += 1 end end if expr_arr . length == 1 return expr_arr [ 0 ] . to_f end result = 0 OPS . each do | op_set | i = 0 while i < ( expr_arr . length - 1 ) do if op_set . include? ( expr_arr [ i ] ) op = expr_arr [ i ] x = expr_arr [ i - 1 ] y = expr_arr [ i + 1 ] result = ops_hash [ op . to_sym ] . ( x . to_f , y . to_f ) expr_arr [ i - 1 .. i + 1 ] = result i = 0 if verbose and not expr_arr . length == 1 puts expr_arr . join ( " " ) end else i += 1 end end end return result end
Takes a valid math expresion (string) and returns the result as a float
or nil if expression is invalid
The elements of the expresion should be seperated by spaces
If verbose, prints the new expression after each intermediary calculation
Takes a valid math expresion ( string ) and returns the result as a float or nil if expression is invalid The elements of the expresion should be seperated by spaces If verbose prints the new expression after each intermediary calculation
# hash of str: func for operations # parse expr # check expression validity # used to track index while handling parens # find matching parens, then replace parens and contents with result of contents # check parens and get nest info. needs to be done inside this loop # if not, info fails to match as expression changes # Initialize match_j so later code can find it # find open paren # find matching close paren # join contents and send to calc # return if internal expression was invalid # replace parens and contents with temp result # indices got moved and removed, so start from beginning # If, after dealing with parens, there is only one element, return it # initialize result variable so the return statement can find it # search for operations in order # search expression for current operations # if found: calculate, replace, and search from begining of expression # else: move to next element in expression # find and assign operation and values # call appropriate op function # replace the 3 used elements with the result # indices got moved and removed, so start from beginning # print verbose output
expr
<not_specific>
verbose
<not_specific>