Alex Hail - 1 year ago 77
Ruby Question

# Ruby calculator - hash not storing correctly

So I'll start off by writing that I am new to this site (today), as well as to the Ruby programming language (3 days ago), so don't feel afraid to rip apart my code--I am trying to learn and get better.

Basically.. I am creating a console calculator that is able to read a simple math problem (or string of math problems) from the user and solve the equation. It doesn't use order of operations or anything fancy (yet) and it is basically working except for this one weird bug I can't figure out.

Userinput = "1 + 2 + 3 - 4"
# First I split the user input into an array of stirngs and then loop over the
# array of strings and depict whether a string is a key or hash (see code below)

# program should store these characters in a hash like so..
hash = { nil=>1, "+"=>2, "+"=>3, "-"=>4 }

Then I would use the key of the hash to determine whether or not I was adding, subtracting, multiplying, or dividing next.

Everything pretty much works fine! Its just that when I do a problem with more than 2 operations (i.e. 1 + 2 - 0 + 3) the program will just randomly leave out some keys and operators. I have been trying different examples to search for a pattern but I cant find the source. Below I'll post examples of the problem and their output, as well as the hash itself, and then full source code. Thanks in advance for any help or critiques!

Examples format

Program Input (user prompt, user input) --
Program output (sum of equation) --
hash at the end of execution

Example 1

Type a math problem (ex. 40 / 5): 40 / 5 + 2 - 5 * 5 - 5 * 5 - 100

-450

{nil=>40, "/"=>5, "+"=>2, "-"=>100, "*"=>5}

Example 2

Type a math problem (ex. 40 / 5): 1 + 2 - 0 + 3

4

{nil=>1, "+"=>3, "-"=>0}

Example 3

Type a math problem (ex. 40 / 5): 10 - 5 * 2 + 8 + 2

12

{nil=>10, "-"=>5, "*"=>2, "+"=>2}

Source code: main.rb

=begin

main.rb
Version 1.0
Written by Alex Hail - 10/16/2016

Parses a basic, user-entered arithmetic equation and solves it

=end

@operationsParser = "" # global parser

private
def appointType(sv)
if sv =~ /\d/
sv.to_i
else
sv
end
end

private
def operate(operations)
sum = 0
operations.each do |k, v|
if k.nil?
sum += v
else
case k
when '+' then sum += v
when '-' then sum -= v
when '*' then sum = sum * v
when '/' then sum = sum / v
else
end
end
end
sum
end

private
def solveEquation
print "Type a math problem (ex. 40 / 5): "
userInput = gets.chomp

#array to hold all numbers and their cooresponding operation
operations = {} # <== Empty hash

#split the user input via spaces
@operationsParser = userInput.split(" ")

#convert numbers into numbers store operators in hash ( nil => 40, "/" => 5) -- would be 40 / 5
@operationsParser.each do |stringValue|
if appointType(stringValue).is_a? Integer

operations[@lastKeyAdded != "" ? @lastKeyAdded : nil] = appointType(stringValue)

else #appointType will return a string by default
end
end

#check if operators(+, *, -, /, or nil) in the keys are valid, if not, error and exit, if so, operate
operations.each do |k,v|
case k
when '+'
when '-'
when '*'
when '/'
when nil
else
# Exit the program if we have an invalid operator in the hash
puts "Exiting program with error - Invalid operator used (Only +, -, *, / please)"
return
end
end

sum = operate(operations)

puts sum, operations
end

solveEquation