Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

class Book checksum digit function not working

get_checksum_digit(self) returns the checksum digit of an isbn. The ISBNs are 13 digits long. The last digit is a checksum digit which is determined from the first 12 digits. The method calculates and returns the checksum digit.
This is how the checksum is calculated

For eg an ISBN 978133829914

A = 9 + 8 + 3 + 8 + 9 + 1 = 38

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

B = (7 + 1 + 3 + 2 + 9 + 4) x 3 = 78

The check digit is then:
(10 – (A + B)) mod 10

This is my Book class:

class Book:
    def __init__(self, bookname, isbn = "N/A", price=0):
        self.bookname, self.isbn, self.price = bookname, isbn, price
        
    def __str__(self):
        return "{}({}),${:.2f}".format(self.bookname, self.isbn, self.price)
        
    def get_checksum_digit(self):
        even_sum = 0
        odd_sum = 0
        for i in range(len(self.isbn)-1):
            if i%2 == 0:
                even_sum += int(self.isbn[i])
            else:
                odd_sum += int(self.isbn[i])
            i_sum = even_sum + (odd_sum * 3)
            self.checksum = (10 - (i_sum)) % 10
            if self.checksum == 10:
                return 0
        return self.checksum
        
        
    def update_checksum(self):
        self.isbn = self.isbn.replace(self.isbn[-1], str(Book.get_checksum_digit(self)))
        return self.isbn

    def is_valid_isbn(self):
        return int(self.isbn[-1]) == Book.get_checksum_digit(self)
       

My is_valid_isbn() method is not working as it should be. Any help please? It isn’t showing True after updating the ISBN last number with the checksum.

This is the test case:

book1 = Book('Onion Skin','9781603094891',14.99)
print(book1)
print(book1.is_valid_isbn())
book1.update_checksum()
print(book1)
print(book1.is_valid_isbn())

This is the output I should get:

Onion Skin(9781603094891),$14.99
False
Onion Skin(9781603094894),$14.99
True
        

This is the output I’m getting:

Onion Skin(9781603094891),$14.99
False
Onion Skin(9784603094894),$14.99
False      

  

>Solution :

Pay close attention to the ISBN numbers:

Onion Skin(9781603094891),$14.99
              ^        ^
Onion Skin(9784603094894),$14.99
              ^        ^

You didn’t want to change that first 1 — changing it invalidates the checksum! That’s happening because of the way you used replace in update_checksum.

In the process of debugging the code I did some other tidying (I had to simplify get_checksum_digit way down just to be able to figure out what it was supposed to be doing). Here’s the final result:

class Book:
    def __init__(self, bookname: str, isbn = "N/A", price=0.0):
        self.bookname, self.isbn, self.price = bookname, isbn, price
        
    def __str__(self) -> str:
        return f"{self.bookname} ({self.isbn}), ${self.price:2f}"
        
    def get_checksum_digit(self) -> str:
        # ISBNs have 13 digits with the 13th digit computed from the first 12:
        #   sum the first 12 digits, multiplying every other digit by 3.
        #   then subtract that from 10, and use the result mod 10.
        return str((10 - sum(
            int(digit) * 3 if i % 2 else int(digit)
            for i, digit in enumerate(self.isbn[:-1])
        )) % 10)
        
    def update_checksum(self) -> None:
        self.isbn = self.isbn[:-1] + self.get_checksum_digit()

    def is_valid_isbn(self) -> bool:
        return self.isbn[-1] == self.get_checksum_digit()


def test_book_isbn():
    isbn = '9781603094891'
    book = Book('Onion Skin', isbn, 14.99)
    assert not book.is_valid_isbn()
    book.update_checksum()
    assert book.is_valid_isbn()
    assert book.isbn[:-1] == isbn[:-1]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading