Boolean logic failure - iphone

I am having a strange problem with boolean logic. I must be doing something daft, but I can't figure it out.
In the below code firstMeasure.isInvisibleArea is true and measureBuffer1 is nil.
Even though test1 is evaluating to NO for some reason it is still dropping into my if statement.
It works ok if I use the commented out line.
Any idea why this happens?
BOOL firstVisible = firstMeasure.isInVisibleArea;
BOOL notFirstVisible = !(firstMeasure.isInVisibleArea);
BOOL measureBufferNil = measureBuffer1 == nil;
BOOL test1 = measureBuffer1 == nil && !firstMeasure.isInVisibleArea;
BOOL test2 = measureBufferNil && !firstVisible;
if (measureBuffer1 == nil && !firstMeasure.isInVisibleArea)
//if (measureBufferNil && !firstVisible)
{
//do some action
}
Update 1:
I isolated the problem to !firstMeasure.isInVisibleArea as I've entirely taken on the measureBuffer bit.
Inside isInVisible area is a small calculation (it doesn't modify anything though), but the calculation is using self.view.frame. I am going take this out of the equation as well and see what happens. My hunch is that self.view.frame is changing between the two calls to isInVisibleArea.
Update 2:
This is indeed the problem. I have added the answer in more detail below

When in doubt, you should fully parenthesize. Without looking up the precedence rules, what I think what is happening is that = is getting higher precedence than == or &&. So try:
BOOL test1 = ((measureBuffer1 == nil) && !firstMeasure.isInVisibleArea);

While you certainly can parenthesize, you should also know that nil objects evaluate to boolean NO and non-nil objects evaluate to boolean YES. So you could just as easily write this:
BOOL firstVisible = firstMeasure.isInVisibleArea;
BOOL notFirstVisible = !(firstMeasure.isInVisibleArea);
BOOL measureBufferNil = measureBuffer1;
BOOL test1 = !measureBuffer1 && !firstMeasure.isInVisibleArea;
BOOL test2 = measureBufferNil && !firstVisible;
if (measureBuffer1 && !firstMeasure.isInVisibleArea) {
//do some action
}
You would end up with the same results. I agree with GoatRider, though. It's always far better to parenthesize your conditional expressions to clarify what you really want to happen than it is to rely on the language's operator precedence to do it for you.

If test1 is evaluating to NO as you say, then drop test1 into the if statement:
if(test1){
//see if this executes?
}
See what that does.

My hunch was correct, it is related to the view frame changing between calls to firstMeasure.isInVisible area.
This whole routine is called in response to the view moving. I think I need to grab the value of firstMeasure.isInVisibleArea at the start of the method and use that value throughout.
Phew. Boolean logic isn't broken. All is right with the world.
Thanks for all your input

Related

how to prevent logging warning in a .get(true , false) statement to appear even though it is true and not false

I am making an application which rarely uses the terminal for output. So, I found that the logging library was a great way to help debug faulty code as supposed to the print statement.
But, for this code, specifically the .get() statement at the bottom...
def process_variables(self, argument):
data = pd.read_excel(self.url, sheet_name=self.sheet)
data = pd.concat([data.iloc[2:102], data.iloc[107:157]]).reset_index()
fb = data.loc[0:99, :].reset_index()
nfb = data.loc[100:155, :].reset_index()
return {'fb': data.loc[0:99, :].reset_index(),
'nfb': data.loc[100:155, :].reset_index(),
'bi': data.loc[np.where(data['Unnamed: 24'] != ' ')],
'uni': data.loc[np.where(data['Unnamed: 25'] != ' ')],
'fb_bi': fb.loc[np.where(fb['Unnamed: 24'] != ' ')],
'fb_uni': fb.loc[np.where(fb['Unnamed: 25'] != ' ')],
'nfb_bi': nfb.loc[np.where(nfb['Unnamed: 24'] != ' ')],
'nfb_uni': nfb.loc[np.where(nfb['Unnamed: 25'] != ' ')],
}.get(argument, f"{logging.warning(f'{argument} not found in specified variables')}")
...returns this...
output
The output returns the default argument even though the switch-case argument was successful, given that it did return the pandas Data frame.
So how can I make it so it only appears when it wasn't found, as it should if it were just a string and not a logging-string method.
Thank you for your help in advance :)
Python evaluates the arguments for the arguments to a function before it calls the function. That's why your logging function will get called regardless of the result of get(). Another thing is your f-string is probably going to evaluate to "None" every time since logging.warning() doesn't return anything, which doesn't seem like what you intended. You should just handle this with a regular if statement like
variables = {
'fb': data.loc[0:99, :].reset_index(),
...
}
if argument in variables:
return variables[argument]
else:
logging.warning(f'{argument} not found in specified variables')

empty form text filed

