Skip to content

Commit

Permalink
finished first version of unit conversion rule
Browse files Browse the repository at this point in the history
  • Loading branch information
fabrichter authored and danielnaber committed Aug 29, 2018
1 parent 1cc3cd8 commit 4ae1b41
Show file tree
Hide file tree
Showing 17 changed files with 1,450 additions and 328 deletions.

Large diffs are not rendered by default.

Expand Up @@ -22,24 +22,42 @@
package org.languagetool.rules; package org.languagetool.rules;


import org.junit.Test; import org.junit.Test;
import org.languagetool.JLanguageTool;


import static org.hamcrest.core.Is.is; import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*; import static org.junit.Assert.*;


public class AbstractUnitConversionRuleTest { public class AbstractUnitConversionRuleTest {




@Test //@Test
public void convertToMetric() { //public void formatMeasurement() {
assertThat(AbstractUnitConversionRule.convertToMetric("1ft"), is("0.3048m")); // AbstractUnitConversionRule filter = new AbstractUnitConversionRule(JLanguageTool.getMessageBundle()) {
assertThat(AbstractUnitConversionRule.convertToMetric("2ft"), is(2*0.3048+"m")); // @Override
assertThat(AbstractUnitConversionRule.convertToMetric("1m"), is("1m")); // public String getId() {
assertThat(AbstractUnitConversionRule.convertToMetric("100mph"), is("160.9343")); // return null;
try { // }
AbstractUnitConversionRule.convertToMetric("1xyz"); //
fail("Expected IllegalArgumentException to be thrown"); // @Override
} catch(IllegalArgumentException e) { // public String getDescription() {
assertTrue(e.getMessage().contains("Could not parse measurement")); // return null;
} // }
} // };
// assertThat(filter.formatMeasurement("1", "ft"), is("0.3048m"));
// assertThat(filter.formatMeasurement("2", "ft"), is(2*0.3048+"m"));
// assertThat(filter.formatMeasurement("1", "m"), is("1m"));
// assertThat(filter.formatMeasurement("100", "mph"), is("160.9343km/h"));
// try {
// filter.formatMeasurement("1", "xyz");
// fail("Expected IllegalArgumentException to be thrown");
// } catch(IllegalArgumentException e) {
// assertTrue(e.getMessage().contains("Could not parse measurement"));
// }
// try {
// filter.formatMeasurement("foobar", "m");
// fail("Expected IllegalArgumentException to be thrown");
// } catch(NumberFormatException e) {
// assertTrue(e.getMessage().contains("foobar"));
// }
//}
} }
@@ -0,0 +1,65 @@
/*
* LanguageTool, a natural language style checker
* * Copyright (C) 2018 Fabian Richter
* *
* * This library is free software; you can redistribute it and/or
* * modify it under the terms of the GNU Lesser General Public
* * License as published by the Free Software Foundation; either
* * version 2.1 of the License, or (at your option) any later version.
* *
* * This library is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* * Lesser General Public License for more details.
* *
* * You should have received a copy of the GNU Lesser General Public
* * License along with this library; if not, write to the Free Software
* * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* * USA
*
*/

package org.languagetool.rules;

import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.languagetool.JLanguageTool;

import java.io.IOException;
import java.util.Arrays;

public class UnitConversionRuleTestHelper {
private boolean verbose = false;

public UnitConversionRuleTestHelper() {
}
public UnitConversionRuleTestHelper(boolean verbose) {
this.verbose = verbose;
}

public void assertMatches(String input, int expectedMatches, String converted, AbstractUnitConversionRule rule, JLanguageTool lt) throws IOException {
RuleMatch[] matches = rule.match(lt.getAnalyzedSentence(input));
if (verbose) {
System.out.println("----------------------------------------");
System.out.println(input);
for (RuleMatch match : matches) {
System.out.println(match);
System.out.println(match.getSuggestedReplacements());
}
}
Assert.assertThat("Got matches: " + Arrays.toString(matches), matches.length, CoreMatchers.is(expectedMatches));
if (expectedMatches > 0 && converted != null) {
RuleMatch match = matches[0];
boolean suggestionCorrect = false;
String suggestion = null;
for (String s : match.getSuggestedReplacements()) {
if (s.contains(converted)) {
suggestionCorrect = true;
suggestion = s;
break;
}
}
Assert.assertTrue("Suggestion is correct: " + suggestion + " / expected: " + converted, suggestionCorrect);
}
}
}
Expand Up @@ -195,7 +195,8 @@ public List<Rule> getRelevantRules(ResourceBundle messages, UserConfig userConfi
new GermanFillerWordsRule(messages, userConfig), new GermanFillerWordsRule(messages, userConfig),
new GermanParagraphRepeatBeginningRule(messages), new GermanParagraphRepeatBeginningRule(messages),
new PunctuationMarkAtParagraphEnd(messages), new PunctuationMarkAtParagraphEnd(messages),
new DuUpperLowerCaseRule(messages) new DuUpperLowerCaseRule(messages),
new UnitConversionRule(messages)
); );
} }


