Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[open] Timeout for a Python inline code -Screen display

edited December 2015 in OpenSesame

Hi, its me again! I think there's a fairly simple solution to this problem, but I can't seem to find it.

I have a paradigm where I'm presenting two screens where people have to rate on a scale of 1 - 5. Now, when they click on the enter key, it accepts the data from the first screen, and moves to the second.

However, I'm running an fMRI on this paradigm and I need the timing to be exact. As such, i wanted to initiate a 2.5-3 second timeout for the screen, whether the participant has made his entry or not. I tried to use self.time() and condition it to close the canvas if it crosses 3000ms, but it closed the canvas 3000ms AFTER the enter key was finally pressed.

Is it because of the getkey function and its position in the loop? Here is the code.

cnv = canvas()
kb = keyboard(keylist=['7', '8', '9'])
min_score = 1
max_score = 5
var.scoreP1_1 = 3 

question = 'Plaintive Rating'

while True:

    score_str = var.scoreP1_1*'*' + (max_score-var.scoreP1_1) * '_' 
    cnv.clear()
    cnv.text('%s<br /><br />%s' % (question, score_str))
    cnv.show()

    response, timestamp = kb.get_key()
    if response == '8':
        break
    if response == '7':
        var.scoreP1_1 = max(min_score, var.scoreP1_1-1)
    elif response == '9':
        var.scoreP1_1 = min(max_score, var.scoreP1_1+1)

I thought of possibly using a null value in the keylist, such that it accepts 'no response' as a key and thus begins counting even when no key has been pressed. But None, null and 0 don't seem to work for that option either.

