ISBN Number CheckISBN missing number solverRefactoring complex phone validationsValidation check and...

Is there any use for defining additional entity types in a SOQL FROM clause?

What causes the sudden spool-up sound from an F-16 when enabling afterburner?

How to deal with fear of taking dependencies

Prime joint compound before latex paint?

Is it wise to focus on putting odd beats on left when playing double bass drums?

Can the Produce Flame cantrip be used to grapple, or as an unarmed strike, in the right circumstances?

A poker game description that does not feel gimmicky

Copycat chess is back

Is every set a filtered colimit of finite sets?

If a centaur druid Wild Shapes into a Giant Elk, do their Charge features stack?

Pristine Bit Checking

Extreme, but not acceptable situation and I can't start the work tomorrow morning

Denied boarding due to overcrowding, Sparpreis ticket. What are my rights?

Is ipsum/ipsa/ipse a third person pronoun, or can it serve other functions?

How do I create uniquely male characters?

Unbreakable Formation vs. Cry of the Carnarium

What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?

What is the meaning of "of trouble" in the following sentence?

What does "enim et" mean?

Can I find out the caloric content of bread by dehydrating it?

"My colleague's body is amazing"

Was there ever an axiom rendered a theorem?

Lied on resume at previous job

How to move the player while also allowing forces to affect it



ISBN Number Check


ISBN missing number solverRefactoring complex phone validationsValidation check and code-savingLexer for C- in PythonConnect 4 refine the diagonal checkFile presence check for an automated workflowValidation logic for range check with input can be String or NumberDecide if number is Armstrong numberProgram to check if a date is valid or notCredit card validity check






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







3












$begingroup$


I’ve recently coded a way of checking a 10-digit ISBN.



I was wondering if the code works to check the numbers, and if there are any flaws in my code.





def isbn(number):
try:
numberreal = number
#keeps real number with "-"
numberzero = number.replace("-", "")
#this makes sure python doesnt drop the first 0 if it is at the start
number = number.replace("-", "")
number = int(number)
number = str(numberzero)
print("The ISBN Number Entered is", numberreal)
num = int(number[0]) * 10 + int(number[1]) * 9 + int(number[2]) * 8 + int(number[3]) * 7 + int(number[4]) * 6 + int(number[5]) * 5 + int(number[6]) * 4 + int(number[7]) * 3 + int(number[8]) * 2
num = num%11
checknum = 11 - num

print("The Check Digit Should Be", checknum, "and the one in the code provided was", number[9])
if int(checknum) == int(number[9]):
print("The Check Digit Provided Is Correct")
else:
print("The Check Digit Provided Is Incorrect")
except ValueError:
print("Not Valid Number")
error()
except IndexError:
print("Not 10 Digits")
error()



def error():
print("Error")

running = True
while running == True:
isbn(input("What is the isbn 10 digit number? "))
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restartingn" + "-" * 34)
else:
print("closing Down")
running = False









share|improve this question











$endgroup$












  • $begingroup$
    I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
    $endgroup$
    – fish2000
    May 8 '14 at 16:33


















3












$begingroup$


I’ve recently coded a way of checking a 10-digit ISBN.



I was wondering if the code works to check the numbers, and if there are any flaws in my code.





def isbn(number):
try:
numberreal = number
#keeps real number with "-"
numberzero = number.replace("-", "")
#this makes sure python doesnt drop the first 0 if it is at the start
number = number.replace("-", "")
number = int(number)
number = str(numberzero)
print("The ISBN Number Entered is", numberreal)
num = int(number[0]) * 10 + int(number[1]) * 9 + int(number[2]) * 8 + int(number[3]) * 7 + int(number[4]) * 6 + int(number[5]) * 5 + int(number[6]) * 4 + int(number[7]) * 3 + int(number[8]) * 2
num = num%11
checknum = 11 - num

print("The Check Digit Should Be", checknum, "and the one in the code provided was", number[9])
if int(checknum) == int(number[9]):
print("The Check Digit Provided Is Correct")
else:
print("The Check Digit Provided Is Incorrect")
except ValueError:
print("Not Valid Number")
error()
except IndexError:
print("Not 10 Digits")
error()



