diff --git a/.gitignore b/.gitignore index c3530eab7..dcee5d692 100644 --- a/.gitignore +++ b/.gitignore @@ -118,3 +118,4 @@ ENV/ .idea eos.iml gitversion +*.swp diff --git a/gui/characterEditor.py b/gui/characterEditor.py index 4a02d5994..626e705ad 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -38,9 +38,21 @@ from logbook import Logger from gui.utils.clipboard import toClipboard, fromClipboard +import utils.roman as roman +import re + pyfalog = Logger(__name__) +def arabicOrRomanToInt(s): + m = re.match(r'\d+$', s) + if m: + i = int(s) + else: + i = roman.fromRoman(s) + return i + + class CharacterTextValidor(BaseValidator): def __init__(self): BaseValidator.__init__(self) @@ -407,7 +419,8 @@ class SkillTreeView(wx.Panel): lines = text.splitlines() for l in lines: - skill, level = l.strip()[:-1].strip(), int(l.strip()[-1]) + s = l.strip() + skill, level = s.rsplit(None, 1)[0], arabicOrRomanToInt(s.rsplit(None, 1)[1]) skill = char.getSkill(skill) if skill: skill.setLevel(level, ignoreRestrict=True) diff --git a/gui/utils/roman.py b/gui/utils/roman.py new file mode 100644 index 000000000..0a75ccadc --- /dev/null +++ b/gui/utils/roman.py @@ -0,0 +1,95 @@ +"""Convert to and from Roman numerals""" + +__author__ = "Mark Pilgrim (f8dy@diveintopython.org)" +__version__ = "1.4" +__date__ = "8 August 2001" +__copyright__ = """Copyright (c) 2001 Mark Pilgrim + +This program is part of "Dive Into Python", a free Python tutorial for +experienced programmers. Visit http://diveintopython.org/ for the +latest version. + +This program is free software; you can redistribute it and/or modify +it under the terms of the Python 2.1.1 license, available at +http://www.python.org/2.1.1/license.html +""" + +import re + + +# Define exceptions +class RomanError(Exception): + pass + + +class OutOfRangeError(RomanError): + pass + + +class NotIntegerError(RomanError): + pass + + +class InvalidRomanNumeralError(RomanError): + pass + + +# Define digit mapping +romanNumeralMap = (('M', 1000), + ('CM', 900), + ('D', 500), + ('CD', 400), + ('C', 100), + ('XC', 90), + ('L', 50), + ('XL', 40), + ('X', 10), + ('IX', 9), + ('V', 5), + ('IV', 4), + ('I', 1)) + + +def toRoman(n): + """convert integer to Roman numeral""" + if not isinstance(n, int): + raise NotIntegerError("decimals can not be converted") + if not (0 < n < 5000): + raise OutOfRangeError("number out of range (must be 1..4999)") + + result = "" + for numeral, integer in romanNumeralMap: + while n >= integer: + result += numeral + n -= integer + return result + + +# Define pattern to detect valid Roman numerals +romanNumeralPattern = re.compile(""" + ^ # beginning of string + M{0,4} # thousands - 0 to 4 M's + (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), + # or 500-800 (D, followed by 0 to 3 C's) + (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), + # or 50-80 (L, followed by 0 to 3 X's) + (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), + # or 5-8 (V, followed by 0 to 3 I's) + $ # end of string + """, re.VERBOSE) + + +def fromRoman(s): + """convert Roman numeral to integer""" + if not s: + raise InvalidRomanNumeralError('Input can not be blank') + if not romanNumeralPattern.search(s): + raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s) + + result = 0 + index = 0 + for numeral, integer in romanNumeralMap: + while s[index:index + len(numeral)] == numeral: + result += integer + index += len(numeral) + return result