Skip to content

Commit

Permalink
Add a command line tool to use num2words, credits to @hernamesbarbara
Browse files Browse the repository at this point in the history
  • Loading branch information
erozqba committed Sep 16, 2018
1 parent f72c999 commit 62f3cad
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 7 deletions.
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[report]
omit =
*/.tox/*
*/tests/*
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include CHANGES.rst
include COPYING
include tests/*
include bin/num2words
16 changes: 14 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,20 @@ The test suite in this library is new, so it's rather thin, but it can be run wi

Usage
-----

There's only one function to use::
Command line::

$ num2words 10001
ten thousand and one
$ num2words 10123123 --lang es
diez millones ciento veintitrés mil ciento veintitrés
$ num2words 24,120.10
twenty-four thousand, one hundred and twenty point one
$ num2words 24,120.10 -l es
veinticuatro mil ciento veinte punto uno
$num2words 2.14 -l es --to currency
dos euros con catorce centimos

In code there's only one function to use::

>>> from num2words import num2words
>>> num2words(42)
Expand Down
81 changes: 81 additions & 0 deletions bin/num2words
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""num2words: convert numbers into words.
Usage:
num2words [options] <number>
num2words --list-languages
num2words --list-converters
num2words --help
Arguments:
<number> Number you want to convert into words
Options:
-L --list-languages Show all languages.
-C --list-converters Show all converters.
-l --lang=<lang> Output language [default: en].
-t --to=<to> Output converter [default: cardinal].
-h --help Show this message.
-v --version Show version.
Examples:
$ num2words 10001
ten thousand and one
$ num2words 10123123 --lang es
diez millones ciento veintitrés mil ciento veintitrés
$ num2words 24,120.10
twenty-four thousand, one hundred and twenty point one
$ num2words 24,120.10 -l es
veinticuatro mil ciento veinte punto uno
$num2words 2.14 -l es --to currency
dos euros con catorce centimos
"""
from __future__ import print_function, unicode_literals
import os
import sys
from docopt import docopt
import num2words

__version__ = "0.5.7"
__license__ = "LGPL"


def get_languages():
return sorted(list(num2words.CONVERTER_CLASSES.keys()))


def get_converters():
return sorted(list(num2words.CONVERTES_TYPES))


def main():
version = "{}=={}".format(os.path.basename(__file__), __version__)
args = docopt(__doc__, argv=None, help=True, version=version, options_first=False)
if args["--list-languages"]:
for lang in get_languages():
sys.stdout.write(lang)
sys.stdout.write(os.linesep)
sys.exit(0)
if args["--list-converters"]:
for lang in get_converters():
sys.stdout.write(lang)
sys.stdout.write(os.linesep)
sys.exit(0)
try:
words = num2words.num2words(args['<number>'], lang=args['--lang'], to=args['--to'])
sys.stdout.write(words+os.linesep)
sys.exit(0)
except Exception as err:
sys.stderr.write(str(args['<number>']))
sys.stderr.write(str(err) + os.linesep)
sys.stderr.write(__doc__)
sys.exit(1)


if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ isort
pep8<1.6
coverage
coveralls

delegator.py
28 changes: 26 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import re

from setuptools import find_packages, setup

PACKAGE_NAME = "num2words"

CLASSIFIERS = [
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
Expand All @@ -16,9 +20,27 @@
LONG_DESC = open('README.rst', 'rt').read() + '\n\n' + \
open('CHANGES.rst', 'rt').read()


def find_version(fname):
"""Parse file & return version number matching 0.0.1 regex
Returns str or raises RuntimeError
"""
version = ''
with open(fname, 'r') as fp:
reg = re.compile(r'__version__ = [\'"]([^\'"]*)[\'"]')
for line in fp:
m = reg.match(line)
if m:
version = m.group(1)
break
if not version:
raise RuntimeError('Cannot find version information')
return version


setup(
name='num2words',
version='0.5.7',
name=PACKAGE_NAME,
version=find_version("bin/num2words"),
description='Modules to convert numbers to words. Easily extensible.',
long_description=LONG_DESC,
license='LGPL',
Expand All @@ -33,4 +55,6 @@
packages=find_packages(exclude=['tests']),
test_suite='tests',
classifiers=CLASSIFIERS,
scripts=['bin/num2words'],
install_requires=["docopt>=0.6.2"]
)
96 changes: 96 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

import os
import unittest

import delegator
import num2words


class CliCaller(object):

def __init__(self):
self.cmd = os.path.realpath(os.path.join(os.path.dirname(__file__),
"..", "bin", "num2words"))
self.cmd_list = ["python", self.cmd]

def run_cmd(self, *args):
cmd_list = self.cmd_list + [str(arg) for arg in args]
cmd = " ".join(cmd_list)
return delegator.run(cmd)


class CliTestCase(unittest.TestCase):
"""Test the command line app"""

def setUp(self):
self.cli = CliCaller()

def test_cli_help(self):
"""num2words without arguments should exit with status 1
and show docopt's default short usage message
"""
output = self.cli.run_cmd()
self.assertEqual(output.return_code, 1)
self.assertTrue(output.err.startswith('Usage:'))

def test_cli_list_langs(self):
"""You should be able to list all availabe languages
"""
output = self.cli.run_cmd('--list-languages')
self.assertEqual(
sorted(list(num2words.CONVERTER_CLASSES.keys())),
output.out.strip().split(os.linesep)
)
output = self.cli.run_cmd('-L')
self.assertEqual(
sorted(list(num2words.CONVERTER_CLASSES.keys())),
output.out.strip().split(os.linesep)
)

def test_cli_list_converters(self):
"""You should be able to list all available converters
"""
output = self.cli.run_cmd('--list-converters')
self.assertEqual(
sorted(list(num2words.CONVERTES_TYPES)),
output.out.strip().split(os.linesep)
)
output = self.cli.run_cmd('-C')
self.assertEqual(
sorted(list(num2words.CONVERTES_TYPES)),
output.out.strip().split(os.linesep)
)

def test_cli_default_lang(self):
"""Default to english
"""
output = self.cli.run_cmd(150)
self.assertEqual(output.return_code, 0)
self.assertEqual(
output.out.strip(),
"one hundred and fifty point zero"
)

def test_cli_with_lang(self):
"""You should be able to specify a language
"""
output = self.cli.run_cmd(150, '--lang', 'es')
self.assertEqual(output.return_code, 0)
self.assertEqual(
output.out.strip(),
"ciento cincuenta punto cero"
)

def test_cli_with_lang_to(self):
"""You should be able to specify a language
"""
output = self.cli.run_cmd(150.55, '--lang', 'es', '--to', 'currency')
self.assertEqual(output.return_code, 0)
self.assertEqual(
output.out.strip(),
"ciento cincuenta euros con cincuenta y cinco centimos"
)
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = flake8, isort, py27,py34,py35,py36
envlist = flake8,isort,py27,py34,py35,py36

[testenv]
passenv = TRAVIS TRAVIS_*
Expand All @@ -10,6 +10,6 @@ commands =
isort --check-only --recursive --diff num2words tests
coverage erase
coverage run -m unittest discover
coverage report --fail-under=75 --omit=.tox/*,/usr/*
coverage report --fail-under=75 --omit=.tox/*,tests/*,/usr/*
coveralls

0 comments on commit 62f3cad

Please sign in to comment.