Expand Down
@@ -0,0 +1,138 @@
/*
* LanguageTool, a natural language style checker
* * Copyright (C) 2018 Fabian Richter
* *
* * This library is free software; you can redistribute it and/or
* * modify it under the terms of the GNU Lesser General Public
* * License as published by the Free Software Foundation; either
* * version 2.1 of the License, or (at your option) any later version.
* *
* * This library is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* * Lesser General Public License for more details.
* *
* * You should have received a copy of the GNU Lesser General Public
* * License along with this library; if not, write to the Free Software
* * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* * USA
*
*/

package org.languagetool.rules.de;

import org.languagetool.rules.AbstractUnitConversionRule;

import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;

import static tech.units.indriya.unit.Units.*;

public class UnitConversionRule extends AbstractUnitConversionRule {

private final NumberFormat format;

public UnitConversionRule(ResourceBundle messages) {
super(messages);
format = NumberFormat.getNumberInstance(Locale.GERMANY);
format.setMaximumFractionDigits(2);
format.setRoundingMode(RoundingMode.HALF_UP);

addUnit("Kilo(gramm)?", KILOGRAM, "Kilogramm", 1, true);
addUnit("Gramm", KILOGRAM, "Gramm", 1e-3, true);
addUnit("Tonnen?", KILOGRAM, "Tonnen", 1e3, true);
addUnit("Pfund", POUND, "Pfund", 1, false);

addUnit("Meilen?", MILE, "Meile", 1, false);
addUnit("Yard", YARD, "Yard", 1, false);
addUnit("Fuß", FEET, "Fuß", 1, false);
addUnit("Zoll", INCH, "Zoll", 1, false);

addUnit("(Kilometer pro Stunde|Stundenkilometer)", KILOMETRE_PER_HOUR, "Kilometer pro Stunde", 1, true);
addUnit("Meilen pro Stunde", MILE.divide(HOUR), "Meilen pro Stunde", 1, false);

addUnit("Meter", METRE, "Meter", 1, true);
addUnit("Kilometer", METRE, "Kilometer", 1e3, true);
addUnit("Dezimeter", METRE, "Dezimeter", 1e-1, false); // metric, but should not be suggested
addUnit("Zentimeter", METRE, "Zentimeter", 1e-2, true);
addUnit("Millimeter", METRE, "Millimeter", 1e-3, true);
addUnit("Mikrometer", METRE, "Mikrometer", 1e-6, true);
addUnit("Nanometer", METRE, "Nanometer", 1e-9, true);
addUnit("Pikometer", METRE, "Pikometer", 1e-12, true);
addUnit("Femtometer", METRE, "Femtometer", 1e-15, true);

addUnit("Quadratmeter", SQUARE_METRE, "Quadratmeter", 1, true);
addUnit("Hektar", SQUARE_METRE, "Hektar", 1e4, true);
addUnit("Ar", SQUARE_METRE, "Ar", 1e2, true);
addUnit("Quadratkilometer", SQUARE_METRE, "Quadratkilometer", 1e6, true);
addUnit("Quadratdezimeter", SQUARE_METRE, "Quadratdezimeter", 1e-2, false/*true*/); // Metric, but not commonly used
addUnit("Quadratzentimeter", SQUARE_METRE, "Quadratzentimeter", 1e-4, true);
addUnit("Quadratmillimeter", SQUARE_METRE, "Quadratmillimeter", 1e-6, true);
addUnit("Quadratmikrometer", SQUARE_METRE, "Quadratmikrometer", 1e-12, true);
addUnit("Quadratnanometer", SQUARE_METRE, "Quadratnanometer", 1e-18, true);

addUnit("Kubikmeter", CUBIC_METRE, "Kubikmeter", 1, true);
addUnit("Kubikkilometer", CUBIC_METRE, "Kubikkilometer", 1e9, true);
addUnit("Kubikdezimeter", CUBIC_METRE, "Kubikdezimeter", 1e-3, false/*true*/); // Metric, but not commonly used
addUnit("Kubikzentimeter", CUBIC_METRE,"Kubikzentimeter", 1e-6, true);
addUnit("Kubikmillimeter", CUBIC_METRE,"Kubikmillimeter", 1e-9, true);
addUnit("Kubikmikrometer", CUBIC_METRE,"Kubikmikrometer", 1e-18, true);
addUnit("Kubiknanometer", CUBIC_METRE, "Kubiknanometer", 1e-27, true);

addUnit("Liter", LITRE, "Liter", 1, true);
addUnit("Milliliter", LITRE, "Milliliter", 1e-3, true);

addUnit( "(?:Grad)? Fahrenheit", FAHRENHEIT, "Grad Fahrenheit", 1, false);
addUnit( "(?:Grad)? Celsius", CELSIUS, "Grad Celsius", 1, true);
}

@Override
public String getId() {
return "EINHEITEN_METRISCH";
}

@Override
public String getDescription() {
return "Schlägt vor oder überprüft Angaben des metrischen Äquivalentes bei bestimmten Maßeinheiten.";
}

@Override
protected String getMessage(Message message) {
switch(message) {
case CHECK:
return "Diese Umrechnung scheint falsch zu sein. Wollen Sie sie automatisch korrigieren lassen?";
case SUGGESTION:
return "Wollen Sie eine Umwandlung ins metrische System automatisch hinzufügen?";
case CHECK_UNKNOWN_UNIT:
return "Die in dieser Umrechnung verwendete Einheit wurde nicht erkannt.";
case UNIT_MISMATCH:
return "Diese Einheiten sind nicht kompatibel.";
default:
throw new RuntimeException("Unknown message type.");
}
}

@Override
protected String getShortMessage(Message message) {
switch(message) {
case CHECK:
return "Falsche Umrechung. Automatisch korrigieren?";
case SUGGESTION:
return "Metrisches Äquivalent hinzufügen?";
case CHECK_UNKNOWN_UNIT:
return "Unbekannte Einheit.";
case UNIT_MISMATCH:
return "Inkompatible Einheiten.";
default:
throw new RuntimeException("Unknown message type.");
}
}

@Override
protected NumberFormat getNumberFormat() {
return format;
}

}
@@ -0,0 +1,70 @@
/*
* LanguageTool, a natural language style checker
* * Copyright (C) 2018 Fabian Richter
* *
* * This library is free software; you can redistribute it and/or
* * modify it under the terms of the GNU Lesser General Public
* * License as published by the Free Software Foundation; either
* * version 2.1 of the License, or (at your option) any later version.
* *
* * This library is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* * Lesser General Public License for more details.
* *
* * You should have received a copy of the GNU Lesser General Public
* * License along with this library; if not, write to the Free Software
* * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* * USA
*
*/