def error():
print("Error")

running = True
while running == True:
isbn(input("What is the isbn 10 digit number? "))
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restartingn" + "-" * 34)
else:
print("closing Down")
running = False









share|improve this question











$endgroup$












  • $begingroup$
    I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
    $endgroup$
    – fish2000
    May 8 '14 at 16:33














3












3








3


2



$begingroup$


I’ve recently coded a way of checking a 10-digit ISBN.



I was wondering if the code works to check the numbers, and if there are any flaws in my code.





def isbn(number):
try:
numberreal = number
#keeps real number with "-"
numberzero = number.replace("-", "")
#this makes sure python doesnt drop the first 0 if it is at the start
number = number.replace("-", "")
number = int(number)
number = str(numberzero)
print("The ISBN Number Entered is", numberreal)
num = int(number[0]) * 10 + int(number[1]) * 9 + int(number[2]) * 8 + int(number[3]) * 7 + int(number[4]) * 6 + int(number[5]) * 5 + int(number[6]) * 4 + int(number[7]) * 3 + int(number[8]) * 2
num = num%11
checknum = 11 - num

print("The Check Digit Should Be", checknum, "and the one in the code provided was", number[9])
if int(checknum) == int(number[9]):
print("The Check Digit Provided Is Correct")
else:
print("The Check Digit Provided Is Incorrect")
except ValueError:
print("Not Valid Number")
error()
except IndexError:
print("Not 10 Digits")
error()



def error():
print("Error")

running = True
while running == True:
isbn(input("What is the isbn 10 digit number? "))
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restartingn" + "-" * 34)
else:
print("closing Down")
running = False









share|improve this question











$endgroup$




I’ve recently coded a way of checking a 10-digit ISBN.



I was wondering if the code works to check the numbers, and if there are any flaws in my code.





def isbn(number):
try:
numberreal = number
#keeps real number with "-"
numberzero = number.replace("-", "")
#this makes sure python doesnt drop the first 0 if it is at the start
number = number.replace("-", "")
number = int(number)
number = str(numberzero)
print("The ISBN Number Entered is", numberreal)
num = int(number[0]) * 10 + int(number[1]) * 9 + int(number[2]) * 8 + int(number[3]) * 7 + int(number[4]) * 6 + int(number[5]) * 5 + int(number[6]) * 4 + int(number[7]) * 3 + int(number[8]) * 2
num = num%11
checknum = 11 - num

print("The Check Digit Should Be", checknum, "and the one in the code provided was", number[9])
if int(checknum) == int(number[9]):
print("The Check Digit Provided Is Correct")
else:
print("The Check Digit Provided Is Incorrect")
except ValueError:
print("Not Valid Number")
error()
except IndexError:
print("Not 10 Digits")
error()



def error():
print("Error")

running = True
while running == True:
isbn(input("What is the isbn 10 digit number? "))
restart = input("Do You Want Restart?")
restart = restart.lower()
if restart in ("yes", "y", "ok", "sure", ""):
print("Restartingn" + "-" * 34)
else:
print("closing Down")
running = False






python python-3.x validation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 30 '14 at 18:05









Jamal

30.6k11121227




30.6k11121227










asked Apr 30 '14 at 15:50









Oliver PerringOliver Perring

143138




143138












  • $begingroup$
    I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
    $endgroup$
    – fish2000
    May 8 '14 at 16:33


















  • $begingroup$
    I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
    $endgroup$
    – fish2000
    May 8 '14 at 16:33
















$begingroup$
I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
$endgroup$
– fish2000
May 8 '14 at 16:33




$begingroup$
I am sure that you wrote this for the learning experience, at least in part – so but if ISBN parsing is a specific thing on your to-do list, the uninventively-named PyISBN module – pyisbn.readthedocs.org – is something I can personally vouch for, as like a dependably no-nonsense and solid library.Here’s the function in their codebase that’s roughly analogous to what you posted: github.com/JNRowe/pyisbn/blob/master/pyisbn/…
$endgroup$
– fish2000
May 8 '14 at 16:33










