python - 使用 genanki 创建 anki 抽认卡的 Python 脚本(预期 str 实例,dict found ERROR)
问题描述
该程序使用pandas获取写在名为“List”的 Excel 文件的第一列中的英文单词列表,该列的标题为“words”,单词位于“Sheet1”中。
然后将单词存储为字符串列表。
PyDictionary和Googletrans通过创建字典和翻译器来使用,其中翻译器被翻译调用,以便将列表中的单词翻译成目标语言“丹麦语”。
然后创建一个简单的 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 件事:
- 我按照 genanki 的建议定义了 my_model 并创建了一个简单的抽认卡模型。这包括一个随机硬编码数字(Anki 需要)、模型名称、一些字段和卡片类型的模板。
- 我将 my_deck 定义为带有硬编码随机数和名称的特定卡片组。
- 我将我的 for 循环更改为现在将翻译和定义直接运行到名为 aNote 的变量中,该变量由 genanki.note 运算符组成,每次将注释添加到 my_deck 时迭代翻译。
- 我编写了可以用 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(...) 变量,以便我可以将 dictionary.meaning(translation.origin) 添加到 for 循环中的注释生成器.
但是,当尝试仅添加定义以确保它们顺利运行时,我遇到了问题。考虑下面的代码:
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 实例,找到的字典”部分给我带来了麻烦,但是,这是我的第一个 python 项目,我不是程序员,所以我希望有人能帮助我理解这个问题。
BR
米克尔
解决方案
始终确保在使用变量时检查变量的类型。根据我的发现,使用 dictionary.meaning(...) 将类型更改为字典。所以你需要做的就是:
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])
推荐阅读
- c++ - 在 C++ 中的“new”运算符之后使用“realloc”是否安全?
- android - GPIO 值总是在变化
- checkbox - 带有复选框和“a”元素的 ion-item - 单击“a”元素单击整个项目和复选框
- sql - 在 SQL 中选择不在当前表中的数字组合
- javascript - Webcodecamjs-QR 码扫描库在 Safari 浏览器中不起作用
- c# - 使用 Mock 进行单元测试。Parent 没有默认构造函数
- c++ - 性能报告 (.vspx) 未在 Visual Studio 2013 中打开(显示损坏)
- scala - akka http 使用 Json Support 和 xmlsupport
- javascript - 将函数作为参数传递给 array.prototype.filter
- javascript - 向三元语句添加附加条件