diff --git a/faker/providers/address/de_AT/__init__.py b/faker/providers/address/de_AT/__init__.py index 9d25d21a38..5cd3a94ce8 100644 --- a/faker/providers/address/de_AT/__init__.py +++ b/faker/providers/address/de_AT/__init__.py @@ -249,6 +249,18 @@ class Provider(AddressProvider): "Vorarlberg", ) + municipality_key_formats = ( + "1####", + "2####", + "3####", + "4####", + "5####", + "6####", + "7####", + "8####", + "9####", + ) + def street_suffix_short(self) -> str: return self.random_element(self.street_suffixes_short) diff --git a/faker/providers/automotive/de_AT/__init__.py b/faker/providers/automotive/de_AT/__init__.py new file mode 100644 index 0000000000..184bc148ee --- /dev/null +++ b/faker/providers/automotive/de_AT/__init__.py @@ -0,0 +1,177 @@ +import string + +from .. import Provider as AutomotiveProvider + + +class Provider(AutomotiveProvider): + """Implement automotive provider for ``de_AT`` locale. + + Sources: + + - https://de.wikipedia.org/wiki/Kfz-Kennzeichen_(%C3%96sterreich) + """ + + license_plate_prefix = ( + "A", + "AM", + "B", + "BA", + "BB", + "BD", + "BG", + "BH", + "BK", + "BL", + "BM", + "BN", + "BP", + "BR", + "BZ", + "DL", + "DO", + "E", + "EF", + "EU", + "FB", + "FE", + "FF", + "FK", + "FR", + "FV", + "FW", + "G", + "GB", + "GD", + "GF", + "GK", + "GM", + "GR", + "GS", + "GU", + "HA", + "HB", + "HE", + "HF", + "HL", + "HO", + "I", + "IL", + "IM", + "JE", + "JO", + "JU", + "JW", + "K", + "KB", + "KD", + "KF", + "KG", + "KI", + "KK", + "KL", + "KO", + "KR", + "KS", + "KU", + "L", + "LA", + "LB", + "LD", + "LE", + "LF", + "LI", + "LK", + "LL", + "LN", + "LZ", + "MA", + "MD", + "ME", + "MI", + "MT", + "MU", + "MZ", + "N", + "ND", + "NK", + "O", + "OP", + "OW", + "P", + "PE", + "PL", + "PT", + "RA", + "RE", + "RI", + "RO", + "S", + "SB", + "SD", + "SE", + "SK", + "SL", + "SO", + "SP", + "SR", + "ST", + "SV", + "SW", + "SZ", + "T", + "TA", + "TD", + "TK", + "TU", + "UU", + "V", + "VB", + "VD", + "VI", + "VK", + "VL", + "VO", + "W", + "WB", + "WD", + "WE", + "WK", + "WL", + "WN", + "WO", + "WT", + "WU", + "WY", + "WZ", + "ZE", + "ZT", + "ZW", + ) + + license_plate_suffix_for_one_starting_letter = ("-%# ???", "-%## ???", "-%## ??", "-%### ??", "-%### ?", "-%#### ?") + + license_plate_suffix_for_two_starting_letters = ( + "-% ???", + "-%# ???", + "-%# ??", + "-%## ??", + "-%## ?", + "-%### ?", + ) + + def license_plate(self) -> str: + """Generate a license plate.""" + prefix: str = self.random_element(self.license_plate_prefix) + + if len(prefix) == 1: + suffix = self.bothify( + self.random_element(self.license_plate_suffix_for_one_starting_letter), + letters=string.ascii_uppercase, + ) + else: + suffix = self.bothify( + self.random_element(self.license_plate_suffix_for_two_starting_letters), + letters=string.ascii_uppercase, + ) + + return prefix + suffix diff --git a/faker/providers/color/de/__init__.py b/faker/providers/color/de/__init__.py new file mode 100644 index 0000000000..b56a8dfc1c --- /dev/null +++ b/faker/providers/color/de/__init__.py @@ -0,0 +1,156 @@ +from collections import OrderedDict + +from .. import Provider as ColorProvider + +localized = True + + +class Provider(ColorProvider): + """ + Color provider for ``de`` locale. Source: https://www.sttmedia.com/colornames + """ + + all_colors: OrderedDict[str, str] = OrderedDict( + ( + ("Eisfarben", "#F0F8FF"), + ("Antikweiß", "#FAEBD7"), + ("Wasser", "#00FFFF"), + ("Aquamarinblau", "#7FFFD4"), + ("Azur", "#F0FFFF"), + ("Beige", "#F5F5DC"), + ("Biskuit", "#FFE4C4"), + ("Schwarz", "#000000"), + ("Mandelweiß", "#FFEBCD"), + ("Blau", "#0000FF"), + ("Blauviolett", "#8A2BE2"), + ("Braun", "#A52A2A"), + ("Gelbbraun", "#DEB887"), + ("Kadettenblau", "#5F9EA0"), + ("Hellgrün", "#7FFF00"), + ("Schokolade", "#D2691E"), + ("Koralle", "#FF7F50"), + ("Kornblumenblau", "#6495ED"), + ("Mais", "#FFF8DC"), + ("Karminrot", "#DC143C"), + ("Cyan", "#00FFFF"), + ("Dunkelblau", "#00008B"), + ("Dunkelcyan", "#008B8B"), + ("Dunkle Goldrutenfarbe", "#B8860B"), + ("Dunkelgrau", "#A9A9A9"), + ("Dunkelgrün", "#006400"), + ("Dunkelkhaki", "#BDB76B"), + ("Dunkelmagenta", "#8B008B"), + ("Dunkles Olivgrün", "#556B2F"), + ("Dunkles Orange", "#FF8C00"), + ("Dunkle Orchidee", "#9932CC"), + ("Dunkelrot", "#8B0000"), + ("Dunkle Lachsfarbe", "#E9967A"), + ("Dunkles Seegrün", "#8FBC8F"), + ("Dunkles Schieferblau", "#483D8B"), + ("Dunkles Schiefergrau", "#2F4F4F"), + ("Dunkeltürkis", "#00CED1"), + ("Dunkelviolett", "#9400D3"), + ("Tiefrosa", "#FF1493"), + ("Tiefes Himmelblau", "#00BFFF"), + ("Trübes Grau", "#696969"), + ("Persenningblau", "#1E90FF"), + ("Backstein", "#B22222"), + ("Blütenweiß", "#FFFAF0"), + ("Waldgrün", "#228B22"), + ("Fuchsia", "#FF00FF"), + ("Gainsboro", "#DCDCDC"), + ("Geisterweiß", "#F8F8FF"), + ("Gold", "#FFD700"), + ("Goldrute", "#DAA520"), + ("Grau", "#808080"), + ("Grün", "#008000"), + ("Grüngelb", "#ADFF2F"), + ("Honigmelone", "#F0FFF0"), + ("Leuchtendes Rosa", "#FF69B4"), + ("Indischrot", "#CD5C5C"), + ("Indigo", "#4B0082"), + ("Elfenbein", "#FFFFF0"), + ("Khaki", "#F0E68C"), + ("Lavendel", "#E6E6FA"), + ("Lavendelrosa", "#FFF0F5"), + ("Rasengrün", "#7CFC00"), + ("Chiffongelb", "#FFFACD"), + ("Hellblau", "#ADD8E6"), + ("Helles Korallenrot", "#F08080"), + ("Helles Cyan", "#E0FFFF"), + ("Helles Goldrutengelb", "#FAFAD2"), + ("Hellgrau", "#D3D3D3"), + ("Hellgrün", "#90EE90"), + ("Hellrosa", "#FFB6C1"), + ("Helle Lachsfarbe", "#FFA07A"), + ("Helles Seegrün", "#20B2AA"), + ("Helles Himmelblau", "#87CEFA"), + ("Helles Schiefergrau", "#778899"), + ("Helles Stahlblau", "#B0C4DE"), + ("Hellgelb", "#FFFFE0"), + ("Limone", "#00FF00"), + ("Limonengrün", "#32CD32"), + ("Leinen", "#FAF0E6"), + ("Magenta", "#FF00FF"), + ("Kastanie", "#800000"), + ("Mittleres Aquamarin", "#66CDAA"), + ("Mittleres Blau", "#0000CD"), + ("Mittlere Orchidee", "#BA55D3"), + ("Mittleres Violett", "#9370DB"), + ("Mittleres Seegrün", "#3CB371"), + ("Mittleres Schieferblau", "#7B68EE"), + ("Mittleres Frühlingsgrün", "#00FA9A"), + ("Mittleres Türkis", "#48D1CC"), + ("Mittleres Violettrot", "#C71585"), + ("Mitternachtsblau", "#191970"), + ("Minzcreme", "#F5FFFA"), + ("Altrosa", "#FFE4E1"), + ("Mokassin", "#FFE4B5"), + ("Navajoweiß", "#FFDEAD"), + ("Marineblau", "#000080"), + ("Alte Spitze", "#FDF5E6"), + ("Olivgrün", "#808000"), + ("Olivgraubraun", "#6B8E23"), + ("Orange", "#FFA500"), + ("Orangerot", "#FF4500"), + ("Orchidee", "#DA70D6"), + ("Blasse Goldrutenfarbe", "#EEE8AA"), + ("Blassgrün", "#98FB98"), + ("Blasstürkis", "#AFEEEE"), + ("Blasses Violetrot", "#DB7093"), + ("Papayacreme", "#FFEFD5"), + ("Pfirsich", "#FFDAB9"), + ("Peru", "#CD853F"), + ("Rosa", "#FFC0CB"), + ("Pflaume", "#DDA0DD"), + ("Taubenblau", "#B0E0E6"), + ("Lila", "#800080"), + ("Rot", "#FF0000"), + ("Rosiges Braun", "#BC8F8F"), + ("Königsblau", "#4169E1"), + ("Sattelbraun", "#8B4513"), + ("Lachsfarben", "#FA8072"), + ("Sandbraun", "#F4A460"), + ("Seegrün", "#2E8B57"), + ("Muschelfarben", "#FFF5EE"), + ("Siennaerde", "#A0522D"), + ("Silber", "#C0C0C0"), + ("Himmelblau", "#87CEEB"), + ("Schieferblau", "#6A5ACD"), + ("Schiefergrau", "#708090"), + ("Schneeweiß", "#FFFAFA"), + ("Frühlingsgrün", "#00FF7F"), + ("Stahlblau", "#4682B4"), + ("Hautfarben", "#D2B48C"), + ("Petrol", "#008080"), + ("Distel", "#D8BFD8"), + ("Tomatenrot", "#FF6347"), + ("Türkis", "#40E0D0"), + ("Violett", "#EE82EE"), + ("Weizen", "#F5DEB3"), + ("Weiß", "#FFFFFF"), + ("Rauchfarben", "#F5F5F5"), + ("Gelb", "#FFFF00"), + ("Gelbgrün", "#9ACD32"), + ) + ) diff --git a/faker/providers/color/de_AT/__init__.py b/faker/providers/color/de_AT/__init__.py new file mode 100644 index 0000000000..172beb7e30 --- /dev/null +++ b/faker/providers/color/de_AT/__init__.py @@ -0,0 +1,5 @@ +from ..de import Provider as BaseProvider + + +class Provider(BaseProvider): + pass diff --git a/faker/providers/color/de_CH/__init__.py b/faker/providers/color/de_CH/__init__.py new file mode 100644 index 0000000000..0727fcfa1c --- /dev/null +++ b/faker/providers/color/de_CH/__init__.py @@ -0,0 +1,9 @@ +from collections import OrderedDict + +from ..de import Provider as BaseProvider + + +class Provider(BaseProvider): + all_colors: OrderedDict[str, str] = OrderedDict( + (color_name.replace("ß", "ss"), color_hexcode) for color_name, color_hexcode in BaseProvider.all_colors.items() + ) diff --git a/faker/providers/color/de_DE/__init__.py b/faker/providers/color/de_DE/__init__.py new file mode 100644 index 0000000000..172beb7e30 --- /dev/null +++ b/faker/providers/color/de_DE/__init__.py @@ -0,0 +1,5 @@ +from ..de import Provider as BaseProvider + + +class Provider(BaseProvider): + pass diff --git a/faker/providers/company/de_AT/__init__.py b/faker/providers/company/de_AT/__init__.py new file mode 100644 index 0000000000..076c6b2ffd --- /dev/null +++ b/faker/providers/company/de_AT/__init__.py @@ -0,0 +1,26 @@ +from .. import Provider as CompanyProvider + + +class Provider(CompanyProvider): + # Source: https://www.wko.at/wirtschaftsrecht/gesellschaftsformen-oesterreich + + formats = ( + "{{last_name}} {{company_suffix}}", + "{{last_name}} {{last_name}} {{company_suffix}}", + "{{last_name}} & {{last_name}} {{company_suffix}}", + ) + + company_suffixes = ( + "AG", + "AG", + "AG", + "GesbR", + "GmbH", + "GmbH", + "GmbH", + "KG", + "KG", + "KG", + "OG", + "e.V.", + ) diff --git a/faker/providers/company/de_CH/__init__.py b/faker/providers/company/de_CH/__init__.py new file mode 100644 index 0000000000..13ea35d8fe --- /dev/null +++ b/faker/providers/company/de_CH/__init__.py @@ -0,0 +1,23 @@ +from .. import Provider as CompanyProvider + + +class Provider(CompanyProvider): + # Source: https://de.wikipedia.org/wiki/Firma#Schweizerisches_Recht + + formats = ( + "{{last_name}} {{company_suffix}}", + "{{last_name}} {{last_name}} {{company_suffix}}", + ) + + company_suffixes = ( + "AG", + "AG", + "AG", + "GmbH", + "GmbH", + "GmbH", + "& Co.", + "& Partner", + "& Cie.", + "& Söhne", + ) diff --git a/faker/providers/currency/de/__init__.py b/faker/providers/currency/de/__init__.py new file mode 100644 index 0000000000..2dcfab4ecc --- /dev/null +++ b/faker/providers/currency/de/__init__.py @@ -0,0 +1,174 @@ +from typing import Tuple + +from .. import ElementsType +from .. import Provider as CurrencyProvider + + +class Provider(CurrencyProvider): + # source: https://www.laenderdaten.info/waehrungen/ + + currencies: ElementsType[Tuple[str, str]] = ( + ("AED", "Arabische Dirham"), + ("AFN", "Afghani"), + ("ALL", "Albanische Lek"), + ("AMD", "Armenische Dram"), + ("ANG", "Antillen Gulden"), + ("AOA", "Angolanische Kwanza"), + ("ARS", "Argentinische Peso"), + ("AUD", "Australische Dollar"), + ("AWG", "Aruba Florin"), + ("AZN", "Aserbaidschanische Manat"), + ("BAM", "Konvertible Mark"), + ("BBD", "Barbados Dollar"), + ("BDT", "Bangladeschische Taka"), + ("BGN", "Bulgarische Lew"), + ("BHD", "Bahrainische Dinar"), + ("BIF", "Burundische Franc"), + ("BMD", "Bermudische Dollar"), + ("BND", "Brunei Dollar"), + ("BOB", "Boliviano"), + ("BRL", "Brasilianische Real"), + ("BSD", "Bahamas Dollar"), + ("BTN", "Bhutanisches Ngultrum"), + ("BWP", "Botswanische Pula"), + ("BYR", "Belarussische Rubel"), + ("BZD", "Belize Dollar"), + ("CAD", "Kanadische Dollar"), + ("CDF", "Kongolesische Franc"), + ("CHF", "Schweizer Franken"), + ("CLP", "Chilenische Peso"), + ("CNY", "Renminbi Yuán"), + ("COP", "Kolumbische Peso"), + ("CRC", "Costa-Rica Colón"), + ("CUC", "Cuba Peso Convertible"), + ("CUP", "Kubanische Peso"), + ("CVE", "Cap Verdische Escudo"), + ("CZK", "Tschechische Krone"), + ("DJF", "Dschibuti Franc"), + ("DKK", "Dänische Krone"), + ("DOP", "Dominikanische Peso"), + ("DZD", "Algerische Dinar"), + ("EGP", "Ägyptische Pfund"), + ("ERN", "Eritreische Nakfa"), + ("ETB", "Äthiopische Birr"), + ("EUR", "Euro"), + ("FJD", "Fidschi Dollar"), + ("FKP", "Falkländische Pfund"), + ("GBP", "Sterling Pfund"), + ("GEL", "Georgische Lari"), + ("GGP", "Guernsey Pfund"), + ("GHS", "Ghanaische Cedi"), + ("GIP", "Gibraltar Pfund"), + ("GMD", "Gambische Dalasi"), + ("GNF", "Guinea Franc"), + ("GTQ", "Guatemaltekischer Quetzal"), + ("GYD", "Guyana Dollar"), + ("HKD", "Hongkong Dollar"), + ("HNL", "Honduranische Lempira"), + ("HRK", "Kroatische Kuna"), + ("HTG", "Haitianische Gourde"), + ("HUF", "Ungarische Forint"), + ("IDR", "Indonesische Rupiah"), + ("ILS", "Israelische Schekel"), + ("NIS", "Israelische Schekel"), + ("IMP", "Isle-of-Man Pfund"), + ("INR", "Indische Rupie"), + ("IQD", "Irakische Dinar"), + ("IRR", "Iranische Rial"), + ("ISK", "Isländische Krone"), + ("JEP", "Jersey Pfund"), + ("JMD", "Jamaikanische Dollar"), + ("JOD", "Jordanische Dinar"), + ("JPY", "Japanische Yen"), + ("KES", "Kenianische Schilling"), + ("KGS", "Kirgisische Som"), + ("KHR", "Kambodschanische Riel"), + ("KMF", "Komorische Franc"), + ("KPW", "Nordkoreanische Won"), + ("KRW", "Südkoreanische Won"), + ("KWD", "Kuwaitische Dinar"), + ("KYD", "Cayman Dollar"), + ("KZT", "Kasachische Tenge"), + ("LAK", "Laotische Kip"), + ("LBP", "Libanesische Pfund"), + ("LKR", "Sri Lanka Rupie"), + ("LRD", "Liberianische Dollar"), + ("LSL", "Lesothische Loti"), + ("LYD", "Libysche Dinar"), + ("MAD", "Marokkanische Dirham"), + ("MDL", "Moldauische Leu"), + ("MGA", "Madagassische Ariary"), + ("MKD", "Mazedonische Denar"), + ("MMK", "Burmesische Kyat"), + ("MNT", "Mongolische Tögrög"), + ("MOP", "Macau Pataca"), + ("MRO", "Mauretanische Ouguiya"), + ("MUR", "Mauritius Rupie"), + ("MVR", "Maledivische Rufiyaa"), + ("MWK", "Malawische Kwacha"), + ("MXN", "Mexikanische Peso"), + ("MYR", "Malaysische Ringgit"), + ("MZN", "Mosambikanische Metical"), + ("NAD", "Namibische Dollar"), + ("NGN", "Nigerianische Naira"), + ("NIO", "Nicaraguanische Córdoba Oro"), + ("NOK", "Norwegische Krone"), + ("NPR", "Nepalesische Rupie"), + ("NZD", "Neuseeländische Dollar"), + ("OMR", "Omanische Rial"), + ("PAB", "Panamaische Balboa"), + ("PEN", "Peruanische Sol"), + ("PGK", "Papua-neuguineische Kina"), + ("PHP", "Philippinische Peso"), + ("PKR", "Pakistanische Rupie"), + ("PLN", "Polnische Złoty"), + ("PYG", "Paraguayische Guaraní"), + ("QAR", "Qatar Riyal"), + ("RON", "Rumänische Leu"), + ("RSD", "Serbische Dinar"), + ("RUB", "Russische Rubel"), + ("RWF", "Ruandische Franc"), + ("SAR", "Saudische Riyal"), + ("SBD", "Salomonische Dollar"), + ("SCR", "Seychellen Rupie"), + ("SDG", "Sudanesische Pfund"), + ("SEK", "Schwedische Krone"), + ("SGD", "Singapur Dollar"), + ("SHP", "St.-Helena Pfund"), + ("SLL", "Sierra-leonische Leone"), + ("SOS", "Somalische Schilling"), + ("SPL", "Seborga Luigini"), + ("SRD", "Surinamische Dollar"), + ("STD", "São-toméische Dobra"), + ("SVC", "El-Salvador-Colón"), + ("SYP", "Syrische Pfund"), + ("SZL", "Swazi Lilangeni"), + ("THB", "Thailändische Baht"), + ("TJS", "Tadschikische Somoni"), + ("TMT", "Turkmenische Manat"), + ("TND", "Tunesische Dinar"), + ("TOP", "Tongaische Pa'anga"), + ("TRY", "Türkische Lira"), + ("TTD", "Trinidad und Tobago Dollar"), + ("TVD", "Tuvalu Dollar"), + ("TWD", "Neu Taiwanesische Dollar"), + ("TZS", "Tansanische Schilling"), + ("UAH", "Ukrainische Hrywnja"), + ("UGX", "Ugandische Schilling"), + ("USD", "Amerikanische Dollar"), + ("UYU", "Uruguayische Peso"), + ("UZS", "Uzbekische So'm"), + ("VEF", "Venezuelanische Bolívar"), + ("VND", "Vietnamesischer Dong"), + ("VUV", "Vanuatuische Vatu"), + ("WST", "Samoanische Tala"), + ("XAF", "Zentralafrikanische CFA-Franc"), + ("XCD", "Ostkaribische Dollar"), + ("XDR", "Sonderziehungsrecht"), + ("XOF", "Westafrikanische CFA-Franc"), + ("XPF", "Pazifische Franc"), + ("YER", "Jemenitische Rial"), + ("ZAR", "Südafrikanische Rand"), + ("ZMW", "Sambische Kwacha"), + ("ZWD", "Simbabwe Dollar"), + ) diff --git a/faker/providers/currency/de_AT/__init__.py b/faker/providers/currency/de_AT/__init__.py index 02376404ab..0371f9d67c 100644 --- a/faker/providers/currency/de_AT/__init__.py +++ b/faker/providers/currency/de_AT/__init__.py @@ -1,4 +1,4 @@ -from .. import Provider as CurrencyProvider +from ..de import Provider as CurrencyProvider class Provider(CurrencyProvider): diff --git a/faker/providers/currency/de_CH/__init__.py b/faker/providers/currency/de_CH/__init__.py new file mode 100644 index 0000000000..af04dff593 --- /dev/null +++ b/faker/providers/currency/de_CH/__init__.py @@ -0,0 +1,9 @@ +from ..de import Provider as CurrencyProvider + + +class Provider(CurrencyProvider): + # source: https://de.wikipedia.org/wiki/Schreibweise_von_Zahlen#Dezimaltrennzeichen_2 + price_formats = ["\N{figure dash}.##", "%.##", "%#.##", "%##.##", "% ###.##", "%# ###.##"] + + def pricetag(self): + return "Fr.\N{no-break space}" + self.numerify(self.random_element(self.price_formats)) diff --git a/faker/providers/currency/de_DE/__init__.py b/faker/providers/currency/de_DE/__init__.py index 93d2014f2c..28e0dcfe83 100644 --- a/faker/providers/currency/de_DE/__init__.py +++ b/faker/providers/currency/de_DE/__init__.py @@ -1,4 +1,4 @@ -from .. import Provider as CurrencyProvider +from ..de import Provider as CurrencyProvider class Provider(CurrencyProvider): diff --git a/faker/providers/job/de_AT/__init__.py b/faker/providers/job/de_AT/__init__.py index 0bb6ccf3f6..056e78cecc 100644 --- a/faker/providers/job/de_AT/__init__.py +++ b/faker/providers/job/de_AT/__init__.py @@ -4989,9 +4989,9 @@ class Provider(BaseProvider): {"neutral": "Änderungsschneider*in", "female": "Änderungsschneiderin", "male": "Änderungsschneider"}, ) - jobs: ElementsType[str] = [job["neutral"] for job in jobs_dict] # type: ignore[index] - jobs_female: ElementsType[str] = [job["female"] for job in jobs_dict] # type: ignore[index] - jobs_male: ElementsType[str] = [job["male"] for job in jobs_dict] # type: ignore[index] + jobs: ElementsType[str] = [job["neutral"] for job in jobs_dict] + jobs_female: ElementsType[str] = [job["female"] for job in jobs_dict] + jobs_male: ElementsType[str] = [job["male"] for job in jobs_dict] def job(self) -> str: return self.random_element(self.jobs) diff --git a/faker/providers/passport/de_AT/__init__.py b/faker/providers/passport/de_AT/__init__.py new file mode 100644 index 0000000000..63921e0dad --- /dev/null +++ b/faker/providers/passport/de_AT/__init__.py @@ -0,0 +1,16 @@ +from .. import ElementsType +from .. import Provider as PassportProvider + + +class Provider(PassportProvider): + """Implement passport provider for ``de_AT`` locale. + + Sources: + + - https://www.bmi.gv.at/607/Reisepass.aspx + """ + + passport_number_formats: ElementsType[str] = ( + "?#######", + "??#######", + ) diff --git a/faker/providers/person/de_AT/__init__.py b/faker/providers/person/de_AT/__init__.py index be2795be13..ddc0067c27 100644 --- a/faker/providers/person/de_AT/__init__.py +++ b/faker/providers/person/de_AT/__init__.py @@ -1569,3 +1569,46 @@ class Provider(PersonProvider): ) prefixes = ("Dr.", "Mag.", "Ing.", "Dipl.-Ing.", "Prof.", "Univ.Prof.") + + # source: + # https://www.bmbwf.gv.at/dam/jcr:68a61bdd-4fd4-416b-bfb2-4fbb44255574/AKADEMISCHE%20GRADE%202022_M%C3%A4rz%202022.pdf + academic_prefixes = ( + "DI", + "DI (FH)", + "Dipl.-Ing.", + "Dipl.-Ing. (FH)", + "Dr. med. univ.", + "Dr. med. dent.", + "Mag.", + "Mag. (FH)", + ) + + academic_suffixes = ( + "BA", + "B.A.", + "BEd", + "BSc", + "B.Sc.", + "Bakk.", + "MA", + "M.A.", + "MBA", + "MEd", + "MSc", + "M.Sc.", + "PhD", + ) + + """ + :return: Academic prefix + """ + + def academic_prefix(self) -> str: + return self.random_element(self.academic_prefixes) + + """ + :return: Academic suffix + """ + + def academic_suffix(self) -> str: + return self.random_element(self.academic_suffixes) diff --git a/faker/providers/person/de_DE/__init__.py b/faker/providers/person/de_DE/__init__.py index 0a39480892..2ba6f0ebb4 100644 --- a/faker/providers/person/de_DE/__init__.py +++ b/faker/providers/person/de_DE/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as PersonProvider @@ -2470,3 +2472,26 @@ class Provider(PersonProvider): ) suffixes = ("B.Sc.", "B.A.", "B.Eng.", "MBA.") + + # Source: https://de.wikipedia.org/wiki/Familienstand + civil_status_list = ( + ("LD", "ledig"), + ("VH", "verheiratet"), + ("VW", "verwitwet"), + ("GS", "geschieden"), + ("EA", "Ehe aufgehoben"), + ("LP", "in eingetragener Lebenspartnerschaft"), + ("LV", "durch Tod aufgelöste Lebenspartnerschaft"), + ("LA", "aufgehobene Lebenspartnerschaft"), + ("LE", "durch Todeserklärung aufgelöste Lebenspartnerschaft"), + ("NB", "nicht bekannt"), + ) + + def civil_status(self) -> Tuple[str, str]: + return self.random_element(self.civil_status_list) + + def civil_status_code(self) -> str: + return self.random_element(self.civil_status_list)[0] + + def civil_status_name(self) -> str: + return self.random_element(self.civil_status_list)[1] diff --git a/faker/providers/person/de_LI/__init__.py b/faker/providers/person/de_LI/__init__.py new file mode 100644 index 0000000000..ca4d16787c --- /dev/null +++ b/faker/providers/person/de_LI/__init__.py @@ -0,0 +1,553 @@ +from collections import OrderedDict + +from .. import Provider as PersonProvider + + +class Provider(PersonProvider): + + # Top 50 surnames in Liechtenstein + # Weighted by number of occurrences + # Source: https://de.wikipedia.org/wiki/Familiennamen_in_Liechtenstein#Die_h%C3%A4ufigsten_50_Familiennamen + # on 2024-10-31 + last_names = OrderedDict( + ( + ("Banzer", 0.011916111), + ("Bargetze", 0.007864633), + ("Batliner", 0.011201144), + ("Beck", 0.05926279), + ("Biedermann", 0.016682555), + ("Büchel", 0.063711471), + ("Bühler", 0.01509374), + ("Eberle", 0.023196695), + ("Foser", 0.008420718), + ("Frick", 0.053781379), + ("Frommelt", 0.021607881), + ("Gassner", 0.028519225), + ("Gstöhl", 0.020734032), + ("Hasler", 0.035668891), + ("Heeb", 0.011201144), + ("Hilti", 0.014458214), + ("Hoop", 0.012789959), + ("Jehle", 0.010486177), + ("Kaiser", 0.018509692), + ("Kaufmann", 0.014855418), + ("Kieber", 0.010009533), + ("Kind", 0.010486177), + ("Kindle", 0.025977121), + ("Konrad", 0.007626311), + ("Kranz", 0.015967588), + ("Lampert", 0.017318081), + ("Marxer", 0.05608516), + ("Matt", 0.017635844), + ("Meier", 0.031776295), + ("Negele", 0.01080394), + ("Nigg", 0.015570384), + ("Nipp", 0.009453448), + ("Nägele", 0.008102955), + ("Näscher", 0.011042262), + ("Oehri", 0.014617096), + ("Ospelt", 0.026612647), + ("Risch", 0.016603114), + ("Ritter", 0.023911662), + ("Schädler", 0.04313632), + ("Sele", 0.016920877), + ("Sprenger", 0.010962822), + ("Thöny", 0.007626311), + ("Vogt", 0.047982205), + ("Wachter", 0.010406737), + ("Walser", 0.016682555), + ("Wanger", 0.008976803), + ("Wille", 0.008182396), + ("Wohlwend", 0.022402288), + ("Wolfinger", 0.010247855), + ("Öhri", 0.01406101), + ) + ) + + # Source: + # https://www.baby-vornamen.de/Namensthemen/Charts/Beliebteste-Vornamen-Liechtenstein-182.php#Jahrescharts-Liechtenstein + # Took the 30 most common baby names per year (1996 to 2022) and weighted them by number of + # occurences (how often the name appeared in one of the year lists) + first_names_male = OrderedDict( + ( + ("Aaron", 0.00817), + ("Adrian", 0.00817), + ("Ajan", 0.00117), + ("Alessandro", 0.00233), + ("Alessio", 0.00467), + ("Alexander", 0.01517), + ("Amar", 0.00233), + ("Andreas", 0.0035), + ("Andrin", 0.00583), + ("Aras", 0.00117), + ("Bastian", 0.00117), + ("Ben", 0.00933), + ("Benedikt", 0.00117), + ("Benjamin", 0.01167), + ("Brian", 0.00117), + ("Christoph", 0.00233), + ("Colin", 0.00117), + ("Conradin", 0.00117), + ("Constantin", 0.0035), + ("Cristiano", 0.00117), + ("Damian", 0.00233), + ("Daniel", 0.00817), + ("Dario", 0.007), + ("Daris", 0.00117), + ("David", 0.014), + ("Davide", 0.00117), + ("Diego", 0.00233), + ("Diogo", 0.00117), + ("Dominic", 0.00117), + ("Dominik", 0.007), + ("Dylan", 0.0035), + ("Eldon", 0.00117), + ("Elia", 0.00583), + ("Elias", 0.01984), + ("Elijah", 0.00117), + ("Elio", 0.00117), + ("Eloi", 0.00117), + ("Emanuel", 0.00467), + ("Emil", 0.0035), + ("Emilian", 0.00233), + ("Emmanuel", 0.00117), + ("Enea", 0.00233), + ("Eren", 0.00117), + ("Eric", 0.00117), + ("Fabian", 0.014), + ("Fabio", 0.01517), + ("Fabrizio", 0.00117), + ("Felix", 0.00817), + ("Finn", 0.00583), + ("Florian", 0.00583), + ("Florin", 0.00117), + ("Gabriel", 0.01284), + ("Gian", 0.0035), + ("Gian-Luca", 0.00117), + ("Gion", 0.00117), + ("Goncalo", 0.00117), + ("Gustav", 0.00117), + ("Hans", 0.00117), + ("Henri", 0.00117), + ("Henry", 0.00233), + ("Ian", 0.00117), + ("Jakob", 0.00233), + ("James", 0.00117), + ("Jan", 0.007), + ("Janick", 0.00117), + ("Janik", 0.00117), + ("Janis", 0.00117), + ("Jano", 0.00117), + ("Joel", 0.01167), + ("Johannes", 0.00933), + ("Jonas", 0.021), + ("Jonathan", 0.00233), + ("Josef", 0.00233), + ("Joshua", 0.00117), + ("Julian", 0.0245), + ("Julius", 0.00233), + ("Justin", 0.00467), + ("Kevin", 0.00583), + ("Kian", 0.00117), + ("Kiano", 0.00117), + ("Kilian", 0.00233), + ("Konstantin", 0.00233), + ("Lars", 0.00233), + ("Laurenz", 0.00117), + ("Laurin", 0.00933), + ("Lean", 0.00117), + ("Leandro", 0.00817), + ("Leano", 0.0035), + ("Lenny", 0.00233), + ("Leo", 0.0105), + ("Leon", 0.01634), + ("Leonardo", 0.00117), + ("Leonhard", 0.00117), + ("Leopold", 0.00233), + ("Levi", 0.00117), + ("Levin", 0.0035), + ("Liam", 0.00467), + ("Lian", 0.00467), + ("Linus", 0.00233), + ("Lio", 0.00233), + ("Lionel", 0.00583), + ("Lirjan", 0.00117), + ("Livio", 0.0035), + ("Lorenz", 0.00117), + ("Loris", 0.00233), + ("Louie", 0.00233), + ("Louis", 0.0105), + ("Luan", 0.00233), + ("Luca", 0.0175), + ("Lucas", 0.00467), + ("Luej", 0.00117), + ("Luigi", 0.00117), + ("Luis", 0.01517), + ("Lukas", 0.0175), + ("Mael", 0.00117), + ("Malik", 0.0035), + ("Malio", 0.00117), + ("Mantas", 0.00117), + ("Manuel", 0.014), + ("Marc", 0.007), + ("Marcel", 0.00233), + ("Marco", 0.0105), + ("Marino", 0.00117), + ("Mario", 0.00117), + ("Marlon", 0.0035), + ("Martim", 0.00117), + ("Martin", 0.0035), + ("Marvin", 0.00117), + ("Mathias", 0.00117), + ("Mats", 0.00117), + ("Matteo", 0.01167), + ("Matthias", 0.007), + ("Matti", 0.00117), + ("Mattia", 0.00233), + ("Maurice", 0.00117), + ("Mauro", 0.0035), + ("Max", 0.00817), + ("Maxim", 0.00117), + ("Maximilian", 0.01634), + ("Metehan", 0.00117), + ("Michael", 0.01167), + ("Michele", 0.00233), + ("Mike", 0.00117), + ("Mikyas", 0.00117), + ("Milan", 0.00117), + ("Milo", 0.00117), + ("Moritz", 0.00233), + ("Muhamed", 0.00233), + ("Muhammed", 0.00467), + ("Nael", 0.00233), + ("Nando", 0.00117), + ("Natanael", 0.00117), + ("Nelio", 0.00117), + ("Nevio", 0.00233), + ("Niclas", 0.00233), + ("Nico", 0.01284), + ("Nicola", 0.00117), + ("Nicolas", 0.00933), + ("Niels", 0.00117), + ("Niklas", 0.007), + ("Nils", 0.00233), + ("Nino", 0.00467), + ("Noah", 0.0245), + ("Noam", 0.00117), + ("Noe", 0.00117), + ("Noel", 0.007), + ("Oliver", 0.00233), + ("Orlando", 0.00117), + ("Oscar", 0.00117), + ("Oskar", 0.00233), + ("Pascal", 0.01167), + ("Patrick", 0.007), + ("Patrik", 0.00117), + ("Paul", 0.00933), + ("Philipp", 0.007), + ("Rafael", 0.00583), + ("Raffael", 0.00233), + ("Ramon", 0.0035), + ("Raphael", 0.01984), + ("Rino", 0.00117), + ("Robin", 0.0105), + ("Rodrigo", 0.00233), + ("Romeo", 0.00117), + ("Ruben", 0.00583), + ("Ryan", 0.00233), + ("Samir", 0.00117), + ("Samuel", 0.01867), + ("Sandro", 0.007), + ("Santiago", 0.00233), + ("Sebastian", 0.0105), + ("Severin", 0.00117), + ("Silas", 0.00117), + ("Silvio", 0.00117), + ("Simon", 0.0175), + ("Stefan", 0.00117), + ("Tenzin", 0.00233), + ("Theo", 0.00233), + ("Theodor", 0.00233), + ("Thiago", 0.00117), + ("Thomas", 0.00117), + ("Tiago", 0.00233), + ("Till", 0.00117), + ("Tim", 0.00467), + ("Timo", 0.00233), + ("Timon", 0.00117), + ("Timur", 0.00117), + ("Tiziano", 0.00117), + ("Tobias", 0.01167), + ("Valentin", 0.00933), + ("Vince", 0.00117), + ("Vincent", 0.00233), + ("Wenzel", 0.00117), + ("Yanis", 0.00117), + ("Yannick", 0.0035), + ("Yassin", 0.00117), + ("Yoan", 0.00117), + ("Ömer", 0.00117), + ) + ) + + first_names_female = OrderedDict( + ( + ("Adriana", 0.00361), + ("Afra", 0.0012), + ("Alea", 0.0012), + ("Alessia", 0.01566), + ("Alexandra", 0.0012), + ("Alicia", 0.0012), + ("Alina", 0.01205), + ("Alisa", 0.0012), + ("Alya", 0.0012), + ("Amaya", 0.0012), + ("Amelia", 0.0012), + ("Amelie", 0.01446), + ("Amy", 0.00361), + ("Anastasia", 0.0012), + ("Angelina", 0.00241), + ("Anika", 0.00241), + ("Anisa", 0.0012), + ("Anja", 0.0012), + ("Anna", 0.02651), + ("Anna-Lena", 0.0012), + ("Annalena", 0.0012), + ("Annika", 0.00241), + ("Annina", 0.0012), + ("Anouk", 0.0012), + ("Aria", 0.0012), + ("Ariana", 0.00241), + ("Aurora", 0.00361), + ("Ayse", 0.0012), + ("Bianca", 0.0012), + ("Carla", 0.00361), + ("Carmen", 0.0012), + ("Carolina", 0.0012), + ("Caroline", 0.0012), + ("Cataleya", 0.0012), + ("Celina", 0.0012), + ("Celine", 0.00482), + ("Chiara", 0.01928), + ("Christina", 0.0012), + ("Claudia", 0.0012), + ("Cosima", 0.0012), + ("Daria", 0.0012), + ("Deborah", 0.0012), + ("Deniis", 0.0012), + ("Diana", 0.00361), + ("Dilara", 0.0012), + ("Eileen", 0.0012), + ("Ela", 0.00361), + ("Elea", 0.00241), + ("Elena", 0.01687), + ("Elfida", 0.0012), + ("Eliana", 0.00241), + ("Eliane", 0.0012), + ("Elif", 0.00241), + ("Elin", 0.00482), + ("Elina", 0.00361), + ("Eliona", 0.0012), + ("Elisa", 0.00361), + ("Elisabeth", 0.0012), + ("Ella", 0.00482), + ("Elvana", 0.0012), + ("Emelina", 0.0012), + ("Emilia", 0.01566), + ("Emilie", 0.0012), + ("Emily", 0.00482), + ("Emine", 0.0012), + ("Emma", 0.01928), + ("Enna", 0.0012), + ("Enya", 0.0012), + ("Eowyn", 0.0012), + ("Erva", 0.0012), + ("Eslemnur", 0.0012), + ("Estella", 0.0012), + ("Eva", 0.00482), + ("Eva-Maria", 0.0012), + ("Evita", 0.0012), + ("Fabienne", 0.00602), + ("Felicia", 0.0012), + ("Filippa", 0.00241), + ("Fiona", 0.00843), + ("Fjolla", 0.0012), + ("Florina", 0.0012), + ("Franziska", 0.00241), + ("Frida", 0.0012), + ("Frieda", 0.0012), + ("Gaia", 0.0012), + ("Geraldine", 0.0012), + ("Gina", 0.00241), + ("Gioia", 0.0012), + ("Giulia", 0.00482), + ("Gizem", 0.0012), + ("Grace", 0.0012), + ("Gwenda", 0.0012), + ("Hana", 0.0012), + ("Hanna", 0.00241), + ("Hannah", 0.00964), + ("Helena", 0.00482), + ("Ilenia", 0.0012), + ("Irina", 0.0012), + ("Isabel", 0.00241), + ("Isabella", 0.00241), + ("Jacqueline", 0.00241), + ("Jana", 0.00964), + ("Janina", 0.00241), + ("Janine", 0.00361), + ("Jasmin", 0.0012), + ("Jennifer", 0.00482), + ("Jenny", 0.0012), + ("Jessica", 0.00964), + ("Joana", 0.00361), + ("Joanna", 0.0012), + ("Johanna", 0.00964), + ("Jolina", 0.0012), + ("Jule", 0.0012), + ("Julia", 0.02048), + ("Katharina", 0.01084), + ("Kerstin", 0.0012), + ("Klara", 0.0012), + ("Klea", 0.0012), + ("Künkyi", 0.0012), + ("Ladina", 0.01084), + ("Lara", 0.02048), + ("Larissa", 0.00964), + ("Laura", 0.02289), + ("Laurina", 0.0012), + ("Lavinia", 0.0012), + ("Lea", 0.01687), + ("Leana", 0.0012), + ("Lena", 0.01807), + ("Leni", 0.00241), + ("Leonie", 0.02048), + ("Letizia", 0.00241), + ("Leyla", 0.0012), + ("Leyla-Katharina", 0.0012), + ("Lhanzey", 0.0012), + ("Lia", 0.00602), + ("Lilia", 0.0012), + ("Liliana", 0.0012), + ("Lillian", 0.0012), + ("Lilly", 0.0012), + ("Lily", 0.0012), + ("Lina", 0.01325), + ("Linda", 0.00361), + ("Lisa", 0.01928), + ("Liv", 0.00241), + ("Livia", 0.00602), + ("Liya", 0.0012), + ("Lola", 0.0012), + ("Lorena", 0.00843), + ("Louana", 0.0012), + ("Louisa", 0.0012), + ("Louise", 0.0012), + ("Luana", 0.00241), + ("Luena", 0.0012), + ("Luisa", 0.01084), + ("Luna", 0.0012), + ("Lydia", 0.00241), + ("Lynn", 0.00482), + ("Madeleine", 0.0012), + ("Madleina", 0.00241), + ("Magdalena", 0.00361), + ("Maila", 0.0012), + ("Maisa", 0.0012), + ("Maivi", 0.0012), + ("Maja", 0.0012), + ("Malea", 0.00482), + ("Malene", 0.0012), + ("Malu", 0.0012), + ("Manila", 0.0012), + ("Mara", 0.00602), + ("Mara-Julie", 0.0012), + ("Maren", 0.0012), + ("Margarita", 0.0012), + ("Mari", 0.0012), + ("Maria", 0.01084), + ("Marie", 0.00602), + ("Marie-Cecilie", 0.0012), + ("Mariella", 0.0012), + ("Marina", 0.00241), + ("Martina", 0.0012), + ("Mathilda", 0.0012), + ("Matilda", 0.00361), + ("Mavie", 0.0012), + ("Maxima", 0.0012), + ("Maya", 0.0012), + ("Melanie", 0.00843), + ("Melanine", 0.0012), + ("Melina", 0.00482), + ("Melissa", 0.00723), + ("Merve", 0.0012), + ("Mia", 0.01446), + ("Michele", 0.00241), + ("Michelle", 0.00482), + ("Mila", 0.00241), + ("Milena", 0.00482), + ("Mina", 0.00361), + ("Mira", 0.0012), + ("Muriel", 0.0012), + ("Nadine", 0.0012), + ("Nahla", 0.0012), + ("Naomi", 0.00482), + ("Natalie", 0.0012), + ("Nathalie", 0.0012), + ("Nathasha", 0.0012), + ("Nelia", 0.0012), + ("Nelya", 0.0012), + ("Neslisah", 0.0012), + ("Nicole", 0.00482), + ("Nina", 0.01928), + ("Noelia", 0.00482), + ("Noemi", 0.00964), + ("Nora", 0.00482), + ("Nour", 0.0012), + ("Olivia", 0.00241), + ("Patricia", 0.0012), + ("Paula", 0.00723), + ("Paulina", 0.0012), + ("Pia", 0.00241), + ("Rahel", 0.00241), + ("Ramona", 0.00361), + ("Raphaela", 0.0012), + ("Rebecca", 0.00602), + ("Robin", 0.0012), + ("Romy", 0.0012), + ("Ronja", 0.00241), + ("Sabrina", 0.00482), + ("Sally", 0.0012), + ("Salome", 0.00241), + ("Samantha", 0.0012), + ("Saphira", 0.00241), + ("Sara", 0.00723), + ("Sarah", 0.01446), + ("Sarina", 0.00241), + ("Selina", 0.00843), + ("Sina", 0.01084), + ("Sofia", 0.00361), + ("Sophia", 0.02048), + ("Sophie", 0.00602), + ("Soraya", 0.0012), + ("Stefanie", 0.00241), + ("Svenja", 0.0012), + ("Tamara", 0.0012), + ("Tatjana", 0.0012), + ("Tenzin", 0.0012), + ("Teresa", 0.0012), + ("Thalia", 0.0012), + ("Tina", 0.0012), + ("Valentina", 0.01325), + ("Valeria", 0.00241), + ("Vanessa", 0.01325), + ("Victoria", 0.00482), + ("Viktoria", 0.0012), + ("Xenia", 0.0012), + ("Yara", 0.0012), + ("Ylvi", 0.0012), + ("Zehra", 0.00241), + ("Zejna", 0.0012), + ("Zoe", 0.00361), + ) + ) diff --git a/faker/providers/person/de_LU/__init__.py b/faker/providers/person/de_LU/__init__.py new file mode 100644 index 0000000000..c07b0f56a1 --- /dev/null +++ b/faker/providers/person/de_LU/__init__.py @@ -0,0 +1,940 @@ +from collections import OrderedDict + +from .. import Provider as PersonProvider + + +class Provider(PersonProvider): + + # Source for last names: https://nachnamen.net/luxemburg + last_names = OrderedDict( + ( + ("Schmit", 6799), + ("Muller", 5784), + ("Weber", 4858), + ("Wagner", 4837), + ("Hoffmann", 4628), + ("Thill", 3304), + ("Schmitz", 3135), + ("Schroeder", 2839), + ("Becker", 2549), + ("Klein", 2413), + ("Faber", 2159), + ("Da silva", 2007), + ("Kieffer", 1949), + ("Reuter", 1944), + ("Schiltz", 1891), + ("Dos santos", 1867), + ("Welter", 1788), + ("Simon", 1785), + ("Schneider", 1721), + ("Hansen", 1657), + ("Meyer", 1614), + ("Kremer", 1605), + ("Pereira", 1580), + ("Weis", 1446), + ("Braun", 1381), + ("Fernandes", 1368), + ("Kayser", 1352), + ("Kirsch", 1351), + ("Steffen", 1350), + ("Krier", 1311), + ("Theisen", 1301), + ("Majerus", 1239), + ("Ries", 1203), + ("Ferreira", 1153), + ("Gonçalves", 1151), + ("Meyers", 1148), + ("Engel", 1135), + ("Schumacher", 1119), + ("Diederich", 1090), + ("Rodrigues", 1074), + ("Martin", 1065), + ("Marx", 1062), + ("Gomes", 1043), + ("Molitor", 1030), + ("Theis", 1021), + ("Wolff", 961), + ("Martins", 952), + ("Heinen", 914), + ("Weydert", 891), + ("Zimmer", 889), + ("Goergen", 867), + ("Fischer", 863), + ("Wagener", 854), + ("Reding", 837), + ("Lentz", 830), + ("Flammang", 828), + ("Bernard", 827), + ("Scholtes", 809), + ("Adrovic", 800), + ("Koch", 775), + ("Goedert", 763), + ("Arend", 753), + ("Winandy", 753), + ("Jacoby", 740), + ("Nilles", 703), + ("Gengler", 690), + ("Peters", 690), + ("Berg", 685), + ("Lanners", 684), + ("Pinto", 676), + ("Sabotic", 673), + ("Back", 672), + ("Lopes", 663), + ("Marques", 658), + ("Lux", 655), + ("Bertemes", 652), + ("Putz", 649), + ("Jung", 648), + ("Haas", 633), + ("Erpelding", 630), + ("Schmitt", 620), + ("Weiler", 613), + ("Mangen", 607), + ("Pauly", 602), + ("Weyland", 601), + ("Dostert", 599), + ("Biver", 598), + ("Alves", 597), + ("Huberty", 594), + ("Schreiner", 590), + ("Decker", 590), + ("Backes", 589), + ("Schaus", 589), + ("Olinger", 576), + ("Rastoder", 562), + ("Schaack", 561), + ("Grethen", 554), + ("Steichen", 542), + ("Mendes", 541), + ("Monteiro", 539), + ("Oliveira", 536), + ("Lucas", 536), + ("Poos", 536), + ("Ney", 535), + ("Teixeira", 528), + ("Michels", 527), + ("Wirtz", 515), + ("Mathieu", 511), + ("Schintgen", 510), + ("Scheer", 493), + ("Peiffer", 486), + ("Hilbert", 485), + ("Thein", 478), + ("Steinmetz", 470), + ("Stoffel", 470), + ("Da costa", 469), + ("Arendt", 468), + ("Clement", 468), + ("Hermes", 465), + ("Dumont", 463), + ("Kohn", 459), + ("Wies", 459), + ("Feller", 454), + ("Soares", 454), + ("Kneip", 453), + ("Kohl", 448), + ("De sousa", 441), + ("Thinnes", 439), + ("Almeida", 437), + ("Elsen", 436), + ("Glod", 433), + ("Mergen", 432), + ("Trausch", 432), + ("Mertens", 430), + ("Schaeffer", 425), + ("Mousel", 424), + ("Heck", 419), + ("Thiel", 418), + ("Duarte", 418), + ("Lang", 416), + ("Mersch", 414), + ("Linden", 414), + ("Thiry", 413), + ("Muhovic", 411), + ("Bausch", 411), + ("Georges", 410), + ("Lambert", 403), + ("Hengen", 403), + ("Konsbruck", 397), + ("Trierweiler", 395), + ("Ewen", 393), + ("Kohnen", 391), + ("Berchem", 388), + ("Schmidt", 387), + ("Thoma", 384), + ("Heiderscheid", 383), + ("May", 382), + ("Wantz", 381), + ("Clemens", 380), + ("Conter", 379), + ("Felten", 377), + ("Gerard", 377), + ("Garcia", 376), + ("Ribeiro", 372), + ("Skrijelj", 370), + ("Wolter", 369), + ("Lorang", 361), + ("Nickels", 360), + ("Barthel", 359), + ("Huss", 358), + ("Jeitz", 358), + ("Moes", 357), + ("Werner", 357), + ("Kerschen", 354), + ("Sinner", 352), + ("Bertrand", 350), + ("Kemp", 350), + ("Lutgen", 349), + ("Gillen", 348), + ("Baustert", 346), + ("Stoltz", 346), + ("Lamesch", 345), + ("Carvalho", 344), + ("Reinert", 341), + ("Schummer", 337), + ("Hilger", 337), + ("Michel", 333), + ("Reiter", 330), + ("Hubert", 329), + ("Neu", 328), + ("Dias", 326), + ("Frisch", 322), + ("Nosbusch", 322), + ("Silva", 320), + ("Weyrich", 320), + ("Wilmes", 318), + ("Brandenburger", 314), + ("Manderscheid", 314), + ("Pedersen", 313), + ("Rollinger", 313), + ("Eischen", 312), + ("Kraus", 312), + ("Paulus", 312), + ("Kauffmann", 311), + ("Colling", 310), + ("Correia", 305), + ("Koenig", 305), + ("Glodt", 303), + ("Antony", 301), + ("Cardoso", 300), + ("Oberweis", 298), + ("Quintus", 297), + ("Jost", 297), + ("Agovic", 296), + ("Machado", 295), + ("Beffort", 293), + ("Wiltzius", 292), + ("Francois", 292), + ("Maas", 291), + ("Vitali", 291), + ("Fischbach", 290), + ("Reckinger", 289), + ("Bauer", 288), + ("Fisch", 288), + ("Beck", 286), + ("Andersen", 285), + ("Delvaux", 284), + ("Gloden", 281), + ("Hames", 280), + ("Ramdedovic", 280), + ("Friederich", 279), + ("Richard", 279), + ("Melchior", 279), + ("Zeimet", 278), + ("Demuth", 276), + ("Muratovic", 273), + ("Ruppert", 273), + ("Hurt", 269), + ("Kass", 268), + ("Hoss", 267), + ("Rausch", 267), + ("Thielen", 266), + ("Andre", 265), + ("Wampach", 265), + ("Linster", 264), + ("Dupont", 263), + ("Dahm", 263), + ("Willems", 263), + ("Schartz", 260), + ("Clees", 260), + ("Fonck", 259), + ("Wilhelm", 258), + ("Jensen", 258), + ("Petit", 258), + ("Schank", 257), + ("Kerger", 257), + ("Franzen", 257), + ("Gaspar", 256), + ("Gilson", 256), + ("Biwer", 255), + ("Wolf", 254), + ("Tavares", 253), + ("Reiser", 253), + ("De jesus", 252), + ("Heintz", 250), + ("Robert", 248), + ("Goetzinger", 246), + ("Schon", 246), + ("Claude", 244), + ("Halsdorf", 244), + ("Moreira", 243), + ("Schuler", 241), + ("Schlesser", 241), + ("Colbach", 241), + ("Haupert", 240), + ("Cikotic", 239), + ("Rossi", 239), + ("Siebenaler", 238), + ("Daleiden", 238), + ("Gaasch", 237), + ("Lemmer", 237), + ("Kasel", 236), + ("Breuer", 235), + ("Skenderovic", 234), + ("Godart", 234), + ("Bettendorff", 234), + ("Karier", 233), + ("Graf", 233), + ("Louis", 233), + ("Feinen", 233), + ("Risch", 232), + ("Weisgerber", 232), + ("Beissel", 231), + ("Mores", 230), + ("Juncker", 229), + ("Buchler", 229), + ("Santos", 229), + ("Feltz", 229), + ("Pletschette", 228), + ("Entringer", 228), + ("Brosius", 227), + ("Bintner", 227), + ("Heirens", 226), + ("Urbany", 226), + ("Marnach", 226), + ("Neumann", 225), + ("Sauber", 225), + ("Pundel", 225), + ("Feyder", 225), + ("Thomas", 224), + ("Meisch", 224), + ("Greisch", 224), + ("Bruck", 224), + ("Turmes", 224), + ("Hemmen", 224), + ("Hemmer", 222), + ("Krecke", 221), + ("Bintz", 220), + ("Baum", 220), + ("Gregoire", 219), + ("Kinsch", 219), + ("Gatti", 218), + ("Schilling", 218), + ("Schwartz", 217), + ("Kaiser", 217), + ("Zenner", 217), + ("Thilmany", 217), + ("Mathias", 215), + ("Mayer", 214), + ("Fuchs", 214), + ("Kocan", 213), + ("Staudt", 213), + ("Franck", 213), + ("Berscheid", 213), + ("Hahn", 213), + ("Strasser", 213), + ("Frank", 212), + ("Feltgen", 212), + ("Goerens", 210), + ("Ley", 209), + ("Zeimes", 208), + ("Lima", 208), + ("Beckius", 207), + ("Heuertz", 207), + ("Feiereisen", 206), + ("Krack", 206), + ("Guillaume", 206), + ("Pires", 206), + ("Seil", 206), + ("Kintziger", 205), + ) + ) + + # Source for first names: https://github.com/MatthiasWinkelmann/firstname-database + first_names_female = OrderedDict( + ( + ("Ada", 0.00390625), + ("Adeline", 0.015625), + ("Adrienne", 0.015625), + ("Agnès", 0.0625), + ("Albertine", 0.0625), + ("Alice", 0.25), + ("Aline", 0.0625), + ("Aloyse", 0.5), + ("Aly", 0.125), + ("Amandine", 0.00390625), + ("Amélie", 0.03125), + ("Andréa", 0.0625), + ("Andrée", 0.125), + ("Angèle", 0.0625), + ("Angélique", 0.015625), + ("Anita", 0.03125), + ("Anna", 0.25), + ("Anne", 1.0), + ("Annette", 0.125), + ("Annick", 0.125), + ("Annie", 0.03125), + ("Anouk", 0.0625), + ("Antoinette", 0.125), + ("Ariane", 0.015625), + ("Arlette", 0.0625), + ("Armande", 0.00390625), + ("Armelle", 0.0078125), + ("Astrid", 0.125), + ("Astride", 0.015625), + ("Audrey", 0.03125), + ("Aurélie", 0.015625), + ("Barbara", 0.0625), + ("Béatrice", 0.0625), + ("Béatrix", 0.00390625), + ("Bénédicte", 0.015625), + ("Bernadette", 0.03125), + ("Berthe", 0.03125), + ("Betty", 0.0625), + ("Bianca", 0.03125), + ("Birgit", 0.015625), + ("Blanche", 0.0625), + ("Blandine", 0.00390625), + ("Brigitte", 0.125), + ("Camille", 0.5), + ("Carine", 0.125), + ("Carol", 0.015625), + ("Carole", 0.25), + ("Caroline", 0.125), + ("Catherine", 0.5), + ("Cécile", 0.25), + ("Cecilia", 0.0078125), + ("Cecille", 0.00390625), + ("Céline", 0.125), + ("Chantal", 0.25), + ("Chloe", 0.00390625), + ("Christelle", 0.03125), + ("Christiane", 0.5), + ("Christine", 0.125), + ("Cindy", 0.0625), + ("Claire", 0.125), + ("Clarisse", 0.00390625), + ("Claudette", 0.0078125), + ("Claudia", 0.0625), + ("Claudie", 0.00390625), + ("Claudine", 0.25), + ("Clémentine", 0.00390625), + ("Clothilde", 0.0078125), + ("Clotilde", 0.00390625), + ("Colette", 0.125), + ("Constance", 0.0078125), + ("Corinne", 0.0625), + ("Cornelia", 0.015625), + ("Cynthia", 0.03125), + ("Damienne", 0.00390625), + ("Daniela", 0.0625), + ("Danièle", 0.125), + ("Danielle", 0.25), + ("Dany", 0.0625), + ("Deborah", 0.03125), + ("Delphine", 0.03125), + ("Denise", 0.25), + ("Désirée", 0.015625), + ("Diane", 0.125), + ("Doris", 0.0625), + ("Dorothée", 0.0078125), + ("Eléonore", 0.0078125), + ("Eliane", 0.03125), + ("Eliette", 0.0078125), + ("Elisabeth", 0.25), + ("Elise", 0.125), + ("Elodie", 0.00390625), + ("Elvira", 0.03125), + ("Elvire", 0.03125), + ("Emilie", 0.0625), + ("Emma", 0.015625), + ("Emmanuelle", 0.03125), + ("Ernestine", 0.015625), + ("Erny", 0.25), + ("Estelle", 0.03125), + ("Esther", 0.03125), + ("Eugénie", 0.0625), + ("Eunice", 0.0078125), + ("Eva", 0.03125), + ("Fabienne", 0.125), + ("Fanny", 0.015625), + ("Félicie", 0.0625), + ("Fernande", 0.125), + ("Ferny", 0.0078125), + ("Flore", 0.00390625), + ("Florence", 0.0625), + ("Florentine", 0.0078125), + ("France", 0.125), + ("Francine", 0.125), + ("Françoise", 0.25), + ("Frédérique", 0.03125), + ("Gabrielle", 0.0625), + ("Gaby", 0.0625), + ("Gaëlle", 0.0078125), + ("Geneviève", 0.03125), + ("Georgette", 0.125), + ("Géraldine", 0.03125), + ("Germaine", 0.125), + ("Gertrude", 0.015625), + ("Ghislaine", 0.015625), + ("Gilberte", 0.03125), + ("Ginette", 0.125), + ("Gisèle", 0.0625), + ("Hélène", 0.25), + ("Heloise", 0.00390625), + ("Henriette", 0.25), + ("Hilda", 0.03125), + ("Huguette", 0.015625), + ("Ida", 0.03125), + ("Inès", 0.015625), + ("Ingrid", 0.03125), + ("Irène", 0.25), + ("Irma", 0.0625), + ("Isabel", 0.125), + ("Isabelle", 0.5), + ("Jacqueline", 0.25), + ("Janine", 0.015625), + ("Jasmine", 0.015625), + ("Jeanette", 0.0078125), + ("Jeanine", 0.015625), + ("Jeanne", 0.5), + ("Jeannette", 0.03125), + ("Jeannie", 0.00390625), + ("Jeannine", 0.0625), + ("Jeanny", 0.125), + ("Jennifer", 0.03125), + ("Jessica", 0.125), + ("Jocelyne", 0.015625), + ("Joëlle", 0.25), + ("Josée", 0.5), + ("Joséphine", 0.125), + ("Josette", 0.25), + ("Josiane", 0.125), + ("Josy", 0.5), + ("Judith", 0.03125), + ("Julia", 0.03125), + ("Julie", 0.125), + ("Julienne", 0.0078125), + ("Juliette", 0.0625), + ("Justine", 0.015625), + ("Karin", 0.125), + ("Karine", 0.03125), + ("Katia", 0.0078125), + ("Kim", 0.0625), + ("Laetitia", 0.015625), + ("Laura", 0.0078125), + ("Laure", 0.0625), + ("Laurence", 0.125), + ("Laurette", 0.00390625), + ("Léa", 0.0625), + ("Léone", 0.00390625), + ("Léonie", 0.125), + ("Léontine", 0.015625), + ("Liliane", 0.25), + ("Lily", 0.03125), + ("Lina", 0.0625), + ("Linda", 0.125), + ("Louise", 0.25), + ("Lucette", 0.0078125), + ("Lucie", 0.125), + ("Lucienne", 0.0625), + ("Ludivine", 0.00390625), + ("Lydia", 0.03125), + ("Lydiane", 0.00390625), + ("Lydianne", 0.00390625), + ("Lydie", 0.0625), + ("Lysiane", 0.00390625), + ("Madeleine", 0.125), + ("Magali", 0.015625), + ("Magalie", 0.00390625), + ("Maggy", 0.125), + ("Maisy", 0.125), + ("Malou", 0.0625), + ("Manuela", 0.03125), + ("Manuelle", 0.00390625), + ("Marceline", 0.015625), + ("Marcelle", 0.125), + ("Margot", 0.25), + ("Marguerite", 0.25), + ("Maria", 2.0), + ("Marianne", 0.25), + ("Marie", 4.0), + ("Marielle", 0.015625), + ("Mariette", 0.25), + ("Marine", 0.00390625), + ("Marion", 0.0625), + ("Marise", 0.00390625), + ("Marlène", 0.03125), + ("Marlyse", 0.00390625), + ("Marthe", 0.125), + ("Martine", 0.5), + ("Marylène", 0.0078125), + ("Maryline", 0.0078125), + ("Maryse", 0.0625), + ("Maryvonne", 0.00390625), + ("Mathilde", 0.03125), + ("Mauricette", 0.00390625), + ("Mélanie", 0.0625), + ("Michèle", 0.5), + ("Micheline", 0.0625), + ("Michelle", 0.03125), + ("Mimy", 0.00390625), + ("Mireille", 0.125), + ("Monika", 0.03125), + ("Monique", 0.5), + ("Morgane", 0.00390625), + ("Muriel", 0.0625), + ("Murielle", 0.03125), + ("Mylène", 0.015625), + ("Myriam", 0.125), + ("Nadège", 0.0078125), + ("Nadia", 0.03125), + ("Nadine", 0.25), + ("Nancy", 0.0625), + ("Natacha", 0.015625), + ("Nathalie", 0.5), + ("Nelly", 0.125), + ("Nicole", 0.5), + ("Nina", 0.03125), + ("Noëlle", 0.015625), + ("Noémie", 0.0078125), + ("Nora", 0.015625), + ("Octavie", 0.0078125), + ("Odette", 0.0625), + ("Odile", 0.0625), + ("Olga", 0.03125), + ("Pascale", 0.0625), + ("Patricia", 0.25), + ("Paule", 0.125), + ("Paulette", 0.0625), + ("Pauline", 0.0625), + ("Peggy", 0.0625), + ("Petra", 0.03125), + ("Pierette", 0.00390625), + ("Pierrette", 0.0625), + ("Rachel", 0.03125), + ("Rachèle", 0.00390625), + ("Raphaëlle", 0.0078125), + ("Raymonde", 0.0625), + ("Regina", 0.015625), + ("Régine", 0.0625), + ("Reine", 0.00390625), + ("Rejane", 0.0078125), + ("Renée", 0.25), + ("Rita", 0.125), + ("Rolande", 0.0078125), + ("Rollande", 0.00390625), + ("Romaine", 0.0625), + ("Rosa", 0.015625), + ("Rosalie", 0.015625), + ("Rose", 0.125), + ("Rosy", 0.015625), + ("Roxane", 0.00390625), + ("Roxanne", 0.00390625), + ("Ruth", 0.015625), + ("Sabine", 0.03125), + ("Sandra", 0.5), + ("Sandrine", 0.0625), + ("Sandy", 0.0625), + ("Sarah", 0.0625), + ("Scarlette", 0.00390625), + ("Severine", 0.03125), + ("Simone", 0.125), + ("Simonne", 0.00390625), + ("Solange", 0.03125), + ("Sonia", 0.03125), + ("Sophie", 0.125), + ("Stéphanie", 0.125), + ("Susanne", 0.03125), + ("Suzanne", 0.125), + ("Suzette", 0.125), + ("Sylvaine", 0.00390625), + ("Sylvia", 0.015625), + ("Sylviane", 0.015625), + ("Sylvie", 0.5), + ("Thérèse", 0.25), + ("Tina", 0.0625), + ("Ursula", 0.03125), + ("Valérie", 0.125), + ("Vera", 0.03125), + ("Véronique", 0.25), + ("Vicky", 0.03125), + ("Victorine", 0.015625), + ("Vinciane", 0.015625), + ("Violette", 0.00390625), + ("Virginie", 0.0625), + ("Viviane", 0.25), + ("Vivienne", 0.00390625), + ("Yolande", 0.0625), + ("Yvette", 0.125), + ("Yvonne", 0.25), + ) + ) + + first_names_male = OrderedDict( + ( + ("Achille", 0.00390625), + ("Adolphe", 0.015625), + ("Adrien", 0.0625), + ("Aimable", 0.00390625), + ("Alain", 0.5), + ("Albert", 0.5), + ("Alex", 0.25), + ("Alexandre", 0.0625), + ("Alexis", 0.0078125), + ("Alfred", 0.0625), + ("Aloïs", 0.00390625), + ("Alphonse", 0.25), + ("André", 1.0), + ("Andreas", 0.015625), + ("Ange", 0.00390625), + ("Anicet", 0.00390625), + ("Anthony", 0.015625), + ("Antoine", 0.5), + ("Aristide", 0.00390625), + ("Armand", 0.5), + ("Arnaud", 0.015625), + ("Arnold", 0.03125), + ("Arthur", 0.125), + ("Auguste", 0.03125), + ("Aurelien", 0.00390625), + ("Axel", 0.0078125), + ("Baptiste", 0.015625), + ("Bastien", 0.00390625), + ("Benoît", 0.0625), + ("Bernard", 0.5), + ("Bernd", 0.015625), + ("Bertrand", 0.03125), + ("Bruno", 0.0625), + ("Carlo", 0.125), + ("Cédric", 0.03125), + ("Célestin", 0.0078125), + ("Charles", 0.5), + ("Charly", 0.00390625), + ("Christian", 0.25), + ("Christophe", 0.125), + ("Claude", 1.0), + ("Clement", 0.015625), + ("Constant", 0.03125), + ("Corneille", 0.015625), + ("Cornel", 0.00390625), + ("Cyril", 0.0078125), + ("Damien", 0.015625), + ("Dan", 0.03125), + ("Daniel", 0.25), + ("David", 0.125), + ("Denis", 0.0625), + ("Désiré", 0.0078125), + ("Didier", 0.125), + ("Dieter", 0.015625), + ("Dimitri", 0.00390625), + ("Edgar", 0.015625), + ("Edgard", 0.0078125), + ("Edmond", 0.125), + ("Edouard", 0.125), + ("Elie", 0.00390625), + ("Eloi", 0.0078125), + ("Emile", 0.5), + ("Emmanuel", 0.03125), + ("Eric", 0.125), + ("Erik", 0.015625), + ("Ernest", 0.25), + ("Erwin", 0.015625), + ("Etienne", 0.0625), + ("Eugène", 0.25), + ("Fabien", 0.03125), + ("Fabrice", 0.5), + ("Felicien", 0.00390625), + ("Félix", 0.125), + ("Ferdinand", 0.03125), + ("Fernand", 1.0), + ("Firmin", 0.00390625), + ("Florent", 0.03125), + ("Francis", 0.125), + ("Franck", 0.03125), + ("François", 1.0), + ("Frank", 0.25), + ("Franky", 0.0078125), + ("Franz", 0.015625), + ("Freddy", 0.0078125), + ("Frédéric", 0.125), + ("Frederick", 0.00390625), + ("Gabriel", 0.015625), + ("Gaël", 0.00390625), + ("Gaston", 0.25), + ("Georges", 0.5), + ("Gérald", 0.0078125), + ("Gérard", 0.25), + ("Geraud", 0.00390625), + ("Gery", 0.00390625), + ("Ghislain", 0.0078125), + ("Gilbert", 0.25), + ("Gilles", 0.125), + ("Grégoire", 0.015625), + ("Grégory", 0.015625), + ("Guillaume", 0.125), + ("Guy", 1.0), + ("Gwenael", 0.00390625), + ("Hans", 0.0625), + ("Heinz", 0.03125), + ("Helmut", 0.015625), + ("Henri", 0.5), + ("Henrique", 0.015625), + ("Henry", 0.03125), + ("Herbert", 0.015625), + ("Hermann", 0.015625), + ("Hervé", 0.03125), + ("Hugo", 0.015625), + ("Hugues", 0.0078125), + ("Ignace", 0.0078125), + ("Jacky", 0.0078125), + ("Jacques", 0.5), + ("James", 0.015625), + ("Jean", 4.0), + ("Jean-Claude", 0.25), + ("Jean-Luc", 0.0625), + ("Jeannot", 0.25), + ("Jean-Paul", 0.25), + ("Jean-Pierre", 0.25), + ("Jeff", 0.0625), + ("Jeremie", 0.00390625), + ("Jérôme", 0.0625), + ("Jim", 0.03125), + ("Joachim", 0.015625), + ("Joé", 0.0625), + ("Joël", 0.125), + ("John", 0.25), + ("Johnny", 0.015625), + ("Johny", 0.125), + ("Jonathan", 0.015625), + ("Jorge", 0.0625), + ("Joseph", 0.5), + ("Jules", 0.125), + ("Julien", 0.0625), + ("Jürgen", 0.015625), + ("Justin", 0.015625), + ("Karl", 0.015625), + ("Kevin", 0.0078125), + ("Klaus", 0.03125), + ("Kurt", 0.015625), + ("Lambert", 0.015625), + ("Laurent", 0.25), + ("Léandre", 0.0078125), + ("Léo", 0.03125), + ("Léon", 0.5), + ("Léonard", 0.0078125), + ("Léonce", 0.00390625), + ("Léopold", 0.015625), + ("Lionel", 0.015625), + ("Loïc", 0.0078125), + ("Louis", 0.25), + ("Luc", 0.25), + ("Lucien", 0.5), + ("Ludovic", 0.0078125), + ("Manfred", 0.015625), + ("Manuel", 0.125), + ("Marc", 1.0), + ("Marcel", 1.0), + ("Marco", 0.25), + ("Marguy", 0.0078125), + ("Marius", 0.0078125), + ("Martial", 0.0078125), + ("Martin", 0.0625), + ("Mathias", 0.125), + ("Mathieu", 0.0078125), + ("Matthieu", 0.00390625), + ("Maurice", 0.0625), + ("Max", 0.015625), + ("Maxime", 0.015625), + ("Maximilien", 0.00390625), + ("Michael", 0.0625), + ("Michaël", 0.0078125), + ("Michel", 1.0), + ("Mickael", 0.00390625), + ("Mike", 0.125), + ("Narcisse", 0.0078125), + ("Nicolas", 0.5), + ("Noël", 0.015625), + ("Norbert", 0.25), + ("Olivier", 0.125), + ("Oswald", 0.00390625), + ("Pascal", 0.125), + ("Patrice", 0.0625), + ("Patrick", 0.5), + ("Paul", 0.5), + ("Peter", 0.0625), + ("Philippe", 0.25), + ("Pierre", 2.0), + ("Ralph", 0.0625), + ("Raoul", 0.015625), + ("Raphaël", 0.03125), + ("Raymond", 0.5), + ("Réginald", 0.00390625), + ("Régis", 0.0078125), + ("Rémi", 0.0078125), + ("Rémy", 0.0625), + ("Renaud", 0.0078125), + ("René", 1.0), + ("Richard", 0.125), + ("Robert", 0.5), + ("Rodolphe", 0.015625), + ("Roger", 1.0), + ("Roland", 0.25), + ("Romain", 0.5), + ("Ronald", 0.03125), + ("Rudy", 0.0625), + ("Samuel", 0.0078125), + ("Sébastien", 0.03125), + ("Serge", 0.25), + ("Severin", 0.00390625), + ("Séverin", 0.00390625), + ("Simon", 0.0078125), + ("Stefan", 0.015625), + ("Stephan", 0.03125), + ("Stéphane", 0.0625), + ("Steven", 0.0078125), + ("Sylvain", 0.0625), + ("Sylvère", 0.0078125), + ("Tanguy", 0.00390625), + ("Teddy", 0.00390625), + ("Théo", 0.25), + ("Théodore", 0.03125), + ("Théophile", 0.015625), + ("Thibaud", 0.00390625), + ("Thibaut", 0.00390625), + ("Thierry", 0.125), + ("Thomas", 0.0625), + ("Tommy", 0.0078125), + ("Valéry", 0.00390625), + ("Victor", 0.25), + ("Vincent", 0.0625), + ("Vivien", 0.00390625), + ("Werner", 0.03125), + ("William", 0.015625), + ("Willy", 0.0625), + ("Wolfgang", 0.03125), + ("Xavier", 0.03125), + ("Yann", 0.015625), + ("Yannick", 0.015625), + ("Yvan", 0.015625), + ("Yves", 0.25), + ("Yvon", 0.03125), + ) + ) + + first_names_nonbinary = OrderedDict( + [("Claudy", 0.00390625), ("Cyrille", 0.0078125), ("Dominique", 0.125)] + + list(first_names_female.items()) + + list(first_names_male.items()) + ) diff --git a/faker/providers/phone_number/de_AT/__init__.py b/faker/providers/phone_number/de_AT/__init__.py new file mode 100644 index 0000000000..180e2d7542 --- /dev/null +++ b/faker/providers/phone_number/de_AT/__init__.py @@ -0,0 +1,120 @@ +from .. import Provider as PhoneNumberProvider + + +class Provider(PhoneNumberProvider): + """Phone number provider for `de_AT` locale. + + Sources: + - https://de.wikipedia.org/wiki/Telefonvorwahl_(%C3%96sterreich) + + """ + + dialing_codes = ( + "650", + "655", + "660", + "661", + "663", + "664", + "665", + "667", + "670", + "676", + "677", + "678", + "680", + "681", + "688", + "690", + "699", + ) + + area_code_formats = ( + "1", # Wien + "316", # Graz + "463", # Klagenfurt + "512", # Innsbruck + "662", # Salzburg + "732", # Linz + "21##", + "22##", + "25##", + "26##", + "27##", + "28##", + "29##", + "31##", + "33##", + "34##", + "35##", + "36##", + "38##", + "42##", + "43##", + "47##", + "48##", + "52##", + "53##", + "54##", + "55##", + "56##", + "61##", + "62##", + "64##", + "65##", + "72##", + "73##", + "74##", + "75##", + "76##", + "77##", + "79##", + ) + + cellphone_formats = ( + "+43 (0) {{dialing_code}} ########", + "+43 {{dialing_code}} ### ### ##", + "+43 {{dialing_code}}########", + "0{{dialing_code}} ### ### ##", + "0{{dialing_code}}/########", + ) + + landline_formats = ( + "+43 (0) {{area_code}} ########", + "+43 {{area_code}} ##### ###", + "+43 {{area_code}}########", + "0{{area_code}} ##### ###", + "(0{{area_code}}) ##### ###", + "0{{area_code}}/########", + ) + + """ + Get dialing code for cellphone numbers. + """ + + def dialing_code(self) -> str: + return self.random_element(self.dialing_codes) + + """ + Get area code for landlines. + """ + + def area_code(self) -> str: + area_code: str = self.random_element(self.area_code_formats) + return self.numerify(area_code) + + """ + Get a landline phone number. + """ + + def phone_number(self) -> str: + pattern: str = self.random_element(self.landline_formats) + return self.numerify(self.generator.parse(pattern)) + + """ + Get a cellphone number. + """ + + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) + return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/de_CH/__init__.py b/faker/providers/phone_number/de_CH/__init__.py index b0210d7b7a..596b4ce302 100644 --- a/faker/providers/phone_number/de_CH/__init__.py +++ b/faker/providers/phone_number/de_CH/__init__.py @@ -2,36 +2,80 @@ class Provider(PhoneNumberProvider): - formats = ( - # source: https://de.wikipedia.org/wiki/Telefonnummer_(Schweiz)#Schreibweisen - "+41 2# ### ## ##", - "+41 3# ### ## ##", - "+41 4# ### ## ##", - "+41 5# ### ## ##", - "+41 6# ### ## ##", - "+41 7# ### ## ##", - "+41 8# ### ## ##", - "+41 9# ### ## ##", - "+41 (0)2# ### ## ##", - "+41 (0)3% ### ## ##", - "+41 (0)4% ### ## ##", - "+41 (0)5# ### ## ##", - "+41 (0)6# ### ## ##", - "+41 (0)7% ### ## ##", - "+41 (0)8# ### ## ##", - "+41 (0)9# ### ## ##", - "02# ### ## ##", - "03% ### ## ##", - "04% ### ## ##", - "05# ### ## ##", - "06# ### ## ##", - "07% ### ## ##", - "08# ### ## ##", - "09# ### ## ##", - # see: http://www.bakom.admin.ch/themen/telekom/00479/00607/index.html - "084# ### ###", - "0878 ### ###", - "0900 ### ###", - "0901 ### ###", - "0906 ### ###", + """Phone number provider for `de_CH` locale. + + Sources: + - https://de.wikipedia.org/wiki/Telefonnummer_(Schweiz) + + """ + + dialing_codes = ( + "75", + "76", + "77", + "78", + "79", + ) + + landline_codes = ( + "21", + "22", + "24", + "26", + "27", + "31", + "32", + "33", + "34", + "43", + "41", + "44", + "52", + "55", + "56", + "61", + "62", + "71", + "81", + "91", + ) + + cellphone_formats = ( + "+41 {{dialing_code}} ### ## ##", + "0{{dialing_code}} ### ## ##", + ) + + landline_formats = ( + "+41 {{landline_code}} ### ## ##", + "0{{landline_code}} ### ## ##", ) + + """ + Get dialing code for cellphone numbers. + """ + + def dialing_code(self) -> str: + return self.random_element(self.dialing_codes) + + """ + Get dialing code for landlines. + """ + + def landline_code(self) -> str: + return self.random_element(self.landline_codes) + + """ + Get a landline phone number. + """ + + def phone_number(self) -> str: + pattern: str = self.random_element(self.landline_formats) + return self.numerify(self.generator.parse(pattern)) + + """ + Get a cellphone number. + """ + + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) + return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/de_LI/__init__.py b/faker/providers/phone_number/de_LI/__init__.py new file mode 100644 index 0000000000..69ef8a68a3 --- /dev/null +++ b/faker/providers/phone_number/de_LI/__init__.py @@ -0,0 +1,6 @@ +from .. import Provider as PhoneNumberProvider + + +class Provider(PhoneNumberProvider): + # https://en.wikipedia.org/wiki/Telephone_numbers_in_Liechtenstein + formats = ("%## ## ##", "+423 %## ## ##") diff --git a/faker/providers/phone_number/de_LU/__init__.py b/faker/providers/phone_number/de_LU/__init__.py new file mode 100644 index 0000000000..9097cf3512 --- /dev/null +++ b/faker/providers/phone_number/de_LU/__init__.py @@ -0,0 +1,37 @@ +from .. import Provider as PhoneNumberProvider + + +class Provider(PhoneNumberProvider): + # https://de.wikipedia.org/wiki/Telefonvorwahl_(Luxemburg) + formats = ( + "22 ## ##", + "23 ## ##", + "24 $# ## ##", + "25 ## ##", + "26 $# ## ##", + "27 $# ## ##", + "28 ## ##", + "29 ## ##", + "3# ## ##", + "4 ### ##", + "71 ## ##", + "72 ## ##", + "74 ## ##", + "75 ## ##", + "76 ## ##", + "78 ## ##", + "80 ## ##", + "81 ## ##", + "83 ## ##", + "87 ## ##", + "88 ## ##", + "89 ## ##", + "92 ## ##", + "95 ## ##", + "99 ## ##", + ) + + prefixes = ("+352 ", "") + + def phone_number(self) -> str: + return self.random_element(self.prefixes) + self.numerify(self.random_element(self.formats)) diff --git a/faker/providers/ssn/de_AT/__init__.py b/faker/providers/ssn/de_AT/__init__.py index f55beef485..e4ef2602e3 100644 --- a/faker/providers/ssn/de_AT/__init__.py +++ b/faker/providers/ssn/de_AT/__init__.py @@ -1,3 +1,6 @@ +from datetime import date +from typing import Optional + from .. import Provider as BaseProvider @@ -15,3 +18,31 @@ def vat_id(self) -> str: """ return self.bothify(self.random_element(self.vat_id_formats)) + + def __get_check_digit(self, ssn_without_checkdigit: str) -> int: + factors: list[int] = [3, 7, 9, 5, 8, 4, 2, 1, 6] + ssn_numbers: list[int] = [int(char) for char in ssn_without_checkdigit] + + sum: int = 0 + for index, factor in enumerate(factors): + sum += ssn_numbers[index] * factor + + check_digit = sum % 11 + + return check_digit + + def ssn(self, birthdate: Optional[date] = None) -> str: + """ + Source: https://de.wikipedia.org/wiki/Sozialversicherungsnummer#Berechnung + :return: a random valid Austrian social security number + """ + _birthdate = birthdate or self.generator.date_object() + format: str = f"%##{_birthdate.strftime('%d%m%y')}" + ssn: str = self.numerify(format) + check_digit: int = self.__get_check_digit(ssn) + + while check_digit > 9: + ssn = self.numerify(format) + check_digit = self.__get_check_digit(ssn) + + return ssn[:3] + str(self.__get_check_digit(ssn)) + ssn[3:] diff --git a/faker/providers/ssn/de_DE/__init__.py b/faker/providers/ssn/de_DE/__init__.py index f5ee062067..14af05f34d 100644 --- a/faker/providers/ssn/de_DE/__init__.py +++ b/faker/providers/ssn/de_DE/__init__.py @@ -1,17 +1,100 @@ +from datetime import date +from string import ascii_uppercase +from typing import Optional + +from faker.utils.checksums import luhn_checksum + from .. import Provider as BaseProvider class Provider(BaseProvider): """ - A Faker provider for the German VAT IDs + A Faker provider for the German VAT ID and the pension insurance number + + Sources: + + - http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 + - https://de.wikipedia.org/wiki/Versicherungsnummer """ vat_id_formats = ("DE#########",) + def __letter_to_digit_string(self, letter: str) -> str: + digit = ascii_uppercase.index(letter) + 1 + if len(str(digit)) == 2: + return str(digit) + return "0" + str(digit) + + def __get_rvnr_checkdigit(self, rvnr: str) -> str: + # replace the letter at index 8 with its corresponding number + letter = rvnr[8] + rvnr = rvnr[:8] + self.__letter_to_digit_string(letter) + rvnr[9:] + + # calculate the product of each digit with the corresponding factor + factors = [2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1] + products = [] + for index, digit in enumerate(rvnr): + products.append(int(digit) * factors[index]) + + # calculate the digit sum for each product + digit_sums = [] + for product in products: + digit_sum = 0 + while product: + digit_sum += product % 10 + product = product // 10 + digit_sums.append(digit_sum) + + # get the check digit by summing up the digit sums and calculating the modulo of 10 + return str(sum(digit_sums) % 10) + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 + :return: A random German VAT ID """ return self.bothify(self.random_element(self.vat_id_formats)) + + def rvnr(self, birthdate: Optional[date] = None) -> str: + """ + Pension insurance number (German: "Rentenversicherungsnummer", abbr. "RVNR") + + Source: https://de.wikipedia.org/wiki/Versicherungsnummer + + :return: A valid German pension insurance number + """ + _birthdate = birthdate or self.generator.date_object() + format: str = f"##{_birthdate.strftime('%d%m%y')}?##" + rvnr: str = self.bothify(format, letters=ascii_uppercase) + + return rvnr + self.__get_rvnr_checkdigit(rvnr) + + def kvnr(self) -> str: + """ + German health insurance number ("Krankenversichertennummer", abbr. "KVNR") + + Source: https://de.wikipedia.org/wiki/Krankenversichertennummer + + :return: a random health insurance number + """ + + letter_number: str = str(self.random_int(min=1, max=26)) + if len(letter_number) == 1: + letter_number = "0" + letter_number + + first_part_format: str = letter_number + "########" + first_part: str = self.numerify(first_part_format) + first_checkdigit: int = luhn_checksum(int(first_part[::-1])) + second_part_format: str = "#########" + second_part: str = self.numerify(second_part_format) + + kvnr: str = first_part + str(first_checkdigit) + second_part + kvnr_checkdigit: int = luhn_checksum(int(kvnr[::-1])) + kvnr = kvnr + str(kvnr_checkdigit) + + letter: str = ascii_uppercase[int(letter_number) - 1] + kvnr = letter + kvnr[2:] + + return kvnr diff --git a/faker/proxy.pyi b/faker/proxy.pyi index 163f973cc5..a20a1b4b95 100644 --- a/faker/proxy.pyi +++ b/faker/proxy.pyi @@ -2983,6 +2983,9 @@ class Faker: def local_latitude(self) -> Decimal: ... def local_longitude(self) -> Decimal: ... + def academic_prefix(self) -> str: ... + def academic_suffix(self) -> str: ... + def dialing_code(self) -> str: ... def canton(self) -> Tuple[str, str]: """ Randomly returns a swiss canton ('Abbreviated', 'Name'). @@ -3004,6 +3007,30 @@ class Faker: """ ... + def landline_code(self) -> str: ... + def civil_status(self) -> Tuple[str, str]: ... + def civil_status_code(self) -> str: ... + def civil_status_name(self) -> str: ... + def kvnr(self) -> str: + """ + German health insurance number ("Krankenversichertennummer", abbr. "KVNR") + + Source: https://de.wikipedia.org/wiki/Krankenversichertennummer + + :return: a random health insurance number + """ + ... + + def rvnr(self, birthdate: Optional[datetime.date] = ...) -> str: + """ + Pension insurance number (German: "Rentenversicherungsnummer", abbr. "RVNR") + + Source: https://de.wikipedia.org/wiki/Versicherungsnummer + + :return: A valid German pension insurance number + """ + ... + def line_address(self) -> str: ... def region(self) -> str: ... def street_prefix(self) -> str: ... @@ -3368,7 +3395,6 @@ class Faker: ... def cellphone_block(self) -> str: ... - def landline_code(self) -> str: ... def special_code(self) -> str: ... def company_rut(self) -> str: """ diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py index 1d26596efe..b15745a172 100644 --- a/tests/providers/test_automotive.py +++ b/tests/providers/test_automotive.py @@ -3,6 +3,7 @@ from typing import Pattern from faker.providers.automotive import calculate_vin_str_weight +from faker.providers.automotive.de_AT import Provider as DeAtAutomotiveProvider from faker.providers.automotive.de_DE import Provider as DeDeAutomotiveProvider from faker.providers.automotive.es_ES import Provider as EsEsAutomotiveProvider from faker.providers.automotive.ro_RO import Provider as RoRoAutomotiveProvider @@ -84,6 +85,16 @@ class TestHuHu(_SimpleAutomotiveTestMixin): license_plate_pattern: Pattern = re.compile(r"[A-Z]{3}-\d{3}") +class TestDeAt(_SimpleAutomotiveTestMixin): + """Test de_AT automotive provider methods""" + + license_plate_pattern: Pattern = re.compile(r"(?P[A-Z]{1,2})-[1-9]{1}[0-9]{0,4} [A-Z]{1,3}") + + def perform_extra_checks(self, license_plate, match): + assert match.group("prefix") in DeAtAutomotiveProvider.license_plate_prefix + assert len(license_plate) in (8, 9) + + class TestDeDe(_SimpleAutomotiveTestMixin): """Test de_DE automotive provider methods""" diff --git a/tests/providers/test_color.py b/tests/providers/test_color.py index 58c4f3a66b..53b0442dca 100644 --- a/tests/providers/test_color.py +++ b/tests/providers/test_color.py @@ -10,6 +10,9 @@ from faker.providers.color.az_AZ import Provider as AzAzColorProvider from faker.providers.color.bg_BG import Provider as BgBgColorProvider from faker.providers.color.cs_CZ import Provider as CsCzColorProvider +from faker.providers.color.de_AT import Provider as DeAtColorProvider +from faker.providers.color.de_CH import Provider as DeChColorProvider +from faker.providers.color.de_DE import Provider as DeDeColorProvider from faker.providers.color.el_GR import Provider as ElGrColorProvider from faker.providers.color.es_ES import Provider as EsEsColorProvider from faker.providers.color.fa_IR import Provider as FaIrColorProvider @@ -316,6 +319,37 @@ def test_color_name(self, faker, num_samples): assert color_name in AzAzColorProvider.all_colors.keys() +class TestDeAt: + """Test de_AT color provider methods""" + + def test_color_name(self, faker, num_samples): + for _ in range(num_samples): + color_name = faker.color_name() + assert isinstance(color_name, str) + assert color_name in DeAtColorProvider.all_colors.keys() + + +class TestDeCh: + """Test de_CH color provider methods""" + + def test_color_name(self, faker, num_samples): + for _ in range(num_samples): + color_name = faker.color_name() + assert isinstance(color_name, str) + assert color_name in DeChColorProvider.all_colors.keys() + assert "ß" not in color_name + + +class TestDeDe: + """Test de_DE color provider methods""" + + def test_color_name(self, faker, num_samples): + for _ in range(num_samples): + color_name = faker.color_name() + assert isinstance(color_name, str) + assert color_name in DeDeColorProvider.all_colors.keys() + + class TestHyAm: """Test hy_AM color provider methods""" diff --git a/tests/providers/test_company.py b/tests/providers/test_company.py index 2face87f1d..c6285eaeb0 100644 --- a/tests/providers/test_company.py +++ b/tests/providers/test_company.py @@ -7,6 +7,8 @@ import pytest from faker.providers.company.az_AZ import Provider as AzAzCompanyProvider +from faker.providers.company.de_AT import Provider as DeAtCompanyProvider +from faker.providers.company.de_CH import Provider as DeChCompanyProvider from faker.providers.company.el_GR import Provider as ElGrCompanyProvider from faker.providers.company.en_PH import Provider as EnPhCompanyProvider from faker.providers.company.es_ES import Provider as EsEsCompanyProvider @@ -45,6 +47,36 @@ def test_large_companies(self, faker, num_samples): assert company in AzAzCompanyProvider.large_companies +class TestDeAt: + """Test de_AT company provider methods""" + + def test_company_suffix(self, faker, num_samples): + for _ in range(num_samples): + suffix = faker.company_suffix() + assert isinstance(suffix, str) + assert suffix in DeAtCompanyProvider.company_suffixes + + def test_company(self, faker, num_samples): + for _ in range(num_samples): + company = faker.company() + assert isinstance(company, str) + + +class TestDeCh: + """Test de_CH company provider methods""" + + def test_company_suffix(self, faker, num_samples): + for _ in range(num_samples): + suffix = faker.company_suffix() + assert isinstance(suffix, str) + assert suffix in DeChCompanyProvider.company_suffixes + + def test_company(self, faker, num_samples): + for _ in range(num_samples): + company = faker.company() + assert isinstance(company, str) + + class TestFiFi: """Test fi_FI company provider methods""" diff --git a/tests/providers/test_currency.py b/tests/providers/test_currency.py index 06914da458..ec3e6431f4 100644 --- a/tests/providers/test_currency.py +++ b/tests/providers/test_currency.py @@ -165,12 +165,65 @@ def setup_class(cls): from faker.providers.currency.de_AT import Provider as DeAtCurrencyProvider cls.provider = DeAtCurrencyProvider + cls.currencies = cls.provider.currencies + cls.currency_names = [currency_name for currency_code, currency_name in cls.currencies] + cls.currency_codes = [currency_code for currency_code, currency_name in cls.currencies] def test_pricetag(self, faker, num_samples): for _ in range(num_samples): pricetag = faker.pricetag() assert isinstance(pricetag, str) + def test_currency(self, faker, num_samples): + for _ in range(num_samples): + cur = faker.currency() + assert cur in self.provider.currencies + + def test_currency_name(self, faker, num_samples): + for _ in range(num_samples): + name = faker.currency_name() + assert name in self.currency_names + + def test_currency_code(self, faker, num_samples): + for _ in range(num_samples): + code = faker.currency_code() + assert code in self.currency_codes + + +class TestDeCh: + """Test de_CH currency provider""" + + num_samples = 100 + + @classmethod + def setup_class(cls): + from faker.providers.currency.de_CH import Provider as DeChCurrencyProvider + + cls.provider = DeChCurrencyProvider + cls.currencies = cls.provider.currencies + cls.currency_names = [currency_name for currency_code, currency_name in cls.currencies] + cls.currency_codes = [currency_code for currency_code, currency_name in cls.currencies] + + def test_pricetag(self, faker, num_samples): + for _ in range(num_samples): + pricetag = faker.pricetag() + assert isinstance(pricetag, str) + + def test_currency(self, faker, num_samples): + for _ in range(num_samples): + cur = faker.currency() + assert cur in self.provider.currencies + + def test_currency_name(self, faker, num_samples): + for _ in range(num_samples): + name = faker.currency_name() + assert name in self.currency_names + + def test_currency_code(self, faker, num_samples): + for _ in range(num_samples): + code = faker.currency_code() + assert code in self.currency_codes + class TestDeDe: """Test de_DE currency provider""" @@ -182,12 +235,30 @@ def setup_class(cls): from faker.providers.currency.de_DE import Provider as DeDeCurrencyProvider cls.provider = DeDeCurrencyProvider + cls.currencies = cls.provider.currencies + cls.currency_names = [currency_name for currency_code, currency_name in cls.currencies] + cls.currency_codes = [currency_code for currency_code, currency_name in cls.currencies] def test_pricetag(self, faker, num_samples): for _ in range(num_samples): pricetag = faker.pricetag() assert isinstance(pricetag, str) + def test_currency(self, faker, num_samples): + for _ in range(num_samples): + cur = faker.currency() + assert cur in self.provider.currencies + + def test_currency_name(self, faker, num_samples): + for _ in range(num_samples): + name = faker.currency_name() + assert name in self.currency_names + + def test_currency_code(self, faker, num_samples): + for _ in range(num_samples): + code = faker.currency_code() + assert code in self.currency_codes + class TestEnAu: """Test en_AU currency provider""" diff --git a/tests/providers/test_passport.py b/tests/providers/test_passport.py index 096b4a788e..002e102826 100644 --- a/tests/providers/test_passport.py +++ b/tests/providers/test_passport.py @@ -1,116 +1,23 @@ import re -from datetime import date, datetime, timedelta +from typing import Pattern -from faker.providers.person.en_US import Provider as EnUSPersonProvider -from faker.providers.person.ru_RU import Provider as RuRuPersonProvider +class TestPassport: + """Test passport provider methods""" -class TestBaseProvider: - - def test_dob(self, faker, num_samples): - for _ in range(num_samples): - dob = faker.passport_dob() - age = (date.today() - dob).days // 365 - assert isinstance(dob, date) - assert age <= 115 - assert age >= 0 - - def test_owner_names(self, faker, num_samples): - for _ in range(num_samples): - given_name, surname = faker.passport_owner("F") - assert given_name in EnUSPersonProvider.first_names_female - assert surname in EnUSPersonProvider.last_names - - given_name, surname = faker.passport_owner("M") - assert given_name in EnUSPersonProvider.first_names_male - assert surname in EnUSPersonProvider.last_names - - given_name, surname = faker.passport_owner("X") - assert given_name in EnUSPersonProvider.first_names_nonbinary - assert surname in EnUSPersonProvider.last_names - - def test_num_formats(self, faker, num_samples): - for _ in range(num_samples): - pass_number = faker.passport_number() - - if pass_number[0].isalpha(): - assert pass_number[1:].isdigit() - else: - assert pass_number.isdigit() - - assert len(pass_number) == 9 - - -class TestEnUS: - def test_dates(self, faker, num_samples=20): - age4 = date.today() - timedelta(days=4 * 365) - age12 = date.today() - timedelta(days=12 * 365) - age17 = date.today() - timedelta(days=17 * 365) - age23 = date.today() - timedelta(days=23 * 365) - age30 = date.today() - timedelta(days=30 * 365) - - birthdays = [(age4, 4), (age12, 12), (age17, 17), (age23, 23), (age30, 30)] - for _ in range(num_samples): - for birthday in birthdays: - birth_date_f, issue_date_f, expiry_date_f = faker.passport_dates(birthday[0]) - birth_date = datetime.strptime(birth_date_f, "%d %b %Y").date() - issue_date = datetime.strptime(issue_date_f, "%d %b %Y").date() - expiry_date = datetime.strptime(expiry_date_f, "%d %b %Y").date() - - if birthday[1] < 21: - assert (expiry_date - issue_date).days // 365 == 5 - else: - assert (expiry_date - issue_date).days // 365 == 10 - - assert expiry_date > issue_date - assert birth_date < issue_date - - def test_gender(self, faker, num_samples=100): - for _ in range(num_samples): - assert faker.passport_gender(7899) in ["M", "F", "X"] - - def test_full(self, faker, num_samples=100): - for _ in range(num_samples): - pass_data = faker.passport_full().split("\n") - assert pass_data[1] in EnUSPersonProvider.last_names - assert pass_data[2] in ["M", "F", "X"] - if pass_data[2] == "M": - assert pass_data[0] in EnUSPersonProvider.first_names_male - elif pass_data[2] == "F": - assert pass_data[0] in EnUSPersonProvider.first_names_female - elif pass_data[2] == "X": - assert pass_data[0] in EnUSPersonProvider.first_names_nonbinary - - -class TestRuRu: - - def test_owner_names(self, faker, num_samples): + def test_passport_number(self, faker, num_samples): for _ in range(num_samples): - last_name, first_name_with_middle = faker.passport_owner("F") - first_name, middle_name = first_name_with_middle.split() - assert last_name in RuRuPersonProvider.last_names_female - assert first_name in RuRuPersonProvider.first_names_female - assert middle_name in RuRuPersonProvider.middle_names_female - - last_name, first_name_with_middle = faker.passport_owner("M") - first_name, middle_name = first_name_with_middle.split() - assert last_name in RuRuPersonProvider.last_names_male - assert first_name in RuRuPersonProvider.first_names_male - assert middle_name in RuRuPersonProvider.middle_names_male + passport_number = faker.passport_number() + assert isinstance(passport_number, str) - last_name, first_name_with_middle = faker.passport_owner("X") - first_name, middle_name = first_name_with_middle.split() - assert last_name in RuRuPersonProvider.last_names_male - assert first_name in RuRuPersonProvider.first_names_male - assert middle_name in RuRuPersonProvider.middle_names_male - def test_number(self, faker, num_samples): - ru_passport_regex_1 = re.compile(r"\d\d \d\d \d{6}") - ru_passport_regex_2 = re.compile(r"\d{4} \d{6}") +class TestDeAt: + """Test de_AT passport provider methods""" + def test_passport_number(self, faker, num_samples): for _ in range(num_samples): - number = faker.passport_number() - assert sum(map(lambda x: x.isdigit(), number)) == 4 + 6 - assert ru_passport_regex_1.match(number) or ru_passport_regex_2.match(number) + pattern: Pattern = re.compile(r"[A-Z]{1,2}\d{7}") + passport_number = faker.passport_number() + assert pattern.fullmatch(passport_number) diff --git a/tests/providers/test_person.py b/tests/providers/test_person.py index e411101bd5..6ee221fe35 100644 --- a/tests/providers/test_person.py +++ b/tests/providers/test_person.py @@ -8,6 +8,8 @@ from faker.providers.person.ar_AA import Provider as ArProvider from faker.providers.person.az_AZ import Provider as AzAzProvider from faker.providers.person.cs_CZ import Provider as CsCZProvider +from faker.providers.person.de_AT import Provider as DeAtProvider +from faker.providers.person.de_LI import Provider as DeLiProvider from faker.providers.person.en import Provider as EnProvider from faker.providers.person.en_GB import Provider as EnGBProvider from faker.providers.person.en_IE import Provider as EnIEProvider @@ -210,6 +212,92 @@ def test_name_female(self): assert last_name in CsCZProvider.last_names_female +class TestDeAt(unittest.TestCase): + """Tests person in the de_AT locale""" + + def setUp(self): + self.fake = Faker("de_AT") + Faker.seed(0) + + def test_academic_prefix(self): + academic_prefix = self.fake.academic_prefix() + assert isinstance(academic_prefix, str) + assert academic_prefix in DeAtProvider.academic_prefixes + + def test_academic_suffix(self): + academic_suffix = self.fake.academic_suffix() + assert isinstance(academic_suffix, str) + assert academic_suffix in DeAtProvider.academic_suffixes + + def test_first_name(self): + first_name = self.fake.first_name() + assert isinstance(first_name, str) + assert first_name in DeAtProvider.first_names + + def test_first_name_female(self): + name_female = self.fake.first_name_female() + assert isinstance(name_female, str) + assert name_female in DeAtProvider.first_names_female + + def test_first_name_male(self): + name_male = self.fake.first_name_male() + assert isinstance(name_male, str) + assert name_male in DeAtProvider.first_names_male + + def test_first_name_nonbinary(self): + name_nonbinary = self.fake.first_name_nonbinary() + assert isinstance(name_nonbinary, str) + assert name_nonbinary in DeAtProvider.first_names + + def test_last_name(self): + last_name = self.fake.last_name() + assert isinstance(last_name, str) + assert last_name in DeAtProvider.last_names + + def test_prefix(self): + prefix = self.fake.prefix() + assert isinstance(prefix, str) + assert prefix in DeAtProvider.prefixes + + def test_prefix_female(self): + prefix_female = self.fake.prefix_female() + assert isinstance(prefix_female, str) + assert prefix_female in DeAtProvider.prefixes_female + + def test_prefix_male(self): + prefix_male = self.fake.prefix_male() + assert isinstance(prefix_male, str) + assert prefix_male in DeAtProvider.prefixes_male + + def test_prefix_nonbinary(self): + prefix_nonbinary = self.fake.prefix_nonbinary() + assert isinstance(prefix_nonbinary, str) + assert prefix_nonbinary in DeAtProvider.prefixes + + +class TestDeLi(unittest.TestCase): + """Tests person in the de_LI locale""" + + def setUp(self): + self.fake = Faker("de_LI") + Faker.seed(0) + + def test_first_name(self): + first_name = self.fake.first_name() + assert isinstance(first_name, str) + assert first_name in DeLiProvider.first_names + + def test_first_name_female(self): + name_female = self.fake.first_name_female() + assert isinstance(name_female, str) + assert name_female in DeLiProvider.first_names_female + + def test_first_name_male(self): + name_male = self.fake.first_name_male() + assert isinstance(name_male, str) + assert name_male in DeLiProvider.first_names_male + + class TestEn(unittest.TestCase): """Tests person in the en locale""" diff --git a/tests/providers/test_phone_number.py b/tests/providers/test_phone_number.py index 24fe8d3c7b..44e835f723 100644 --- a/tests/providers/test_phone_number.py +++ b/tests/providers/test_phone_number.py @@ -3,6 +3,8 @@ from typing import Pattern from faker.providers.phone_number import Provider as PhoneNumberProvider +from faker.providers.phone_number.de_AT import Provider as DeAtPhoneNumberProvider +from faker.providers.phone_number.de_CH import Provider as DeChPhoneNumberProvider from faker.providers.phone_number.en_PH import Provider as EnPhPhoneNumberProvider @@ -97,16 +99,6 @@ def test_landline_number(self, faker, num_samples): assert self.landline_patterns.fullmatch(landline_number) -class TestDeCh: - def test_phone_number(self, faker, num_samples): - pattern: Pattern = re.compile( - r"((0041|\+41) ?)?((\(0\)|0)?\d{2})? ?[0-9]{3} ?[0-9]{2} ?[0-9]{2}|" r"0[89][0-9]{2} ?[0-9]{3} ?[0-9]{3}" - ) - for _ in range(num_samples): - phone_number = faker.phone_number() - assert pattern.fullmatch(phone_number) - - class TestFrCh: def test_phone_number(self, faker, num_samples): pattern: Pattern = re.compile( @@ -137,6 +129,45 @@ def test_phone_number(self, faker, num_samples): assert pattern.fullmatch(phone_number) +class TestDeAt: + """Test de_AT phone number provider methods""" + + landline_pattern: Pattern = re.compile(r"(\+43( \(0\))?|\(?0)\s?(?P[0-9]{1,4})\)?\s?\/?[0-9 ]+") + cellphone_pattern: Pattern = re.compile(r"(\+43( \(0\))?|0)\s?(?P[0-9]{3})\s?\/?[0-9 ]+") + + def test_phone_number(self, faker, num_samples): + for _ in range(num_samples): + phone_number = faker.phone_number() + assert self.landline_pattern.fullmatch(phone_number) + + def test_cellphone_number(self, faker, num_samples): + for _ in range(num_samples): + cellphone_number = faker.cellphone_number() + assert self.cellphone_pattern.fullmatch(cellphone_number) + assert ( + self.cellphone_pattern.match(cellphone_number).group("dialing_code") + in DeAtPhoneNumberProvider.dialing_codes + ) + + +class TestDeCh: + """Test de_CH phone number provider methods""" + + pattern: Pattern = re.compile(r"(\+41|0) ?(?P\d{2}) \d{3} \d{2} \d{2}") + + def test_phone_number(self, faker, num_samples): + for _ in range(num_samples): + phone_number = faker.phone_number() + assert self.pattern.fullmatch(phone_number) + assert self.pattern.match(phone_number).group("dialing_code") in DeChPhoneNumberProvider.landline_codes + + def test_cellphone_number(self, faker, num_samples): + for _ in range(num_samples): + cellphone_number = faker.cellphone_number() + assert self.pattern.fullmatch(cellphone_number) + assert self.pattern.match(cellphone_number).group("dialing_code") in DeChPhoneNumberProvider.dialing_codes + + class TestEnPh: """Test en_PH phone number provider methods""" diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py index a4955c326b..a99b2224df 100644 --- a/tests/providers/test_ssn.py +++ b/tests/providers/test_ssn.py @@ -201,6 +201,51 @@ def test_vat_id(self): for _ in range(100): assert re.search(r"^ATU\d{8}$", self.fake.vat_id()) + def test_ssn(self): + for _ in range(100): + ssn: str = self.fake.ssn() + assert len(ssn) == 10 + assert len(self.fake.ssn(self.fake.date_of_birth())) == 10 + + def test_ssn_checkdigit(self): + for _ in range(100): + ssn: str = self.fake.ssn() + ssn_digits: list[int] = [int(char) for char in ssn[:3] + ssn[4:]] + factors: list[int] = [3, 7, 9, 5, 8, 4, 2, 1, 6] + sum: int = 0 + for index, digit in enumerate(ssn_digits): + sum += digit * factors[index] + assert sum % 11 == int(ssn[3]) + + +class TestDeDe(unittest.TestCase): + def setUp(self): + self.fake = Faker("de_DE") + self.rvnr_pattern: Pattern = re.compile(r"\d{8}[A-Z]\d{3}") + self.kvnr_pattern: Pattern = re.compile(r"[A-Z]\d{19}") + Faker.seed(0) + + def test_vat_id(self): + for _ in range(100): + assert re.search(r"^DE\d{9}$", self.fake.vat_id()) + + def test_rvnr(self): + for _ in range(100): + rvnr = self.fake.rvnr() + assert self.rvnr_pattern.fullmatch(rvnr) + + def test_rvnr_birthdate(self): + for _ in range(100): + birthdate: datetime.date = self.fake.date_object() + rvnr = self.fake.rvnr(birthdate) + assert self.rvnr_pattern.fullmatch(rvnr) + assert rvnr[2:8] == birthdate.strftime("%d%m%y") + + def test_kvnr(self): + for _ in range(100): + kvnr = self.fake.kvnr() + assert self.kvnr_pattern.fullmatch(kvnr) + class TestElCY(unittest.TestCase): def setUp(self):