How to Simulate While Loops in Scratch? - mit-scratch

In most programming languages, there is a "while" loop that runs code while a condition is true. However, in Scratch, there is only a "repeat until" loop that repeats until a condition is true. How do I simulate a "while" loop in Scratch?

Say you wanted to use a "while" loop to run while "ConditionA" is true.
WHILE ConditionA
Say "hello"
In Scratch, you can use a "repeat until" loop in this way:
REPEAT UNTIL NOT ConditionA
Say "hello"

This is easy. Just loop an "if" operator.
forever
if <...>
code goes here
else
end
end

Related

How do I exit this function?

Essentially its built like so:
.If
..other stuff
.Else
..For
...For
....If (this is where I need to be able to break out of the whole thing)
I've tried using return, and break, but they just are not working for whatever reason. I added in a ticker and it appears that the break command isn't working?
The code just continues going on and repeating the for loop even AFTER it is 'broken' in the If statement.
My function is only about 150 lines long, so I've been able to study it closely, and this seems to be where the problem is.
If you have
for (...)
for (...)
if (true)
break;
end
end
you'll only break out of the inner loop. But, of course, the outer loop will continue as normal!
Breaking out of nested-loops is one of the very few reasonable use cases for a goto. However, MATLAB does not have a goto, so you'll have to repeat yourself in some way or another:
for (...)
for (...)
if (condition)
break;
end
if (condition)
break;
end
An equally ugly yet common and less verbose way:
try
for (...)
for (...)
if (condition)
error(' ');
end
end
catch %#ok
(code you want to be executed after the nested loop)
end
or, to be pedantic,
breakout_ID = 'fcn:breakout_condition';
try
for (...)
for (...)
if (condition)
error(breakout_ID, ' ');
end
end
catch ME
% graceful breakout
if strcmp(ME.Identifier, breakout_ID)
(code you want to be executed after the nested loop)
% something else went wrong; throw that error
else
rethrow(ME);
end
end
Or you build a (nested) function containing just that nested loop, and use return to break out. But that may not always give the most "obvious" code structure, as well as cause you to have to write lots of boilerplate code (subfunction) and/or have unforeseen side effects (nested functions), so...
Personally, I favor the try/catch above.

What is the command and syntax for breaking/stopping a program in QBASIC?

I am currently writing a QBASIC program that runs an indefinite loop (while loop). However, if a certain condition is met, I want to exit the program. What command do I use, and also what is the syntax.
Thanks
ENDexits program, and clears all variables, which frees up memory.
STOPexits program, but retains the value of all variables, which makes it possible (in certain versions of QB) to continue execution at another point, by choosing Set next statement from the Debugmenu, and then Startfrom the Runmenu. END has the same effect as STOP + choosing Restart from the Runmenu once the program has terminated.
If you have a loop, and want to exit the program from inside it, you may use either
DO
IF condition THEN EXIT DO
LOOP
END
or
DO
IF condition THEN END
LOOP
You're looking for the END or SYSTEM statement. For example:
PRINT "Hello World!"
END
PRINT "This won't be printed."
If you're using regular old QBASIC/QuickBASIC, then you can ignore all of the QB64 details on the linked pages and just use either SYSTEM or END. Both will do the same thing for the most part.1
If you're using FreeBASIC, it's recommended to use END instead of SYSTEM since some things won't get cleaned up properly when you use SYSTEM. See SYSTEM for more information pertaining to FreeBASIC if that's what you're using.
1 The END statement when running the program using QB.EXE /RUN PROGRAM.BAS will print "Press any key to continue" before exiting to the QB/QBASIC environment. The SYSTEM statement when run the same way will simply return you to the DOS shell without any need for a key press. Also, typing SYSTEM in the "Immediate Window" of the QB/QBASIC environment will exit the environment and return to the DOS shell. Otherwise the two statements behave exactly the same in QB/QBASIC, whether for standalone (compiled) programs or .BAS modules.
You can keep any condition according to the need of your program. For eg:
CLS
LET a = 5
WHILE a > 0
PRINT a;
a = a - 1
WEND
END
Here, in the program while wends executes itself until a = 0. This will not run an infinite loop.
The answer is
exit();
to exit the program.

New control transfer statements (labels) for Swift 2.0

What would be the best practices for the new control transfer statements (labels) in Swift 2?
Since I hear about it I can't stop compare it with the goto command from the good and old Basic language, what never was well accepted from experient programmers at the time.
Some uses of the control flow transfer looks ok, like in example below:
outer: for i in 1...100{
for j in 1...100{
print("\(i), \(j)")
if j == 10 {
break outer
}
}
}
But what are the limitations for the control flow transfer use?
When start to be bad practice to use it?
If its use was such a bad practice why it is back?
You can prefix a loop statement, an if statement, or a switch statement with a statement label followed by a colon (:) ,break and continue statements are used to change control flow in a loop statement or a switch statement.
break statement breaks the current loop execution where as continue just breaks current iteration.
consider:
firstLoop :for j in 0...1{
secondLoop: for i in 0...10{
if (i % 2) == 0{
if (i == 4){
break firstLoop
}
print(i)
}
}
}
Output will be : 0,2
If we replace break firstloop by break secondLoop o/p Will be: 0,2,0,2
If we replace break firstloop by continue o/p Will be: 0,2,6,8,10,0,2,6,8,10
If we replace break firstloop by continue firstloop continue o/p Will be again : 0,2,0,2
If continue is followed by a statement label then it will stop the current iteration of that statement label not the loop pointed by statement label.
goto VS statement label
. goto is a kind of unconditional branching ,where you can branch anywhere in the program,The goto statement is discouraged , because it alters the sequential flow of logic .
Why statement Label is used and what is it's Limitation?
. where as continue and break can make use of statement label if and only if it is written inside the loop which has same statement label which it is using so the code will be more safer. It makes programers life easy , off course you can't directly branch out to any part of program using continue,break and statement Label it can be considered as a limitation.
I think you are asking about using labels for break and continue statements. That is a much more limited, safer use than the horrible goto statements from basic. It simply lets you tell the compiler the scope you need to break out of/continue when you have nested looping constructs.
As far as I know break and continue is the only use of labels in Swift, and for that it seems useful and appropriate.

