Variables 2b (using your own classes with data)

Level 1 - Basics

We used existing Java classes to create objects until now: Point and Rectangle. But it is also possible to create your own, custom class.

For example, we want to register a product with its price, we could create a class for this with String productName and int priceInCents, and use that in our code.

public class Product {

    String name;
    int priceInCents;

}

Now switch back to the Application file and copy this into your run() method:

Product product = new Product();
product.name = "Expensive designer lamp";
product.priceInCents = 12000;

Extend this code:

ArrayList<Product> cart = new ArrayList<>(); Product product = new Product(); product.name = "Expensive designer lamp"; product.priceInCents = 12000; cart.add(product); Product anotherProduct = new Product(); anotherProduct.name = "Fake turd"; anotherProduct.priceInCents = 520; cart.add(anotherProduct);

Extend the code so it calculates and shows the total price of the items in the cart. Hint:

ArrayList<Product> cart = new ArrayList<>(); Product product = new Product(); product.name = "Expensive designer lamp"; product.priceInCents = 12000; cart.add(product); Product anotherProduct = new Product(); anotherProduct.name = "Fake turd"; anotherProduct.priceInCents = 520; cart.add(anotherProduct); int sum = 0; for (Product item : cart) { sum = sum + item.priceInCents; } SaxionApp.printLine("The total is: €" + ((double)sum / 100));

Go back to the file with the Product class. You can see the fields name and priceInCents here. Add a new field shippingCostsInCents with type int.

public class Product { String name; int priceInCents; int shippingCostsInCents; }

Change your program: set the shipping costs to a value for both of the products that you add to the cart. And also calculate the shipping costs total.

ArrayList<Product> cart = new ArrayList<>(); Product product = new Product(); product.name = "Expensive designer lamp"; product.priceInCents = 12000; product.shippingCostsInCents = 625; cart.add(product); Product anotherProduct = new Product(); anotherProduct.name = "Fake turd"; anotherProduct.priceInCents = 520; anotherProduct.shippingCostsInCents = 325; cart.add(anotherProduct); int sum = 0; int shipping = 0; for (Product item : cart) { sum = sum + item.priceInCents; shipping = shipping + item.shippingCostsInCents; } SaxionApp.printLine("The total is: €" + ((double)sum / 100)); SaxionApp.printLine(" plus shipping: €" + ((double)shipping / 100));

Level 2 - Do it yourself

Create a new class Circle with these fields, all ints: x, y, radius, red, green, blue.

In your program, add 150 objects of type Circle to a list. They all should have random values for x, y, radius, red, green and blue. Restrictions:

Finally draw all the circles in the list to the canvas with the correct position, size and color. Use SaxionApp.createColor() to convert r-g-b values to a color. Use SaxionApp.setFill to set the background color of the circles. Use SaxionApp.turnBorderOff() to remove the ugly green border.

// the Circle class (in a separate file) public class Circle { int x; int y; int radius; int red; int green; int blue; } // in your application run() method: ArrayList<Circle> circles = new ArrayList<>(); while (circles.size() < 150) { Circle c = new Circle(); c.x = SaxionApp.getRandomValueBetween(0, SaxionApp.getWidth()); c.y = SaxionApp.getRandomValueBetween(0, SaxionApp.getHeight()); c.radius = SaxionApp.getRandomValueBetween(30, 100); c.red = SaxionApp.getRandomValueBetween(0, 255); c.green = SaxionApp.getRandomValueBetween(0, 255); c.blue = SaxionApp.getRandomValueBetween(0, 255); circles.add(c); } SaxionApp.turnBorderOff(); for (Circle c : circles) { Color color = SaxionApp.createColor(c.red, c.green, c.blue); SaxionApp.setFill(color); SaxionApp.drawCircle(c.x, c.y, c.radius); }

Change the program and add three counters. Count the circles that are

Show all three results afterwards and decide which color won.

