I created a simple calculator. Everything works great; however, if I divide by zero, I would like to show an error message. I know how to do alert popups, but I don't know how to implement it so it comes up when I divide by zero. Here is a snipped of my calculator code:
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
CalcDisplay.text = [NSString stringWithFormat:#"%g",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
You can just add a test prior to doing the division e.g. change:
case 4:
result = result / currentNumber;
break;
to:
case 4:
if (currentNumber == 0)
// ... do alert here ...
else
result = result / currentNumber;
break;
You have to check if the second division operand is zero, and if yes, then print an error message. Don't forget, that you can't just compare double or something with ==, you have to use presicion, like this:
case 4:
if(ABS(currentNumber) < 1e-12) // most probably its zero
// your message
return;
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
if(currentNumber == 0){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}else{
result = result / currentNumber;
}
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
CalcDisplay.text = [NSString stringWithFormat:#"%g",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
Please try this code, I have copied an pasted the code you have given and added some necessary lines to it which i felt would solve your issue.
Related
In Swift it is possible to check a tuple like,
switch(type1, type2) {
case (1, 1):
functionNormal()
case (1, 2):
functionUncommon()
case (1, 3):
functionRare()
...
}
Is it possible to check tuple like multiple values in Objective-C Switch case? Any way around?
There could be various approaches, depending on exactly what your type1 and type2 data might be.
However, here is a basic example:
NSInteger i = 1;
NSInteger j = 2;
switch (i) {
case 1:
switch (j) {
case 1:
[self functionNormal];
break;
case 2:
[self functionUncommon];
break;
case 3:
[self functionRare];
break;
default:
NSLog(#"first value: 1 ... missing case for second value: for %ld", (long)j);
break;
}
break;
case 2:
switch (j) {
case 1:
[self secondFunctionNormal];
break;
case 2:
[self secondFunctionUncommon];
break;
case 3:
[self secondFunctionRare];
break;
default:
NSLog(#"first value: 2 ... missing case for second value: %ld", (long)j);
break;
}
break;
default:
NSLog(#"missing first case for first value: %ld", (long)i);
break;
}
This is rather inefficient, of course, but maybe it can get you on your way.
Edit
Again, it will depend on your data, but another approach more closely resembling your Swift example:
NSInteger i = 1;
NSInteger j = 2;
NSInteger ij = i * 1000 + j;
switch (ij) {
case 1001:
[self functionNormal];
break;
case 1002:
[self functionUncommon];
break;
case 1003:
[self functionRare];
break;
case 2001:
[self secondFunctionNormal];
break;
case 2002:
[self secondFunctionUncommon];
break;
case 2003:
[self secondFunctionRare];
break;
default:
NSLog(#"case was something else: %ld", (long)ij);
break;
}
I have a random method to create 2 random integers. My concern is that %65-%70 of outputs are same integers like "5-5" "4-4" "3-3".
-(void)random{
NSUInteger randomNumber = arc4random_uniform(5);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"five.png"];
break;
}
NSUInteger randomNumber2 = arc4random_uniform(5);
switch (randomNumber2) {
case 0:
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
}
}
Should i create 25 different case to reach better result?
NSUInteger randomNumber = arc4random_uniform(25);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
case 5:
_tile2.image = [UIImage imageNamed:#"two.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
...
}
}
arc4random_uniform is great for getting one random integer. When i need to get 2 or more random numbers, the outputs are not that great. What is the best way of doing this?
Sorry, but I don't believe you. You must be doing something other than what you've shown. The following code pasted into Playground consistently gives around a 20% match, not the 65-70% you claim:
import Cocoa
let sampleSize = 1000
var count = 0
for i in 1...sampleSize {
var randomNumber1 = arc4random_uniform(5)
var randomNumber2 = arc4random_uniform(5)
if randomNumber1 == randomNumber2 {
++count
}
}
println( Double(count) / Double(sampleSize) )
Whatever problem you're having, it isn't with how arc4random_uniform generates pairs of values.
Would using an array of numbers be a solution for you?
You can have a mutable array of numbers `[#0, #1, #2, #3, #4] and retrieve one number from a random index
NSMutableArray *array = [NSMutableArray arrayWithObjects:#0, #1, #2, #3, #4];
NSInteger firstIndex = arc4random_uniform([array count]);
NSNumber *firstNumber = array[index];
Remove the number you've just found:
[array removeObjectAtIndex:firstIndex];
And than repeat the same for the second number. The first retrieved number won't be in the array anymore so even if the arc4random_uniform() gives you the same value (your 65-70% case) the actual number you are gonna use in your switch case it's gonna be different.
This approach is probably a bit clumsy, but I think it does what you need giving you a bit of control over the randomness.
Im trying to do the calculations using NSNumbers and keep track of the numbers that the user inputs..
The problem is that my app is not doing any calculations now after updated my code to append . the decimal value to value whenever the user press the dot button. Which can be found Append or Add the decimal point functionality in calculator.
I have seen that the proper way to keep track of the inputs from the user and do the calculation is using the NSNumber but as I'm really new to Objective-c I have been struggling understanding the use and implementing it.
So, hopefully someone could walk me through to find the proper solution.
This is the header...
int Method;
float SelectNumber;
float RunningTotal;
bool DecimalActived;
#interface ViewController : UIViewController{
IBOutlet UILabel *Screen;
}
-(IBAction)Number9:(UIButton *)sender;
-(IBAction)Dot:(UIButton *)sender;
#end
This is the the implementation file..
-(IBAction)Number9:(UIButton *)sender{
[self appendDigit:#"9"];
}
- (IBAction)Dot:(UIButton *)sender {
NSString *currentText = Screen.text;
if ([currentText rangeOfString:#"." options:NSBackwardsSearch].length == 0) {
[self appendDigit:#"."];
}
}
- (void)appendDigit:(NSString *)digit {
// handle two special cases: append to only zero means just replace
// but append decimal point to zero is a regular append
if ([self->Screen.text isEqualToString:#"0"] && ![digit isEqual:#"."]) {
self->Screen.text = digit;
} else {
self->Screen.text = [Screen.text stringByAppendingString:digit];
}
}
- (IBAction)Percent:(UIButton *)sender {
[self MySwitch];
Method = 5;
SelectNumber = 0;
DecimalActived = FALSE;
Screen.text = [NSString stringWithFormat:#"%.2g", RunningTotal];
}
- (IBAction)PositiveOrNegative:(UIButton *)sender {
[self MySwitch];
Method = 6;
SelectNumber = 0;
DecimalActived = FALSE;
Screen.text = [NSString stringWithFormat:#"%g", RunningTotal];
}
-(IBAction)Equals:(UIButton *)sender{
[self MySwitch];
Method = 0;
SelectNumber = 0;
DecimalActived = FALSE;
Screen.text = [NSString stringWithFormat:#"%g", RunningTotal];
}
-(IBAction)AllClear:(UIButton *)sender{
Method = 0;
RunningTotal = 0;
SelectNumber = 0;
Screen.text = [NSString stringWithFormat:#"0"];
}
- (double) MySwitch {
NSNumberFormatter SelectNumber = [[NSNumberFormatter alloc] init];
[SelectNumber setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber RunningTotal = [SelectNumber numberFromString:self->Screen.text];
if (RunningTotal == 0) {
RunningTotal = SelectNumber;
} else{
switch (Method) {
case 1:
RunningTotal = RunningTotal * SelectNumber;
break;
case 2:
RunningTotal = RunningTotal / SelectNumber;
break;
case 3:
RunningTotal = RunningTotal - SelectNumber;
break;
case 4:
RunningTotal = RunningTotal + SelectNumber;
break;
case 5:
RunningTotal = RunningTotal / 100;
break;
case 6:
if(RunningTotal > 0){
RunningTotal = - RunningTotal;
} else{
RunningTotal = + RunningTotal;
}
break;
default:
break;
}
}
return RunningTotal;
}
If you guys have any question or need more information regarding my program please feel free to ask and I will provide as much information as possible or answer any questions that you guys may have.. :)
The header should look more like this:
// this uses more conventional (lowercase) property names
// and removes a couple that looked extraneous
#interface ViewController : UIViewController
#property(strong,nonatomic) IBOutlet UILabel *screen;
#property(assign,nonatomic) NSInteger method;
#property(strong,nonatomic) NSNumber *runningTotal;
#end
As the user presses digits, decimal, minus sign, append to the screen label as you have it. When the user presses an operation button, record an integer for the operation and record the current (NSNumber) value of the screen label. To do a computation...
- (void)doComputation {
float screenF = [[self screenValue] floatValue];
float runningF = [self.runningTotal floatValue];
float result;
switch (self.method) {
case 1:
result = runningF * screenF;
break;
case 2:
result = (screenF == 0.0)? 0.0 : runningF / screenF;
break;
case 3:
result = runningF - screenF;
break;
case 4:
result = runningF + screenF;
break;
default:
break;
}
self.screen.text = [NSString stringWithFormat:#"%0.8f", result];
self.runningTotal = [NSNumber numberWithFloat:result];
}
(screen value, as you have it...)
- (NSNumber *)screenValue {
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
return [f numberFromString:self.screen.text];
}
How does this work?
NSNumberFormatter SelectNumber = [[NSNumberFormatter alloc] init];
[SelectNumber setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber RunningTotal = [SelectNumber numberFromString:self->Screen.text];
if (RunningTotal == 0) {
RunningTotal = SelectNumber;
} else{
switch (Method) {
case 1:
RunningTotal = RunningTotal * SelectNumber;
break;
This code shouldn't even work. Either SelectNumber is a float or it's a NSNumberFormatter*
I Am using GPUImage.
I Want to Rotate (With 90, 180, 270, 360 degree) Image With Animation using GPUImageFilter.
Please Help.
Thanks in Advance.
Just Check What i did to do For Rotation
int tag - is defined in .h file
-(IBAction)btnRotate_Clicked:(id)sender
{
[self hideFilterView];
[self hideFontView];
[self hideEnhanceView];
if (tag == 0)
{
staticPictureOriginalOrientation = UIImageOrientationRight;
tag = 1;
}
else if (tag == 1)
{
staticPictureOriginalOrientation = UIImageOrientationDown;
tag = 2;
}
else if (tag == 2)
{
staticPictureOriginalOrientation = UIImageOrientationLeft;
tag = 3;
}
else
{
staticPictureOriginalOrientation = UIImageOrientationUp;
tag = 0;
}
UIImageOrientation orientation = staticPictureOriginalOrientation;
switch(orientation){
case UIImageOrientationUp:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
break;
case UIImageOrientationLeft:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatio];
break;
case UIImageOrientationRight:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatio];
break;
case UIImageOrientationDown:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
break;
default:
break;
}
[self prepareStaticFilter];
}
-(void) prepareStaticFilter
{
isImageProcessed = TRUE;
[staticPicture addTarget:filter];
if (hasBlur)
{
[filter addTarget:blurFilter];
[blurFilter addTarget:self.MimageView];
}
else
{
[filter addTarget:self.MimageView];
}
GPUImageRotationMode imageViewRotationMode = kGPUImageNoRotation;
switch (staticPictureOriginalOrientation)
{
case UIImageOrientationLeft:
imageViewRotationMode = kGPUImageRotateLeft;
break;
case UIImageOrientationRight:
imageViewRotationMode = kGPUImageRotateRight;
break;
case UIImageOrientationDown:
imageViewRotationMode = kGPUImageRotate180;
break;
default:
imageViewRotationMode = kGPUImageNoRotation;
break;
}
[filter setInputRotation:imageViewRotationMode atIndex:0];
[staticPicture processImage];
}
I am new to creating apps for the iOS. Recently, I've been working on making a calculator app based on gestures. I am using switch cases to change operations, and I originally had it rigged up with buttons, but now I want to use gestures. Here is my code so far. The opAddition function is the first way I tried it, but it wouldn't switch functions. For example, if I wanted to switch from addition to subtraction, it would only work after the number was inputed. That's why I tried to use Switch-Case, but now I don't know how to link up gestures to them.
#implementation ABViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
calculatorScreen.adjustsFontSizeToFitWidth = YES;
self.notification.layer.cornerRadius = 90;
self.notification.layer.masksToBounds = YES;
self.notification.alpha = 0;
[[self.notification layer] setBorderWidth:8.0f];
[[self.notification layer] setBorderColor:[UIColor whiteColor].CGColor];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - buttons
-(IBAction)buttonDigitPressed:(id)sender{
currentNumber = currentNumber *10 + (int)[sender tag];
NSString *number = [NSString stringWithFormat:#"%.1f", currentNumber];
if ( number.length < 11) {
calculatorScreen.text = number;
}
};
#pragma mark - operator button code
-(IBAction)buttonOperationPressed:(id)sender{
if (currentOperation == 0) { result = currentOperation; }
else {
if (_operationSimple.direction == UISwipeGestureRecognizerDirectionUp){
currentOperation = 1;
} else if (_operationSimple.direction == UISwipeGestureRecognizerDirectionDown){
currentOperation = 2;
}
switch (currentOperation) {
case 1:
result = result + currentNumber;
self.notificationText.text = #"+";
[self notify];
break;
case 2:
result = result - currentNumber;
self.notificationText.text = #"-";
[self notify];
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
}
}
currentNumber = 0;
calculatorScreen.text = [NSString stringWithFormat:#"%.1f", result];
if ( [sender tag] == 0) { result = 0; }
currentNumber = [sender tag];
};
#pragma mark - Cancelations
-(IBAction)cancelInput{
currentNumber = 0;
self.notificationText.text = #"C";
[self notify];
calculatorScreen.text = #"0.0";
result = 0.0;
NSLog(#"Cancel Input");
}
-(IBAction)cancelOperation{
currentNumber = 0;
self.notificationText.text = #"AC";
[self notify];
calculatorScreen.text = #"0.0";
currentOperation = 0;
NSLog(#"Clear Operation");
}
double newresult = 0;
#pragma mark - Operations
-(IBAction)opAddition{
result = result + currentNumber;
self.notificationText.text = #"+";
[self notify];
newresult = result;
currentNumber = 0;
NSLog(#"Number Added. New result:");
NSLog([NSString stringWithFormat:#"%2f", newresult]);
calculatorScreen.text = [NSString stringWithFormat:#"%.1f", result];
}
#pragma mark - notification stuffs
- (void)notify{
[UIView animateWithDuration:1.0 animations:^{
self.notification.alpha = 1.0f;
}];
[UIView animateWithDuration:1.0 animations:^{
self.notification.alpha = 0.0f;
}];
}
#end