-
-
Save jamiefdhurst/3181897 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby | |
def is_valid_isbn13?(isbn13) | |
sum = 0 | |
13.times { |i| sum += i % 2 == 0 ? isbn13[i].to_i : isbn13[i].to_i * 3 } | |
0 == sum % 10 | |
end | |
puts "Loading file and reading ISBNs..." | |
isbns = [] | |
File.open("isbns.txt", "r").each_line do |line| | |
isbns.push(line) | |
end | |
puts "Cleaning ISBNs..." | |
isbns.collect! do |isbn| | |
isbn = isbn.scan(/\d/).join('') | |
end | |
puts "Checking ISBNs..." | |
isbns.each do |isbn| | |
sum = 0 | |
if (isbn.length != 13 or is_valid_isbn13?(isbn) == false) | |
puts " - #{isbn} is invalid..." | |
isbns.delete(isbn) | |
else | |
puts " - #{isbn} is valid..." | |
end | |
end |
If you're struggling with that first method, maybe this helps:
I guess you're struggling with this line:
13.times { |i| sum += i % 2 == 0 ? isbn13[i].to_i : isbn13[i].to_i * 3 }
13.times {}
means to execute the block every time, and |i|
denotes i
to be the counter. Within the block you've got a ternary operation:
sum += i % 2 == 0 ? isbn13[i].to_i : isbn13[i].to_i * 3 }
Ternary operators work like so:
someVar = x > 2 ? 1 : 2
which is the same as:
if x > 2
someVar = 1
else
someVar = 2
So sum += i % 2 == 0 ? isbn13[i].to_i : isbn13[i].to_i * 3 }
adds isbn13[i].to_i
to sum
if i
is even, and adds isbn13[i].to_i*3
if it's not.
The reason the function has a ?
on the end is Ruby notation - any functions that return boolean should end with ?
Not sure if that's any use or not but maybe it is :P
This does the same thing and is hopefully a bit more Ruby-ish.
Hope it's useful..
#!/usr/bin/env ruby
class String
def remove_non_digits
self.scan(/\d/).join('')
end
def remove_non_digits!
replace remove_non_digits
end
def is_valid_isbn13?
isbn13 = self.remove_non_digits!
sum = 0
13.times { |i| sum += i % 2 == 0 ? isbn13[i].to_i : isbn13[i].to_i * 3 }
0 == sum % 10
end
end
File.open("isbns.txt", "r").each do |potential_isbn|
if potential_isbn.is_valid_isbn13?
message = " is a valid ISBN13"
else
message = " is not a valid ISBN 13"
end
puts potential_isbn + message
end
@richquick In:
def remove_non_digits
isbn = self.scan(/\d/).join('')
end
No need to do isbn =
as you're just returning it.
fair point. Updated.
Note: the "is_valid_isbn13?" method was provided by Wikipedia, and is bloody confusing because it uses moduli...