This contains the lecture about how to read data from the console. And obviously it contains also other information: about UML, about TextIO class and other stuff. See also http://abouthydrology.blogspot.it/2013/07/java-for-hydrologists-101.html for more information and for the other slides
3. Objectives
Summarizing what a Java class shold have as “standard”
Introduction
•Summarizing what programming the LinearEquationSolver taught
•Introducing comments and Javadocs
•Talking of other various aspects of programming at convenience
R. Rigon
Wednesday, September 4, 13
4. package org.geoframe.first;
public class LinearEquationSolver {
private double a,b,sol=Double.NaN;
public LinearEquationSolver(double a, double b){
....the code here solves the equation ...
}
public double getSolution(){
....the code here accesses the solution...
}
public static void main(String[] args){
....this is useful to try the solver ...
}
}
main()
The structure of a standard class
Variable
declaration
constructor
getter and setter
R. Rigon
Classes parts
Wednesday, September 4, 13
7. Document it (see Comment and documentation in BE book)
package org.geoframe.first;
/**
* LinearEquationSolver solves a linear equation, and was used to illustrate some
* Java features in Java for Hydrologists 101.
* This linear equation can be expressed as
* a x + b = 0 where a and b are the two coefficients of the equation
* @author Riccardo Rigon, 2013
* ....
* Copyright GPL v. 3 (http://www.gnu.org/licenses/gpl.html)
*/
public class LinearEquationSolver {
/**
* a and b are the coefficients of the linear equation
* sol is the solution of the linear equation
*/
private double a,b,sol=Double.NaN;
/**
* LinearEquationSolver allocate and solves a linear equation
* @param a is the first coefficient of the linear equation
* @param b is the known term of the linear equation
*/
public LinearEquationSolver(double a, double b){
....the code here solves the equation ...
}
......
}
R. Rigon
Javadoc
Wednesday, September 4, 13
8. package org.geoframe.first;
/**
* LinearEquationSolver solves a linear equation, and was used to illustrate some
* Java features in Java for Hydrologists 101.
* This linear equation can be expressed as
* a x + b = 0 where a and b are the two coefficients of the equation
* @author Riccardo Rigon, 2013
* Copyright GPL v. 3 (http://www.gnu.org/licenses/gpl.html)
*/
public class LinearEquationSolver {
/**
* a and b are the coefficients of the linear equation
* sol is the solution of the linear equation
*/
private double a,b,sol=Double.NaN;
/**
* LinearEquationSolver allocate and solves a linear equation
* @param a is the first coefficient of the linear equation
* @param b is the known term of the linear equation
*/
public LinearEquationSolver(double a, double b){
....the code here solves the equation ...
}
......
}
Document it (see Comment and documentation in BE book)
Classcommentfield
comment
method
comment
Javadoc
Wednesday, September 4, 13
9. /**
* LinearEquationSolver solves a linear equation, and was used to illustrate some
* Java features in Java for Hydrologists 101.
* This linear equation can be expressed as
* a x + b = 0 where a and b are the two coefficients of the equation
* @author Riccardo Rigon, 2013
* Copyright GPL v. 3 (http://www.gnu.org/licenses/gpl.html)
*/
Comment begins
Comment ends
A Comment
R. Rigon
Javadoc
Wednesday, September 4, 13
10. /**
* LinearEquationSolver solves a linear equation, and was used to illustrate some
* Java features in Java for Hydrologists 101.
* This linear equation can be expressed as
* a x + b = 0 where a and b are the two coefficients of the equation
* @author Riccardo Rigon, 2013
* Copyright GPL v. 3 (http://www.gnu.org/licenses/gpl.html)
*/
Annotations
A Comment
This is the author annotation and contains the name of the authors and the
date
R. Rigon
Javadoc
Wednesday, September 4, 13
11. /**
* LinearEquationSolver solves a linear equation, and was used to illustrate some
* Java features in Java for Hydrologists 101.
* This linear equation can be expressed as
* a x + b = 0 where a and b are the two coefficients of the equation
* @author Riccardo Rigon, 2013
* Copyright GPL v. 3 (http://www.gnu.org/licenses/gpl.html)
*/
A Comment
Do not forget a copyleft !
R. Rigon
Javadoc
Wednesday, September 4, 13
12. To produce the javadoc document
R. Rigon
Javadoc
Wednesday, September 4, 13
13. To produce the javadoc document
R. Rigon
Javadoc
Wednesday, September 4, 13
15. The structure of a standard class revised
Variable
declaration
constructor
getter and setter
Class Comment
Field Comment
Method Comment
Method Comment
etc etc
public class ClassName {
}
package org.geoframe.first;
R. Rigon
Classes structure
Wednesday, September 4, 13
16. Other standard methods
public static void print { }
Having one method ore more than one methods to print the class value is
deemed necessary. This is extremely useful for the programmer, and,
obviously for those who use her/his programs
So put a print( ) in any class
R. Rigon
Classes structure
Wednesday, September 4, 13
17. Other standard methods
public static void print { }
I made it static. So it will be called with the class name, e.g. :
LinearEquationSolver.print()
R. Rigon
Classes structure
Wednesday, September 4, 13
18. Riccardo Rigon
Java for Hydrologists
Naming conventions
R.Rigon-IltavolodilavorodiRemowolf
Wednesday, September 4, 13
19. Objectives
Why we name classes and things that way
Introduction
• Saying a little about naming conventions
•Talking of other various aspects of programming at convenience
R. RigonR. Rigon
Wednesday, September 4, 13
20. Objectives
Summarizing what a Java class has to be has “standard”
Introduction
•Summarizing what programming the LinearEquationSolver taught
•Introducing comments and Javadocs
•Talking of other various aspects of programming at convenience
R. RigonR. Rigon
Wednesday, September 4, 13
21. What Is a Naming Convention?
A naming convention is a rule to follow as you decide what to name your
identifiers (e.g. class, package, variable, method, etc..).
Why Use Naming Conventions?
Different Java programmers can have different styles and approaches to
the way they program. By using standard Java naming conventions they
make their code easier to read for themselves and for other programmers.
Readability of Java code is important because it means less time is spent
trying to figure out what the code does, leaving more time to fix or
modify it.
http://java.about.com/od/javasyntax/a/nameconventions.htm
The names of ...
R. Rigon
Names
Wednesday, September 4, 13
22. To illustrate the point it's worth mentioning that most software companies
will have a document that outlines the naming conventions they want
their programmers to follow. A new programmer who becomes familiar
with those rules will be able to understand code written by a programmer
who might have left the company many years before hand.
Conventions
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
23. When choosing a name for an identifier make sure it's meaningful.
Don't worry about the length of the name. A longer name that sums up
the identifier perfectly is preferable to a shorter name that might be quick
to type but ambiguous.
Picking a Name for Your Identifier
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
24. Using the right letter case is the key to following a naming convention:
• Lowercase is where all the letters in a word are written without any
capitalization (e.g., while, if, mypackage).
• Uppercase is where all the letters in a word are written in capitals. When there
are more than two words in the name use underscores to separate them (e.g.,
MAX_HOURS, FIRST_DAY_OF_WEEK).
• CamelCase (also known as Upper CamelCase) is where each new word begins
with a capital letter (e.g., CamelCase, CustomerAccount, PlayingCard).
• Mixed case (also known as Lower CamelCase) is the same as CamelCase except
the first letter of the name is in lowercase (e.g., hasChildren,
customerFirstName, customerLastName).
A few words about cases
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
25. The below list outlines the standard Java naming conventions for each identifier
type:
Packages: Names should be in lowercase. With small projects that only have a few
packages it's okay to just give them simple (but meaningful!) names:
package annotations
In software companies and large projects where the packages might be imported
into other classes, the names will normally be subdivided. Typically this will start
with the company domain before being split into layers or features:
package org.geoframe.annotations
Standard Java Naming Conventions
This guarantees the unicity of the name in the world.
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
26. Classes: Names should be in CamelCase. Try to use nouns because a class is
normally representing something in the real world:
class LinearEquationSolver
class Folder
Interfaces: Names should be in CamelCase. They tend to have a name that
describes an operation that a class can do: interface Comparable
interface Enumerable
Note that some programmers like to distinguish interfaces by beginning the name
with an "I":
interface IRiverBasin
Classes, Interfaces, Annotations
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
27. Methods: Names should be in mixed case. Use verbs to describe what the method
does:
void calculateTax()
string getSurname()
Methods
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
28. Variables: Names should be in mixed case. The names should represent what the
value of the variable represents:
string firstName
int orderNumber
Only use very short names when the variables are short lived, such as in for loops:
for (int i=0; i<20;i++)
{
//i only lives in here
}
Constants: Names should be in uppercase. static final int DEFAULT_WIDTH
static final int MAX_HEIGHT
Methods, Variables, Constants
http://java.about.com/od/javasyntax/a/nameconventions.htm
R. Rigon
Names
Wednesday, September 4, 13
29. Riccardo Rigon
Java for Hydrologists
A little of I/O from console
R.Rigon-IltavolodilavorodiRemowolf
Wednesday, September 4, 13
30. Objectives
Well, I do not want to run my java programs inside Eclipse forever
Introduction
•Getting values from console
•Talking of other various aspects of programming at convenience
R. RigonR. Rigon
Wednesday, September 4, 13
31. Having variable inputs at run-time
I need to read:
•parameters a and b
(If I know that the solver can treat any a and b case, I do not need
to do any check here. If the case I have to catch exception thrown
by the solver)
Then execute the LinerEquationSolver class
Finally print the results on the console
R. Rigon
A parameters reader
Wednesday, September 4, 13
32. A Little diversion to talk about UML
This class is not very general indeed. But let’s see how we can implement it
This is the name of the class
These are the fields of the class
These are the methods of the class
GetTwoDoubleParameters
-a: double
-b: double
+setParameter(): void
R. Rigon
A parameters reader
Wednesday, September 4, 13
33. This class is not very general indeed. But let’s see how we can implement it
GetTwoDoubleParameters
-a: private double
-b: private double
+setParameter(String ): void
Instead of the standard UML notation
I will use often use the Java specific
modifiers:
private
public
protected
A Little diversion to talk about UML
R. Rigon
A parameters reader
Wednesday, September 4, 13
34. Assuming “a” field and setParameter
are static: I will use s for indicating
them.I will use a C for indicating a
constructor
(in the case of
GetTwoDoubleParameters, the
constructor is not explicitly present)
A Little diversion to talk about UML
GetTwoDoubleParameters
-a: private s double
-b: private double
+ s setParameter(String ): void
+ C GetTwoDoubleParameters(): void
R. Rigon
A parameters reader
Wednesday, September 4, 13
35. package org.geoframe.io;
/**
* GetTwoDoubleParameters reads two double parameters from stIO. A very simple
* class that uses a static method.
*
* @author Riccardo Rigon
* @version 1/256
*/
public class GetTwoDoubleParameters {
public double a;
public double b;
/**
* set Parameter is used to get a parameter from StdIO. It uses the class TextIO
* @param name
* @return
*/
static public double setParameter(String name){
double c;
TextIO.put("Please insert the '"+name+"' parameter: ");
c = TextIO.getDouble();
return c;
}
public static void main(String[] args) {
// Now we test the functioning of the class
double a,b;
System.out.println("This is the GetTwoDoubleParameters main( )");
a=setParameter("a");
b=setParameter("b");
System.out.println("a = "+a);
System.out.println("a = "+b);
System.out.println("This is ends computation");
}
}
I p u t o n c e t h e
entire code
here to show the
correspondence
with the UML
R. Rigon
A parameters reader code
Wednesday, September 4, 13
36. public class GetTwoDoubleParameters {
public double a;
public double b;
static public double setParameter(String name){
....
return c;
}
public static void main(String[] args) {
....
}
}
There is a one-to-one corrispondence with UML
R. Rigon
A parameters reader code
Wednesday, September 4, 13
37. /**
* setParameter is used to get a parameter from StdIO. It uses
the class TextIO
* @param name
* @return
*/
static public double setParameter(String name){
double c;
TextIO.put("Please insert the '"+name+"' parameter: ");
c = TextIO.getDouble();
return c;
}
I use here the TexIO class by David J. Eck - For references and usage see chapter
2 of his book, or TextIO Javadoc ;-)
GetParameter( )
R. Rigon
A parameters reader code
Wednesday, September 4, 13
38. How did I imported it in Eclipse ?
•Right click on the package
R. Rigon
Eclipse
Wednesday, September 4, 13
39. How did I imported it in Eclipse ?
•A window menu appears
•Choose “File System”
R. Rigon
Eclipse
Wednesday, September 4, 13
40. How did I imported it in Eclipse ?
•Select the directory where your .java file is
R. Rigon
Eclipse
Wednesday, September 4, 13
41. public static void main(String[] args) {
// Now we test the functioning of the class
double a,b;
System.out.println("This is the GetTwoDoubleParameters main( )");
a=setParameter("a");
b=setParameter("b");
// Calling the above from a different package have to use
// GetTwoDoubleParameters.setParameters();
System.out.println("a = "+a);
System.out.println("a = "+b);
}
Class Name
This just because the method is static
Some details
R. Rigon
Code details
Wednesday, September 4, 13
42. public static void main(String[] args) {
// Now we test the functioning of the class
double a,b;
System.out.println("This is the GetTwoDoubleParameters main( )");
a=setParameter("a");
b=setParameter("b");
// Calling the above from a different package have to use
// GetTwoDoubleParameters.setParameters();
System.out.println("a = "+a);
System.out.println("a = "+b);
} method name
This just because the method is static
Some details
R. Rigon
Code details
Wednesday, September 4, 13
43. public static void main(String[] args) {
static double a,b,sol;
System.out.println("This is the LinearEquationWithVariableInputs main()");
System.out.println("Solving a lineat equation using GetTwoDoubleParameters");
a=GetTwoDoubleParameters.setParameter("a");
b=GetTwoDoubleParameters.setParameter("b");
//Printing them
System.out.println("a = "+a);
System.out.println("b = "+b);
//Solving the linear equation
try{
LinearEquationSolver ll = new LinearEquationSolver(a,b);
sol=ll.getSolution();
System.out.println("The solution of "+a+" x + "+b+" == 0 is: x = "+sol);
}catch(RuntimeException e){
TextIO.put(e);
}
}
Some details
This solves the linear equation. Please observe the differences of this method
behavior with the one of the previous slide. This is NOT static
R. Rigon
Code details
Wednesday, September 4, 13
44. public static void main(String[] args) {
static double a,b,sol;
System.out.println("This is the LinearEquationWithVariableInputs main()");
System.out.println("Solving a lineat equation using GetTwoDoubleParameters");
a=GetTwoDoubleParameters.setParameter("a");
b=GetTwoDoubleParameters.setParameter("b");
//Printing them
System.out.println("a = "+a);
System.out.println("b = "+b);
//Solving the linear equation
try{
LinearEquationSolver ll = new LinearEquationSolver(a,b);
sol=ll.getSolution();
System.out.println("The solution of "+a+" x + "+b+" == 0 is: x = "+sol);
}catch(RuntimeException e){
TextIO.put(e);
}
}
The method throw and axception. Therefore we have to catch it.
Some details
R. Rigon
Code details
Wednesday, September 4, 13
45. Set the names of parameters
[For each one]
start
From the names understand
the number of parameters
Get the parameters from
StdIO
A more general class for reading parameters
R. Rigon
Activity diagrams
Wednesday, September 4, 13
46. Store the parameters in an array
continue
Retrieve the parameters
for any use
Use them
end
R. Rigon
Activity diagrams
Wednesday, September 4, 13
47. A more general class for reading parameters
Analyzing the previous Activity diagram (Fowler p. 117). It follows that:
1. you have to retrieve the names of the parameters - Let’s us say that we
use a string array to hard-coding it, at the moment;
2. the second passage is a trivial interrogation of the length of the array;
R. Rigon
Designing a new class
Wednesday, September 4, 13
48. A more general class for reading parameters
3.Now that we know the number of parameters (after step 1 actually), we can
allocate the necessary memory to contain them. The natural choice here is an
array of double.
4. for each one of the parameters I need to retrieve it from StdIO: this require
a method (actually a setter). Reading and storing could be done by the same
method
5. Making available the data for any use means to do nothing is the
parameters are in a public field. Otherwise we need to implement a getter
method
6. Etc.
R. Rigon
Designing a new class
Wednesday, September 4, 13
49. So
Our class needs, at least:
1. a double[] to store the data.
2. A constructor: we can think to make get the names of the parameters to
perform inside it the major operation
3. A setter method
4. A getter method
5. A print method to show what has been created
R. Rigon
Designing a new class
Wednesday, September 4, 13
50. Now the temptation is to show
The class diagram and telling: here it is. In reality, at this point I went to
writing down the code along the above lines and the result after some iteration
is the one shown in the next slide
R. Rigon
Designing a new class
Wednesday, September 4, 13
51. A more general class for reading parameters
GetDoubleParameters
- params: double[]
+getParameters( ): double[]
This is a more general class. Can request any number of parameters (double
anyway). They are stored in an array of double. What is really important is
that this class is reusable also in other contexts
-setParameterFromStdIO(String): double
+ C GetDoubleParameters(String[]): void
+print(String): void
R. Rigon
Designing a new class
Wednesday, September 4, 13
52. public class GetDoubleParameters {
//Contains the parameters values
private double params[];
//Get the parameters from the standard Input (the console)
private double setParameterFromStdIO(String name){
}
//is the getter method to make available the otherwise private
data
public double[] getParameters() {
}
//pass the address of the appropriately allocate memory space
private void addressParametersSpace(double params[]) {
}
//Constructor: needs as input the list of parameters’name
public GetDoubleParameters(String[] prmsname){
}
....
}
R. Rigon
Coding
Wednesday, September 4, 13
53. public static void main(String[] args) {
System.out.println("This is the GetDoubleParameters main()");
String[] nms={"First","Second","Third","Fourth","Fifth"};
GetDoubleParameters prmtrs=new GetDoubleParameters(nms);
int j;
for(int i=0;i<nms.length;i++){
j=i+1;
TextIO.put("The parameter "+j+" is:"+prmtrs.getParams()[i]+"n");
}
System.out.println("This ends the computation");
}
This set the names of the parameters requested and implicitly, their number
The main( )
R. Rigon
Coding
Wednesday, September 4, 13
54. public static void main(String[] args) {
System.out.println("This is the GetDoubleParameters main()");
String[] nms={"First","Second","Third","Fourth","Fifth"};
GetDoubleParameters prmtrs=new GetDoubleParameters(nms);
int j;
for(int i=0;i<nms.length;i++){
j=i+1;
TextIO.put("The parameter "+j+" is:"+prmtrs.getParams()[i]+"n");
}
System.out.println("This ends the computation");
}
This get the parameters values from StdIO.
R. Rigon
Coding
Wednesday, September 4, 13
55. public static void main(String[] args) {
System.out.println("This is the GetDoubleParameters main()");
String[] nms={"First","Second","Third","Fourth","Fifth"};
GetDoubleParameters prmtrs=new GetDoubleParameters(nms);
int j;
for(int i=0;i<nms.length;i++){
j=i+1;
TextIO.put("The parameter "+j+" is:"+prmtrs.getParams()[i]+"n");
}
System.out.println("This ends the computation");
}
This prints the parameters values to the StdIO.
R. Rigon
Coding
Wednesday, September 4, 13
56. public static void main(String[] args) {
System.out.println("This is the GetDoubleParameters main()");
String[] nms={"First","Second","Third","Fourth","Fifth"};
GetDoubleParameters prmtrs=new GetDoubleParameters(nms);
int j;
for(int i=0;i<nms.length;i++){
j=i+1;
TextIO.put("The parameter "+j+" is:"+prmtrs.getParams()[i]+"n");
}
System.out.println("This ends the computation");
}
These are local variables. They live inside the main. i lives inside the for loop.
Notes( )
R. Rigon
Coding
Wednesday, September 4, 13
57. public static void main(String[] args) {
System.out.println("This is the GetDoubleParameters main()");
String[] nms={"First","Second","Third","Fourth","Fifth"};
GetDoubleParameters prmtrs=new GetDoubleParameters(nms);
int j;
for(int i=0;i<nms.length;i++){
j=i+1;
TextIO.put("The parameter "+j+" is:"+prmtrs.getParams()[i]+"n");
}
System.out.println("This ends the computation");
}
This is a string concatenation
Notes( )
R. Rigon
Coding
Wednesday, September 4, 13
58. prmtrs.getParams()[i]
How to call a non static method
object name
a.k.a. class
instantiation
R. Rigon
Details
Wednesday, September 4, 13
60. method returns a double[]
prmtrs.getParams()[i] this select the i-eth element
How to call a non static method
R. Rigon
Details
Wednesday, September 4, 13
61. public GetDoubleParameters(String[] prmsname){
int n;
n=prmsname.length;
this.params=new double[n];
for(int i=0;i<n;i++){
this.getParameters()[i]=setParameterFromStdIO(prmsname[i]);
}
}
The constructor
This is step 2 in
activity diagram
Actually this code could have been shrunk down to
this.params=new double[prmsname.length];
eliminating the first two lines
R. Rigon
Methods inspection
Wednesday, September 4, 13
62. public GetDoubleParameters(String[] prmsname){
int n;
n=prmsname.length;
this.params=new double[n];
for(int i=0;i<n;i++){
this.getParameters()[i]=setParameterFromStdIO(prmsname[i]);
}
}
The constructor
This is step 3
and 4 in the
activity diagram
The right side retrieves the data from the console, the left side stores them.
R. Rigon
Methods inspection
Wednesday, September 4, 13
63. private double setParameterFromStdIO(String name){
double c;
TextIO.put("Please insert the '"+name+"' parameter: ");
c = TextIO.getDouble();
// TextIO is used also because it check that the
parameter is a double and if it is not a double it ask it again.
So it is robust implementatio. See DJE’s book, chapter 2.
return c;
}
The setter
R. Rigon
Methods inspection
Wednesday, September 4, 13
64. The getter
public double[] getParameters() {
return params;
}
It is trivial but obscure for beginners. This function knows the params values
because it is inside the class. What it is important is that it is public. So what it
really does is to take a private information and publish to the public.
R. Rigon
Methods inspection
Wednesday, September 4, 13
65. //print the parameters and their names
public void print(String[] parNames){
for(int i=0;i<parNames.length;i++){
TextIO.put("The "+parNames[i]+" parameter is:"+params[i]+"n");
}
}
The printer
R. Rigon
Methods inspection
Wednesday, September 4, 13
66. A code snippet
from the Class LinearEquationSolverWithVariableInputs
System.out.println("Solving a linear equation using
GetDoubleParameters");
//Declaring the parameters
String[] pa={"a","b"};
//Using the class that makes the input job
GetDoubleParameters prmtrs=new GetDoubleParameters(pa);
//Prints the parameters and their names
prmtrs.print(pa);
}
R. Rigon
Using the class
Wednesday, September 4, 13
67. A code snippet
from the Class LinearEquationSolverWithVariableInputs
//Solving the linear equation.
a=prmtrs.getParameters()[0];
b=prmtrs.getParameters()[1];
try{
LinearEquationSolver ll1 = new LinearEquationSolver(a,b);
sol=ll1.getSolution();
System.out.println("The solution of "+a+" x + "+b+" == 0 is: x
= "+sol);
}catch(RuntimeException e){
TextIO.put(e);
}
R. Rigon
Using the class
Wednesday, September 4, 13
68. Overall summary
It has been reminded what is the “standard” structure of a Java class. We
learned:
•how to make Javadoc documentation and how to process it;
•better what a UML class diagram is;
•about the existence of TextIO by David J. Eck to get information from
console and how to import an external (.java file or) class;
•what an activity diagram is (and we used it to design our class and
methods);
•better what are the differences between a static and non.static methods
We built two new reusable classes and commented them thoroughly and we
used them in conjunction with the LinearEquationSolver to solve a linear
equation.
R. Rigon
Summary
Wednesday, September 4, 13
69. Thank you for your attention.
G.Ulrici,2000?
It ends here
R. Rigon
Wednesday, September 4, 13
70. References
Bruce Eckel (2006), Thinking in Java, fourth edition, Prentice Hall.
Fowler, M. (2003). UML Distilled, 3rd Ed (pp. 1–118). Addison-Wesley.
Eck, D. J. (2012). Introduction to Programming Using Java (pp. 1–751).
R. Rigon
To be read
Wednesday, September 4, 13