Hi,

There’s no need to feel any pain, Scott’s idea to make a front-to-back card for 
this achieves exactly what you want without anyone needing to write any extra 
code.

https://groups.google.com/d/msg/mnemosyne-proj-users/ufnJ81XtH5E/yp3CAAlMAgAJ

Cheers,

Peter

From: [email protected] 
[mailto:[email protected]] On Behalf Of Ernesto Sastre
Sent: 25 June 2016 22:56
To: mnemosyne-proj-users <[email protected]>
Subject: [mnemosyne-proj-users] Re: Multiple Deletions using Cloze Deletion tool


El jueves, 9 de junio de 2016, 11:33:04 (UTC-3), Garret L escribió:
Hi, I'm new to this forum, so this may have already been mentioned, but is 
there a way to make multiple parts of a single card hidden using cloze deletion?

I feel you bro, I was actually looking for the same. I gave a glimpse at 
Peter's cloze.py code, and although it is not that hard to follow I could not 
set my mind to code a new card type class (Multi-cloze deletion class) that 
inherited from the cloze class. I have exams next week and I can't afford to 
spend time on this right now.  I am sure that Peter would be able to perform 
with great ease some modifications to his own cloze.py code to fit your needs. 
There is a function in it that does "create sister cards"; maybe discarding it 
from the code is a first step approach. I will adjunt cloze.py code
#
# cloze.py <[email protected]<mailto:[email protected]>>
#

import re

from mnemosyne.libmnemosyne.translator import _
from mnemosyne.libmnemosyne.card import Card
from mnemosyne.libmnemosyne.plugin import Plugin
from mnemosyne.libmnemosyne.card_type import CardType
from mnemosyne.libmnemosyne.fact_view import FactView

cloze_re = re.compile(r"\[(.+?)\]", re.DOTALL)


