Alphabets in rectangles

Hi all, I am trying to create a visual stimuli which contains two rectangles(red and green) flashing at different frequencies. These rectangle boxes should contain different set of alphabets (26 alphabets should be spread out to both rectangles).

I am not able to attach alphabets to my rectangles. Somehow code is not working properly. The Psychopy Gui opens and it closes immediately. It cant read what is happening.

Here is the code which I am working on.

from psychopy import visual, core  
import numpy as np
class TablesGenerator(object):
    def_text_table1 = [
        ['A', 'B', 'C'],
        ['G', 'H', 'I'],
        ['M', 'N', 'O'],
        ['S', 'T', 'U'],
        ['Y', 'Z', '-']
        ]
        
    def_text_table2 = [
        ['D', 'E', 'F'],
        ['J', 'K', 'L'],
        ['P', 'Q', 'R'],
        ['V', 'W', 'X'],
        ['?', '_', '-']
        ]
    def __init__(self, text_table1=def_text_table1, fullscr=False,
                 pos=(0, 0), bg_color='red', fg_color='black'):
        self.text_table1 = text_table1
        self.fullscr = fullscr
        self.pos = pos
        self.fg_color = fg_color
        self.bg_color = bg_color
        
    def __init__(self, text_table2=def_text_table2, fullscr=False,
                 pos=(0, 0), bg_color='green', fg_color='black'):
        self.text_table2 = text_table2
        self.fullscr = fullscr
        self.pos = pos
        self.fg_color = fg_color
        self.bg_color = bg_color

# Create a window.
# For configuring and debugging the code turn off full screen.
fullscr = False
win = visual.Window(
    [1200,1000],
    monitor="testMonitor",
    units="deg",
    fullscr=fullscr
    )
win.setMouseVisible(False)

# Sinusoidal control version.
freq_one = 0.5
freq_two = 1.5
# Colors of the rectangles.
color_one = 'red'
color_two = 'green'
# Positions of the rectanges.
pos_one = (-7, 0)
pos_two = (7, 0)


start = core.getTime()
cnt = 0
while cnt<600:
    second = core.getTime() - start

    sin_val_one = 1.0+0.5*np.sin(2 * np.pi * second * float(freq_one))
    sin_val_two = 1.0+0.5*np.sin(2 * np.pi * second * float(freq_two))
    
    def _create_TextStim1(self, win, text1, font='Monospace', height=10, wrapWidth=600):

        text_stim1 = visual.TextStim(win=win, text1=''.join(text_table1), font=font, 
           height=height, wrapWidth=wrapWidth, color=self.fg_color)
         
        return text_stim1
        
    def _create_TextStim2(self, win, text2, font='Monospace', height=10, wrapWidth=600):

        text_stim2 = visual.TextStim(win=win, text2=''.join(text_table2), font=font, 
           height=height, wrapWidth=wrapWidth, color=self.fg_color)
       
        return text_stim2
        
        rect_one = visual.Rect(
        win=win,text1=''.join(text_stim1),
        fillColor=color_one,
        lineColor=color_one, 
        size=20,
        pos=pos_one,
        opacity=sin_val_one
        )
        rect_two = visual.Rect(
        win=win,text2=''.join(text_stim2),
        fillColor=color_two,
        lineColor=color_two, 
        size=20,
        pos=pos_two,
        opacity=sin_val_two
        )

        rect_one.draw()
        rect_two.draw()
        win.flip()
        cnt += 1

    win.close()

Can anyone please help me resolve this error?
Thanks in Advance !

Hello! I believe the reason the window opens and closes is that whenever you call Window() to initialize it, it opens, and then closes when the script is ended, so that’s not really the issue.

I’m not going to lie, it’s not totally clear what you want to do, and there are a lot of problems with the code above. The problem seems to be that you don’t quite yet understand how functions (the sections that start with “def”), and classes work in Python, and need to put in some work understanding how programs run from start to finish. For example, you’re “defining” the functions, but never end up calling them. That’s like writing a recipe but never actually cooking the food, so nothing ever happens. You also write a class definition for TablesGenerator, but you never create one. That’s like a toy manufacturer building a mold for a toy, but never actually making a toy out of it. So the problem is you’re not understanding how the program runs, and how to write and use functions and classes.

Also in the beginning, you may not need to worry about using classes yet for psychopy until you get a little more experience. Since I’m not totally sure what the goal is, I’m going to write a simplified version of some of your code so you can maybe learn a little bit about the process. You could also try using the builder, which you can extend with custom code. It’s a gentler introduction. Whatever you decide to do in the short term (long term, learning to code is the way to go :slight_smile: ), here’s that shorter script to get you started. I’ll also attach it.

