Repository: joke2k/faker
Pull request #729 (2018-03-17 18:22:11)

Improved currency provider
### What does this changes

I added:
- Currencies' long names
- Method to get theses names
- Cryptocurrencies' long names
- Method to get theses names
- Added some cryptocurrencies
- With tests


Patch:
diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py
index 417a033e..b7418fc1 100644
--- a/faker/providers/__init__.py
+++ b/faker/providers/__init__.py
@@ -12,7 +12,6 @@ _re_perc = re.compile(r'%')
 _re_excl = re.compile(r'!')
 _re_at = re.compile(r'@')
 _re_qm = re.compile(r'\?')
-_re_cir = re.compile(r'\^')
 
 
 class BaseProvider(object):
@@ -214,17 +213,3 @@ class BaseProvider(object):
         :returns: string with all numerical and letter placeholders filled in
         """
         return self.lexify(self.numerify(text), letters=letters)
-
-    def hexify(self, text='^^^^', upper=False):
-        """
-        Replaces all circumflex ('^') occurrences with a random
-        hexadecimal character.
-
-        :param text: string to be parsed
-        :param upper: Format as uppercase hexadecimal
-        :returns: string with all letter placeholders filled in
-        """
-        letters = string.hexdigits[:-6]
-        if upper:
-            letters = letters.upper()
-        return _re_cir.sub(lambda x: self.random_element(letters), text)
diff --git a/faker/providers/automotive/de_DE/__init__.py b/faker/providers/automotive/de_DE/__init__.py
deleted file mode 100644
index 14bc54d3..00000000
--- a/faker/providers/automotive/de_DE/__init__.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# coding=utf-8
-
-
-from __future__ import unicode_literals
-from .. import Provider as AutomotiveProvider
-import string
-
-
-class Provider(AutomotiveProvider):
-
-    # http://berlin.de/daten/liste-der-kfz-kennzeichen/kfz-kennz-d.csv
-    license_plate_prefix = (
-        'A', 'AA', 'AB', 'ABI', 'ABG', 'AC', 'AE', 'AIC', 'AK', 'AM', 'AN', 'AÖ', 'AP', 'AS', 'AUR', 'AW', 'AZ', 'B',
-        'BA', 'BAD', 'BAR', 'BB', 'BC', 'BD', 'BGL', 'BI', 'BIR', 'BIT', 'BK', 'BL', 'BLK', 'BM', 'BN', 'BO', 'BOR',
-        'BOT', 'BP', 'BRA', 'BRB', 'BS', 'BT', 'BTF', 'BÜS', 'BW', 'BWL', 'BYL', 'BZ', 'C', 'CB', 'CE', 'CHA', 'CO',
-        'COC', 'COE', 'CUX', 'CW', 'D', 'DA', 'DAH', 'DAN', 'DAU', 'DBR', 'DD', 'DE', 'DEG', 'DEL', 'DGF', 'DH', 'DL',
-        'DLG', 'DN', 'Do', 'DON', 'DU', 'DÜW', 'E', 'EA', 'EB', 'EBE', 'ED', 'EE', 'EF', 'EI', 'EIC', 'EL', 'EM', 'EMD',
-        'EMS', 'EN', 'ER', 'ERB', 'ERH', 'ERZ', 'ES', 'ESW', 'EU', 'F', 'FB', 'FD', 'FDS', 'FF', 'FFB', 'FG', 'FL',
-        'FN', 'FO', 'FR', 'FRG', 'FRI', 'FS', 'FT', 'FÜ', 'G', 'GAP', 'GE', 'GER', 'GF', 'GG', 'GI', 'GL', 'GM', 'GÖ',
-        'GP', 'GR', 'GRZ', 'GS', 'GT', 'GTH', 'GÜ', 'GZ', 'H', 'HA', 'HAL', 'HAM', 'HAS', 'HB', 'HBN', 'HD', 'HDH',
-        'HE', 'HEF', 'HEI', 'HEL', 'HER', 'HF', 'HG', 'HGW', 'HH', 'HI', 'HL', 'HM', 'HN', 'HO', 'HOL', 'HOM', 'HP',
-        'HR', 'HRO', 'HS', 'HSK', 'HST', 'HU', 'HVL', 'HWI', 'HX', 'HZ', 'IGB', 'IK', 'IN', 'IZ', 'J', 'JL', 'K', 'KA',
-        'KB', 'KC', 'KE', 'KEH', 'KF', 'KG', 'KH', 'KI', 'KIB', 'KL', 'KLE', 'KN', 'KO', 'KR', 'KS', 'KT', 'KU', 'KÜN',
-        'KUS', 'KYF', 'L', 'LA', 'LAU', 'LB', 'LD', 'LDK', 'LDS', 'LER', 'LEV', 'LG', 'LI', 'LIF', 'LIP', 'LL', 'LM',
-        'LÖ', 'LOS', 'LRO', 'LSA', 'LSN', 'LU', 'LWL', 'M', 'MA', 'MB', 'MD', 'ME', 'MEI', 'MG', 'MI', 'MIL', 'MK',
-        'MKK', 'MM', 'MN', 'MOL', 'MOS', 'MR', 'MS', 'MSH', 'MSP', 'MST', 'MTK', 'MÜ', 'MÜR', 'MVL', 'MYK', 'MZ', 'MZG',
-        'N', 'NB', 'ND', 'NDH', 'NE', 'NEA', 'NES', 'NEW', 'NF', 'NI', 'NK', 'NL', 'NM', 'NMS', 'NOH', 'NOM', 'NR',
-        'NU', 'NVP', 'NW', 'NWM', 'OA', 'OAL', 'OB', 'OD', 'OE', 'OF', 'OG', 'OH', 'OHA', 'OHV', 'OHZ', 'OL', 'OPR',
-        'OS', 'OSL', 'OVP', 'P', 'PA', 'PAF', 'PAN', 'PB', 'PCH', 'PE', 'PF', 'PI', 'PIR', 'PLÖ', 'PM', 'PR', 'PS', 'R',
-        'RA', 'RD', 'RE', 'REG', 'RO', 'ROS', 'ROW', 'RP', 'RPL', 'RS', 'RT', 'RÜD', 'RÜG', 'RV', 'RW', 'RZ', 'S',
-        'SAD', 'SAL', 'SAW', 'SB', 'SC', 'SDL', 'SE', 'SG', 'SH', 'SHA', 'SHG', 'SHK', 'SHL', 'SI', 'SIG', 'SIM', 'SK',
-        'SL', 'SLF', 'SLK', 'SLS', 'SM', 'SN', 'SO', 'SOK', 'SÖM', 'SON', 'SP', 'SPN', 'SR', 'ST', 'STA', 'STD', 'SU',
-        'SÜW', 'SW', 'SZ', 'TDO', 'TBB', 'TF', 'TG', 'THL', 'THW', 'TIR', 'TÖL', 'TR', 'TS', 'TÜ', 'TUT', 'UE', 'UL',
-        'UM', 'UN', 'V', 'VB', 'VEC', 'VER', 'VIE', 'VK', 'VR', 'VS', 'W', 'WAF', 'WAK', 'WB', 'WE', 'WEN', 'WES', 'WF',
-        'WHV', 'WI', 'WIL', 'WL', 'WM', 'WN', 'WND', 'WO', 'WOB', 'WST', 'WT', 'WTM', 'WÜ', 'WUG', 'WUN', 'WW', 'WZ',
-        'Y', 'Z', 'ZW',
-    )
-
-    license_plate_suffix = (
-        '-??-%@@@',
-        '-?-%@@@',
-    )
-
-    def license_plate(self):
-        return self.random_element(self.license_plate_prefix) + \
-               self.lexify(self.numerify(self.random_element(self.license_plate_suffix)), string.ascii_uppercase)
diff --git a/faker/providers/currency/__init__.py b/faker/providers/currency/__init__.py
index 28f8f42b..9edd187c 100644
--- a/faker/providers/currency/__init__.py
+++ b/faker/providers/currency/__init__.py
@@ -4,182 +4,235 @@ from .. import BaseProvider
 
 
 class Provider(BaseProvider):
+    # Format: (code, name)
     currencies = (
-        "AED",
-        "AFN",
-        "ALL",
-        "AMD",
-        "ANG",
-        "AOA",
-        "ARS",
-        "AUD",
-        "AWG",
-        "AZN",
-        "BAM",
-        "BBD",
-        "BDT",
-        "BGN",
-        "BHD",
-        "BIF",
-        "BMD",
-        "BND",
-        "BOB",
-        "BRL",
-        "BSD",
-        "BTN",
-        "BWP",
-        "BYR",
-        "BZD",
-        "CAD",
-        "CDF",
-        "CHF",
-        "CLP",
-        "CNY",
-        "COP",
-        "CRC",
-        "CUC",
-        "CUP",
-        "CVE",
-        "CZK",
-        "DJF",
-        "DKK",
-        "DOP",
-        "DZD",
-        "EGP",
-        "ERN",
-        "ETB",
-        "EUR",
-        "FJD",
-        "FKP",
-        "GBP",
-        "GEL",
-        "GGP",
-        "GHS",
-        "GIP",
-        "GMD",
-        "GNF",
-        "GTQ",
-        "GYD",
-        "HKD",
-        "HNL",
-        "HRK",
-        "HTG",
-        "HUF",
-        "IDR",
-        "ILS",
-        "IMP",
-        "INR",
-        "IQD",
-        "IRR",
-        "ISK",
-        "JEP",
-        "JMD",
-        "JOD",
-        "JPY",
-        "KES",
-        "KGS",
-        "KHR",
-        "KMF",
-        "KPW",
-        "KRW",
-        "KWD",
-        "KYD",
-        "KZT",
-        "LAK",
-        "LBP",
-        "LKR",
-        "LRD",
-        "LSL",
-        "LTL",
-        "LYD",
-        "MAD",
-        "MDL",
-        "MGA",
-        "MKD",
-        "MMK",
-        "MNT",
-        "MOP",
-        "MRO",
-        "MUR",
-        "MVR",
-        "MWK",
-        "MXN",
-        "MYR",
-        "MZN",
-        "NAD",
-        "NGN",
-        "NIO",
-        "NIS",
-        "NOK",
-        "NPR",
-        "NZD",
-        "OMR",
-        "PAB",
-        "PEN",
-        "PGK",
-        "PHP",
-        "PKR",
-        "PLN",
-        "PYG",
-        "QAR",
-        "RON",
-        "RSD",
-        "RUB",
-        "RWF",
-        "SAR",
-        "SBD",
-        "SCR",
-        "SDG",
-        "SEK",
-        "SGD",
-        "SHP",
-        "SLL",
-        "SOS",
-        "SPL",
-        "SRD",
-        "STD",
-        "SVC",
-        "SYP",
-        "SZL",
-        "THB",
-        "TJS",
-        "TMT",
-        "TND",
-        "TOP",
-        "TRY",
-        "TTD",
-        "TVD",
-        "TWD",
-        "TZS",
-        "UAH",
-        "UGX",
-        "USD",
-        "UYU",
-        "UZS",
-        "VEF",
-        "VND",
-        "VUV",
-        "WST",
-        "XAF",
-        "XCD",
-        "XDR",
-        "XOF",
-        "XPF",
-        "YER",
-        "ZAR",
-        "ZMW",
-        "ZWD"
+        ("AED", "United Arab Emirates dirham"),
+        ("AFN", "Afghan afghani"),
+        ("ALL", "Albanian lek"),
+        ("AMD", "Armenian dram"),
+        ("ANG", "Netherlands Antillean guilder"),
+        ("AOA", "Angolan kwanza"),
+        ("ARS", "Argentine peso"),
+        ("AUD", "Australian dollar"),
+        ("AWG", "Aruban florin"),
+        ("AZN", "Azerbaijani manat"),
+        ("BAM", "Bosnia and Herzegovina convertible mark"),
+        ("BBD", "Barbadian dollar"),
+        ("BDT", "Bangladeshi taka"),
+        ("BGN", "Bulgarian lev"),
+        ("BHD", "Bahraini dinar"),
+        ("BIF", "Burundian franc"),
+        ("BMD", "Bermudian dollar"),
+        ("BND", "Brunei dollar"),
+        ("BOB", "Bolivian boliviano"),
+        ("BRL", "Brazilian real"),
+        ("BSD", "Bahamian dollar"),
+        ("BTN", "Bhutanese ngultrum"),
+        ("BWP", "Botswana pula"),
+        ("BYR", "Belarusian ruble"),
+        ("BZD", "Belize dollar"),
+        ("CAD", "Canadian dollar"),
+        ("CDF", "Congolese franc"),
+        ("CHF", "Swiss franc"),
+        ("CLP", "Chilean peso"),
+        ("CNY", "Renminbi"),
+        ("COP", "Colombian peso"),
+        ("CRC", "Costa Rican colón"),
+        ("CUC", "Cuban convertible peso"),
+        ("CUP", "Cuban peso"),
+        ("CVE", "Cape Verdean escudo"),
+        ("CZK", "Czech koruna"),
+        ("DJF", "Djiboutian franc"),
+        ("DKK", "Danish krone"),
+        ("DOP", "Dominican peso"),
+        ("DZD", "Algerian dinar"),
+        ("EGP", "Egyptian pound"),
+        ("ERN", "Eritrean nakfa"),
+        ("ETB", "Ethiopian birr"),
+        ("EUR", "Euro"),
+        ("FJD", "Fijian dollar"),
+        ("FKP", "Falkland Islands pound"),
+        ("GBP", "Pound sterling"),
+        ("GEL", "Georgian lari"),
+        ("GGP", "Guernsey pound"),
+        ("GHS", "Ghanaian cedi"),
+        ("GIP", "Gibraltar pound"),
+        ("GMD", "Gambian dalasi"),
+        ("GNF", "Guinean franc"),
+        ("GTQ", "Guatemalan quetzal"),
+        ("GYD", "Guyanese dollar"),
+        ("HKD", "Hong Kong dollar"),
+        ("HNL", "Honduran lempira"),
+        ("HRK", "Croatian kuna"),
+        ("HTG", "Haitian gourde"),
+        ("HUF", "Hungarian forint"),
+        ("IDR", "Indonesian rupiah"),
+        ("ILS", "Israeli new shekel"),
+        ("NIS", "Israeli new shekel"),
+        ("IMP", "Manx pound"),
+        ("INR", "Indian rupee"),
+        ("IQD", "Iraqi dinar"),
+        ("IRR", "Iranian rial"),
+        ("ISK", "Icelandic króna"),
+        ("JEP", "Jersey pound"),
+        ("JMD", "Jamaican dollar"),
+        ("JOD", "Jordanian dinar"),
+        ("JPY", "Japanese yen"),
+        ("KES", "Kenyan shilling"),
+        ("KGS", "Kyrgyzstani som"),
+        ("KHR", "Cambodian riel"),
+        ("KMF", "Comorian franc"),
+        ("KPW", "North Korean won"),
+        ("KRW", "Western Krahn language"),
+        ("KWD", "Kuwaiti dinar"),
+        ("KYD", "Cayman Islands dollar"),
+        ("KZT", "Kazakhstani tenge"),
+        ("LAK", "Lao kip"),
+        ("LBP", "Lebanese pound"),
+        ("LKR", "Sri Lankan rupee"),
+        ("LRD", "Liberian dollar"),
+        ("LSL", "Lesotho loti"),
+        ("LTL", "Lithuanian litas"),
+        ("LYD", "Libyan dinar"),
+        ("MAD", "Moroccan dirham"),
+        ("MDL", "Moldovan leu"),
+        ("MGA", "Malagasy ariar"),
+        ("MKD", "Macedonian denar"),
+        ("MMK", "Burmese kyat"),
+        ("MNT", "Mongolian tugrik"),
+        ("MOP", "Macanese pataca"),
+        ("MRO", "Mauritanian ouguiya"),
+        ("MUR", "Mauritian rupee"),
+        ("MVR", "Maldivian rufiyaa"),
+        ("MWK", "Malawian kwacha"),
+        ("MXN", "Mexican peso"),
+        ("MYR", "Malaysian ringgit"),
+        ("MZN", "Mozambican metical"),
+        ("NAD", "Namibian dollar"),
+        ("NGN", "Nigerian naira"),
+        ("NIO", "Nicaraguan córdoba"),
+        ("NOK", "Norwegian krone"),
+        ("NPR", "Nepalese rupee"),
+        ("NZD", "New Zealand dollar"),
+        ("OMR", "Omani rial"),
+        ("PAB", "Panamanian balboa"),
+        ("PEN", "Peruvian sol"),
+        ("PGK", "Papua New Guinean kina"),
+        ("PHP", "Philippine peso"),
+        ("PKR", "Pakistani rupee"),
+        ("PLN", "Polish zloty"),
+        ("PYG", "Paraguayan guarani"),
+        ("QAR", "Qatari riyal"),
+        ("RON", "Romanian leu"),
+        ("RSD", "Serbian dinar"),
+        ("RUB", "Russian ruble"),
+        ("RWF", "Rwandan franc"),
+        ("SAR", "Saudi riyal"),
+        ("SBD", "Solomon Islands dollar"),
+        ("SCR", "Seychellois rupee"),
+        ("SDG", "Sudanese pound"),
+        ("SEK", "Swedish krona"),
+        ("SGD", "Singapore dollar"),
+        ("SHP", "Saint Helena pound"),
+        ("SLL", "Sierra Leonean leone"),
+        ("SOS", "Somali shilling"),
+        ("SPL", "Seborga luigino"),
+        ("SRD", "Surinamese dollar"),
+        ("STD", "São Tomé and Príncipe dobra"),
+        ("SVC", "Salvadoran colón"),
+        ("SYP", "Syrian pound"),
+        ("SZL", "Swazi lilangeni"),
+        ("THB", "Thai baht"),
+        ("TJS", "Tajikistani somoni"),
+        ("TMT", "Turkmenistan manat"),
+        ("TND", "Tunisian dinar"),
+        ("TOP", "Tongan paʻanga"),
+        ("TRY", "Turkish lira"),
+        ("TTD", "Trinidad and Tobago dollar"),
+        ("TVD", "Tuvaluan dollar"),
+        ("TWD", "New Taiwan dollar"),
+        ("TZS", "Tanzanian shilling"),
+        ("UAH", "Ukrainian hryvnia"),
+        ("UGX", "Ugandan shilling"),
+        ("USD", "United States dollar"),
+        ("UYU", "Uruguayan peso"),
+        ("UZS", "Uzbekistani soʻm"),
+        ("VEF", "Venezuelan bolívar"),
+        ("VND", "Vietnamese đồng"),
+        ("VUV", "Vanuatu vatu"),
+        ("WST", "Samoan tālā"),
+        ("XAF", "Central African CFA franc"),
+        ("XCD", "Eastern Caribbean dollar"),
+        ("XDR", "Special drawing rights"),
+        ("XOF", "West African CFA franc"),
+        ("XPF", "CFP franc"),
+        ("YER", "Yemeni rial"),
+        ("ZAR", "South African rand"),
+        ("ZMW", "Zambian kwacha"),
+        ("ZWD", "Zimbabwean dollar"),
     )
 
     # Source: https://en.wikipedia.org/wiki/List_of_cryptocurrencies
     cryptocurrencies = (
-        'AMP', 'AUR', 'BC', 'BTC', 'BURST', 'DASH', 'DOGE', 'EMC', 'ETH',
-        'GRC', 'KOI', 'LTC', 'MSC', 'MZC', 'NMC', 'NXT', 'POT', 'PPC', 'SIL',
-        'TIT', 'VTC', 'XDN', 'XMR', 'XPM', 'XRP', 'ZEC',
+        ('AMP', "AMP"),
+        ('AUR', "Auroracoin"),
+        ('BC', "BlackCoin"),
+        ('BTC', "Bitcoin"),
+        ('BURST', "Burstcoin"),
+        ('DASH', "Dash"),
+        ('DOGE', "Dogecoin"),
+        ('EMC', "Emercoin"),
+        ('ETH', "Ethereum"),
+        ('ETC', "Ethereum Classic"),
+        ('GRC', "Gridcoin"),
+        ('KOI', "Coinye"),
+        ('LTC', "Litecoin"),
+        ('MSC', "Omni"),
+        ('MZC', "MazaCoin"),
+        ('NMC', "Namecoin"),
+        ('NXT', "Nxt"),
+        ('POT', "PotCoin"),
+        ('PPC', "Peercoin"),
+        ('TIT', "Titcoin"),
+        ('VTC', "Vertcoin"),
+        ('XDN', "DigitalNote"),
+        ('XMR', "Monero"),
+        ('XPM', "Primecoin"),
+        ('XRP', "Ripple"),
+        ('ZEC', "Zcash"),
+        ('STC', "SwiftCoin"),
+        ('BCN', "Bytecoin"),
+        ('FTH', "Feathercoin"),
+        ('NEO', "NEO"),
+        ('NEM', "XEM"),
+        ('USDT', "Tether"),
+        ('IOTA', "IOTA"),
+        ('DRC', "Decred"),
+        ('WAVES', "Waves Platform"),
+        ('LSK', "Lisk"),
+        ('ZCL', "Zclassic"),
+        ('BCH', "Bitcoin Cash"),
+        ('UBQ', "Ubiq"),
+        ('EOS', "EOS.IO"),
+        ('SRN', "Sirin Labs"),
+        ('TRX', "TRON"),
+        ('ADA', "Cardano"),
     )
 
-    def currency_code(self):
+    def currency(self):
         return self.random_element(self.currencies)
 
-    def cryptocurrency_code(self):
+    def currency_code(self):
+        return self.currency()[0]
+
+    def currency_name(self):
+        return self.currency()[1]
+
+    def cryptocurrency(self):
         return self.random_element(self.cryptocurrencies)
+
+    def cryptocurrency_code(self):
+        return self.cryptocurrency()[0]
+
+    def cryptocurrency_name(self):
+        return self.cryptocurrency()[1]
diff --git a/faker/providers/internet/__init__.py b/faker/providers/internet/__init__.py
index 660db4c3..d95d9ae6 100644
--- a/faker/providers/internet/__init__.py
+++ b/faker/providers/internet/__init__.py
@@ -15,38 +15,6 @@ from faker.utils.decorators import lowercase, slugify, slugify_unicode
 localized = True
 
 
-IPV4_PUBLIC_NETS = {
-    'a': ip_network('0.0.0.0/1'),
-    'b': ip_network('128.0.0.0/2'),
-    'c': ip_network('192.0.0.0/3')
-}
-IPV4_PRIVATE_NET_BLOCKS = {
-    'a': (
-        ip_network('0.0.0.0/8'),
-        ip_network('10.0.0.0/8'),
-        ip_network('127.0.0.0/8'),
-    ),
-    'b': (
-        ip_network('169.254.0.0/16'),
-        ip_network('172.16.0.0/12')
-    ),
-    'c': (
-        ip_network('192.0.0.0/29'),
-        ip_network('192.0.0.170/31'),
-        ip_network('192.0.2.0/24'),
-        ip_network('192.168.0.0/16'),
-        ip_network('198.18.0.0/15'),
-        ip_network('198.51.100.0/24'),
-        ip_network('203.0.113.0/24')
-    ),
-}
-IPV4_NET_CLASSES = {
-    'a': (167772160, 184549375, 24),
-    'b': (2886729728, 2887778303, 20),
-    'c': (3232235520, 3232301055, 16)
-}
-
-
 class Provider(BaseProvider):
     safe_email_tlds = ('org', 'com', 'net')
     free_email_domains = ('gmail.com', 'yahoo.com', 'hotmail.com')
@@ -213,94 +181,15 @@ class Provider(BaseProvider):
 
         return self.generator.parse(pattern)
 
-    def ipv4(self, network=False, address_class=None, private=None):
-        """
-        Produce a random IPv4 address or network with a valid CIDR.
-
-        :param network: Network address
-        :param address_class: IPv4 address class (a, b, or c)
-        :param private: Public or private
-        :returns: IPv4
-        """
-        if private is True:
-            return self.ipv4_private(address_class=address_class,
-                                     network=network)
-        elif private is False:
-            return self.ipv4_public(address_class=address_class,
-                                    network=network)
-        if address_class is None:
-            ip_range = (0, (2 ** IPV4LENGTH) - 1)
-        else:
-            net = IPV4_PUBLIC_NETS[address_class]
-            ip_range = (net._ip[0], net.ip[-1])
-        address = str(ip_address(self.generator.random.randint(*ip_range)))
+    def ipv4(self, network=False):
+        """Produce a random IPv4 address or network with a valid CIDR"""
+        address = str(ip_address(self.generator.random.randint(
+            0, (2 ** IPV4LENGTH) - 1)))
         if network:
             address += '/' + str(self.generator.random.randint(0, IPV4LENGTH))
             address = str(ip_network(address, strict=False))
         return address
 
-    def ipv4_network_class(self):
-        """
-        Returns a IPv4 network class 'a', 'b' or 'c'.
-
-        :returns: IPv4 network class
-        """
-        return self.random_element('abc')
-
-    def ipv4_private(self, network=False, address_class=None):
-        """
-        Returns a private IPv4.
-
-        :param network: Network address
-        :param address_class: IPv4 address class (a, b, or c)
-        :returns: Private IPv4
-        """
-        address_class = address_class or self.ipv4_network_class()
-        min_, max_, netmask = IPV4_NET_CLASSES[address_class]
-        address = str(ip_address(
-            self.generator.random.randint(min_, max_)))
-        if network:
-            address += '/' + str(self.generator.random.randint(netmask, 31))
-            address = str(ip_network(address, strict=False))
-        return address
-
-    def ipv4_public(self, network=False, address_class=None):
-        """
-        Returns a public IPv4 excluding private blocks.
-
-        :param network: Network address
-        :param address_class: IPv4 address class (a, b, or c)
-        :returns: Public IPv4
-        """
-        address_class = address_class or self.ipv4_network_class()
-        public_net = IPV4_PUBLIC_NETS[address_class]
-        private_blocks = IPV4_PRIVATE_NET_BLOCKS[address_class]
-        # Make valid IP ranges, created from private block exclusion
-        net_ranges = []
-        ## Starts at end of 1st block if it's 1st of class
-        if public_net[0] != private_blocks[0][0]:
-            net_ranges = [(public_net[0]._ip, private_blocks[0][0]._ip-1)]
-        ## Loop on private blocks and guess available ranges
-        for i, block in enumerate(private_blocks):
-            if i+1 == len(private_blocks):
-                break
-            net_range = (block[-1]._ip+1, private_blocks[i+1][0]._ip-1)
-            net_ranges.append(net_range)
-        ## Add last range
-        net_ranges.append((private_blocks[-1][-1]._ip-1, public_net[-1]._ip-1))
-        net_ranges = [(i, j) for i, j in net_ranges if (j-i) > 0]
-        # Choose a range
-        min_, max_ = self.generator.random.choice(net_ranges)
-        address = str(ip_address(
-            self.generator.random.randint(min_, max_)))
-        # Add network mask
-        if network:
-            net_masks = {'a': 8, 'b': 16, 'c': 24}
-            min_net_mask = net_masks[address_class]
-            address += '/' + str(self.generator.random.randint(min_net_mask, 31))
-            address = str(ip_network(address, strict=False))
-        return address
-
     def ipv6(self, network=False):
         """Produce a random IPv6 address or network with a valid CIDR"""
         address = str(ip_address(self.generator.random.randint(
diff --git a/faker/providers/ssn/fi_FI/__init__.py b/faker/providers/ssn/fi_FI/__init__.py
index ba9c817b..cc4d9227 100644
--- a/faker/providers/ssn/fi_FI/__init__.py
+++ b/faker/providers/ssn/fi_FI/__init__.py
@@ -7,11 +7,12 @@ import datetime
 
 class Provider(SsnProvider):
 
-    def ssn(self, min_age=0, max_age=105):
+    def ssn(self, min_age=18, max_age=90):
         """
         Returns 11 character Finnish personal identity code (Henkilötunnus,
-        HETU, Swedish: Personbeteckning). This function assigns random
-        gender to person.
+        HETU, Swedish: Personbeteckning). Age of person is between 18 and 90
+        years, based on local computer date. This function assigns random
+        sex to person.
 
         HETU consists of eleven characters of the form DDMMYYCZZZQ, where
         DDMMYY is the date of birth, C the century sign, ZZZ the individual
