else condition is not executing? - ios

in this following else if ,the last else condtion is not executing ?
Please help me
if (Flag==1)
{
...
}
else if ([totalBooksId containsObject:currentbook])
{
...
}
else if (![totalBooksId containsObject:currentbook])
{
...
} else {
...
}
All variable have some values but still else is not executing.
the above else statement is not executing at all? Please help me

This is will work
if(Flag==1){
if([OwnList containsObject:currentbook]){
if(fileExists) {
[self renameReadButton];
}else if(!fileExists){
[self renameDownloadButton];
}
[self renameLendButton];
}
}
else if([totalBooksId containsObject:currentbook]){
//Checking bought books
if([OwnList containsObject:currentbook]){
if(fileExists){
[self renameReadButton];
}else {
[self renameDownloadButton];
}
} else{
[self renameBuyButton];
}
}
else if(![totalBooksId containsObject:currentbook]) {
if([freeList containsObject:currentbook]){
if(fileExists){
[self renameReadButton];
}else{
[self renameDownloadButton];
}
} else{
[self renameBuyButton];
}
}

If the last else on an else-if block is not hit it usually means either of these:
One of the conditions in the initial if clause or the following else-if clauses was true
One of the evaluated conditions altered the program path (exception, stack corruption, etc.)
The code of the entire if-else block was never reached
In your case it seems to be the first case, because one of the else if conditions is the inverse of another.
Either ([totalBooksId containsObject:currentbook]) is true, or !([totalBooksId containsObject:currentbook]) is true. To hit the final else, both of them must be false.

You have three statement
else if([totalBooksId containsObject:currentbook]) // first
{
}
else if(![totalBooksId containsObject:currentbook]) // second
{
}
else { [self renameBuyButton]; } // last
Last statement is not executed because first and second catch all possible situations.
First catch [totalBooksId containsObject:currentbook] == true , second cath [totalBooksId containsObject:currentbook] == false and there is no third possibility.

Related

Expected expression before else statement

I get an error saying Expected expression before my else-statement but I do not know why. I searched through other posts but I cant find a solution.
- (void)setDeviationSize:(double)newDeviation
{
if (newDeviation != 0) {
deviationLayer.lineWidth = 2.0 / newDeviation;
if (newDeviation * pixelPerMeter * scrollView.zoomScale < 2 * cPointRadius) {
deviationLayer.hidden = YES;
} else {
deviationLayer.hidden = NO;
deviationLayer.transform = CATransform3DMakeScale(newDeviation, newDeviation, 0);
}
} else {
deviationLayer.hidden = YES;
} else <---- EXPECTED EXPRESSION {
for(LectureModel* lecture in lectures) {
NSString *title;
if([lecture.title length] > 30) {
title = [NSString stringWithFormat:#"%#...", [lecture.title substringToIndex:30]];
} else {
title = lecture.title;
}
[alert addActionWithTitle:title handler:^(UIAlertAction * _Nonnull action) {
LectureModel* full = [LectureModel findById:lecture.id];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self showModelInPopover:full];
} else {
[[TransitionManager shared] openModelInCatalog:full];
}
}
[self presentViewController:alert animated:YES completion:nil];
}
}
}
What am I missing?
Like vadian and luk2302 pointed out you have an if statement with two else attached to it, so the compiler doesn't understand what the second else is related to and throwing the error.
Maybe you wanted something like
if (newDeviation != 0) {
/* do something */
} else if (someCondition) {
/* do something different */
} else {
/* do something else */
}
If this is not the logic you want, please explain what you want to achieve, so we can help you better.
#user12372692
In order to achieve what you want, there are two ways to solve this -
A. if else condition making.
B. using switch case.
Way A :-
if else condition is written like following :-
if (condition 1) {
/* do something for condition 1 is true */
} else if (condition 2) {
/* do something for condition 2 is true */
} else {
/* do something for both condition 1 and 2 are false. */
}
so as per this your condition should be :-
if (newDeviation != 0) {
/* do something */
} else if (OtherCondition) {
/* do something*/
} else {
/* do something for both above two conditions are false */
}
Way B :-
switch(newDeviation){
case (newDeviation != 0 ) : {/* Do your work */}; break;
case (condition 2) : {/* Do your work */}; break;
case (condition 3) : {/* Do your work */}; break;
}

How repeat part of function Swift

