We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Frustration with a double loop
Page Index Toggle Pages: 1
Frustration with a double loop (Read 1094 times)
Frustration with a double loop
Sep 30th, 2009, 3:12pm
 
Good afternoon!
I am trying to load a big data set to perform some calculations based on the values contained in certain columns. I built this code using a simple data set and it worked on most columns, but I noticed that (for some reason it loops over certain columns twice! I can't seem to figure out why!
For example if I had a spread sheet where the 9th column contained only 2 values ('blue' and 'red')
I should see this:
1
2
Red is 20
Blue is 27

but the output that  I am seeing is more like this:
1
2
1
2
Red is 40
Blue is 54

Has anyone seen anything like this before? Do I have a glaring mistake in my code?? I am open to (and grateful for) any suggestions that you might have.
Many thanks!



import processing.pdf.*;
Table t;
HashMap myMap;
int rowCount, labelCount;
int count;

void setup(){
 t = new Table("wf08-09.tsv");
 rowCount = t.getRowCount(  );

 myMap = new HashMap();
 crunchData();
 size(200, 200, PDF, "filename.pdf");
 displayMapContents(myMap);
}

void crunchData(){
 for (int i = 1; i < rowCount; i++) { // Start at 1 to skip the col title
   String value = t.getString(i, 8);
   if(myMap.containsKey(value)){
     count = (Integer)myMap.get(value);
     myMap.put(value,++count);
   }
   else if(!myMap.containsKey(value)){
     myMap.put(value,count); // DEBUGGING
     println(i);
   }    
 }  
}

void displayMapContents(HashMap hm){
 Iterator i = hm.entrySet().iterator();  // Get an iterator

 while (i.hasNext()){
   Map.Entry me = (Map.Entry)i.next();
   print(me.getKey() + " is ");
   println(me.getValue());
 }
}
Re: Frustration with a double loop
Reply #1 - Oct 1st, 2009, 4:49am
 
Let see...
I have no idea why you got twice the values you expect (Blue is 54, probably, no).
I see some issues in your code, and I fail to connect it with the result you have.

So, you get a string at column 9.
If the string is already in the map as a key, you get the previous count. You can probably thank Java 1.5's auto-unboxing in the ++count line...
And you increase the count in the map. OK.
Then you test again if the value is in the map. A bit redundant since you are in the 'else' part already. Not a real problem, unless speed (and readability) is important.
If it is not there, you put the current value of 'count' (a bit random there, no I would put a simple '1') and print the line where it have been found.
Right

Aha!
I think I found the issue.
Remember () what the size() reference page says:
Quote:
The size() function must be the first line in setup(). [...] Again, the size() method must be the first line of the code (or first item inside setup). Any code that appears before the size() command may run more than once, which can lead to confusing results.
Re: Frustration with a double loop
Reply #2 - Oct 1st, 2009, 10:34am
 
Thank you very much for that reminder!
I have taken your advice and cleaned up the code just a little bit. As I have advanced the program I am now encountering another issue: here is the output that I am expecting to see (on a Column that contained values 'M' or 'E')

2923 Total lines
------------------------------------
46.0% M[1335]
54.0% E[1585]
------------------------------------

which looks good, but adding the two gives me 2920.
Then I am getting other print outs like this (for a column that contained letters 'P','S','G' & 'M'):

2923 Total lines
------------------------------------
10.0% P[289]
93.0% S[2720]
22.0% G[651]
10.0% M[287]
------------------------------------
As you can see, the numbers don't add up to the total and the % = 135%!

Is my code really that sloppy? I can understand the data being less than perfect but if my row count is consistent and I am restraining the loop to that count... how is it that the totals and % are off?

Any other ideas or suggestions on how to make this code more reliable?
I am very grateful for any helpful responses!
Thanks!

import processing.pdf.*;
Table t;

HashMap myMap;
int rowCount, labelCount;
int count;
float percent;

void setup(){
 size(200, 200, PDF, "out.pdf");  

 t = new Table("wf08-09.tsv");
 rowCount = t.getRowCount(  );
 println(rowCount+" Total lines");
 println("------------------------------------");
 myMap = new HashMap();
 crunchData();
 displayMapContents(myMap);
 println("------------------------------------");  
}

void displayMapContents(HashMap hm){
 Iterator i = hm.entrySet().iterator();  // Get an iterator
 while (i.hasNext()){
   Map.Entry me = (Map.Entry)i.next();
   Integer value = (Integer)me.getValue();
   percent = ((float)value/(float)rowCount)*100 ;
   float f = (float)Math.round(percent);
   print(f+"% ");
   println(me.getKey()+"["+me.getValue()+"]");
 }
}

void crunchData(){
 for (int i = 1; i < rowCount; i++) { // Start at 1 to skip the col title
   String value = t.getString(i, 8);
   
   if(myMap.containsKey(value)){
     count = (Integer)myMap.get(value);
     myMap.put(value,++count);
   }
   else if(!myMap.containsKey(value)){
     myMap.put(value,count);
     // println(i); //DEBUGGING
   }    
 }  
}  
Re: Frustration with a double loop
Reply #3 - Oct 1st, 2009, 10:51am
 
it's this (which PhiLho has already mentioned)

else if(!myMap.containsKey(value)){
  myMap.put(value,count);
}

count is full of junk at this point.

use
myMap.put(value,1);
instead.
Re: Frustration with a double loop
Reply #4 - Oct 1st, 2009, 11:03am
 
Thanks Koogy (and PhiLho)!
I didn't understand it at first but now I got it, and looking back it was a dumb oversight, thank you for your assistance in my debugging- I am a lone programmer in a big office and it is nice to get another programmer to review your code.
Thank you!!!!

BTW: would you guys know of a quick way to re-order the HashMap in descending order?
Re: Frustration with a double loop
Reply #5 - Oct 1st, 2009, 11:15am
 
> BTW: would you guys know of a quick way to re-order the HashMap in descending order?

by not using a hashmap 8)

http://www.lampos.net/how-to-sort-hashmap
Re: Frustration with a double loop
Reply #6 - Oct 1st, 2009, 11:38am
 
Feralo wrote on Oct 1st, 2009, 11:03am:
would you guys know of a quick way to re-order the HashMap in descending order
As koogy said, just don't use a HashMap, unordered by design, use a TreeMap.
At least if you want to sort it by its keys.
Re: Frustration with a double loop
Reply #7 - Oct 1st, 2009, 1:54pm
 
Many thanks for the excellent advice- I look forward to learning more about TreeMap and possibly re-writing this code when time permits.
Have an excellent afternoon (or whatever the time may be where you live).
Page Index Toggle Pages: 1