3
\$\begingroup\$

I am trying to write a lab/program that loops through a .txt input file. Reads an entire line of data as a string, then splits that string into an array delimited by a space. If there are 4 items in the resulting array, and each item is a valid double, I want it to determine the distance between the points & return info to a separate output.txt file.

RLabs.java

import java.io.*;
import java.util.Scanner;

public class RLabs {

    public static void main(String[] args) throws FileNotFoundException {
        double dealtaX, deltaY, distance,x1, y1, x2, y2;
        String Line, item1, item2, item3, item4;
        String[] Sect;
        Scanner inFile;
        PrintWriter outFile;

        System.out.println("I/O File Line Distance Program Starting. Opening file...");
        System.out.println("Please ensure data is entered per line in the format of (X1 Y1 X2 Y2).");
        inFile = new Scanner(new File("input.txt"));
        outFile = new PrintWriter(new File("countresults.txt"));


        while(inFile.hasNext()){

            Line = inFile.nextLine();
            Sect = Line.split(" ");
            if(Sect.length == 4) {
                item1 = Sect[0];
                item2 = Sect[1];
                item3 = Sect[2];
                item4 = Sect[3];

                if(testDoubleLow(item1,0)&&(testDoubleLow(item2,0)&&(testDoubleLow(item3,0)&&(testDoubleLow(item4,0))))){
                    x1 = Double.parseDouble(item1);
                    y1 = Double.parseDouble(item2);
                    x2 = Double.parseDouble(item3);
                    y2 = Double.parseDouble(item4);
                    dealtaX = (x2-x1);
                    deltaY = (y2-y1);

                    distance = Math.sqrt(Math.pow(deltaY,2)+ Math.pow(dealtaX,2));
                    outFile.printf(Line);

                    outFile.printf(" The distance between (%1.1f,%1.1f) and (%1.1f,%1.1f) is %1.1f\n", x1,y1,x2,y2,distance);

                }
                else {
                    outFile.println("Line did not correct data");
                }






            }
            else {
                outFile.println("Line did not have 4 item(s)");
            }
        }

        outFile.close();
        inFile.close();


        System.out.println("Done...");
    }

        private static boolean testDoubleLow(String token, double l){

            if(testDouble(token)) {
                double num = Double.parseDouble(token);
                if(num > l ) {
                    return true;
                }
            }

            return false;
        }

        private static boolean testDouble(String s) {
            try {
                Double.parseDouble(s);
                return true;
            }
            catch(Exception e) {
                return false;


    }

    }
}

Input data I'm using

17.2 23.2 15.6 17.76

1

frog

123 frog 2 98

22 99 19 76

-13 03 92 03

l 123 03 96

1293.333333333333333 3 4 111111111111111111

2 1 1 2

21.4518345 94 21 mom

12 67 tti 30

128 30 -2 69

670 20 49 100

1230 230 304 500 60 30 60 606 59

Output from program

17.2 23.2 15.6 17.76 The distance between (17.2,23.2) and (15.6,17.8) is 5.7

Line did not have 4 item(s)

Line did not have 4 item(s)

Line did not have correct data

22 99 19 76 The distance between (22.0,99.0) and (19.0,76.0) is 23.2

Line did not have correct data

Line did not have correct data

1293.333333333333333 3 4 111111111111111111 The distance between (1293.3,3.0) and (4.0,111111111111111104.0) is 111111111111111104.0

2 1 1 2 The distance between (2.0,1.0) and (1.0,2.0) is 1.4

Line did not have correct data

Line did not have correct data

Line did not have correct data

670 20 49 100 The distance between (670.0,20.0) and (49.0,100.0) is 626.1

Line did not have 4 item(s)

\$\endgroup\$
0
\$\begingroup\$

Object-Orientated

your code is very procedural (honestly, it's just one long main methode) not very object-orientated... seperate your code into seperate concern(Segregation of concerns), at least a kind of DistanceParser class and a ErrorHandler class. Doing this make your ready open for the open-closed principal

DistanceParser fileParser = DistanceParser.fileInstance(inputFile);   //applying dependecy injection
fileParser.setErrorHandler(new FileErrorHandler(logFile));
fileParser.parse();

if you would apply that logic you were able to create easily any other parser (maybe DistanceParser.inputStreamInstance(inputStream) ), you could easily replace your FileErrorHandler with any other ErrorHandler and you were able to test your functionality with a proper unit test

@Test
DistanceParser fileParser = DistanceParser.fileInstance(invalidInput);
ErrorHandler errorHandlerMock = mock(ErrorHandler.class);
fileParser.setErrorHandler(errorHandlerMock );
fileParser.parse(); //errors during execution are handled by the errorHandler (handleError())
verify(errorHandlerMock , atLeastOnce()).handleError();

You know you could implement interfaces on your Parser class and your Errorhandler class, so you can apply Liskovs Substitution Principal ...

Tell, don't ask

another minor issue is naming of your methods, i'm still wondering about your testDoubleLow() methode. if you would use proper names your code would be far more readable.

misleading naming here:

  • testDouble(String s) should be named into isDouble(String doubleAsString)
  • testDoubleLow(String token, double l) should be named into
    isBiggerThan(String doubleAsString, double minimalValue)
\$\endgroup\$
0
\$\begingroup\$

Declare at initialization

        double dealtaX, deltaY, distance,x1, y1, x2, y2;
        String Line, item1, item2, item3, item4;
        String[] Sect;
        Scanner inFile;
        PrintWriter outFile;

In most modern languages, including Java, we declare variables at initialization. In a few cases, we need the scope to be greater so we declare earlier.

There were some older languages where variables had to be declared at the beginning of blocks (e.g. the original version of C) or at the beginning of methods. That is not necessary in Java.

The four item variables are unnecessary. You can just use the array directly.

Java naming conventions

The general Java naming convention is to name constants as ALL_CAPS, types as PascalCase, and variables and methods as camelCase. Sect and Line are variables, so they'd be sect and line in normal usage.

I'm also not sure what Sect is supposed to be. More common names include pieces or tokens, although more explanatory names are possible. Arrays and collections are often plural, as they represent multiple things.

Don't repeat work

You parse each string three times. Once in testDoubleLow; once in testDouble; and then a third time in the main method. It would be better to parse once and then store the result for the other two times.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.