## DEV Community is a community of 765,064 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Discussion on: Daily Challenge #10 - Calculator

margo1993
``````package utils

import (
"errors"
"fmt"
"math"
"regexp"
"strconv"
"strings"
)

func evaluate(expression string) (float64, error) {
supportedExpressions := []string{"/", "*", "+", "-"}

expression = strings.Replace(expression, " ", "", len(expression) / 2)

for _, e := range supportedExpressions {
for moreExpressionsAvailable(expression, e) {
firstExpression := findFirstExpression(expression, e)
calculatedString, e := calculateString(firstExpression)

if e != nil {
return 0, e
}

expression = strings.Replace(expression, firstExpression, fmt.Sprintf("%0.2f", calculatedString), 1)
}
}
result, e := strconv.ParseFloat(expression, 32)
return math.Round(result * 100) / 100, e
}

func moreExpressionsAvailable(string string, e string) bool {
r := regexp.MustCompile("\\" + e)
return r.MatchString(string)
}

func findFirstExpression(expression string, operation string) string {
r := regexp.MustCompile("[0-9.]+\\" + operation + "[0-9.]+")
return r.FindString(expression)
}

func calculateString(expression string) (float64, error) {
r := regexp.MustCompile("([0-9.]+)([/*+\\-])([0-9.]+)")

submatches := r.FindStringSubmatch(expression)

if len(submatches) < 3 {
return 0, errors.New("not enought data")
}

num1, _ := strconv.ParseFloat(submatches[1], 32)
numb2, _ := strconv.ParseFloat(submatches[3], 32)
result, e := calculate(num1, numb2, submatches[2])
return result, e
}

func calculate(num1 float64, num2 float64, operation string) (float64, error) {

switch operation {
case "*":
return num1 * num2, nil
case "/":
return num1 / num2, nil
case "+":
return num1 + num2, nil
case "-":
return num1 - num2, nil
}

return 0, errors.New("Unsupported operator")
}
``````