@@ -33,24 +34,11 @@ class Provider(SsnProvider):
         birthday = datetime.date.today() - age
         hetu_date = "%02d%02d%s" % (
             birthday.day, birthday.month, str(birthday.year)[-2:])
+        if birthday.year < 2000:
+            separator = '-'
+        else:
+            separator = 'A'
         suffix = str(self.generator.random.randrange(2, 899)).zfill(3)
         checksum = _checksum(hetu_date + suffix)
-        separator = self._get_century_code(birthday.year)
         hetu = "".join([hetu_date, separator, suffix, checksum])
         return hetu
-
-    @staticmethod
-    def _get_century_code(year):
-        """Returns the century code for a given year"""
-        if 2000 <= year < 3000:
-            separator = 'A'
-        elif 1900 <= year < 2000:
-            separator = '-'
-        elif 1800 <= year < 1900:
-            separator = '+'
-        else:
-            raise ValueError(
-                'Finnish SSN do not support people born '
-                'before the year 1800 or after the year 2999'
-            )
-        return separator


Test patch:
diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py
index 82c529a2..10604e2e 100644
--- a/tests/providers/test_automotive.py
+++ b/tests/providers/test_automotive.py
@@ -28,13 +28,3 @@ class TestHuHU(unittest.TestCase):
         plate = self.factory.license_plate()
 
         assert re.match("[A-Z]{3}-\d{3}", plate)