ArrayList<Circle> circles = new ArrayList<>(); while (circles.size() < 150) { Circle c = new Circle(); c.x = SaxionApp.getRandomValueBetween(0, SaxionApp.getWidth()); c.y = SaxionApp.getRandomValueBetween(0, SaxionApp.getHeight()); c.radius = SaxionApp.getRandomValueBetween(30, 100); c.red = SaxionApp.getRandomValueBetween(0, 255); c.green = SaxionApp.getRandomValueBetween(0, 255); c.blue = SaxionApp.getRandomValueBetween(0, 255); circles.add(c); } int red = 0; int green = 0; int blue = 0; SaxionApp.turnBorderOff(); for (Circle c : circles) { Color color = SaxionApp.createColor(c.red, c.green, c.blue); SaxionApp.setFill(color); SaxionApp.drawCircle(c.x, c.y, c.radius); if (c.red > c.green && c.red > c.blue) { red++; } if (c.green > c.red && c.green > c.blue) { green++; } if (c.blue > c.red && c.blue > c.green) { blue++; } } SaxionApp.print("Counted circles mainly red: " + red); SaxionApp.print(", mainly green: " + green); SaxionApp.prinLine(", mainly blue: " + blue); if (red > green && red > blue) { SaxionApp.printLine("RED WON", Color.RED); } if (green > red && green > blue) { SaxionApp.printLine("GREEN WON", Color.GREEN); } if (blue > red && blue > green) { SaxionApp.printLine("BLUE WON", Color.BLUE); }

Level 3 - Objects from data

Classes and data go well together. Data are values stored in a file on disk. One of the formats to store data is the CSV-format. It can store one object per line, the fields are separated with a comma (,) or semicolon (;), depending on the program used to create it.

An example of CSV data for our Circle class:

x;y;radius;red;green;blue
350;350;200;200;200;200
200;200;105;0;0;0
200;200;100;200;200;200
200;200;85;0;0;0
200;200;80;230;200;200
500;200;105;0;0;0
500;200;100;200;200;200
500;200;85;0;0;0
500;200;80;230;200;200
350;350;180;200;200;200
350;340;150;200;0;0
350;320;150;200;200;200
270;300;35;0;0;0
430;300;35;0;0;0
270;300;30;255;255;255
430;300;30;255;255;255
260;290;20;0;0;0
440;300;20;0;0;0
260;290;18;60;0;255
440;300;18;60;0;255
260;290;8;0;0;0
440;300;8;0;0;0
350;350;30;100;100;100

The first line is the field names, the other lines contain values for the fields. Each row defines one circle.

Create a new CSV file in your Exercise:

The SaxionApp has a builtin CSV reader.

Change your program, so the while loop that creates the circles doesn't use random values, but values from the CSV. Use this example to modify your code:

ArrayList<Circle> circles = new ArrayList<>();

// NOTE: instead of "Exercise1", use the correct Exercise directory name here
// or "Sandbox" if you use the Sandbox project.
CsvReader reader = new CsvReader("Exercise1/circles.csv"); 
reader.setSeparator(';'); // fields separated by semicolon
reader.skipRow(); // skip the header row with field names

while (reader.loadRow()) { // keep looping until there are no more rows

    Circle c = new Circle(); 
    c.x = reader.getInt(0);
    c.y = reader.getInt(1);
    // do the rest of the fields yourself ...

    // add the circle to the arraylist
}

If you do it correctly, you should see a painting that is rumoured to have been made by Van Gogh himself. At least it has the same qualities.

ArrayList<Circle> circles = new ArrayList<>(); CsvReader reader = new CsvReader("Exercise15/circles.csv"); reader.setSeparator(';'); // fields separated by semicolon reader.skipRow(); // skip the header row with field names while (reader.loadRow()) { Circle c = new Circle(); c.x = reader.getInt(0); c.y = reader.getInt(1); c.radius = reader.getInt(2); c.red = reader.getInt(3); c.green = reader.getInt(4); c.blue = reader.getInt(5); circles.add(c); } // (removed the color counting stuff) SaxionApp.turnBorderOff(); for (Circle c : circles) { Color color = SaxionApp.createColor(c.red, c.green, c.blue); SaxionApp.setFill(color); SaxionApp.drawCircle(c.x, c.y, c.radius); }

Level 4 - Class from data

