From f2778dbd57552317b5d9e9d3742f7248ad3f2b36 Mon Sep 17 00:00:00 2001 From: LambrosKolovos Date: Thu, 1 Oct 2020 19:00:34 +0300 Subject: [PATCH 1/3] Added base number category --- .../unitconverterultimate/MainActivity.java | 5 + .../fragments/ConversionFragment.java | 4 + .../models/BaseNumberUnit.java | 17 +++ .../models/Conversion.java | 3 +- .../unitconverterultimate/models/Unit.java | 9 +- .../presenters/ConversionPresenter.java | 134 ++++++++++++++++++ .../presenters/ConversionView.java | 1 + .../util/Conversions.java | 15 ++ .../main/res/menu/menu_navigation_drawer.xml | 5 + app/src/main/res/values/strings.xml | 10 ++ 10 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/physphil/android/unitconverterultimate/models/BaseNumberUnit.java diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/MainActivity.java b/app/src/main/java/com/physphil/android/unitconverterultimate/MainActivity.java index 65138cc8..b36741e5 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/MainActivity.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/MainActivity.java @@ -187,6 +187,9 @@ private int getConversionFromDrawer(int itemId) { case R.id.drawer_volume: return Conversion.VOLUME; + + case R.id.base_numbers: + return Conversion.BASE; } return Conversion.AREA; @@ -224,6 +227,8 @@ private int getMenuPositionOfConversion(@Conversion.id final int conversion) { return 13; case Conversion.VOLUME: return 14; + case R.id.base_numbers: + return 15; default: return 0; } diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/fragments/ConversionFragment.java b/app/src/main/java/com/physphil/android/unitconverterultimate/fragments/ConversionFragment.java index 4bceb9ce..8f4d6e28 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/fragments/ConversionFragment.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/fragments/ConversionFragment.java @@ -259,6 +259,10 @@ private void convert() { double value = isNumeric(input) ? Double.parseDouble(input) : 0; switch (mConversionId) { + case Conversion.BASE: + mPresenter.convertBaseNumber(value, getCheckedUnit(mGrpFrom), getCheckedUnit(mGrpTo)); + break; + case Conversion.TEMPERATURE: mPresenter.convertTemperatureValue(value, getCheckedUnit(mGrpFrom), getCheckedUnit(mGrpTo)); break; diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/models/BaseNumberUnit.java b/app/src/main/java/com/physphil/android/unitconverterultimate/models/BaseNumberUnit.java new file mode 100644 index 00000000..e6b974b8 --- /dev/null +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/models/BaseNumberUnit.java @@ -0,0 +1,17 @@ +package com.physphil.android.unitconverterultimate.models; + +public class BaseNumberUnit extends Unit{ + + /** + * Create a unit object + * + * @param id id of the unit + * @param labelResource string resource id of the label + */ + public BaseNumberUnit(int id, int labelResource) { + + //Need custom function to convert + super(id, labelResource, 0.0, 0.0); + + } +} diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/models/Conversion.java b/app/src/main/java/com/physphil/android/unitconverterultimate/models/Conversion.java index d71a12b2..6e372ec2 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/models/Conversion.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/models/Conversion.java @@ -43,13 +43,14 @@ public final class Conversion { public static final int TIME = 11; public static final int TORQUE = 12; public static final int VOLUME = 13; + public static final int BASE = 15; private int id; private int labelResource; private List units; @IntDef({AREA, COOKING, CURRENCY, STORAGE, ENERGY, FUEL, LENGTH, MASS, POWER, PRESSURE, SPEED, - TEMPERATURE, TIME, TORQUE, VOLUME}) + TEMPERATURE, TIME, TORQUE, VOLUME, BASE}) public @interface id { } diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/models/Unit.java b/app/src/main/java/com/physphil/android/unitconverterultimate/models/Unit.java index b39580b4..e128f547 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/models/Unit.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/models/Unit.java @@ -190,6 +190,12 @@ public class Unit { public static final int CUBIC_FOOT = 1218; public static final int CUBIC_YARD = 1219; + public static final int BINARY = 1501; + public static final int DECIMAL = 1502; + public static final int OCTAL = 1503; + public static final int HEXADECIMAL = 1504; + + @IntDef({SQ_KILOMETRES, SQ_METRES, SQ_CENTIMETRES, HECTARE, SQ_MILE, SQ_YARD, SQ_FOOT, SQ_INCH, ACRE, AUD, BGN, BRL, CDN, CHF, CNY, CZK, DKK, EUR, GBP, HKD, HRK, HUF, IDR, ILS, INR, ISK, JPY, KRW, MXN, MYR, NOK, NZD, PHP, PLN, RON, RUB, SEK, SGD, THB, LIRA, USD, ZAR, BIT, BYTE, KILOBIT, KILOBYTE, MEGABIT, MEGABYTE, GIGABIT, GIGABYTE, TERABIT, TERABYTE, @@ -204,7 +210,8 @@ public class Unit { YEAR, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, MILLISECOND, NANOSECOND, N_M, TEASPOON, TABLESPOON, CUP, FLUID_OUNCE, QUART, PINT, GALLON, BARREL, FLUID_OUNCE_UK, QUART_UK, PINT_UK, - GALLON_UK, BARREL_UK, MILLILITRE, LITRE, CUBIC_CM, CUBIC_M, CUBIC_INCH, CUBIC_FOOT, CUBIC_YARD}) + GALLON_UK, BARREL_UK, MILLILITRE, LITRE, CUBIC_CM, CUBIC_M, CUBIC_INCH, CUBIC_FOOT, CUBIC_YARD, + BINARY, DECIMAL, OCTAL, HEXADECIMAL}) public @interface id {} private int id; diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java index d6cd743d..d708839a 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java @@ -150,6 +150,140 @@ public void onGetUnitsToDisplay(@Conversion.id int conversionId) { } } + + /** + * Convert a number from a base to another + * + * @param value the value to convert + * @param from the base to be converted from + * @param to the base to be converted to + */ + + + //Handle conversion from selected Base + public void convertBaseNumber(double value, Unit from, Unit to){ + double result = value; + if (from.getId() != to.getId()) { + switch (to.getId()) { + + case (Unit.BINARY): + result = toBinary(from.getId(), value); + break; + + case(Unit.OCTAL): + result = toOctal(from.getId(), value); + break; + + case(Unit.DECIMAL): + result = toDecimal(from.getId(), value); + break; + + } + } + mView.showResult(result); + } + + //Handle conversions to Binary + private double toBinary(int fromId, double value){ + double result = value; + switch (fromId){ + case(Unit.DECIMAL): + result = Double.parseDouble(Integer.toBinaryString((int) value)); + break; + + case(Unit.OCTAL): + if(isOctal((int) value)) + result = Double.parseDouble(Integer.toBinaryString((int) value)); + else{ + mView.showToast(R.string.toast_error_not_octal); + return 0; + } + break; + } + return result; + } + + //Handle conversions to Decimal + private double toDecimal(int fromId, double value){ + double result = value; + switch (fromId){ + case(Unit.BINARY): + binToDecimal((int) value); + break; + + case(Unit.OCTAL): + octToDecimal((int) value); + break; + } + return result; + + } + + //Handle conversions to Hex + private double toOctal(int fromId, double value){ + double result = value; + switch (fromId){ + case(Unit.DECIMAL): + result = Double.parseDouble(Integer.toOctalString((int) value)); + break; + + case(Unit.BINARY): + double temp = binToDecimal((int) value); + result = Double.parseDouble(Integer.toOctalString((int) temp)); + break; + } + return result; + } + + + //Convert from Binary to Decimal + private double binToDecimal(int binaryNum){ + String valueString = String.valueOf(binaryNum); + + if(isBinary(binaryNum)){ + double result = Integer.parseInt(valueString, 2); + return result; + } + else{ + mView.showToast(R.string.toast_error_not_binary); + return 0; + } + } + + //Convert from Octal to Decimal + private double octToDecimal(int binaryNum){ + String valueString = String.valueOf(binaryNum); + + if(isOctal(binaryNum)){ + double result = Integer.parseInt(valueString, 8); + return result; + } + else{ + mView.showToast(R.string.toast_error_not_octal); + return 0; + } + } + + //Check if given number is Octal + private static boolean isOctal(int num){ + return String.valueOf(num).matches("^[1-7][0-7]*$"); + } + + //Check if given number is Binary base + private static boolean isBinary(int num) { + if (num == 0 || num == 1 || num < 0) { + return false; + } + while (num != 0) { + if (num % 10 > 1) { + return false; + } + num = num / 10; + } + return true; + } + + /** * Convert a temperature value from one unit to another * diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java index 826c6eee..ab380a82 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java @@ -32,6 +32,7 @@ public interface ConversionView { void showLoadingError(int message); void restoreConversionState(final ConversionState state); void showResult(double result); + void showResultHex(String hex); void updateCurrencyConversion(); void showToast(int message); void showToastError(int message); diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/util/Conversions.java b/app/src/main/java/com/physphil/android/unitconverterultimate/util/Conversions.java index ef70b16a..d155105b 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/util/Conversions.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/util/Conversions.java @@ -22,6 +22,7 @@ import com.physphil.android.unitconverterultimate.R; import com.physphil.android.unitconverterultimate.api.models.Country; import com.physphil.android.unitconverterultimate.api.models.Currencies; +import com.physphil.android.unitconverterultimate.models.BaseNumberUnit; import com.physphil.android.unitconverterultimate.models.Conversion; import com.physphil.android.unitconverterultimate.models.TemperatureUnit; import com.physphil.android.unitconverterultimate.models.Unit; @@ -71,6 +72,7 @@ private Conversions() { getTimeConversions(); getTorqueConversions(); getVolumeConversions(); + getBaseConversions(); mCurrencyUpdated = false; } @@ -362,6 +364,19 @@ private void getVolumeConversions() { addConversion(Conversion.VOLUME, new Conversion(Conversion.VOLUME, R.string.volume, units)); } + private void getBaseConversions() { + List units = new ArrayList<>(); + + units.add(new BaseNumberUnit(BINARY, R.string.binary)); + units.add(new BaseNumberUnit(OCTAL, R.string.octal)); + units.add(new BaseNumberUnit(DECIMAL, R.string.decimal)); + units.add(new BaseNumberUnit(HEXADECIMAL, R.string.hexadecimal)); + + addConversion(Conversion.BASE, new Conversion(Conversion.BASE, R.string.baseNum, units)); + } + + + public boolean hasCurrency() { return mConversions.get(Conversion.CURRENCY).getUnits().size() > 0; } diff --git a/app/src/main/res/menu/menu_navigation_drawer.xml b/app/src/main/res/menu/menu_navigation_drawer.xml index 9675ea53..45d1a264 100644 --- a/app/src/main/res/menu/menu_navigation_drawer.xml +++ b/app/src/main/res/menu/menu_navigation_drawer.xml @@ -95,6 +95,11 @@ android:icon="@drawable/ic_volume" android:title="@string/volume"/> + + Text copied to clipboard Currency conversions updated There was an error updating the currency conversions. + Given number is not binary + Given number is not octal Formatting Set the number of decimal places to be shown in converted value @@ -105,6 +107,13 @@ Time Torque Volume + Base Numbers + + + Binary + Decimal + Octal + Hexadecimal Sq Kilometre @@ -285,6 +294,7 @@ American Dollar South African Rand + Acknowledgements From 5054f2e73118523c60fe879973e4bd555f3b0545 Mon Sep 17 00:00:00 2001 From: LambrosKolovos Date: Mon, 5 Oct 2020 17:36:16 +0300 Subject: [PATCH 2/3] Fixed some issues --- .../presenters/ConversionPresenter.java | 44 ++++++++++++------- .../presenters/ConversionView.java | 1 - app/src/main/res/values/strings.xml | 1 + 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java index d708839a..1c635a39 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionPresenter.java @@ -159,13 +159,28 @@ public void onGetUnitsToDisplay(@Conversion.id int conversionId) { * @param to the base to be converted to */ - - //Handle conversion from selected Base public void convertBaseNumber(double value, Unit from, Unit to){ double result = value; + if(from.getId() == Unit.BINARY) { + if(!isBinary((int) value)) { + mView.showToast(R.string.toast_error_not_binary); + return; + } + } + + if(from.getId() == Unit.OCTAL){ + if(!isOctal((int) value)) { + mView.showToast(R.string.toast_error_not_octal); + return; + } + } + + if(from.getId() == Unit.HEXADECIMAL){ + mView.showToast(R.string.toast_error_hex_coming_soon); + } + if (from.getId() != to.getId()) { switch (to.getId()) { - case (Unit.BINARY): result = toBinary(from.getId(), value); break; @@ -186,18 +201,15 @@ public void convertBaseNumber(double value, Unit from, Unit to){ //Handle conversions to Binary private double toBinary(int fromId, double value){ double result = value; + double temp; switch (fromId){ case(Unit.DECIMAL): result = Double.parseDouble(Integer.toBinaryString((int) value)); break; case(Unit.OCTAL): - if(isOctal((int) value)) - result = Double.parseDouble(Integer.toBinaryString((int) value)); - else{ - mView.showToast(R.string.toast_error_not_octal); - return 0; - } + temp = octToDecimal((int) value); + result = Double.parseDouble(Integer.toBinaryString((int) temp)); break; } return result; @@ -206,13 +218,14 @@ private double toBinary(int fromId, double value){ //Handle conversions to Decimal private double toDecimal(int fromId, double value){ double result = value; + String valueString = String.valueOf((int)value); switch (fromId){ case(Unit.BINARY): - binToDecimal((int) value); + result = Integer.parseInt(valueString, 2); break; case(Unit.OCTAL): - octToDecimal((int) value); + result = Integer.parseInt(valueString, 8); break; } return result; @@ -235,7 +248,6 @@ private double toOctal(int fromId, double value){ return result; } - //Convert from Binary to Decimal private double binToDecimal(int binaryNum){ String valueString = String.valueOf(binaryNum); @@ -251,10 +263,10 @@ private double binToDecimal(int binaryNum){ } //Convert from Octal to Decimal - private double octToDecimal(int binaryNum){ - String valueString = String.valueOf(binaryNum); + private double octToDecimal(int octalNum){ + String valueString = String.valueOf(octalNum); - if(isOctal(binaryNum)){ + if(isOctal(octalNum)){ double result = Integer.parseInt(valueString, 8); return result; } @@ -271,7 +283,7 @@ private static boolean isOctal(int num){ //Check if given number is Binary base private static boolean isBinary(int num) { - if (num == 0 || num == 1 || num < 0) { + if (num == 0 || num < 0) { return false; } while (num != 0) { diff --git a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java index ab380a82..826c6eee 100644 --- a/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java +++ b/app/src/main/java/com/physphil/android/unitconverterultimate/presenters/ConversionView.java @@ -32,7 +32,6 @@ public interface ConversionView { void showLoadingError(int message); void restoreConversionState(final ConversionState state); void showResult(double result); - void showResultHex(String hex); void updateCurrencyConversion(); void showToast(int message); void showToastError(int message); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c55ae9f5..fb8189ab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ There was an error updating the currency conversions. Given number is not binary Given number is not octal + Hexadecimal coming soon! Formatting Set the number of decimal places to be shown in converted value From 136c9bccfc143c4560e2f18ff5b0d8e95595118f Mon Sep 17 00:00:00 2001 From: LambrosKolovos Date: Mon, 5 Oct 2020 19:07:45 +0300 Subject: [PATCH 3/3] Added some tests --- .../test/ConversionTests.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/src/test/java/com/physphil/android/unitconverterultimate/test/ConversionTests.java b/app/src/test/java/com/physphil/android/unitconverterultimate/test/ConversionTests.java index 748a91b7..e3367982 100644 --- a/app/src/test/java/com/physphil/android/unitconverterultimate/test/ConversionTests.java +++ b/app/src/test/java/com/physphil/android/unitconverterultimate/test/ConversionTests.java @@ -396,4 +396,27 @@ public void testVolume() mPresenter.convert(5.5, volume.getUnitById(CUBIC_YARD), volume.getUnitById(TEASPOON)); verify(view, atLeastOnce()).showResult(AdditionalMatchers.eq(853138.298312504, DELTA_9)); } + + @Test + public void testBinary() + { + Conversion basenumbers = mConversions.getById(Conversion.BASE); + + mPresenter.convertBaseNumber(11.0, basenumbers.getUnitById(BINARY), basenumbers.getUnitById(DECIMAL)); + verify(view, atLeastOnce()).showResult(eq(3)); + + mPresenter.convertBaseNumber(11.0, basenumbers.getUnitById(BINARY), basenumbers.getUnitById(OCTAL)); + verify(view, atLeastOnce()).showResult(eq(5)); + + mPresenter.convertBaseNumber(6, basenumbers.getUnitById(DECIMAL), basenumbers.getUnitById(BINARY)); + verify(view, atLeastOnce()).showResult(eq(110)); + + mPresenter.convertBaseNumber(15, basenumbers.getUnitById(DECIMAL), basenumbers.getUnitById(BINARY)); + verify(view, atLeastOnce()).showResult(eq(17)); + + mPresenter.convertBaseNumber(12, basenumbers.getUnitById(OCTAL), basenumbers.getUnitById(DECIMAL)); + verify(view, atLeastOnce()).showResult(eq(10)); + + + } } \ No newline at end of file