teaching machines

Half-homework 2 – Methods – due October 7

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.

Warning

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);

Requirements

Complete the five classes described below. Place all classes in package hw2. Make all methods static.

Main

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.

StringUtilities

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).

MathUtilities

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.

HyperUtilities

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:
    1. Draw a square, which we know has four vertices. Don’t read on without drawing.
    2. Look at a single vertex on the square. How many edges leave it?
    3. Draw a cube, which we know has eight vertices.
    4. Look at a single vertex on the cube. How many edges leave it?
    5. In general, for an n-dimensional box, how many edges leave each vertex?
    6. Given the number of vertices and the number of edge leavings per vertex, how many total edge leavings are there across the entire box?
    7. 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:
    1. Draw a square, which we know has four edges.
    2. Look at a single edge on the square. How many faces leave it?
    3. Draw a cube, which we know has twelve edges.
    4. Look at a single edge on the cube. How many faces leave it?
    5. In general, for an n-dimensional box, how many faces leave each edge?
    6. Given the number of edges and the number of face leavings per edge, how many total face leavings are there across the entire box?
    7. 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?

FileUtilities

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:
    public static ...(...) throws IOException {
    
    Convert the result of 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.

Submission

To check your work and submit it for grading:

  1. Run the SpecChecker by selecting hw2 SpecChecker from the run configurations dropdown in IntelliJ IDEA and clicking the run button.
  2. Fix problems until all tests pass.
  3. Commit and push your work to your repository.
  4. 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

Leave a Reply

Your email address will not be published. Required fields are marked *