Store this data as CSV-file in your exercise, call it temp.csv.

The data is the average temperature (*10, so 97 means 9.7 degrees) per year in the eastern part of the Netherlands since 1951.

weatherstation;year;temperature
Twente;1951;97
Twente;1952;86
Twente;1953;98 
Twente;1954;88
Twente;1955;86
Twente;1956;79
Twente;1957;97
Twente;1958;93
Twente;1959;102
Twente;1960;94
Twente;1961;97
Twente;1962;78
Twente;1963;76
Twente;1964;89
Twente;1965;83
Twente;1966;92
Twente;1967;97
Twente;1968;88
Twente;1969;85
Twente;1970;85
Twente;1971;91
Twente;1972;85
Twente;1973;90
Twente;1974;93
Twente;1975;93
Twente;1976;92
Twente;1977;93
Twente;1978;87
Twente;1979;78
Twente;1980;85
Twente;1981;91
Twente;1982;97
Twente;1983;96
Twente;1984;86
Twente;1985;78
Twente;1986;85
Twente;1987;83
Twente;1988;99
Twente;1989;104
Twente;1990;104
Twente;1991;91
Twente;1992;102
Twente;1993;90
Twente;1994;101
Twente;1995;98
Twente;1996;78
Twente;1997;97
Twente;1998;98
Twente;1999;105
Twente;2000;105
Twente;2001;99
Twente;2002;103
Twente;2003;99
Twente;2004;99
Twente;2005;101
Twente;2006;108
Twente;2007;107
Twente;2008;101
Twente;2009;100
Twente;2010;85
Twente;2011;103
Twente;2012;98
Twente;2013;94
Twente;2014;113
Twente;2015;105
Twente;2016;102
Twente;2017;105
Twente;2018;111
Twente;2019;110
Twente;2020;113
Twente;2021;101
Twente;2022;113

Create a new program.

Use the list afterwards to create a diagram:

// class YearTemperature. You probably chose a better name. public class YearTemperature { // there are three columns in the csv, so three fields here // the first is a string, the last contain only numbers, so int. String weatherStation; int year; int temp; } // in the run() method of the Application: // (change YearTemperature to your own classname) ArrayList<YearTemperature> yearTemperatures = new ArrayList<>(); // (change to your own path and file name) CsvReader reader = new CsvReader("Exercise15/temp.csv"); reader.setSeparator(';'); // fields separated by semicolon reader.skipRow(); // skip the header row with field names while (reader.loadRow()) { YearTemperature t = new YearTemperature(); t.weatherStation = reader.getString(0); t.year = reader.getInt(1); t.temp = reader.getInt(2); yearTemperatures.add(t); } int x = 10; // little margin on the left int scale = 3; // to enlarge the graph a bit, otherwise it is such a tiny graph for (YearTemperature t : yearTemperatures) { // draw vertical line SaxionApp.drawLine(x, SaxionApp.getHeight(), x, SaxionApp.getHeight() - t.temp * scale); x = x + scale; // move right for the next line }

Now change the program:

// (change YearTemperature to your own classname) ArrayList<YearTemperature> yearTemperatures = new ArrayList<>(); // (change to your own path and file name) CsvReader reader = new CsvReader("Exercise15/temp.csv"); reader.setSeparator(';'); // fields separated by semicolon reader.skipRow(); // skip the header row with field names while (reader.loadRow()) { YearTemperature t = new YearTemperature(); t.weatherStation = reader.getString(0); t.year = reader.getInt(1); t.temp = reader.getInt(2); yearTemperatures.add(t); } int selectedYear = 0; // keep asking until it is ok while (selectedYear < 1951 || selectedYear > 2022) { SaxionApp.printLine("From which year do you want to see the graph? (1951-2022)"); selectedYear = SaxionApp.readInt(); } int x = 10; int scale = 3; for (YearTemperature t : yearTemperatures) { // only draw if it matches our criterium: year should be >= than the selected year if (t.year >= selectedYear) { SaxionApp.drawLine(x, SaxionApp.getHeight(), x, SaxionApp.getHeight() - t.temp * scale); x = x + scale; } }