| 
			
			 | 
		#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 |