Skip to content

Commit

Permalink
feat: set kanji meaning to incorrect on vocabulary
Browse files Browse the repository at this point in the history
  • Loading branch information
ajite committed Oct 31, 2023
1 parent a820443 commit 4defe2c
Show file tree
Hide file tree
Showing 4 changed files with 281 additions and 1 deletion.
20 changes: 20 additions & 0 deletions hebikani/hebikani.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ def __init__(self, data):
super().__init__(data)
self._readings = None
self._auxiliary_readings = None
self._auxiliary_meanings = None
self._meanings = None
self._meaning_question = Question(self, QuestionType.MEANING)
self._reading_question = None
Expand Down Expand Up @@ -940,6 +941,20 @@ def meanings(self):
)
return self._meanings

@property
def auxiliary_meanings(self):
# Only works for vocabulary. We want to set kanji answer as inexact
if (
self.object == SubjectObject.VOCABULARY
and len(self.characters) == 1
and self._auxiliary_meanings is None
):
component_subject_ids = self.data["data"]["component_subject_ids"]
kanji = Cache.get_subject(component_subject_ids[0])
if kanji:
self._auxiliary_meanings = kanji.meanings
return self._auxiliary_meanings

@property
def reading_question(self):
"""Get the reading question."""
Expand Down Expand Up @@ -1043,6 +1058,11 @@ def solve(self, inputed_answer: str, hard_mode: bool = False) -> AnswerType:
)
else:
_answer = self.subject.meanings.solve(inputed_answer)
if _answer == AnswerType.INCORRECT and self.subject.auxiliary_meanings:
_answer = self.subject.auxiliary_meanings.solve(inputed_answer)
_answer = (
AnswerType.INEXACT if _answer == AnswerType.CORRECT else _answer
)

if _answer == AnswerType.INCORRECT:
self.wrong_answer_count += 1
Expand Down
1 change: 1 addition & 0 deletions hebikani/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class SubjectObject(enumerate):
RADICAL = "radical"
KANJI = "kanji"
VOCABULARY = "vocabulary"
KANA_VOCABULARY = "kana_vocabulary"


class Gender(enumerate):
Expand Down
237 changes: 237 additions & 0 deletions tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,243 @@
],
}

