How to add a break in a trial loop in PsychoPy - loops

I'm learning how to work with PsychoPy. My problem is that I cannot add a break in a trial loop within another loop.
Situation:
There are two stimuli lists: ListA.xlsx and ListB.xlsx. Both lists contain 20 sentences. A third list ('AB.xlsx') refers to block A ('ListA.xlsx') and block B ('ListB.xlsx').
When I start the experiment, PsychoPy runs through the twenty sentences of ListA.xlsx in a loop. After block A, the experiment stops for a break. The participant can continue the experiment by pressing the spacebar. When the experiment resumes, PsychoPy runs through the twenty sentences of ListB.xlsx in a loop.
For the block break, I'm using the following code:
if blocks.thisTrialN not in [1] :
continueRoutine=False
Problem:
What I want to add is a break within block A and within block B, i.e. I want to add a break after 10 sentences. I've already tried many different things, but I don't get it to work.
I'd appreciate any advice!

In your "break" routine, insert a code component and put something like this in its "begin routine" tab:
if currentLoop.thisN != 9: # NB counting is 0-based
continueRoutine = False
Builder maintains a variable named currentLoop to refer to whatever loop is currently running, so this code and routine can be re-used in any loop in your experiment, without needing to refer to the name of the specific loop that is enclosing it.

Related

replace page of array with another using paste() R

I have a 3d array with lots of pages (or whatever you call 3rd dimension). I am trying to stick that array into a loop, and loop through the pages to fill in values.
In my real dataset, I'm manipulating values with a handful of custom functions, so the way it works best to minimize the amount of retyping I would need to do when changing variables is to create a new array inside the loop, make changes to that new array, then replace the new page in its spot in the original array. However, I'm having a hard time plugging the new page back into the original array. Example follows.
code="A" # I'll be running this loop with various name codes
assign(paste0("testarray",code),array(dim=c(5,5,20)))
# creates array "testarrayA" . I'm using assign(paste()) because I will
# do this with many different array codes, and I want to only change
# the code value each time for ease
set.seed(5)
testarrayA[,,1] <- runif(25,3,20) #fill first page
Then I want to run this array through a loop to change the values on each page. In the real code, the changes are made with somewhat complex custom functions, so again, for ease, I start by making a smaller array, changing that, then trying to plug back into the array from above. See following.
# this loop doesn't work at the moment, so just run lines
# inside the loop individually to attempt. set "page" object as 1
for(page in 1:dim(get(paste0("testarray",code)))[3] ){
# for pages 1-end of third dimension (20)
temparray <- get(paste0("testarray",code))[,,page:(page+1)]
# create smaller array of only current and (blank) next page of original array
temparray[,,2] <- temparray[,,1]*2
# do functions to change the values on the next page of temporary array.
# (just multiplying values by 2 for this example)
# try to plug in temporary array[2] as original array[page+1].
# both of these codes give me errors at the moment, but these are
# the options I have tried so far.
# trial 1:
get(paste0("testarray",code))[,,page+1] <- temparray[,,2]
# trial 2:
assign(paste0("testarray",code)[,,page+1],temparray[,,2])
}
I believe the problem comes from not being able to use paste() in the receiving end of an assign command. The first trial listed above returns error "target of assignment expands to non-language object," which I'm not quite sure how to interpret, and the second, "incorrect number of dimensions," which shouldn't be the case. When I highlight and run each object individually, they have the same dimensions, so I don't know what I'm doing wrong.
Basically, I need to know how to use paste() on the receiving end of an assign function such as <- or assign(), or if there's a reasonable workaround for the errors I'm getting. I know I could just omit the creation of the smaller temporary array, but in my actual code, that would make a lot more work by requiring me to change names a bunch of times in each command inside the loop when I run on a new dataset. I'd rather just change the "code" if possible. Thanks!

GNU Smalltalk - Break from whileTrue loop without return

What is a simple and concise way to break from a whileTrue loop in GNU Smalltalk that doesn't require returning?
Here is my code. I want to break from the loop at Line 31 at the end if char_stack is empty.
https://gist.github.com/SYZYGY-DEV333/ea3f5eeb3473927c8faa294bb72a8858
Any help would be much appreciated.
One of the articles of the Byte magazine (1982) titled Building Control Structures in the Smalltalk-80 System by Peter Deutsch , shows how easy is to implement while-loop breaks for infrequent events that might happen inside the loop.
To implement this we only need a new class and an extension to BlockClosure, making a total of 9 lines of code(!).
The class: BlockWithExit, subclass of Object with two ivars exit and block and the following methods
on: aBlock
block := aBlock
value
exit := [^nil].
^block value
exit
exit value
Extension
BlockClosure>>withExit
^BlockWithExit new on: self
and that's it!
Example
Find the max of a collection until its exhaustion or until nil is found (the infrequent event)
maxBeforeNil: aCollection
| max supplier loop |
max := 0.
supplier := aCollection readStream.
loop := [
[supplier atEnd]
whileFalse: [
value := supplier next.
value isNil ifTrue: [loop exit].
max := max max: value]] withExit.
loop value.
^max
Why does this work the way it does? Because a block with a non-local return exits from the method that defines the block.
In this case this method is BlockWithExit>>value, therefore when [^nil] is evaluated from loop exit, the flow exits value and goes to its sender, right after loop value.
The outstanding corollary of Deutsch's discovery is that the whole mechanism of Exceptions can be built using this very same trick of defining an exit block in an ivar like: exit := [^nil].
In general, Smalltalk does not have a way of breaking from a loop, except for returning from the enclosing method.
Try to extract your loop into another method from which you can return to break from the loop.
In a way, Smalltalk the language does not even have loops... but some methods happen to evaluate blocks more than once. Hence it does not have a special way to terminate "loops". Return is the way.
If you have not already done so, familiarize yourself with the different iteration methods of Collection: do:, select:, collect:, detect:ifNone:, ... The latter is another way to run an "incomplete" loop over a collection, but it does not solve all cases in which you might wish for a "break".

