Python脚本使用genanki创建anki抽认卡(预期的str实例,dict发现错误)

时间:2018-06-27 16:54:11

标签: python pandas google-translate anki pydictionary

该程序使用pandas获取在名为“ List”的excel文件的第一列中写入的英语单词的列表,该列的标题为“ words”,这些单词位于“ Sheet1”中。

然后将单词存储为字符串列表。

通过创建 dictionary translator 来使用

PyDictionaryGoogletrans,其中翻译会调用翻译器,以翻译来自列出目标语言“丹麦语”。

然后创建一个简单的for循环,在该循环中,已翻译单词列表中的每个翻译均以其来源->其目的地及其定义进行打印。

这在下面的代码中显示:

from googletrans import Translator
import pandas as pd
from PyDictionary import PyDictionary

# Load excel file and parse the list of words as strings
file_location = "/Users/.../List.xlsx"
xl_workbook = pd.ExcelFile(file_location)
df = xl_workbook.parse("Sheet1")
aList = df['words'].tolist()
[str(i) for i in aList]

# Use PyDictionary to load definitions of words
dictionary = PyDictionary()

# Translate the list of strings into target language and give definitions
translator = Translator()
translations = translator.translate(aList, dest='da')

# Simple for-loop printing the words
for translation in translations:
    print(
        translation.origin, ' -> ', translation.text,
        dictionary.meaning(translation.origin)
    )

该程序实际运行并产生了我希望的结果。但是,该问题会在下一步中发生,如下所述:

我希望将这些单词输入到我最喜欢的闪存卡程序Anki中。 Anki用Python编写,并有一个名为Genanki的非正式发行版。但是,这是我遇到问题的时候。

我现在将以下4件事添加到上面的代码中:

  1. 我定义genanki提出的my_model,并创建一个简单的抽认卡模型。这包括一个随机的硬编码数字(Anki要求),模型名称,一些字段和卡类型的模板。
  2. 我将my_deck定义为带有硬编码随机数和名称的特定卡片集。
  3. 我更改了for循环,现在将翻译和定义直接运行到名为aNote的变量中,该变量由genanki.note运算符组成,每次将翻译添加到my_deck时,都会对翻译进行迭代。
  4. 我写了可以用Anki打开的anki文件。

这可以在下面的代码中看到:

from googletrans import Translator
import pandas as pd
from PyDictionary import PyDictionary
import genanki

# Load excel file and parse the list of words as strings
file_location = "/Users/.../List.xlsx"
xl_workbook = pd.ExcelFile(file_location)
df = xl_workbook.parse("Sheet1")
aList = df['words'].tolist()
[str(i) for i in aList]

# Use PyDictionary to load definitions of words
dictionary = PyDictionary()

# Use genanki to define a flashcard model
my_model = genanki.Model(
    2042686211,
    'Simple Model',
    fields=[
        {'name': 'Question'},
        {'name': 'Answer'},
    ],
    templates=[
        {
            'name': 'Card 1',
            'qfmt': '{{Question}}',
            'afmt': '{{FrontSide}}<hr id="answer">{{Answer}}',
        },
    ])

# Specify the deck with genanki
my_deck = genanki.Deck(
    1724897887,
    'TestV3v1')

# Translate the list of strings with definition and add as note to anki
translator = Translator()

translations = translator.translate(aList, dest='da')
for translation in translations:
    aNote = genanki.Note(
        model=my_model, fields=[translation.origin, translation.text]
    )
    my_deck.add_note(aNote)

# Output anki file in desired folder
genanki.Package(my_deck).write_to_file(
    '/Users/.../TestV3v1.apkg')

此代码也可以很好地执行,并生成一个可以在Anki中打开的文件,然后卡在抽认卡的正面显示原始单词,在背面显示译文。

我的问题

为了完成我的项目,我希望在翻译附带的每张卡片的背面添加一个定义。我最初以为我只需要纠正my_model = genanki.model(...)变量,方法是添加另一个字段,这样我就可以在for循环中将Dictionary。意义(translation.origin)添加到注释生成器中。

但是,当尝试仅添加定义以确保它们平稳运行时,我遇到了问题。考虑下面的代码:

for translation in translations:
    aNote = genanki.Note(
        model=my_model, fields=[translation.origin,
                                dictionary.meaning(translation.origin)
                                ]
    )
    my_deck.add_note(aNote)

我希望卡片能像往常一样打印,正面写上原始单词,背面写上定义,但是使用此for循环运行完整代码会给我带来以下错误:

Error: The Following Error occured: list index out of range
Error: The Following Error occured: list index out of range
Error: The Following Error occured: list index out of range
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: The Following Error occured: list index out of range
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: The Following Error occured: list index out of range
Error: The Following Error occured: list index out of range
Error: The Following Error occured: list index out of range
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: A Term must be only a single word
Error: The Following Error occured: list index out of range
Error: A Term must be only a single word
Error: The Following Error occured: list index out of range
Traceback (most recent call last):
  File "/Users/Lehmann/Desktop/XYZ/Programming/Translator/TranslatorProgramv3.py", line 51, in <module>
    '/Users/Lehmann/Desktop/XYZ/Programming/Translator/TestV3v1.apkg')
  File "/anaconda3/lib/python3.6/site-packages/genanki/__init__.py", line 313, in write_to_file
    self.write_to_db(cursor, now_ts)
  File "/anaconda3/lib/python3.6/site-packages/genanki/__init__.py", line 331, in write_to_db
    deck.write_to_db(cursor, now_ts)
  File "/anaconda3/lib/python3.6/site-packages/genanki/__init__.py", line 267, in write_to_db
    note.write_to_db(cursor, now_ts, self.deck_id)
  File "/anaconda3/lib/python3.6/site-packages/genanki/__init__.py", line 228, in write_to_db
    self._format_fields(),        # flds
  File "/anaconda3/lib/python3.6/site-packages/genanki/__init__.py", line 240, in _format_fields
    return '\x1f'.join(self.fields)
TypeError: sequence item 1: expected str instance, dict found

我怀疑这是“期望的str实例,找到了dict”的部分引起了我的麻烦,但是,这是我的第一个python项目,我不是程序员,因此我希望那里的人可以帮助我理解问题。

BR

米克尔

1 个答案:

答案 0 :(得分:2)

始终确保在使用变量时检查其类型。从我发现的结果来看,使用dictionary。意义(...)将类型更改为dictionary。因此,您所需要做的就是:

meaning=dictionary.meaning(translation.origin)
meaning_to_string=''.join('{}: {}'.format(key,val) for key,val in meaning.items())

#moving to aNote
aNote=genanki.Note(model=my_model, fields=[translation.origin,meaning_to_string])