1
\$\begingroup\$

Write a static method named plusScores that accepts as a parameter a Scanner containing a series of lines that represent student records. Each student record takes up two lines of input. The first line has the student's name and the second line has a series of plus and minus characters. Below is a sample input:

Kane, Erica
--+-+
Chandler, Adam
++-+
Martin, Jake
+++++++
Dillon, Amanda
++-++-+-

The number of plus/minus characters will vary, but you may assume that at least one such character appears and that no other characters appear on the second line of each pair. For each student you should produce a line of output withthe student's name followed by a colon followed by the percent of plus characters. For example, if the input above is stored in a Scanner called input, the call of plusScores(input); should produce the following output:

Kane, Erica: 40.0% plus
Chandler, Adam: 75.0% plus
Martin, Jake: 100.0% plus
Dillon, Amanda: 62.5% plus

I'm looking for alternative ways of solving this problem, and of course any potential bugs or pitfalls my code may have. If you have something interesting to share, please do! I'm new to programming and am eager to see other ways of accomplishing a problem such as this one. Here's my code:

public static void plusScores(Scanner sc) {
    while (sc.hasNextLine()) {
        String line = sc.nextLine();
        if (!line.startsWith("+") && !line.startsWith("-")) {
            System.out.print(line);
        } else {

            int plus = 0;
            int minus = 0;

            for (char ch : line.toCharArray()) {
                if (ch == '+') {
                    plus++;
                } else {
                    minus++;
                }
            }

            float percentPlus = ((float) (plus) / (plus + minus)) * 100;
            System.out.format(": %.1f%% plus\n", percentPlus);
        }
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ well your code is pretty good and correctly answer the task given so I'd let it as it is. We can see that bad input (for example two students name given in a row) will produce "buggy" output but the task tell you that you can "assume" that the input will be correct... If you want, you can edit your answer to include your main method or something so users may give you a review on your whole code ;) \$\endgroup\$ – Ronan Dhellemmes Jan 18 '18 at 11:18
1
\$\begingroup\$

Your approach is mostly correct, but it has the fallacies of encompassing the entire logic and gives no meaningful names/explanations to the flow, variables etc. a more robust, extensible, clear and maintainable solution would be to replace all constants with final variables and encapsulate small problem domains into their own methods. For exmaple:

   public static final String PLUS = "+";
   public static final String MINUS = "-";

   ...

   if (isStudentNameLine(line)) {
        processStudentNameLine(line);
   } else {
   ...

   private static boolean isStudentNameLine(String line) {
       return !line.startsWith(PLUS) && !line.startsWith(MINUS);
   }

   private static void processStudentNameLine(String line) {
        System.out.print(line);
   }

This may seem like an overkill to replace one lines of codes with methods. There are many advantages to this approach:

  1. using variables instead of constants mean you dont have to deal with typos
  2. smaller methods are easier to debug
  3. the code becomes clearer
\$\endgroup\$
  • \$\begingroup\$ I'll definitely take away separating specific subtasks into their own respective methods :). \$\endgroup\$ – cody.codes Jan 18 '18 at 19:44
1
\$\begingroup\$

Your approach is mostly correct, but it seems to be too specifically written to solve the problem as stated.

For instance, you're making the assumption that any line that doesn't start with a plus or a minus is a line containing student names.

One example case: what if a student gets no pluses or minuses? This wouldn't occur in the case as stated, but you usually don't get this "it's already handled" and it just helps to program in such a way that input which slightly deviates from normal can still be dealt with gracefully.

You're also making the assumption that when you're counting pluses and minuses, everything that is not a plus is a minus.

This works, for now. But if changes in the scoring mechanism are requested, you might want to go with a more flexible approach - one which separates the I/O and the counting, for instance.

\$\endgroup\$
  • \$\begingroup\$ it is stated in the exercise that the 2nd line will contain at least one plus or minus signs... \$\endgroup\$ – Sharon Ben Asher Jan 18 '18 at 13:19
  • \$\begingroup\$ This is interesting and I really like the idea of being able to write code that could potentially deal with situations other than the stated case. Do you have any recommendations for what you'd do in this case (specifically what code would you write?) \$\endgroup\$ – cody.codes Jan 18 '18 at 19:40
  • 1
    \$\begingroup\$ @cody.codes sharon provides a good example of splitting things up; adding to that would be doing things like taking each alternative line as student name (so expecting input to be student name, pluses and minuses, student name, pluses and minuses... by line, not by content) \$\endgroup\$ – Pimgd Jan 19 '18 at 8:44

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.