diff options
author | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2024-08-16 18:09:12 -0500 |
---|---|---|
committer | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2024-08-22 11:45:36 -0500 |
commit | b528bb32fbf3a69b57a98fedefb7656b0569f637 (patch) | |
tree | 0e4a43aa1f25c5e64e1c4655da0ab5642057e111 /src/main/java/sevenUnitsGUI/Presenter.java | |
parent | e74668b91c247e7395362e8e411c3e1a13ec10d1 (diff) |
Add named unit sets to unit converter
Diffstat (limited to 'src/main/java/sevenUnitsGUI/Presenter.java')
-rw-r--r-- | src/main/java/sevenUnitsGUI/Presenter.java | 122 |
1 files changed, 86 insertions, 36 deletions
diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java index 8f99649..4512e01 100644 --- a/src/main/java/sevenUnitsGUI/Presenter.java +++ b/src/main/java/sevenUnitsGUI/Presenter.java @@ -46,6 +46,7 @@ import sevenUnits.unit.UnitDatabase; import sevenUnits.unit.UnitPrefix; import sevenUnits.unit.UnitType; import sevenUnits.unit.UnitValue; +import sevenUnits.utils.NameSymbol; import sevenUnits.utils.Nameable; import sevenUnits.utils.ObjectProduct; import sevenUnits.utils.UncertainDouble; @@ -558,17 +559,13 @@ public final class Presenter { } // convert strings to data, checking if anything is invalid - final Unit fromUnit, toUnit; + final Unit fromUnit; final UncertainDouble uncertainValue; if (this.database.containsUnitName(fromUnitString)) { fromUnit = this.database.getUnit(fromUnitString); } else throw this.viewError("Nonexistent From unit: %s", fromUnitString); - if (this.database.containsUnitName(toUnitString)) { - toUnit = this.database.getUnit(toUnitString); - } else - throw this.viewError("Nonexistent To unit: %s", toUnitString); try { uncertainValue = UncertainDouble .fromRoundedString(inputValueString); @@ -577,38 +574,81 @@ public final class Presenter { "Invalid value " + inputValueString); return; } - + if (this.database.containsUnitName(toUnitString)) { + final Unit toUnit = this.database.getUnit(toUnitString); + ucview.showUnitConversionOutput( + this.convertUnitToUnit(fromUnitString, toUnitString, + inputValueString, fromUnit, toUnit, uncertainValue)); + } else if (this.database.containsUnitSetName(toUnitString)) { + final List<LinearUnit> toMulti = this.database + .getUnitSet(toUnitString); + ucview.showUnitConversionOutput( + this.convertUnitToMulti(fromUnitString, inputValueString, + fromUnit, toMulti, uncertainValue)); + } else + throw this.viewError("Nonexistent To unit: %s", toUnitString); + } else + throw new UnsupportedOperationException( + "This function can only be called when the view is a UnitConversionView."); + } + + private UnitConversionRecord convertUnitToMulti(String fromUnitString, + String inputValueString, Unit fromUnit, List<LinearUnit> toMulti, + UncertainDouble uncertainValue) { + for (final LinearUnit toUnit : toMulti) { if (!fromUnit.canConvertTo(toUnit)) throw this.viewError("Could not convert between %s and %s", fromUnit, toUnit); - - // convert - we will need to erase uncertainty for non-linear units, so - // we need to treat linear and non-linear units differently - final String outputValueString; - if (fromUnit instanceof LinearUnit && toUnit instanceof LinearUnit) { - final LinearUnit fromLinear = (LinearUnit) fromUnit; - final LinearUnit toLinear = (LinearUnit) toUnit; - final LinearUnitValue initialValue = LinearUnitValue.of(fromLinear, - uncertainValue); - final LinearUnitValue converted = initialValue.convertTo(toLinear); - - outputValueString = this.numberDisplayRule - .apply(converted.getValue()); - } else { - final UnitValue initialValue = UnitValue.of(fromUnit, - uncertainValue.value()); - final UnitValue converted = initialValue.convertTo(toUnit); - - outputValueString = this.numberDisplayRule - .apply(UncertainDouble.of(converted.getValue(), 0)); - } + } + + final LinearUnitValue initValue; + if (fromUnit instanceof LinearUnit) { + final var fromLinear = (LinearUnit) fromUnit; + initValue = LinearUnitValue.of(fromLinear, uncertainValue); + } else { + initValue = UnitValue.of(fromUnit, uncertainValue.value()) + .convertToBase(NameSymbol.EMPTY); + } + + final List<LinearUnitValue> converted = initValue + .convertToMultiple(toMulti); + final String toExpression = converted.stream().map( + v -> this.numberDisplayRule.apply(v.getValue()) + " " + v.getUnit()) + .collect(Collectors.joining(" + ")); + return UnitConversionRecord.valueOf(fromUnitString, toExpression, + inputValueString, ""); + + } + + private UnitConversionRecord convertUnitToUnit(String fromUnitString, + String toUnitString, String inputValueString, Unit fromUnit, + Unit toUnit, UncertainDouble uncertainValue) { + if (!fromUnit.canConvertTo(toUnit)) + throw this.viewError("Could not convert between %s and %s", fromUnit, + toUnit); - ucview.showUnitConversionOutput( - UnitConversionRecord.valueOf(fromUnitString, toUnitString, - inputValueString, outputValueString)); - } else - throw new UnsupportedOperationException( - "This function can only be called when the view is a UnitConversionView."); + // convert - we will need to erase uncertainty for non-linear units, so + // we need to treat linear and non-linear units differently + final String outputValueString; + if (fromUnit instanceof LinearUnit && toUnit instanceof LinearUnit) { + final LinearUnit fromLinear = (LinearUnit) fromUnit; + final LinearUnit toLinear = (LinearUnit) toUnit; + final LinearUnitValue initialValue = LinearUnitValue.of(fromLinear, + uncertainValue); + final LinearUnitValue converted = initialValue.convertTo(toLinear); + + outputValueString = this.numberDisplayRule.apply(converted.getValue()); + } else { + final UnitValue initialValue = UnitValue.of(fromUnit, + uncertainValue.value()); + final UnitValue converted = initialValue.convertTo(toUnit); + + outputValueString = this.numberDisplayRule + .apply(UncertainDouble.of(converted.getValue(), 0)); + } + + return UnitConversionRecord.valueOf(fromUnitString, toUnitString, + inputValueString, outputValueString); } /** @@ -770,7 +810,7 @@ public final class Presenter { * @return true iff the One-Way Conversion feature is available (views that * show units as a list will have metric units removed from the From * unit list and imperial/USC units removed from the To unit list) - * + * * @since 2022-03-30 */ public boolean oneWayConversionEnabled() { @@ -994,6 +1034,7 @@ public final class Presenter { .entrySet().stream(); var toUnits = this.database.unitMapPrefixless(this.showDuplicates) .entrySet().stream(); + var unitSets = this.database.unitSetMap().entrySet().stream(); // filter by dimension, if one is selected if (selectedDimensionName.isPresent()) { @@ -1003,6 +1044,8 @@ public final class Presenter { u -> viewDimension.equals(u.getValue().getDimension())); toUnits = toUnits.filter( u -> viewDimension.equals(u.getValue().getDimension())); + unitSets = unitSets.filter(us -> viewDimension + .equals(us.getValue().get(0).getDimension())); } // filter by unit type, if desired @@ -1011,13 +1054,20 @@ public final class Presenter { this::isSemiMetric) != UnitType.METRIC); toUnits = toUnits.filter(u -> UnitType.getType(u.getValue(), this::isSemiMetric) != UnitType.NON_METRIC); + // unit sets are never considered metric + unitSets = unitSets + .filter(us -> this.metricExceptions.contains(us.getKey())); } // set unit names ucview.setFromUnitNames(fromUnits.flatMap(this::applySearchRule) .map(Map.Entry::getKey).collect(Collectors.toSet())); - ucview.setToUnitNames(toUnits.flatMap(this::applySearchRule) - .map(Map.Entry::getKey).collect(Collectors.toSet())); + final var toUnitNames = toUnits.flatMap(this::applySearchRule) + .map(Map.Entry::getKey); + final var unitSetNames = unitSets.map(Map.Entry::getKey); + final var toNames = Stream.concat(toUnitNames, unitSetNames) + .collect(Collectors.toSet()); + ucview.setToUnitNames(toNames); } } |