Skip to content

Commit c2c3dc7

Browse files
committed
add utils
1 parent b5e94bd commit c2c3dc7

2 files changed

Lines changed: 188 additions & 0 deletions

File tree

backend/internal/utils/range.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package utils
2+
3+
import (
4+
"errors"
5+
"strconv"
6+
"strings"
7+
)
8+
9+
func ParseRange(literal string) ([]*float64, error) {
10+
if literal == "" {
11+
return []*float64{nil, nil}, nil
12+
}
13+
14+
strRange := strings.Split(strings.TrimSuffix(strings.TrimPrefix(strings.Replace(literal, " ", "", -1), "["), "]"), ",")
15+
16+
if len(strRange) != 2 {
17+
return nil, errors.New("invalid range")
18+
}
19+
20+
numRange := make([]*float64, 0)
21+
22+
if strRange[0] != "" {
23+
lowerBound, errLowerBound := strconv.ParseFloat(strRange[0], 64)
24+
25+
if errLowerBound != nil {
26+
return nil, errors.New("parsing lower bound")
27+
}
28+
29+
numRange = append(numRange, &lowerBound)
30+
} else {
31+
numRange = append(numRange, nil)
32+
}
33+
34+
if strRange[1] != "" {
35+
upperBound, errUpperBound := strconv.ParseFloat(strRange[1], 64)
36+
37+
if errUpperBound != nil {
38+
return nil, errors.New("parsing upper bound")
39+
}
40+
41+
numRange = append(numRange, &upperBound)
42+
} else {
43+
numRange = append(numRange, nil)
44+
}
45+
46+
return numRange, nil
47+
}

backend/internal/utils/units.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"regexp"
7+
"strconv"
8+
"strings"
9+
)
10+
11+
const (
12+
DecimalRegex = `[-+]?(\d*\.)?\d+(e[-+]?\d+)?`
13+
Separator = "#"
14+
)
15+
16+
var operationExp = regexp.MustCompile(fmt.Sprintf(`([+\-\/*]{1})(%s)`, DecimalRegex))
17+
18+
type Units struct {
19+
Name string
20+
Operations Operations
21+
}
22+
23+
func ParseUnits(literal string, globalUnits map[string]Operations) (Units, error) { // TODO: puede fallar si no tiene op y no estan en global o si las op que tiene estan mal
24+
if literal == "" {
25+
return Units{
26+
Name: "",
27+
Operations: make(Operations, 0),
28+
}, nil
29+
}
30+
31+
parts := strings.Split(literal, Separator)
32+
33+
if parts[0] == literal { // literal doesn't contain Separator
34+
ops, ok := globalUnits[parts[0]]
35+
36+
if !ok {
37+
return Units{}, fmt.Errorf("units \"%s\" not found in global", parts[0])
38+
}
39+
40+
return Units{
41+
Name: parts[0],
42+
Operations: ops,
43+
}, nil
44+
}
45+
46+
if len(parts) != 2 {
47+
return Units{}, fmt.Errorf("units %v can only have 2 parts", parts)
48+
}
49+
50+
operations, err := NewOperations(parts[1])
51+
52+
if err != nil {
53+
return Units{}, err
54+
}
55+
56+
return Units{
57+
Name: parts[0],
58+
Operations: operations,
59+
}, nil
60+
}
61+
62+
type Operations []Operation
63+
64+
func NewOperations(literal string) (Operations, error) {
65+
if literal == "" {
66+
return make(Operations, 0), nil
67+
}
68+
69+
matches := operationExp.FindAllStringSubmatch(literal, -1)
70+
71+
if matches == nil {
72+
return nil, fmt.Errorf("incorrect operations: %s", literal)
73+
}
74+
75+
operations := make([]Operation, 0)
76+
for _, match := range matches {
77+
operation := getOperation(match[1], match[2])
78+
operations = append(operations, operation)
79+
}
80+
return operations, nil
81+
}
82+
83+
func getOperation(operator string, operand string) Operation {
84+
numOperand, err := strconv.ParseFloat(operand, 64)
85+
if err != nil {
86+
log.Fatalln("units: operations: getOperation:", err)
87+
}
88+
return Operation{
89+
Operator: operator,
90+
Operand: numOperand,
91+
}
92+
}
93+
94+
func (operations Operations) Convert(value float64) float64 {
95+
result := value
96+
for _, op := range operations {
97+
result = op.convert(result)
98+
}
99+
return result
100+
}
101+
102+
func (operations Operations) Revert(value float64) float64 {
103+
result := value
104+
for i := len(operations) - 1; i >= 0; i-- {
105+
result = operations[i].revert(result)
106+
}
107+
return result
108+
}
109+
110+
type Operation struct {
111+
Operator string
112+
Operand float64
113+
}
114+
115+
func (operation Operation) convert(value float64) float64 {
116+
switch operation.Operator {
117+
case "+":
118+
return value + operation.Operand
119+
case "-":
120+
return value - operation.Operand
121+
case "*":
122+
return value * operation.Operand
123+
case "/":
124+
return value / operation.Operand
125+
}
126+
return value
127+
}
128+
129+
func (operation Operation) revert(value float64) float64 {
130+
switch operation.Operator {
131+
case "+":
132+
return value - operation.Operand
133+
case "-":
134+
return value + operation.Operand
135+
case "*":
136+
return value / operation.Operand
137+
case "/":
138+
return value * operation.Operand
139+
}
140+
return value
141+
}

0 commit comments

Comments
 (0)