Your objective in this homework is to make code self-contained and reusable using methods. You will do this in the context of solving several disconnected problems that have no overarching story. Sorry.

Breaking code up into methods has several benefits: it enables large problems to be decomposed into smaller, mind-sized bytes; methods with a distinct purpose are easier to test than gangly spans of code; and because of the scope boundaries of methods, data becomes more insulated and less likely to get accidentally overwritten or inappropriately referenced. Additionally, methods jive with a basic human desire to make things that have lasting value. Like a family recipe, methods stand the test of time and get passed around.

When one is first learning about methods, there’s a great temptation to acquire the parameters from the user and print out the method’s return value *inside* the method, like this:

```
public void triple(int n) {
Scanner in = new Scanner(System.in);
System.out.println("What is n? ");
n = in.nextInt();
System.out.println(n + n + n);
}
```

Don’t do this. Methods generally should not perform input and output. Where the input comes from and where the output goes to should be decided by the caller of the method—not the method itself. Our method `triple`

is most reusable and testable when we write it like this:

```
public int triple(int n) {
return n + n + n;
}
```

Written properly, we can feed it data from many different sources:

```
triple(scanner.nextInt());
triple(generator.nextInt());
triple(17);
```

Additionally, we can embed the return value in many different contexts:

```
int thrice = triple(17);
System.out.println(triple(2));
int b = a + triple(5);
```

Complete the five classes described below. Place all classes in package `hw2`

. Make all methods `static`

.

Write class `Main`

with a `main`

method, which you are encouraged to use to test your code. Nothing in particular is required of it, but it must exist.

Write class `StringUtilities`

with the following methods:

- Method
`expandAnalogy`

which accepts an analogy as you might find on a standardized test and returns it in its readable form. For example,`expandAnalogy("windshield:bugs::atmosphere:meteors")`

→`windshield is to bugs as atmosphere is to meteors`

. Both parameter and return value are of type`String`

. Do not conjugate “is” to its plural form “are” under any circumstances. - Method
`littleToBig`

, which converts a date in D/M/YYYY or*little endian*form into YYYY/MM/DD or*big endian*form. For example,`littleToBig("15/1/1999")`

→`1999/01/15`

. Both parameter and return value are of type`String`

. Do not assume numbers in the parameter have a certain number of digits, but do return a date where the year has four digits, the month has two, and the day has two. Pad with leading zeroes. Little endian date formatting is the most common on Earth, but it is not used in the United States. Big endian formatting is used in Asia and has the advantage of sorting chronologically when using a standard dictionary sort. - Method
`middleToBig`

, which converts a date in M/D/YYYY or*middle endian*form into YYYY/MM/DD or*big endian*form. For example,`middleToBig("1/15/1999")`

→`1999/01/15`

. The rules of`littleToBig`

apply also to`middleToBig`

. - Method
`says`

, which accepts two parameters: a subject of type`String`

and an utterance of type`String`

. It returns a sentence of type`String`

in which the subject says the utterance. For example,`says("Taylor", "You need to calm down.")`

→`Taylor says, "You need to calm down."`

. - Method
`capitalizeMatches`

which accepts two parameters: a haystack of type`String`

and a needle of type`String`

. It returns a`String`

in which most occurrences of the needle in the haystack are replaced with a capitalized version of the needle. For example,`capitalizeMatches("Inch by inch, life's a cinch. Yard by yard, life's hard.", "yard")`

→`Inch by inch, life's a cinch. YARD by YARD, life's hard.`

Replace the occurrences of the needle that are entirely lowercase (`yard`

) and those whose first letter only is capitalized (`Yard`

). Allow the needle to appear inside other words (`shipYARD`

).

Write class `MathUtilities`

with the following methods:

- Method
`max3`

, which accepts three`int`

parameters. It returns the largest of the three. - Method
`max4`

, which accepts four`int`

parameters. It returns the largest of the four. - Method
`pow`

, which accepts two parameters: a base of type`int`

, and an exponent of type`int`

. It returns base raised to the power of the exponent. Unlike the builtin function of the same name in the`Math`

class, this version returns an`int`

. - Method
`perpendicularSlope`

, which accepts as its parameter a line’s slope of type`double`

. It returns the slope of a perpendicular line. - Method
`treeHeight`

, which might be used in a mobile app to determine the height of a tree. It accepts two parameters: the phone’s distance from the base of the tree, and the angle in degrees that the phone is turned upward to point at the top of the tree. Both parameters are of type`double`

. Return the height of the tree as a`double`

.

Write class `HyperUtilities`

to help calculate various properties of n-dimensional boxes. A box in 1D is a line segment, a box in 2D is a square, a box in 3D is a cube, a box in 4D is a hypercube, and so on. This class has the following methods:

- Method
`countVertices`

, which accepts a box’s number of dimensions of type`int`

. It returns the number of vertices or corners on the box. Work out the formula by completing this table and generalizing:n vertex count 1 ? 2 ? 3 ? … … - Method
`countEdges`