class Cloze(CardType):

    """CardType to do cloze deletion on a string, e.g. "The political parties in
    the US are the [democrats] and the [republicans]." would give the following
    cards:

    Q:The political parties in the US are the [...] and the republicans.
    A:democrats

    Q:The political parties in the US are the democrats and the [...].
    A:republicans

    Illustration of a CardType which does not use the traditional FactView
    mechanism.

    This is implemented by creating cards which contain extra_data entries
    "cloze" and "index", containing e.g. "democrats" and 0. Storing both the
    cloze and its index allows us to have enough data to support all possible
    editing operations.

    """

    id = "5"
    name = _("Cloze deletion")

    fact_keys_and_names = [("text", _("Text"))]
    unique_fact_keys = ["text"]
    required_fact_keys = ["text"]

    v = FactView(_("Cloze"), "5.1")
    v.q_fact_keys = ["f"]  # Generated on the fly.
    v.a_fact_keys = ["b"]  # Generated on the fly.
    fact_views = [v]

    def fact_key_format_proxies(self):
        return {"text": "text", "f": "text", "b": "text"}

    def is_fact_data_valid(self, fact_data):
        text = fact_data["text"]
        for f in self.component_manager.all("hook", "preprocess_cloze"):
            text = f.run(text)
        return bool(cloze_re.search(text))

    def _q_a_from_cloze(self, text, index):

        """Auxiliary function used by other card types to return question
        and answer for the cloze with a given index in a text which can have
        the following form:

        La [casa:house] es [grande:big]

        Use 'index=-1' to get the cloze text without brackets and without
        hints.

        """

        for f in self.component_manager.all("hook", "preprocess_cloze"):
            text = f.run(text)
        cursor = 0
        current_index = 0
        question = text
        answer = None
        while True:
            cursor = text.find("[", cursor)
            if cursor == -1:
                break
            cloze = text[cursor + 1:text.find("]", cursor)]
            if ":" in cloze:
                cloze_without_hint, hint = cloze.split(":", 1)
            else:
                cloze_without_hint, hint = cloze, "..."
            if current_index == index:
                question = question.replace(\
                    "[" + cloze + "]", "[" + hint + "]", 1)
                answer = cloze_without_hint
            else:
                question = question.replace(\
                    "[" + cloze + "]", cloze_without_hint, 1)
            cursor += 1
            current_index += 1
        for f in self.component_manager.all("hook", "postprocess_q_a_cloze"):
            question, answer = f.run(question, answer)
        return question, answer

    def fact_data(self, card):
        question, answer = self._q_a_from_cloze\
            (card.fact["text"], card.extra_data["index"])
        return {"f": question, "b": answer}

    def create_sister_cards(self, fact):
        cards = []
        text = fact["text"]
        for f in self.component_manager.all("hook", "preprocess_cloze"):
            text = f.run(text)
        for match in cloze_re.finditer(text):
            card = Card(self, fact, self.fact_views[0])
            card.extra_data["cloze"] = match.group(1)
            card.extra_data["index"] = len(cards)
            cards.append(card)
        return cards

    def _edit_clozes(self, fact, new_fact_data,
                    cloze_fact_key, cloze_fact_view):

        """Auxiliary function used by other card types to when editing clozes.
        Should take into account that not all fact views are cloze-based.

        """

        new_cards, edited_cards, deleted_cards = [], [], []
        old_clozes = cloze_re.findall(fact[cloze_fact_key])
        new_clozes = cloze_re.findall(new_fact_data[cloze_fact_key])
        # If the number of clozes is equal, just edit the existing cards.
        if len(old_clozes) == len(new_clozes):
            for card in self.database().cards_from_fact(fact):
                if "cloze" in card.extra_data:
                    index = card.extra_data["index"]
                    card.extra_data["cloze"] = new_clozes[index]
                edited_cards.append(card)
        # If not, things are a little more complicated.
        else:
            new_clozes_processed = set()
            for card in self.database().cards_from_fact(fact):
                if "cloze" in card.extra_data:
                    old_cloze = card.extra_data["cloze"]
                    index = card.extra_data["index"]
                    if old_cloze in new_clozes:
                        new_index = new_clozes.index(old_cloze)
                        card.extra_data["cloze"] = new_clozes[new_index]
                        card.extra_data["index"] = new_index
                        new_clozes_processed.add(new_clozes[new_index])
                        edited_cards.append(card)
                    else:
                        deleted_cards.append(card)
                else:
                    edited_cards.append(card)
            for new_cloze in set(new_clozes).difference(new_clozes_processed):
                new_index = new_clozes.index(new_cloze)
                card = Card(self, fact, cloze_fact_view)
                card.extra_data["cloze"] = new_cloze
                card.extra_data["index"] = new_index
                new_cards.append(card)
        return new_cards, edited_cards, deleted_cards

    def edit_fact(self, fact, new_fact_data):
        return self._edit_clozes(fact, new_fact_data,
            "text", self.fact_views[0])


class ClozePlugin(Plugin):

    name = _("Cloze deletion")
    description = _("""A card type blanking out certain fragments in a text.\n
E.g., the text \"The capital of [France] is [Paris]\", will give cards with 
questions \"The capital of France is [...].\" and \"The capital of [...] is 
Paris\".\n
Editing the text will automatically update all sister cards.\n\nYou can also 
specify hints, e.g. [cloze:hint] will show
 [hint] in the question as opposed to [...].""")
    components = [Cloze]


Remember to register the plugin adding to the bottom of the code above:
from mnemosyne.libmnemosyne.plugin import register_user_plugin
register_user_plugin(DecoratedVocabularyPlugin)

Regards.
--
You received this message because you are subscribed to the Google Groups 
"mnemosyne-proj-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 
[email protected]<mailto:[email protected]>.
To post to this group, send email to 
[email protected]<mailto:[email protected]>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/mnemosyne-proj-users/d43ce3f8-8a06-4449-b340-319c37777d80%40googlegroups.com<https://groups.google.com/d/msgid/mnemosyne-proj-users/d43ce3f8-8a06-4449-b340-319c37777d80%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"mnemosyne-proj-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/mnemosyne-proj-users/ac601523ee024614b767fe6ca299b100%40xmail102.UGent.be.
For more options, visit https://groups.google.com/d/optout.

Reply via email to