Comments

  • edited 12:52PM

    Hi Jacob,

    Normally, keyboard.get_key() returns only when a key is pressed. If you poll responses in a loop, as you're doing, a common strategy is to set the timeout value of the keyboard to 0, and to check whether a timeout occurred in the loop around it. Do you see what I mean? So you use keyboard.get_key() only to poll the keyboard in a non-blocking fashion, and implement the timeout logic in the loop around it.

    Below you see a slight modification of my previous script which shows the general idea.

    Note that the scale is now always shown for 3000 ms or less. If you want to make sure that the scale is always shown for exactly 3000 ms, even if the participant pressed the spacebar before, you have to add some padding time to the end of the script. If needed, it might be a good exercise to try to figure that out yourself!

    Cheers!
    Sebastiaan

    # Create a keyboard and canvas object
    cnv = canvas()
    kb = keyboard(keylist=['left', 'right', 'space'], timeout=0)
    
    # For the score, we use a 0 - 4 scale, and start at 2
    min_score = 0
    max_score = 4
    var.score = 2 # Use var to make this an experimental variable
    
    timeout = 3000
    
    question = 'How awesome is OpenSesame?'
    
    start_time = clock.time()
    while True:
        # Example: A score of two would be "XX___"
        # Clear the canvas and show this score string
        score_str = var.score*'X' + (max_score-var.score) * '_' 
        cnv.clear()
        cnv.text('%s<br /><br />%s' % (question, score_str))
        cnv.show()
        # Check whether a timeout occurred, and set the score to None in this case
        if clock.time() - start_time >= timeout:
            var.score = None
            break   
        # Collect a response, and break the loop (i.e. accept the response)
        # When a space is pressed. Decrease the score for 'left', and increase
        # the score for 'right'.
        response, timestamp = kb.get_key()
        if response == 'space':
            break
        if response == 'left':
            var.score= max(min_score, var.score-1)
        elif response == 'right':
            var.score = min(max_score, var.score+1)
    
  • Hi there,

    I'm having a similar problem, but I couldn't workout how the above script would apply to my experiment. In my visual search experiment, I want my canvas to always remain for 2500ms, regardless of a key press. However, I would like to collect the response and response time of the keypress. The code below maintains the mask for 2500ms and collects the response, but it doesn't get the response_time (it currently returns a minimum of 2992, i.e. timeout, or as much as 5500ms). Is there a way to do this?

    # Show search array canvas for 500ms
    t0 = c.show()
    clock.sleep(495)
    
    # Show the mask for 2500ms, get key and response time
    t1 = mask.show()
    clock.sleep(2495)
    var.response, t2 = kb.get_key()
    var.response_time = t2-t0
    

    Many thanks,
    Joff

  • Hi Joff,

    t0 = c.show()
    while True:
        if clock.time()-t0 > 495:
        t1 = mask.show()
        elif clock.time()-t1 > 2500:
            break
        if not var.response:
            var.response, t2 = kb.get_key(timeout = 10)
            var.response_time = t2-t0
    

    Does this make sense?

    Eduard

    Buy Me A Coffee

  • Hi Eduard,

    Thanks for the quick response! I understand what is happening up until "if not var.response:", then I am a bit lost, as I would have thought that could be an else statement?

    I tested the code and I get an error "t1 is not defined", I am guessing this is because the elif statement refers to t1?

    Thanks,
    Joff

  • Hi Joff,

    Sorry, I should have used comments. Here again:

    # show your canvas and initialize t1, so that you can use it before presenting the mask
    # t1 was undefined before, which was the reason for the crash
    t0 = c.show()
    t1 = clock.time()
    # keep on sampling for the response in a while loop
    while True:
        # check if 500 ms have passed, if so, present the mask
        if clock.time()-t0 > 495:
            t1 = mask.show()
        # check if 2500 ms (since the mask onset) have passed, if so, break the loop
        elif clock.time()-t1 > 2500:
            break
        # if no response was given yet, sample for keypresses (for 10ms). If nothing has been pressed, go on
        # If a response was given, skip this step (and wait until loop is broken)
        if not var.response:
            var.response, t2 = kb.get_key(timeout = 10)
            # if a response was given, calculate the response time
            if var.response:
                var.response_time = t2-t0
    

    Is this clearer?

    Eduard

    Buy Me A Coffee

  • Hi Eduard,

    Thanks for the comments, that does make sense now. However, after presenting the mask OpenSesame (not the experiment) crashes, without an error report, as if it is overloaded or something.

    Any ideas?

    Thanks,
    Joff

  • Yes, stupid me....

    Swap the if and the first elif statement. You were caught in an infinite loop. See why?

    here the updated code:

    # show your canvas and initialize t1, so that you can use it before presenting the mask
    # t1 was undefined before, which was the reason for the crash
    t0 = c.show()
    t1 = clock.time()
    # keep on sampling for the response in a while loop
    while True:
    
        # check if 2500 ms (since the mask onset) have passed, if so, break the loop
        if clock.time()-t1 > 2500:
            break
    
        # check if 500 ms have passed, if so, present the mask
        elif clock.time()-t0 > 495:
            t1 = mask.show()
    
        # if no response was given yet, sample for keypresses (for 10ms). If nothing has been pressed, go on
        # If a response was given, skip this step (and wait until loop is broken)
        if not var.response:
            var.response, t2 = kb.get_key(timeout = 10)
            # if a response was given, calculate the response time
            if var.response:
                var.response_time = t2-t0
    

    Buy Me A Coffee

  • Hi Eduard,

    I tested the code but it's the same problem I'm afraid! I think I see what you mean about the infinite loop: clock.time() - t0 is always greater than 495, after 495ms has passed (although I realise the if statement should interrupt this). Could this be the source of the continuing error?

    Thanks,
    Joff

  • Hi Joff,

    Not sure what is wrong here. Could you try this code? Instead of showing the canvas on every frame, it executes this part only once (even though I don't think this should have caused a memory error or anything like that)

    # show your canvas and initialize t1, so that you can use it before presenting the mask
    # t1 was undefined before, which was the reason for the crash
    t0 = c.show()
    t1 = False
    # keep on sampling for the response in a while loop
    while True:
    
        # check if 500 ms have passed, if so, present the mask
        if clock.time()-t0 > 495 and not t1:
            t1 = mask.show()
    
        # check if 2500 ms (since the mask onset) have passed, if so, break the loop
        elif t1 and clock.time()-t1 > 2500:
            break
    
        # if no response was given yet, sample for keypresses (for 10ms). If nothing has been pressed, go on
        # If a response was given, skip this step (and wait until loop is broken)
        if not var.response:
            var.response, t2 = kb.get_key(timeout = 10)
            # if a response was given, calculate the response time
            if var.response:
                var.response_time = t2-t0
    

    Eduard

    Buy Me A Coffee

  • Hi Eduard,

    Thanks again for the suggestion, unfortunately it is still not working. What happens now is that the mask is shown for the correct duration, however all responses are shown as incorrect regardless of the response - I'm guessing it is logging everything as a timeout.

    If you know of a simple solution that would be great, but I wouldn't want you too spend any more time on this issue and is not crucial to the experiment (I'm more interested in accuracy), although it could be useful data to have.

    Thanks again for all your help.

    Joff

  • Hi Joff,

    Here another attempt. I tested it and I get response times that make sense and also the proper key labels out if it.

    c = canvas()
    mask = canvas()
    kb = keyboard()
    c.circle(0,0,20,fill=True)
    mask.circle(0,0,20,fill=True,color=(255,0,0))
    var.response = None
    # show your canvas and initialize t1, so that you can use it before presenting the mask
    # t1 was undefined before, which was the reason for the crash
    t0 = c.show()
    t1 = False
    # keep on sampling for the response in a while loop
    # remove pending keypresses
    kb.flush()
    while True:
    
        # check if 500 ms have passed, if so, present the mask
        if clock.time()-t0 > 495 and not t1:
            t1 = mask.show()
            print 'show mask'
    
        # check if 2500 ms (since the mask onset) have passed, if so, break the loop
        elif t1 and clock.time()-t1 > 2500:
            print 'break loop'
            break
    
        # if no response was given yet, sample for keypresses (for 10ms). If nothing has been pressed, go on
        # If a response was given, skip this step (and wait until loop is broken)
        if not var.response:
            print 'sample response'
            var.response, t2 = kb.get_key(timeout = 10)
            # if a response was given, calculate the response time
            if var.response:
                var.response_time = t2-t0
    

    I hope this solves it now for good.

    Eduard

    Buy Me A Coffee

  • Sorry Eduard, the response times are still not being recorded properly. I copied your code in, save your mask and canvas, but an incorrect response time is set on the first trial and this doesn't change for subsequent trials. Very strange, but I don't want to waste anymore of your time so thank you for your help.

    Joff

Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games