1 Answer
1






active

oldest

votes


















8












$begingroup$

Right now, the code doesn't work. Your code only validates ISBNs that use Arabic numerals, but some ISBNs can end in an "X". Quoting from the ISBN FAQs:




Why do some ISBNs end in an "X"?



In the case of the check digit, the last digit of the ISBN, the upper case X can appear. The method of determining the check digit for the ISBN is the modulus 11 with the weighting factors 10 to 1. The Roman numeral X is used in lieu of 10 where ten would occur as a check digit.




So you should think about how you’d fix that first.



Comments on the existing isbn() function



This isn't how I'd write it. Your function doesn’t return a True/False value. The code which acts interactively, and prints things to the user, and the code which validates the ISBN, are both intertwined. I would separate the two. This will make debugging issues like the "X" easier, and you can reuse the validating function later.



For example, if you wanted to enter IBSNs to a database, and verify that the entered numbers were accurate, you could get a True/False value from the function without printing to the console.



Here are some general comments on the existing isbn() function:




  • It's not clear what the difference between the numberzero, numberreal and number variables are. This is a side-effect of mixing the validation and printing code.


  • Give it a more specific name, and add a docstring (a way to document functions in Python). Later you may want to validate ISBN-13 codes, and you don't want the namespace cluttered.


  • There are better ways of handling errors than printing the word "Error" to the console. You could raise a custom ValueError, or something else.


  • The line which constructs num is excessively long: you can use sum() and a list comprehension to construct it in a more compact way, and it will make it clearer what formula you're using later down the line.


  • The line num = num%11 can be replaced by num %= 11. Just makes things slightly neater.



With those points in mind, here's how I might rewrite your function:





def validate_isbn10(number):
"""A function for validating ISBN-10 codes."""
formatted_num = number.replace("-", "")

if len(formatted_num) != 10:
raise ValueError('The number %s is not a 10-digit string.' % number)

check_sum = sum(int(formatted_num[i]) * (10 - i) for i in xrange(8))
check_sum %= 11
check_digit = 11 - check_sum

if formatted_num[-1] == "X":
return check_digit == 10
else:
return check_digit == int(formatted_num[-1])


If you wanted to be able to tell the user what the correct check digit should be (in the event of an incorrectly formatted string), then you could factor our a check_digit() function as well.



I leave it as an exercise to write a separate function which interactively prompts the user for an ISBN-10 code, and tells them whether or nots it correctly formatted.



Comments on the rest of the code



Here are some things that concern me in the rest of your code:




  • You should wrap the interactive code in a if __name__ == "__main__": block. This means that it will only run if the file is executed directly, but you can also import the file to just get the function definitions (say, if you wanted to use this ISBN validator in a larger project).



  • The line while running == True:. If you're going to compare to booleans, then it's much more idiomatic to write while running is True:, or even better, while running:. But that's not a good way to do it.



    Instead, suppose you have a interactive_user_isbn() function which runs the interactive session with the user. Then at the end of that function, if they want to go again, then you can ask them, and if they do, call the function again.



    Make the repeat prompt more explicit about what will be repeated, and give them a hint about what they can type to repeat the function.



    If they type nothing, then I would err on assuming that they don't want to go again, but that's just my opinion.



    Something like:





    def interactive_user_isbn():
    # ask the user for an ISBN
    # check if it's correct
    # pay the user a compliment etc

    repeat = input("Do you want to check another number? (y/n)")
    if repeat.lower() in ["yes", "y", "ok", "sure"]:
    print("n")
    interactive_user_isbn()
    else:
    print("Okay, bye!")







share|improve this answer











$endgroup$













  • $begingroup$
    thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
    $endgroup$
    – Oliver Perring
    May 17 '14 at 10:40










  • $begingroup$
    Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
    $endgroup$
    – Leonid
    Apr 17 '16 at 5:06












Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f48588%2fisbn-number-check%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









