# textcat annotation with diff highlight

**URL:** <https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780>\
**Category:** Uncategorized\
**Tags:** usage, textcat, done, custom, front-end\
**Created:** [April 9, 2020, 8:21am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780 "2020-04-09T08:21:55Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tagucci](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tagucci/32/1324_2.png) [@tagucci](https://support.prodi.gy/u/tagucci)\
**Post date:** [April 9, 2020, 8:21am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/1 "2020-04-09T08:21:55Z")

</div>

Hi,

I'm trying to annotate grammatical error labels with the checking difference between source sentence (error sentence) and target sentence (corrected sentence) like [this](https://prodi.gy/docs/api-interfaces#diff).  
However, commands like below caused error (unrecognized argument).

```python
prodigy textcat.manual grammatical_err dataset.jsonl --label orthography,spelling,verb,form,tense,sva --view-id diff

```

The data format in `dataset.jsonl` is below.

```python
{'accept': {'text': 'This is the test.'},
  'reject': {'text': 'This is a test.'}}

```

How can I solve to annotate text category with diff highlight?

---

<div class="post-metadata">

**Author:** ![ines](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ines/32/3_2.png) [@ines](https://support.prodi.gy/u/ines)\
**Post date:** [April 9, 2020, 8:42am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/2 "2020-04-09T08:42:58Z")

</div>

Hi! The `--view-id` is argument doesn't exist on the `textcat.manual` recipe – [see here](https://prodi.gy/docs/recipes#textcat) for the available arguments.

It sounds like you want to combine the [`diff` interface](https://prodi.gy/docs/api-interfaces#diff) with the [`choice` UI](https://prodi.gy/docs/api-interfaces#choice) for multiple choice options, right? The easiest way to do this would be to use a custom recipe with [`blocks`](https://prodi.gy/docs/api-interfaces#blocks). Check out the docs here for details and examples: [https://prodi.gy/docs/custom-interfaces#blocks](https://prodi.gy/docs/custom-interfaces#blocks) You might also find [my video tutorial](https://prodi.gy/docs/custom-recipes#video-imagecaptioning) helpful.

Your blocks could look like this:

```python
blocks = [{"view_id": "diff"}, {"view_id": "choice"}]

```

And then each record in your data could look like this:

```python
{
    "accept": {"text": "This is the test."},
    "reject": {"text": "This is a test."},
    "options": [
        {"id": "orthography", "text": "orthography"},
        # and so on...
    ]
}

```

---

<div class="post-metadata">

**Author:** ![tagucci](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tagucci/32/1324_2.png) [@tagucci](https://support.prodi.gy/u/tagucci)\
**Post date:** [April 10, 2020, 11:18am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/3 "2020-04-10T11:18:43Z")

</div>

@ines  
Thanks for replying and detailed information!

Following your video tutorial, I wrote custom recipe `recipe.py` as below.

```python
import prodigy
from prodigy.components.loaders import JSONL
from prodigy.util import split_string

@prodigy.recipe(
    "grammar-error",
    dataset=("The dataset to use", "positional", None, str),
    source=("The source data as a JSONL file", "positional", None, str),
    )

def grammar_error(dataset, source):
    stream = JSONL(source)
    blocks = [{"view_id": "diff"}, {"view_id": "choice"}]
    options = [
         {"id": "orthography", "text": "orthography"},
         {"id": "spelling", "text": "spelling"},
         {"id": "verb", "text": "verb"},
         {"id": "form", "text": "form"},
         {"id": "tense", "text": "tese"},
         {"id": "sva", "text": "sva"}
    ]
    return {
        "stream": stream,
        "dataset": dataset,
        "view_id": "blocks",
        "config": {
            "labels": options,
            "blocks": blocks
        }
    }

```

Then, run the below command.

```python
prodigy grammar-error gec dataset.jsonl -F ./recipe.py

```

However, the following message is displayed when I launched the server.

**Oops, something went wrong:(**  
**You might have come across a bug in Prodigy's web app – sorry about that. We'd love to fix this, so feel free to open an issue on the Prodigy Support Forum and include the steps that led to this message.**

How do I fix this error?

---

<div class="post-metadata">

**Author:** ![ines](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ines/32/3_2.png) [@ines](https://support.prodi.gy/u/ines)\
**Post date:** [April 10, 2020, 11:33am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/4 "2020-04-10T11:33:59Z")

</div>

Ah, Prodigy could probably fail more gracefully here. It looks like you forgot to actually add your options to the incoming task at `"options"`? Instead, you're just passing them in as the labels (which are what you'd use as the top-level labels for manual NER or image annotation).

See the docs here for how the options fit in: [https://prodi.gy/docs/custom-recipes#example-choice](https://prodi.gy/docs/custom-recipes#example-choice)  
I'm also showing this in the video starting at ~32:00: [https://youtu.be/zlyq9z7hdUA?t=1920](https://youtu.be/zlyq9z7hdUA?t=1920)

---

<div class="post-metadata">

**Author:** ![tagucci](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tagucci/32/1324_2.png) [@tagucci](https://support.prodi.gy/u/tagucci)\
**Post date:** [April 10, 2020, 1:14pm UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/5 "2020-04-10T13:14:20Z")

</div>

@ines  
Hmm, I fixed to forget "options" in `stream` but it's still something wrong.

```python
import prodigy
from prodigy.components.loaders import JSONL
from prodigy.util import split_string

@prodigy.recipe(
    "grammar-error",
    dataset=("The dataset to use", "positional", None, str),
    source=("The source data as a JSONL file", "positional", None, str),
    )
def grammar_error(dataset, source):
    stream = JSONL(source)
    blocks = [
        {"view_id": "diff"},  
        {"view_id": "choice"},
        ]
    stream = add_options(stream)
    return {
        "stream": stream,
        "dataset": dataset,
        "view_id": "blocks",
        "config": {
            "blocks": blocks,
        }
    }

def add_options(stream):
    options = [
         {"id": "orthography", "text": "orthography"},
         {"id": "spelling", "text": "spelling"},
         {"id": "verb", "text": "verb"},
         {"id": "form", "text": "form"},
         {"id": "tense", "text": "tese"},
         {"id": "sva", "text": "sva"}
    ]
    for task in stream:
        task["options"] = options
        yield task

```

I could launch server successfully when I changed `blocks = [{"view_id": "diff"}, {"view_id": "choice"},]` to blocks = [{"view\_id": "diff"}] although this could show only diff.  
Why do I fail when combining `diff` and `choice`?

---

<div class="post-metadata">

**Author:** ![ines](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ines/32/3_2.png) [@ines](https://support.prodi.gy/u/ines)\
**Post date:** [April 12, 2020, 9:47am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/6 "2020-04-12T09:47:44Z")

</div>

Your recipe looks good. I just had a look and it seems like the combination of `choice` and `diff` is the only one that's currently not possible because they both share and use the `"accept"` key differently. For the `diff` interface, it holds one version of the text, and for the choice interface, it holds the list of accepted options.

I will fix this for the next version and make the `diff` UI also accept a simpler format of maybe `"inserted": "..."` and `"deleted": "..."` so it doesn't clash with any other UI.

---

<div class="post-metadata">

**Author:** ![tagucci](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/tagucci/32/1324_2.png) [@tagucci](https://support.prodi.gy/u/tagucci)\
**Post date:** [April 13, 2020, 12:19am UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/7 "2020-04-13T00:19:24Z")

</div>

@ines  
Thanks! I'm looking forward to use newer prodigy:)

---

<div class="post-metadata">

**Author:** ![ines](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ines/32/3_2.png) [@ines](https://support.prodi.gy/u/ines)\
**Post date:** [June 17, 2020, 4:52pm UTC](https://support.prodi.gy/t/textcat-annotation-with-diff-highlight/2780/8 "2020-06-17T16:52:54Z")

</div>

Just released Prodigy v1.10, which supports a simpler data format for the `diff` interface that doesn't clash with the format of other interfaces like `choice`. [See here](https://prodi.gy/docs/api-interfaces#diff) for details.

> [@rocket Out now: Prodigy v1.10 (plus new video!)](https://support.prodi.gy/t/out-now-prodigy-v1-10-plus-new-video/3030):
>
> Prodigy v1.10 is out now tada And it includes a bunch of cool new features, including dependency and relation annotation, audio and video annotation, an enhanced manual image UI, more settings for NER annotation, including character-based highlighting and a cool example workflow for creating training data for fine-tuning transformer models, new recipe callbacks for validating answers at runtime and for modifying examples before the database, new settings for UI customisation, and lots more! Th…
