Thursday, June 13, 2013

The Fish Market Program is (almost) Done!

I made some good progress on my program and I'm happy with it.  I still need to go through and look for ways to check what the user types to be sure it is correct input.

I have four classes:
  1. SaltyFishMarket:  Control begins here in main.  All main does is declare a new SaltyFishMarket object and that activates the constructor.  The constructor sets up the DecimalFormat object and the Scanner, then calls the buyFish method three times.  The buyFish method returns a Fisherman object which gets used to access the amount of fish each fisherman caught.  The buyFish method also updates a field that keeps track of Salty's total cost.  After the constructor calculates the price that Salty paid per pound, it calls a method to set the price per pound that customers will have to pay.  Finally, the constructor calls a method that sells fish to customers.

    I decided to have five customers.  I made a sellToOneCustomer method and had the sellFish method call it five times.  I could change the number of customers by putting in more or fewer calls to sellToOneCustomer.  After the five calls to sellToOneCustomer, the sellFish method calculates Salty's profit for the day and announces what kind of day Salty had.
  2. Fisherman:  The fields of my Fisherman class are a name, a fish count, a total weight of fish caught, a String for the weather, a probability that corresponds to the weather, and a random number generator.  The constructor gets activated when a Fisherman object is declared (which happens in the SaltyFishMarket class).  The constructor receives a name as an argument and sets the name field.  After that the constructor declares a Weather object then queries that object to find out what the weather is.  Based on the string that is returned by the Weather object, the constructor sets the probability.

    One thing I did to avoid code duplication is make a method in the Fisherman class called goFishing that gets called by the SaltyFishMarket class after it makes a new Fisherman object.  Since a fisherman casts his line five times, I made another method called FishOnce and I had the goFishing method call that one five times.  The FishOnce method gets a random number between 0 and 1 and sees if that number is less than the probability.  If so, a fish is caught.  For example, suppose it's a windy day and the probability is 0.8.  When you get a random double, if it's something like .4 or .6 or anything less than .8, you treat that as a signal that a fish was caught.  About 80% of the numbers between 0 and 1 are less than .8, so that trick works well.

    If a fish is caught, I declare a new Fish object.  Then I query that object for the weight and length of the fish and that's how I decide whether to keep it or not.

    I made the program more fun to run by printing out what happens as the fisherman fishes.  For example, here is a partial run of my code.  The specs didn't say we had to do this, but it's entertaining to see how the program is different every time it runs.

  3. Fish:  This is a really simple class.  The fields are a length, a weight, and a random number generator.  The constructor uses the random number generator to set the length and weight of the fish within the bounds specified.  Brandon showed how to do that in our webinar.
  4. Weather:  This is a really simple class, too.  Its only field is a random number generator.  When a Weather object is created by the Fisherman class, the random number generator is used to get one of four possible values.  I made a getWeather method that returns one of the four strings ("sunny", "cloudy", "windy", or "rainy").

My SaltyFishMarket program

So, if you watched the webinar, you know that my first rendering of this program did not entirely meet the specs.  I got started writing the program and was having so much fun with it that I didn't read the specs carefully enough.  That's not entirely bad... it's not going to be hard for me to correct the way I wrote it in order to make it match specs.

At first I only had a class for the market and a class for a fisherman.  I've now decided to add a class for weather and a class for fish.


The weather class constructor is not going to take any arguments.  All the class needs is a field for a random number generator.  The constructor can allocate the Random object.  I'll also make a method that can be called to get the weather.  It can use the Random object to get one of four possible values and return one of the weather strings. Each fisherman is supposed to check the weather, so I'll add that to my fisherman class.  Every time something calls the getWeather method, a new random number will be generated and the weather will change.


I'll call the class that will contain the main SaltyFishMarket.  Here's my plan for that class.  My main will be ultra-simple:


public static void main(String[] args)
{
    SaltyFishMarket sfm = new SaltyFishMarket();
}

Originally my main was really long.  To make it short like that, I'm going to take all the variables I had in main and make them be fields of this class.  The work that my original main was doing could be divided up as follows:


  1. set up the decimal format and scanner stuff
  2. buy fish from three fishermen
  3. figure out the price to charge
  4. sell fish to some customers
I'll have the constructor set things up.  After it does that, it will call some other methods.  I'll make a buyFish and a setPrice and a sellFish method that the constructor can call.

Okay, I'll get to work on this and will post again when I've made some progress.




Saturday, June 8, 2013

Third Program

I have been waiting to get some ideas from your blogs about what to write about, and most people are not really able to write a lot just now.  Brandon has suggested that I blog about my own programming process.  He is the one who creates the programming assignments, then I write the code to test his idea and give him some feedback.  I think blogging as I go is a good idea and I hope you find it helpful.

The third program is similar to the second one.  It's about a business that needs a report generated.  This time the business is a lawn care service and the report is about one customer.  The program collects data from a user.  It asks for the customer's name, address, and phone number.  It asks how many years that customer has had an account with the company, and it asks about their yard -- its length and width, how many flower beds the customer has, and how many shrubs.

The difference between the third program and the second is that we now know how to create classes (and objects, which are just variables of that class type) to help solve such problems.  So now instead of keeping all the data inside the main method, I'll read the data from the user and then stash all the data inside a new object.  I'll be able to later get the data out of that object whenever and wherever I need it.

It seems sort of silly right now to make a new object for the data when all I have is one customer and that one customer's data is already in main.  But imagine that I have 10 customers or 100 customers.  Soon we're going to learn about writing loops.  I could run a loop a bunch of times and each time collect data about one customer, then put all that customer's data in an object.  We're also going to learn about containers that can hold multiple objects.  I could declare a container of customers and put all of my customer objects into a container.  All that is down the road...

Here is how I will structure my program.  I'll have main do this:

  1. Read in all the data about a customer.  
  2. Declare a new customer object and pass the data to the constructor of the customer class.
  3. Read in all the data about that customer's yard.
  4. Declare a new yard object and pass the data to the constructor of the yard class.
  5. Calculate the charge for that customer's yard.  When I need some piece of data I'll use an accessor method on the appropriate object.
  6. Print out the report.
I'll put my main in a class file that will be called something like "TestLawnService" or "MyLawnService" or some such thing.  The only thing in this class will be my main.  I'll need two more files, one for my customer class and one for my yard class.

One thing you might find useful is printing a percent as a whole number with a percent sign.  Once you learn about the DecimalFormat class in chapter 4, it will become easy.  But you can do it with printf, too.  Suppose my percent variable contains a real number between 0 and 100, such as 45.678.  I can print this as 46% with this printf statement:

printf("The percentage is %.0f%%.", percentage);

The %.0f is a placeholder that says to round the corresponding value to a whole number.  The %% is a placeholder that turns into the % character.  

Program 3 was easier than program 2 for me because I already understood something about programs that read data and make a report.