-
-class TestDeDe(unittest.TestCase):
-
-    def setUp(self):
-        self.factory = Faker('de_DE')
-
-    def test_de_DE_plate_format(self):
-        plate = self.factory.license_plate()
-
-        assert re.match("[A-Z]{1,3}-[A-Z]{1,2}-\d{1,4}", plate)
diff --git a/tests/providers/test_currency.py b/tests/providers/test_currency.py
index e701d938..b3d86d50 100644
--- a/tests/providers/test_currency.py
+++ b/tests/providers/test_currency.py
@@ -8,8 +8,34 @@ class TestCurrencyProvider(unittest.TestCase):
     def setUp(self):
         self.factory = Faker()
 
+    def test_currency(self):
+        for _ in range(99):
+            cur = self.factory.currency()
+            self.assertIsInstance(cur, tuple)
+            self.assertIn(cur, CurrencyProvider.currencies)
+
+    def test_currency_code(self):
+        for _ in range(99):
+            code = self.factory.currency_code()
+            self.assertIsInstance(code, str)
+
+    def test_currency_name(self):
+        for _ in range(99):
+            name = self.factory.currency_name()
+            self.assertIsInstance(name, str)
+
+    def test_cryptocurrency(self):
+        for _ in range(99):
+            cur = self.factory.cryptocurrency()
+            self.assertIsInstance(cur, tuple)
+            self.assertIn(cur, CurrencyProvider.cryptocurrencies)
+
     def test_cryptocurrency_code(self):
         for _ in range(99):
             code = self.factory.cryptocurrency_code()
             self.assertIsInstance(code, str)