Breakable loop in Scratch?

How do you make a breakable loop in Scratch? I'm using Scratch 2.0 and can't find any good way to make a loop breakable, from inside of the loop itself.
Disclaimer:
There is no perfect way to do it. If you can possibly stand this true fact then feel free to continue.
There are a few different ways you could do it.
With repeat until
The first and most simple one follows this:
But this isn't technically part of the script - it's just repeating until some value returns true.
With a custom block (stop this script)
In order to do it inside of the script, you'll need to use a sneaky little trick with custom blocks.
Create a custom block called whatever you want - but probably along the lines of "breakable loop". Inside of it, create this script:
By using stop script we are breaking out of the script that is currently running - which, according to Scratch, is the custom block.
See the result! (as scratchblocks)
With broadcast and wait
You could also use a broadcast-and-wait method, very similar to above:
Though I highly suggest you don't use this method, as if any other sprites have breakable loops you'll need to rename each one, which can be tedious after using a lot of loops in a lot of sprites!
(Note this bug has been fixed in version 442 of the editor and such the following no longer applies.)
Help! My project is lagging a bunch now!
As #foi has noticed, if your code must be run inside of a frame you probably checked run without screen refresh. Unfortunately, due to a bug in the Scratch player, this causes the program to essentially break after the stop this script block has been activated. How can you handle this?
It follows the same principle you use when you use a run without screen refresh custom block inside of a forever loop - the loop doesn't use screen refresh while the inside does, allowing for instant animations whether or not one is using turbo mode.
Here's an example - the image is really too long to be embedded, so see it here instead.
You can make a variable inside or outside of the repeat and make your script like this:
repeat until [[my variable] = [e.g: 1]]
your code
your code
your code
your code
end of repeat until
For a "repeat until" block the simplest way would be to "or" your normal until condition with the break condition in the until.
By adding an incremeting loop counter variable in the loop you can use a "repeat until" to replicate the function of a "repeat n times" block
By using a "repeat until" block with only your break condition you get the equivalent of a "forever" block
If you need another script/ sprite to trigger the break then a public variable will let you break the loop from anywhere and let a single condition break loops for different sprites.
I'd post an image of the blocks but this is my first reply and the site won't let me!
good luck
You can use these few ways to do it...
conditional loop
stop this script
if then else, in the else section, put nothing
I would prefer to use the first method, as it requires less blocks and for the first method, you can still add in code that will be executed after the loop has stopped executing.
You can make it repeat x times or make it have a certain point where it stops, such as another variable changing.
Otherwise, I don't think there is a wat to do that.
Use the repeat until block. Then put in an equals block or whatever into the boolean part. Then inside that repeat until block, put a stop this script block.
Hope this helps :D

Does this flowchart look right?

The flowchart I'm making doesn't look right. I've looked in my textbook for examples, but they don't seem to apply to this particular assignment. The pseudocode is right, because the Java is right, but the flowchart just looks wrong.
In this assignment the program is to display an array of items (iPod, Xbox, etc.) by using an array. The program is to ask the user which items they would like to order. The user is to enter the item. The program displays "In Stock". Then the program replaces the item from the array with an empty string. The program asks the user if they would like to make another order. If the user enters in the same item, the message "Out of Stock" is displayed.If the user enters another item, the same process repeats. (While loop) Entering the the word "No" ends the program.
You can see all this in the pseudocode, I just thought writing it all out might be easier. (Or not, maybe it just took extra work reading it.)
(Click image to enlarge)
I'm no flowchart guru, but I see that you have the 2nd WHILE as a conditional diamond with the loop completely under it. How does it ever escape that loop? The flow should always come into the top of the diamond, with the exit options on either side. This means that the first WHILE is wrong too.
Also, the third WHILE only has a single exit. And the same for the IF underneath it.
For all of these test/condition diamonds the flow should come in the top and exit either side.

Loop At <itab> TO <wa> Where <cond> does not find lines

I have a problem with Loop through a using the condition that an attribute from one table is the same with the other. For better explaining i'll past the code. Is not something difficult but i don't understand where i make the mistake.
LOOP AT gt_spfli INTO wa_spfli.
AT NEW carrid.
WRITE:/ wa_spfli-carrid.
ENDAT.
LOOP AT gt_sflight INTO wa_sflight WHERE carrid EQ wa_sflight-carrid.
WRITE:/ wa_sflight-carrid,
wa_sflight-connid,
wa_sflight-price.
ENDLOOP.
ULINE.
ENDLOOP.
For every carrid in spfli i want to show what sflight contains for that carrid. But it only writes the wa_spfli-carrid. It never gets to second write. When i do debugging i get that wa_sflight is always empty. ( or never gets to it ) gt_sflight and gt_spfli is populated so where does the problem comes from? If i remove the "where carrid EQ wa_sflight-carrid" works... but is not what i want to be shown on screen.
Additional info ( don't know if it's useful ): the gt_spfli and gt_sflight is populated through a function module i made myself.
On the inner loop, you want to compare carrid with wa_spfli-carrid (which comes from the outer loop) and not with wa_sflight-carrid.

Resources