8












$begingroup$

Right now, the code doesn't work. Your code only validates ISBNs that use Arabic numerals, but some ISBNs can end in an "X". Quoting from the ISBN FAQs:




Why do some ISBNs end in an "X"?



In the case of the check digit, the last digit of the ISBN, the upper case X can appear. The method of determining the check digit for the ISBN is the modulus 11 with the weighting factors 10 to 1. The Roman numeral X is used in lieu of 10 where ten would occur as a check digit.




So you should think about how you’d fix that first.



Comments on the existing isbn() function



This isn't how I'd write it. Your function doesn’t return a True/False value. The code which acts interactively, and prints things to the user, and the code which validates the ISBN, are both intertwined. I would separate the two. This will make debugging issues like the "X" easier, and you can reuse the validating function later.



For example, if you wanted to enter IBSNs to a database, and verify that the entered numbers were accurate, you could get a True/False value from the function without printing to the console.



Here are some general comments on the existing isbn() function:




  • It's not clear what the difference between the numberzero, numberreal and number variables are. This is a side-effect of mixing the validation and printing code.


  • Give it a more specific name, and add a docstring (a way to document functions in Python). Later you may want to validate ISBN-13 codes, and you don't want the namespace cluttered.


  • There are better ways of handling errors than printing the word "Error" to the console. You could raise a custom ValueError, or something else.


  • The line which constructs num is excessively long: you can use sum() and a list comprehension to construct it in a more compact way, and it will make it clearer what formula you're using later down the line.


  • The line num = num%11 can be replaced by num %= 11. Just makes things slightly neater.



With those points in mind, here's how I might rewrite your function:





def validate_isbn10(number):
"""A function for validating ISBN-10 codes."""
formatted_num = number.replace("-", "")

if len(formatted_num) != 10:
raise ValueError('The number %s is not a 10-digit string.' % number)

check_sum = sum(int(formatted_num[i]) * (10 - i) for i in xrange(8))
check_sum %= 11
check_digit = 11 - check_sum

if formatted_num[-1] == "X":
return check_digit == 10
else:
return check_digit == int(formatted_num[-1])


If you wanted to be able to tell the user what the correct check digit should be (in the event of an incorrectly formatted string), then you could factor our a check_digit() function as well.



I leave it as an exercise to write a separate function which interactively prompts the user for an ISBN-10 code, and tells them whether or nots it correctly formatted.



Comments on the rest of the code



Here are some things that concern me in the rest of your code:




  • You should wrap the interactive code in a if __name__ == "__main__": block. This means that it will only run if the file is executed directly, but you can also import the file to just get the function definitions (say, if you wanted to use this ISBN validator in a larger project).



  • The line while running == True:. If you're going to compare to booleans, then it's much more idiomatic to write while running is True:, or even better, while running:. But that's not a good way to do it.



    Instead, suppose you have a interactive_user_isbn() function which runs the interactive session with the user. Then at the end of that function, if they want to go again, then you can ask them, and if they do, call the function again.



    Make the repeat prompt more explicit about what will be repeated, and give them a hint about what they can type to repeat the function.



    If they type nothing, then I would err on assuming that they don't want to go again, but that's just my opinion.



    Something like:





    def interactive_user_isbn():
    # ask the user for an ISBN
    # check if it's correct
    # pay the user a compliment etc

    repeat = input("Do you want to check another number? (y/n)")
    if repeat.lower() in ["yes", "y", "ok", "sure"]:
    print("n")
    interactive_user_isbn()
    else:
    print("Okay, bye!")







share|improve this answer











$endgroup$













  • $begingroup$
    thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
    $endgroup$
    – Oliver Perring
    May 17 '14 at 10:40










  • $begingroup$
    Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
    $endgroup$
    – Leonid
    Apr 17 '16 at 5:06
















8












$begingroup$

Right now, the code doesn't work. Your code only validates ISBNs that use Arabic numerals, but some ISBNs can end in an "X". Quoting from the ISBN FAQs:




