Odd Type Mismatch error

86 views
Skip to first unread message

joliver

unread,
Sep 1, 2022, 6:20:50 PM9/1/22
to E-Prime
Hello,
Found a bug in one of our tasks that causes a crash when a response button is pressed rapidly. We're using sliders controlled via task events (button box, but 2 moves down, 4 moves up and 5 locks in the response). What is odd is that the crash only appears to occur during the practice trials in the beginning and not during actual event trials.

If - immediately prior to the slide presenting - one rapidly hits ANY viable response button (2, 4 or 5) it will throw a type mismatch at the 3rd line of the following (entire user script copied, but the line beginning "If theKeyValue = "2"..." is what gets highlighted). I don't understand why a Type Mismatch error would occur only in this scenario. My best guess is that it is caching button presses and then attempting to implement them prior to drawing the slide, but I'd expect a different type of error in that scenario and it wouldn't explain why it doesn't happen during the primary portion of the task. I can't find any obvious way to disable caching responses. Any ideas would be greatly appreciated - this one really has me stumped! Happy to share any additional task details as needed.



Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As String)
    Dim theValue As Long
    If theKeyValue = "2" And CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value > CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).ValueMin Then
        theValue = CLng(CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value) - 1
        CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value = theValue
        CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1")).ValueDefault = theValue
    End If

    If theKeyValue = "4" And CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value < CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).ValueMax Then
        theValue = CLng(CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value) + 1
        CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value = theValue
        CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1")).ValueDefault = theValue
    End If
End Sub

Sub MoveTheIndicatorByResponseBox (c As Context, theKeyValue As String)
    Dim theValue As Long
    If theKeyValue = "2" And CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value > CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).ValueMin Then
        theValue = CLng(CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value) - 1
        CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value = theValue
        CSlideSlider(PostFixation.ActiveObjects("Slider1")).ValueDefault = theValue
    End If

    If theKeyValue = "4" And CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value < CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).ValueMax Then
        theValue = CLng(CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value) + 1
        CSlideSlider(ImageryResponseSlide.ActiveObjects("Slider1")).Value = theValue
        CSlideSlider(PostFixation.ActiveObjects("Slider1")).ValueDefault = theValue
    End If
End Sub

joliver

unread,
Sep 2, 2022, 3:44:37 PM9/2/22
to E-Prime
Update: After a number of changes, for still unclear reasons this is now happening only with our button box (which is a USB device recognized as a keyboard) and not with actual keyboard responses - i.e. mashing the 5 key on the keyboard does not cause a crash. Has anyone encountered something like this before? 

Spape, Michiel

unread,
Sep 3, 2022, 7:48:28 AM9/3/22
to e-p...@googlegroups.com

Hi Joliver,

No idea, to be honest, but what you may do in instances like this is putting some debug.prints in between to capture actually what is happening. I.e. underneath each Sub with

Debug.print “PracticeMoveTheIndicatorByResponseBox, theKeyvalue=” & theKeyValue & “.”

Especially the ending with . is useful, so you will find out if there’s no accidental space or multiple keys or whatever being captured!

Hope that helps,

Michiel

 

--
You received this message because you are subscribed to the Google Groups "E-Prime" group.
To unsubscribe from this group and stop receiving emails from it, send an email to e-prime+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/e-prime/4af928ff-d127-46cc-a13f-5ac13d8a7444n%40googlegroups.com.

joliver

unread,
Sep 22, 2022, 12:29:22 PM9/22/22
to E-Prime
I appreciate this suggestion Michiel and sorry for the delayed response - I'm running labs in two different cities so it was a while before I could get my hands on the button box in question again. 

So thanks to debugging, it "seems" what is happening is for some reason the slider value is being set to a blank <somehow> and I'm guessing that is causing the type mismatch as it is trying to test whether a blank is > a number.
"PracticeMoveTheIndicatorByResponseBox, theKeyvalue=5.
ActiveObjects.Value: .
ActiveObjects.ValueMin: 0.

What I don't understand is how this is happening when you mash the buttons or why it is only happening during practice trials and not actual trials. I added an inline immediately before slide onset to manually set the value to 5
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value = 5

This does not change anything. The default value (which would presumably overwrite the inline anyways) is already set to 5. 

Does anyone have other ideas? This one really has me stumped....

David McFarlane

unread,
Sep 22, 2022, 4:46:49 PM9/22/22
to e-p...@googlegroups.com
Poking in here ...