-            self.assertIn(code, CurrencyProvider.cryptocurrencies)
+
+    def test_cryptocurrency_name(self):
+        for _ in range(99):
+            name = self.factory.cryptocurrency_name()
+            self.assertIsInstance(name, str)
diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py
index 42490102..ab5db852 100644
--- a/tests/providers/test_ssn.py
+++ b/tests/providers/test_ssn.py
@@ -8,7 +8,6 @@ from datetime import datetime
 
 from faker import Faker
 from faker.providers.ssn.et_EE import checksum as et_checksum
-from faker.providers.ssn.fi_FI import Provider as fi_Provider
 from faker.providers.ssn.hr_HR import checksum as hr_checksum
 from faker.providers.ssn.pt_BR import checksum as pt_checksum
 from faker.providers.ssn.pl_PL import checksum as pl_checksum, calculate_month as pl_calculate_mouth
@@ -32,30 +31,6 @@ class TestEtEE(unittest.TestCase):
             self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
 
 
-class TestFiFI(unittest.TestCase):
-    """ Tests SSN in the fi_FI locale """
-
-    def setUp(self):
-        self.factory = Faker('fi_FI')
-        self.provider = fi_Provider
-
-    def test_century_code(self):
-        self.assertEqual(self.provider._get_century_code(1900), '-')
-        self.assertEqual(self.provider._get_century_code(1999), '-')
-        self.assertEqual(self.provider._get_century_code(2000), 'A')
-        self.assertEqual(self.provider._get_century_code(2999), 'A')
-        self.assertEqual(self.provider._get_century_code(1800), '+')
-        self.assertEqual(self.provider._get_century_code(1899), '+')
-        with self.assertRaises(ValueError):
-            self.provider._get_century_code(1799)
-        with self.assertRaises(ValueError):
-            self.provider._get_century_code(3000)
-
-    def test_ssn_sanity(self):
-        for age in range(100):
-            self.factory.ssn(min_age=age, max_age=age+1)
-
-
 class TestHrHR(unittest.TestCase):
     """ Tests SSN in the hr_HR locale """
 
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 93e5e5d8..4c58c9f9 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,6 +1,3 @@
 mock==2.0.0
 UkPostcodeParser==1.1.2
 email_validator==1.0.3
