PDA

View Full Version : Cocoa Help please :-)




gizabo
Apr 4, 2009, 12:33 PM
Hey, im making an app to test grades... u click the "right button" if they got the anwser right, and the wrong button if they got it wrong...


So at the bottem there is a label, and i want it to show the total percentage you got correct... So why doesnt this code work

perRight = varRight + varWrong / varRight * 100;


perRight > Should be the total percentage
varRight > # of correct anwsers
varWrong > # of wrong anwsers

so lets say i have 60 righs and 40 wrongs... it adds that and its 100.. then it divides it by total right anwsers which is 60... and i should get .60 ... then i multiply by 100 to get 60

how would i asign the % to the variable perRight?



GorillaPaws
Apr 4, 2009, 12:48 PM
Hey, im making an app to test grades... u click the "right button" if they got the anwser right, and the wrong button if they got it wrong...


So at the bottem there is a label, and i want it to show the total percentage you got correct... So why doesnt this code work



perRight > Should be the total percentage
varRight > # of correct anwsers
varWrong > # of wrong anwsers

so lets say i have 60 righs and 40 wrongs... it adds that and its 100.. then it divides it by total right anwsers which is 60... and i should get .60 ... then i multiply by 100 to get 60

how would i asign the % to the variable perRight?

Check your order of operations. Use () to tell the compiler to process your math in the order you want.

gizabo
Apr 4, 2009, 12:52 PM
Here is what my AppController.M looks like:


@implementation AppController

perRight = ((varRight + varWrong) / varRight) * 100;

- (IBAction)right:(id)sender; {
varRight++;
[numberRight setStringValue:[NSString stringWithFormat:@"%i Correct", varRight]];
[percentCorrect setStringValue:[NSString stringWithFormat:@"Percent Right: %i", perRight]];
}

- (IBAction)wrong:(id)sender; {
varWrong++;
[numberWrong setStringValue:[NSString stringWithFormat:@"%i Incorrect", varWrong]];
[percentCorrect setStringValue:[NSString stringWithFormat:@"Percent Right: %i", perRight]];
}

@end




And when i run it, i get this error:

warining: type defaults to 'int" in declaration of "perRight"
error: 'varRight' undeclared here (not in a function)
error: 'varWrong' undeclared here (not in a function)
warning: data definition has no type or storage class

GorillaPaws
Apr 4, 2009, 01:03 PM
Here is what my AppController.M looks like:





And when i run it, i get this error:

You need to declare your variables. An undeclared variable will default to int, but when you're doing division, you're going to want a float type.

gizabo
Apr 4, 2009, 01:07 PM
Im sorry, i dont understand... Do i need to change anything in my AppController.H?

#import <Cocoa/Cocoa.h>


@interface AppController : NSObject {

int varRight;
int varWrong;
int perRight;


IBOutlet NSTextField *percentCorrect;
IBOutlet NSTextField *numberRight;
IBOutlet NSTextField *numberWrong;
}

- (IBAction)right:(id)sender;
- (IBAction)wrong:(id)sender;

@end




And ill change the %i to a %f like u said like this
[percentCorrect setStringValue:[NSString stringWithFormat:@"Percent Right: %f", perRight]];


But am i doing anything wrong?

lee1210
Apr 4, 2009, 02:17 PM
floats aren't really worth using at this point. In this case, you're really only worried about 4-5 sigfigs, so it's not a huge deal, but I would use double for any floating point math you need to do. As such, declare all of your variables as doubles. The number right, number wrong, and total number will be whole numbers, and can be stored in ints if you like, but then you have to be sure you make casts to double, so it may be easier at this point to just define them as doubles. The 12 bytes of memory you spend for it will likely go unnoticed.

Once they are doubles, you can use the appropriate format specifier to display it... look here:
http://developer.apple.com/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
for the right specifier. You will also want to specify decimal positions, as the result will not always be whole. You could alternately do something like this:

double x,y;
int result;
...
result = (int)((((x+y)/x)*100)+.5);


This will round to the nearest percent, and give you an int result that you can print with %d or %i.