package org.languagetool.rules.de;

import org.junit.Test;
import org.languagetool.JLanguageTool;
import org.languagetool.Language;
import org.languagetool.Languages;
import org.languagetool.rules.AbstractUnitConversionRule;
import org.languagetool.rules.UnitConversionRuleTestHelper;

import java.io.IOException;

public class UnitConversionRuleTest {

/* Still problematic:
Der Weg ist 10 km (20 Meilen) lang.
6'682 Hektar
zahlende Gebühr betrug bis zum 4. Juli 2005 5 Pfund,
7,92 inch = 0,201168 m = 20,1168 cm
Brennwert 210 kJ/100 g (50 kcal/100 g).
69.852 Fuß (über 21 Kilometer)
Als inoffizieller Nachfolger der 64'er
ihre Flughöhe lag bei bis zu 18.000 m (60.000 ft).
5.808,5 km (3.610 Meilen)
3 000 Meilen lang
*/

private final UnitConversionRuleTestHelper unitConversionRuleTestHelper = new UnitConversionRuleTestHelper();

@Test
public void match() throws IOException {
Language lang = Languages.getLanguageForShortCode("de");
JLanguageTool lt = new JLanguageTool(lang);
UnitConversionRule rule = new UnitConversionRule(JLanguageTool.getMessageBundle(lang));
assertMatches("Ich bin 6 Fuß groß.", 1, "1,83 Meter", rule, lt);
assertMatches("Ich bin 6 Fuß (2,02 m) groß.", 1, "1,83 Meter", rule, lt);
assertMatches("Ich bin 6 Fuß (1,82 m) groß.", 0, null, rule, lt);
assertMatches("Der Weg ist 100 Meilen lang.", 1, "160,93 Kilometer", rule, lt);
assertMatches("Der Weg ist 10 km (20 Meilen) lang.", 1, "6,21", rule, lt);
assertMatches("Der Weg ist 10 km (6,21 Meilen) lang.", 0, null, rule, lt);
assertMatches("Der Weg ist 100 Meilen (160,93 Kilometer) lang.", 0, null, rule, lt);
assertMatches("Die Ladung ist 10.000,75 Pfund schwer.", 1, "4,54 Tonnen", rule, lt);
assertMatches("Sie ist 5'6\" groß.", 1, "1,68 m", rule, lt);
assertMatches("Meine neue Wohnung ist 500 sq ft groß.", 1, "46,45 Quadratmeter", rule, lt);
}

private void assertMatches(String input, int expectedMatches, String converted, AbstractUnitConversionRule rule, JLanguageTool lt) throws IOException {
unitConversionRuleTestHelper.assertMatches(input, expectedMatches, converted, rule, lt);
}
}

0 comments on commit 4ae1b41

Please sign in to comment.