General notes:
- use
if __name__ == '__main__':
if __name__ == '__main__':
to avoid themain()
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 themain()
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 themain()
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 themain()
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 themain()
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 themain()
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 themain()
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.