Why do some ISBNs end in an "X"?



In the case of the check digit, the last digit of the ISBN, the upper case X can appear. The method of determining the check digit for the ISBN is the modulus 11 with the weighting factors 10 to 1. The Roman numeral X is used in lieu of 10 where ten would occur as a check digit.




So you should think about how you’d fix that first.



Comments on the existing isbn() function



This isn't how I'd write it. Your function doesn’t return a True/False value. The code which acts interactively, and prints things to the user, and the code which validates the ISBN, are both intertwined. I would separate the two. This will make debugging issues like the "X" easier, and you can reuse the validating function later.



For example, if you wanted to enter IBSNs to a database, and verify that the entered numbers were accurate, you could get a True/False value from the function without printing to the console.



Here are some general comments on the existing isbn() function:




  • It's not clear what the difference between the numberzero, numberreal and number variables are. This is a side-effect of mixing the validation and printing code.


  • Give it a more specific name, and add a docstring (a way to document functions in Python). Later you may want to validate ISBN-13 codes, and you don't want the namespace cluttered.


  • There are better ways of handling errors than printing the word "Error" to the console. You could raise a custom ValueError, or something else.


  • The line which constructs num is excessively long: you can use sum() and a list comprehension to construct it in a more compact way, and it will make it clearer what formula you're using later down the line.


  • The line num = num%11 can be replaced by num %= 11. Just makes things slightly neater.



With those points in mind, here's how I might rewrite your function:





def validate_isbn10(number):
"""A function for validating ISBN-10 codes."""
formatted_num = number.replace("-", "")

if len(formatted_num) != 10:
raise ValueError('The number %s is not a 10-digit string.' % number)

check_sum = sum(int(formatted_num[i]) * (10 - i) for i in xrange(8))
check_sum %= 11
check_digit = 11 - check_sum

if formatted_num[-1] == "X":
return check_digit == 10
else:
return check_digit == int(formatted_num[-1])


If you wanted to be able to tell the user what the correct check digit should be (in the event of an incorrectly formatted string), then you could factor our a check_digit() function as well.



I leave it as an exercise to write a separate function which interactively prompts the user for an ISBN-10 code, and tells them whether or nots it correctly formatted.



Comments on the rest of the code



Here are some things that concern me in the rest of your code:




  • You should wrap the interactive code in a if __name__ == "__main__": block. This means that it will only run if the file is executed directly, but you can also import the file to just get the function definitions (say, if you wanted to use this ISBN validator in a larger project).



  • The line while running == True:. If you're going to compare to booleans, then it's much more idiomatic to write while running is True:, or even better, while running:. But that's not a good way to do it.



    Instead, suppose you have a interactive_user_isbn() function which runs the interactive session with the user. Then at the end of that function, if they want to go again, then you can ask them, and if they do, call the function again.



    Make the repeat prompt more explicit about what will be repeated, and give them a hint about what they can type to repeat the function.



    If they type nothing, then I would err on assuming that they don't want to go again, but that's just my opinion.



    Something like:





    def interactive_user_isbn():
    # ask the user for an ISBN
    # check if it's correct
    # pay the user a compliment etc

    repeat = input("Do you want to check another number? (y/n)")
    if repeat.lower() in ["yes", "y", "ok", "sure"]:
    print("n")
    interactive_user_isbn()
    else:
    print("Okay, bye!")







share|improve this answer











$endgroup$













  • $begingroup$
    thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
    $endgroup$
    – Oliver Perring
    May 17 '14 at 10:40










  • $begingroup$
    Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
    $endgroup$
    – Leonid
    Apr 17 '16 at 5:06














8












8








8





$begingroup$

Right now, the code doesn't work. Your code only validates ISBNs that use Arabic numerals, but some ISBNs can end in an "X". Quoting from the ISBN FAQs:




Why do some ISBNs end in an "X"?



In the case of the check digit, the last digit of the ISBN, the upper case X can appear. The method of determining the check digit for the ISBN is the modulus 11 with the weighting factors 10 to 1. The Roman numeral X is used in lieu of 10 where ten would occur as a check digit.