It seems like your USB button box sometimes produces an empty input
value. Short of fixing the problem at the USB device, you will need to
handle this possibility in your code. E.g., add a line to ignore empty
inputs,

If
(CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value = _
"") Then Return

or convert empty inputs to a valid numeric value before processing,

If (...) And _

(Val(CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value _
> 2) Then

Still no idea why you would get this only during practice trials.


Now some unsolicited comments on coding style ...

When I find myself using an unwieldy construct such as
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")) (and
especially when the identical construct appears multiple times), I like
to create a temporary "convenience" variable for clarity (and marginally
for abstruse performance reasons). E.g.,

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim theValue As Long
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
If ((theKeyValue = "2") And (thisSlider.Value >
thisSlider.ValueMin)) Then
theValue = thisSlider.Value - 1
thisSlider.Value = theValue
nextSlider.ValueDefault = theValue
End If
If ((theKeyValue = "4") And (thisSlider.Value <
thisSlider.ValueMax)) Then
theValue = thisSlider.Value + 1
thisSlider.Value = theValue
nextSlider.ValueDefault = theValue
End If
End Sub

Note that the intent is to increment or decrement thisSlider.Value and
set nextSlider.ValueDefault to thisSlider.Value, so we do not really
need theValue. Also, I would use If-ElseIf instead of a pair of If
statements (no need to do the second conditional test if the first one
succeeds). Thus,

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
If ((theKeyValue = "2") And (thisSlider.Value >
thisSlider.ValueMin)) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
ElseIf ((theKeyValue = "4") And _
(thisSlider.Value < thisSlider.ValueMax)) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
End If
End Sub

If we wanted to practice "defensive coding" we would also add a final
Else clause, just to make it explicit that it does nothing in that case:

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
If ((theKeyValue = "2") And (thisSlider.Value >
thisSlider.ValueMin)) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
ElseIf ((theKeyValue = "4") And _
(thisSlider.Value < thisSlider.ValueMax)) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
Else
' do nothing
End If
End Sub

We might even use a Select Case here, though in this particular case it
does not work quite as neatly as we would like:

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
Select Case theKeyValue
Case "2"
If (thisSlider.Value > thisSlider.ValueMin) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case "4"
If (thisSlider.Value < thisSlider.ValueMax) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case Else
' do nothing
End Select
End Sub

Now let's handle the case where thisSlider.Value is empty. Here is one
way, simply exiting the subroutine in that case:

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
If (thisSlider.Value = "") Then Return ' <<< EXIT HERE FOR EMPTY VALUE
Select Case theKeyValue
Case "2"
If (thisSlider.Value > thisSlider.ValueMin) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case "4"
If (thisSlider.Value < thisSlider.ValueMax) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case Else
' do nothing
End Select
End Sub

And here is another way, simply using Val(thisSlider.Value) to convert
thisSlider.Value to a valid numeric value before we test it:

Sub PracticeMoveTheIndicatorByResponseBox (c As Context, theKeyValue As
String)
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = _
CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1"))
Set nextSlider =
CSlideSlider(PracticeResponsePost.ActiveObjects("Slider1"))
Select Case theKeyValue
Case "2"
If (Val(thisSlider.Value) > thisSlider.ValueMin) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case "4"
If (Val(thisSlider.Value) < thisSlider.ValueMax) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case Else
' do nothing
End Select
End Sub

Finally, let's suppose that we could pass thisSlide & nextSlide as
arguments (not sure if we can do this in a Task Event). In that case we
could construct one Sub that would handle both the practice & real
trials; even better if we could directly pass thisSlideSlider &
nextSlideSlider, but here is the exampe simply passing the Slide variables:

Sub MoveIndicatorByResponseBox (c As Context, theKeyValue As String, _
thisSlide as Slide, nextSlide as Slide))
Dim thisSlider as SlideSlider ' for notational convenience
Dim nextSlider as SlideSlider ' for notational convenience
Set thisSlider = CSlideSlider(thisSlide.ActiveObjects("Slider1"))
Set nextSlider = CSlideSlider(nextSlide.ActiveObjects("Slider1"))
Select Case theKeyValue
Case "2"
If (Val(thisSlider.Value) > thisSlider.ValueMin) Then
thisSlider.Value = thisSlider.Value - 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case "4"
If (Val(thisSlider.Value) < thisSlider.ValueMax) Then
thisSlider.Value = thisSlider.Value + 1
nextSlider.ValueDefault = thisSlider.Value
End If
Case Else
' do nothing
End Select
End Sub

-- David McFarlane


