diff --git a/pynames/fixtures/test_from_list_generator.json b/pynames/fixtures/test_from_list_generator.json index 4c29d59..5688e5f 100644 --- a/pynames/fixtures/test_from_list_generator.json +++ b/pynames/fixtures/test_from_list_generator.json @@ -1,30 +1,25 @@ { - "names": [ {"lang": "ru", - "genders": {"m": {"ru": "ru_m_name_1", + "native_language": "ru", + "names": [ {"genders": {"m": {"ru": "ru_m_name_1", "en": "en_m_name_1"}}}, - {"lang": "ru", - "genders": {"f": {"ru": "ru_f_name_2", + {"genders": {"f": {"ru": "ru_f_name_2", "en": "en_f_name_2"}}}, - {"lang": "ru", - "genders": {"f": {"ru": "ru_f_name_3", + {"genders": {"f": {"ru": "ru_f_name_3", "en": "en_f_name_3"}}}, - {"lang": "ru", - "genders": {"m": {"ru": "ru_m_name_4", + {"genders": {"m": {"ru": "ru_m_name_4", "en": "en_m_name_4"}, "f": {"ru": "ru_f_name_4", "en": "en_f_name_4"}}}, - {"lang": "ru", - "genders": {"m": {"ru": "ru_m_name_5", + {"genders": {"m": {"ru": "ru_m_name_5", "en": "en_m_name_5"}, "f": {"ru": "ru_f_name_5", "en": "en_f_name_5"}}}, - {"lang": "ru", - "genders": {"m": {"ru": "ru_m_name_5", + {"genders": {"m": {"ru": "ru_m_name_5", "en": "en_m_name_5"}, "f": {"ru": "ru_f_name_5", "en": "en_f_name_5"}}} diff --git a/pynames/fixtures/test_from_tables_generator.json b/pynames/fixtures/test_from_tables_generator.json new file mode 100644 index 0000000..7d1d3f4 --- /dev/null +++ b/pynames/fixtures/test_from_tables_generator.json @@ -0,0 +1,25 @@ +{ + "source": "", + "languages": ["ru", "en"], + "native_language": "en", + "templates": { "t1": {"probability": 2, + "genders": ["m"], + "template": ["table1", "table2"]}, + "t2": {"probability": 2, + "genders": ["f"], + "template": ["table1", "table3"]}, + "t3": {"probability": 1, + "genders": ["m", "f"], + "template": ["table1", "table2", "table4", "table3"]}}, + + "tables": { "table1": [{"languages": {"en": "T1EN1", "ru": "T1RU1"}}, + {"languages": {"en": "T1EN2", "ru": "T1RU2"}}, + {"languages": {"en": "T1EN3", "ru": "T1RU3"}}], + + "table2": [{"languages": {"en": "_m_en_1", "ru": "_m_ru_1"}}, + {"languages": {"en": "_m_en_2", "ru": "_m_ru_2"}}], + + "table3": [{"languages": {"en": "_f_en_1", "ru": "_f_ru_1"}}], + + "table4": [{"languages": {"en": "'", "ru": "'"}}]} +} \ No newline at end of file diff --git a/pynames/from_list_generator.py b/pynames/from_list_generator.py new file mode 100644 index 0000000..dcf0211 --- /dev/null +++ b/pynames/from_list_generator.py @@ -0,0 +1,48 @@ +# coding: utf-8 +import json +import random + +from .generators import GENDER, LANGUAGE, Name, BaseGenerator, PynamesException + +class FromListGenerator(BaseGenerator): + + SOURCE = None + + def __init__(self): + self.names_list = [] + self.choices = {} + + if self.SOURCE is None: + error_msg = 'FromListGenerator: you must make subclass of FromListGenerator and define attribute SOURCE in it.' + raise NotImplementedError(error_msg) + + with open(self.SOURCE) as f: + names_data = json.load(f) + for name_data in names_data['names']: + self.names_list.append(Name(names_data['native_language'], name_data)) + + if not self.names_list: + raise PynamesException('FromListGenerator: no names loaded from "%s"' % self.SOURCE) + + def _get_cache_key(self, genders): + return '_'.join(genders) + + def _get_slice(self, genders): + key = self._get_cache_key(genders) + genders = frozenset(genders) + if key not in self.choices: + self.choices[key] = [name_record + for name_record in self.names_list + if name_record.exists_for(genders)] + return self.choices[key] + + def get_names_number(self, genders=GENDER.ALL): + return len(self._get_slice(genders)) + + def get_name(self, genders=GENDER.ALL): + return random.choice(self._get_slice(genders)) + + def get_name_simple(self, gender=GENDER.MALE, language=LANGUAGE.NATIVE): + name = self.get_name(genders=[gender]) + return name.get_for(gender, language) + diff --git a/pynames/from_tables_generator.py b/pynames/from_tables_generator.py new file mode 100644 index 0000000..d5221bf --- /dev/null +++ b/pynames/from_tables_generator.py @@ -0,0 +1,99 @@ +# coding: utf-8 +import json +import random + +from .generators import GENDER, LANGUAGE, Name, BaseGenerator, PynamesException + + +class Template(object): + + __slots__ = ('name', 'probability', 'genders', 'template', 'native_language', 'languages') + + def __init__(self, name, native_language, languages, data): + self.name = name + self.native_language = native_language + self.languages = frozenset(languages) + self.probability = data['probability'] + self.genders = frozenset(data['genders']) + self.template = data['template'] + + def exists_for(self, genders): + return genders & self.genders + + def get_names_number(self, tables): + number = 1 + for slug in self.template: + number *= len(tables[slug]) + return number + + def get_name(self, tables): + languages = dict( (lang, u'') for lang in self.languages) + for slug in self.template: + record = random.choice(tables[slug]) + for lang in languages: + languages[lang] += record['languages'][lang] + genders = dict( (gender, languages) for gender in self.genders) + return Name(self.native_language, {'genders': genders}) + + +class FromTablesGenerator(BaseGenerator): + + SOURCE = None + + def __init__(self): + self.templates_choices = {} + self.templates = [] + self.tables = {} + + if self.SOURCE is None: + error_msg = 'FromTablesGenerator: you must make subclass of FromTablesGenerator and define attribute SOURCE in it.' + raise NotImplementedError(error_msg) + + with open(self.SOURCE) as f: + data = json.load(f) + native_language = data['native_language'] + languages = data['languages'] + self.templates = [ Template(template_name, native_language, languages, template_data) + for template_name, template_data in data['templates'].items() ] + self.tables = data['tables'] + + def _get_templates_cache_key(self, genders): + return 't:%s' % '_'.join(genders) + + def _get_templates_slice(self, genders): + key = self._get_templates_cache_key(genders) + genders = frozenset(genders) + if key not in self.templates_choices: + self.templates_choices[key] = [template + for template in self.templates + if template.exists_for(genders)] + return self.templates_choices[key] + + def _get_names_number_for_template(self): + pass + + + def get_names_number(self, genders=GENDER.ALL): + templates = self._get_templates_slice(genders) + number = sum([template.get_names_number(self.tables) for template in templates]) + return number + + def get_name(self, genders=GENDER.ALL): + templates = self._get_templates_slice(genders) + definition_number = sum([template.probability for template in templates]) + + choice = random.randint(1, definition_number) + + for template in templates: + if choice > template.probability: + choice -= template.probability + continue + return template.get_name(self.tables) + + raise PynamesException('FromTablesGenerator: wrong template structure - cannot choose template for genders %r with template source: "%s"' % (genders, self.SOURCE) ) + + def get_name_simple(self, gender=GENDER.MALE, language=LANGUAGE.NATIVE): + name = self.get_name(genders=[gender]) + return name.get_for(gender, language) + + diff --git a/pynames/generators.py b/pynames/generators.py index 7680692..fac1782 100644 --- a/pynames/generators.py +++ b/pynames/generators.py @@ -1,9 +1,5 @@ # coding: utf-8 -import json -import random - - class PynamesException(Exception): pass @@ -32,8 +28,8 @@ class Name(object): __slots__ = ('genders', 'native_language', 'translations') - def __init__(self, data): - self.native_language = data['lang'] + def __init__(self, native_language, data): + self.native_language = native_language self.genders = frozenset(data['genders'].keys()) self.translations = data['genders'] @@ -55,44 +51,3 @@ class Name(object): def __str__(self): return self.__unicode__() -class FromListGenerator(BaseGenerator): - - SOURCE = None - - def __init__(self): - self.names_list = [] - self.choices = {} - - if self.SOURCE is None: - error_msg = 'FromListGenerator: you must make subclass of FromListGenerator and defined attribute SOURCE in it.' - raise NotImplementedError(error_msg) - - with open(self.SOURCE) as f: - names_data = json.load(f) - for name_data in names_data['names']: - self.names_list.append(Name(name_data)) - - if not self.names_list: - raise PynamesException('FromListGenerator: no names loaded from "%s"' % self.SOURCE) - - def _get_cache_key(self, genders): - return '_'.join(genders) - - def _get_slice(self, genders): - key = self._get_cache_key(genders) - genders = frozenset(genders) - if key not in self.choices: - self.choices[key] = [name_record - for name_record in self.names_list - if name_record.exists_for(genders)] - return self.choices[key] - - def get_names_number(self, genders=GENDER.ALL): - return len(self._get_slice(genders)) - - def get_name(self, genders=GENDER.ALL): - return random.choice(self._get_slice(genders)) - - def get_name_simple(self, gender=GENDER.MALE, language=LANGUAGE.NATIVE): - name = self.get_name(genders=[gender]) - return name.get_for(gender, language) diff --git a/pynames/russian/__init__.py b/pynames/russian/__init__.py index 4d4392f..653b71f 100644 --- a/pynames/russian/__init__.py +++ b/pynames/russian/__init__.py @@ -2,7 +2,7 @@ import os -from ..generators import FromListGenerator +from ..from_list_generator import FromListGenerator FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixtures') diff --git a/pynames/russian/fixtures/pagan_names_list.json b/pynames/russian/fixtures/pagan_names_list.json index 8443a71..b0286d5 100644 --- a/pynames/russian/fixtures/pagan_names_list.json +++ b/pynames/russian/fixtures/pagan_names_list.json @@ -1,189 +1,190 @@ { "source": "http://paganism.msk.ru/name/name.htm", - "names": [ {"lang": "ru", "genders": {"m": {"ru": "Бажен"}, "f": {"ru": "Бажена"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Белослав"}, "f": {"ru": "Белослава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Беримир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Бериславe"}, "f": {"ru": "Берислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Благослав"}, "f": {"ru": "Благослава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Блуд"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Богдан"}, "f": {"ru": "Богдана"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Божко"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Боголюб"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Богомил"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Богумил"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Божидар"}, "f": {"ru": "Божидара"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Болеслав"}, "f": {"ru": "Болеслава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Боримира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Борислав"}, "f": {"ru": "Борислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Борщ"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Боян"}, "f": {"ru": "Бояна"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Братислав"}, "f": {"ru": "Братислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Бронислав"}, "f": {"ru": "Бронислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Брячислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Будимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Велимир"}, "f": {"ru": "Велимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Велимудр"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Велислав"}, "f": {"ru": "Велислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Венцеслав"}, "f": {"ru": "Венцеслава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Вера"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Веселин"}, "f": {"ru": "Веселина"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Весела"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Владимир"}, "f": {"ru": "Владимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Володимир"}, "f": {"ru": "Володимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Владислав"}, "f": {"ru": "Владислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Володислав"}, "f": {"ru": "Володислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Воислав"}, "f": {"ru": "Воислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Волк"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ворон"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Воротислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Всеволод"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Всемил"}, "f": {"ru": "Всемила"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Всеслав"}, "f": {"ru": "Всеслава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Сеслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Вторак"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Вторуша"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Вячеслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Вацслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Вышеслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Годослав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Годлав"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Голуба"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Горазд"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Горислав"}, "f": {"ru": "Горислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Горыня"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Гостемил"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Гостомысл"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Градимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Градислав"}, "f": {"ru": "Градислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Гранислав"}, "f": {"ru": "Гранислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Гремислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Гудислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Дарен"}, "f": {"ru": "Дарена"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Дарина"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Дара"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Девятко"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Доброгнев"}, "f": {"ru": "Доброгнева"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Добролюб"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Добромил"}, "f": {"ru": "Добромила"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Добромир"}, "f": {"ru": "Добромира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Добромысл"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Доброслав"}, "f": {"ru": "Доброслава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Доброжир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Домаслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Драгомир"}, "f": {"ru": "Драгомира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Дубыня"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Дружина"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ёрш"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Жаворонок"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ждан"}, "f": {"ru": "Ждана"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Жизномир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Жировит"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Жирослав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Заяц"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Звенислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Зима"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Златомир"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Златоцвета"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Злоба"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Избыгнев"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Изяслав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Искрен"}, "f": {"ru": "Искра"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Искро"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Истислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Истома"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Казимир"}, "f": {"ru": "Казимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Кощей"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Красимир"}, "f": {"ru": "Красимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Крив"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Лада"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ладимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ладислав"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Лебедь"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Лудислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Лучезар"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Любим"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Любовь"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Любава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Любомила"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Любомир"}, "f": {"ru": "Любомира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Любомысл"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Любослав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Людмил"}, "f": {"ru": "Людмила"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Мал"}, "f": {"ru": "Малуша"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Малой"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Младен"}, "f": {"ru": "Млада"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Мечислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милан"}, "f": {"ru": "Милана"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милен"}, "f": {"ru": "Милена"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Милада"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Милица"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Умила"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милован"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милорад"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Милослав"}, "f": {"ru": "Милослава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Миролюб"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Мирослав"}, "f": {"ru": "Мирослава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Молчан"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Мстислав"}, "f": {"ru": "Мстислава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Надежда"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Надежа"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Невзор"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Некрас"}, "f": {"ru": "Некраса"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Орел"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Осьмой"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Осьмуша"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Передслава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Предслава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Пересвет"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Путимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Путислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Радигост"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Радимир"}, "f": {"ru": "Радимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Радомир"}, "f": {"ru": "Радомира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Радислав"}, "f": {"ru": "Радислава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Радмила"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Радосвета"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Радость"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Рада"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Разумник"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ратибор"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ратмир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Родислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ростислав"}, "f": {"ru": "Ростислава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Сбыслава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Светислав"}, "f": {"ru": "Светислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Светлан"}, "f": {"ru": "Светлана"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Световид"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Свентовид"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Светозар"}, "f": {"ru": "Светозара"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Светлозар"}, "f": {"ru": "Светлозара"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Святогор"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Святополк"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Святослав"}, "f": {"ru": "Святослава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Славомир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Соловей"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Сом"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Снежана"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Станимир"}, "f": {"ru": "Станимира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Станислав"}, "f": {"ru": "Станислава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Стоян"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Судимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Судислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Твердимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Твердислав"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Творимир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Тихомир"}, "f": {"ru": "Тихомира"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Тур"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Храбр"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Часлав"}, "f": {"ru": "Часлава"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Чеслав"}, "f": {"ru": "Чеслава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Чернава"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Чернавка"}}}, - {"lang": "ru", "genders": {"f": {"ru": "Щука"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ярило"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Яромир"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ярополк"}}}, - {"lang": "ru", "genders": {"m": {"ru": "Ярослав"}, "f": {"ru": "Ярослава"}}} + "native_language": "ru", + "names": [ {"genders": {"m": {"ru": "Бажен"}, "f": {"ru": "Бажена"}}}, + {"genders": {"m": {"ru": "Белослав"}, "f": {"ru": "Белослава"}}}, + {"genders": {"m": {"ru": "Беримир"}}}, + {"genders": {"m": {"ru": "Бериславe"}, "f": {"ru": "Берислава"}}}, + {"genders": {"m": {"ru": "Благослав"}, "f": {"ru": "Благослава"}}}, + {"genders": {"m": {"ru": "Блуд"}}}, + {"genders": {"m": {"ru": "Богдан"}, "f": {"ru": "Богдана"}}}, + {"genders": {"m": {"ru": "Божко"}}}, + {"genders": {"m": {"ru": "Боголюб"}}}, + {"genders": {"m": {"ru": "Богомил"}}}, + {"genders": {"m": {"ru": "Богумил"}}}, + {"genders": {"m": {"ru": "Божидар"}, "f": {"ru": "Божидара"}}}, + {"genders": {"m": {"ru": "Болеслав"}, "f": {"ru": "Болеслава"}}}, + {"genders": {"m": {"ru": "Боримира"}}}, + {"genders": {"m": {"ru": "Борислав"}, "f": {"ru": "Борислава"}}}, + {"genders": {"m": {"ru": "Борщ"}}}, + {"genders": {"m": {"ru": "Боян"}, "f": {"ru": "Бояна"}}}, + {"genders": {"m": {"ru": "Братислав"}, "f": {"ru": "Братислава"}}}, + {"genders": {"m": {"ru": "Бронислав"}, "f": {"ru": "Бронислава"}}}, + {"genders": {"m": {"ru": "Брячислав"}}}, + {"genders": {"m": {"ru": "Будимир"}}}, + {"genders": {"m": {"ru": "Велимир"}, "f": {"ru": "Велимира"}}}, + {"genders": {"m": {"ru": "Велимудр"}}}, + {"genders": {"m": {"ru": "Велислав"}, "f": {"ru": "Велислава"}}}, + {"genders": {"m": {"ru": "Венцеслав"}, "f": {"ru": "Венцеслава"}}}, + {"genders": {"f": {"ru": "Вера"}}}, + {"genders": {"m": {"ru": "Веселин"}, "f": {"ru": "Веселина"}}}, + {"genders": {"f": {"ru": "Весела"}}}, + {"genders": {"m": {"ru": "Владимир"}, "f": {"ru": "Владимира"}}}, + {"genders": {"m": {"ru": "Володимир"}, "f": {"ru": "Володимира"}}}, + {"genders": {"m": {"ru": "Владислав"}, "f": {"ru": "Владислава"}}}, + {"genders": {"m": {"ru": "Володислав"}, "f": {"ru": "Володислава"}}}, + {"genders": {"m": {"ru": "Воислав"}, "f": {"ru": "Воислава"}}}, + {"genders": {"m": {"ru": "Волк"}}}, + {"genders": {"m": {"ru": "Ворон"}}}, + {"genders": {"m": {"ru": "Воротислав"}}}, + {"genders": {"m": {"ru": "Всеволод"}}}, + {"genders": {"m": {"ru": "Всемил"}, "f": {"ru": "Всемила"}}}, + {"genders": {"m": {"ru": "Всеслав"}, "f": {"ru": "Всеслава"}}}, + {"genders": {"m": {"ru": "Сеслав"}}}, + {"genders": {"m": {"ru": "Вторак"}}}, + {"genders": {"m": {"ru": "Вторуша"}}}, + {"genders": {"m": {"ru": "Вячеслав"}}}, + {"genders": {"m": {"ru": "Вацслав"}}}, + {"genders": {"m": {"ru": "Вышеслав"}}}, + {"genders": {"m": {"ru": "Годослав"}}}, + {"genders": {"m": {"ru": "Годлав"}}}, + {"genders": {"f": {"ru": "Голуба"}}}, + {"genders": {"m": {"ru": "Горазд"}}}, + {"genders": {"m": {"ru": "Горислав"}, "f": {"ru": "Горислава"}}}, + {"genders": {"m": {"ru": "Горыня"}}}, + {"genders": {"m": {"ru": "Гостемил"}}}, + {"genders": {"m": {"ru": "Гостомысл"}}}, + {"genders": {"m": {"ru": "Градимир"}}}, + {"genders": {"m": {"ru": "Градислав"}, "f": {"ru": "Градислава"}}}, + {"genders": {"m": {"ru": "Гранислав"}, "f": {"ru": "Гранислава"}}}, + {"genders": {"m": {"ru": "Гремислав"}}}, + {"genders": {"m": {"ru": "Гудислав"}}}, + {"genders": {"m": {"ru": "Дарен"}, "f": {"ru": "Дарена"}}}, + {"genders": {"f": {"ru": "Дарина"}}}, + {"genders": {"f": {"ru": "Дара"}}}, + {"genders": {"m": {"ru": "Девятко"}}}, + {"genders": {"m": {"ru": "Доброгнев"}, "f": {"ru": "Доброгнева"}}}, + {"genders": {"m": {"ru": "Добролюб"}}}, + {"genders": {"m": {"ru": "Добромил"}, "f": {"ru": "Добромила"}}}, + {"genders": {"m": {"ru": "Добромир"}, "f": {"ru": "Добромира"}}}, + {"genders": {"m": {"ru": "Добромысл"}}}, + {"genders": {"m": {"ru": "Доброслав"}, "f": {"ru": "Доброслава"}}}, + {"genders": {"m": {"ru": "Доброжир"}}}, + {"genders": {"m": {"ru": "Домаслав"}}}, + {"genders": {"m": {"ru": "Драгомир"}, "f": {"ru": "Драгомира"}}}, + {"genders": {"m": {"ru": "Дубыня"}}}, + {"genders": {"m": {"ru": "Дружина"}}}, + {"genders": {"m": {"ru": "Ёрш"}}}, + {"genders": {"m": {"ru": "Жаворонок"}}}, + {"genders": {"m": {"ru": "Ждан"}, "f": {"ru": "Ждана"}}}, + {"genders": {"m": {"ru": "Жизномир"}}}, + {"genders": {"m": {"ru": "Жировит"}}}, + {"genders": {"m": {"ru": "Жирослав"}}}, + {"genders": {"m": {"ru": "Заяц"}}}, + {"genders": {"f": {"ru": "Звенислава"}}}, + {"genders": {"m": {"ru": "Зима"}}}, + {"genders": {"m": {"ru": "Златомир"}}}, + {"genders": {"f": {"ru": "Златоцвета"}}}, + {"genders": {"m": {"ru": "Злоба"}}}, + {"genders": {"m": {"ru": "Избыгнев"}}}, + {"genders": {"m": {"ru": "Изяслав"}}}, + {"genders": {"m": {"ru": "Искрен"}, "f": {"ru": "Искра"}}}, + {"genders": {"m": {"ru": "Искро"}}}, + {"genders": {"m": {"ru": "Истислав"}}}, + {"genders": {"m": {"ru": "Истома"}}}, + {"genders": {"m": {"ru": "Казимир"}, "f": {"ru": "Казимира"}}}, + {"genders": {"m": {"ru": "Кощей"}}}, + {"genders": {"m": {"ru": "Красимир"}, "f": {"ru": "Красимира"}}}, + {"genders": {"m": {"ru": "Крив"}}}, + {"genders": {"f": {"ru": "Лада"}}}, + {"genders": {"m": {"ru": "Ладимир"}}}, + {"genders": {"m": {"ru": "Ладислав"}}}, + {"genders": {"f": {"ru": "Лебедь"}}}, + {"genders": {"m": {"ru": "Лудислав"}}}, + {"genders": {"m": {"ru": "Лучезар"}}}, + {"genders": {"m": {"ru": "Любим"}}}, + {"genders": {"f": {"ru": "Любовь"}}}, + {"genders": {"f": {"ru": "Любава"}}}, + {"genders": {"f": {"ru": "Любомила"}}}, + {"genders": {"m": {"ru": "Любомир"}, "f": {"ru": "Любомира"}}}, + {"genders": {"m": {"ru": "Любомысл"}}}, + {"genders": {"m": {"ru": "Любослав"}}}, + {"genders": {"m": {"ru": "Людмил"}, "f": {"ru": "Людмила"}}}, + {"genders": {"m": {"ru": "Мал"}, "f": {"ru": "Малуша"}}}, + {"genders": {"m": {"ru": "Малой"}}}, + {"genders": {"m": {"ru": "Младен"}, "f": {"ru": "Млада"}}}, + {"genders": {"m": {"ru": "Мечислав"}}}, + {"genders": {"m": {"ru": "Милан"}, "f": {"ru": "Милана"}}}, + {"genders": {"m": {"ru": "Милен"}, "f": {"ru": "Милена"}}}, + {"genders": {"m": {"ru": "Милава"}}}, + {"genders": {"f": {"ru": "Милада"}}}, + {"genders": {"f": {"ru": "Милица"}}}, + {"genders": {"f": {"ru": "Умила"}}}, + {"genders": {"m": {"ru": "Милован"}}}, + {"genders": {"m": {"ru": "Милорад"}}}, + {"genders": {"m": {"ru": "Милослав"}, "f": {"ru": "Милослава"}}}, + {"genders": {"m": {"ru": "Миролюб"}}}, + {"genders": {"m": {"ru": "Мирослав"}, "f": {"ru": "Мирослава"}}}, + {"genders": {"m": {"ru": "Молчан"}}}, + {"genders": {"m": {"ru": "Мстислав"}, "f": {"ru": "Мстислава"}}}, + {"genders": {"f": {"ru": "Надежда"}}}, + {"genders": {"f": {"ru": "Надежа"}}}, + {"genders": {"m": {"ru": "Невзор"}}}, + {"genders": {"m": {"ru": "Некрас"}, "f": {"ru": "Некраса"}}}, + {"genders": {"m": {"ru": "Орел"}}}, + {"genders": {"m": {"ru": "Осьмой"}}}, + {"genders": {"m": {"ru": "Осьмуша"}}}, + {"genders": {"f": {"ru": "Передслава"}}}, + {"genders": {"f": {"ru": "Предслава"}}}, + {"genders": {"m": {"ru": "Пересвет"}}}, + {"genders": {"m": {"ru": "Путимир"}}}, + {"genders": {"m": {"ru": "Путислав"}}}, + {"genders": {"m": {"ru": "Радигост"}}}, + {"genders": {"m": {"ru": "Радимир"}, "f": {"ru": "Радимира"}}}, + {"genders": {"m": {"ru": "Радомир"}, "f": {"ru": "Радомира"}}}, + {"genders": {"m": {"ru": "Радислав"}, "f": {"ru": "Радислава"}}}, + {"genders": {"f": {"ru": "Радмила"}}}, + {"genders": {"f": {"ru": "Радосвета"}}}, + {"genders": {"f": {"ru": "Радость"}}}, + {"genders": {"f": {"ru": "Рада"}}}, + {"genders": {"m": {"ru": "Разумник"}}}, + {"genders": {"m": {"ru": "Ратибор"}}}, + {"genders": {"m": {"ru": "Ратмир"}}}, + {"genders": {"m": {"ru": "Родислав"}}}, + {"genders": {"m": {"ru": "Ростислав"}, "f": {"ru": "Ростислава"}}}, + {"genders": {"f": {"ru": "Сбыслава"}}}, + {"genders": {"m": {"ru": "Светислав"}, "f": {"ru": "Светислава"}}}, + {"genders": {"m": {"ru": "Светлан"}, "f": {"ru": "Светлана"}}}, + {"genders": {"m": {"ru": "Световид"}}}, + {"genders": {"m": {"ru": "Свентовид"}}}, + {"genders": {"m": {"ru": "Светозар"}, "f": {"ru": "Светозара"}}}, + {"genders": {"m": {"ru": "Светлозар"}, "f": {"ru": "Светлозара"}}}, + {"genders": {"m": {"ru": "Святогор"}}}, + {"genders": {"m": {"ru": "Святополк"}}}, + {"genders": {"m": {"ru": "Святослав"}, "f": {"ru": "Святослава"}}}, + {"genders": {"m": {"ru": "Славомир"}}}, + {"genders": {"m": {"ru": "Соловей"}}}, + {"genders": {"m": {"ru": "Сом"}}}, + {"genders": {"f": {"ru": "Снежана"}}}, + {"genders": {"m": {"ru": "Станимир"}, "f": {"ru": "Станимира"}}}, + {"genders": {"m": {"ru": "Станислав"}, "f": {"ru": "Станислава"}}}, + {"genders": {"m": {"ru": "Стоян"}}}, + {"genders": {"m": {"ru": "Судимир"}}}, + {"genders": {"m": {"ru": "Судислав"}}}, + {"genders": {"m": {"ru": "Твердимир"}}}, + {"genders": {"m": {"ru": "Твердислав"}}}, + {"genders": {"m": {"ru": "Творимир"}}}, + {"genders": {"m": {"ru": "Тихомир"}, "f": {"ru": "Тихомира"}}}, + {"genders": {"m": {"ru": "Тур"}}}, + {"genders": {"m": {"ru": "Храбр"}}}, + {"genders": {"m": {"ru": "Часлав"}, "f": {"ru": "Часлава"}}}, + {"genders": {"m": {"ru": "Чеслав"}, "f": {"ru": "Чеслава"}}}, + {"genders": {"f": {"ru": "Чернава"}}}, + {"genders": {"f": {"ru": "Чернавка"}}}, + {"genders": {"f": {"ru": "Щука"}}}, + {"genders": {"m": {"ru": "Ярило"}}}, + {"genders": {"m": {"ru": "Яромир"}}}, + {"genders": {"m": {"ru": "Ярополк"}}}, + {"genders": {"m": {"ru": "Ярослав"}, "f": {"ru": "Ярослава"}}} ] } \ No newline at end of file diff --git a/pynames/tests.py b/pynames/tests.py index a1dded1..ceb8797 100644 --- a/pynames/tests.py +++ b/pynames/tests.py @@ -3,33 +3,32 @@ import os import unittest -from .generators import Name, GENDER, LANGUAGE, FromListGenerator +from .generators import Name, GENDER, LANGUAGE +from .from_list_generator import FromListGenerator +from .from_tables_generator import FromTablesGenerator FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixtures') class TestName(unittest.TestCase): def test_base(self): - name = Name({'lang': 'ru', - 'genders': {'m': {'ru': 'ru_name'}}}) + name = Name('ru', {'genders': {'m': {'ru': 'ru_name'}}}) self.assertEqual(unicode(name), 'ru_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_name') self.assertEqual(name.get_for(GENDER.MALE), 'ru_name') def test_genders(self): - name = Name({'lang': 'ru', - 'genders': {'m': {'ru': 'ru_m_name'}, - 'f': {'ru': 'ru_f_name'}}}) + name = Name('ru', {'genders': {'m': {'ru': 'ru_m_name'}, + 'f': {'ru': 'ru_f_name'}}}) self.assertEqual(unicode(name), 'ru_m_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name') self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name') def test_languages(self): - name = Name({'lang': 'ru', - 'genders': {'m': {'ru': 'ru_m_name', - 'en': 'en_m_name'}, - 'f': {'ru': 'ru_f_name', - 'en': 'en_f_name'}}}) + name = Name('ru', {'genders': {'m': {'ru': 'ru_m_name', + 'en': 'en_m_name'}, + 'f': {'ru': 'ru_f_name', + 'en': 'en_f_name'}}}) self.assertEqual(unicode(name), 'ru_m_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name') self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name') @@ -85,3 +84,52 @@ class TestFromListGenerator(unittest.TestCase): for i in xrange(100): name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.EN) self.assertTrue(name in self.NAMES_EN_FEMALE) + + +class TestFromTablesGenerator(unittest.TestCase): + + class TestGenerator(FromTablesGenerator): + SOURCE = os.path.join(FIXTURES_DIR, 'test_from_tables_generator.json') + + NAMES_RU_MALE = ["T1RU1_m_ru_1", "T1RU2_m_ru_1", "T1RU3_m_ru_1", "T1RU1_m_ru_2", "T1RU2_m_ru_2", "T1RU3_m_ru_2", "T1RU1_m_ru_1'_f_ru_1", "T1RU2_m_ru_1'_f_ru_1", "T1RU3_m_ru_1'_f_ru_1", "T1RU1_m_ru_2'_f_ru_1", "T1RU2_m_ru_2'_f_ru_1", "T1RU3_m_ru_2'_f_ru_1"] + NAMES_EN_MALE = ["T1EN1_m_en_1", "T1EN2_m_en_1", "T1EN3_m_en_1", "T1EN1_m_en_2", "T1EN2_m_en_2", "T1EN3_m_en_2", "T1EN1_m_en_1'_f_en_1", "T1EN2_m_en_1'_f_en_1", "T1EN3_m_en_1'_f_en_1", "T1EN1_m_en_2'_f_en_1", "T1EN2_m_en_2'_f_en_1", "T1EN3_m_en_2'_f_en_1"] + NAMES_RU_FEMALE = ["T1RU1_f_ru_1", "T1RU2_f_ru_1", "T1RU3_f_ru_1", "T1RU1_m_ru_1'_f_ru_1", "T1RU2_m_ru_1'_f_ru_1", "T1RU3_m_ru_1'_f_ru_1", "T1RU1_m_ru_2'_f_ru_1", "T1RU2_m_ru_2'_f_ru_1", "T1RU3_m_ru_2'_f_ru_1"] + NAMES_EN_FEMALE = ["T1EN1_f_en_1", "T1EN2_f_en_1", "T1EN3_f_en_1", "T1EN1_m_en_1'_f_en_1", "T1EN2_m_en_1'_f_en_1", "T1EN3_m_en_1'_f_en_1", "T1EN1_m_en_2'_f_en_1", "T1EN2_m_en_2'_f_en_1", "T1EN3_m_en_2'_f_en_1"] + + def test_not_derived(self): + self.assertRaises(NotImplementedError, FromTablesGenerator) + + def test_wrong_path(self): + class WrongGenerator(FromTablesGenerator): + SOURCE = '' + self.assertRaises(IOError, WrongGenerator) + + def test_base(self): + generator = self.TestGenerator() + self.assertEqual(generator.get_names_number(), 15) + self.assertTrue(generator.get_name_simple() in self.NAMES_EN_MALE) + + def test_male_female_selection(self): + generator = self.TestGenerator() + self.assertEqual(generator.get_names_number(genders=[GENDER.MALE]), 12) + self.assertEqual(generator.get_names_number(genders=[GENDER.FEMALE]), 9) + self.assertEqual(generator.get_names_number(), 15) + + def test_get_name(self): + generator = self.TestGenerator() + + for i in xrange(100): + name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.RU) + self.assertTrue(name in self.NAMES_RU_MALE) + + for i in xrange(100): + name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.RU) + self.assertTrue(name in self.NAMES_RU_FEMALE) + + for i in xrange(100): + name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.EN) + self.assertTrue(name in self.NAMES_EN_MALE) + + for i in xrange(100): + name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.EN) + self.assertTrue(name in self.NAMES_EN_FEMALE)