@@ -0,0 +1,2724 @@
+# imo.py - functions for handling IMO numbers%0A# coding: utf-8%0A#%0A# Copyright (C) 2015 Arthur de Jong%0A#%0A# This library is free software; you can redistribute it and/or%0A# modify it under the terms of the GNU Lesser General Public%0A# License as published by the Free Software Foundation; either%0A# version 2.1 of the License, or (at your option) any later version.%0A#%0A# This library is distributed in the hope that it will be useful,%0A# but WITHOUT ANY WARRANTY; without even the implied warranty of%0A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU%0A# Lesser General Public License for more details.%0A#%0A# You should have received a copy of the GNU Lesser General Public%0A# License along with this library; if not, write to the Free Software%0A# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA%0A# 02110-1301 USA%0A%0A%22%22%22IMO number (International Maritime Organization number).%0A%0AA number used to uniquely identify ships (the hull) for purposes of%0Aregistering owners and management companies. The ship identification number%0Aconsists of a six-digit sequentially assigned number and a check digit. The%0Anumber is usually prefixed with %22IMO%22.%0A%0ANote that there seem to be a large number of ships with an IMO that does not%0Ahave a valid check digit or even have a different length.%0A%0A%3E%3E%3E validate('IMO 9319466')%0A'9319466'%0A%3E%3E%3E validate('IMO 8814275')%0A'8814275'%0A%3E%3E%3E validate('8814274')%0ATraceback (most recent call last):%0A    ...%0AInvalidChecksum: ...%0A%3E%3E%3E format('8814275')%0A'IMO 8814275'%0A%22%22%22%0A%0Afrom stdnum.exceptions import *%0Afrom stdnum.util import clean%0A%0A%0Adef compact(number):%0A    %22%22%22Convert the number to the minimal representation. This strips the%0A    number of any valid separators and removes surrounding whitespace.%22%22%22%0A    number = clean(number, ' ').upper().strip()%0A    if number.startswith('IMO'):%0A        number = number%5B3:%5D%0A    return number%0A%0A%0Adef calc_check_digit(number):%0A    %22%22%22Calculate the check digits for the number.%22%22%22%0A    return str(sum(int(n) * (7 - i) for i, n in enumerate(number%5B:6%5D)) %25 10)%0A%0A%0Adef validate(number):%0A    %22%22%22Checks to see if the number provided is valid. This checks the length%0A    and check digit.%22%22%22%0A    number = compact(number)%0A    if not number.isdigit():%0A        raise InvalidFormat()%0A    if len(number) != 7:%0A        raise InvalidLength()%0A    if calc_check_digit(number%5B:-1%5D) != number%5B-1%5D:%0A        raise InvalidChecksum()%0A    return number%0A%0A%0Adef is_valid(number):%0A    %22%22%22Checks to see if the number provided is valid. This checks the length%0A    and check digit.%22%22%22%0A    try:%0A        return bool(validate(number))%0A    except ValidationError:%0A        return False%0A%0A%0Adef format(number):%0A    %22%22%22Reformat the passed number to the standard format.%22%22%22%0A    return 'IMO ' + compact(number)%0A

Add int. maritime org. number (IMO)