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.
Page Index Toggle Pages: 1
code efficiency (Read 346 times)
code efficiency
Feb 1st, 2009, 9:37pm
 
i was wondering where i can use more efficient methods to write out this code? as you can see from the link below, i have a lot of repetitive code.

how would i point to the second or first spots when i want to read the seconds of a clock? say i want to draw the #5 every time it is 5, 15, 25, 35, etc. with a vector image of the #5, how could i condense this code instead of writing repetitive lines of code?

i haven't gotten to classes or arrays yet and am a little puzzled how i can use them, but would love to know how i can use them to write better, more efficient code!

http://dada.cca.edu/~ryau/Sp09/clocks/c2/index.html

thanks!
Re: code efficiency
Reply #1 - Feb 2nd, 2009, 1:35pm
 
result looks good, code looks TERRIBLE 8)

have a class (Digit) containing a two dimensional array for digits, each one containing booleans denoting which segments are lit for that digit.

then have a method that takes the digit number and lights up the relevant segments.

then this abomination:

Code:

void secSpot2(){
pushMatrix();
scale(0.8);
translate(411,414);
switch (s) {
case 1:
case 11:
case 21:
case 31:
case 41:
case 51:
num1();
break;
case 2:
case 12:
case 22:
case 32:
case 42:
case 52:
num2();
break;
case 3:
case 13:
case 23:
case 33:
case 43:
case 53:
num3();
break;
case 4:
case 14:
case 24:
case 34:
case 44:
case 54:
num4();
break;
case 5:
case 15:
case 25:
case 35:
case 45:
case 55:
num5();
break;
case 6:
case 16:
case 26:
case 36:
case 46:
case 56:
num6();
break;
case 7:
case 17:
case 27:
case 37:
case 47:
case 57:
num7();
break;
case 8:
case 18:
case 28:
case 38:
case 48:
case 58:
num8();
break;
case 9:
case 19:
case 29:
case 39:
case 49:
case 59:
num9();
break;
case 0:
case 10:
case 20:
case 30:
case 40:
case 50:
case 60:
num0();
break;
}
popMatrix();
}


can be replaced with
Code:

void secSpot2(){
pushMatrix();
scale(0.8);
translate(411,414);
Digit.draw(s % 10); // the new digit class
popMatrix();
}


% is modulo, or 'remainder' so 11 % 1 = 1.

(all the Spot1 code should use floor(s / 10) )

/ is divide and floor picks the integer part of the result

so 21 / 10 = 2.1 and floor(2.1) = 2

even if you move all the num0, num1... code into a method that takes a parameter, num(int digit) say, and use the above instead of those huge switch statements, that'd be a great improvement.

like i say, the result looks great but if you're repeating stuff over and over again like that it's a sign that something is wrong.
Re: code efficiency
Reply #2 - Feb 2nd, 2009, 10:53pm
 
ok, i've rewritten your time class and replaced it with the following:

Code:

// HOURS//////////////////////////////////////////////

void hourSpot1(){
pushMatrix();
translate(166,323);
//digit.draw(floor(h / 10)); // this is 24 hour clock
digit.draw(floor((h % 12) / 10)); // this is 12 hour clock
popMatrix();
}

void hourSpot2(){
pushMatrix();
translate(198,323);
//digit.draw(h % 10); // 24 hour clock
digit.draw(((h % 12) % 10)); // this is 12 hour clock
popMatrix();
}

//MINUTES//////////////////////////////////////////////

void minSpot1(){
pushMatrix();
translate(242,323);
digit.draw(floor(m / 10));
popMatrix();
}

void minSpot2(){
pushMatrix();
translate(274,323);
digit.draw(m % 10);
popMatrix();
}

//SECONDS//////////////////////////////////////////////

void secSpot1(){
pushMatrix();
scale(0.8);
translate(382,414);
digit.draw(floor(s / 10));
popMatrix();
}

void secSpot2(){
pushMatrix();
scale(0.8);
translate(411,414);
digit.draw(s % 10);
popMatrix();
}


(52 lines rather than 296)

please forgive indenting. more to come...

{edit, oops, pasted the wrong thing}
Re: code efficiency
Reply #3 - Feb 2nd, 2009, 10:54pm
 
and replaced your timepieces file with the following Digit class (the variable definition at the top is because this is an inner class so i can't make everything static like i'd like to)

Code:

Digit digit = new Digit();