, which accepts a box’s number of dimensions of type`int`

. It returns the number of edges contained in the box. An edge is line between two vertices. We already know how many vertices are in a box; we have a method for counting them. We can figure out the number of edges by figuring out how many edges there are per vertex. Work out the formula through this thought process:- Draw a square, which we know has four vertices. Don’t read on without drawing.
- Look at a single vertex on the square. How many edges leave it?
- Draw a cube, which we know has eight vertices.
- Look at a single vertex on the cube. How many edges leave it?
- In general, for an
`n`

-dimensional box, how many edges leave each vertex? - Given the number of vertices and the number of
*edge leavings*per vertex, how many total edge leavings are there across the entire box? - The number of edge leavings is bigger than the actual number of edges. Each edge connects two vertices and therefore contributes two edge leavings to the total number of leavings. So, by counting leavings, we have double-counted. Compensate for this double-counting. Does your formula work for both the square and the cube?

- Method
`countFaces`

, which accepts a box’s number of dimensions of type`int`

. It returns the number of faces contained in the box. A face is a surface connecting four vertices and surrounded by four edges. Our strategy here is similar to that for`countEdges`

. We already know how many edges are in a box; we have a method for counting them. We can figure out the number of faces by figuring out how many faces there are per edge. Work out the formula through this thought process:- Draw a square, which we know has four edges.
- Look at a single edge on the square. How many faces leave it?
- Draw a cube, which we know has twelve edges.
- Look at a single edge on the cube. How many faces leave it?
- In general, for an n-dimensional box, how many faces leave each edge?
- Given the number of edges and the number of
*face leavings*per edge, how many total face leavings are there across the entire box? - The number of face leavings is bigger than the actual number of faces. Each face connects four edges and therefore contributes four face leavings to the total number of leavings. So, by counting leavings, we have quadruple-counted. Compensate for this quadruple-counting. Does your formula work for both the square and the cube?

Write class `FileUtilities`

with the following methods:

- Method
`desktop`

, which returns a`File`

instance referring to the`Desktop`

directory in the user’s home directory. For example, your home directory might have this path in macOS:`/Users/yoozer`

, whereas the desktop directory would be`/Users/yoozer/Desktop`

. Investigate`System.getProperty`

as a means for determining the user’s home directory. Investigate also the documentation for the`File`

class, one of whose constructors allows you to join a parent directory and a child. - Method
`slurp`

, which accepts a`File`

and returns its contents as a`String`

. Investigate`Files.readAllBytes`

as a means of reading the file. Reading files can fail if the file cannot be opened. Mark this method as dangerous with a`throws`

clause:Convert the result ofpublic static ...(...) throws IOException {

`readAllBytes`

to the right type using an explicit`String`

constructor. - Method
`contains`

, which accepts two parameters: a`File`

instance and a`String`

to search for. It returns a`boolean`

indicating whether or not the file contains the search`String`

. Mark that this method throws an`IOException`

. - Method
`freeSpaceInUnits`

, which accepts two parameters: a`File`

instance referring to a partition on the computer’s file system, and`int`

representing the requested order of magnitude of storage units. It returns a`double`

reporting the number of storage units that are free on the specified partition. An order of 0 indicates bytes, 1 indicates kilobytes ($2^{10}$ bytes), 2 indicates megabytes ($2^{20}$ bytes), 3 indicates gigabytes ($2^{30}$ bytes), 4 indicates terabytes ($2^{40}$ bytes), and so on. To convert from bytes to kilobytes, for example, we’d set up the following conversion:$$x\ \textrm{bytes} \times \frac{1\ \textrm{kilobyte}}{2^{10}\ \textrm{bytes}}$$The bytes cancel, leaving you a quantity in kilobytes.

To check your work and submit it for grading:

- Run the SpecChecker by selecting
`hw2 SpecChecker`

from the run configurations dropdown in IntelliJ IDEA and clicking the run button. - Fix problems until all tests pass.
- Commit and push your work to your repository.
- Verify on Gitlab that your submission uploaded successfully by adding the comment
`test hw2`

to any commit. You will receive an email of the SpecChecker results.

A passing SpecChecker does not guarantee you credit. Your grade is conditioned on a few things:

- You must meet the requirements described above. The SpecChecker checks some of them, but not all.
- You must not plagiarize. Write your own code. Talk about code with your classmates. Ask questions of your instructor or TA. Do not look at others’ code. Do not ask questions specific to your homework anywhere online but Piazza. Your instructor employs a vast repertoire of tools to sniff out academic dishonesty, including: drones, CS 1 moles, and a piece of software called MOSS that rigorously compares your code to every other submission. You don’t want to live in a world serviced by those who achieved their credentials by questionable means. For your future self, career, and family, do your own work.
- Your code must be submitted correctly and on time. Machine and project issues are common—anticipate them. Commit early and often to Git. Extensions will not be granted. If you need more time to make things work, start earlier.

## Comments