-python-dateutil>=2.4
-six
-text-unidecode
diff --git a/tests/test_base_provider.py b/tests/test_base_provider.py
index e45c6692..299ae362 100644
--- a/tests/test_base_provider.py
+++ b/tests/test_base_provider.py
@@ -1,5 +1,4 @@
 import unittest
-import string
 
 from faker import Generator
 from faker.providers import BaseProvider
@@ -90,18 +89,3 @@ class TestBaseProvider(unittest.TestCase):
         self.assertFalse(bothified)
         bothified = self.provider.lexify(text, letters='someletters')
         self.assertFalse(bothified)
-
-    def test_hexify(self):
-        text = '^^^'
-
-        for i in range(1000):
-            hexified = self.provider.hexify(text)
-            for c in hexified:
-                self.assertIn(c, string.hexdigits[:-6])
-                self.assertNotIn(c, string.hexdigits[-6:])
-
-        for i in range(1000):
-            hexified = self.provider.hexify(text, upper=True)
-            for c in hexified:
-                self.assertIn(c, string.hexdigits[:-6].upper())
-                self.assertNotIn(c, string.hexdigits[-6:].lower())
diff --git a/tests/test_factory.py b/tests/test_factory.py
index 6be72a3e..05c53212 100644
--- a/tests/test_factory.py
+++ b/tests/test_factory.py
@@ -6,7 +6,6 @@ import re
 import unittest
 import string
 import sys
