I am trying to get a sound to play if 'Space' is not pressed AND if time is >1s, and to stop it if 'Space' is pressed
alarm = sound.Sound(700, secs = 5)
if (len(event.getKeys())==0) & (time1.getTime() > 1):
alarm.play()
elif event.getKeys(keyList = 'space'):
alarm.stop()
However, when I do this, I cannot press 'space' to stop the alarm.
Can anyone tell me what I am doing wrong here? Is there any thing wrong with the '(len(event.getKeys())==0)' portion?
In Matlab, I can just write
if ~KbCheck && .....
but I am not sure how to do it in Psychopy.
Thanks!
Use event.getKeys(keyList=['space']). The keyList is a list, not a string. Also, change the order of your logic since the first call to event.getKeys() clears the keyboard buffer for all keys, since no keyList was provided so that nothing is left to be registered in your elif.
So this should do the trick:
if event.getKeys(keyList = ['space']):
alarm.stop()
elif time1.getTime() > 1 and not event.getKeys(): # if another key was pressed... #added brackets here
alarm.play()
As you can see, I also simplified the syntax for one of the tests.
Related
I am trying to collect the participants' responses (i.e., the first key they press on the keyboard) and their reaction time (i.e., the time elapsed since the presentation of a picture and the response). I am using the KbQueueXXX functions in Psychtoolbox, but I am not sure if I am using them properly.
Thanks for your help.
Dear Psychtoolbox users,
I wrote a script to run a 2AFC task where participants must respond within a fixed deadline of 2 seconds. If participants respond earlier, then they move to the subsequent trial straight away. To collect their responses (i.e., the first key they pressed and their RT), I coded a custom function that incorporates KbQueueCheck(). I am now reviewing and debugging my script but I have some doubts about the KbQueueXXX functions. I would be grateful if you could give me some feedback.
Task script
In a mixture of code and pseudocode, here is what I am doing.
KbQueueCreate(KEYBOARD, KEYS_OF_INTEREST);
KbQueueStart(KEYBOARD);
% TRIALS' LOOP STARTS
for iTrial = 1:nTrials
KbQueueFlush(KEYBOARD);
% show stimulus and record its onset and offset times
respDeadline = stimulusOffset + 2;
collectResponse(KEYBOARD, respDeadline, stimulusOnset); % <- KbQueueCheck() here!
end
% TRIALS' LOOP ENDS
KbQueueStop(KEYBOARD);
KbQueueRelease(KEYBOARD);
Custom function
Below is my custom function collectResponse() where I embedded KbQueueCheck().
function [choice, rt, choiceTime, firstPress, keyCodes, pressed] = collectResponse(deviceIndex, untilTime, targetOnset)
%% LOOK FOR KEYPRESSES
pressed = false;
while pressed == false && GetSecs <= untilTime
[pressed, firstPress] = KbQueueCheck(deviceIndex);
end
%% PROCESS KEYPRESSES
if pressed == false % NO KEYS WERE PRESSED
keyCodes = NaN;
firstPress = NaN;
choiceTime = NaN;
choice = NaN;
rt = NaN;
else % ONE OR MORE KEYS WERE PRESSED
keyCodes = find(firstPress > 0); % all keypresses
choiceTime = min(firstPress(keyCodes)); % ts of first keypress
choice = find(firstPress == choiceTime); % first keypress
if length(choice) > 1
% handle simultaneous keypresses
choice = -999;
end
rt = choiceTime - targetOnset; % reaction time
end
end
My questions
I am not sure whether I am calling KbQueueXXX functions correctly and whether they are in the expected position.
Shall I keep KbQueueCreate()/KbQueueStart() and KbQueueStop()/KbQueueRelease() respectively before and after the trials’ loop?
Shall I rather just KbQueueStart(), KbQueueCheck(), and KbQueueStop() at each trial iteratively?
Is it OK to KbQueueFlush() at the beginning of each trial, before the presentation of a new stimulus?
Is my custom function collectResponse() fit for the purpose I described at the top of this post?
Thank you very much for your time, I look forward to knowing your thoughts.
Kind regards,
Valerio
OS: Windows 10
MATLAB: 9.10.0.1851785 (R2021a) Update 6
PTB: 3.0.18 - Flavor: beta - Corresponds to SVN Revision 13009
The original post can be found in the Psychtoolbox forum.
KbQueueXXX functions: which to use and where do they go in relation to the trials' loop?
i want to know if the window is minimized or not. i have connected window-state-event signal from GtkWidget to this function
def on_main_window_hide(object, event)
if event.changed_mask & Gdk::WindowState::ICONIFIED
if event.new_window_state & Gdk::WindowState::ICONIFIED
puts("minimize" + $counter.to_s)
$counter+=1
else
puts ("unminimize")
end
end
end
and even after doing minimizing and unminimizing couple of times .. it never prints if the window is unminimized, here is the output
minimize0
minimize1
minimize2
minimize3
minimize4
plus, minimizing gives the window-state-event signal twice, like if minimize0 is initial value then on minimizing it becomes minimize2
how can i detect properly if a window is minimized ?
I think you got confused by the callback name. The window-state-event signal gets emitted for every state event change, so the callback should be called on_main_window_state_event as it will be emitted not only when the window hides. Then you can check the event mask for changes.
Your callback has a redundant if condition. From the API, the changed_mask is a:
mask specifying what flags have changed
And window_new_state is also a mask but contains:
the new window state, a combination of GdkWindowState bits
This means that the second if condition will always evaluate as true if the first one also evaluates as true but the else branch will never happen. If you want your "unminimize" print to occur then you must remove the second if condition and move the print to the else branch of the first if condition. Another option would be to check for the bit mask and really check the status.
Your code should be:
def on_main_window_state_event(object, event)
if event.changed_mask & Gdk::WindowState::ICONIFIED
puts("minimize" + $counter.to_s)
$counter+=1
else
puts ("unminimize")
end
end
Hello I have three problems with my code:
when I type in "N" for my first question, it goes into an error.
I get in an infinite loop after the "Run again?" input.
my counters do not add up properly so even when I get an answer right or wrong, it doesn't count them.
Please help me.
Below is my code:
#Introduction-ish print statement
print("In this application, we will be playing a coin coss game. For as "\
"many times as you like, we will continue playing the game.")
#def function1():
response=str(input("\nWould you like to run this application? Type 'Y' to run "\
"or 'N' to not run: "))
if response=="N":
print("\nOutcome of Game:")
print("You did not run the application."\
" Nothing happened. You did not play the game.")
#Counters
programCounter=0
hCounter=0
tCounter=0
guessCountR=0
guessCountW=0
#User Input
if response=="Y":
funcGuess=str(input("\nPick one- Type 'H' for Heads or 'T' for Tails: "))
#Coins
import random
#number=random.randint(1,2)
while response !="N" and funcGuess=="H" or funcGuess=="T":
number=random.randint(1,2)
if number==1:
number=="Heads"
hCounter+=1
else:
number=="Tails"
tCounter+=1
if funcGuess==number:
guessCountR+=1
else:
guessCountW+=1
print(number)
response=str(input("Run again?"))
if response=="Y":
funcGuess=str(input("\nPick one- Type 'H' for Heads or 'T' for Tails: "))
if response=="N":
print("\nOutcome of Game:")
print("You guessed ",programCounter, "time(s).")
print("You guessed heads",hCounter, "time(s).")
print("You guessed tails",tCounter, "time(s).")
print("You guessed correctly",guessCountR, "time(s).")
print("You guessed incorrectly",guessCountW, "time(s).")
#Guess Count
guessCount=guessCountR+guessCountW
#paste
#if response =="Y":
#function1()
#else:
#print("\nOutcome of Game:")
#print("You did not run the application."\
#" Nothing happened. You did not play the game.")
I don't mind all the comments. I purposely left them there but if anyone helping finds them useful, please let me know.
Apologies in advanced for the long post.
Problem 1:
On line 34 you're evaluating a variable called funcGuess. It only gets defined on line 26 should you answer 'Y' to the initial question.
Problem 2:
The while loop loops infinitely, because break conditions can never be met. There's no way to assign response the value "N" within the loop. Also, be sure to put both sides of the or evaluation between parentheses in order to evaluate the line correctly
Problem 3:
The correct number and the guess are assigned into variables number and funcGuess, respectively. number is always 1 or 2, and funcGuess is always "H" or "T". Therefore funcGuess == number can never evaluate as True.
Here's what I've got so far:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_LEFT:
mods = pygame.key.get_mods()
if mods and KMOD_SHIFT:
movei = -5
if mods and KMOD_CTRL:
movei = -20
else:
movei = -10
The problem is it seems to only pick up one or the other (KMOD_SHIFT or KMDO_CTRL) ALL THE TIME, not selectively. So it doesn't matter which modifier I press (shift, alt, ctrl etc.) the effect is still the same.
The effect I'm going for is that the onscreen character can creep, run or walk, respectively.
Thanks in advance.
You're using the logical and operator, while you really need the bit-wise operator &. Instead of
if mods and KMOD_SHIFT:
you want
if mods & KMOD_SHIFT:
The logical and will return the value of the second operand as long as the first one has a true value (in this case, not equal to 0). The & operator will perform a bit-wise AND operation and will therefore return a non-zero value (logically interpreted as true) only if some of the bits from the KMOD constant are on in the mods variable.
I'm trying to write a simple ruby function that can prompt the user for a value and if the user presses ENTER by itself, then a default value is used.
In the following example, the first call to the Prompt function can be handled by pressing ENTER by itself and the default value will be used. However, the second time I call Prompt and press ENTER, nothing happens, and it turns out I have to press some other character before ENTER to return from the 'gets' call.
There must be some way to flush the input buffer to avoid this problem. Anyone know what to do?
Thanks,
David
def BlankString(aString)
return (aString == nil) ||
(aString.strip.length == 0)
end
#Display a message and accept the input
def Prompt(aMessage, defaultReponse = "")
found = false
result = ""
showDefault = BlankString(defaultReponse) ? "" : "(#{defaultReponse})"
while not found
puts "#{aMessage}#{showDefault}"
result = gets.chomp
result.strip!
found = result.length > 0
if !found
then if !BlankString(showDefault)
then
result = defaultReponse
found = true
end
end
end
return result
end
foo = Prompt("Prompt>", "sdfsdf")
puts foo
foo = Prompt("Prompt>", "default")
puts foo
This isn't technically an answer, but it'll help you anyways: use Highline (http://highline.rubyforge.org/), it'll save you a lot of grief if you're making a command-line interactive interface like this
I tried your code (under Windows) and it seemed to work fine.
What OS are you using?
I also tried your code (under OSX) with ruby 1.8.6 and it worked fine:
:! ruby prompt.rb
Prompt>(sdfsdf)
sdfsdf
Prompt>(default)
default
What do you get when you run the following?
c = gets
b = gets
a = gets
p [ a, b, c ]
I just hit 'Enter' 3x and get
["\n", "\n", "\n"]
I'm guessing what's wrong is that you're entering an infinite loop in your while statement by not passing it a defaultResponse (in some code that you're actually runinng that's not in your example).
I have confirmed (by running the program outside of Komodo) that the problem is in fact solely happening inside Komodo. I thank everyone for the feedback and taking the time to do the independent test (which I hadn't though of) to help narrow down the problem.