still learning the basics. I have a function in which there is a block, that needs to be repeated without calling the whole function again. How is this done in Swift?
func connected(to peripheral: Peripheral) {
let cwConnection = CWStatusBarNotification()
cwConnection.display(withMessage: "Ring Connected", forDuration: 3)
BluejayManager.shared.getHeliosInfo { (success) in
if success {
// Go on
} else {
// Repeat this block (BluejayManager.shared.getHeliosInfo)
}
}
}
Hey Riyan it's just simple. Here is the solution to your problem. Just put the block in other small method and when you just need to call that block call that small function.
func connected(to peripheral: Peripheral) {
let cwConnection = CWStatusBarNotification()
cwConnection.display(withMessage: "Ring Connected", forDuration: 3)
self.callBluejayManagerShared() // Call of block from method
}
func callBluejayManagerShared(){
BluejayManager.shared.getHeliosInfo { (success) in
if success {
// Go on
} else {
// Repeat this block (BluejayManager.shared.getHeliosInfo)
self.callBluejayManagerShared()
}
}
}
Now when you just want to call block you just need to call self.callBluejayManagerShared() method.
Hope this help you
You can use repeat - while around and BluejayManager.shared.getHeliosInfo check for success as break condition:
repeatGetInfo: repeat {
BluejayManager.shared.getHeliosInfo
{ (success) in
if success
{
// do your stuff.
break repeatGetInfo
} else
{
continue repeatGetInfo
}
}
} while true
Hope this helps

What is correct implementation of IDA* algorithm with manhattan heuristic?