I'm using a FormTextField in a Flutter app
To update a certain column value, the user types in the FormTextField, otherwise leaves the field empty.
I tried this code, but it was adding a null value to the column, deleting the existing value. I'm not happy with this behavior.
String _getProd5Name() {
if ((_prod5Controller.text).isNotEmpty == true) {
_prod5String = _prod5Controller.text;
}
return _prod5String;
}
Is there a way to do it?
I found similar questions, but they are relevant to other languages and their solutions don't solve my case.
String _getProd5Name() {
// Actually you don't have to make it private
// since this is a local variable inside a function
String _prod5String = variableContainingInitialValue;
if (_prod5Controller.text.isNotEmpty) {
_prod5String = _prod5Controller.text;
}
return _prod5String;
}
Here is my advice, since I love wrapping everything on 1 line. You can change the "" part with your result expectation. It's the same with your logic but it's shorter and instead of returning null I make it returning the empty string "". And also (_prod5Controller.text).isNotEmpty == true you can just shorten it to (_prod5Controller.text).isNotEmpty because .isNotEmpty always returning boolean true/false and if-else consuming boolean
String _getProd5Name() {
return ((_prod5Controller.text).isNotEmpty) ? _prod5String = _prod5Controller.text : "";
}

understanding why swift code won't work correctly

I'm new to coding and currently teaching myself swift using swift playgrounds on the iPad. My code runs and completes the puzzle but it continues to loop and I don't know why. I can't find any way to correct this code. Although I have found videos on YouTube with various code written differently. I don't just want to copy it though. I want to understand why this isn't working. I can send a video of the puzzle if needed.
while !isOnGem || !isOnClosedSwitch {
moveForward()
if isBlocked && !isBlockedRight {
turnRight()
}
if isBlocked && isBlockedRight {
turnLeft()
}
if isOnGem {
collectGem()
}
if isOnClosedSwitch {
toggleSwitch()
}
}
Without any other information regarding the functions in each of your if blocks, I'd say that it is due to your boolean values for isOnGem and isOnClosedSwitch. If the function collectGem() does not change the value of isOnGem to the opposite of what it was initially set to (true or false) and toggleSwitch() doesn't change the value of isOnClosedSwitch to the opposite of it's original value then you will be stuck in the loop. Since the loop will run "while" at least one of those values remain unchanged.
I believe adding a isOnGem = false and isOnClosedSwitch = false to their respective if blocks will be the solution.
You are missing the exit condition. while !isOnGem || !isOnClosedSwitchwill continue to loop as long as either condition is true, therefore your exit condition will be having both values set to false.
Note that both Booleans are inverted in your check so to make both conditions false you have to set the Booleans to true.
Since you code runs and yet does not exit to loop, you will want to check for changes to isOnGem and isOnClosedSwitch there might be one of the two that is always false resulting in the loop not exiting or the function that runs after each checks might have reset them to false
check for code like:
func collectGem(){
...
isOnGem = false
...
}
or one of the functions might not even have run, you can log each function like :
func toggleSwitch() {
print("toggleSwitchRunning")
}
and if "toggleSwitchRunning" did not print into the console, check that the condition that set isOnClosedSwitch to true is working properly

UITextField strange behaviour for blank checking

I've a UITextField say txtTitle. I want to check for not blank of that field at the time of inserting data into database.
For that I written
if(![txtTitle.text isEqualToString:#""])
{
//Save
}
But where I am shocked is its not working! I did these type of checking before and its working properly. But not with this case. So that I checking it using following,
if(txtTitle.text!=NULL)
{
//Save
}
It's working properly.
Now here I am confusing about this. I used to print NSLog(#"%#",txtTitle.text) without inputting anything into it. Its printed (null).
Someone please justify the difference between two IF conditions.
Thanks
Maybe you can check for the length property of the string instead, using
if([txtTitle.text length] > 0){
// Save
}
I think the difference is between a completely uninitialized string and a string that has been initialized, but is simply empty.
Hope this helps
#Hemang
As you have mentioned that NSLog gives you (null)..you have to compare like
[txtTitle.text isEqualToString:#"(null)"]
other wise use
if([txtTitle.text length] > 0)
{
}

Having a problem with simple bool

I've some really simple code that checks if my bool is == YES but it does not ever enter.
NSLog(#"boool %d",self.arrayAlreadyPopulated );
if (self.arrayAlreadyPopulated == YES)
{
Match *aMatch = [appDelegate.matchScoresArray objectAtIndex:(numMatchCounter)];
aMatch.teamName1 = TeamNameHolder;
}
else
{
Match *aMatch = [[Match alloc] init];
aMatch.teamName1 = TeamNameHolder;
[appDelegate.matchScoresArray addObject:aMatch];
[aMatch release];
}
The debug at the top says that the value of self.arrayAlreadyPopulated is 1 on the 2nd pass as it should be.
But it never enters the first first part but jumps down to the 'else'
I cant see for the life of me what the problem is. -.-
Anybody able to clue me in?
Thanks
-Code
EDIT declaration code
BOOL arrayAlreadyPopulated;
#property (nonatomic) BOOL arrayAlreadyPopulated;
#synthesize arrayAlreadyPopulated;
Don't compare a BOOL against YES or NO. They can carry values that are not NO but don't compare equal to YES. Instead, use the boolean expression directly in the if statement:
if (self.arrayAlreadyPopulated)
{
// ...
}
arrayAlreadyPopulated is probably not actually a BOOL. If, for example, it was a float, the %d would still print 1.
Check and double check that you're assigning the value to arrayAlreadyPopulated always as self.arrayAlreadyPopulated = YES instead of just arrayAlreadyPopulated = YES.
Sometimes, using the property v/s the associated variable of the property interchangeably doesn't always work out the way you'd expect it to. Use the "variable" name only if you're using it to release memory by [variable release] statement, just the way you'll find it in any Apple example code. In all other cases use self.propertyname.