# 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 f 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_part2.py`, and `creditcard_tester.py`). Copy both files into the (recently created) `CSCI051p-Workspace/CreditCards` folder. <a name="part1"></a> ## 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. #### `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 ``` <a name="checkin"></a> ####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. <a name="part2"></a> ## 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. You can read about the algorithm in [this article](http://www.dirigodev.com/blog/ecommerce/anatomy-of-a-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).<br/> `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.<br/> `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 you can also use those functions from Part 1 to implement your solutions! #### Verify The `verify` function takes a 13 digit integer as input and returns `True` if the number passes the Luhn algorithm amd `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 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 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: 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? <a name="submission"></a> ## Submission For this lab, you are required to submit three files: - `creditcard.py` a Python file implmenting the functions described in Part 2 - `creditcard_tester.py` your test file - `feedback.txt` a text file containing your feedback from this assignment These should be submitted using [submit.cs](http://submit.cs.pomona.edu) as one submission with three files. ## Grade Point Allocations | Part | Feature | Value | |-----------|----------------------------------------| ----- | | Lab | Check-in | 3 | | Execution | Verify is correct | 10 | | Execution | Generate is correct | 10 | | Execution | Main is correct | 4 | | Testing | Thorough test cases for Verify and Generate | 4 | | Style | Correctly named files | 1 | | Style | Files submitted together | 1 | | Style | Correct file-level comment | 1 | | Style | Docstrings in functions | 3 | | Style | Good use of inline comments | 3 | | Style | Good use of variable names and whitespace | 3 | | Feedback | Completed feedback file submitted | 2 |