summaryrefslogtreecommitdiff
path: root/src/examples/romanNumerals.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/romanNumerals.py')
-rw-r--r--src/examples/romanNumerals.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/examples/romanNumerals.py b/src/examples/romanNumerals.py
new file mode 100644
index 0000000..1561ac8
--- /dev/null
+++ b/src/examples/romanNumerals.py
@@ -0,0 +1,77 @@
+# romanNumerals.py
+#
+# Copyright (c) 2006, Paul McGuire
+#
+
+from pyparsing import *
+
+def romanNumeralLiteral(numeralString, value):
+ return Literal(numeralString).setParseAction(replaceWith(value))
+
+one = romanNumeralLiteral("I",1)
+four = romanNumeralLiteral("IV",4)
+five = romanNumeralLiteral("V",5)
+nine = romanNumeralLiteral("IX",9)
+ten = romanNumeralLiteral("X",10)
+forty = romanNumeralLiteral("XL",40)
+fifty = romanNumeralLiteral("L",50)
+ninety = romanNumeralLiteral("XC",90)
+onehundred = romanNumeralLiteral("C",100)
+fourhundred = romanNumeralLiteral("CD",400)
+fivehundred = romanNumeralLiteral("D",500)
+ninehundred = romanNumeralLiteral("CM",900)
+onethousand = romanNumeralLiteral("M",1000)
+
+numeral = ( onethousand | ninehundred | fivehundred | fourhundred |
+ onehundred | ninety | fifty | forty | ten | nine | five |
+ four | one ).leaveWhitespace()
+
+romanNumeral = OneOrMore(numeral).setParseAction( lambda s,l,t : sum(t) )
+
+# unit tests
+def makeRomanNumeral(n):
+ def addDigit(n,limit,c,s):
+ if n >= limit:
+ n -= limit
+ s += c
+ return n,s
+
+ ret = ""
+ while n >= 1000: n,ret = addDigit(n,1000,"M",ret)
+ while n >= 900: n,ret = addDigit(n, 900,"CM",ret)
+ while n >= 500: n,ret = addDigit(n, 500,"D",ret)
+ while n >= 400: n,ret = addDigit(n, 400,"CD",ret)
+ while n >= 100: n,ret = addDigit(n, 100,"C",ret)
+ while n >= 90: n,ret = addDigit(n, 90,"XC",ret)
+ while n >= 50: n,ret = addDigit(n, 50,"L",ret)
+ while n >= 40: n,ret = addDigit(n, 40,"XL",ret)
+ while n >= 10: n,ret = addDigit(n, 10,"X",ret)
+ while n >= 9: n,ret = addDigit(n, 9,"IX",ret)
+ while n >= 5: n,ret = addDigit(n, 5,"V",ret)
+ while n >= 4: n,ret = addDigit(n, 4,"IV",ret)
+ while n >= 1: n,ret = addDigit(n, 1,"I",ret)
+ return ret
+tests = " ".join([makeRomanNumeral(i) for i in range(1,5000+1)])
+
+expected = 1
+for t,s,e in romanNumeral.scanString(tests):
+ if t[0] != expected:
+ print "==>",
+ print t,tests[s:e]
+ expected += 1
+print
+
+def test(rn):
+ print rn,romanNumeral.parseString(rn)
+test("XVI")
+test("XXXIX")
+test("XIV")
+test("XIX")
+test("MCMLXXX")
+test("MMVI")
+
+
+
+
+
+