# 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. <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. **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 ``` <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. 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 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 |