I am trying to implement IDA* algorithm to solve 15 puzzle problem in objective C, I have implemented the algorithm very well but not getting the exact result. Here is my code-
- (TreeNode *)IDAStarSolution:(TreeNode *)startState {
int limit = 5;//2*[startState fx];
appDelegate.CN=[NSNumber numberWithInt:limit];
TreeNode *result=nil;
while (result==nil) {
[appDelegate.closedList addObject:startState];
newLimit = 99999;
result = [self depthLimitSearch:startState costLimit:limit];
limit = newLimit;
appDelegate.CN=[NSNumber numberWithInt:newLimit];
[appDelegate.closedList removeAllObjects];
}
return result;
}
- (TreeNode*)depthLimitSearch:(TreeNode *)current costLimit:(int)currentCostBound {
NSArray *neighbors =[current expandNodeToChilds];
for (TreeNode *s in neighbors) {
if ([s.puzzleBox isFinalStateBox]) {
appDelegate.result=s.moveString;
return s;
}
if (![self closedSetContains:s]) {
int currentCost = [s.cost intValue] + [s.puzzleBox.manhattanDistance intValue];
if (currentCost <= currentCostBound) {
[appDelegate.closedList addObject:s];
[s.puzzleBox displayPuzzleBox];
TreeNode *solution = [self depthLimitSearch:s costLimit:currentCostBound];
if (solution!=nil&& (bestSolution ==nil|| [solution.cost intValue] < [bestSolution.cost intValue])) {
bestSolution = solution;
//return solution;
}
}else {
if (currentCost < newLimit) {
NSLog(#"new limit %d", currentCost);
newLimit = currentCost;
}
}
}
}
return bestSolution;
}
-(BOOL)closedSetContains:(TreeNode *)node{
for (TreeNode *tNode in appDelegate.closedList) {
if (tNode==node) {
return YES;
}
}
return NO;
}
The depthLimitedSearch always returning null, and then expand the same node again and again.
So what i have done wrong please suggest.
Implementation is similar to java code given at :
Iterative Deepening A Star (IDA*) to solve n-puzzle (sliding puzzle) in Java
As i am returning bestSolution now, if i set the limit more than optimum cost then it returns the first solution it found, which is not optimum. What to do now?
I think your mutation/enumeration problem is caused by the structure of your closedSetContains method. You are enumerating appDelegate.closedList but return from the middle of the enumeration. I suspect that when you then modify appDelegate.closedList it causes the error, because it looks like the enumeration is still active. You should be able to confirm this by checking the array reference from the exception with the array appDelegate.closedList in the debugger.
Changing your closedSetContains to this -
-(BOOL)closedSetContains:(TreeNode *)node{
BOOL ret=NO;
for (TreeNode *tNode in appDelegate.closedList) {
if (tNode==node) {
ret=YES;
break;
}
}
return ret;
}
may help. But if appDelegate.closedList is an NSMutableArray you can replace the whole method with [appDelegate.closedList containsObject:node]

Not all control paths return a value

if(newNode->getData()->name<currNode->getData()->name)
{
if(currNode->getLeftChild()==NULL)
{
return currNode;
}
compare(newNode,currNode->getLeftChild());
}
else if(newNode->getData()->name>=currNode->getData()->name)
{
if(currNode->getRightChild()==NULL)
{
return currNode;
}
compare(newNode,currNode->getRightChild());
}
else
{
currNode==NULL;
return currNode;
}
Does the last else not cover any other paths that could be taken?
Why am i still getting an error saying not all control paths return a value?
What am I missing? and any hints on a better solution would be nice!
Thank you for your time.
Use below code
if(newNode->getData()->name<currNode->getData()->name)
{
if(currNode->getLeftChild()==NULL)
{
return currNode;
}
compare(newNode,currNode->getLeftChild());
return currNode;
}
else if(newNode->getData()->name>=currNode->getData()->name)
{
if(currNode->getRightChild()==NULL)
{
return currNode;
}
compare(newNode,currNode->getRightChild());
return currNode;
}
else
{
currNode==NULL;
return currNode;
}
You are not returning any value in first and second else part
if u dont want to return anything just use return "";

If statement not calling all methods returning BOOL

I have code like this:
-(IBAction)send {
if ([self isCorrect1] && [self isCorrect2] && ...) {
[self sendRequest];
}
}
-(BOOL)isCorrect1 {
...
}
-(BOOL)isCorrect2 {
...
}
Every isCorrect method is checking some condition showing some message in the view and returning result of the checking. I noticed that if first condition is false it will only show error message for the first method (and I need all of them to be checked) and no breakpoint is triggered inside these methods. I thought it was some kind of LLVM optimization so I created code like this:
-(IBAction)send {
BOOL correct = [self isCorrect1];
correct = correct && [self isCorrect2];
...
if (correct) {
[self sendRequest];
}
}
And is still not working correctly. Do I have to create new BOOL variable to store result for the check or is there some other way?
Since the first condition is evaluated to false, it won't check for the rest of the conditions and will go to the else part straightaway.
Try this.
BOOL finalResult = [self isCorrect1];
finalResult = [self isCorrect2] && finalResult;
finalResult = [self isCorrect3] && finalResult;
finalResult = [self isCorrect4] && finalResult;
...
if (finalResult) {
}
This will go through all of the isCorrect tests and will let you know if it passed all of them in the end or not.
The behaviour you see is the expected behaviour of the &&, namely, it "short-circuits" the evaluation, if it can determine the result in advance, before having evaluated all conditions:
expression-yielding-false && something-else
The result of the above is completely determined by the first part; regardless of what the second operand yields, the final result is false. This allows you to write something like:
if (obj != null && obj->count == 3)
{
...
}
If the && did not have the short-circuit behaviour, you'd have to write
if (obj != null)
{
if (obj->count == 3)
{
...
}
}
The || has a similar behaviour. In case of
something-yielding-true || anything
the right-hand side cannot affect the result value, as the left-hand side already returned true.
One possible work-around would be:
int succeeses = 0;
succeesses += [self isCorrect1]? 1 : 0;
succeesses += [self isCorrect2]? 1 : 0;
succeesses += [self isCorrect3]? 1 : 0;
if (successes == 3)
{
// All tests did succeed
}
else
{
// At least one failed.
}
If you need to know, which tests passed, and which failed, you can try:
BOOL passed1 = [self isCorrect1];
BOOL passed2 = [self isCorrect2];
BOOL passed3 = [self isCorrect3];
if (passed1 && passed2 && passed3)
{
// All tests did succeed
}
else
{
// At least one failed.
}
A more dense version of the above would be
int passed = 0;
passed |= [self isCorrect1]? (1 << 0) : 0;
passed |= [self isCorrect2]? (1 << 1) : 0;
passed |= [self isCorrect3]? (1 << 2) : 0;
if (passed == 7)
{
// All tests did succeed
}
else
{
if (passed & (1 << 0))
{
// First test passed
}
else
{
// First test failed
}
if (passed & (1 << 1))
{
// Second test passed
}
else
{
// Second test failed
}
if (passed & (1 << 2))
{
// Third test passed
}
else
{
// Third test failed
}
}
which is simply a more occult formulation of the version with a boolean variable per test tried.

Resources