-from ipaddress import ip_address, ip_network
 
 try:
     from StringIO import StringIO
@@ -367,146 +366,6 @@ class FactoryTestCase(unittest.TestCase):
             self.assertTrue(
                 re.compile(r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$').search(address))
 
-        address = provider.ipv4(private=True)
-        self.assertTrue(len(address) >= 7)
-        self.assertTrue(len(address) <= 15)
-        self.assertTrue(
-            re.compile(r'^(\d{1,3}\.){3}\d{1,3}$').search(address))
-
-        address = provider.ipv4(private=False)
-        self.assertTrue(len(address) >= 7)
-        self.assertTrue(len(address) <= 15)
-        self.assertTrue(
-            re.compile(r'^(\d{1,3}\.){3}\d{1,3}$').search(address))
-
-    def test_ipv4_network_class(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            klass = provider.ipv4_network_class()
-            self.assertIn(klass, 'abc')
-
-    def test_ipv4_private(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_private()
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertTrue(ip_address(address).is_private)
-            self.assertTrue(
-                re.compile(r'^(\d{1,3}\.){3}\d{1,3}$').search(address))
-
-        for _ in range(999):
-            address = provider.ipv4_private(network=True)
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 9)
-            self.assertTrue(len(address) <= 18)
-            self.assertTrue(ip_network(address)[0].is_private)
-            self.assertTrue(
-                re.compile(r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$').search(address))
-
-    def test_ipv4_private_class_a(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_private(address_class='a')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertTrue(ip_address(address).is_private)
-            self.assertTrue(
-                re.compile(r'^10\.(\d{1,3}\.){2}\d{1,3}$').search(address))
-
-    def test_ipv4_private_class_b(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_private(address_class='b')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertTrue(ip_address(address).is_private)
-            self.assertTrue(
-                re.compile(r'^172\.(\d{1,3}\.){2}\d{1,3}$').search(address))
-
-    def test_ipv4_private_class_c(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_private(address_class='c')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertTrue(ip_address(address).is_private)
-            self.assertTrue(
-                re.compile(r'^192\.168\.\d{1,3}\.\d{1,3}$').search(address))
-
-    def test_ipv4_public(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_public()
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertFalse(ip_address(address).is_private, address)
-            self.assertTrue(
-                re.compile(r'^(\d{1,3}\.){3}\d{1,3}$').search(address))
-
-        for _ in range(999):
-            address = provider.ipv4_public(network=True)
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 9)
-            self.assertTrue(len(address) <= 18)
-            # Hack around ipaddress module
-            # As 192.0.0.0 is net addr of many 192.0.0.0/* nets
-            # ipaddress considers them as private
-            if ip_network(address).network_address != ip_address('192.0.0.0'):
-                self.assertFalse(ip_network(address)[0].is_private, address)
-            self.assertTrue(
-                re.compile(r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$').search(address))
-
-    def test_ipv4_public_class_a(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_public(address_class='a')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertFalse(ip_address(address).is_private, address)
-
-    def test_ipv4_public_class_b(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_public(address_class='b')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertFalse(ip_address(address).is_private, address)
-
-    def test_ipv4_public_class_c(self):
-        from faker.providers.internet import Provider
-        provider = Provider(self.generator)
-
-        for _ in range(999):
-            address = provider.ipv4_public(address_class='c')
-            address = text.force_text(address)
-            self.assertTrue(len(address) >= 7)
-            self.assertTrue(len(address) <= 15)
-            self.assertFalse(ip_address(address).is_private, address)
-
     def test_ipv6(self):
         from faker.providers.internet import Provider