Show punctuated text as feedback

OS Win10
PsychoPy version 3.2.4
Standard Standalone? (y/n) y
What are you trying to achieve?: Show punctuated text in Hebrew as feedback

In my experiment there is a trail with a short video , a response routine and a written feedback. I created a loop referring to xlsx conditions file.
A different punctuated text in Hebrew is attached to each condition as a parameter.

(Since we have no specific letters for different vowels, punctuation is critical for precise reading of short words, as in my experiment.)

What did you try to make it work?:
The loop works well if the feedback text on the condition file is without punctuation.

What specifically went wrong when you tried that?:
The experiment stops when the feedback is about to appear. The Error shown is:

ord(text), ord(text), byref(abc)):

TypeError: ord() expected a character, but string of length 2 found

It makes sense because punctuation in Hebrew appears under/above/inside the letter. Is there a way to bypass this limitation?
Thanks a lot,
Nitza

1 Like

What version of Python are you using?

If this is not simply a Python 2 issue, please provide some example Hebrew text that causes the error. If the issue is actually that you simply have a letter plus some punctuation in the text variable, then you could just access a particular character by index:

ord(text[0])

Otherwise, show us all of your custom code. We can’t tell much from the tiny snippet taken out of context, including not being nested properly in brackets.

I am sorry, This is my first experiment and I thought I copied the error message.
I used only the builder and don’t know how to provide more info.

The version is Python 3.6.6 that was installed (I think) with PsychoPy 3.2.4

Some examples for text are shown in the attached picture.

The specific location of the punctuation could be different for each word (200 words).

Thanks,
Nitza

Hi, we can’t do anything with text in an image. Can you please just paste in some actual characters into a post here (i.e. I guess from what you have in your conditions file)?

That is, bear in mind that I don’t know how to type and compose these characters myself, so am going to need some hand-holding so I can put those characters into some code expressions.

There should be some more detail in the full error message (e.g. it should indicate a file and specific line number in which the error occurred).

Hi,
This for example is the word gav
גַּב
and sid
סִיד

The output file with the error was:

Traceback (most recent call last):
File “E:\Documents\טל MA\Exp_try\NVS_PunTextFback_lastrun.py”, line 513, in
HebFback.setText(Heb_FB)
File “C:\Program Files\PsychoPy3\lib\site-packages\psychopy\visual\text.py”, line 354, in setText
setAttribute(self, ‘text’, text, log)
File “C:\Program Files\PsychoPy3\lib\site-packages\psychopy\tools\attributetools.py”, line 141, in setAttribute
setattr(self, attrib, value)
File “C:\Program Files\PsychoPy3\lib\site-packages\psychopy\tools\attributetools.py”, line 32, in set
newValue = self.func(obj, value)
File “C:\Program Files\PsychoPy3\lib\site-packages\psychopy\visual\text.py”, line 345, in text
self._setTextShaders(text)
File “C:\Program Files\PsychoPy3\lib\site-packages\psychopy\visual\text.py”, line 365, in _setTextShaders
width=self._wrapWidthPix) # width of the frame
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\font\text.py”, line 338, in init
group=self._group)
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 810, in init
self.document = document
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 919, in _set_document
self._init_document()
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 1020, in _init_document
self._update()
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 956, in _update
lines = self._get_lines()
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 932, in _get_lines
glyphs = self._get_glyphs()
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\text\layout.py”, line 1059, in _get_glyphs
glyphs.extend(font.get_glyphs(text[start:end]))
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\font\base.py”, line 385, in get_glyphs
self.glyphs[c] = glyph_renderer.render(c)
File “C:\Program Files\PsychoPy3\lib\site-packages\pyglet\font\win32.py”, line 431, in render
ord(text), ord(text), byref(abc)):
TypeError: ord() expected a character, but string of length 3 found

I made a shorter version of the experiment for this correspondence.
Attached are the code and the condition files
list1Cond.xlsx (9.7 KB) NVS_PunTextFback.py (32.6 KB)

When the HebFback text is defined as $NoP_Heb (words without punctuation) the experiment works fine

Please let me know if you need some more info or files
Thanks a lot!
Nitza

Thanks for the example text, and more particularly the full text of the error message. I had thought the error was due to some custom code of yours, but instead the issue is buried deep in the third party library pyglet, which PsychoPy uses to display text. This makes things more complicated.

For ease of use, could you please upload your Builder .psyexp file, rather than the the generated .py script?

Thanks for looking into it
NVS_PunTextFback.psyexp (22.2 KB)

This is the location of the error within the pyglet package:

As can be seen, the developer admits that this section of code is a hack to get around some limitations of Windows. I guess pyglet could be changed to code more defensively for Hebrew text, but realistically that isn’t going to happen on a time frame that will work for you.

There could be a couple of work-arounds.

  • In the first instance, although it is a bit hard for me to know, the experiment seems to run OK for me on a Mac, so the problem may indeed be Windows-specific. Is running on Mac or Linux feasible?
  • Secondly, it might be possible to programatically generate bitmap images from the text in your conditions file using a different package, and display those instead of relying on pyglet to display the text directly.

Thank you for the effort.
I will check the feasibility of the two options you suggested.
Thanks again,
Nitza

I had the same problem. but i solved it by just deleting / commenting out that portion of the code, specifically the :

if gdi32.GetCharABCWidthsW(self._dc,
# ord(text), ord(text), byref(abc)):

       # lsb = abc.abcA
       # if lsb < 0:
            # Negative LSB: we shift the layout rect to the right
            # Otherwise we will cut the left part of the glyph
         #   rect.x = -lsb
         #   width -= lsb
    # XXX END HACK HACK HACK

See if it works for you