The goals of this lab are to help you to understand:
We will demonstrate these through the following example:
If you're going to do commerce on the web, you're going to support credit cards. But how do you know if a given number is valid? And how do you know which network issued the card?
Example: Is 5300023581452982
a valid credit card number?Is it? Visa? MasterCard, Discover? or American Express?
While eventually the card number is validated when you attempt to post a transaction, there's a lot of reasons why you might want to know its valid before the transaction takes place. The most common being just trying to catch an honest key-entry mistake made by your site visitor.
So there are two things we'd like to figure out, for any "potential" card number:
If we get this code to work, it seems like it might be useful to re-use it in several other programs we may write in the future. We can do this by writing the code as a function. Think of a function as an independent program its own inputs and output. The program is defined under a name so that we can use it simply by calling its name.
Example: n = int("50")
the function int()
takes the string "50"
as input and converts it to an int
value 50
which is then stored in the value n
.
When you create these credit card functions, we might want to re-use them by placing them in a Module which is a file with a collection of functions in it. Furthermore we can take a group of related modules and place them together in a Python Package. You install packages on your computer with the pip
command.
In [ ]:
import math
dir(math)
If you look through the output, you'll see a factorial
name. Let's see if it's a function we can use:
In [ ]:
help(math.factorial)
It says it's a built-in function, and requies an integer value (which it referrs to as x, but that value is arbitrary) as an argument. Let's call the function and see if it works:
In [ ]:
math.factorial(5) #this is an example of "calling" the function with input 5. The output should be 120
In [ ]:
math.factorial(0) # here we call the same function with input 0. The output should be 1.
In [ ]:
## Call the factorial function with an input argument of 4. What is the output?
#TODO write code here.
Until this point we've used the boring print()
function for our output. Let's do better. In the IPython.display
module there are two functions display()
and HTML()
. The display()
function outputs a Python object to the Jupyter notebook. The HTML()
function creates a Python object from HTML Markup as a string.
For example this prints Hello in Heading 1.
In [ ]:
from IPython.display import display, HTML
print("Exciting:")
display(HTML("<h1>Hello</h1>"))
print("Boring:")
print("Hello")
Let's keep the example going by writing two of our own functions to print a title and print text as normal, respectively.
Execute this code:
In [ ]:
def print_title(text):
'''
This prints text to IPython.display as H1
'''
return display(HTML("<H1>" + text + "</H1>"))
def print_normal(text):
'''
this prints text to IPython.display as normal text
'''
return display(HTML(text))
Now let's use these two functions in a familiar program!
In [ ]:
print_title("Area of a Rectangle")
length = float(input("Enter length: "))
width = float(input("Enter width: "))
area = length * width
print_normal("The area is %.2f" % area)
Now that we know a bit about Packages, Modules, and Functions let me expand your horizons a bit. There's a whole world of Python code out there that you can use, and it's what makes Python the powerful and popular programming language that it is today. All you need to do to use it is read!
For example. Let's say I want to print some emojis in Python. I might search the Python Package Index https://pypi.org/ for some modules to try.
For example this one: https://pypi.org/project/emoji/
Let's take it for a spin!
In [ ]:
!pip install emoji
Once the package is installed we can use it. Learning how to use it is just a matter of reading the documentation and trying things out. There are no short-cuts here! For example:
In [ ]:
# TODO: Run this
import emoji
print(emoji.emojize('Python is :thumbs_up:'))
print(emoji.emojize('But I thought this :lab_coat: was supposed to be about :credit_card: ??'))
In [ ]:
## TODO: Write your code here
Now that we know a bit about Packages, Modules, and Functions let's attempt to write our first function. Let's tackle the easier of our two credit card related problems:
This problem can be solved by looking at the first digit of the card number:
So for card number 5300023581452982
the issuer is "MasterCard".
It should be easy to write a program to solve this problem. Here's the algorithm:
input credit card number into variable card
get the first digit of the card number (eg. digit = card[0])
if digit equals "4"
the card issuer "Visa"
elif digit equals "5"
the card issuer "MasterCard"
elif digit equals "6"
the card issuer is "Discover"
elif digit equals "3"
the card issues is "American Express"
else
the issuer is "Invalid"
print issuer
Turn the algorithm into python code
In [ ]:
## TODO: Write your code here
IMPORTANT Make sure to test your code by running it 5 times. You should test issuer and also the "Invalid Card" case.
It would be nice to re-write this code to use a function. This can seem daunting / confusing for beginner programmers, which is why we teach the Write - Refactor - Test - Rewrite approach. In this approach you write the ENTIRE PROGRAM and then REWRITE IT to use functions. Yes, it's inefficient, but until you get comfotable thinking "functions first" its the best way to modularize your code with functions. Here's the approach:
We already did step 1: Write so let's move on to:
Let's strip the logic out of the above code to accomplish the task of the function:
str
str
To help you out we've written the function stub for you all you need to do is write the function body code.
In [ ]:
def CardIssuer(card):
'''This function takes a card number (card) as input, and returns the issuer name as output'''
## TODO write code here they should be the same as lines 3-13 from the code above
# the last line in the function should return the output
return issuer
You wrote the function, but how do you know it works? The short answer is unless you write code to test your function you're simply guessing!
Testing our function is as simple as calling the function with input values where WE KNOW WHAT TO EXPECT from the output. We then compare that to the ACTUAL value from the called function. If they are the same, then we know the function is working as expected!
Here are some examples:
WHEN card='40123456789' We EXPECT CardIssuer(card) to return Visa
WHEN card='50123456789' We EXPECT CardIssuer(card) to return MasterCard
WHEN card='60123456789' We EXPECT CardIssuer(card) to return Discover
WHEN card='30123456789' We EXPECT CardIssuer(card) to return American Express
WHEN card='90123456789' We EXPECT CardIssuer(card) to return Invalid Card
Write the tests based on the examples:
In [ ]:
# Testing the CardIssuer() function
print("WHEN card='40123456789' We EXPECT CardIssuer(card) to return Visa ACTUAL", CardIssuer("40123456789"))
print("WHEN card='50123456789' We EXPECT CardIssuer(card) to return MasterCard ACTUAL", CardIssuer("50123456789"))
## TODO: You write the remaining 3 tests, you can copy the lines and edit the values accordingly
In [ ]:
# TODO Re-write the program here, calling our function.
Step on the accellerator and the car goes. How does it work? Who cares, it's an abstraction! Functions are the same way. Don't believe me. Consider the Luhn Check Algorithm: https://en.wikipedia.org/wiki/Luhn_algorithm
This nifty little algorithm is used to verify that a sequence of digits is possibly a credit card number (as opposed to just a sequence of numbers). It uses a verfication approach called a checksum to as it uses a formula to figure out the validity.
Here's the function which given a card will let you know if it passes the Luhn check:
In [ ]:
# Todo: execute this code
def checkLuhn(card):
''' This Luhn algorithm was adopted from the pseudocode here: https://en.wikipedia.org/wiki/Luhn_algorithm'''
total = 0
length = len(card)
parity = length % 2
for i in range(length):
digit = int(card[i])
if i%2 == parity:
digit = digit * 2
if digit > 9:
digit = digit -9
total = total + digit
return total % 10 == 0
In order to test the checkLuhn()
function you need some credit card numbers. (Don't look at me... you ain't gettin' mine!!!!) Not to worry, the internet has you covered. The website: http://www.getcreditcardnumbers.com/ is not some mysterious site on the dark web. It's a site for generating "test" credit card numbers. You can't buy anything with these numbers, but they will pass the Luhn test.
Grab a couple of numbers and test the Luhn function as we did with the CardIssuer()
function. Write at least to tests like these ones:
WHEN card='5443713204330437' We EXPECT checkLuhn(card) to return True
WHEN card='5111111111111111' We EXPECT checkLuhn(card) to return False
In [ ]:
#TODO Write your two tests here
Finally use your two functions to write the following program. It will ask for a series of credit card numbers, until you enter 'quit' for each number it will output whether it's invalid or if valid name the issuer.
Here's the Algorithm:
loop
input a credit card number
if card = 'quit' stop loop
if card passes luhn check
get issuer
print issuer
else
print invalid card
In [ ]:
## TODO Write code here
Please answer the following questions. This should be a personal narrative, in your own voice. Answer the questions by double clicking on the question and placing your answer next to the Answer: prompt.
Answer:
Answer:
Answer:
1 ==> I can do this on my own and explain how to do it.
2 ==> I can do this on my own without any help.
3 ==> I can do this with help or guidance from others. If you choose this level please list those who helped you.
4 ==> I don't understand this at all yet and need extra help. If you choose this please try to articulate that which you do not understand.
Answer:
In [ ]:
# SAVE YOUR WORK FIRST! CTRL+S
# RUN THIS CODE CELL TO TURN IN YOUR WORK!
from ist256.submission import Submission
Submission().submit()