class Digit {

public static final int SEG_TOP = (0x1 << 0);
public static final int SEG_MID = (0x1 << 1);
public static final int SEG_BOT = (0x1 << 2);
public static final int SEG_TOP_L = (0x1 << 3);
public static final int SEG_TOP_R = (0x1 << 4);
public static final int SEG_BOT_L = (0x1 << 5);
public static final int SEG_BOT_R = (0x1 << 6);

// define which bars light for which digit (uses a bitfield)
final int[] segments = {
/* 0 */ SEG_TOP | SEG_TOP_L | SEG_TOP_R | SEG_BOT_L | SEG_BOT_R | SEG_BOT,
/* 1 */ SEG_TOP_R | SEG_BOT_R,
/* 2 */ SEG_TOP | SEG_TOP_R | SEG_MID | SEG_BOT_L | SEG_BOT,
/* 3 */ SEG_TOP | SEG_TOP_R | SEG_MID | SEG_BOT_R | SEG_BOT,
/* 4 */ SEG_TOP_L | SEG_TOP_R | SEG_MID | SEG_BOT_R,
/* 5 */ SEG_TOP | SEG_TOP_L | SEG_MID | SEG_BOT_R | SEG_BOT,
/* 6 */ SEG_TOP | SEG_TOP_L | SEG_MID | SEG_BOT_L | SEG_BOT_R | SEG_BOT,
/* 7 */ SEG_TOP | SEG_TOP_R | SEG_BOT_R,
/* 8 */ SEG_TOP | SEG_TOP_L | SEG_TOP_R | SEG_MID | SEG_BOT_L | SEG_BOT_R | SEG_BOT,
/* 9 */ SEG_TOP | SEG_TOP_L | SEG_TOP_R | SEG_MID | SEG_BOT_R | SEG_BOT
};

// TODO move pushMatrix, translate and popMatrix to horizDashTop() etc
public void draw(int digit) {
// check whether this digit shows this segment
// uses binary AND for testing individual bits
if ((segments[digit] & SEG_TOP) != 0) {
pushMatrix();
translate(1, 0);
horizDashTop();
popMatrix();
}
if ((segments[digit] & SEG_MID) != 0) {
pushMatrix();
translate(2,19);
horizDashMid();
popMatrix();
}
if ((segments[digit] & SEG_BOT) != 0) {
pushMatrix();
translate(1, 38);
horizDashBott();
popMatrix();
}
if ((segments[digit] & SEG_TOP_L) != 0) {
pushMatrix();
translate(0,2);
vertDashLTop();
popMatrix();
}
if ((segments[digit] & SEG_TOP_R) != 0) {
pushMatrix();
translate(16,2);
vertDashRTop();
popMatrix();
}
if ((segments[digit] & SEG_BOT_L) != 0) {
pushMatrix();
translate(0,22);
vertDashLBott();
popMatrix();
}
if ((segments[digit] & SEG_BOT_R) != 0) {
pushMatrix();
translate(16,22);
vertDashRBott();
popMatrix();
}
}
}


(74 lines rather than 274)

same thing is possible with the date stuff.
Re: code efficiency
Reply #4 - Feb 3rd, 2009, 7:12am
 
wow, thank you so much! it works great! you are extremely helpful and easy to follow. hopefully my code will be less of a disaster from now on. i moved the moved the pushMatrix, translate and popMatrix to horizDashTop(), etc. to the time vector pieces like you suggested.

my only question is how does this part work:

 public static final int SEG_TOP = (0x1 << 0);
 public static final int SEG_MID = (0x1 << 1);
 public static final int SEG_BOT = (0x1 << 2);
 public static final int SEG_TOP_L = (0x1 << 3);
 public static final int SEG_TOP_R = (0x1 << 4);
 public static final int SEG_BOT_L = (0x1 << 5);
 public static final int SEG_BOT_R = (0x1 << 6);

i looked up the left shift << thing and kind of get it. i'm not sure what 0x1 is? public, static, and final is java? sorry i'm such a newbie!

thanks again for steering me towards the right direction! this is very helpful!
Re: code efficiency
Reply #5 - Feb 3rd, 2009, 11:47am
 
oh, the other thing i meant to say was to use frameRate(2); in your setup - my processor usage went from 90+% to about 10% after i did this - there's no point updating the screen 60 times a second if what you're displaying only updates once a second 8)

the SEG_TOP things is the old C way of using integers to represent sets. you can represent as many boolean values as you have bits in an int

0x1 << 0 = 1 or 00000001
0x1 << 1 = 2 or 00000010
0x1 << 2 = 4 or 00000100

(you sometimes see these things defined as 0x1, 0x2, 0x4, 0x8 etc but that gets fiddly above 10 or so bits)

and you can OR these together to set as many bits as you like

00000001 | (SEG_TOP)
00000010 = (SEG_MID)
00000011 (SEG_TOP and SEG_MID both set)

which is what the segments array is setting up.

and this

Code:

if ((segments[digit] & SEG_BOT_R) != 0) {


checks to see if the relevant bit is set (is easier in C as you don't need the compare as anything that isn't 0 is taken as boolean true)

see Uses Of Bitmasks here
http://en.wikipedia.org/wiki/Mask_(computing)

it is a bit arcane these days, this stuff. when i started we didn't have the luxury of gigs of memory and got used to bit twiddling like this to save space 8)

public static final on a variable marks it out as a constant, something that can't be changed (the UPPERCASE name for constants is also a common thing)
Re: code efficiency
Reply #6 - Feb 5th, 2009, 8:08am
 
yeah that makes sense now. thanks again for your help, koogs!
Page Index Toggle Pages: 1