## Refactoring with Weighted Sum Check digits

In the previous post, I added UPC-A checkdigit verification to my ISBN verification code. This was a departure from the “theme” of the previous work which was focused on ISBN-10 and ISBN-13 codes alone. As I did this work, I made a few observations:

• Most of the check digit calculations were VERY similar, but not quite identical
• The group of methods/functions no longer were solely ISBN specific
• Duplicate code was starting to pop up in the class

Based on this, I decided to do a quick refactoring exercise and see if I could simplify things a bit.

## UPC Validation in Python: Making it Easy

This is turning into a bit of a rabbit hole, but today I noticed that UPCs (Universal Product Codes) have a check digit also. UPCs are the numbers (most of the time accompanied by a bar code) that appear on just about every item and enable those cool scanners at the checkout of your local supermarket.

Interestingly enough, the checkdigit for a UPC-A code (the “normal” UPC) is generated almost like the checkdigit for ISBN-13. Here are the major differences:

• UPCs only have 12 digits (including the checkdigit) versus 13 for ISBN-13
• The checkdigit is calculated by weighting the ODD numbers by 3 (versus the EVEN numbers in ISBN-13)

Other than that, it’s the same process!

## Using Simple Code Coverage in Python

I think that I’ve done a good job writing my unit tests, but how do I know for sure? The goal of unit tests is to make sure that code properly fulfills requirements. All of the code. So, basically I want to make sure that every line of code I have written is doing what it’s supposed to do. Enter the concept of code coverage.

## Testing Exceptions in Python with unittest

When we implemented the `convert_isbn_10_to_13()` method, we decided to use a custom exception (`FormatException`) to indicate that there was something wrong with the ISBN-10 string that is provided as input.

```    def convert_isbn_10_to_13(isbn10_code_string: str) -> str:
if not ISBNValidator.validate_isbn10(isbn10_code_string):
raise ISBNValidator.FormatException(f"{isbn10_code_string} is not a valid ISBN-10 code string.")```

From a design standpoint, this is a good thing, but it presents a small challenge when we think about how we might test it within the confines of the Python `unittest` framework. Luckily the developers of the unittest module thought of this and we can assert whether or not a particular function raises a particular exception.

## Simple ISBN-10 to ISBN-13 Conversion

Well, there appears to be a lot more to ISBNs than I originally thought! This is a great example of how curiosity can be a good catalyst for practice at times. As I mentioned in the last post, I found out that there is a way to convert the “old” ISBN-10 codes to the newer ISBN-13 format. What would our ISBN exercise be like if we couldn’t upgrade an old code to a new one?

## ISBN Validator: Making it General Purpose

Now that we’ve constructed this ISBN validator to understand both ISBN-10 and ISBN-13 numbers, I thought it might be a good idea to make a more generic `validate_isbn` method that attempts to detect which type of ISBN we are dealing with and then calls the correct method to validate it. That way, anybody using our validator can just pass in a string and we’ll do our best to figure it out. This might be useful in a library where there are books that feature each type of ISBN.

## Reliable ISBN-13 Validation

As I’ve been progressing through the exercise of parsing ISBN numbers, I discovered that the ISBN-10 numbers that I’ve been parsing were phased out in 2007! I guess that too many people were writing books around the world and they were running out of numbers. To deal with the problem, the ISBN people created something called a ISBN-13 code that is… (wait for it) … 13 digits long instead of the 10 digits in the previous standard.

After learning this shocking information, I decided that it wouldn’t be proper to have an ISBN validator that was almost 15 years out of date, so I added support for ISBN-13 validation to my practice example.

## ISBN Validation: Adding Simple Python Unit Tests

In the previous versions of the ISBN Validation Exercise, I had the “test” code embedded with the actual validator itself. For simplicity, I think this is was the easiest way for the author to present the exercise on Codementor. As a reminder, this is what the “inline” test code looked like:

```    def test_isbns():
isbn = "123"
assert ISBNExercise.validate_isbn10(isbn) is False
isbn = "0136091814"
assert ISBNExercise.validate_isbn10(isbn) is True
isbn = "1616550416"
...```

Generally, it isn’t considered good design practice to embed testing code inside of an application, and since I’m getting a bit carried away with this example, I figured that I’d do a bit of refactoring to add a more robust series of tests using the Python `unittest` framework. For those of you who aren’t familiar with the concept of unit tests, or why they are helpful, there is a great post at RealPython that explains the concept, as well as how to use the `unittest` framework in Python.

## Basic ISBN-10 Validation in Python: Part 2

In my previous post Practicing Python, I started work on this exercise at Codementor. I got a decent solution working, but it still had a few deficiencies. Namely:

• It did not account for dashes in the ISBN
• Some of the error handling was not complete (namely making sure that the last digit was either numeric or an “x” character)
• The test code was also incomplete (did not test the last digit as “x” or a ISBN with dashes)

## Practicing Python: Quick ISBN-10 Validation

One of my resolutions this year is to try to increase the number of opportunities I have to practice programming — something I really enjoy doing. Fortuitously, this article appeared in my inbox today, so I figured that I’d give it a whirl. All in all, it took me about 10 minutes to complete and helped me to reinforce some basic Python skills. It also will give me a change to experiment with a new code formatting plugin in WordPress.  In the future I think that I’m going to post my practice sessions here.

This particular solution is focused on validating ISBN-10 codes and explores basic string slicing as well as the use of the modulus operator in Python.  It was a nice diversion!

Scroll to Top