P01 – 可审计银行业务
- 该作业将于2018年9月14日星期四晚上10点之前完成。
- 是什么意思?网网求允许配对编程,但此配置不需要。请在9月10日星期一晚上10点之前注册您的合作伙伴,与合作伙伴合作。如果您在访问此表单时遇到问题,请尝试按照此处的建议操作。
通过这项任务,您将实施一个简单的银行会计系统。该系统中的一个复杂因素是银行交易(存款和取款)可以用三种不同方式之一在内部表示。在CS300中,比较和对比不同的数据表示和不同的数据结构将是一个反复出现的主题。
目标和评分标准
该编程任务的主要目标包括:
- 检查数组和面向过程的代码的使用(本课程的先决条件),
- 使用相同数据的多个不同表示,
- 开发测试以演示代码的功能,并熟悉CS300分级测试。
15分3 zyBooks测试:这些自动评分测试结果在提交时可见,并允许多个机会来纠正代码的组织和功能。只会在截止日期前提交您的最高得分提交。
20分4最终测试:这些自动评分测试在作业截止日期之后进行他们检查与zyBooks类似测试的功能组织状语从句:正确性但是,您将无法重新提交额外点的更正,因此应尽可能彻底地考虑并测试您自己的代码的正确性。
5分1测试测试:此自动评分测试在作业截止日期之后运行,类似于其他名单名单最终测试会它检查您的测试代码是否正确区分了工作状语从句:错误的分配实现您将无法重新提交额外积分的吐槽,因此应尽可能彻底地考虑并测试您自己的测试代码的正确性。
10分代码可读性:人类评分者将审核您最终提交的评论,状语从句:组织风格他们将检查它是否符合CS300课程风格指南的要求。您将无法重新提交额外积分的更正,因此应仔细检查您的代码对课程样式指南的可读性。
0开始
如果您还没有,请在计算机上安装Eclipse with Java 8,或者找到已安装它们的计算机。如果您在整个学期遇到任何问题,您应该使用另一台计算机按时完成您的工作(可能是这些实验室中的一台机器)。您还有责任在工作时保持进度的安全备份。与您的UW NetID关联的OneDrive和GoogleDrive帐户通常是存储此类备份的便捷且安全的位置。
在Eclipse中创建一个新的Java8项目。您可以根据需要为此项目命名,但P01可审计银行业务是一种描述性选择。在名为AuditableBanking.java的文件中创建一个名为AuditableBanking的新类。在您提交作业以获得此作业的自动评分测试的反馈之前,需要这些确切的名称。不应在自定义程序包中组织此分配的代码(它应全部保留在默认程序包中)。如果您需要提醒或介绍如何使用Eclipse,请参阅这些说明。
将这个作业的代码提交给zybooks中的自动评分测试会很有帮助。这将1)在截止日期前给你时间来修复测试检测到的任何缺陷,2)为您提供工作的额外备份,以及3)通过实施任务来帮助跟踪您的进度。这些测试旨在检测并提供有关非常特定类型的缺陷的反馈。您有责任进行其他测试,以验证其余代码是否按照此文章的规定运行。
您还应该查看CS300课程风格指南,以查看样式和记录代码的要求(占该分配要点的20%)。如果您不熟悉的的的的的的的的的的的的的的的的的JavaDoc的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的中的样式注释,则zyBook部分1.2包含一些其他详细信息。
1.提交新的交易
由于该程序的工作是存储和审计事务,我们将讨论如何在程序中提交和存储这些事务。交易组将一起提交,并且这些组中的每一个将由完整大小的原始整数数组表示(有关完美大小和超大数组的更多信息,请参阅zybooks 1.4 -1.7)。稍后我们将看到这些整数的编码可能会因一组事务而异,因此跟踪每组事务与其他事务的区别非常重要。这些事务组的集合将由超大的事务组数组(或完美大小的整数数组)表示。
。我们将实现的第一种方法将完美大小的事务数组添加到一个完美大小的整数数组的超大数组中此方法的签名行为状语从句:必须与以下内容完全匹配:
/**
* Adds a transaction group to an array of transaction groups. If the allTransactions array is
* already full then this method will do nothing other than return allTransactionCount.
*
* @param newTransactions is the new transaction group being added (perfect size).
* @param allTransactions is the collection that newTransactions is being added to (oversize).
* @param allTransactionsCount is the number of transaction groups within allTransactions
* (before newTransactions is added.
* @return the number of transaction groups within allTransactions after newTransactions is added.
*/
public static int submitTransactions(int[] newTransactions, int[][] allTransactions,
int allTransactionsCount) {
return -1;
}
实现此方法后,您应该创建一个名为AuditableBankingTests的空类定义的文件。然后,您可以将这两个文件提交给zybooks,并确保它们通过了第一个zybooks测试。如果没有,请在继续之前纠正他们报告的任何缺陷。
2.交易编码和处理指令
如在先前步骤中提到的,可以以不同方式在整数阵列内编码不同的事务组。以下是我们的程序必须支持的三种编码的描述。
- 二进制金额事务:当事务组数组中的第一个数字(索引为零)为零时,该数组中的其余数字表示编码为二进制金额事务的事务。每个二元金额交易是零或一问鼎代表1美元的存款,零代表1美元的提款。在此类事务数组中找到的任何其他数字都表示错误,但我们不会测试您的代码如何响应此类错误,因此您可以忽略它们。
- 整数金额交易:当事务组数组中的第一个数字(索引为零)为1时,该数组中的其余数字表示编码为整数金额交易的交易。整数金额交易可以是正整数或负整数。正整数表示指定整数金额的存款,负整数表示指定金额的提取。在此类事务中找到的任何零都表示错误,但我们不会测试您的代码如何响应此类错误,因此您可以忽略它们。
- Quick Withdraw Transactions: When the first number (at index zero) within a transaction group is two, the rest of the numbers in that array represent transactions encoded as Quick Withdraw Transactions. The non-negative integer numbers within quick withdraw transaction arrays represent the numbers of withdraws, rather than the amounts of withdraws (as was the case with the previous encoding). The amounts for quick withdraws are fixed at $20, $40, $80, and $100. And the number of withdraws of each amount is stored at indexes one, two, three, and four respectively. This means that the size of every quick withdraw array should be five. Arrays of other sizes, and negative withdraw amounts both represent errors, but we will not test how your code responds to such errors, so you can ignore them.
For the purpose of this program, the user will enter each group of transactions as a string of integers separated by spaces, which conforms to one of these three encoding standards. For example, they might enter this string containing a binary amount transaction:
0 1 0 0 1 1 1 0 1
Define a new method called processCommand that takes such a string as command/input, and correctly adds a new transaction group to the provided set of transactions groups. When the first character within a command does not correspond to a valid transaction encoding or the allTransactions array starts out full, this method should not make any changes to allTransactions. Note in the required method signature below, that this method returns an int (as is required to keep track of the potentially growing size of our oversize array):
public static int processCommand(String command, int[][] allTransactions, int allTransactionsCount) { // TODO: Implement this method return -1;}
The following methods from the Java8 API may be helpful in implementing this processCommand method:
- Integer.parseInt(string) – returns an integer encoding of the number represented by the string input.
- string.trim() – returns a new copy of the string this method is called on, but without any leading or trailing whitespace.
- string.split(” “) – breaks the string this method is called on into parts around each space, and returns all of those parts as a single array of strings.
Since it is currently difficult to tell whether this method is working, we are going to write a test method within AuditableBankingTests to help us verify this. Add a method to this class with the following signature:
public static boolean testProcessCommand() {
// TODO: Implement this method
return false;
}
This test method should test AuditablBankingTests.processCommand by passing in some hard-coded arguments (a command like “0 0 1 1 0 1 1” into an oversize array containing two prior transaction groups) and checking whether the return value and contents of allTransactions match the specified behavior (like allTransactions[2][2] == 1). Try checking for at least two very specific defects within in this test, and keep this test code as simple as possible to avoid the likelihood of confounding bugs within your tests. This method should print out feedback about any defects that it finds. In addition to this feedback for human eyes, this method should return false when any defects are found and true when none are found. Create a main method within your AuditableBankingTests class to run this test (and additional tests that you add in the future).
3. AUDITING TRANSACTIONS
Next, we’ll implement a method to calculate and return the total account balance based on a collection of provided transaction groups. Here is the required signature for this method (to be implemented within AuditableBanking.java), along with the signature of a corresponding test method (to be implemented within AuditableBankingTests.java).
public static int calculateCurrentBalance(int[][] allTransactions, int allTransactionsCount) {
// TODO: Implement this method
return -1;
}
public static boolean testCalculateCurrentBalance() {
// TODO: Implement this method
return false;
}
Another form of auditing that we would like to perform on collections of transaction groups is to count the number of overdrafts. An overdraft is when a withdraw is made that results in a negative balance. To detect overdrafts, you’ll need to process collections of transaction groups in order of increasing indexes starting at zero. Within each group of transactions, you should processes transactions in order of increasing indexes too. Here is the signature of the method that you must implement, along with some test code to add to your AuditableBankingTests class. These tests should help you verify your own understanding of the required method’s behavior, and should also help you begin to test your implementation of it.
Another form of auditing that we would like to perform on collections of transaction groups is to count the number of overdrafts. An overdraft is when a withdraw is made that results in a negative balance. To detect overdrafts, you’ll need to process collections of transaction groups in order of increasing indexes starting at zero. Within each group of transactions, you should processes transactions in order of increasing indexes too. Here is the signature of the method that you must implement, along with some test code to add to your AuditableBankingTests class. These tests should help you verify your own understanding of the required method’s behavior, and should also help you begin to test your implementation of it.
public static int calculateNumberOfOverdrafts(int[][] allTransactions, int allTransactionsCount) {
// TODO: Implement this method
return -1;
}
public static boolean testCalculateNumberOfOverdrafts() {
boolean foundProblem = false;
int[][] transactions = new int[][] {
{1,10,-20,+30,-20,-20}, // +2 overdrafts (ending balance: -20)
{0,1,1,1,0,0,1,1,1,1}, // +2 overdrafts (ending balance: -15)
{1,115}, // +0 overdrafts (ending balance: +100)
{2,3,1,0,1}, // +1 overdrafts (ending balance: -100)
};
// test with a single transaction of the Integer Amount encoding
int transactionCount = 1;
int overdrafts = AuditableBanking.calculateNumberOfOverdrafts(transactions,transactionCount);
if(overdrafts != 2) {
System.out.println("FAILURE: calculateNumberOfOverdrafts did not return 2 when transactionCount = 1, and transactions contained: "+Arrays.deepToString(transactions));
foundProblem = true;
} else
System.out.println("PASSED TEST 1/2 of TestCalculateNumberOfOverdrafts!!!");
// test with four transactions: including one of each encoding
transactionCount = 4;
overdrafts = AuditableBanking.calculateNumberOfOverdrafts(transactions,transactionCount);
if(overdrafts != 5) {
System.out.println("FAILURE: calculateNumberOfOverdrafts did not return 5 when transactionCount = 4, and transactions contained: "+Arrays.deepToString(transactions));
foundProblem = true;
} else
System.out.println("PASSED TESTS 2/2 of TestCalculateNumberOfOverdrafts!!!");
return !foundProblem;
}
After you get these two methods working revisit your definition of the processCommand method. Update this method to calculate and print out the balance when the first non-white-space character within the command string is a B (upper or lower case), and to calculate and print out the number of overdrafts when the first non-white-space character within the command string is an O (upper or lower case). The following methods from the Java8 API may be helpful in updating the processCommand method in this way:
- string.charAt(index) – returns the character at the specified zero-based index from within this string.
- string.toUpperCase() – returns a new copy of the string this method is called on, but with an upper case version of each alphabetic character.
4. THE DRIVER APPLICATION
The last step of this assignment is to implement a nice text-based interface to access and “drive” the program. Organize this functionality into whatever custom static methods you see fit, but ensure that running the main method within your AuditableBanking class results in an interaction logs comparable to the sample shown below. All of your variables should be local to some static method (no class or instance fields are allowed), unless they are constants marked with the keyword final. Pay close attention to the details within the example log below, to ensure that your program’s welcome message, thank you message, command prompts, current balance, and overdraft numbers are all printed in the same manner. You do not need to worry about erroneous input from the user, because all of our grading tests will focus on properly encoded commands, as described within this specification. The user should be able to submit at least 100 transaction groups. Note that the user’s input below is shown in red, and that the rest of the text below was printed out by the program.
========== Welcome to the Auditable Banking App ==========
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: 0 1 1 0 0 0 1 1
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: 1 -10 +100
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: 2 2 1 0 0
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: B
Current Balance: 11
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: o
Number of Overdrafts: 2
COMMAND MENU:
Submit a Transaction (enter sequence of integers separated by spaces)
Show Current [B]alance
Show Number of [O]verdrafts
[Q]uit Program
ENTER COMMAND: q
============ Thank you for using this App!!!! ============
5. ASSIGNMENT SUBMISSION
Congratulations on finishing this first CS300 assignment! After verifying that your work is correct, and written clearly in a style that is consistent with the course style guide, you should submit your work through zybooks. The most recent of your highest scoring submissions made before the deadline of 10:00PM on Thursday, September 13th will be record as your zybooks test score. The other portion of your grade for this assignment will be determined by running that same submission against addition automated grading tests after the submission deadline. Remember that students working with a partner in accordance with the Pair Programming Policy must each submit their shared work to zybooks, and that either partner’s submission may be used to generate these scores for both partners.
6. EXTRA CHALLENGES
If you would like to extend the functionality of this assignment beyond what is required, please make such changes in a separate copy of your project. Do NOT submit such extensions using zyBooks.
- 使用旧的二进制金额交易编码,通常将20美元的提款编码为二十个零。虽然这些交易对账户的净余额产生相同的影响,但透支的数量可能会大不相同。尝试在您的程序中考虑到这一点,将二元金额交易中的任意数量的连续0计为单次提款,以便计算透支。
- 另一个有趣的计算金额是账户交易历史记录中的最大余额。请注意实现此功能的代码中的任何冗余与其他审核方法相比。如果您还没有学习工具来概括和重用这些方法的共性,那么未来的CS300主题可能会有所帮助。
- 必须为每组事务输入编码类型(第一个数字)并不总是必要的。实现一个替代的processCommand实现,在它能够时推断并附加编码类型。开发一些标准以避免可能的编码之间的混淆可能会有所帮助,例如:在可变数量编码的末尾附加零,否则将四个数字长,以帮助将其与快速提取编码区分开来。