myth-hash 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- myth-hash-0.1.0/LICENSE +7 -0
- myth-hash-0.1.0/MANIFEST.in +1 -0
- myth-hash-0.1.0/PKG-INFO +76 -0
- myth-hash-0.1.0/README.md +61 -0
- myth-hash-0.1.0/myth_hash/__init__.py +5 -0
- myth-hash-0.1.0/myth_hash/cli.py +89 -0
- myth-hash-0.1.0/myth_hash/core/__init__.py +13 -0
- myth-hash-0.1.0/myth_hash/core/character_data_loader.py +70 -0
- myth-hash-0.1.0/myth_hash/core/hash_util.py +63 -0
- myth-hash-0.1.0/myth_hash/core/words.py +117 -0
- myth-hash-0.1.0/myth_hash/data/character_nouns.json +1991 -0
- myth-hash-0.1.0/myth_hash/data/personality_attributes.json +3109 -0
- myth-hash-0.1.0/myth_hash/data/physical_attributes.json +3369 -0
- myth-hash-0.1.0/myth_hash.egg-info/PKG-INFO +76 -0
- myth-hash-0.1.0/myth_hash.egg-info/SOURCES.txt +19 -0
- myth-hash-0.1.0/myth_hash.egg-info/dependency_links.txt +1 -0
- myth-hash-0.1.0/myth_hash.egg-info/entry_points.txt +2 -0
- myth-hash-0.1.0/myth_hash.egg-info/top_level.txt +1 -0
- myth-hash-0.1.0/pyproject.toml +0 -0
- myth-hash-0.1.0/setup.cfg +4 -0
- myth-hash-0.1.0/setup.py +33 -0
myth-hash-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2024 Claas Flint
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include myth-hash/data/*.json
|
myth-hash-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: myth-hash
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A tool for generating human-readable, multilingual fantasy character names based on input string hashes.
|
|
5
|
+
Home-page: https://github.com/yourusername/myth_hash
|
|
6
|
+
Author: Claas Flint
|
|
7
|
+
Author-email: claas.flint@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.11
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
|
|
16
|
+
# Myth Hash
|
|
17
|
+
|
|
18
|
+
`Myth Hash` is aPython package designed to create human-readable hashes that are not only functional but also cognitively engaging. A key feature of this tool is its multilingual support, enabling the generation of hashes in multiple languages. The concept behind these human-readable hashes is to enhance communication and recognition by creating hashes that form vivid, memorable mental images. The goal is to make the hash as human-compatible as possible, ensuring it effectively serves its purpose in an intuitive and user-friendly manner.
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Character Name Generation:** Generates a unique fantasy name based on an input string.
|
|
22
|
+
- **Supported Languages:** Currently supports English (`en`) and German (`de`).
|
|
23
|
+
- **CLI Support:** Easily generate names via the command line.
|
|
24
|
+
- **Library Usage:** Integrate `Myth Hash` into your Python projects.
|
|
25
|
+
- **Customizable Data:** Modify the included JSON files to customize the generated names.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
You can install `Myth Hash` using pip:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install myth-hash
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Command Line Interface (CLI)
|
|
38
|
+
|
|
39
|
+
After installing the package, you can use the myth-hash command to generate fantasy names.
|
|
40
|
+
|
|
41
|
+
Basic Example:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
myth-hash "The moon whispered secrets, but only the cats understood."
|
|
45
|
+
```
|
|
46
|
+
Example Output:
|
|
47
|
+
```bash
|
|
48
|
+
exotic-thoughtful-Griffin
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Using as a Library
|
|
52
|
+
|
|
53
|
+
You can also use Myth Hash within your Python code:
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
```python
|
|
57
|
+
import myth_hash
|
|
58
|
+
|
|
59
|
+
# Generate a character name using the hash_name function
|
|
60
|
+
name_parts = myth_hash.hash_name("The moon whispered secrets, but only the cats understood.", "en")
|
|
61
|
+
print(name_parts) # Output: ('exotic', 'thoughtful', 'Griffin')
|
|
62
|
+
|
|
63
|
+
# Access individual parts of the name
|
|
64
|
+
physical_attr, personality_attr, mystical_creature = name_parts
|
|
65
|
+
print(f"Physical Attribute: {physical_attr}")
|
|
66
|
+
print(f"Personality Trait: {personality_attr}")
|
|
67
|
+
print(f"Mystical Creature: {mystical_creature}")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Contributing
|
|
71
|
+
|
|
72
|
+
Contributions are welcome! Please fork the repository, create a new branch for your feature or bug fix, and submit a pull request.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
This project is licensed under the MIT License. See the LICENSE file for details.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Myth Hash
|
|
2
|
+
|
|
3
|
+
`Myth Hash` is aPython package designed to create human-readable hashes that are not only functional but also cognitively engaging. A key feature of this tool is its multilingual support, enabling the generation of hashes in multiple languages. The concept behind these human-readable hashes is to enhance communication and recognition by creating hashes that form vivid, memorable mental images. The goal is to make the hash as human-compatible as possible, ensuring it effectively serves its purpose in an intuitive and user-friendly manner.
|
|
4
|
+
## Features
|
|
5
|
+
|
|
6
|
+
- **Character Name Generation:** Generates a unique fantasy name based on an input string.
|
|
7
|
+
- **Supported Languages:** Currently supports English (`en`) and German (`de`).
|
|
8
|
+
- **CLI Support:** Easily generate names via the command line.
|
|
9
|
+
- **Library Usage:** Integrate `Myth Hash` into your Python projects.
|
|
10
|
+
- **Customizable Data:** Modify the included JSON files to customize the generated names.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
You can install `Myth Hash` using pip:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install myth-hash
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Command Line Interface (CLI)
|
|
23
|
+
|
|
24
|
+
After installing the package, you can use the myth-hash command to generate fantasy names.
|
|
25
|
+
|
|
26
|
+
Basic Example:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
myth-hash "The moon whispered secrets, but only the cats understood."
|
|
30
|
+
```
|
|
31
|
+
Example Output:
|
|
32
|
+
```bash
|
|
33
|
+
exotic-thoughtful-Griffin
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Using as a Library
|
|
37
|
+
|
|
38
|
+
You can also use Myth Hash within your Python code:
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
```python
|
|
42
|
+
import myth_hash
|
|
43
|
+
|
|
44
|
+
# Generate a character name using the hash_name function
|
|
45
|
+
name_parts = myth_hash.hash_name("The moon whispered secrets, but only the cats understood.", "en")
|
|
46
|
+
print(name_parts) # Output: ('exotic', 'thoughtful', 'Griffin')
|
|
47
|
+
|
|
48
|
+
# Access individual parts of the name
|
|
49
|
+
physical_attr, personality_attr, mystical_creature = name_parts
|
|
50
|
+
print(f"Physical Attribute: {physical_attr}")
|
|
51
|
+
print(f"Personality Trait: {personality_attr}")
|
|
52
|
+
print(f"Mystical Creature: {mystical_creature}")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Contributing
|
|
56
|
+
|
|
57
|
+
Contributions are welcome! Please fork the repository, create a new branch for your feature or bug fix, and submit a pull request.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
This project is licensed under the MIT License. See the LICENSE file for details.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from myth_hash import hash_name
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def setup_logging(log_level: str) -> None:
|
|
9
|
+
numeric_level = getattr(logging, log_level.upper(), None)
|
|
10
|
+
if not isinstance(numeric_level, int):
|
|
11
|
+
raise ValueError(f"Invalid log level: {log_level}")
|
|
12
|
+
logging.basicConfig(level=numeric_level)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def hash_name_cli(input_string: str, language: str, output_format: str) -> None:
|
|
16
|
+
try:
|
|
17
|
+
physical_attr, personality_attr, character = hash_name(input_string, language)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
logging.error(f"Failed to generate fantasy name: {e}")
|
|
20
|
+
raise
|
|
21
|
+
|
|
22
|
+
if output_format == "text":
|
|
23
|
+
print(f"{physical_attr}-{personality_attr}-{character.replace(' ', '')}")
|
|
24
|
+
elif output_format == "json":
|
|
25
|
+
output = {
|
|
26
|
+
"physical_attribute": physical_attr,
|
|
27
|
+
"personality_attribute": personality_attr,
|
|
28
|
+
"character": character,
|
|
29
|
+
}
|
|
30
|
+
print(json.dumps(output, ensure_ascii=False))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def parse_arguments() -> argparse.Namespace:
|
|
34
|
+
parser = argparse.ArgumentParser(
|
|
35
|
+
description="Generates a fantasy name consisting of two character attributes and a mythical creature from a hash value of an input string."
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument(
|
|
38
|
+
"input_string",
|
|
39
|
+
type=str,
|
|
40
|
+
help="Input string to hash and generate a fantasy name.",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"-l",
|
|
44
|
+
"--language",
|
|
45
|
+
type=str,
|
|
46
|
+
default="en",
|
|
47
|
+
choices=["en", "de"],
|
|
48
|
+
help="Specify the output language. Supported languages: English (en) and German (de). Default is English.",
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"-f",
|
|
52
|
+
"--format",
|
|
53
|
+
type=str,
|
|
54
|
+
default="text",
|
|
55
|
+
choices=["text", "json"],
|
|
56
|
+
help="Specify the output format. Choose between plain text (text) and JSON (json). Default is text.",
|
|
57
|
+
)
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"--log-level",
|
|
60
|
+
type=str,
|
|
61
|
+
default="INFO",
|
|
62
|
+
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
63
|
+
help="Set the logging level. Default is INFO.",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return parser.parse_args()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def validate_input_string(input_string: str) -> None:
|
|
70
|
+
if not input_string.strip():
|
|
71
|
+
raise ValueError("Input string cannot be empty.")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def main():
|
|
75
|
+
args = parse_arguments()
|
|
76
|
+
|
|
77
|
+
setup_logging(args.log_level)
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
validate_input_string(args.input_string)
|
|
81
|
+
hash_name_cli(args.input_string, args.language, args.format)
|
|
82
|
+
except ValueError as ve:
|
|
83
|
+
logging.error(f"Input validation error: {ve}")
|
|
84
|
+
except Exception as e:
|
|
85
|
+
logging.error(f"An unexpected error occurred: {e}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .character_data_loader import CharacterData, CharacterDataLoader
|
|
2
|
+
from .hash_util import check_language, generate_indices, hash_name
|
|
3
|
+
from .words import CharacterNoun, NominativAdjective
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"CharacterDataLoader",
|
|
7
|
+
"CharacterData",
|
|
8
|
+
"hash_name",
|
|
9
|
+
"generate_indices",
|
|
10
|
+
"check_language",
|
|
11
|
+
"CharacterNoun",
|
|
12
|
+
"NominativAdjective",
|
|
13
|
+
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from .words import CharacterNoun, NominativAdjective
|
|
7
|
+
|
|
8
|
+
BASE_PATH = Path(__file__).parent.parent / "data"
|
|
9
|
+
CHARACTER_NOUNS_FILE = BASE_PATH / "character_nouns.json"
|
|
10
|
+
PHYSICAL_ATTRIBUTES_FILE = BASE_PATH / "physical_attributes.json"
|
|
11
|
+
PERSONALITY_ATTRIBUTES_FILE = BASE_PATH / "personality_attributes.json"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class CharacterData:
|
|
16
|
+
character_nouns: list[CharacterNoun]
|
|
17
|
+
physical_attributes: list[NominativAdjective]
|
|
18
|
+
personality_attributes: list[NominativAdjective]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CharacterDataLoader:
|
|
22
|
+
_instance: Optional["CharacterDataLoader"] = None
|
|
23
|
+
_character_data: CharacterData | None = None
|
|
24
|
+
|
|
25
|
+
def __new__(cls):
|
|
26
|
+
if cls._instance is None:
|
|
27
|
+
cls._instance = super().__new__(cls)
|
|
28
|
+
cls._instance._load_data()
|
|
29
|
+
return cls._instance
|
|
30
|
+
|
|
31
|
+
def _load_data(self) -> None:
|
|
32
|
+
self._character_data = CharacterData(
|
|
33
|
+
character_nouns=self._load_character_nouns(),
|
|
34
|
+
physical_attributes=self._load_attributes(PHYSICAL_ATTRIBUTES_FILE),
|
|
35
|
+
personality_attributes=self._load_attributes(PERSONALITY_ATTRIBUTES_FILE),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def _load_attributes(file_path: Path) -> list[NominativAdjective]:
|
|
40
|
+
try:
|
|
41
|
+
with open(file_path, encoding="utf8") as f:
|
|
42
|
+
json_dict = json.load(f)
|
|
43
|
+
except (FileNotFoundError, json.JSONDecodeError) as e:
|
|
44
|
+
raise RuntimeError(f"Error loading attributes from {file_path}: {e}") from e
|
|
45
|
+
|
|
46
|
+
return [
|
|
47
|
+
NominativAdjective(word_id, data["words"])
|
|
48
|
+
for word_id, data in json_dict.items()
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _load_character_nouns() -> list[CharacterNoun]:
|
|
53
|
+
try:
|
|
54
|
+
with open(CHARACTER_NOUNS_FILE, encoding="utf8") as f:
|
|
55
|
+
json_dict = json.load(f)
|
|
56
|
+
except (FileNotFoundError, json.JSONDecodeError) as e:
|
|
57
|
+
raise RuntimeError(
|
|
58
|
+
f"Error loading character nouns from {CHARACTER_NOUNS_FILE}: {e}"
|
|
59
|
+
) from e
|
|
60
|
+
|
|
61
|
+
return [
|
|
62
|
+
CharacterNoun(char_id, data["data"]) for char_id, data in json_dict.items()
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def character_data(self) -> CharacterData:
|
|
67
|
+
if self._character_data is None:
|
|
68
|
+
self._load_data()
|
|
69
|
+
assert self._character_data is not None
|
|
70
|
+
return self._character_data
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
|
|
3
|
+
from .character_data_loader import CharacterData, CharacterDataLoader
|
|
4
|
+
|
|
5
|
+
SUPPORTED_LANGUAGES = {"en", "de"}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def check_language(language: str) -> None:
|
|
9
|
+
if language not in SUPPORTED_LANGUAGES:
|
|
10
|
+
raise ValueError(
|
|
11
|
+
f"Unsupported language '{language}'. Supported languages are: {', '.join(SUPPORTED_LANGUAGES)}."
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def generate_indices(input_string: str, list_sizes: list[int]) -> list[int]:
|
|
16
|
+
sha256 = hashlib.sha256(input_string.encode())
|
|
17
|
+
d = sha256.digest()
|
|
18
|
+
hash_length = len(d)
|
|
19
|
+
indices = []
|
|
20
|
+
|
|
21
|
+
for i, size in enumerate(list_sizes):
|
|
22
|
+
start = (hash_length // len(list_sizes)) * i
|
|
23
|
+
end = start + (hash_length // len(list_sizes))
|
|
24
|
+
|
|
25
|
+
segment = int.from_bytes(d[start:end], "big")
|
|
26
|
+
|
|
27
|
+
index = segment % size
|
|
28
|
+
indices.append(index)
|
|
29
|
+
|
|
30
|
+
return indices
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def hash_name(input_string: str, language: str = "en") -> tuple[str, str, str]:
|
|
34
|
+
check_language(language)
|
|
35
|
+
|
|
36
|
+
data_loader = CharacterDataLoader()
|
|
37
|
+
character_data: CharacterData = data_loader.character_data
|
|
38
|
+
|
|
39
|
+
indices = generate_indices(
|
|
40
|
+
input_string,
|
|
41
|
+
[
|
|
42
|
+
len(character_data.physical_attributes),
|
|
43
|
+
len(character_data.personality_attributes),
|
|
44
|
+
len(character_data.character_nouns),
|
|
45
|
+
],
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
physical_attr_index = indices[0]
|
|
49
|
+
personality_attr_index = indices[1]
|
|
50
|
+
character_nouns_index = indices[2]
|
|
51
|
+
|
|
52
|
+
character_noun = character_data.character_nouns[character_nouns_index]
|
|
53
|
+
physical_attr = character_data.physical_attributes[physical_attr_index].word(
|
|
54
|
+
language, character_noun.get_attribute(language, "gender")
|
|
55
|
+
)
|
|
56
|
+
personality_attr = character_data.personality_attributes[
|
|
57
|
+
personality_attr_index
|
|
58
|
+
].word(language, character_noun.get_attribute(language, "gender"))
|
|
59
|
+
return (
|
|
60
|
+
physical_attr,
|
|
61
|
+
personality_attr,
|
|
62
|
+
character_noun.get_attribute(language, "word"),
|
|
63
|
+
)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
class NominativAdjective:
|
|
2
|
+
def __init__(self, word_id: int, words: dict) -> None:
|
|
3
|
+
"""
|
|
4
|
+
Constructor for the NominativAdjective class.
|
|
5
|
+
|
|
6
|
+
:param word_id: ID of the adjective
|
|
7
|
+
:param words: A dictionary that contains the words in different languages and genders
|
|
8
|
+
"""
|
|
9
|
+
self.word_id = word_id
|
|
10
|
+
self.validate_words(words)
|
|
11
|
+
self.words = words
|
|
12
|
+
|
|
13
|
+
def __str__(self) -> str:
|
|
14
|
+
return str(
|
|
15
|
+
self.words.get("en", {}).get("neutral", "No neutral English word available")
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def __repr__(self) -> str:
|
|
19
|
+
return f"Adjective: {self.word_id} - {self.words}"
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def validate_words(words: dict):
|
|
23
|
+
"""
|
|
24
|
+
Validates the structure of the words dictionary. The dictionary should contain languages as keys
|
|
25
|
+
and dictionaries as values, with the inner dictionaries having genders as keys and words as values.
|
|
26
|
+
|
|
27
|
+
:param words: Dictionary to validate
|
|
28
|
+
:raises ValueError: If the dictionary structure is invalid
|
|
29
|
+
"""
|
|
30
|
+
for language, genders in words.items():
|
|
31
|
+
if not isinstance(genders, dict):
|
|
32
|
+
raise ValueError(
|
|
33
|
+
f"The value for language '{language}' must be a dictionary."
|
|
34
|
+
)
|
|
35
|
+
for gender in genders:
|
|
36
|
+
if gender not in ["masculine", "feminine", "neutral"]:
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f"Invalid gender '{gender}' for language '{language}'."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def word(self, language: str, gender: str = "neutral") -> str:
|
|
42
|
+
"""
|
|
43
|
+
Returns the word in the specified language and gender.
|
|
44
|
+
|
|
45
|
+
:param language: The language of the word
|
|
46
|
+
:param gender: The gender of the word. Options are "masculine", "feminine", and "neutral".
|
|
47
|
+
If no gender is specified, the neutral word is returned.
|
|
48
|
+
:return: The word in the specified language and gender
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
return str(self.words[language][gender])
|
|
52
|
+
except KeyError as exc:
|
|
53
|
+
raise ValueError(
|
|
54
|
+
f"No word found for the language '{language}' and gender '{gender}'."
|
|
55
|
+
) from exc
|
|
56
|
+
|
|
57
|
+
def set_word(self, language: str, gender: str, word: str) -> None:
|
|
58
|
+
self.words[language][gender] = word
|
|
59
|
+
|
|
60
|
+
def as_json(self) -> dict:
|
|
61
|
+
"""
|
|
62
|
+
Returns a JSON-compatible dictionary that contains the attributes of the adjective.
|
|
63
|
+
|
|
64
|
+
:return: A dictionary that contains the attributes of the adjective
|
|
65
|
+
"""
|
|
66
|
+
return {"id": self.word_id, "words": self.words}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class CharacterNoun:
|
|
70
|
+
def __init__(self, character_id: int, data: dict) -> None:
|
|
71
|
+
"""
|
|
72
|
+
Constructor for the CharacterNoun class.
|
|
73
|
+
|
|
74
|
+
:param character_id: ID of the noun
|
|
75
|
+
:param data: A dictionary containing the word and gender information in different languages
|
|
76
|
+
"""
|
|
77
|
+
self.character_id = character_id
|
|
78
|
+
self.data = data
|
|
79
|
+
|
|
80
|
+
def __str__(self) -> str:
|
|
81
|
+
return self.get_attribute("en", "word")
|
|
82
|
+
|
|
83
|
+
def __repr__(self) -> str:
|
|
84
|
+
return f"CharacterNoun: {self.character_id} - {self.data}"
|
|
85
|
+
|
|
86
|
+
def get_attribute(self, language: str, attribute: str) -> str:
|
|
87
|
+
"""
|
|
88
|
+
Returns the specified attribute in the specified language.
|
|
89
|
+
|
|
90
|
+
:param language: The language of the attribute
|
|
91
|
+
:param attribute: The attribute to get. Options are 'word' and 'gender'.
|
|
92
|
+
:return: The attribute in the specified language
|
|
93
|
+
"""
|
|
94
|
+
try:
|
|
95
|
+
return str(self.data[language][attribute])
|
|
96
|
+
except KeyError as exc:
|
|
97
|
+
raise ValueError(
|
|
98
|
+
f"No {attribute} found for the language '{language}'."
|
|
99
|
+
) from exc
|
|
100
|
+
|
|
101
|
+
def as_json(self) -> dict:
|
|
102
|
+
"""
|
|
103
|
+
Returns a JSON-compatible dictionary that contains the attributes of the noun.
|
|
104
|
+
|
|
105
|
+
:return: A dictionary that contains the attributes of the noun
|
|
106
|
+
"""
|
|
107
|
+
return {"character_id": self.character_id, "data": self.data}
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def from_json(json: dict) -> "CharacterNoun":
|
|
111
|
+
"""
|
|
112
|
+
Returns a CharacterNoun object from a JSON-compatible dictionary.
|
|
113
|
+
|
|
114
|
+
:param json: A JSON-compatible dictionary that contains the attributes of the noun
|
|
115
|
+
:return: A CharacterNoun object
|
|
116
|
+
"""
|
|
117
|
+
return CharacterNoun(json["character_id"], json["data"])
|