Skip to content

Commit

Permalink
new parse_fraction function for simple fractions added with test data (
Browse files Browse the repository at this point in the history
…#60)

* new parse_fraction function for simple fractions added with test data

* usage of fractional number in readme mentioned

* usage of fractional number (a correction) in readme mentioned

* valueError in other languages removed

* changing README bullets and paragraph

adding bullets in readme and changing introductory paragraph

* update README renaming sections

* formatting of line changed

* extension of inline headers removed

* minor wordings in README

* pep8 guidelines and readability of code

* new line after top-level function PEP8 guidelines
  • Loading branch information
Manish-210 authored Mar 24, 2021
1 parent 18aa853 commit c834854
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 11 deletions.
30 changes: 21 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ number-parser requires Python 3.6+.
Usage
=====

The library provides three major APIs which corresponds to the following common usages.
The library provides the following common usages.

Interface #1: Multiple numbers
------------------------------
Converting numbers in-place
---------------------------

Identifying the numbers in a text string, converting them to corresponding numeric values while ignoring non-numeric words.
This also supports ordinal number conversion (for English only).
Expand All @@ -36,28 +36,40 @@ This also supports ordinal number conversion (for English only).
>>> parse("First day of year two thousand")
'1 day of year 2000'

Parsing a number
----------------

Interface #2: Single number
--------------------------------
Converting a single number written in words to it's corresponding integer.

>>> from number_parser import parse_number
>>> parse_number("two thousand and twenty")
2020
>>> parse_number("not_a_number")

Parsing an ordinal
------------------

Interface #3: Single number Ordinal
-------------------------------------

Converting a single ordinal number written in words to it's corresponding integer. (Support for only English)
Converting a single ordinal number written in words to its corresponding integer. (Support for English only)

>>> from number_parser import parse_ordinal
>>> parse_ordinal("twenty third")
23
>>> parse_ordinal("seventy fifth")
75

Parsing a fraction
------------------

Converting a fractional number written in words to its corresponding integral fraction. (Support for English only)

>>> from number_parser import parse_fraction
>>> parse_fraction("forty two divided by five hundred and six")
'42/506'
>>> parse_fraction("one over two")
'1/2'
>>> parse_fraction("forty two / one million")
'42/1000000'


Language Support
----------------
Expand Down
2 changes: 1 addition & 1 deletion number_parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from number_parser.parser import parse, parse_number, parse_ordinal
from number_parser.parser import parse, parse_number, parse_ordinal, parse_fraction
30 changes: 30 additions & 0 deletions number_parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,36 @@ def parse_number(input_string, language=None):
return None


def parse_fraction(input_string, language=None):
"""Converts a single number written in fraction to a numeric type"""
if not input_string.strip():
return None

if language is None:
language = _valid_tokens_by_language(input_string)

FRACTION_SEPARATORS = ["divided by", "over", "by", "/"]

for separator in FRACTION_SEPARATORS:
position_of_separator = input_string.find(separator)

if position_of_separator == -1:
continue

string_before_separator = input_string[:position_of_separator]
string_after_separator = input_string[position_of_separator + len(separator):]

number_before_separator = parse_number(string_before_separator, language)
number_after_separator = parse_number(string_after_separator, language)

if number_before_separator is None or number_after_separator is None:
return None

return f'{number_before_separator}/{number_after_separator}'

return None


def parse(input_string, language=None):
"""
Converts all the numbers in a sentence written in natural language to their numeric type while keeping
Expand Down
29 changes: 28 additions & 1 deletion tests/test_number_parsing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from number_parser import parse, parse_number
from number_parser import parse, parse_number, parse_fraction
from number_parser.parser import LanguageData, parse_ordinal


Expand Down Expand Up @@ -121,6 +121,33 @@ def test_parse_sentences_ordinal(expected, test_input, lang):
assert parse(test_input, lang) == expected



@pytest.mark.parametrize(
"test_input,expected,lang",
[
# empty / not-a-number
('', None, None),
('example of sentence', None, None),
# numeric
('32', None, None),
(' 3 ', None, None),
# en
('eleven', None, 'en'),
('one hundred and forty two by a sentence', None, 'en'),
('sentence / eleven', None, 'en'),
('one hundred and forty two by eleven', '142/11', 'en'),
('one hundred and forty two divided by eleven', '142/11', 'en'),
('one hundred and forty two / eleven', '142/11', 'en'),
('one hundred and forty two over eleven', '142/11', 'en'),
('two million three thousand and nineteen/two thousand and nineteen', '2003019/2019', 'en'),
('billion over nineteen billion and nineteen', '1000000000/19000000019', 'en'),
]
)
def test_parse_fraction(expected, test_input, lang):
assert parse_fraction(test_input, language=lang) == expected


def test_LanguageData_unsupported_language():
with pytest.raises(ValueError):
LanguageData('xxxx')

0 comments on commit c834854

Please sign in to comment.