understanding why swift code won't work correctly - swift

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

Related

How to use Optional in Netlogo Extensions

I want to create a netlogo primitive that may receive a boolean or may not. Therefore I want make possible to the user that he uses the primitive of these two ways:
1:
ask Walkers [
qlearningextension:learning
]
2:
ask Walkers [
qlearningextension:learning true
]
I tried to do that with OptionalType, but I could not make it. Is it possible to do what I want? If so, how can I do it?
So OptionalType unfortunately only works with CommandBlockType. For a good example of how that works, check out the sample-scala extension (maybe that's where you saw a reference to it in the first pace). OptionalType will not work with BooleanType.
There is a secondary option, that's a little hacky. You can use RepeatableType along with setting defaultOption and minimumOption in your syntax (so NetLogo knows that 0 arguments is okay/expected). Scala code example:
object RepeatableTypeTest extends api.Command {
override def getSyntax =
commandSyntax(
right = List(BooleanType | RepeatableType),
defaultOption = Some(0),
minimumOption = Some(0)
)
def perform(args: Array[api.Argument], context: api.Context) {
println(args.length)
if (args.length > 0) {
val ref = args(0).getBoolean
println(ref)
} else {
println("No argument given!")
}
}
}
Then you just have to wrap calls with the boolean argument in parenthesis, so NetLogo knows you're not starting a new command (it expects the defaultOption without the parens):
to test
sample-scala:rep-bool
(sample-scala:rep-bool true)
(sample-scala:rep-bool false)
(sample-scala:rep-bool false true false true false)
end
The problem with this, as you can see in the example, is if your users want to they can provide extra useless booleans: (sample-scala:rep-bool false true false false true false false). If your code ignores them they won't have an effect, but they could be confusing or weird to extension users.

Why breakpoint breaks at else block in 'if else' condition

I am trying to figure out, why, if I put breakpoints on if and on else line, why my if else {} condition breaks on else if the condition was true in if block?
I am using realm but I do not think, that is an issue.
//Check if Object already exists in database
if !RealmService.shared.ifPortfolioExists(name: portfolio.name){//Breakpoint on this line which is true
//Create portfolio
RealmService.shared.create(portfolio)
//Assign portfolio to transaction
transaction.portfolio = portfolio
//Create transaction
RealmService.shared.create(transaction)
}else{//Breakpoint on this line
//Assign portfolio to transaction
transaction.portfolio = portfolio
//Create transaction
RealmService.shared.create(transaction)
}
Am I working out of my mind or am I just stupid? Can please someone explain me this.
The compiler reads them to see if it should proceed into the following block of code. A breakpoint inside of the if will trigger when true and else when false
Do this to better understand where your breakpoints take effect:
if x != y {
print("if breakpoint")//set breakpoint here
} else {
print("else breakpoint")//set breakpoint here
// you should see that the breakpoint doesn't fire here
}

What is the most efficient to run certain lines of code only when a boolean is true?

If I had code that looked like the following:
if (bool1) {
statement1
statement2
} else if (bool2) {
statement3
statement4
}
and I only want to run statement 2 and 4 given another boolean (say bool3) is true, what is the best way to format that. I understand that I could add a nested if statement, but that seems bad from a maintainability perspective if I have 5 or more else ifs.
Any suggestions?
A nested if sounds perfectly fine to me at least. If none of the statements mess with bool1, bool3 and bool4 though and you really don't want to use nested ifs you could put them after eachother with conjunctions:
if (bool1) {
statement1
}
if (bool1 && bool3) {
statement2
}
if (bool2 && !bool1) {
statement3
}
if (bool2 && !bool1 && bool3) {
statement4
}
This looks terrible though so I'd just go with a plain and simple nested if.

AutoHotKey infinite while loop

Is there a way to create something like this in AutoHotKey?
bool isReady = false;
while (!isReady) {
// Do something here
isReady = true;
}
I tried to experiment with While loop, but it ended with just 1 loop regardless of the condition I give the program. I am currently using Version 1.0.47.06.
I read the documentation here: http://www.autohotkey.com/docs/commands/While.htm I tried to give the while loop a value of true. But it only executed once. (I was expecting it to loop forever, until I terminate the script).
condition := true
while (condition)
{
MsgBox, condition
}
while (true)
{
MsgBox, true
}
Your code is correct, but the While command requires version 1.0.48+.
You should update to the latest version of AHK here - http://ahkscript.org/download/
To create a infinite loop , you can use this syntax:
Loop
{
; Your other code goes here
}

Boolean logic failure

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