Assignment 3: Credit Cards

Overview

The goal of this assignment is to give you more practice with functions, conditionals, and loops, and to introduce you to software testing.

Grading Rubric

FeatureValue
verify10
generate10
main4
Test cases for verify3
Test cases for generate3
Good use of conditionals2
Good use of functions2
Good use of inline comments2
Good use of variable names and whitespace2

Part 1: Helper Functions

Create a week3 folder and open it in VS Code. Download the starter package and copy creditcard_part1.py, creditcard.py, and creditcard_tester.py into your week3 folder.

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 (as an int). (Hint: review the operators you've seen in lecture!)e

Note—do not implement this with string operations!

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 passed all of our tests and 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 integer constructed by removing the last digit. For example, decimal_right_shift(123) should evaluate to 12 and decimal_right_shift(1) should evaluate to 0.

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!

Seriously, do not implement this with string operations!

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 argument 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 to implement sum_digit! 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 ask the user for a positive integer between 100 and 999 (inclusive) and then print the sum of those digits (obtained by calling sum_digits). Remember to add a docstring for your main function!

Note: All of your processing must be on integers. In other words, after getting the input from the user, you should immediately convert it to an integer. In other words: Don't use any string operations!

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 convince yourself at the console that your main function behaves correctly.

Sample run

  Please enter a positive integer in the range 100-999:
  > 257
  The sum of the digits of 257 is 14

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.

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:

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 integer, 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!

Note: All of your processing must be on integers. In other words, your functions must not convert their integer parameters into strings. No string operations!

Note: Your program should make use of the helper functions from creditcard_part1.py—don't reinvent the wheel!

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 your own 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 to verify whether numbers actually satisfy the Luhn algorithm.

generate

The generate function takes a 6 digit integer (in the range 100000-999999) 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 as well as test cases for the corner cases.

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 from the range 100000-999999:
> 981342
Three valid numbers:
9813428854407
9813424039581
9813420046028

Hints and Suggestion

Some questions to think about before you start writing code:

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, 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:

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 has good style:

Submission

For this lab you are required to submit the following files:

Note that we will deduct points if your files are incorrectly named, if you do not include your names in the correct place, or if you do not include all the files in your last submission. Please double and triple check this before submitting!

Autograder

The autograder on Gradescope includes both simple and sophisticated test cases. The simple checks are used to make sure your program works for some basic cases and will provide an opportunity for you to improve your code before the deadline. The results of the simple checks will be shown shortly after you submit your code. A more comprehensive set of test cases will be applied to check your code after the due date and the results will be available after then. Your final grade will not be shown on Gradescope until after the assignment due date.

Note that we may adjust your autograder score and provide additional comments by reading your code in detail.

To submit multiple python source code files at once, you need to select all of them and submit them together. You can drag and drop all of them, or navigate to the appropriate directory and select all of them (using command and left click on Mac, or Ctr and left click on Windows or Linux). Please do NOT zip them or submit any zip file.