flashingSquares.py (3.8 KB)

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from psychopy import visual, core
import numpy as np

# This is a function, right now it's just a set of instructions, but 
# we still haven't actually done anything with it
def create_TextStim(win, textTable, font="Monospace", height=10, wrapWidth=600, fg_color='black'):

    textStim = visual.TextStim(win=win, text=''.join(textTable), 
                   font=font, height=height, wrapWidth=wrapWidth, 
                   color=fg_color)

    return textStim

# This is a common way to start
# a script in python.
if __name__ == '__main__':

    # So it looks like you wanted to create one 
    # TextStim for each row of letters here, but
    # actually couldn't you just make two text
    # stims that have one string? Unless you 
    # wanted to record mouse clicks on each one? 
    # If so you probably meant to create them in a
    # loop.
    #text_table1 = [
    #    ['A', 'B', 'C'],
    #    ['G', 'H', 'I'],
    #    ['M', 'N', 'O'],
    #    ['S', 'T', 'U'],
    #    ['Y', 'Z', '-']
    #    ]
    #text_table2 = [
    #    ['D', 'E', 'F'],
    #    ['J', 'K', 'L'],
    #    ['P', 'Q', 'R'],
    #    ['V', 'W', 'X'],
    #    ['?', '_', '-']
    #    ]
    text1 = "ABC\nGHI\nMNO\nSTU\nYZ-"
    text2 = "DEF\nJKL\nPQR\nVWX\n?_-"

    # Sinusoidal control version.
    freq_one = 0.5
    freq_two = 1.5
    # Colors of the rectangles.
    color_one = 'red'
    color_two = 'green'
    # Positions of the rectanges.
    pos_one = (-7, 0)
    pos_two = (7, 0)

    fullscr=False

    # create a window, assign to a variable 'win'
    win = visual.Window(
        size=(1200,1000),
        monitor="testMonitor",
        units="deg",
        fullscr=fullscr
    )

    # This is how you would call now we're going to call 
    # the create_TextStim function that we wrote above, and save what 
    # it returns (a TextStim object) to a variable, but 
    # since we're not using a grid right now, it's not 
    # necessary.
    #
    # Note that you wrote the same function twice.
    # You don't need to. You just call it twice and
    # save it to different variables
    #textStim1 = create_TextStim(win, text_table1)
    #textStim2 = create_TextStim(win, text_table2)
    font = "Monospace"
    height = 10
    wrapWidth = 600
    fg_color= "black"
    # I'm removing the height value you had for now
    # because it was way too big
    textStim1 = visual.TextStim(win=win, text=text1, 
                   font=font, wrapWidth=wrapWidth, 
                   color=fg_color
    )
    textStim2 = visual.TextStim(win=win, text=text2, 
                   font=font, wrapWidth=wrapWidth, 
                   color=fg_color
    )

    pos_one = (-7, 0)
    pos_two = (7,0)

    textStim1.pos = pos_one
    textStim2.pos = pos_two

    # We'll start off with the opacity at 1
    rect_one = visual.Rect(
        win=win, fillColor=color_one, 
        lineColor=color_one, size=20,
        pos=pos_one, opacity = 1,
    )
    rect_two = visual.Rect(
        win=win, fillColor=color_two, 
        lineColor=color_two, size=20,
        pos=pos_two, opacity = 1,
    )

    # If you want these to just stay 
    # visible set autoDraw to True
    textStim1.setAutoDraw(True)
    textStim2.setAutoDraw(True)
    rect_one.setAutoDraw(True)
    rect_two.setAutoDraw(True)

    # Now that we've created our visual stimuli,
    # we'll make a loop that keeps changing their
    # values. We don't want to keep creating them
    # every time we go through the loop, we just
    # change their values
    start = core.getTime()
    cnt = 0
    while cnt < 600:
        second = core.getTime() - start
        sin_val_one = 1.0+0.5*np.sin(2 * np.pi * second * float(freq_one))
        sin_val_two = 1.0+0.5*np.sin(2 * np.pi * second * float(freq_two))
        rect_one.opacity = sin_val_one
        rect_two.opacity = sin_val_two
    
        win.flip()
        cnt += 1

Hi Daniel,

Thank you so much for your help. I am just a beginner in coding and I knew the code had many flaws. But I am trying to learn by coding. I guess in the long term run, I would be able to code well.

Once again, I appreciate the help you extended and this is how I really wanted to work. :slight_smile:

I’m glad it helped! By the way, I really like this tutorial:

http://zetcode.com/lang/python/

It’ll take you through the fundamental concepts of python. He has a free and a paid version.

1 Like