Сценарий Python, создающий карточки anki с использованием genanki (ожидаемый экземпляр str, dict found ERROR) - PullRequest
0 голосов
/ 27 июня 2018

Программа берет список английских слов, записанных в первом столбце файла Excel с именем «List», используя pandas , заголовок столбца - «слова», а слова находятся в «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 вещи в мой код выше:

  1. Я определяю my_model в соответствии с предложением genanki и создаю простую модель карточки. Это включает в себя случайное жестко закодированное число (которое требует 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 (...), добавив другое поле, чтобы я мог просто добавить 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, dict found", которая доставляет мне неприятности, однако это мой самый первый проект на Python, и я не программист, поэтому я надеюсь, что кто-то там может помочь мне понять проблему ,

BR

Миккель

1 Ответ

0 голосов
/ 19 июля 2018

всегда проверяйте тип переменной, когда вы ее используете. Из того, что я нашел, использование 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])
...