How to exit a loop depending on how long I keep a key pressed?

How can I end this loop depending on how long I keep X pressed? If I hold X for five seconds it should send B, S, C, Y, and U at one second intervals.
When I hold X for one second it should only send B, if I hold X for two seconds it should send B and S, etc. Currently it simply sends B, S, C, Y, and U.
*$x::
While(GetKeyState("x", "P"))
{
send b
Sleep 1000
send s
Sleep 1000
send c
Sleep 1000
send y
Sleep 1000
send u
Sleep 1000
}
Return
Solution does not have to be a loop.
x::
index:="i"
letters:="l"
output:="o"
l:="bscyu"
i:=(i<o0?++i:1)
StringSplit,o,l
send % o%i%
sleep,1000
return
x Up::i:=0
I can see a few possible approaches.
1) The first and perhaps worst is to have an if... to test the keystate, and an exit, after every single send. This is extremely repetitive, but not too terrible if you stick it in a function, and just call that, something like:
*$x::
while (GetKeyState("x", "P")) {
sendStuff('b')
sendStuff('s')
sendStuff('c')
...
}
sendStuff(str) {
Send str
if (!GetKeyState("x", "P")) {
exit
}
sleep 1000
}
2) The next is to continue operating as you are, with a chained series of commands, and have an external, separate script kill that series of commands while running, then re-Run() your script when you wish to restart. Killing external scripts is covered in the FAQ, here: http://www.autohotkey.com/docs/FAQ.htm#close
There are three relevant sections there which are a little long to paste here, but in summary, you may be interested in the following commands:
; Allow script's hidden main window to be detected.
DetectHiddenWindows On
; Avoid need to specify full path of file.
SetTitleMatchMode 2
; Kill another script: Update params to the script's case sensitive name.
WinClose Script Filemame.ahk - AutoHotkey
; Suspend other script.
PostMessage, 0x111, 65305,,, Script Filename.ahk - AutoHotkey
; Pause other script.
PostMessage, 0x111, 65306,,, Script Filename.ahk - AutoHotkey
; Pause/resume current script on Ctrl+Alt+P
^!p::Pause
3) There's also a longer code sample just below that, which describes canceling a loop, and it's my belief that this is the correct approach to this problem, as while it might be fiddlier initially, it is considerably more scalable, reduces code duplication, and permits you to handle multiple loop entry/exit conditions in a single place.
It is, in short, the best in terms of Programming Style.
Place the entries (b, s, c, y, u) that you wish to sent into a string, array or other iterable datastructure, and iterate over it, so that your while loop sends only a single item and a pause each iteration. Then the next time you hit your hotkey, you can either resume the loop from where you left off, or start over, depending on whether you maintain a pointer to your current position in the structure.
For example, using the above sendStuff function, a loop will give you the very powerful and trivially extensible:
*$x::
{
letters = b,s,c,y,u
Loop, parse, letters, `,
sendStuff(%A_LoopField%)
return
}
This post is so old, but I just can't help it.
sendChars := "bscyu"
$x::
i := 1 ; (!i ? 1 : i) ; permits starting where left off.
While (getKeyState("x", "P")) {
Send % subStr(sendChars, i, 1)
i := ((i==strLen(sendChars)) ? 1 : (i+1))
if (getKeyState("x", "P")) { ; why wait if you don't have to.
Sleep 1000
}
}
The docs point out that a While loop is only evaluated at the beginning of each iteration, so listing all the keys in a loop will just send all the keys, then break out of loop once at that top again and sees that "x" is no longer being pressed.

BREAK statement in PL/pgSQL

How to have the break statement in PostgreSQL? I have the structure like this:
for()
{
for()
{
if(somecondition)
break;
}
}
As per my understanding it should only break the inner for loop?
There is no BREAK in PL/pgSQL.
EXIT terminates the loop.
CONTINUE continues at the next iteration of the loop.
You can attach a <<label>> to loops and add it as parameter to each of these commands. Then you terminate / continue the labeled loop. Else, it concerns the inner loop.
RETURN exits from the function (so not applicable in a DO statement).
All of this applies to procedural elements of PL/pgSQL, not SQL.
Code example using all three:
Loop in function does not work as expected
Note, that: Yes! you need the "WHEN", even if you end up (like me ;-)) with something like
LOOP
...
IF l_my_var = 'some condition' THEN
-- this is ok, bla
IF l_debug_level >= 2 THEN
RAISE NOTICE 'debug 2: skipping a duplicate %, l_my_var;
END IF;
-- do something
CONTINUE WHEN TRUE; -- https://stackoverflow.com/questions/15173194/break-statement-in-pl-pgsql
ELSE
-- do something
END IF;
...
which looks somewhat twisted with both IF and WHEN.
Remark to the editor:
One could make the link behind "CONTINUE" more precise: https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html#AEN66440