get_subject_fresh_kanji_vocab = {
"object": "collection",
"url": "https://api.wanikani.com/v2/subjects?ids=850%2C2579",
"pages": {"per_page": 1000, "next_url": None, "previous_url": None},
"total_count": 2,
"data_updated_at": "2023-09-20T03:36:15.305537Z",
"data": [
{
"id": 850,
"object": "kanji",
"url": "https://api.wanikani.com/v2/subjects/850",
"data_updated_at": "2023-09-20T03:36:15.305537Z",
"data": {
"created_at": "2012-06-05T23:58:47.796331Z",
"level": 3,
"slug": "生",
"hidden_at": None,
"document_url": "https://www.wanikani.com/kanji/%E7%94%9F",
"characters": "生",
"meanings": [
{"meaning": "Life", "primary": True, "accepted_answer": True}
],
"auxiliary_meanings": [],
"readings": [
{
"type": "onyomi",
"primary": True,
"reading": "せい",
"accepted_answer": True,
},
{
"type": "onyomi",
"primary": True,
"reading": "しょう",
"accepted_answer": True,
},
{
"type": "kunyomi",
"primary": False,
"reading": "い",
"accepted_answer": False,
},
{
"type": "kunyomi",
"primary": False,
"reading": "なま",
"accepted_answer": False,
},
{
"type": "kunyomi",
"primary": False,
"reading": "う",
"accepted_answer": False,
},
{
"type": "kunyomi",
"primary": False,
"reading": "は",
"accepted_answer": False,
},
{
"type": "kunyomi",
"primary": False,
"reading": "き",
"accepted_answer": False,
},
],
"component_subject_ids": [210],
"amalgamation_subject_ids": [
2576,
2577,
2578,
2579,
2653,
2665,
2788,
2916,
3407,
3436,
3449,
3451,
3473,
3715,
3806,
3827,
4059,
4195,
4498,
4659,
4969,
5154,
5326,
5548,
5571,
6225,
6346,
6432,
6471,
6640,
6903,
6980,
7189,
7429,
7500,
7617,
7671,
7731,
7738,
8196,
8668,
8701,
8745,
9141,
],
"visually_similar_subject_ids": [526, 654, 1887, 546, 503, 511],
"meaning_mnemonic": "The <radical>life</radical> radical and the <kanji>life</kanji> kanji are the same, so hopefully you now just know them both.",
"meaning_hint": "Study your radicals and you'll read good.",
"reading_mnemonic": "You can save <kanji>life</kanji> or take it away with your new <reading>sa</reading>ber (<ja>せい</ja>). This is the saber you got from doing the correct thing (remember?), and now you need to figure out how to use it with this life. So what do you do?",
"reading_hint": "Imagine having someone's life in the palm of your hands. It's up to you whether you protect it with your saber or... well... do the other thing sabers are for.",
"lesson_position": 50,
"spaced_repetition_system_id": 1,
},
},
{
"id": 2579,
"object": "vocabulary",
"url": "https://api.wanikani.com/v2/subjects/2579",
"data_updated_at": "2023-09-18T23:37:01.015481Z",
"data": {
"created_at": "2012-02-29T07:50:29.000000Z",
"level": 3,
"slug": "生",
"hidden_at": None,
"document_url": "https://www.wanikani.com/vocabulary/%E7%94%9F",
"characters": "生",
"meanings": [
{"meaning": "Fresh", "primary": True, "accepted_answer": True},
{"meaning": "Raw", "primary": False, "accepted_answer": True},
{"meaning": "Live", "primary": False, "accepted_answer": True},
],
"auxiliary_meanings": [],
"readings": [
{"primary": True, "reading": "なま", "accepted_answer": True}
],
"parts_of_speech": ["noun", "の adjective"],
"component_subject_ids": [850],
"meaning_mnemonic": "Normally a single kanji alone like this would mean the same thing as its parent kanji, but in the case of <kanji>生</kanji> it's a little different (but still related). When you think of something that has life, it's <vocabulary>fresh</vocabulary> or <vocabulary>raw</vocabulary>. Think sashimi or sushi, for example. You want that to be as close as possible to life as you can, so you eat it when it's fresh and raw. This word can also be used to describe a <vocabulary>live</vocabulary> event, like a concert or sporting event. \r\n\r\nYou'll see this word at the beginning of other words. For example, <ja>生たまご</ja> is \"raw egg.\"",
"reading_mnemonic": "This uses one of the kun'yomi readings. Here's a mnemonic to help you remember it:\r\n\r\nAfter eating <vocabulary>raw</vocabulary> fish, my yoga teacher and I say <reading>nama</reading>ste (<ja>なま</ja>) to the sushi chef, bowing low to show our appreciation.",
"context_sentences": [
{"en": "One draft beer, please.", "ja": "生ビール、一つ下さい。"},
{"en": "Are raw peppers tasty?", "ja": "生のパプリカは、おいしいですか?"},
{
"en": "Grandma has seen The Beatles in person.",
"ja": "おばあちゃんはビートルズを生でみたことがある。",
},
],
"pronunciation_audios": [
{
"url": "https://files.wanikani.com/u93fhhk0hyq8ob2e28fz4e1kwknn",
"metadata": {
"gender": "male",
"source_id": 7144,
"pronunciation": "なま",
"voice_actor_id": 2,
"voice_actor_name": "Kenichi",
"voice_description": "Tokyo accent",
},
"content_type": "audio/webm",
},
{
"url": "https://files.wanikani.com/shgr3klx57ehp6x6nltpwwodgi0l",
"metadata": {
"gender": "female",
"source_id": 24080,
"pronunciation": "なま",
"voice_actor_id": 1,
"voice_actor_name": "Kyoko",
"voice_description": "Tokyo accent",
},
"content_type": "audio/webm",
},
{
"url": "https://files.wanikani.com/cx0jxv2xowp0726ahkfgjgj2vrar",
"metadata": {
"gender": "male",
"source_id": 7144,
"pronunciation": "なま",
"voice_actor_id": 2,
"voice_actor_name": "Kenichi",
"voice_description": "Tokyo accent",
},
"content_type": "audio/ogg",
},
{
"url": "https://files.wanikani.com/cew3bcc59rg5h3px9lnm78nph9nf",
"metadata": {
"gender": "male",
"source_id": 7144,
"pronunciation": "なま",
"voice_actor_id": 2,
"voice_actor_name": "Kenichi",
"voice_description": "Tokyo accent",
},
"content_type": "audio/mpeg",
},
{
"url": "https://files.wanikani.com/ppwiwn9q1xc3c9zozrxkox7o06kh",
"metadata": {
"gender": "female",
"source_id": 24080,
"pronunciation": "なま",
"voice_actor_id": 1,
"voice_actor_name": "Kyoko",
"voice_description": "Tokyo accent",
},
"content_type": "audio/mpeg",
},
{
"url": "https://files.wanikani.com/vdvg8qhcg3kwenjensadk3tg392c",
"metadata": {
"gender": "female",
"source_id": 24080,
"pronunciation": "なま",
"voice_actor_id": 1,
"voice_actor_name": "Kyoko",
"voice_description": "Tokyo accent",
},
"content_type": "audio/ogg",
},
],
"lesson_position": 77,
"spaced_repetition_system_id": 1,
},
},
],
}

