Created
November 6, 2009 00:50
-
-
Save eight/227568 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
"""ISBN(国際標準図書番号)規格改定 | |
http://www.isbn-center.jp/whatsnew/kikaku.html | |
ISBNコードをいろいろするライブラリ。isbnlib.py | |
""" | |
import os,sys | |
#13桁ISBNの接頭文字 | |
ISBN13_PREFIX = ('978','979') | |
#書籍JANの接頭文字(ISBNと同様) | |
JAN_PREFIX_1ST = ISBN13_PREFIX | |
#書籍JAN2段目の接頭文字 | |
JAN_PREFIX_2ND = ('192','191') | |
#2005年12月現在、10桁に対して付加する接頭文字 | |
ISBN13=ISBN13_PREFIX[0] | |
def cd10(code): | |
"""10桁ISBNのチェックデジットを計算して返す。 | |
http://www.kikuchi.biz-web.jp/barcodefile/ISBN.html | |
""" | |
s = str(code)[:9] | |
w = 10 | |
a = 0 | |
for i in range(len(s)): | |
a = a + (int(s[i]) * w) | |
w -= 1 | |
d = 11 - (a % 11) | |
if d == 10: d = "X" | |
if d == 11: d = "0" | |
return d | |
def cd13(code): | |
"""13桁ISBNのチェックデジットを計算して返す。 | |
http://www.isbn-center.jp/whatsnew/kikaku.html | |
""" | |
s = str(code)[:12] | |
a = b = 0 | |
for i in range(0,len(s),2): a = a + int(s[i]) | |
for i in range(1,len(s),2): b = b + int(s[i]) | |
d = (a + (b*3)) % 10 | |
if d>0: d = 10 - d | |
return d | |
def cdjan(s): return cd13(s) | |
class ISBN(object): | |
"""10桁と13桁のISBNを相互変換するクラス | |
""" | |
def __init__(self, anyisbn): | |
"""クラスの初期化 | |
9桁(チェックデジットなし)、10桁、13桁(JAN)のいずれの形式でも | |
受け入れる。逆にそれ以外は受け入れない。 | |
""" | |
self.raw = None | |
anyisbn = anyisbn.strip().upper().replace('ISBN','').replace('-','') | |
if len(anyisbn) in (9,10): | |
self.raw = anyisbn[:9] | |
elif len(anyisbn)==13: | |
self.raw = anyisbn[3:12] | |
else: | |
raise ValueError,"ISBN [%s] length error. should be 9 or 10 or 13" % anyisbn | |
def isbn10(self): return "%s%s" % (self.raw,self.old_checkdegit()) | |
def oldstyle(self): return self.isbn10() | |
def old_checkdegit(self): return cd10(self.raw) | |
def isbn13(self): return "%s%s%s" % (ISBN13,self.raw,self.new_checkdegit()) | |
def newstyle(self): return self.isbn13() | |
def new_checkdegit(self): return cd13(ISBN13+self.raw) | |
class CCode(object): | |
"""Cコード(バーコードの2段目に含まれている)の内容を保持しているクラス。 | |
""" | |
_target = (u"一般",u"教養",u"実用",u"専門","None",u"婦人",u"学参I (小・中学生対象)",u"学参II(高校生対象)",u"児童 (中学生以下対象)",u"雑誌扱い") | |
_style = (u"単行本",u"文庫",u"新書",u"全集・双書",u"ムック・その他",u"事・辞典",u"図鑑",u"絵本",u"磁性媒体など",u"コミック") | |
_ndc = (u"総記",u"百科事典",u"年鑑","None",u"情報科学","None","None","None","None","None", | |
u"哲学",u"心理(学)",u"倫理(学)","None",u"宗教",u"仏教",u"キリスト教","None","None","None", | |
u"歴史・総記",u"日本歴史",u"外国歴史",u"伝記","None",u"地理",u"旅行","None","None","None", | |
u"社会科学総記",u"政治(含む国防軍事)",u"法律",u"経済・財政・統計",u"経営","None",u"社会",u"教育","None",u"民族風習", | |
u"自然科学総記",u"数学",u"物理学",u"化学",u"天文・地学",u"生物学","None",u"医学・薬学","None","None", | |
u"工学工業総記",u"土木",u"建築",u"機械",u"電気",u"電子・通信",u"海事",u"採鉱・冶金",u"その他工業","None", | |
u"産業総記",u"農林業",u"水産業",u"商業","None",u"交通通信業","None","None","None","None", | |
u"芸術総記",u"絵画・彫刻",u"写真・工芸",u"音楽・舞踏",u"演劇・映画",u"体育・スポーツ",u"諸芸・娯楽",u"家事","None",u"コミック・劇画" | |
u"語学総記",u"日本語",u"英米語","None",u"ドイツ語",u"フランス語","None",u"外国語","None","None", | |
u"文学総記",u"日本文学総記",u"日本文学詩歌",u"日本文学小説","None",u"日本文学・評論・随筆その他","None",u"外国文学小説",u"外国文学その他","None") | |
def __init__(self,ccode=None): | |
self.raw = ccode | |
if self.raw: | |
self.target = int(ccode[0:1]) | |
self.targetv = self._target[self.target] | |
self.style = int(ccode[1:2]) | |
self.stylev = self._style[self.style] | |
self.ndc = int(ccode[2:4]) | |
self.ndcv = self._ndc[self.ndc] | |
def __str__(self): return self.raw | |
class BookJAN(ISBN): | |
"""2段目バーコードのデータをCコードと価格に分類するクラス。 | |
Cコードの細かい内容はCCodeクラスが管理する。 | |
""" | |
def __init__(self, input): | |
if len(input)==13: | |
if input[:3] in JAN_PREFIX_1ST: | |
super(BookJAN,self).__init__(input) | |
self.ccode = None | |
self.price = None | |
elif input[:3] in JAN_PREFIX_2ND: | |
self.raw = input | |
self.ccode = CCode(self.raw[3:7]) | |
self.price = int(self.raw[7:12]) | |
else: | |
raise Exception,"[%s] does not valid Book JAN code" % input | |
else: | |
raise Exception,"[%s] does not valid Book JAN code" % input | |
def test(encoding='euc-jp'): | |
"""テストルーチン""" | |
tests = ('494999908','4798108545', | |
'4-7741-2228-9','ISBN4-7741-2228-9','isbn4774122289', | |
'ISBN450123456','12345678901','9784398470270','9784817180148') | |
print "="*20 | |
print " ISBN" | |
print "="*20 | |
for c in tests[0:4]: | |
isbn = ISBN(c) | |
print "Raw ",isbn.raw,"[<-",c,"]" | |
print "Old ",isbn.oldstyle() | |
print "New ",isbn.newstyle() | |
print "" | |
print "="*20 | |
print " Book JAN" | |
print "="*20 | |
tests = ('9784398470270','9784817180148') | |
for c in tests[0:4]: | |
jan = BookJAN(c) | |
print "RAW ",jan.raw | |
print "New ",jan.newstyle() | |
print "" | |
print "="*20 | |
print " Book JAN CCode" | |
print "="*20 | |
tests = ('1910193003605','1923055038004') | |
for c in tests[0:4]: | |
jan = BookJAN(c) | |
print "RAW ",jan.raw | |
if jan.ccode: | |
print "C-CODE ",jan.ccode | |
print "C-CODE.Target ",jan.ccode.target,' :',jan.ccode.targetv.encode(encoding) | |
print "C-CODE.Style ",jan.ccode.style,' :',jan.ccode.stylev.encode(encoding) | |
print "C-CODE.NDC ",jan.ccode.ndc,':',jan.ccode.ndcv.encode(encoding) | |
print "PRICE ",jan.price | |
print "" | |
idx = 0 | |
cc = 0 | |
for c in CCode()._ndc: | |
print idx, | |
if c: | |
print c.encode(encoding) | |
cc += 1 | |
else: | |
print c | |
idx += 1 | |
print cc,'/',len(CCode()._ndc) | |
if __name__=='__main__': | |
encoding = "euc-jp" | |
if sys.platform == 'win32': encoding="cp932" | |
test(encoding) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment