Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Library Management

Notices

Reply
 
Thread Tools Search this Thread
Old 12-06-2022, 12:16 PM   #1
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,791
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
Would this be able to turned into a template function?
ownedbycats is online now   Reply With Quote
Old 12-06-2022, 04:26 PM   #2
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
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)
Attached Thumbnails
Click image for larger version

Name:	Clipboard01.png
Views:	92
Size:	57.3 KB
ID:	198238  
chaley is offline   Reply With Quote
Advert
Old 12-10-2022, 09:28 PM   #3
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,791
Karma: 74203799
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.
ownedbycats is online now   Reply With Quote
Old 12-11-2022, 08:03 AM   #4
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,362
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by ownedbycats View Post
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.
Sure. It is a template function like any other. You just make a GPM template to call it.
Code:
program: whatever_you_called_it()
You could instead make it a stored template instead of a template function.

Example:
Click image for larger version

Name:	Clipboard02.png
Views:	72
Size:	39.9 KB
ID:	198334

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)
Call it with
Code:
program: isbn10_to_13()
chaley is offline   Reply With Quote
Old 12-11-2022, 09:06 AM   #5
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,791
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, ',')
Template tester shows it producing a result of
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.
ownedbycats is online now   Reply With Quote
Advert
Old 12-11-2022, 09:53 AM   #6
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
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
Here is a solution in Python. This will be much faster but probably harder for you to understand what it does. It doesn't use the stored template, instead including the conversion functions directly.
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)
chaley is offline   Reply With Quote
Old 12-11-2022, 11:00 AM   #7
ownedbycats
Custom User Title
ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.ownedbycats ought to be getting tired of karma fortunes by now.
 
ownedbycats's Avatar
 
Posts: 10,791
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.
ownedbycats is online now   Reply With Quote
Reply


Forum Jump

Similar Threads
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


All times are GMT -4. The time now is 11:11 PM.


MobileRead.com is a privately owned, operated and funded community.