# At least one label

**URL:** <https://support.prodi.gy/t/at-least-one-label/2145>\
**Category:** Uncategorized\
**Tags:** usage, textcat, solved\
**Created:** [October 24, 2019, 9:42pm UTC](https://support.prodi.gy/t/at-least-one-label/2145 "2019-10-24T21:42:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yuri](https://avatars.discourse-cdn.com/v4/letter/y/71c47a/32.png) [@Yuri](https://support.prodi.gy/u/Yuri)\
**Post date:** [October 24, 2019, 9:42pm UTC](https://support.prodi.gy/t/at-least-one-label/2145/1 "2019-10-24T21:42:35Z")

</div>

We are annotating texts with multiple non exclusive labels.

1. Is it possible to enforce a human annotator to select at least one label?
2. Alternatively, in the case where no label was selected we want to treat the task as ignored. Is it possible?

---

<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:** [October 25, 2019, 9:14am UTC](https://support.prodi.gy/t/at-least-one-label/2145/2 "2019-10-25T09:14:17Z")

</div>

> [@Yuri](#):
>
> - Is it possible to enforce a human annotator to select at least one label?

Maybe not exactly "force", but you could alert the user if an answer was submitted and no options were selected. For instance, assuming you're using the `choice` interface, you could add JavaScript that looks like this:

```javascript
prodigy.addEventListener('prodigyanswer', event => {
    const selected = event.detail.task.accept || []
    if (!selected.length) {
        alert('Task with no selected options submitted.')
    }
})

```

> [@Yuri](#):
>
> - Alternatively, in the case where no label was selected we want to treat the task as ignored. Is it possible?

Yes, that'd also be possible. After annotation, you could export the data, check for examples that don't have selected options and change the `"answer"` to `"ignore"`. Datasets in Prodigy are append-only (to make sure you can't so easily destroy work), so if you want to keep working with the data in Prodigy, you'd have to import it to a new dataset.

```python
from prodigy.components.db import connect

db = connect()
examples = db.get_dataset("your_dataset")
for eg in examples:
    if not eg.get("accept", []):
        eg["answer"] = "ignore"

db.add_dataset("new_dataset")
db.add_examples(examples, datasets=["new_dataset"])

```

---

<div class="post-metadata">

**Author:** ![Yuri](https://avatars.discourse-cdn.com/v4/letter/y/71c47a/32.png) [@Yuri](https://support.prodi.gy/u/Yuri)\
**Post date:** [October 25, 2019, 2:30pm UTC](https://support.prodi.gy/t/at-least-one-label/2145/3 "2019-10-25T14:30:29Z")

</div>

> [@ines](#):
>
> prodigy.addEventListener('prodigyanswer', event =\> { const selected = event.detail.task.accept || if (!selected.length) { alert('Task with no selected options submitted.') } })

Thank you, how can I involve this piece of code into the "textcat.manual" built-in recipe?

---

<div class="post-metadata">

**Author:** ![Yuri](https://avatars.discourse-cdn.com/v4/letter/y/71c47a/32.png) [@Yuri](https://support.prodi.gy/u/Yuri)\
**Post date:** [October 25, 2019, 2:45pm UTC](https://support.prodi.gy/t/at-least-one-label/2145/4 "2019-10-25T14:45:14Z")

</div>

How accepted annotation task without selected labels can be represented in history by "X" sign (like in ignored annotation case)?  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/prodigy/original/2X/b/b4f3218f3b5b1874cfb211446e38de2a9b62c622.png)

---

<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:** [October 25, 2019, 4:35pm UTC](https://support.prodi.gy/t/at-least-one-label/2145/5 "2019-10-25T16:35:02Z")

</div>

> [@Yuri](#):
>
> Thank you, how can I involve this piece of code into the "textcat.manual" built-in recipe?

You can add it to the `"javascript"` setting in your `prodigy.json`. You probably want to make it `if (!selected.length && window.prodigy.viewId == 'choice')` to only show the alert in the `choice` interface and not everywhere.

The other code snippet I posted is a postprocessing step, so that wouldn't have to go in any recipe.

> [@Yuri](#):
>
> How accepted annotation task without selected labels can be represented in history by "X" sign (like in ignored annotation case)?

The icon here reflects the annotation decision: `"accept"`, `"reject"` or `"ignore"`. So if a task is accepted, it will get the accept icon, and it's not easily possible to show a different icon here. Otherwise, the behaviour would be very inconsistent and confusing.
