cs193p fall 2011 iPhone Application Developnment Assignment 1 solution
Once again big thank you goes to Stanford and Paul Hegarty for creating this great video tutorials.
Nuff' talking. Lets get to work.
TASK 1.
1. Implement a “backspace” button for the user to press if they hit the wrong digit button.
This is not intended to be “undo,” so if they hit the wrong operation button, they are
out of luck! It’s up to you to decided how to handle the case where they backspace
away the entire number they are in the middle of entering, but having the display go
completely blank is probably not very user-friendly.
My Solution:
My idea here is to create a new string that contains everything but the last character from the display UILable. The hardest thing here is to dig into the documentation to find a method that you can call upon NSString to create a subString from original string. I have found substringToIndex: method. It creates a new string from the original string. It takes original string from the beginning and to the index you provide. Find more on substringToIndex:
- (IBAction)backspacePressrd { if (self.display.text.length){ self.display.text= [self.display.text substringToIndex:(self.display.text.length - 1)]; }
TASK 2.
2. When the user hits an operation button, put an = on the end of the text label that is
showing what was sent to the brain (required task #4). Thus the user will be able to tell
whether the number in the Calculator’s display is the result of a calculation or a
number that the user has just entered.
My Solution: I am not sure if I understood this assignment correctly. It is not hard to add = to the end of brainHistory UILable every time someone hits enter. The trick is to remove it after something other than enter is pressed. So I introduced new Boolean variable which is true if the = is shown and false if it is not. If someone has a better solution to this let me know.
Iniside the interface of the ViewControler.m file I have declared property
@property (nonatomic) BOOL equalsIsShown;inside of the interface of the same file I have synthesized getter and setter for the same property.
@synthesize equalsIsShown=_equalsIsShown;
I have added check if a = is already on the screen when user starts to enter the number. If it is app will remove it.
- (IBAction)digitPressed:(UIButton *)sender {
NSString *digit =[sender currentTitle];
NSLog(@"Digit pressed %@", digit);
NSRange isNumberDecimal = [self.display.text rangeOfString:@"."];
if ((self.brainHistory.text.length)&&(self.equalsIsShown)){
self.brainHistory.text= [self.brainHistory.text
substringToIndex:(self.brainHistory.text.length - 1)];
self.equalsIsShown=NO;
}
if (self.userIsInTheMiddleOfEnteringANumber){
//the rest of the method stays unchanged
I have also modified operationPressed: method. The last two lines are new.
- (IBAction)operationPressed:(UIButton *)sender { if(self.userIsInTheMiddleOfEnteringANumber){ [self enterPressed]; } NSString *operation = [sender currentTitle]; double result=[self.brain performOperation:operation]; self.display.text=[NSString stringWithFormat:@"%g",result]; self.brainHistory.text=[self.brainHistory.text stringByAppendingString:@" "]; self.brainHistory.text=
[self.brainHistory.text stringByAppendingString:operation]; self.brainHistory.text=[self.brainHistory.text stringByAppendingString:@"="]; self.equalsIsShown=YES; }
TASK 3.
3. Add a +/- operation which changes the sign of the number in the display. Be careful
with this one. If the user is in the middle of entering a number, you probably want to
change the sign of that number and let them continue entering it, not force an
enterPressed like other operations do. But if they are not in the middle of entering a
number, then it would work just like any other single-operand operation (e.g. sqrt).
My Solution: I am not sure if I am doing this right. I don't understand what does if user is in the middle of entering a nuber have to do with plus/minus change? I have created a separate button (new button) for this. Created a new method pusMinus for my new button. When I hit the button I convert the string from display UILabel to a double, then multiply the number with -1 and then again convert it back to string.
- (IBAction)plusMinus { self.display.text=
[NSString stringWithFormat:@"%g",([self.display.text doubleValue]*-1)]; }
This is not ideal solution because if users decides to change sign in front of the number right after typing decimal point the point will be lost. A better solution could be by manipulating strings. First you check first character of the display UILabel if it is minus or a nuber. If it is a minus then remove the fist character. If it is not create a new string with minus in front. Think that would work.
Great, will you post assignment 2?
ReplyDeleteI hope so. I was looking at assignment 2 but I don't quite understand it, so it could take some time before I understand it and solve it.
ReplyDeleteYes, it's a bit confusing. Thanks for the reply:)
ReplyDeletere- Task 3
ReplyDeleteIf the user is a typing number then he should be able to continue extending the number. (just as you did).
However it would also be possible to change the sign of an answer (result). I that case you need to change the stack as well.
Good point Arnaud.
DeleteMaybe solution would be:
Check if the user is in the middle of entering the number. If he is then pop operand and push new number on the stack. I am too lazy to implement that in the code, so if you decide to try it let us know the result...
I fact that is what I implemented.
DeleteFor Task 1 this solution is able to reset the display when the last digit is deleted with backspace:
ReplyDelete- (IBAction)backspacePressed {
if (self.display.text.length > 1){
self.display.text = [self.display.text substringToIndex:(self.display.text.length -1)];
} else { self.display.text = @"0"; self.userIsInTheMiddleOfEnteringANumber = NO; }
}
Hi Salvatore,
DeleteI first did the substring, and then depending on the result I set the display to 0. This seemed to make it neater for catering for negative numbers too...
- (IBAction)backspacePressed {
self.display.text =[self.display.text substringToIndex:
[self.display.text length] - 1];
if ( [self.display.text isEqualToString:@""]
|| [self.display.text isEqualToString:@"-"]) {
self.display.text = @"0";
self.userIsInTheMiddleOfEnteringNumber = NO;
}
}
Full solution at http://www.i4-apps.com
For Task 2 there is no need to track if equal is shown or not.
ReplyDeleteYou can update the Brain History display (log) after an operation with the text resulting from this string manipulation:
self.log.text = [[self.log.text stringByReplacingOccurrencesOfString:@"= " withString:@""] stringByAppendingString:@"= "];
yep.. i did the same
DeleteI've posted my solution to the extra credit tasks at http://www.i4-apps.com
ReplyDeleteFOR TASK 2:
ReplyDeleteif ([self.userInputHistory.text rangeOfString:@"="].location == NSNotFound) {
self.userInputHistory.text = [self.userInputHistory.text stringByAppendingString:@" ="];
}else {
self.userInputHistory.text = [[self.userInputHistory.text stringByReplacingOccurrencesOfString:@" =" withString:@""]stringByAppendingString:@" ="];
}
This is how I implemented Task 1. If the last character after backspacing is a point, the point gets removed, too.
ReplyDelete- (IBAction)backspace {
NSUInteger length = self.display.text.length;
if(length > 1) {
self.display.text = [self.display.text substringToIndex:length-1];
if([self.display.text hasSuffix:@"."]) {
self.display.text = [self.display.text substringToIndex:length-2];
}
} else {
self.display.text = @"0";
self.userIsInTheMiddleOfEnteringANumber = NO;
}
}