0
import java.util.*;

public class BugFixes
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        altCaps("Computer Science");
    }

    static void altCaps(String hi)
    {
        String hi2 = hi;
        int locate = 0;
        for(int i = 0; i < hi2.length();i++)
        {
            if((Character.isLetter(hi2.charAt(locate))))
            {
                if(hi2.charAt(locate) % 2 == 0)
                {
                    System.out.print(hi2.toLowerCase().charAt(locate));
                    locate++;                   
                }
                else if(hi2.charAt(locate) % 2 == 1)
                {
                    System.out.print(hi2.toUpperCase().charAt(locate));
                    locate++;
                }                
            }
            else if(hi2.charAt(locate) == ' ')
            {
                System.out.print(" ");
                 locate++;
            }
        }
    }
}

This is one of the problems that I have on my current lab. I was able to fix a few other mistakes but I can't seem to find this one.

My question is why it is outputting "COMpUtER SCIEnCE"? I don't understand what is happening here and I've been looking through it for an hour now. My goal is to output "CoMpUtEr ScIeNcE"

I thought the (hi2.charAt(locate) % 2 == 0) and vice versa would alternate between the even and odd locations in the string, but I believe I have made a mistake somewhere. I just can't find it.

Using BlueJ V3.1.7

1 year high school Computer Science Experience and currently enrolled in AP Computer Science

Any Tips?

  • 2
    You should start to learn how to debug a program. Then you can look step-by-step what output is produced and, looking at the state of your program, find programming bugs. – Jeroen Heier Aug 25 '17 at 03:51

3 Answers3

1

not really. So hi2.charAt(locate) % 2 == 0 is actually checking if the integer value of the character is odd or even, but you want to actually check if the index is odd or even if I get you right. In other words:

hi2.charAt(2) % 2 == 0

Is check if m is odd or even. However, I think you want to check if 2 (the index) is odd or even. I guess from here it's easy to assume that you need to change:

if(hi2.charAt(locate) % 2 == 0)
   //...
else if(hi2.charAt(locate) % 2 == 1)
   //...

to

if(locate % 2 == 0)
   //...
else if(locate % 2 == 1)
   //...

This won't give you exactly the output you want, but it's just a matter of inverting the if conditions or the body as you wish. Also, there's no other cases for the operation % 2, meaning you'd only get either an odd or even index, so you could simplify the code by just doing:

if(locate % 2 == 0)
   //...
else
   //...

Which reads better. Hope this helps!

Fred
  • 16,367
  • 6
  • 50
  • 65
1

I would strongly advise refactoring your code to reduce repetative calls, and make inspection of values possible (rather than comparison of function evaluation).

For example:

char currentCharacter = hi2.charAt(locate);

would replace four instances of the function call, and allow you to inspect what the actual value is (rather than what you expect the value to be). This would likely make your error more evident.

Assuming the following values:

hi2 = "Computer Science";
locate = 0;

then it may be worth stepping through the evaluation.

0. hi2.charAt(locate) % 2 == 0
1. "Computer Science".charAt(0) % 2 == 0
2. 'C' % 2 == 0
3. 67 % 2 == 0
4. 1 == 0
5. false

The fundamental problem is that by never assigning your value to a variable, you never take the time to understand what is in it. By assigning it to the variable, you are able to inspect the value using a debugger.

By inspecting the values, we can see that you probably want the mod of 0, not 'C', therefore you probably wanted

0. locate % 2 == 0
1. 0 % 2 == 0
2. 0 == 0
3. true

Bonus

Refactoring your code to reduce repetition, would also highlight other errors. For example, try the following:

assert  "CoMpUtEr sCiEnCe".equals(BugFixes.altcaps("Computer Science"));
assert  "CoMpUtEr-sCiEnCe 201".equals(BugFixes.altcaps("Computer-Science 201"));

KISS: removal of needless logic would reduce the chance of things going wrong.

Jefferey Cave
  • 2,507
  • 1
  • 27
  • 46
  • 1
    I think `i` should be used instead of `locate` – OneCricketeer Aug 25 '17 at 04:10
  • @cricket_007 depenends on whether we are supposed to skip whitespace in the capitalization count. I think there is another defect that may become more apparent later, and requires `locate` for the fix – Jefferey Cave Aug 25 '17 at 04:14
0

For starters, you don't need to reassign the string, or the locate variable, or check if a character is already a character. Just use the iteration integer, if you need it, and the parameter.

Secondly, you're modding the character, not the position.

Anyways, a simple boolean toggle would be easier to understand than modding.

void altCaps(String hi) {
    boolean caps = true;
    for (char ch : hi.toCharArray()) {
        if (ch == ' ') {
            System.out.print(ch);
        } 
        else if (Character.isLetter(ch)) {
            if (caps) System.out.print(Character.toUpperCase(ch));
            else System.out.print(Character.toLowerCase(ch));
            caps = !caps;  // switch between upper and lower every character 
        } 
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Thank you, that does work. but due to my lower level of Java knowledge I don't exactly understand for(char ch : hi.toCharArray()){ if (ch == ' ') { What is 'ch'? What is the function of the Colon? And what does "caps = !caps;" do? – TheLoGiiKaLOne Aug 25 '17 at 04:55
  • First question : https://stackoverflow.com/questions/11685305/what-is-the-syntax-of-enhanced-for-loop-in-java second question : it assigns the boolean to the negated value of itself – OneCricketeer Aug 25 '17 at 11:43