From 28546ed30ec452ff5a297d9ded0c721ca7fc312b Mon Sep 17 00:00:00 2001 From: administrator Date: Mon, 28 Aug 2017 19:08:31 -0500 Subject: [PATCH] functionality complete --- src/main/java/strman/NumberFormatOptions.java | 72 ++++++++++++ src/main/java/strman/Strman.java | 109 ++++++++++++++++++ src/test/java/strman/StrmanTests.java | 86 ++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 src/main/java/strman/NumberFormatOptions.java diff --git a/src/main/java/strman/NumberFormatOptions.java b/src/main/java/strman/NumberFormatOptions.java new file mode 100644 index 0000000..0924c9d --- /dev/null +++ b/src/main/java/strman/NumberFormatOptions.java @@ -0,0 +1,72 @@ +package CS342Final.strman; + +/** + * A class designed to hold our different options for formatting numbers + * @author Frank Lubek + * @author Jake Arcivar + */ +public class NumberFormatOptions { + + + + /** + * Options for formatting numbers. + *

precision is the number of digits after the decimal point. + * thousandsSeparator is what is inserted to divide groupings of numbers based + * on certain powers of 10. + * deciamlPoint is what is inserted betweeen integer and non-integer parts of a real number. + */ + private int precision; + private String thousandsSeparator; + private String decimalPoint; + + + /** + * Constructor for our NumberFormatOptions class. + *

Takes the percision we want or how many decimal places, + * the thousands seperator we want ("," or "."), and the decimal point we want. + * + * + * @param prec An int that specifies amount of decimal points + * @param dPoint A Sting that denotes what we use as our decimal point + * @param tSep A String that denotes whether we use commas or periods as seperators + */ + public NumberFormatOptions(int prec, String dPoint, String tSep) { + this.precision = prec; + this.thousandsSeparator = tSep; + this.decimalPoint = dPoint; + } + + public NumberFormatOptions(int prec) { + this.precision = prec; + this.thousandsSeparator = null; + this.decimalPoint = null; + } + + /** + * Gets the precision the number we are formatting will use. + * + * @return int Our precission being used + */ + public int getPrecision() { + return this.precision; + } + + /** + * Gets the thousands seperator the number we are formatting will use + * + * @return String Our thousands seperator being used + */ + public String getSeparator() { + return this.thousandsSeparator; + } + + /** + * Gets the decimal point the number we are formatting will use + * + * @return String Our decimal point being used + */ + public String getDecimalPoint() { + return this.decimalPoint; + } +} diff --git a/src/main/java/strman/Strman.java b/src/main/java/strman/Strman.java index 6598b0b..b8cfb71 100644 --- a/src/main/java/strman/Strman.java +++ b/src/main/java/strman/Strman.java @@ -26,7 +26,9 @@ package strman; +import java.math.BigDecimal; import java.nio.charset.StandardCharsets; +import java.text.DecimalFormat; import java.util.*; import java.util.function.Predicate; import java.util.function.Supplier; @@ -35,6 +37,8 @@ import java.util.stream.IntStream; import java.util.stream.Stream; +import CS342Final.strman.NumberFormatOptions; + import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; @@ -50,6 +54,10 @@ public abstract class Strman { private Strman() { } + + + + /** * Appends Strings to value * @@ -446,6 +454,107 @@ public static String format(final String value, String... params) { return result; } + /** + * Formats the integer part of a number a helper function for format numbers. + * + * @param s A string representation of a number to be formatted and returned as a string + * @return The formatted string + * @author Jake Arcivar, Frank Lubek + */ + public static String formatPrefix(String s) { + String retVal = s; + int length = s.length(); + if (length > 3) { + for (int i = length - 3; i > 0; i -= 3) { + String sub1 = retVal.substring(0, i); + String sub2 = retVal.substring(i); + retVal = sub1 + "," + sub2; + } + return retVal; + } else { + return s; + } + } + + /** + * Formats numbers by adding a separator commas to a whole number + * + * @param number Our number we are formatting + * @return String Our number in string form with separators added + * @author Jake Arcivar, Frank Lubek + */ + public static String formatNumber(double number) { + + String retVal = null; + String numToStr = Double.toString(number); + int splitIndex = numToStr.indexOf('.'); + String end = numToStr.substring(splitIndex + 1); + if (!end.startsWith("0") || end.length() > 1) { + String pre = numToStr.substring(0, splitIndex); + String post = numToStr.substring(splitIndex + 1); + retVal = formatPrefix(pre) + "." + post; + return retVal; + } else { + retVal = formatPrefix(numToStr.substring(0, splitIndex)); + return retVal; + } + } + + /** + * Formats our number using options decided by NumberFormatOptions + * + * @param number Our double that we are formatting + * @param options The options we will use to format our number from the NumberFormatOptions class + * @return String Our thousands seperator being used + * @author Jake Arcivar, Frank Lubek + */ + public static String formatNumber(double number, NumberFormatOptions options) { + + String accumulator = ""; + for (int i = 0; i < options.getPrecision(); ++i) { + accumulator = accumulator.concat("#"); + } + String pattern = "#." + accumulator; + DecimalFormat df = new DecimalFormat(pattern); + String s1 = df.format(number); + String s2 = formatNumber(Double.parseDouble(s1)); + if (s1.length() > 8 && !s1.contains(".")) { + s2 = new BigDecimal(s2).toPlainString(); + String[] x = s2.split(""); + for (int i = (s1.length() - 4); i > 0; i--) { + x[i] = x[i] + ","; + if ((i - 2) > 0 && (i - 1) > 0) { + i = i - 2; + } else { + i = 1; + } + } + s2 = x[0]; + for (int i = 1; i < s1.length(); i++) { + s2 = s2 + x[i]; + } + } + String s3 = s2.replaceAll(",", "+"); + String retVal = s2; + if (options.getSeparator() != null && options.getDecimalPoint() != null) { + String s4 = s3.replace(".", options.getDecimalPoint()); + retVal = s4.replaceAll("\\+", options.getSeparator()); + } + if ((!retVal.contains(".")) && (options.getPrecision() > 0)) { + String acc = "."; + for (int i = 0; i < options.getPrecision(); ++i) { + acc = acc + "0"; + } + retVal = retVal + acc; + // DecimalFormat df2 = new DecimalFormat("0"); + // df2. + } + return retVal; + } + + + + /** * Convert hexadecimal unicode (4 digits) string to string chars * diff --git a/src/test/java/strman/StrmanTests.java b/src/test/java/strman/StrmanTests.java index ae7b88e..2132024 100644 --- a/src/test/java/strman/StrmanTests.java +++ b/src/test/java/strman/StrmanTests.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Optional; +import CS342Final.strman.NumberFormatOptions; import org.junit.Ignore; import org.junit.Test; @@ -373,6 +374,91 @@ public void format_shouldFormatStringsToFooBar() throws Exception { assertThat(format("{1} {0}", "bar", "foo"), equalTo("foo bar")); } + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_noParams1() throws Exception { + double input = 1000; + String correctOutput = "1,000"; + assertThat(formatNumber(input), equalTo(correctOutput)); + } + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_noParams2() throws Exception { + double input = 500000; + String correctOutput = "500,000"; + assertThat(formatNumber(input), equalTo(correctOutput)); + } + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_noParams3() throws Exception { + double input = 1234567; + String correctOutput = "1,234,567"; + assertThat(formatNumber(input), equalTo(correctOutput)); + } + + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_2spacesAfterDecimal1() throws Exception { + double input = 1000; + String correctOutput = "1,000.00"; + assertThat(formatNumber(input, new NumberFormatOptions(2)), equalTo(correctOutput)); + } + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_2spacesAfterDecimal2() throws Exception { + double input = 500000; + String correctOutput = "500,000.00"; + assertThat(formatNumber(input, new NumberFormatOptions(2)), equalTo(correctOutput)); + } + + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_2spacesAfterDecimal3() throws Exception { + double input = 123456789; + String correctOutput = "123,456,789.00"; + assertThat(formatNumber(input, new NumberFormatOptions(2)), equalTo(correctOutput)); + } + + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_rounding1() throws Exception { + double input = 1000.754; + String correctOutput = "1.001"; + assertThat(formatNumber(input, new NumberFormatOptions(0, ",", ".")), equalTo(correctOutput)); + } + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_rounding2() throws Exception { + double input = 1000000.754; + String correctOutput = "1.000.000,75"; + assertThat(formatNumber(input, new NumberFormatOptions(2, ",", ".")), equalTo(correctOutput)); + } + + + @Test + //@Author Jake Arcivar Frank Lubek + public void formatNumber_rounding3() throws Exception { + double input = 1234.56789; + String correctOutput = "1.234,5679"; + assertThat(formatNumber(input, new NumberFormatOptions(4, ",", ".")), equalTo(correctOutput)); + } + + @Test(expected = IllegalArgumentException.class) public void format_shouldThrowExceptionWhenValueDoesNotExist() throws Exception { assertThat(format("{1} {0}"), equalTo("{1} {0}"));