Haha it is true. It is not worth a new card type at all. Though the code is quite well structured so as to allow creating one clone of cloze deletion with minimal effort I think On Jun 26, 2016 1:15 AM, "Peter Bienstman" <[email protected]> wrote:
> 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]> > > # > > > > 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]. > 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/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 a topic in the > Google Groups "mnemosyne-proj-users" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/mnemosyne-proj-users/ufnJ81XtH5E/unsubscribe > . > To unsubscribe from this group and all its topics, 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 > <https://groups.google.com/d/msgid/mnemosyne-proj-users/ac601523ee024614b767fe6ca299b100%40xmail102.UGent.be?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/CANn16chyHgC8PVRYrohNbXTwOrVBKeaYhg%3DerLNi%3DzB72tbMtQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
