diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52774ee..52a8733 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,13 @@ Changelog
=========
+### [3.5][v3.5] ###
+
+Released 2018-01-12
+
+- Add `DYNAMIC_DECIMALS` setting to expand the number of decimal places until the displayed result is non-zero.
+
+
### [3.4][v3.4] ###
Released 2017-12-27
@@ -160,4 +167,5 @@ Released 2014-08-09.
[v3.3]: https://github.com/deanishe/alfred-convert/releases/tag/v3.3
[v3.3.1]: https://github.com/deanishe/alfred-convert/releases/tag/v3.3.1
[v3.4]: https://github.com/deanishe/alfred-convert/releases/tag/v3.4
+[v3.5]: https://github.com/deanishe/alfred-convert/releases/tag/v3.5
[openx]: https://openexchangerates.org/
\ No newline at end of file
diff --git a/Convert-3.4.alfredworkflow b/Convert-3.5.alfredworkflow
similarity index 85%
rename from Convert-3.4.alfredworkflow
rename to Convert-3.5.alfredworkflow
index 59c9133..4c8c4e0 100644
Binary files a/Convert-3.4.alfredworkflow and b/Convert-3.5.alfredworkflow differ
diff --git a/README.md b/README.md
index 81e1f09..0edf820 100644
--- a/README.md
+++ b/README.md
@@ -90,14 +90,15 @@ The workflow is configured via the configuration sheet (`[𝒙]`) in Alfred Pref
Basic configuration is performed in the configuration sheet:
-| Option | Meaning |
-|-----------------------|----------------------------------------------------------------------------------------------------------|
-| `APP_KEY` | API key for [openexchangerates.org][openx]. |
-| `COPY_UNIT` | Include unit when copying conversion result. Any value but `0` or empty turns this option on. |
-| `DECIMAL_PLACES` | Number of decimal places to show in results. |
-| `DECIMAL_SEPARATOR` | Character to separate whole numbers and decimal fractions. Used for parsing input and generating output. |
-| `THOUSANDS_SEPARATOR` | Character to delimit thousands Used for parsing input and generating output. |
-| `UPDATE_INTERVAL` | How often (in minutes) to update currency exchange rates. |
+| Option | Meaning |
+|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
+| `APP_KEY` | API key for [openexchangerates.org][openx]. |
+| `COPY_UNIT` | Include unit when copying conversion result. Any value but `0` or empty turns this option on. |
+| `DECIMAL_PLACES` | Number of decimal places to show in results. |
+| `DECIMAL_SEPARATOR` | Character to separate whole numbers and decimal fractions. Used for parsing input and generating output. |
+| `DYNAMIC_DECIMALS` | Dynamically increase the number of decimal places (up to 10) so that the result is non-zero. Any value but `0` or empty turns this option on. |
+| `THOUSANDS_SEPARATOR` | Character to delimit thousands Used for parsing input and generating output. |
+| `UPDATE_INTERVAL` | How often (in minutes) to update currency exchange rates. |
#### Active currencies ####
@@ -155,6 +156,8 @@ See [CHANGELOG][changelog] for more information.
| Release | Date |
|-----------------|----------------|
+| [3.5][v3.5] | 2018-01-12 |
+| [3.4][v3.4] | 2017-12-26 |
| [3.3.1][v3.3.1] | 2017-11-21 |
| [3.3][v3.3] | 2017-11-20 |
| [3.2.2][v3.2.2] | 2017-11-07 |
@@ -214,6 +217,8 @@ All other code/media are released under the [MIT Licence][mit].
[v3.2.2]: https://github.com/deanishe/alfred-convert/releases/tag/v3.2.2
[v3.3]: https://github.com/deanishe/alfred-convert/releases/tag/v3.3
[v3.3.1]: https://github.com/deanishe/alfred-convert/releases/tag/v3.3.1
+[v3.4]: https://github.com/deanishe/alfred-convert/releases/tag/v3.4
+[v3.5]: https://github.com/deanishe/alfred-convert/releases/tag/v3.5
[cryptocompare]: https://www.cryptocompare.com/
[openx]: https://openexchangerates.org/
[openx-free]: https://openexchangerates.org/signup/free
diff --git a/src/config.py b/src/config.py
index 50772dc..b7d7949 100644
--- a/src/config.py
+++ b/src/config.py
@@ -26,8 +26,10 @@
DECIMAL_SEPARATOR = os.getenv('DECIMAL_SEPARATOR') or '.'
THOUSANDS_SEPARATOR = os.getenv('THOUSANDS_SEPARATOR') or ''
+DYNAMIC_DECIMALS = os.getenv('DYNAMIC_DECIMALS', '') not in ('', '0')
COPY_UNIT = os.getenv('COPY_UNIT', '') not in ('', '0')
+
# ----------------------------------------------------------------------
# Currency settings
# ----------------------------------------------------------------------
diff --git a/src/convert.py b/src/convert.py
index c0c6580..47d6b2a 100755
--- a/src/convert.py
+++ b/src/convert.py
@@ -31,6 +31,7 @@
DECIMAL_PLACES,
DECIMAL_SEPARATOR,
DEFAULT_SETTINGS,
+ DYNAMIC_DECIMALS,
HELP_URL,
ICON_UPDATE,
NOKEY_FILENAME,
@@ -153,11 +154,55 @@ class Formatter(object):
"""
def __init__(self, decimal_places=2, decimal_separator='.',
- thousands_separator=''):
+ thousands_separator='', dynamic_decimals=True):
"""Create a new `Formatter`."""
self.decimal_places = decimal_places
self.decimal_separator = decimal_separator
self.thousands_separator = thousands_separator
+ self.dynamic_decimals = dynamic_decimals
+
+ def _decimal_places(self, n):
+ """Calculate the number of decimal places the result should have.
+
+ If :attr:`dynamic_decimals` is `True`, increase the number of
+ decimal places until the result is non-zero.
+
+ Args:
+ n (float): Number that will be formatted.
+
+ Returns:
+ int: Number of decimal places for result.
+ """
+ log.debug('DYNAMIC_DECIMALS are %s',
+ ('off', 'on')[self.dynamic_decimals])
+
+ if not self.dynamic_decimals:
+ return self.decimal_places
+
+ m = max(self.decimal_places, 10) + 1
+ p = self.decimal_places
+ while p < m:
+ e = 10 ** p
+ i = n * e
+ # log.debug('n=%f, e=%d, i=%f, p=%d', n, e, i, p)
+ if n * e >= 10:
+ break
+
+ p += 1
+
+ # Remove trailing zeroes
+ s = str(i)
+ if '.' not in s: # not a fraction
+ return p
+
+ s = s.split('.')[-1]
+ # log.debug('s=%s, p=%d', s, p)
+ while s.endswith('0'):
+ s = s[:-1]
+ p -= 1
+ # log.debug('s=%s, p=%d', s, p)
+
+ return p
def formatted(self, n, unit=None):
"""Format number with thousands and decimal separators."""
@@ -165,7 +210,7 @@ def formatted(self, n, unit=None):
if self.thousands_separator:
sep = u','
- fmt = u'{{:0{}.{:d}f}}'.format(sep, self.decimal_places)
+ fmt = u'{{:0{}.{:d}f}}'.format(sep, self._decimal_places(n))
num = fmt.format(n)
# log.debug('n=%r, fmt=%r, num=%r', n, fmt, num)
num = num.replace(',', '||comma||')
@@ -436,27 +481,6 @@ def parse_units(self, query, qty=1):
return from_unit, to_unit
-def format_number(n):
- """Format a floating point number with thousands/decimal separators.
-
- Args:
- n (float): Number to format
-
- """
- sep = ''
- if THOUSANDS_SEPARATOR:
- sep = ','
-
- fmt = '{{:0{}.{:d}f}}'.format(sep, DECIMAL_PLACES)
- num = fmt.format(n)
- # log.debug('n=%r, fmt=%r, num=%r', n, fmt, num)
- num = num.replace(',', '||comma||')
- num = num.replace('.', '||point||')
- num = num.replace('||comma||', THOUSANDS_SEPARATOR)
- num = num.replace('||point||', DECIMAL_SEPARATOR)
- return num
-
-
def register_units():
"""Add built-in and user units to unit registry."""
# Add custom units from workflow and user data
@@ -541,7 +565,8 @@ def convert(query):
valid=False, icon=ICON_WARNING)
else: # Show results
- f = Formatter(DECIMAL_PLACES, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR)
+ f = Formatter(DECIMAL_PLACES, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR,
+ DYNAMIC_DECIMALS)
wf.setvar('query', query)
for conv in results:
value = copytext = f.formatted(conv.to_number, conv.to_unit)
diff --git a/src/info.plist b/src/info.plist
index b41c563..273c7e7 100644
--- a/src/info.plist
+++ b/src/info.plist
@@ -503,6 +503,8 @@ DECIMAL_PLACES is the number of decimal places to show in conversion results.
DECIMAL_SEPARATOR is the character used to separate whole numbers from decimal fraction when parsing and outputting numbers.
+DYNAMIC_DECIMALS is whether to dynamically increase the number of decimal places shown until the result is non-zero. Set to 0 or empty to turn off.
+
THOUSANDS_SEPARATOR is the character used to separate thousands when parsing and outputting numbers.
UPDATE_INTERVAL is the number of minutes between exchange rate updates.
@@ -627,6 +629,8 @@ UPDATE_INTERVAL is the number of minutes between exchange rate updates.
2
DECIMAL_SEPARATOR
.
+ DYNAMIC_DECIMALS
+ 1
THOUSANDS_SEPARATOR
,
UPDATE_INTERVAL
@@ -637,7 +641,7 @@ UPDATE_INTERVAL is the number of minutes between exchange rate updates.
APP_KEY
version
- 3.4
+ 3.5
webaddress