[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Fwd: Please Forward: Ruby Quiz Submission

James Gray

5/2/2007 1:14:00 AM

Begin forwarded message:

> From: Alex Wayne <alex@beautifulpixel.com>
> Date: May 1, 2007 8:08:59 PM CDT
> To: submission@rubyquiz.com
> Subject: Please Forward: Ruby Quiz Submission
>
> A simple approach. It has 2 classes. One class parses the card
> number, the other provides a command line interface to the first
> class. The harder part (the Luhn calculation) is heavily commented
> for clarity.
>
> For brevity on the command line, I named the program ccinfo.rb.
> The long winded "cc_validator_class.rb" is for the library that
> does allthe heavily lifting but is not called directly. To use it
> stick both files in a directory and type:
>
> ruby ccinfo.rb 4111111111111111
>
> Thanks for the quizzes!
>
> -Alex Wayne
> http://beautifu...
> class CCValidator
>
> attr_reader :number, :card_type
>
> def initialize(number)
> @number = number.to_s
> @card_type = parse_type(number)
> @valid = parse_valid(number)
> end
>
> def valid?
> @valid
> end
>
> private
>
> # A simple Regex case statement returns the card type
> def parse_type(number)
> case number
> when /^3(4|7)\d{13}$/
> :amex
> when /^6011\d{12}$/
> :discover
> when /^5[1-5]\d{14}$/
> :mastercard
> when /^4(\d{12}|\d{15})$/
> :visa
> else
> :unknown
> end
> end
>
> # Calculate number validity
> def parse_valid(number)
> # Rather than starting to double on the second to last
> number, we decide wether or
> # not we can start on the first number by how many digits the
> number has. If it's
> # even the first number gets double and then every other
> number after. If it's odd
> # start double on the second digit, thereby "offset"-ing the
> progression.
> offset = (number.size % 2 == 0) ? 0 : 1
>
> # covert number string to an array of integer digits.
> digits = number.split('').collect { |digit| digit.to_i }
>
> # Iterate through the digit array, double every other digit.
> Each is not used here
> # because we need to keep track of the index and stuff the
> result back in the original
> # array.
> digits.size.times do |i|
> if (i + offset) % 2 == 0
> digits[i] = digits[i] * 2
> end
> end
>
> # convert array with doubled integer digits, into strings.
> Then split all elements
> # back into single digits.
> digits = digits.collect { |digit| digit.to_s.split('') }
>
> # Flatten the potentialilly nested arrays and convert all
> digits back to integers for
> # addition.
> digits = digits.flatten.collect { |digit| digit.to_i }
>
> # Add up the digits and see if the result is a multiple of
> 10, proving that the card
> # number is valid.
> digits.inject(0) { |sum, digit| sum + digit } % 10 == 0
> end
>
> end
> require "cc_validator_class"
>
> class CCValidator
> class CommandLine
> def initialize
> if @number = ARGV.shift
> write_output
> else
> write_usage
> end
> end
>
> def write_output
> result = CCValidator.new(@number)
> puts <<-OUTPUT
> ===============================
> Credit Card Validator
>
> Card Number: #{result.number}
>
> Type: #{result.card_type.to_s.capitalize}
> Valid: #{result.valid? ? 'YES' : 'NO'}
>
> OUTPUT
> end
>
> def write_usage
> puts <<-USAGE
> ===============================
> Credit Card Validator
>
> This program will tell the type of credit card and if the number is
> valid. To use, simply
> provide a credit card number on the command line, and the results
> will be immediately
> displayed.
>
> EXAMPLE:
> ruby ccinfo.rb 4111111111111111
>
> USAGE
> end
> end
> end
>
> CCValidator::CommandLine.new