|
|
#1 |
|
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 11,360
Karma: 79528341
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,525
Karma: 8065948
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: 11,360
Karma: 79528341
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Yes, that's where I figured to put it.
Should've bee a little more clear. What I'm a bit confused on is whether it could be plugged into a template (presumably Action Chains' single-field edit) to convert an identifier from isbn10 to 13.
|
|
|
|
|
|
#4 | |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
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: 11,360
Karma: 79528341
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 10:54 AM. |
|
|
|
| Advert | |
|
|
|
|
#6 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
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: 11,360
Karma: 79528341
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.
|
|
|
|
![]() |
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Search to find ISBN-10s | ownedbycats | Library Management | 2 | 10-08-2022 09:18 AM |
| Search for ISBN-10s | ownedbycats | Library Management | 19 | 02-09-2021 12:23 PM |
| Using built-in template functions in a custom template function | ilovejedd | Library Management | 4 | 01-28-2018 01:20 PM |
| Problem with contains function in save template | MicaOlaAdams | Calibre | 5 | 10-21-2016 11:25 AM |
| how to use re() function in Template Program Mode? | msciwoj | Library Management | 3 | 07-07-2016 04:55 PM |