Cocoa Help please :-)

Discussion in 'Mac Programming' started by gizabo, Apr 4, 2009.

  1. macrumors regular

    Joined:
    Jul 20, 2008
    #1
    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?
     
  2. macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #2
    Check your order of operations. Use () to tell the compiler to process your math in the order you want.
     
  3. thread starter macrumors regular

    Joined:
    Jul 20, 2008
    #3
    Here is what my AppController.M looks like:



    And when i run it, i get this error:
     
  4. macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #4
    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.
     
  5. thread starter macrumors regular

    Joined:
    Jul 20, 2008
    #5
    Im sorry, i dont understand... Do i need to change anything in my AppController.H?



    And ill change the %i to a %f like u said like this

    But am i doing anything wrong?
     
  6. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    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:
    Code:
    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
     
  7. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #7
    Hi

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

    % right is is given by:-

    Code:
    perRight = 100.0f * varRight / ( varWrong + varRight ) ;
    
    b e n
     
  8. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    Ha! I didn't even look at the equation being transposed.

    -Lee
     
  9. thread starter macrumors regular

    Joined:
    Jul 20, 2008
    #9
    btw, thanks so much for trying to help me out :)! Im really new at this...


    i put this code into the appcontroller.m

    it still doesnt work


    if you want, you can download it

    http://www.gizabo.com/media/right.zip
     
  10. thread starter macrumors regular

    Joined:
    Jul 20, 2008
  11. macrumors member

    Joined:
    May 9, 2003
    Location:
    Austin, TX
    #11
    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.
     
  12. thread starter macrumors regular

    Joined:
    Jul 20, 2008
    #12
    i changed this:
    into this:
    still get the same error messages...




    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
     
  13. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13
    OK, downloaded the code. This is AppController.m:
    Code:
    #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:
    Code:
    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:
    Code:
    - (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
     
  14. thread starter macrumors regular

    Joined:
    Jul 20, 2008
    #14
    ahhh my app finally works!

    Thanks so much for the help guys!
     

Share This Page