/
Suldin_Stanislav
/
Course_project
Обзор
Документация
Войти
/
Suldin_Stanislav
/
Course_project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
generator.py
152 строки
7 KB
Suldin_Stanislav
Create: generator.py
25 июн 2026, 18:28
Верифицирован
25 июн 2026, 18:28
2f7fa88
Код
Авторство
О чём код?
import csv import json import re import random from faker import Faker from datetime import date class TestDataGenerator: """Класс для генерации реалистичных тестовых данных для разных стран.""" def __init__(self, locale='ru_RU'): self.locale = locale self.fake = Faker(locale) self.translit_map = { 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'y', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', 'х': 'h', 'ц': 'ts', 'ч': 'ch', 'ш': 'sh', 'щ': 'sch', 'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya' } self.locale_domains = { 'ru_RU': ['yandex.ru', 'mail.ru', 'rambler.ru', 'list.ru', 'bk.ru'], 'en_US': ['gmail.com', 'yahoo.com', 'outlook.com'], 'en_GB': ['btinternet.com', 'virginmedia.com', 'gmail.com'], 'de_DE': ['t-online.de', 'web.de', 'gmx.de'], 'fr_FR': ['orange.fr', 'sfr.fr', 'free.fr'] } self.country_themes = { 'ru_RU': ['balalaika', 'matryoshka', 'siberia', 'taiga', 'cosmos', 'volga'], 'en_US': ['eagle', 'burger', 'freedom', 'valley', 'canyon', 'jazz'], 'en_GB': ['tea_lover', 'bigben', 'queen', 'foggy', 'bridge', 'pub'], 'de_DE': ['pretzel', 'berlin', 'autobahn', 'forest', 'beer', 'techno'], 'fr_FR': ['croissant', 'paris', 'baguette', 'eiffel', 'cheese', 'wine'] } self.phone_formats = { 'ru_RU': '+7 (9##) ###-##-##', 'en_US': '+1-###-###-####', 'en_GB': '+44 #### ######', 'de_DE': '+49 #### #######', 'fr_FR': '+33 # ## ## ## ##' } self.postcode_patterns = { 'ru_RU': r'^\d{6}$', 'en_US': r'^\d{5}(-\d{4})?$', 'en_GB': r'^[A-Z]{1,2}\d[A-Z\d]? \d[A-Z]{2}$', 'de_DE': r'^\d{5}$', 'fr_FR': r'^\d{5}$' } self.default_domains = ['gmail.com', 'outlook.com'] self.phone_regex = r"^\+7 \(\d{3}\) \d{3}-\d{2}-\d{2}$" self.email_regex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,3}$" def _transliterate(self, text): return "".join(self.translit_map.get(char, char) for char in text.lower()) def generate_phone(self): fmt = self.phone_formats.get(self.locale, '##########') return self.fake.numerify(fmt) def validate_postcode(self, postcode): pattern = self.postcode_patterns.get(self.locale) return bool(re.match(pattern, str(postcode), re.IGNORECASE)) if pattern else True def _validate_email(self, email): return bool(re.match(self.email_regex, email)) def generate_realistic_email(self, first_name, last_name, birth_year=None): domains = self.locale_domains.get(self.locale, self.default_domains) domain = self.fake.random_element(domains) current_year = date.today().year age = current_year - birth_year if birth_year else 25 choice = random.random() if choice < 0.6: f = self._transliterate(first_name) if self.locale.startswith('ru') else first_name.lower() l = self._transliterate(last_name) if self.locale.startswith('ru') else last_name.lower() styles = [f"{f}.{l}", f"{l}_{f}", f"{f}{l}", f"{f[0]}{l}"] email_base = random.choice(styles) elif choice < 0.8: themes = self.country_themes.get(self.locale, ['user', 'cool', 'web']) email_base = f"{random.choice(themes)}_{self.fake.word()}" else: adj = "senior" if age > 50 else ("young" if age < 25 else "pro") email_base = f"{adj}_{self.fake.user_name()}" if birth_year and random.random() > 0.5: suffix = str(birth_year) if random.random() > 0.5 else str(birth_year)[2:] email_base += suffix return f"{email_base}@{domain}" def generate_records(self, count): records = [] for _ in range(count): gender = random.choice(['male', 'female']) if self.locale.startswith('ru'): if gender == 'male': fn, mn, ln = self.fake.first_name_male(), self.fake.middle_name_male(), self.fake.last_name_male() else: fn, mn, ln = self.fake.first_name_female(), self.fake.middle_name_female(), self.fake.last_name_female() full_name = f"{ln} {fn} {mn}" else: fn = self.fake.first_name_male() if gender == 'male' else self.fake.first_name_female() ln = self.fake.last_name() full_name = f"{fn} {ln}" city, street, pc, bld = self.fake.city(), self.fake.street_name(), self.fake.postcode(), self.fake.building_number() dob = self.fake.date_of_birth(minimum_age=18, maximum_age=90) email = self.generate_realistic_email(fn, ln, birth_year=dob.year) phone = self.generate_phone() records.append({ 'name': full_name, 'email': email, 'phone': phone, 'address': f"{pc}, {city}, {street}, {bld}", 'postcode_valid': self.validate_postcode(pc), 'phone_valid': bool(re.match(self.phone_regex, phone)) if self.locale == 'ru_RU' else True, 'email_valid': self._validate_email(email), 'date': dob.strftime('%Y-%m-%d'), 'country': self.locale }) return records def save_to_json(self, data, filename): with open(filename, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=4) def save_to_csv(self, data, filename): if not data: return keys = data[0].keys() with open(filename, 'w', encoding='utf-8-sig', newline='') as f: dict_writer = csv.DictWriter(f, fieldnames=keys) dict_writer.writeheader() dict_writer.writerows(data) def main(): print("--- Генератор тестовых данных ---") locales = {'RU': 'ru_RU', 'US': 'en_US', 'UK': 'en_GB', 'DE': 'de_DE', 'FR': 'fr_FR'} country_choice = input("Выберите код страны (RU/US/UK/DE/FR, по умолчанию RU): ").upper().strip() or 'RU' locale = locales.get(country_choice, 'ru_RU') count_input = input("Количество записей (по умолчанию 5): ").strip() count = int(count_input) if count_input.isdigit() else 5 print("\nДоступные форматы: 1 - JSON, 2 - CSV, 3 - Оба (по умолчанию)") format_choice = input("Выберите формат (1/2/3): ").strip() or '3' generator = TestDataGenerator(locale=locale) data = generator.generate_records(count) if data: print(f"\nСгенерировано {len(data)} записей.") if format_choice in ['1', '3']: generator.save_to_json(data, 'test_data.json') print("Сохранено в test_data.json") if format_choice in ['2', '3']: generator.save_to_csv(data, 'test_data.csv') print("Сохранено в test_data.csv") if __name__ == '__main__': main()