On 2022-09-22 Thu 12:29 PM, joliver wrote:
> I appreciate this suggestion Michiel and sorry for the delayed response
> - I'm running labs in two different cities so it was a while before I
> could get my hands on the button box in question again.
>
> So thanks to debugging, it "seems" what is happening is for some reason
> the slider value is being set to a blank <somehow> and I'm guessing that
> is causing the type mismatch as it is trying to test whether a blank is
> > a number.
> "PracticeMoveTheIndicatorByResponseBox, theKeyvalue=5.
> ActiveObjects.Value: .
> ActiveObjects.ValueMin: 0.
>
> What I don't understand is how this is happening when you mash the
> buttons or why it is only happening during practice trials and not
> actual trials. I added an inline immediately before slide onset to
> manually set the value to 5
> CSlideSlider(PracticeResponseSlide.ActiveObjects("Slider1")).Value = 5
>
> This does not change anything. The default value (which would presumably
> overwrite the inline anyways) is already set to 5.
>
> Does anyone have other ideas? This one really has me stumped....
>
>
> On Saturday, September 3, 2022 at 6:48:28 AM UTC-5 michie...@helsinki.fi
> wrote:
>
> Hi Joliver,____
>
> No idea, to be honest, but what you may do in instances like this is
> putting some debug.prints in between to capture actually what is
> happening. I.e. underneath each Sub with____
>
> Debug.print “PracticeMoveTheIndicatorByResponseBox, theKeyvalue=” &
> theKeyValue & “.”____
>
> Especially the ending with . is useful, so you will find out if
> there’s no accidental space or multiple keys or whatever being
> captured!____
>
> Hope that helps,____
>
> Michiel____
>
> __ __
>
> *From:*e-p...@googlegroups.com <e-p...@googlegroups.com> *On Behalf
> Of *joliver
> *Sent:* 02 September 2022 22:45
> *To:* E-Prime <e-p...@googlegroups.com>
> *Subject:* Re: Odd Type Mismatch error____
>
> __ __
>
> Update: After a number of changes, for still unclear reasons this is
> now happening /only /with our button box (which is a USB device
> recognized as a keyboard) and not with actual keyboard responses -
> i.e. mashing the 5 key on the keyboard does not cause a crash. Has
> anyone encountered something like this before? ____
>
> On Thursday, September 1, 2022 at 5:20:50 PM UTC-5 joliver wrote:____
>
> Hello,____
>
> Found a bug in one of our tasks that causes a crash when a
> response button is pressed rapidly. We're using sliders
> controlled via task events (button box, but 2 moves down, 4
> moves up and 5 locks in the response). What is odd is that the
> crash only appears to occur during the practice trials in the
> beginning and not during actual event trials.____
>
> __ __
>
> If - immediately prior to the slide presenting - one rapidly
> hits ANY viable response button (2, 4 or 5) it will throw a type
> mismatch at the 3rd line of the following (entire user script
> copied, but the line beginning "If theKeyValue = "2"..." is what
> gets highlighted). I don't understand why a Type Mismatch error
> would occur only in this scenario. My best guess is that it is
> caching button presses and then attempting to implement them
> prior to drawing the slide, but I'd expect a different type of
> error in that scenario and it wouldn't explain why it doesn't
> happen during the primary portion of the task. I can't find any
> obvious way to disable caching responses. Any ideas would be
> greatly appreciated - this one really has me stumped! Happy to
> share any additional task details as needed.____
>
> __ __
>
> __ __
>
> __ __
> End Sub____

McFarlane, David

unread,
Sep 23, 2022, 10:32:20 AM9/23/22
to e-p...@googlegroups.com
Pondering this a bit further ...

I suppose that you use different Slide objects for your practice trials vs. your regular trials. Perhaps something in that difference makes the problem happen only on the practice trials. Try comparing *all* of the properties between those two Slide objects, especially the settings of any Task Events. I might also delete the Slide object from the practice Procedure and then rebuild it from scratch, in case something weird had found its way into that object.

(On a side note in case anyone stumbles on this thread on the web, I see that the careful indentation in my code samples does not appear in the web view, even though it appears fine in my e-mail. Sigh.)

-- David McFarlane

________________________________________
From: e-p...@googlegroups.com <e-p...@googlegroups.com> on behalf of David McFarlane <mcfa...@msu.edu>
Sent: Thursday, September 22, 2022 4:46 PM
To: e-p...@googlegroups.com


Subject: Re: Odd Type Mismatch error

Poking in here ...

Reply all
Reply to author
Forward
0 new messages