Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi folks, hoping someone can help.

I have an arraylist of Integers. When there is a button click the data in the text field gets converted and added to the array list as an int. You can see, once there has been ten submissions (counter takes care of that) it calls the function train();. Here is my code for that below

Java
public void onClick(View v) {
            // TODO Auto-generated method stub

            String rate = happy.getText().toString();
            int rating = Integer.valueOf(rate);
            counter += 1;

            if (counter == 10) {
                train();
            }

            if (rating > 0 && rating < 11) {
                happyRating.add(rating);

                test = happyRating.get(0);
                Log.d("Value: ", Integer.toString(test));

            } else {

                InputAlertHandler.post(new Runnable() {
                    public void run() {
                        int duration = Toast.LENGTH_LONG;
                        CharSequence text = "Please enter Happiness Indicator between 1 and 10";
                        Context context = getApplicationContext();
                        inputAlert = Toast
                                .makeText(context, text, duration);
                        inputAlert.show();
                    }
                });
            }
        }

In the function train(); I am getting data from this array list and using it in calculations.
public void train() {

    for (int i = 2; i < 12; i++) {

        if (happyRating.get(i - 1) < happyRating.size()){

            int x, x1, x2, y, y1, y2;
            double learningRate = -0.00002;

            x1 = happyRating.get(i - 1);
            x2 = happyRating.get(i - 2);
            y1 = iteration[i - 1];
            y2 = iteration[i - 2];

            x = x2 - x1;
            y = y2 - y1;

            if (x == 0) {
                slope = 0;
            } else {
                slope = (y2 - y1) / (x2 - x1);
            }
            j++;

            Log.d("J:", + Integer.toString(j));

            double weightAdj = happyRating.get(j) * slope * learningRate;

            weighting = (weighting + weightAdj);

            Log.d("WEIGHTING:", + Double.toString(weighting));

        }
        else{
            break;
        }
    }

When the train() gets called I get the error. Now I know this looks strange and you'll ask why set i=2 and i<12, the reason for this is I need to calculate the slope of the two previous points, and use [i-2] and [i-1] to get those points, if I had i = 0 then had [i-1] there would be an error. I know why I'm getting the index error because when i hits 11 and i-1 = 10 and there's no index ten in the array list. However I thought that by including my check
if (happyRating.get(i - 1) < happyRating.size())

That this would handle that error. I was obviously wrong.
Could anyone suggest an alternative to my method?

Regards,
Gary
Posted
Comments
Prasad Khandekar 22-Apr-13 10:35am    
You may want to change this if (happyRating.get(i - 1) < happyRating.size()){ line to if (i < happyRating.size()){
GaryDoo 22-Apr-13 11:05am    
@Prasad, thank you for your reply, unfortunately I still get the same issue...

I have made some changes to your block, have a look and let me know if that works...
Rather then going backward (i-1, i-2), I rewrite the logic for going forward (i, i+1).
So, when you are at i=0, you actually calculates slope for (i and i+1) to a max value of 9 (happyRating.size() - 1)
Java
public void train() {
 
    for (int i = 0; i < happyRating.size() - 1; i++) {
 
        if ((i + 1) < happyRating.size()){
 
            int x, x1, x2, y, y1, y2;
            double learningRate = -0.00002;
 
            x1 = happyRating.get(i + 1);
            x2 = happyRating.get(i);
            y1 = iteration[i + 1];
            y2 = iteration[i];
 
            x = x2 - x1;
            y = y2 - y1;
 
            if (x == 0) {
                slope = 0;
            } else {
                slope = (y2 - y1) / (x2 - x1);
            }
            j++;
 
            Log.d("J:", + Integer.toString(j));
 
            double weightAdj = happyRating.get(j) * slope * learningRate;
 
            weighting = (weighting + weightAdj);
 
            Log.d("WEIGHTING:", + Double.toString(weighting));
 
        }
        else{
            break;
        }
    }
}


Hope that helps you out...

Regards,
Niral Soni
 
Share this answer
 
Comments
GaryDoo 22-Apr-13 11:45am    
Hi Nira, thank you for your reply. Would you mind explaining further to me about rewriting the logic to go forward instead of backwards? I don't just want to copy and paste something and not have a full understanding of it first.

Also why would you have if ((i + 1) < happyRating.size()) instead of just i or happyRating.get(i)?

Regards,
gary
Niral Soni 22-Apr-13 12:17pm    
((i + 1) < happyRating.size()) instead of just i or happyRating.get(i)

Because, in your original code, happyRating.get(i - 1) could be any random value (eventhough you asked explicitly for value between 1 to 10).

Regarding the new logic -
1) the loop starts with index 0 until it reaches to 8. So that the total values accessed within the block will be in the pairs - (0,1) (1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) which covers all the indexes within happyRating arraylist
2) your x1y1 pair will be the index i + 1, and x2y2 pair will be the index i.
GaryDoo 22-Apr-13 12:50pm    
I am so sorry, I don't know if it's tiredness or looking at the code too long...of course if (happyRating.get(i - 1) < happyRating.size()) doesn't work, that is a really stupid mistake!! I'm sorry about that!! thank you for explaining the slope logic! so will the correct slope calculation be used in the weighting calculation?

Also just to ask the question differently, why are you saying i+1 in the if statement?

That's the last question! Thanks for your help
Niral Soni 23-Apr-13 5:26am    
In the for loop, value of 0 <= i < happyRating.size() - 1, which means if happyRating size is 10, then i will loop from value 0 till value 8.
the if condition within for loop is actually not required (i just placed it to avoid multiple changes in your code). You can remove this if block (and no need of break statement in else block).

Anyway, i+1 < happyRating.size() is a boundary check condition to avoid any IndexOutOfBoundsException.
Hi,
There are same issues in your code.
1- The counter variable is never reseted (may be can be set to zero in another function)
2- You only call the train function when counter is equal to 10 but your array only has 9 items or less, if the rating is not between 0 and 11
3- Another thing, you may not use this
Java
if (happyRating.get(i - 1) < happyRating.size())

but this
Java
if ((i - 1) < happyRating.size())

because you address the item by i - 1 and this is what you want to check.
4- Same as counter. The variable j is not initialized in that function neither reseted, be carefull.

Best regards
Filipe
 
Share this answer
 
Comments
GaryDoo 22-Apr-13 11:03am    
Thank you for your reply Filpe, I have set both counter and j as global, I can adjust this. In relation to the counter, I want the user to make 10 submissions, so each time the user clicks submit, the counter increases, is this not the correct way of tracking it?
by changing

if (happyRating.get(i - 1) < happyRating.size()) to if ((i - 1) < happyRating.size())

I still get the error.
Filipe Marques 22-Apr-13 12:15pm    
In train() function, inside the if block, you have happyRating.get(i - 1). If you keep the code of onClick() function (see my second point in my answer), when i=11 you are access the 10th element, your array only has 9 elements.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900