vocabulary_subject = {
"id": 2467,
"object": "vocabulary",
Expand Down
24 changes: 23 additions & 1 deletion tests/test_hebikani.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
get_specific_subjects_next,
get_updated_subjects,
get_subject_without_utf_entry,
get_subject_fresh_kanji_vocab,
get_summary,
post_review,
vocab_katakana_equals_hiragna_subject,
Expand Down Expand Up @@ -345,8 +346,25 @@ def test_question_answer_values():
assert question.answer_values == "what"


def test_use_kanji_reading_on_vocabulary():
def test_use_kanji_meaning_on_vocabulary():
"""When using the meaning of a kanji in the vocabulary it should return inexact."""
kanji, vocabulary = [Subject(s) for s in get_subject_fresh_kanji_vocab["data"]]
Cache.subjects[kanji.id] = kanji
Cache.subjects[vocabulary.id] = vocabulary
question = Question(vocabulary, QuestionType.MEANING)
assert question.solve("Life") == AnswerType.INEXACT
assert question.solve("Fresh") == AnswerType.CORRECT
assert question.solve("Test") == AnswerType.INCORRECT

question = Question(kanji, QuestionType.MEANING)
assert question.solve("Life") == AnswerType.CORRECT
assert question.solve("Fresh") == AnswerType.INCORRECT
assert question.solve("Test") == AnswerType.INCORRECT
Cache.subjects = {}


def test_use_kanji_reading_on_vocabulary():
"""When using the reading of a kanji in the vocabulary it should return inexact."""
kanji = Subject(subject_water_kanji)
Cache.subjects[kanji.id] = kanji
vocabulary = Subject(subject_water_vocabulary)
Expand All @@ -355,6 +373,7 @@ def test_use_kanji_reading_on_vocabulary():
assert question.solve("すい") == AnswerType.INEXACT
assert question.solve("みず") == AnswerType.CORRECT
assert question.solve("み") == AnswerType.INCORRECT
Cache.subjects = {}


def test_question_primary():
Expand All @@ -369,6 +388,8 @@ def test_question_primary():
def test_card_is_solved():
"""Test the card is solved."""
subject = Subject(vocabulary_subject)
# To avoid making a query online to get the kanji auxiliaries
Cache.subjects[440] = subject
assert subject.solved is False

subject.meaning_question.solve("one")
Expand All @@ -384,6 +405,7 @@ def test_card_is_solved():
subject.reading_question.solve("いち")

assert subject.solved is False
Cache.subjects = {}


def test_hard_mode():
Expand Down

0 comments on commit 4defe2c

Please sign in to comment.