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