Matt Kent
Matt Kent

Reputation: 1185

What's causing this error in my code?

I am making a quiz for my computer science class and the basic concept is that you have 15 keywords and 15 definitions. All need to be randomly displayed and the correct answer has to appear. The user has to match the correct definition to the keyword twice and then that keyword and definition are not displayed again. When all have been answered twice the quiz is over.

I have stored both my keywords and my definitions in the same file so they don't get out of sync. The text file looks like so:

Keyword1,Definition1
Keyword2,Definition2
Keyword3,Definition3
...

The issue I am getting is with two lines in my code. First I shall reference all relevant code to make what I am asking as clear as possible. I have created a class Answer and that looks like this:

Public Class Answer
Public Answer As String
Public Answered As Boolean

End Class My main form form1 looks like this:

Public Class Form1
Const NUMBER_OF_ANSWERS As Integer = 3

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    kv = New Dictionary(Of String, Answer)
    For Each line As String In IO.File.ReadAllLines("C:\Users\Matt\Documents\keywords.txt")
        Dim parts() As String = line.Split(",")
        kv.Add(parts(0), New Answer With {.Answer = parts(1), .Answered = False})
    Next

    Dim r As New Random
    Dim kvRandom As List(Of KeyValuePair(Of String, String)) =
      kv.OrderBy(Function() r.Next).ToList

    'questions will appear in random order
    For Each line As KeyValuePair(Of String, String) In kvRandom
        Dim keyword As String = line.Key
        Dim correctDefinition As String = line.Value

        Dim keywords As New List(Of String)
        keywords.Add(keyword)
        keywords.AddRange(kv.Keys.Except({keyword}).
          OrderBy(Function() r.Next).Take(NUMBER_OF_ANSWERS - 1))

        Dim definitionsRandom As List(Of String) =
          keywords.Select(Function(x) kv(x)).OrderBy(Function() r.Next).ToList

        LabelKeyword.Text = keyword
        RadioButtonDef1.Text = definitionsRandom(0)
        RadioButtonDef2.Text = definitionsRandom(1)
        RadioButtonDef3.Text = definitionsRandom(2)
    Next

End Sub

My error is on the following two lines:

kv.OrderBy(Function() r.Next).ToList which is:

Error 1 Value of type 'System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of String, flashquiz.Answer))' cannot be converted to 'System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of String, String))'. C:\Users\Matt\Desktop\flashquiz\flashquiz\Form1.vb 62 11 flashquiz and

keywords.Select(Function(x) kv(x)).OrderBy(Function() r.Next).ToList which is:

Error 2 Value of type 'System.Collections.Generic.List(Of flashquiz.Answer)' cannot be converted to 'System.Collections.Generic.List(Of String)'. C:\Users\Matt\Desktop\flashquiz\flashquiz\Form1.vb 75 15 flashquiz

I'm not sure what is wrong, so any help will be greatly appreciated. I know that it's to do with the Answer class but not exactly what.

Upvotes: 1

Views: 84

Answers (1)

Steven Doggart
Steven Doggart

Reputation: 43743

The first offending line is here:

Dim kvRandom As List(Of KeyValuePair(Of String, String)) =
  kv.OrderBy(Function() r.Next).ToList

In this line, you are taking all of the items in kv, sorting them randomly, and returning them as a List(Of Answer). You are then trying to assign that list to the kvRandom variable which is declared as List(Of KeyValuePair(Of String, String)). Since those two types are incompatible, it is giving you the error.

To fix it, you need to either change kvRandom to be declared as List(Of Answer), like this:

Dim kvRandom As List(Of Answer) = kv.OrderBy(Function() r.Next).ToList()

Or, you need to add a Select method to convert the items in the list properly, for instance:

Dim kvRandom As List(Of KeyValuePair(Of String, String)) =
    kv.OrderBy(Function() r.Next) _
    .Select(Function(x) New KeyValuePair(Of String, String)(x.Key, x.Value.Answer)) _
    .ToList()

The second offending line is here:

Dim definitionsRandom As List(Of String) =
      keywords.Select(Function(x) kv(x)).OrderBy(Function() r.Next).ToList

The Select method is returning a list of items returned by the lambda expression Function(x) kv(x). Since kv is a Dictionary(Of String, Answer), that means kv(x) will return an Answer object. Therefore, the Select method is returning a list of Answer objects. You are then sorting it in random order and converting it to a List(Of Answer) object. Then you try to assign that to the definitionsRandom variable, which is a List(Of String). Since they are two different incompatible types, it is giving you the error.

To fix it, you need to change your lambda expression in your call to the Select method to return a String rather than an Answer object. For instance:

Dim definitionsRandom As List(Of String) =
      keywords.Select(Function(x) kv(x).Answer).OrderBy(Function() r.Next).ToList

Notice, the lambda expression is returning kv(x).Answer rather than kv(x).

Upvotes: 4

Related Questions