diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2009-03-06 15:07:59 +0100 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2009-03-06 15:07:59 +0100 |
commit | 4b0b859dd1d0884da54d633cf6dec8c5f4d8318f (patch) | |
tree | 1ac7ddcf64eb66e16e818634af865bebdb50a5e4 | |
parent | f2a4f351d61aca1dd24d62a3ec9893f0f3965fc0 (diff) | |
download | pyexiv2-4b0b859dd1d0884da54d633cf6dec8c5f4d8318f.tar.gz |
Conversion of a string to a Rational.
-rw-r--r-- | src/pyexiv2.py | 42 | ||||
-rw-r--r-- | unittest/rational.py | 8 |
2 files changed, 30 insertions, 20 deletions
diff --git a/src/pyexiv2.py b/src/pyexiv2.py index 0241914..4f23757 100644 --- a/src/pyexiv2.py +++ b/src/pyexiv2.py @@ -289,6 +289,8 @@ class Rational(object): A class representing a rational number. """ + _format_re = re.compile(r'(?P<numerator>-?\d+)/(?P<denominator>\d+)') + def __init__(self, numerator, denominator): """ Constructor. @@ -306,6 +308,26 @@ class Rational(object): self.numerator = long(numerator) self.denominator = long(denominator) + @staticmethod + def from_string(string): + """ + Instantiate a Rational from a string formatted as + C{[-]numerator/denominator}. + + @param string: a string representation of a rational number + @type string: C{str} + + @return: the rational number parsed + @rtype: L{Rational} + + @raise ValueError: if the format of the string is invalid + """ + match = Rational._format_re.match(string) + if match is None: + raise ValueError('Invalid format for a rational: %s' % string) + gd = match.groupdict() + return Rational(long(gd['numerator']), long(gd['denominator'])) + def __eq__(self, other): """ Compare two rational numbers for equality. @@ -327,26 +349,6 @@ class Rational(object): """ return '%d/%d' % (self.numerator, self.denominator) -def StringToRational(string): - """ - Try to convert a string containing a rational number to a Rational object. - - Try to convert a string containing a rational number to the corresponding - Rational object. - The conversion is done by matching a regular expression. - If the pattern does not match, the Rational object with numerator=0 and - denominator=1 is returned. - - Keyword arguments: - string -- the string potentially containing a rational number - """ - pattern = re.compile("(-?[0-9]+)/(-?[1-9][0-9]*)") - match = pattern.match(string) - if match == None: - return Rational(0, 1) - else: - return Rational(*map(long, match.groups())) - class MetadataTag(object): diff --git a/unittest/rational.py b/unittest/rational.py index 8ae6d65..f475846 100644 --- a/unittest/rational.py +++ b/unittest/rational.py @@ -36,6 +36,14 @@ class TestRational(unittest.TestCase): self.assertEqual(r.denominator, 1) self.assertRaises(ZeroDivisionError, Rational, 1, 0) + def test_from_string(self): + self.assertEqual(Rational.from_string('4/3'), Rational(4, 3)) + self.assertEqual(Rational.from_string('-4/3'), Rational(-4, 3)) + self.assertRaises(ValueError, Rational.from_string, '+3/5') + self.assertRaises(ValueError, Rational.from_string, '3 / 5') + self.assertRaises(ValueError, Rational.from_string, '3/-5') + self.assertRaises(ValueError, Rational.from_string, 'invalid') + def test_equality(self): r1 = Rational(2, 1) r2 = Rational(2, 1) |