So you should think about how you’d fix that first.



Comments on the existing isbn() function



This isn't how I'd write it. Your function doesn’t return a True/False value. The code which acts interactively, and prints things to the user, and the code which validates the ISBN, are both intertwined. I would separate the two. This will make debugging issues like the "X" easier, and you can reuse the validating function later.



For example, if you wanted to enter IBSNs to a database, and verify that the entered numbers were accurate, you could get a True/False value from the function without printing to the console.



Here are some general comments on the existing isbn() function:




  • It's not clear what the difference between the numberzero, numberreal and number variables are. This is a side-effect of mixing the validation and printing code.


  • Give it a more specific name, and add a docstring (a way to document functions in Python). Later you may want to validate ISBN-13 codes, and you don't want the namespace cluttered.


  • There are better ways of handling errors than printing the word "Error" to the console. You could raise a custom ValueError, or something else.


  • The line which constructs num is excessively long: you can use sum() and a list comprehension to construct it in a more compact way, and it will make it clearer what formula you're using later down the line.


  • The line num = num%11 can be replaced by num %= 11. Just makes things slightly neater.



With those points in mind, here's how I might rewrite your function:





def validate_isbn10(number):
"""A function for validating ISBN-10 codes."""
formatted_num = number.replace("-", "")

if len(formatted_num) != 10:
raise ValueError('The number %s is not a 10-digit string.' % number)

check_sum = sum(int(formatted_num[i]) * (10 - i) for i in xrange(8))
check_sum %= 11
check_digit = 11 - check_sum

if formatted_num[-1] == "X":
return check_digit == 10
else:
return check_digit == int(formatted_num[-1])


If you wanted to be able to tell the user what the correct check digit should be (in the event of an incorrectly formatted string), then you could factor our a check_digit() function as well.



I leave it as an exercise to write a separate function which interactively prompts the user for an ISBN-10 code, and tells them whether or nots it correctly formatted.



Comments on the rest of the code



Here are some things that concern me in the rest of your code:




  • You should wrap the interactive code in a if __name__ == "__main__": block. This means that it will only run if the file is executed directly, but you can also import the file to just get the function definitions (say, if you wanted to use this ISBN validator in a larger project).



  • The line while running == True:. If you're going to compare to booleans, then it's much more idiomatic to write while running is True:, or even better, while running:. But that's not a good way to do it.



    Instead, suppose you have a interactive_user_isbn() function which runs the interactive session with the user. Then at the end of that function, if they want to go again, then you can ask them, and if they do, call the function again.



    Make the repeat prompt more explicit about what will be repeated, and give them a hint about what they can type to repeat the function.



    If they type nothing, then I would err on assuming that they don't want to go again, but that's just my opinion.



    Something like:





    def interactive_user_isbn():
    # ask the user for an ISBN
    # check if it's correct
    # pay the user a compliment etc

    repeat = input("Do you want to check another number? (y/n)")
    if repeat.lower() in ["yes", "y", "ok", "sure"]:
    print("n")
    interactive_user_isbn()
    else:
    print("Okay, bye!")







share|improve this answer











$endgroup$



Right now, the code doesn't work. Your code only validates ISBNs that use Arabic numerals, but some ISBNs can end in an "X". Quoting from the ISBN FAQs:




Why do some ISBNs end in an "X"?



In the case of the check digit, the last digit of the ISBN, the upper case X can appear. The method of determining the check digit for the ISBN is the modulus 11 with the weighting factors 10 to 1. The Roman numeral X is used in lieu of 10 where ten would occur as a check digit.




So you should think about how you’d fix that first.



Comments on the existing isbn() function



This isn't how I'd write it. Your function doesn’t return a True/False value. The code which acts interactively, and prints things to the user, and the code which validates the ISBN, are both intertwined. I would separate the two. This will make debugging issues like the "X" easier, and you can reuse the validating function later.



