Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

General notes:

  • use if __name__ == '__main__': if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 <= len(str(number)) <= 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 <= len(str(number)) <= 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 <= len(str(number)) <= 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

added 2 characters in body
Source Link
alecxe
  • 17.5k
  • 8
  • 52
  • 93

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 <<= len(str(number)) <<= 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 < len(str(number)) < 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 <= len(str(number)) <= 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

Source Link
alecxe
  • 17.5k
  • 8
  • 52
  • 93

General notes:

  • use if __name__ == '__main__': to avoid the main() function to be executed when the module is imported
  • I'd pass around the credit card number as a string instead of converting it to string in every single validation step
  • add docstrings to each of the defined functions

Regarding check_provider() function:

  • you can check the length to be in range in one go:

    if not(13 < len(str(number)) < 16):
    
  • I would improve the way you distinguish between cards by introducing a mapping between brands and regular expressions (like it was done in pycard module). Then, match each of the expressions one by one until you find a match or a brand was not found:

    import re
    BRANDS = {
     'Visa': re.compile(r'^4\d{12}(\d{3})?$'),
     'Mastercard': re.compile(r'''
     ^(5[1-5]\d{4}|677189)\d{10}$| # Traditional 5-series + RU support
     ^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)\d{12}$ # 2016 2-series
     ''', re.VERBOSE),
     'American Express': re.compile(r'^3[47]\d{13}$'),
     'Discover': re.compile(r'^(6011|65\d{2})\d{12}$'),
    }
    def check_provider(number):
     """Checks a credit card number and returns a matching brand name, or INVALID if no brand matched."""
     for brand, regexp in BRANDS.items():
     if regexp.match(number):
     return brand
     return 'INVALID'
    

Regarding implementing the Luhn algorithm, check the pycard's implementation - it is quite clean and understandable.

lang-py

AltStyle によって変換されたページ (->オリジナル) /