CSCI 1103 Project 4: Portfolio's as Objects
- Due: 11:59pm Wed 11/15/2017
- Approximately 5.0% of total grade
- Submit to Canvas
- Projects are individual work: no collaboration with other students is allowed. Seek help from course staff if you get stuck for too long.
CODE DISTRIBUTION: p4-code.zip
CHANGELOG:
- Mon Nov 13 15:44:09 CST 2017
- The sample sessions for
Portfolio
incorrectly called thegetOwner()
method asp.owner()
. This has been corrected. - Tue Nov 7 12:10:00 CST 2017
- The documentation string for the
Stock
methodgetPrice()
incorrectly mentioned the number of shares. This has been corrected to sayReturn the price of the stock
- Sun Nov 5 20:35:31 CST 2017
- The original spec did not include a description of
Problem4Tests.java
. The file is necessary to complete the project and receive full credit.p4-code.zip
was missingjunit-1103.jar
originally and it has been added back in. This file can also be copied over from any previous project or lab.
Table of Contents
- 1. Introduction
- 2. Download Code and Setup
- 3. Object-Oriented Stock Class
- 4. Problem 1: Stock Fields, Accessor Methods, toString()
- 5. Problem 2: Buying and Selling Stocks
- 6. Problems 1 and 2
Stock
Manual Inspection Criteria - 7. Portfolio Class Overview
- 8. Problem 3: Basic Portfolio Functionality
- 9. Problem 4: Stock Transactions with Portfolios
- 10. Automatic Testing (50%)
- 11. Zip and Submit
1 Introduction
This project will build on experience with the Stock
class from lab
to build a Portfolio
, a group of Stock
objects which are tracked
by an investor. The interaction between Portfolio
and Stock
will
underscore the point of object-oriented programming: create useful but
simplified ways to interact with an object through its instance
methods.
Importantly, there are no static methods in this project aside from
a few main()
methods that are provided. Instead, all methods to be
written are non-static so that they are associated with specific
instances of an object and can make use of the this
reference to
that specific instance. Should the concept of this
but unfamiliar,
it is strongly suggested that one reviews prior to attempting the
project.
The Portfolio
object is also interesting as it will track multiple
Stock
objects in an array. This requires a good understanding of how
to move through an array of objects and what the default values of an
array of reference types (null
).
2 Download Code and Setup
As in previous projects, download the code pack linked at the top of the page. Unzip this which will create a folder and create your files in that folder.
File | State | Notes |
---|---|---|
TextIO.java | Provided | Allows easy input calls like TextIO.getInt() |
KTests.java | Testing | Test functions, runs all project tests from command line |
junit-1103.jar | Testing | For testing, don't try to edit this one |
Investors.java | Demo | Shows behavior of the Portfolio class |
Problem1Tests.java | Testing | Tests for problem 1 |
Problem2Tests.java | Testing | Tests for problem 2 |
Problem3Tests.java | Testing | Tests for problem 3 |
Problem4Tests.java | Testing | Tests for problem 4 |
Stock.java | Create | Create for Problem 1 and beyond |
Portfolio.java | Create | Create Problems 2-4 |
3 Object-Oriented Stock Class
The first step in the project is to re-work the Stock
class to
eliminate all the static
aspects of it. Recall that working on the
static version of stocks, rather long-winded code was required as in
Stock s = new Stock(); s.symbol = "APPL"; s.price = 1.43; s.numShares = 0; s.name = "Apple Inc."; double cost = Stock.buyMore(s, 10);
Removing the static aspects and adding a constructor will allow the following equivalent but concise code to be used.
Stock s = new Stock("APPL", 1.43, 0, "Apple Inc."); double cost = s.buyMore(10);
Note the use of a constructor to provide initial values and the use of
the non-static buyMore()
method associated with a specific instance
of the stock.
Starting with the code written for the previous version of Stock
with static methods is a good idea. All of the same functionality is
present just reformulated into a proper object-oriented style. The
following changes in Stock
need to be made.
Private Fields
All fields are now private
rather than public
. Code like
s.price = 1.43;
will still work inside the file Stock.java
. However, outside of
the file, such references will no longer compile.
The private fields will require accessor methods to be introduced such as
public String getSymbol()
which retrieve data in the stock but don't directly allow that data to be changed.
Non-static methods
All methods in the Stock
class will be non-static. The previous
prototype
public static double buyMore(Stock s, int moreShares)
gave an explicit reference to the Stock
to operate on. The new
prototype
public double buyMore(int moreShares)
has an implicit reference to the stock via the this
pointer.
toString() Method
Rather than having methods to print their information to the screen,
most classes define a toString()
method which produces a "pretty"
version of the information in the class. Stocks
can still be
printed with the following type of code.
Stock s = new Stock("APPL", 1.43, 0, "Apple Inc."); System.out.println( s.toString() );
3.1 Sample Session
Analyze the below interactive session from DrJava to get a sense of
how a Stock
is supposed to behave. Then move on to look at the
structure of the class to see all methods required for the class.
Welcome to DrJava. > Stock s = new Stock("APPL", 1.43, 0, "Apple Inc."); // construct a stock > s.symbol Static Error: No field in Stock has name 'symbol' // fields are private > s.price Static Error: No field in Stock has name 'price' // fields are private > s.getSymbol() // use accessors to see data for stock APPL // symbol > s.getPrice() 1.43 // price > s.getShares() 0 // number of shares > s.getName() Apple Inc. // name > s.toString() // show a string of info on the stock "Apple Inc. (APPL): price: $1.43 shares: 0" > s // DrJava toString()'s automatically Apple Inc. (APPL): price: $1.43 shares: 0 > double cost = s.buyMore(20); // buy some more shares > cost // cost of buying: negative -28.599999999999998 > s.getShares() // should have 20 mores shares 20 > s // toString() should show increased shares Apple Inc. (APPL): price: $1.43 shares: 20 > cost = s.buyMore(40); // buy more shares and check cost > cost -57.199999999999996 > s Apple Inc. (APPL): price: $1.43 shares: 60 // more shares acquired > double profit = s.sellOff(25); // sell some shares > profit // profit: positive 35.75 > s Apple Inc. (APPL): price: $1.43 shares: 35 // toString() reflects fewer shares // second stock for different company, different info for the constructo > Stock g = new Stock("GOOGL", 44.56, 10, "Google Corp."); > g Google Corp. (GOOGL): price: $44.56 shares: 10 // different info taken from the constructor args > g.getName() // compare the names of the two stocks Google Corp. > s.getName() // separate stocks, separate names Apple Inc. > g.getShares() // separate share quantities 10 > s.getShares() 35 > g.getPrice() // separate prices 44.56 > s.getPrice() 1.43 > g.buyMore(100) // buy some more google -4456.0 > g Google Corp. (GOOGL): price: $44.56 shares: 110 // toString() shows increased shares
3.2 Class Structure of Stock
All the methods in the outline for Stock
are required.
Note that the private
fields have been omitted in the class
description but they should be added.
public class Stock{ // Represent ownership of a single stock public Stock(String symbol, double price, int numShares, String name); // Constructor which takes initial values for fields. Assign each // parameter to its corresponding field. public String getSymbol(); // Return the symbol for the stock public double getPrice(); // Return the price of the stock public int getShares(); // Return the number of shares owned public String getName(); // Return the name of the stock public String toString(); // Return a String with information on the given stock to the // screen. The format should be // Microsoft Corporation (MSFT): price: $79.12 shares: 350 // ^^^ ^^^ ^^ ^^ // Name Symbol Price Number of shares // // Note that the price is preceded by a $ and has 2 decimal places // of accuracy. Since this method returns a formatted string, the // String.format() method use useful. public double buyMore(int moreShares); // Buy more of the specified stock. The number of additional shares // to buy is the parameter moreShares. Modify stock.numShares to be // this amount more. Calculate the cost of the purchase which is the // // cost = -(moreShares * stock.price) // // Note that costs are negative while profits are positive. Return // the cost. public double sellOff(int lessShares); // Sell off shares of the specified stock. The number of shares to // sell is the parameter lessShares. If the numShares field of stock // is smaller than lessShares, the transaction is error and return // 0.0 without changing anything about stock. Otherwise, reduce // stock.numShares by lessShares. Calculate the profit which is // // profit = stock.price * lessShares // // Return the profit. }
4 Problem 1: Stock Fields, Accessor Methods, toString()
The overall goal of problems 1 and 2 are to complete the
implementation of the Stock
class. The tests in Problem1.java
pertain to the basic setup for the class.
A good strategy to get started is:
- Copy the outline of the
Stock
class provided above into the fileStock.java
- Modify it so that it compiles against the test file
Problem1.java
by adding curly braces and returning default values likefalse
and0.0
where needed. - Begin filling in methods to start passing tests.
A first step along these lines is to add some private fields. These
should be identical to the fields originally in the Stock
class
during lab with the alteration of the public
to private
.
private String symbol; private double price; private int numShares; private String name;
Next define the simple accessor methods to allow the values of these fields to be retrieved.
public String getSymbol() public double getPrice() public int getShares() public String getName()
These methods should all be one-liners which simply return the field value corresponding to the method name. Importantly though, they are methods so that the values returned do not allow the internal fields of the stock to be changed.
Finally, write the toString()
method.
public String toString()
This method produces a string that is identical in format to the lab
printInfo()
method. Make use of the method String.format()
to
construct a string and return it rather than using printf()
to put
output on the screen. toString() should not print anything on its
own.
5 Problem 2: Buying and Selling Stocks
After defining the basic methods for Stock
, work on methods that
mutate it, changing the data associated with it. The only data that
can be changed in the stock is the number of shares available which
can be manipulated by the buy/sell methods.
public double buyMore(int moreShares) public double sellOff(int lessShares)
These methods follow the same conventions as before.
- Buying costs money and returns, a negative number. The cost is the number of shares to purchase multiplied by the price of the stock. The number of shares of the stock is increased.
- Selling off creates profit, a positive number. Profit is the number of shares sold multiplied by the price of the stock.
6 Problems 1 and 2 Stock
Manual Inspection Criteria grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
3% | Good style, indentation, and variable name choices are used. The Camel case naming convention is used. Code is properly indented |
2% | Brief but sufficient comments are supplied to indicate what is happening. Comments that appear in the specification do not count. |
2% | Fields of the class are private and fields/methods are non-static. |
3% | Methods are relatively short. No loops are needed for these basic methods. |
10% | Total weight for these criteria |
7 Portfolio Class Overview
A stock portfolio is a group of stocks which are tracked by an
individual investor. The class Portfolio
models this grouping by
allocating an array of Stock
objects and allowing the additions to
it (though not removal). Stocks in a portfolio can be manipulated
through methods of the Portfolio
for instance buying and
selling and the Portfolio
tracks how many stocks are in it up to a
maximum specified at creation time. Attempting to add more stocks than
the maximum are ignored.
Importantly, each Portolio
has a quantity of cash associated with
it. In order to purchase stocks, the investor must deposit()
cash
into the Portfolio
. Purchase of stock shares in the Portfolio
will make use of the cash. If there is insufficient cash to purchase
shares of a stock, the request is ignored. If the investor attempts to
buy shares of a Stock
that has not been added to the Portfolio
,
the request is ignored.
Similarly, selling of shares of a stock will store the profit from the sale in the cash associated with the portfolio. In the event an investor mistakenly attempts to sell more shares than are owned, the request is ignored.
Each Portfolio
has an owner and a total value. The total value is
the combined value of cash and stock.
Implementing the Portfolio
will require the following.
- Creation of an array of
Stock
objects when thePortfolio
is constructed - Tracking how many stocks are in the above array so that they can be added up to the maximum specified in the constructor
- When buying or selling, the
Stock
symbol is provided. The code forPortfolio
will search the array for aStock
with the given symbol and modify it. If not found, no action is taken. - Buying and selling stocks will alter the cash in the
Portfolio
. Insufficient cash will prevent shares from being purchased and selling more shares than available will not change anything including the cash. - Most methods in
Portfolio
returnboolean
values indicating whether the methods succeeded and altered thePortfolio
or failed and made no changes. For example, adding to many stocks will fail and buying more shares than supported by the cash available will fail. - The total value of a
Portfolio
is changes only when cash isdeposit()
-ed orwithdraw()
-n. Otherwise it should not be affected by buying and selling shares of stocks as they do not change in price.
7.1 Sample Session
The below sample is rather long but shows all of the functionality of
the Portfolio
. Parts of it appear in the later sections to
demonstrate specific aspects of the Portfolio
class.
> Portfolio barren = new Portfolio("Barren Wuffet", 3); // construct with owner name and max stocks > barren.getOwner() // retrieve the owner Barren Wuffet > barren.getCash() // initially no cash in the portfolio 0.0 > barren.getStockCount() // initially no stocks in the portfolio 0 > barren.toString() // show the toString() Portfolio of Barren Wuffet Cash: $0.00 0 stocks Total value: $0.00 > barren // also shows toString() Portfolio of Barren Wuffet Cash: $0.00 0 stocks Total value: $0.00 > barren.totalValue() // no stocks so total value comes from cash 0.0 > barren.deposit(100000.00) // put some money in true // deposit() should always work: true > barren.getCash() // show cash was deposited 100000.00 > barren.toString() // toString() shows the cash in the account Portfolio of Barren Wuffet Cash: $100000.00 0 stocks Total value: $100000.00 > barren.totalValue() // no stocks so total value comes from cash 100000.00 > barren.addStock("MSFT",79.12,"Microsoft Corporation") // add a stock to the portfolio, max is 3 from above true // 1st stock added, success > barren.getStockCount() // 1 stock of 3 possible in portfolio 1 > barren.buyShares("MSFT", 19) // buy some shares of the newly added stock true // enough money to do this > barren.getCash() // show change in cash after purchase of stock 98496.72 > barren.totalValue() // some value is now in stock but total doesn't change 100000.00 > barren // show full portfolio Portfolio of Barren Wuffet Cash: $98496.72 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 19 // own some shares in MSFT now Total value: $100000.00 // total value of portfolio remains the same > barren.buyShares("MSFT", 20) // buy more shares of MSFT true // enough cash > barren Portfolio of Barren Wuffet Cash: $96914.32 // less cash 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 39 // more shares Total value: $100000.00 > barren.sellShares("MSFT", 30) // sell some shares true // had 39, now have 9 > barren.sellShares("MSFT", 15) // sell some shares false // had 9, can't sell 15 > barren // show portfolio Portfolio of Barren Wuffet Cash: $99287.92 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 9 // no change Total value: $100000.00 > barren.addStock("AAPL",163.05,"Apple Inc.") // add some more stocks true // 2nd stock of 3 okay > barren.addStock("GOOGL",1000.62,"Alphabet Inc Class A") true // 3rd stock of 3 okay > barren.getStockCount() // show change in stockCount 3 > barren // show portfolio Portfolio of Barren Wuffet Cash: $99287.92 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 9 Apple Inc. (AAPL): price: $163.05 shares: 0 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 0 Total value: $100000.00 > barren.addStock("GIS",52.03,"General Mills, Inc.") // add another stock false // 4th stock of 3 - failed to add > barren.getStockCount() // no change in stockCount 3 > barren // show no new stock present Portfolio of Barren Wuffet Cash: $99287.92 3 stocks // only 3 Microsoft Corporation (MSFT): price: $79.12 shares: 9 Apple Inc. (AAPL): price: $163.05 shares: 0 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 0 Total value: $100000.00 > barren.sellShares("GOOGL", 20) // sell some shares of GOOGL false // not enough shares: fail > barren // no change to portfolio Portfolio of Barren Wuffet Cash: $99287.92 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 9 Apple Inc. (AAPL): price: $163.05 shares: 0 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 0 Total value: $100000.00 > barren.buyShares("GOOGL", 200) // buy a LOT of shares false // fail: not enough cash > barren.buyShares("GOOGL", 30) // buy fewer shares true // success > barren // show change Portfolio of Barren Wuffet Cash: $69269.32 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 9 Apple Inc. (AAPL): price: $163.05 shares: 0 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 30 // shares acquired Total value: $100000.00 > barren.buyShares("AAPL", 50) // buy more shares of companies true > barren.buyShares("MSFT", 50) true > barren // show changes Portfolio of Barren Wuffet Cash: $57160.82 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 59 Apple Inc. (AAPL): price: $163.05 shares: 50 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 30 Total value: $100000.00 > barren.withdraw(30000.00) // withdraw some cash true // sufficient cash: success > barren.totalValue() // total value is lower on a withdrawal 70000.00 > barren Portfolio of Barren Wuffet Cash: $27160.82 // cash smaller 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 59 Apple Inc. (AAPL): price: $163.05 shares: 50 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 30 Total value: $70000.00 // total value decreased > barren.withdraw(40000.00) // withdraw more cash false // insufficient funds: fail > barren // show no change after failed withdrawal Portfolio of Barren Wuffet Cash: $27160.82 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 59 Apple Inc. (AAPL): price: $163.05 shares: 50 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 30 Total value: $70000.00 > Portfolio gordon = new Portfolio("Gordon Gecko", 5); // create a second portfolio, different owner and max stocks > gordon // show initial values Portfolio of Gordon Gecko Cash: $0.00 0 stocks Total value: $0.00 > barren // original portfolio is unaffected by new one Portfolio of Barren Wuffet Cash: $27160.82 3 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 59 Apple Inc. (AAPL): price: $163.05 shares: 50 Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 30 Total value: $70000.00
7.2 Class Structure of Portfolio
Below are all of the public methods that should appear in the Portfolio class. The private fields do not appear but are described at the beginning of Problem 3.
public class Portfolio{ // A class to represent a group of stocks owned by an investor along // with a cash reserve to purchase more stocks. The owner and maximum // number of stocks are fixed at construction time. Methods that // mutate the Portfolio return boolean values indicate whether the // operation was successful or not. public Portfolio(String owner, int maxStocks); // Construct a new portfolio that can hold the given maximum number // of stocks. The owner of the portfolio is the first // parameter. Initially the portfolio has no stocks and no cash in // it. public String getOwner(); // Retrieve the owner of the portfolio. public double getCash(); // Return the amount of cash currently in the portfolio public int getStockCount(); // Return how many stocks are currently stored in the array of // stocks tracked by the portfolio. public boolean deposit(double amount); // Add the given amount to the cash in the portfolio and return // true. If the amount given is negative, ignore the request and // return false. public boolean withdraw(double amount); // Deduct the given amount from the cash in portfolio and return // true. If the amount is negative or is larger than the amount of // cash in the portfolio, ignore the request and return false. public double totalValue(); // Return the total value of all cash and stocks in the entire // portfolio. Use a loop to compute the individual value of each // stock using and appropriate method. Add on the cash to total // before returning. public String toString(); // Create a string representation of the portfolio. An example of // the output format is below and includes must information in the // portfolio. Use a loop over the stocks in the portfolio to create // the listing of stocks calling each stock's toString() method to // produce its string representation. Use of the String.format() to // format each line of the resulting string and append it to an // answer is a good approach. // // EXAMPLE: // Portfolio of Gordon Gecko // Cash: $18734.20 // 3 stocks // Apple Inc. (AAPL): price: $166.89 shares: 50 // Alphabet Inc Class A (GOOGL): price: $1000.62 shares: 15 // Microsoft Corporation (MSFT): price: $79.12 shares: 100 // Total value: $50000.00 // // Note that the last line "Total value..." has a newline at the end // of it. A good strategy is to create an initial empty string then // append strings to it with +=. Each line has a newline "\n" at the // end of it. public boolean addStock(String symbol, double price, String name); // Add a stock to the portfolio with the given symbol, price, and // name. The initial number of shares for the stock must be // 0. Ensure that the count of stocks tracked by the portfolio is // updated. Return true on a successful add. If the count of stocks // is already at the maximum for the portfolio, ignore the add // request and return false. public boolean buyShares(String symbol, int numShares); // Buy more shares a stock in the portfolio. Use a loop to locate // the stock with the given symbol. Purchase more shares of the // stock using an appropriate method of the Stock class. Deduct the // cost of the purchase from the portfolio's cash. Return true on a // successful purchase. If the cost of buying is larger than the // amount of cash in th portfolio, do not buy any shares and return // false. If no stock in the portfolio has the given symbol, return // false. public boolean sellShares(String symbol, int numShares); // Sell off shares a stock in the portfolio. Use a loop to locate // the stock with the given symbol. Sell off shares of the stock // using an appropriate method of the Stock class. Add the profit // from the sale to the portfolio's cash. Return true on a // successful sale. If the numShares is larger than the number of // shares owned, ignore the sell request and return false. If no // stock in the portfolio has the given symbol, return false. }
8 Problem 3: Basic Portfolio Functionality
8.1 Fields, Constructor, Accessors
The first steps to getting the Portfolio
class are to establish its
fields and basic accessor methods. The private
fields are not listed
but should roughly be as follows.
private String owner; private int stockCount; private Stock stocks[]; private double cash;
More fields may be added if desired but these 4 represent the bare minimum.
Focus attention first on the constructor and accessors.
public Portfolio(String owner, int maxStocks) ; public String getOwner() ; public double getCash() ; public int getStockCount()
These simple methods return values of some of the fields as demonstrated in the first part of the sample session.
> Portfolio barren = new Portfolio("Barren Wuffet", 3); // construct with owner name and max stocks > barren.getOwner() // retrieve the owner Barren Wuffet > barren.getCash() // initially no cash in the portfolio 0.0 > barren.getStockCount() // initially no stocks in the portfolio 0
8.2 Cash Mutators
Move on to deal with the basic cash mutators.
public boolean deposit(double amount); public boolean withdraw(double amount);
These allow the cash field of the Portfolio
to be manipulated with
some restrictions: attempts to withdraw()
more cash than is present
will return false
and leave the current cash unchanged.
> barren.deposit(100000.00) // put some money in true // deposit() should always work: true > barren.withdraw(30000.00) // withdraw some cash true // sufficient cash: success > barren.getCash() 70000.00 > barren.withdraw(5000000.00) // withdraw too much false // insufficient cash: fail > barren.getCash() // unchanged 70000.00
8.3 totalValue()
Begin the implementation of the totalValue()
method here which will
also involve the amount of cash in the portfolio.
public double totalValue();
A sample of how totalValue()
works.
> barren.totalValue() // no stocks so total value comes from cash 100000.00
Note though that after adding code to work with stocks in the
Portfolio
, this method may need adjustment to account for the value
of the stocks.
8.4 toString()
Finally, the toString()
method can produce some basic information at
this point.
public String toString();
As with the toString()
for Stock
, the strings of
Portfolio
can be more easily produced with the String.format()
method which works much like printf()
except that a string is
produced. For portfolios without stocks, the string versions will
look like this.
> barren.toString() // show the toString() Portfolio of Barren Wuffet Cash: $0.00 0 stocks Total value: $0.00 > barren.deposit(100000.00) // put some money in > barren.toString() // show the toString() Portfolio of Barren Wuffet Cash: $100000.00 0 stocks Total value: $100000.00
Eventually toString()
will need to account for stocks but getting a
start on it here is a good move.
8.5 Problem 3 Portfolio
Manual Inspection Criteria grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
3% | Good style, indentation, and variable name choices are used. The Camel case naming convention is used. Code is properly indented |
2% | Brief but sufficient comments are supplied to indicate what is happening. Comments that appear in the specification do not count. |
5% | Accessor methods like getCash() are relatively short. No loops are needed for these basic methods. |
5% | The constructor initializes all fields appropriately. |
5% | No static fields or methods appear in the class. All methods make use of the fields of specific instances of the class. |
20% | Total weight for these criteria |
9 Problem 4: Stock Transactions with Portfolios
9.1 addStock()
To complete the Portfolio, define the methods that operate on stocks of the portfolio. Before a stock can be bought or sold, it must be added to the portfolio.
public boolean addStock(String symbol, double price, String name);
- Under most circumstances, this method should create a new
Stock
object and place it in the array of stocks associated with thePortfolio
. - The attributes of the stock are given in the parameters
to
addStock()
except for the number of initial shares which is always 0 on adding a stock. - On successfully adding the stock, the
stockCount
associated with thePortfolio
should be increased by 1. - Only add the given stock if the
stockCount
is less than the max stocks given during construction of thePortfolio
. A standard implementation does not need an extra field to track this but will instead just comparestockCount
to the.length
of the array of stocks. If the count is less than the length, another stock can be added. If not, then ignore the add request and returnfalse
.
> barren.toString() // toString() shows the cash in the account Portfolio of Barren Wuffet Cash: $100000.00 0 stocks Total value: $100000.00 > barren.addStock("MSFT",79.12,"Microsoft Corporation") // add a stock to the portfolio, max is 3 from above true // 1st stock added, success > barren.getStockCount() // 1 stock of 3 possible in portfolio 1
9.2 Stock Mutators
Once a stock has been added to the Portfolio
, shares of it can be
bought and sold with the following methods.
public boolean buyShares(String symbol, int numShares); public boolean sellShares(String symbol, int numShares);
Both of these methods should employ a similar algorithm.
- Use a loop to search through the array of stocks for one with the
given
symbol
. If no such stock is found, return false. - Make use of an appropriate method of
Stock
to retrieve its symbol for checking; this is needed as that field is a private field with a public accessor method. - Make use of the
strA.equals(strB)
deep string comparison method to correctly compare strings to one another. - If a stock with the given symbol is found, check whether the
operation will succeed:
- Buying: the cost of the transaction must be less than or equal to
than the cash available in the
Portfolio
- Selling: the number of shares of the
Stock
must be greater than or equal to the number of shares being sold.
If the operation would not succeed make no changes to stocks or portfolio and return
false
. - Buying: the cost of the transaction must be less than or equal to
than the cash available in the
- If the operation would succeed, make the desired modification to
the specific stock by invoking an appropriate
Stock
method (buy/sell) and adjust the cash associated withPortfolio
based on the transaction (cash decreases on buying, increases on selling). Returntrue
to indicate a successful transaction.
> barren.buyShares("MSFT", 19) // buy some shares of the newly added stock true // enough money to do this > barren.getCash() // show change in cash after purchase of stock 98496.72 > barren.totalValue() // some value is now in stock but total doesn't change 100000.00 > barren // show full portfolio Portfolio of Barren Wuffet Cash: $98496.72 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 19 // own some shares in MSFT now Total value: $100000.00 // total value of portfolio remains the same > barren.buyShares("MSFT", 20) // buy more shares of MSFT true // enough cash > barren Portfolio of Barren Wuffet Cash: $96914.32 // less cash 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 39 // more shares Total value: $100000.00 > barren.sellShares("MSFT", 30) // sell some shares true // had 39, now have 9 > barren.sellShares("MSFT", 15) // sell some shares false // had 9, can't sell 15 > barren // show portfolio Portfolio of Barren Wuffet Cash: $99287.92 1 stocks Microsoft Corporation (MSFT): price: $79.12 shares: 9 // no change Total value: $100000.00
9.3 Adjust toString() and totalValue()
Tied up with the introduction of stocks into the Portfolio
will be
changes to the methods
public String toString(); public double totalValue();
which must both now account for the presence of stocks. It is likely
both will use loops over the array of stocks to produce appropriate
results. Make sure to employ methods of Stock
to ease this task:
- The
toString()
forStock
produces output that can be directly used in thePortfolio
toString()
method. Stocks
can produce their shares and price with accessors which is useful intotalValue()
9.4 Problem 4 Portfolio
Manual Inspection Criteria grading
The criteria below will be examined by graders to account for part of your grade.
Wgt | Criteria |
---|---|
3% | Good style, indentation, and variable name choices are used. The Camel case naming convention is used. Code is properly indented |
2% | Brief but sufficient comments are supplied to indicate what is happening. Comments that appear in the specification do not count. |
3% | addStock() checks the available space in the stock array and adds/ignores add requests appropriately. |
2% | addStock() correctly invokes the constructor for Stock() to add new stocks to the Portfolio. |
3% | buyShares() / sellShares() use a loop over the array of stocks but use the stockCount to limit the loop. |
2% | buyShares() / sellShares() use deep string equality checks to locate the correct stock to operate on |
3% | buyShares() / sellShares() use conditionals to check for success of buy/sell before adjusting the portfolio |
2% | buyShares() / sellShares() correctly ignore non-existent stocks |
20% | Total weight for these criteria |
10 Automatic Testing (50%) grading
10.1 Running Tests
Run the tests associated with the project and ensure all of them
pass. This can be done in DrJava by pressing the Test
button when
test files are open.
On the command line you can run all tests with the following commands.
On Unix/Mac platforms, use a terminal to run the following commands in the folder where your code exists.
> javac -cp .:junit-1103.jar KTests.java #compile > java -cp .:junit-1103.jar KTests #run tests
On windows, use cmd.exe
and change to the correct directory. Run the
commands below where which use a semicolon (;) rather than a colon (:).
> javac -cp .;junit-1103.jar KTests.java #compile > java -cp .;junit-1103.jar KTests #run tests
Correctly passing all tests will yield output similar to the following.
JUnit version 4.12 .......... Time: 0.024 OK (10 tests)
Failing some tests will yield long messages which hint at where there might be a problem. Failures always end with the number of tests passed/failed as in the following.
FAILURES!!! Tests run: 10, Failures: 5
10.2 Test Grading Policies
Some policies to keep in mind with respect to how automatic tests affect grades.
- Credit on this section is proportional to the number of tests passed.
- If there were 30 total tests for the project…
- Passing 30 / 30 tests gets
30 / 30 * 50 = 50.00
- Passing 15 / 30 tests gets
15 / 30 * 50 = 25.00
- Passing 4 / 30 tests gets
4 / 30 * 50 = 6.67
- A 5% penalty may be deducted from this portion if code does not compile initially but a grader is able to quickly fix the problem.
- Passing no tests because code does not compile or does not work properly gets 0 credit.
11 Zip and Submit
11.1 Submit to Canvas
Once your are confident your code is working, you are ready to submit. Ensure your folder has all of the required files. Create a zip archive of your lab folder and submit it to blackboard.
On Canvas:
- Click on the Assignments section
- Click on the appropriate link for this lab
- Scroll down to "Attach a File"
- Click "Browse My Computer"
- Select you Zip file and press OK
11.2 Late Policies
You may wish to review the policy on late project submission which will cost you late tokens to submit late or credit if you run out of tokens. No projects will be accepted more than 48 hours after the deadline.
http://www-users.cs.umn.edu/~kauffman/1103/syllabus.html#late-projects