-Lee

lazydog
Apr 4, 2009, 03:17 PM
Hi

I'm pretty sure you're calculating the percentage wrong:-

% right is is given by:-


perRight = 100.0f * varRight / ( varWrong + varRight ) ;


b e n

lee1210
Apr 4, 2009, 03:21 PM
Hi

I'm pretty sure you're calculating the percentage wrong:-

% right is is given by:-


perRight = 100.0f * varRight / ( varWrong + varRight ) ;


b e n
Ha! I didn't even look at the equation being transposed.

-Lee

gizabo
Apr 4, 2009, 03:42 PM
btw, thanks so much for trying to help me out :-)! Im really new at this...


i put this code into the appcontroller.m


perRight = 100.0f * varRight / ( varWrong + varRight ) ;

it still doesnt work


if you want, you can download it

http://www.gizabo.com/media/right.zip

gizabo
Apr 4, 2009, 03:49 PM
sorry, download it here
http://www.mediafire.com/?2mzhvvyynjx


the other link doesnt work

chrysrobyn
Apr 4, 2009, 04:20 PM
i put this code into the appcontroller.m

perRight = 100.0f * varRight / ( varWrong + varRight ) ;
it still doesnt work


Did you change the type of perRight to a float or double? You're certainly sending it a float, and if it's still an int, that'd be the first place I'd suspect.

If you did, you should elaborate on the type of error message.

gizabo
Apr 4, 2009, 04:27 PM
i changed this:
int perRight;

into this:
double perRight;

still get the same error messages...

warining: type defaults to 'int" in declaration of "perRight"
error: 'varRight' undeclared here (not in a function)
error: 'varWrong' undeclared here (not in a function)
warning: data definition has no type or storage class






Would u mind downloading my code and taking a look?
http://www.mediafire.com/?2mzhvvyynjx



In the file that im sending you, perRight is still an int in AppController.H

lee1210
Apr 4, 2009, 06:47 PM
OK, downloaded the code. This is AppController.m:
#import "AppController.h"
@implementation AppController

perRight = 100.0f * varRight / ( varWrong + varRight );

- (IBAction)right:(id)sender; {
varRight++;
[numberRight setStringValue:[NSString stringWithFormat:@"%i Correct", varRight]];
[percentCorrect setStringValue:[NSString stringWithFormat:@"Percent Right: %f", perRight]];
}

- (IBAction)wrong:(id)sender; {
varWrong++;
[numberWrong setStringValue:[NSString stringWithFormat:@"%i Incorrect", varWrong]];
[percentCorrect setStringValue:[NSString stringWithFormat:@"Percent Right: %f", perRight]];
}

@end

This line:

perRight = 100.0f * varRight / ( varWrong + varRight );

is outside of any method definition. This will not work. In many of the hardware modeling languages, things happen "at once", so something like this might fly, but in a procedural language you can't stick a statement out in no-man's-land and hope that it is "constantly" evaluated. If you want this to be up-to-date each time an action happens, perhaps you can make a method:
-updateScore
on your AppController class, that will get the current value (no need to store it in an ivar, you can always recalculate it) and set the appropriate NSTextField to this value. This can then be called from both of your other methods after they update the appropriate ivar.

It's fine to keep varRight and varWrong as ints, but you need to force floating point division to get anything of worth, so in updateScore, you'd have a line like:

- (void) updateScore {
double percentScore = 100.* (((double)varRight)/(varLeft+varRight));
[percentCorrect setDoubleValue:percentScore];
}


I'll leave formatting to you, you could do it with an NSString and use setStringValue: instead, or set the formatting of the control using the appropriate methods.

Casting varRight to double will force promotion of the other argument of the / to double as well, and the result will be a double. This will then force the left operand of the *, 100. (which will be a float) to be promoted to a double as well, and the whole expression will evaluate to a double. The same could be done with a float, but as i stated earlier, it's not worth the cost of precision in my opinion, even when you don't need it.

-Lee

gizabo
Apr 4, 2009, 09:51 PM
ahhh my app finally works!

Thanks so much for the help guys!