# Credit cards
The goal of this assignment is to give you more practice with functions,
including testing functions and modeling function call behavior with stack
frames. For this assignment, you will implement functions that take a variety
of parameter types and return a variety of types.
| Part | Section |
|---------------|-----------------------------------------------|
| 1 (in-lab) | [Practice with Functions](#part1) |
| 1 (in-lab) | [Check-in Instructions](#checkin) |
| 2 (lab/home) | [More functions](#part2) |
| 2 (lab/home) | [Submission Instructions](#submission) |
## Getting started
Create a new project named `CreditCards` in the `CSCI051p-Workspace` you
created on your Desktop. *Double check that you are creating the project in
the right place, or you will likely have trouble finding your files later.*
Then download the [starter code](cc.zip), and unzip the file (on a Mac,
unzipping will happen automatically). You should see a folder named `starter`
that contains three files (`creditcard_part1.py`, `creditcard.py`, and
`creditcard_tester.py`). Copy all the files into the (recently created)
`CSCI051p-Workspace/CreditCards` folder.
## Part 1: Helper Functions
#### What to implement
Open the file `creditcard_part1.py`. Your job for Part 1 is to implement the
four functions in that file.
#### last_digit
Implement the helper function `last_digit` which takes a positive integer and
returns the last digit of that integer.
When you believe your function is working correctly, open the file
`creditcard_tester.py`. You should see at the top that this file imports
functions from the other two files. The `main` function in file
`creditcard_tester.py` contains a bunch of `assert` statements. The `assert`
statement evaluates a boolean expression; if that expression evaluates to
`False`, the `assert` statement throws an error. This allows us to
programatically test our functions! Try running the file
`creditcard_tester.py`; if it prints `last_digit passed`, then your
implementation of `last_digit` should be correct!
#### decimal_right_shift
Go back to the file `creditcard_part1.py` and implement the function
`decimal_right_shift`, which takes an integer and returns the number
constructed by removing the last digit. For example,
`decimal_right_shift(123)` should evaluate to `12`
When you believe your function is working correctly, re-run the file
`creditcard_tester.py`. This time it should pass the second batch of tests!
#### sum_digits
Go back to the file `creditcard_part1.py` and implement the function
`sum_digits`, which takes a 3-digit integer as a parameter and returns the
(integer) sum of the digits. You may assume that the value passed as an
arugment to sum_digits is always a positive 3-digit integer.
Hint: you will want to use the functions `last_digit` and
`decimal_right_shift` as helper functions! Remember to add a docstring for
this function.
Note that for `sum_digits`, the tester file only includes one assert
statement, `assert False`. This will always throw an error! Replace this
line with a set of assert statements that thoroughly test your `sum_digits`
function, and convince yourself that your implementation is correct.
**Note: you need to read the test cases for `last_digit` and `decimal_right_shift`,
and learn to create the test cases for `sum_digits`**
#### `main`
Implement the `main` function in `creditcard_part1.py`, which should
repeatedly asks the user for a 3-digit positive integer until
they do so and then print the sum of those digits (obtained by calling
`sum_digits`). Remember to add a docstring for your main function!
Hint: you will want to allow users to enter the string `"000"`, so you can't
use the integer value to test whether the user has entered a string with the
right number of digits. Instead, you should use the function `len`, which
takes a string as an argument and returns the number of characters in that
string.
Note: since main functions don't take arguments and always return `None`, we
can't programmatically test them for correctness the way we test other
functions. Instead, you should just convince yourself that your `main`
function behaves correctly.
##### Sample run
```
Please enter a 3-digit positive integer:
257
The sum of the digits of 257 is 14
```
####Checking in
Before finding a TA or professor, make sure your functions have
- appropriate docstrings
- good algorithm comments
- mnemonic variable names
- good use of horizontal and vertical white space
We will double check your code and your test cases, ask you a few questions
about it,
answer any questions you have, and award your points for Part 1.
This must be completed before leaving the lab.
After that you should start working on Part 2.
## Part 2: Credit Card Numbers
####Background Information - Valid credit card numbers
What makes a credit card number valid? For our purposes, we'll assert
that a number is valid if it passes the Luhn algorithm.
(In practice there are also additional restrictions. For example,
all Visa cards must start with the number 4)
An algorithm is a set of instructions for accomplishing a specific task, so the
Luhn algorithm is a set of instructions for checking whether a number
is potentially a valid credit card number.
To see how the Luhn algorithm works, let us use it to validate the number
`9813428854407`:
1. Double the value of alternate digits of the credit card number
beginning with the second digit from the right (the first right-hand
digit is the check digit).
`9 16 1 6 4 4 8 16 5 8 4 0 7`
2. Add the individual digits comprising the products obtained in
Step 1 to each of the unaffected digits in the original number.
`9 + (1+6) + 1 + 6 + 4 + 4 + 8 + (1+6) + 5 + 8 + 4 + 0 + 7 = 70`
3. If the total obtained in Step 2 is a number ending in zero
(`30, 40, 50`, etc.), then the account number is valid.
`70` ends in a `0`, so the account number is valid.
Before you continue, please make sure you fully understand the Luhn
algorithm and how it checks numbers for validity! It doesn't make
sense to try to implement an algorithm until you understand how it
works. (Please feel free to discuss the algorithm with other students,
the TAs, the professors, etc!)
Make sure you understand it well enough to answer the following questions:
- Is `1234567890123` a valid number?
-If the first 12 digits of a 13-digit credit card number are
`111111111111`, what must the 13th digit be?
#### Specifications
All the code for this assignment should implemented in the file
`creditcard.py`. Please
read the assignment specification carefully to make sure that you submit all
the required components.
Your program will ask the user for a 6 digit number, then generate
three valid 13 digit credit card numbers each starting with those
initial 6 digits.
Your program must implement the following functions. You may also choose to
define additional functions, if you'd like. For example, you could define a
helper function that computes the Luhn sum for a number. If you do define any
helper functions, we strong encourage you to add test cases for your helper
functions!
Note:
- The line at the top of
`creditcard.py` imports the functions `last_digit` and `decimal_shift_right`
from the file `creditcard_part1.py`, so your program should make use of the helper functions from `creditcard_part1.py` --- don't reinvent the wheel !! Failing to call helper functions when appropriate will result in a loss of style points.
- **All of your processing MUST be on integers. In other words, your functions must not convert their integer parameters into strings.**
#### Luhn Sum
The `luhn_sum` function takes a 13 digit integer as input and returns the Luhn
sum of that number (i.e., the value you get at the end of Step 2 above).
Hint: You'll want to use the functions you defined in Part 1! Also, remember to add a docstring!
#### Verify
The `verify` function takes a 13 digit integer as input and returns `True`
if the number passes the Luhn algorithm and `False` if it fails.
After you think your function is working correctly, you should add test cases
to `creditcard_tester.py` and run them to convince yourself this function is
working correctly. Remember that a thorough set of test cases should include at
least one test case for every branch of your code (white-box testing) as well
as test cases for the corner cases (black-box testing). You may also find it helpful to use a [website](https://planetcalc.com/2464) to verify whether numbers actually satisfy the Luhn algorithm.
Hint: remember to use the functions you've defined thus far and to add a docstring for your function!
#### Generate
The `generate` function takes a 6 digit integer and returns a valid 13 digit
credit card number which begins with the given 6 digits. The return value
must be of type `int`.
Hint: the 6 randomly generated digits must be selected from the full
range from 0 through 9.
After you think your function is working correctly, you should add test cases
to `creditcard_tester.py` and run them to convince yourself this function is
working correctly. Remember that a thorough set of test cases should include at
least one test case for every branch of your code (white-box testing) as well
as test cases for the corner cases (black-box testing).
Hint: remember to use the functions you've defined thus far and to add a docstring for your function!
#### Main
The `main` function asks the user for an initial 6 digit number,
then generates and prints three valid credit card numbers that start
with those 6 numbers. See example run below. Remember to add a docstring for
your main function!
#### Example Run
```
Enter a 6 digit number:
981342
Three valid numbers:
9813428854407
9813424039581
9813420046028
```
#### Hints and Suggestion
Some questions to think about before you start writing code:
- The Luhn algorithm works on digits, but the `verify` and `generate` functions
take integers. You will want to use your helper functions from Part 1 to break
integers into digits.
- Having generated digits, how will you reassemble them into a number?
#### Random Numbers
Python is popular in part because there are many modules and packages
that are available to use. If, for example, you need to generate
random numbers, you can use the `random` module.
In order to do so, you first need to tell the interpreter that you want to
use that module. There are different ways to do this, but the one
we'll use requires naming the exact functions that we want from the
`random` module.
Taking a look at the `random` [documentation](https://docs.python.org/3/library/random.html), we see that `randint` will enable us to generate a
random
integers within a given range. To use this we must add the following line at
the beginning of our program (right after that multi-line comment that's at the
top of all our programs):
```
from random import randint
```
This allows us to use the `randint` function as if it was defined in our code.
#### Coding style
Make sure that your program is properly commented:
- You should have comments at the very beginning of the file stating your name,
course, assignment number and the date.
- Each function should have an appropriate docstring, describing:
* the purpose of the function
* the types and meanings of each parameter
* the type and meaning of the return value(s)
- Include other comments as necessary to make your code clear
In addition, make sure that you've used good style. This includes:
- Following naming conventions, e.g. all variables and functions should be
lowercase.
- Using good (mnemonic) variable names.
- Proper use of whitespace, including indenting and use of blank lines to
separate chunks of code that belong together.
## Part 3: Ethical Reflection
Collecting and storing credit card information is considered risky because
ensuring security is hard, and users can experience significant real-world
harms (e.g., financial loss or identity theft) if hackers manage to steal this
information. For this reason, many small businesses contract with third-party
companies to handle credit card payments.
CoolGamzRUs decides to add in-app purchases to their game, and they want to
contract with a third-party company to handle payments. They've identified
three possible companies that offer the sort of service they're looking for:
1. Company A is a large, multi-national tech company that offers many different
types of products and services. Their services, including their payment
processing feature, are used by many apps and other small businesses. However,
their market dominance means that they can track where people spend money
(and how much money they spend) across all apps, websites, and companies that
use their services.
2. Company B is a medium-size financial services company. They are known for
offering an array of financial services directly to consumers and also offer
a payment-processing service for small businesses. However, they recently
disclosed to the U.S. Federal Trade Commission (FTC) that they suffered a data
breach in which hackers stole information about 5 million of their users.
3. Company C is a small start-up company trying to break into the payment
processing space. You don't know of any businesses that currently use their
payment processing services.
From an ethical perspective, what factors should CoolGamzRUs consider when
deciding which third-party company to contract with? You may consider the types
of information provided or other information. Which of these companies would
you recommend and why? If you want, your answer may be conditional depending on
other information about these companies that was not provided.
## Part 4: Feedback
Provide a file named `feedback.txt` that answers the usual questions:
1. How long did you spend on this assignment? Please include time spent
during lab, including time spent on Part 1.
2. Any comments or feedback? Things you found interesting? Things you found
challenging? Things you found boring?
## Submission
For this lab, you are required to submit three files:
- `creditcard_part1.py` a Python file implmenting the functions described in Part 1
- `creditcard.py` a Python file implmenting the functions described in Part 2
- `creditcard_tester.py` your test file
- `ethics.txt` your short ethical reflection
- `feedback.txt` a text file containing your feedback from this assignment
These should be submitted using
[Gradescope](https://www.gradescope.com).
## Grade Point Allocations
| Part | Feature | Value |
|-----------|----------------------------------------| ----- |
| Lab | Check-in | 3 |
| Execution | Luhn_sum is correct | 10 |
| Execution | Verify is correct | 10 |
| Execution | Generate is correct | 10 |
| Execution | Main is correct | 5 |
| Testing | Thorough test cases for luhn_sum, verify, generate | 6 |
| Style | Correctly named files | 1 |
| Style | Files submitted together | 1 |
| Style | Correct file-level comment | 1 |
| Style | Docstrings in functions | 4 |
| Style | Good use of inline comments | 4 |
| Style | Good use of variable names and whitespace | 4 |
| Style | Good use of conditionals and loops | 4 |
| Style | Good use of function calls | 4 |
| Ethics | Completed ethical reflection file | 2 |
| Feedback | Completed feedback file submitted | 2 |