Skip to content

Commit

Permalink
Merge pull request #46 from sidhant92/bigdecimal
Browse files Browse the repository at this point in the history
For Decimal Use BigDecimal
  • Loading branch information
sidhant92 authored Sep 1, 2024
2 parents 0aea20b + a2fe377 commit 1d62964
Show file tree
Hide file tree
Showing 22 changed files with 235 additions and 121 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ The following Data Types are supported:
5. Boolean
6. Semantic Version

---
**NOTE**

Decimal will internally use BigDecimal for storage.

---

Usage examples:

Simple Numerical Comparison
Expand Down
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ dependencies {
implementation 'io.vavr:vavr:0.10.4'
implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3'
implementation 'org.projectlombok:lombok:1.18.26'
implementation 'org.apache.commons:commons-math3:3.6.1'

annotationProcessor 'org.projectlombok:lombok:1.18.26'
testAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.36'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package com.github.sidhant92.boolparser.datatype;

import java.math.BigDecimal;
import java.util.Optional;
import com.github.sidhant92.boolparser.constant.DataType;

/**
* @author sidhant.aggarwal
* @since 05/03/2023
*/
public class DecimalDataType extends AbstractDataType<Double> {
public class DecimalDataType extends AbstractDataType<BigDecimal> {
public DecimalDataType() {
super(Double.class);
super(BigDecimal.class);
}

@Override
Expand All @@ -22,7 +23,7 @@ public boolean isValid(final Object value) {
boolean isValid = super.defaultIsValid(value);
if (!isValid) {
try {
Double.parseDouble(value.toString());
new BigDecimal(value.toString());
return true;
} catch (Exception ex) {
return false;
Expand All @@ -40,13 +41,13 @@ public boolean isValid(final Object value, final boolean useStrictValidation) {
}

@Override
public Optional<Double> getValue(Object value) {
final Optional<Double> result = defaultGetValue(value);
public Optional<BigDecimal> getValue(Object value) {
final Optional<BigDecimal> result = defaultGetValue(value);
if (result.isPresent()) {
return result;
}
try {
return Optional.of(Double.parseDouble(value.toString()));
return Optional.of(new BigDecimal(value.toString()));
} catch (final Exception ignored) {
}
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Optional;
import java.util.stream.Collectors;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.datatype.DataTypeFactory;
import com.github.sidhant92.boolparser.datatype.DecimalDataType;
import com.github.sidhant92.boolparser.datatype.LongDataType;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;
import com.github.sidhant92.boolparser.util.ValueUtils;

Expand All @@ -19,16 +25,20 @@ public class AvgFunction extends AbstractFunction {
public Object evaluate(final List<EvaluatedNode> items) {
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.DECIMAL))) {
return ValueUtils.caseDouble(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).average().getAsDouble());
final DecimalDataType decimalDataType = (DecimalDataType) DataTypeFactory.getDataType(DataType.DECIMAL);
final List<BigDecimal> itemsConverted = items
.stream()
.map(item -> decimalDataType.getValue(item.getValue()))
.map(Optional::get)
.collect(Collectors.toList());
final BigDecimal sum = itemsConverted
.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
return ValueUtils.castDecimal(sum.divide(new BigDecimal(itemsConverted.size()), 3, RoundingMode.DOWN));
}
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.LONG))) {
return ValueUtils.caseDouble(items
.stream().mapToLong(a -> Long.parseLong(a.getValue().toString())).average().getAsDouble());
}
return ValueUtils.caseDouble(items
.stream().mapToInt(a -> Integer.parseInt(a.getValue().toString())).average().getAsDouble());
final LongDataType longDataType = (LongDataType) DataTypeFactory.getDataType(DataType.LONG);
final long sum = items
.stream().mapToLong(a -> longDataType.getValue(a.getValue()).get()).sum();
return ValueUtils.castDecimal(new BigDecimal(sum).divide(new BigDecimal(items.size()), 2, RoundingMode.UNNECESSARY));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.datatype.DataTypeFactory;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;

/**
Expand All @@ -18,7 +19,7 @@ public class IntFunction extends AbstractFunction {
public Object evaluate(final List<EvaluatedNode> items) {
final EvaluatedNode item = items.get(0);
if (item.getDataType() == DataType.DECIMAL) {
return ((Double) item.getValue()).intValue();
return ((BigDecimal) DataTypeFactory.getDataType(DataType.DECIMAL).getValue(item.getValue()).get()).intValue();
}
if (item.getDataType() == DataType.LONG) {
return ((Long) item.getValue()).intValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Optional;
import java.util.stream.Collectors;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.datatype.DataTypeFactory;
import com.github.sidhant92.boolparser.datatype.DecimalDataType;
import com.github.sidhant92.boolparser.datatype.IntegerDataType;
import com.github.sidhant92.boolparser.datatype.LongDataType;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;
import com.github.sidhant92.boolparser.util.ValueUtils;

Expand All @@ -19,16 +26,25 @@ public class MaxFunction extends AbstractFunction {
public Object evaluate(final List<EvaluatedNode> items) {
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.DECIMAL))) {
return ValueUtils.caseDouble(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).max().getAsDouble());
final DecimalDataType decimalDataType = (DecimalDataType) DataTypeFactory.getDataType(DataType.DECIMAL);
final List<BigDecimal> itemsConverted = items
.stream()
.map(item -> decimalDataType.getValue(item.getValue()))
.map(Optional::get)
.collect(Collectors.toList());
final BigDecimal max = itemsConverted
.stream().max(Comparator.naturalOrder()).get();
return ValueUtils.castDecimal(max);
}
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.LONG))) {
return ValueUtils.caseDouble(items
.stream().mapToLong(a -> Long.parseLong(a.getValue().toString())).max().getAsLong());
final LongDataType longDataType = (LongDataType) DataTypeFactory.getDataType(DataType.LONG);
return ValueUtils.castDecimal(items
.stream().mapToLong(a -> longDataType.getValue(a.getValue()).get()).max().getAsLong());
}
return ValueUtils.caseDouble(items
.stream().mapToInt(a -> Integer.parseInt(a.getValue().toString())).max().getAsInt());
final IntegerDataType integerDataType = (IntegerDataType) DataTypeFactory.getDataType(DataType.INTEGER);
return ValueUtils.castDecimal(items
.stream().mapToInt(a -> integerDataType.getValue(a.getValue()).get()).max().getAsInt());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.math3.stat.StatUtils;
import org.apache.commons.math3.stat.descriptive.moment.Mean;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;
import com.github.sidhant92.boolparser.util.ValueUtils;
import com.github.sidhant92.boolparser.function.FunctionFactory;

/**
* @author sidhant.aggarwal
Expand All @@ -19,9 +16,7 @@
public class MeanFunction extends AbstractFunction {
@Override
public Object evaluate(final List<EvaluatedNode> items) {
final double mean = StatUtils.mean(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).toArray());
return ValueUtils.caseDouble(mean);
return FunctionFactory.getArithmeticFunction(FunctionType.AVG).evaluate(items);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.math3.stat.descriptive.rank.Median;
import java.util.Optional;
import java.util.stream.Collectors;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.datatype.DataTypeFactory;
import com.github.sidhant92.boolparser.datatype.DecimalDataType;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;
import com.github.sidhant92.boolparser.util.ValueUtils;

Expand All @@ -16,17 +19,25 @@
* @since 21/05/2024
*/
public class MedianFunction extends AbstractFunction {
private final Median median;

public MedianFunction() {
this.median = new Median();
}

@Override
public Object evaluate(final List<EvaluatedNode> items) {
final double res = median.evaluate(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).toArray());
return ValueUtils.caseDouble(res);
final DecimalDataType decimalDataType = (DecimalDataType) DataTypeFactory.getDataType(DataType.DECIMAL);
final List<BigDecimal> itemsConverted = items
.stream()
.map(item -> decimalDataType.getValue(item.getValue()))
.map(Optional::get)
.collect(Collectors.toList());
Collections.sort(itemsConverted);
if (items.size() % 2 == 0) {
final BigDecimal res = itemsConverted.get(items.size() / 2).add(itemsConverted.get(items.size() / 2 - 1))
.divide(new BigDecimal("2"), 2, BigDecimal.ROUND_DOWN);
return ValueUtils.castDecimal(res);
} else {
return ValueUtils.castDecimal(itemsConverted.get(items.size() / 2));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Optional;
import java.util.stream.Collectors;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
import com.github.sidhant92.boolparser.datatype.DataTypeFactory;
import com.github.sidhant92.boolparser.datatype.DecimalDataType;
import com.github.sidhant92.boolparser.datatype.IntegerDataType;
import com.github.sidhant92.boolparser.datatype.LongDataType;
import com.github.sidhant92.boolparser.domain.EvaluatedNode;
import com.github.sidhant92.boolparser.util.ValueUtils;

Expand All @@ -19,16 +26,25 @@ public class MinFunction extends AbstractFunction {
public Object evaluate(final List<EvaluatedNode> items) {
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.DECIMAL))) {
return ValueUtils.caseDouble(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).min().getAsDouble());
final DecimalDataType decimalDataType = (DecimalDataType) DataTypeFactory.getDataType(DataType.DECIMAL);
final List<BigDecimal> itemsConverted = items
.stream()
.map(item -> decimalDataType.getValue(item.getValue()))
.map(Optional::get)
.collect(Collectors.toList());
final BigDecimal min = itemsConverted
.stream().min(Comparator.naturalOrder()).get();
return ValueUtils.castDecimal(min);
}
if (items
.stream().anyMatch(a -> a.getDataType().equals(DataType.LONG))) {
return ValueUtils.caseDouble(items
.stream().mapToLong(a -> Long.parseLong(a.getValue().toString())).min().getAsLong());
final LongDataType longDataType = (LongDataType) DataTypeFactory.getDataType(DataType.LONG);
return ValueUtils.castDecimal(items
.stream().mapToLong(a -> longDataType.getValue(a.getValue()).get()).min().getAsLong());
}
return ValueUtils.caseDouble(items
.stream().mapToInt(a -> Integer.parseInt(a.getValue().toString())).min().getAsInt());
final IntegerDataType integerDataType = (IntegerDataType) DataTypeFactory.getDataType(DataType.INTEGER);
return ValueUtils.castDecimal(items
.stream().mapToInt(a -> integerDataType.getValue(a.getValue()).get()).min().getAsInt());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.github.sidhant92.boolparser.function.arithmetic;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.math3.stat.StatUtils;
import org.apache.commons.math3.stat.descriptive.moment.Mean;
import java.util.Map;
import com.github.sidhant92.boolparser.constant.ContainerDataType;
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.FunctionType;
Expand All @@ -19,9 +19,34 @@
public class ModeFunction extends AbstractFunction {
@Override
public Object evaluate(final List<EvaluatedNode> items) {
final double mode = StatUtils.mode(items
.stream().mapToDouble(a -> Double.parseDouble(a.getValue().toString())).toArray())[0];
return ValueUtils.caseDouble(mode);
Map<Object, Integer> hm = new HashMap<Object, Integer>();
int max = 1;
Object temp = items.get(0).getValue();

for (int i = 0; i < items.size(); i++) {
final Object value = items.get(i).getValue();

if (hm.get(value) != null) {

int count = hm.get(value);
count++;
hm.put(value, count);

if (count > max) {
max = count;
temp = value;
}
} else {
hm.put(value, 1);
}
}
if (temp instanceof BigDecimal) {
return ValueUtils.castDecimal((BigDecimal) temp);
}
if (temp instanceof Long) {
return ValueUtils.castLong((Long) temp);
}
return temp;
}

@Override
Expand Down
Loading

0 comments on commit 1d62964

Please sign in to comment.