For example, if you wanted to enter IBSNs to a database, and verify that the entered numbers were accurate, you could get a True/False value from the function without printing to the console.



Here are some general comments on the existing isbn() function:




  • It's not clear what the difference between the numberzero, numberreal and number variables are. This is a side-effect of mixing the validation and printing code.


  • Give it a more specific name, and add a docstring (a way to document functions in Python). Later you may want to validate ISBN-13 codes, and you don't want the namespace cluttered.


  • There are better ways of handling errors than printing the word "Error" to the console. You could raise a custom ValueError, or something else.


  • The line which constructs num is excessively long: you can use sum() and a list comprehension to construct it in a more compact way, and it will make it clearer what formula you're using later down the line.


  • The line num = num%11 can be replaced by num %= 11. Just makes things slightly neater.



With those points in mind, here's how I might rewrite your function:





def validate_isbn10(number):
"""A function for validating ISBN-10 codes."""
formatted_num = number.replace("-", "")

if len(formatted_num) != 10:
raise ValueError('The number %s is not a 10-digit string.' % number)

check_sum = sum(int(formatted_num[i]) * (10 - i) for i in xrange(8))
check_sum %= 11
check_digit = 11 - check_sum

if formatted_num[-1] == "X":
return check_digit == 10
else:
return check_digit == int(formatted_num[-1])


If you wanted to be able to tell the user what the correct check digit should be (in the event of an incorrectly formatted string), then you could factor our a check_digit() function as well.



I leave it as an exercise to write a separate function which interactively prompts the user for an ISBN-10 code, and tells them whether or nots it correctly formatted.



Comments on the rest of the code



Here are some things that concern me in the rest of your code:




  • You should wrap the interactive code in a if __name__ == "__main__": block. This means that it will only run if the file is executed directly, but you can also import the file to just get the function definitions (say, if you wanted to use this ISBN validator in a larger project).



  • The line while running == True:. If you're going to compare to booleans, then it's much more idiomatic to write while running is True:, or even better, while running:. But that's not a good way to do it.



    Instead, suppose you have a interactive_user_isbn() function which runs the interactive session with the user. Then at the end of that function, if they want to go again, then you can ask them, and if they do, call the function again.



    Make the repeat prompt more explicit about what will be repeated, and give them a hint about what they can type to repeat the function.



    If they type nothing, then I would err on assuming that they don't want to go again, but that's just my opinion.



    Something like:





    def interactive_user_isbn():
    # ask the user for an ISBN
    # check if it's correct
    # pay the user a compliment etc

    repeat = input("Do you want to check another number? (y/n)")
    if repeat.lower() in ["yes", "y", "ok", "sure"]:
    print("n")
    interactive_user_isbn()
    else:
    print("Okay, bye!")








share|improve this answer














share|improve this answer



share|improve this answer








edited May 23 '17 at 12:40









Community

1




1










answered Apr 30 '14 at 17:29









alexwlchanalexwlchan

8,1051552




8,1051552












  • $begingroup$
    thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
    $endgroup$
    – Oliver Perring
    May 17 '14 at 10:40










  • $begingroup$
    Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
    $endgroup$
    – Leonid
    Apr 17 '16 at 5:06


















  • $begingroup$
    thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
    $endgroup$
    – Oliver Perring
    May 17 '14 at 10:40










  • $begingroup$
    Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
    $endgroup$
    – Leonid
    Apr 17 '16 at 5:06
















$begingroup$
thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
$endgroup$
– Oliver Perring
May 17 '14 at 10:40




$begingroup$
thnx this is realy helpful and realy helps me learn a lot more about this sort of thing. while running: is a lot better way then I was using so thanks for that.
$endgroup$
– Oliver Perring
May 17 '14 at 10:40












$begingroup$
Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
$endgroup$
– Leonid
Apr 17 '16 at 5:06




$begingroup$
Should be xrange(9) I think. See this short clip: youtube.com/watch?v=5qcrDnJg-98
$endgroup$
– Leonid
Apr 17 '16 at 5:06


















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f48588%2fisbn-number-check%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...