![]() |
#1 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,797
Karma: 74203799
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Template function to convert ISBN-10s
I found this code to convert ISBN-10s to 13s:
Code:
def check_digit_10(isbn): assert len(isbn) == 9 sum = 0 for i in range(len(isbn)): c = int(isbn[i]) w = i + 1 sum += w * c r = sum % 11 if r == 10: return 'X' else: return str(r) def check_digit_13(isbn): assert len(isbn) == 12 sum = 0 for i in range(len(isbn)): c = int(isbn[i]) if i % 2: w = 3 else: w = 1 sum += w * c r = 10 - (sum % 10) if r == 10: return '0' else: return str(r) def convert_10_to_13(isbn): assert len(isbn) == 10 prefix = '978' + isbn[:-1] check = check_digit_13(prefix) return prefix + check ![]() |
![]() |
![]() |
![]() |
#2 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,362
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Code:
def evaluate(self, formatter, kwargs, mi, locals): isbn = mi.isbn if len(isbn) != 10: return 'isbn length != 10' prefix = '978' + isbn[:-1] check = self.check_digit_13(prefix) return prefix + check def check_digit_13(self, isbn): assert len(isbn) == 12 sum = 0 for i in range(len(isbn)): c = int(isbn[i]) if i % 2: w = 3 else: w = 1 sum += w * c r = 10 - (sum % 10) if r == 10: return '0' else: return str(r) |
![]() |
![]() |
Advert | |
|
![]() |
#3 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,797
Karma: 74203799
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Yes, that's where I figured to put it.
![]() |
![]() |
![]() |
![]() |
#4 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,362
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Code:
program: whatever_you_called_it() Example: This template is slightly different from the function above, correcting a bug and making it return the existing isbn if it isn't 10 long. Code:
def evaluate(book, context): isbn = book.identifiers.get('isbn', '') if len(isbn) != 10: # This isn't an isbn 10. Return it as it is. return isbn prefix = '978' + isbn[:-1] check = check_digit_13(prefix) return prefix + check def check_digit_13(isbn): sum = 0 for i in range(len(isbn)): c = int(isbn[i]) if i % 2: w = 3 else: w = 1 sum += w * c r = 10 - (sum % 10) if r == 10: return '0' else: return str(r) Code:
program: isbn10_to_13() |
|
![]() |
![]() |
![]() |
#5 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,797
Karma: 74203799
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Thanks.
When trying to get the new ISBN back into the identifiers field, I tried this: Code:
program: isbn = columnupdate_identifier_isbnconvert(); newisbn = strcat('isbn:', isbn); list_union($identifiers, newisbn, ',') isbn:9780690042399, goodreads:2152001, isbn:0690042396 However, actually running it fails, I think because the identifiers field won't accept the isbn value when one already exists. What would be the best option for either a) instead of list_union, replacing the ISBN; b) removing the existing ISBN before doing the list_union? I thought list_re should work, but I'm having trouble with the syntax. ![]() Last edited by ownedbycats; 12-11-2022 at 09:54 AM. |
![]() |
![]() |
Advert | |
|
![]() |
#6 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,362
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Here are two solutions, one in GPM and one in Python.
Code:
program: new_ids = ''; found_isbn = ''; # first search for an isbn. Remove it from the list if found. for id in $identifiers: if '^isbn:' in id then found_isbn = '1' else # Can't use list operations because ids can contain commas new_ids = new_ids & (if new_ids then ', ' fi) & id fi rof; # If we found an isbn try to convert it and then add it back into the identifiers list if found_isbn then isbn = isbn10_to_13(); newisbn = strcat('isbn:', isbn); new_ids & (if new_ids then ', ' fi) & newisbn else $identifiers fi Code:
python: def evaluate(book, context): new_ids = {} # Copy the identifiers dict, replacing isbns with the converted value for k,v in book.identifiers.items(): new_ids[k] = convert_isbn(v) if k == 'isbn' else v # Rebuild the identifiers string from the new identifiers dict return ', '.join([k + ':' + v for k,v in new_ids.items()]) def convert_isbn(isbn): if len(isbn) != 10: # This isn't an isbn 10. Return it as it is. return isbn prefix = '978' + isbn[:-1] check = check_digit_13(prefix) return prefix + check def check_digit_13(isbn): sum = 0 for i in range(len(isbn)): c = int(isbn[i]) if i % 2: w = 3 else: w = 1 sum += w * c r = 10 - (sum % 10) if r == 10: return '0' else: return str(r) |
![]() |
![]() |
![]() |
#7 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,797
Karma: 74203799
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Oh, I didn't realize about the list ops not working for ids. That's useful to know in the future. Thanks.
![]() |
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Search to find ISBN-10s | ownedbycats | Library Management | 2 | 10-08-2022 08:18 AM |
Search for ISBN-10s | ownedbycats | Library Management | 19 | 02-09-2021 11:23 AM |
Using built-in template functions in a custom template function | ilovejedd | Library Management | 4 | 01-28-2018 12:20 PM |
Problem with contains function in save template | MicaOlaAdams | Calibre | 5 | 10-21-2016 10:25 AM |
how to use re() function in Template Program Mode? | msciwoj | Library Management | 3 | 07-07-2016 03:55 PM |