Last Updated: 2017-11-13 Mon 15:45

CSCI 1103 Project 4: Portfolio's as Objects

CODE DISTRIBUTION: p4-code.zip

CHANGELOG:

Mon Nov 13 15:44:09 CST 2017
The sample sessions for Portfolio incorrectly called the getOwner() method as p.owner(). This has been corrected.
Tue Nov 7 12:10:00 CST 2017
The documentation string for the Stock method getPrice() incorrectly mentioned the number of shares. This has been corrected to say Return 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 missing junit-1103.jar originally and it has been added back in. This file can also be copied over from any previous project or lab.

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 file Stock.java
  • Modify it so that it compiles against the test file Problem1.java by adding curly braces and returning default values like false and 0.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 the Portfolio 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 for Portfolio will search the array for a Stock 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 return boolean values indicating whether the methods succeeded and altered the Portfolio 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 is deposit()-ed or withdraw()-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 the Portfolio.
  • 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 the Portfolio should be increased by 1.
  • Only add the given stock if the stockCount is less than the max stocks given during construction of the Portfolio. A standard implementation does not need an extra field to track this but will instead just compare stockCount 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 return false.
> 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.

  1. Use a loop to search through the array of stocks for one with the given symbol. If no such stock is found, return false.
  2. 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.
  3. Make use of the strA.equals(strB) deep string comparison method to correctly compare strings to one another.
  4. 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.

  5. 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 with Portfolio based on the transaction (cash decreases on buying, increases on selling). Return true 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() for Stock produces output that can be directly used in the Portfolio toString() method.
  • Stocks can produce their shares and price with accessors which is useful in totalValue()

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


Author: Chris Kauffman (kauffman@umn.edu)
Date: 2017-11-13 Mon 15:45