Repository: joke2k/faker
Pull request #892 (2019-01-15 14:33:49)

Generating a zipcode within a given state for EnUS
### What does this change

New functions to generate a zipcode within a given state for EnUs locale: postcode_in_state(state_abbr) and aliases functions zipcode_in_state and postalcode_in_state, and tests for those functions.

### What was wrong

No way to specify the state of a generated zipcode.

### How this fixes it

Implemented functionality to generate zipcode that is within a given state



Patch:
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index facb1d28..dd586cb1 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -24,24 +24,9 @@ Making Changes
    the new branch with ``git checkout fix/master/my_contribution``.
    Please avoid working directly on the ``master`` branch.
 -  Make commits of logical units.
+-  Follow our `coding style`_.
 -  Check for unnecessary whitespace with ``git diff --check`` before
    committing.
--  Make sure your commit messages are in the proper format.
-
-::
-
-        Make the example in CONTRIBUTING imperative and concrete
-
-        Without this patch applied the example commit message in the CONTRIBUTING
-        document is not a concrete example.  This is a problem because the
-        contributor is left to imagine what the commit message should look like
-        based on a description rather than an example.  This patch fixes the
-        problem by making the example concrete and imperative.
-
-        The first line is a real life imperative statement with a ticket number
-        from our issue tracker.  The body describes the behavior without the patch,
-        why this is a problem, and how the patch fixes the problem when applied.
-
 -  Make sure you have added the necessary tests for your changes.
 -  Run *all* the tests to assure nothing else was accidentally broken.
 
@@ -57,3 +42,6 @@ Additional Resources
 -  `General GitHub documentation <https://help.github.com>`__
 -  `GitHub pull request
    documentation <https://help.github.com/articles/about-pull-requests>`__
+
+
+.. _`coding style`: https://github.com/joke2k/faker/blob/master/docs/coding_style.rst
diff --git a/docs/coding_style.rst b/docs/coding_style.rst
index 9fed53bd..af5b7bdd 100644
--- a/docs/coding_style.rst
+++ b/docs/coding_style.rst
@@ -3,7 +3,7 @@ Coding Style
 
 Lines length should not exceed 120 characters. Please use trailing commas.
 
-You can find our complete flake8 configuration in the `tox.ini_` file.
+You can find our complete flake8 configuration in the tox.ini_ file.
 
 
 Encoding
@@ -19,7 +19,7 @@ Data Sets
 ---------
 
 For each data set, please provide a comment with reference to the source
-and/or origin of the data.
+and/or origin of the data. We only accept datasets coming from statistical sources, such as census or government institutions.
 
 
 Name Lists
diff --git a/faker/providers/address/de/__init__.py b/faker/providers/address/de/__init__.py
new file mode 100644
index 00000000..b5ade9eb
--- /dev/null
+++ b/faker/providers/address/de/__init__.py
@@ -0,0 +1,66 @@
+# coding=utf-8
+
+from __future__ import unicode_literals
+from .. import Provider as AddressProvider
+
+
+class Provider(AddressProvider):
+    countries = (
+        'Afghanistan', 'Alandinseln', 'Albanien', 'Algerien',
+        'Amerikanisch-Ozeanien', 'Amerikanisch-Samoa',
+        'Amerikanische Jungferninseln', 'Andorra', 'Angola', 'Anguilla',
+        'Antarktis', 'Antigua und Barbuda', 'Argentinien', 'Armenien', 'Aruba',
+        'Aserbaidschan', 'Australien', 'Bahamas', 'Bahrain', 'Bangladesch',
+        'Barbados', 'Belarus', 'Belgien', 'Belize', 'Benin', 'Bermuda',
+        'Bhutan', 'Bolivien', 'Bosnien und Herzegowina', 'Botsuana',
+        'Bouvetinsel', 'Brasilien', 'Britische Jungferninseln',
+        'Britisches Territorium im Indischen Ozean', 'Brunei Darussalam',
+        'Bulgarien', 'Burkina Faso', 'Burundi', 'Chile', 'China', 'Cookinseln',
+        'Costa Rica', 'Côte d’Ivoire', 'Demokratische Republik Kongo',
+        'Demokratische Volksrepublik Korea', 'Deutschland', 'Dominica',
+        'Dominikanische Republik', 'Dschibuti', 'Dänemark', 'Ecuador',
+        'El Salvador', 'Eritrea', 'Estland', 'Falklandinseln', 'Fidschi',
+        'Finnland', 'Frankreich', 'Französisch-Guayana',
+        'Französisch-Polynesien', 'Färöer', 'Gabun', 'Gambia', 'Georgien',
+        'Ghana', 'Gibraltar', 'Grenada', 'Griechenland', 'Grönland',
+        'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea',
+        'Guinea-Bissau', 'Guyana', 'Haiti', 'Heard- und McDonald-Inseln',
+        'Honduras', 'Indien', 'Indonesien', 'Irak', 'Iran', 'Irland', 'Island',
+        'Isle of Man', 'Israel', 'Italien', 'Jamaika', 'Japan', 'Jemen',
+        'Jersey', 'Jordanien', 'Kaimaninseln', 'Kambodscha', 'Kamerun',
+        'Kanada', 'Kap Verde', 'Kasachstan', 'Katar', 'Kenia', 'Kirgisistan',
+        'Kiribati', 'Kokosinseln', 'Kolumbien', 'Komoren', 'Kongo', 'Kroatien',
+        'Kuba', 'Kuwait', 'Laos', 'Lesotho', 'Lettland', 'Libanon', 'Liberia',
+        'Libyen', 'Liechtenstein', 'Litauen', 'Luxemburg', 'Madagaskar',
+        'Malawi', 'Malaysia', 'Malediven', 'Mali', 'Malta', 'Marokko',
+        'Marshallinseln', 'Martinique', 'Mauretanien', 'Mauritius', 'Mayotte',
+        'Mazedonien', 'Mexiko', 'Mikronesien', 'Monaco', 'Mongolei',
+        'Montenegro', 'Montserrat', 'Mosambik', 'Myanmar', 'Namibia', 'Nauru',
+        'Nepal', 'Neukaledonien', 'Neuseeland', 'Nicaragua', 'Niederlande',
+        'Niederländische Antillen', 'Niger', 'Nigeria', 'Niue', 'Norfolkinsel',
+        'Norwegen', 'Nördliche Marianen', 'Oman', 'Osttimor', 'Pakistan',
+        'Palau', 'Palästinensische Gebiete', 'Panama', 'Papua-Neuguinea',
+        'Paraguay', 'Peru', 'Philippinen', 'Pitcairn', 'Polen', 'Portugal',
+        'Puerto Rico', 'Republik Korea', 'Republik Moldau', 'Ruanda',
+        'Rumänien', 'Russische Föderation', 'Réunion', 'Salomonen', 'Sambia',
+        'Samoa', 'San Marino', 'Saudi-Arabien', 'Schweden', 'Schweiz',
+        'Senegal', 'Serbien', 'Serbien und Montenegro', 'Seychellen',
+        'Sierra Leone', 'Simbabwe', 'Singapur', 'Slowakei', 'Slowenien',
+        'Somalia', 'Sonderverwaltungszone Hongkong',
+        'Sonderverwaltungszone Macao', 'Spanien', 'Sri Lanka',
+        'St. Barthélemy', 'St. Helena', 'St. Kitts und Nevis', 'St. Lucia',
+        'St. Martin', 'St. Pierre und Miquelon',
+        'St. Vincent und die Grenadinen', 'Sudan', 'Suriname',
+        'Svalbard und Jan Mayen', 'Swasiland', 'Syrien',
+        'São Tomé und Príncipe', 'Südafrika',
+        'Südgeorgien und die Südlichen Sandwichinseln', 'Tadschikistan',
+        'Taiwan', 'Tansania', 'Thailand', 'Togo', 'Tokelau', 'Tonga',
+        'Trinidad und Tobago', 'Tschad', 'Tschechische Republik', 'Tunesien',
+        'Turkmenistan', 'Turks- und Caicosinseln', 'Tuvalu', 'Türkei',
+        'Uganda', 'Ukraine', 'Ungarn', 'Uruguay', 'Usbekistan', 'Vanuatu',
+        'Vatikanstadt', 'Venezuela', 'Vereinigte Arabische Emirate',
+        'Vereinigte Staaten', 'Vereinigtes Königreich', 'Vietnam',
+        'Wallis und Futuna', 'Weihnachtsinsel', 'Westsahara',
+        'Zentralafrikanische Republik', 'Zypern', 'Ägypten',
+        'Äquatorialguinea', 'Äthiopien', 'Äußeres Ozeanien', 'Österreich',
+    )
diff --git a/faker/providers/address/de_AT/__init__.py b/faker/providers/address/de_AT/__init__.py
index 6b8eb5fb..32ae17ab 100644
--- a/faker/providers/address/de_AT/__init__.py
+++ b/faker/providers/address/de_AT/__init__.py
@@ -1,13 +1,15 @@
 # coding=utf-8
 
 from __future__ import unicode_literals
-from .. import Provider as AddressProvider
+from ..de import Provider as AddressProvider
 
 
 class Provider(AddressProvider):
 
     city_formats = ('{{city_name}}', )
 
+    city_with_postcode_formats = ('{{postcode}} {{city}}', )
+
     street_name_formats = (
         '{{first_name}}-{{last_name}}-{{street_suffix_long}}',
         '{{last_name}}{{street_suffix_short}}',
@@ -26,15 +28,7 @@ class Provider(AddressProvider):
 
     # https://en.wikipedia.org/wiki/List_of_postal_codes_in_Austria
     postcode_formats = (
-        '1###',
-        '2###',
-        '3###',
-        '4###',
-        '5###',
-        '6###',
-        '7###',
-        '8###',
-        '9###',
+        '1###', '2###', '3###', '4###', '5###', '6###', '7###', '8###', '9###',
     )
 
     # https://en.wikipedia.org/wiki/List_of_cities_and_towns_in_Austria
@@ -79,66 +73,6 @@ class Provider(AddressProvider):
         'Oberösterreich', 'Salzburg', 'Kärnten', 'Vorarlberg',
     )
 
-    countries = (
-        'Afghanistan', 'Alandinseln', 'Albanien', 'Algerien',
-        'Amerikanisch-Ozeanien', 'Amerikanisch-Samoa',
-        'Amerikanische Jungferninseln', 'Andorra', 'Angola', 'Anguilla',
-        'Antarktis', 'Antigua und Barbuda', 'Argentinien', 'Armenien', 'Aruba',
-        'Aserbaidschan', 'Australien', 'Bahamas', 'Bahrain', 'Bangladesch',
-        'Barbados', 'Belarus', 'Belgien', 'Belize', 'Benin', 'Bermuda',
-        'Bhutan', 'Bolivien', 'Bosnien und Herzegowina', 'Botsuana',
-        'Bouvetinsel', 'Brasilien', 'Britische Jungferninseln',
-        'Britisches Territorium im Indischen Ozean', 'Brunei Darussalam',
-        'Bulgarien', 'Burkina Faso', 'Burundi', 'Chile', 'China', 'Cookinseln',
-        'Costa Rica', 'Côte d’Ivoire', 'Demokratische Republik Kongo',
-        'Demokratische Volksrepublik Korea', 'Deutschland', 'Dominica',
-        'Dominikanische Republik', 'Dschibuti', 'Dänemark', 'Ecuador',
-        'El Salvador', 'Eritrea', 'Estland', 'Falklandinseln', 'Fidschi',
-        'Finnland', 'Frankreich', 'Französisch-Guayana',
-        'Französisch-Polynesien', 'Färöer', 'Gabun', 'Gambia', 'Georgien',
-        'Ghana', 'Gibraltar', 'Grenada', 'Griechenland', 'Grönland',
-        'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea',
-        'Guinea-Bissau', 'Guyana', 'Haiti', 'Heard- und McDonald-Inseln',
-        'Honduras', 'Indien', 'Indonesien', 'Irak', 'Iran', 'Irland', 'Island',
-        'Isle of Man', 'Israel', 'Italien', 'Jamaika', 'Japan', 'Jemen',
-        'Jersey', 'Jordanien', 'Kaimaninseln', 'Kambodscha', 'Kamerun',
-        'Kanada', 'Kap Verde', 'Kasachstan', 'Katar', 'Kenia', 'Kirgisistan',
-        'Kiribati', 'Kokosinseln', 'Kolumbien', 'Komoren', 'Kongo', 'Kroatien',
-        'Kuba', 'Kuwait', 'Laos', 'Lesotho', 'Lettland', 'Libanon', 'Liberia',
-        'Libyen', 'Liechtenstein', 'Litauen', 'Luxemburg', 'Madagaskar',
-        'Malawi', 'Malaysia', 'Malediven', 'Mali', 'Malta', 'Marokko',
-        'Marshallinseln', 'Martinique', 'Mauretanien', 'Mauritius', 'Mayotte',
-        'Mazedonien', 'Mexiko', 'Mikronesien', 'Monaco', 'Mongolei',
-        'Montenegro', 'Montserrat', 'Mosambik', 'Myanmar', 'Namibia', 'Nauru',
-        'Nepal', 'Neukaledonien', 'Neuseeland', 'Nicaragua', 'Niederlande',
-        'Niederländische Antillen', 'Niger', 'Nigeria', 'Niue', 'Norfolkinsel',
-        'Norwegen', 'Nördliche Marianen', 'Oman', 'Osttimor', 'Pakistan',
-        'Palau', 'Palästinensische Gebiete', 'Panama', 'Papua-Neuguinea',
-        'Paraguay', 'Peru', 'Philippinen', 'Pitcairn', 'Polen', 'Portugal',
-        'Puerto Rico', 'Republik Korea', 'Republik Moldau', 'Ruanda',
-        'Rumänien', 'Russische Föderation', 'Réunion', 'Salomonen', 'Sambia',
-        'Samoa', 'San Marino', 'Saudi-Arabien', 'Schweden', 'Schweiz',
-        'Senegal', 'Serbien', 'Serbien und Montenegro', 'Seychellen',
-        'Sierra Leone', 'Simbabwe', 'Singapur', 'Slowakei', 'Slowenien',
-        'Somalia', 'Sonderverwaltungszone Hongkong',
-        'Sonderverwaltungszone Macao', 'Spanien', 'Sri Lanka',
-        'St. Barthélemy', 'St. Helena', 'St. Kitts und Nevis', 'St. Lucia',
-        'St. Martin', 'St. Pierre und Miquelon',
-        'St. Vincent und die Grenadinen', 'Sudan', 'Suriname',
-        'Svalbard und Jan Mayen', 'Swasiland', 'Syrien',
-        'São Tomé und Príncipe', 'Südafrika',
-        'Südgeorgien und die Südlichen Sandwichinseln', 'Tadschikistan',
-        'Taiwan', 'Tansania', 'Thailand', 'Togo', 'Tokelau', 'Tonga',
-        'Trinidad und Tobago', 'Tschad', 'Tschechische Republik', 'Tunesien',
-        'Turkmenistan', 'Turks- und Caicosinseln', 'Tuvalu', 'Türkei',
-        'Uganda', 'Ukraine', 'Ungarn', 'Uruguay', 'Usbekistan', 'Vanuatu',
-        'Vatikanstadt', 'Venezuela', 'Vereinigte Arabische Emirate',
-        'Vereinigte Staaten', 'Vereinigtes Königreich', 'Vietnam',
-        'Wallis und Futuna', 'Weihnachtsinsel', 'Westsahara',
-        'Zentralafrikanische Republik', 'Zypern', 'Ägypten',
-        'Äquatorialguinea', 'Äthiopien', 'Äußeres Ozeanien', 'Österreich',
-    )
-
     def street_suffix_short(self):
         return self.random_element(self.street_suffixes_short)
 
@@ -151,8 +85,6 @@ class Provider(AddressProvider):
     def state(self):
         return self.random_element(self.states)
 
-    def postcode(self):
-        return self.bothify(self.random_element(self.postcode_formats))
-
     def city_with_postcode(self):
-        return self.postcode() + " " + self.random_element(self.cities)
+        pattern = self.random_element(self.city_with_postcode_formats)
+        return self.generator.parse(pattern)
diff --git a/faker/providers/address/de_DE/__init__.py b/faker/providers/address/de_DE/__init__.py
index d92f6053..eca12523 100644
--- a/faker/providers/address/de_DE/__init__.py
+++ b/faker/providers/address/de_DE/__init__.py
@@ -1,14 +1,14 @@
 # coding=utf-8
 
 from __future__ import unicode_literals
-from .. import Provider as AddressProvider
+from ..de import Provider as AddressProvider
 
 
 class Provider(AddressProvider):
 
     city_formats = ('{{city_name}}', )
 
-    city_with_postcode_formats = ('{{city_name}} {{postcode}}', )
+    city_with_postcode_formats = ('{{postcode}} {{city}}', )
 
     street_name_formats = (
         '{{first_name}}-{{last_name}}-{{street_suffix_long}}',
@@ -116,66 +116,6 @@ class Provider(AddressProvider):
         'Sachsen-Anhalt', 'Schleswig-Holstein', 'Thüringen',
     )
 
-    countries = (
-        'Afghanistan', 'Alandinseln', 'Albanien', 'Algerien',
-        'Amerikanisch-Ozeanien', 'Amerikanisch-Samoa',
-        'Amerikanische Jungferninseln', 'Andorra', 'Angola', 'Anguilla',
-        'Antarktis', 'Antigua und Barbuda', 'Argentinien', 'Armenien', 'Aruba',
-        'Aserbaidschan', 'Australien', 'Bahamas', 'Bahrain', 'Bangladesch',
-        'Barbados', 'Belarus', 'Belgien', 'Belize', 'Benin', 'Bermuda',
-        'Bhutan', 'Bolivien', 'Bosnien und Herzegowina', 'Botsuana',
-        'Bouvetinsel', 'Brasilien', 'Britische Jungferninseln',
-        'Britisches Territorium im Indischen Ozean', 'Brunei Darussalam',
-        'Bulgarien', 'Burkina Faso', 'Burundi', 'Chile', 'China', 'Cookinseln',
-        'Costa Rica', 'Côte d’Ivoire', 'Demokratische Republik Kongo',
-        'Demokratische Volksrepublik Korea', 'Deutschland', 'Dominica',
-        'Dominikanische Republik', 'Dschibuti', 'Dänemark', 'Ecuador',
-        'El Salvador', 'Eritrea', 'Estland', 'Falklandinseln', 'Fidschi',
-        'Finnland', 'Frankreich', 'Französisch-Guayana',
-        'Französisch-Polynesien', 'Färöer', 'Gabun', 'Gambia', 'Georgien',
-        'Ghana', 'Gibraltar', 'Grenada', 'Griechenland', 'Grönland',
-        'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea',
-        'Guinea-Bissau', 'Guyana', 'Haiti', 'Heard- und McDonald-Inseln',
-        'Honduras', 'Indien', 'Indonesien', 'Irak', 'Iran', 'Irland', 'Island',
-        'Isle of Man', 'Israel', 'Italien', 'Jamaika', 'Japan', 'Jemen',
-        'Jersey', 'Jordanien', 'Kaimaninseln', 'Kambodscha', 'Kamerun',
-        'Kanada', 'Kap Verde', 'Kasachstan', 'Katar', 'Kenia', 'Kirgisistan',
-        'Kiribati', 'Kokosinseln', 'Kolumbien', 'Komoren', 'Kongo', 'Kroatien',
-        'Kuba', 'Kuwait', 'Laos', 'Lesotho', 'Lettland', 'Libanon', 'Liberia',
-        'Libyen', 'Liechtenstein', 'Litauen', 'Luxemburg', 'Madagaskar',
-        'Malawi', 'Malaysia', 'Malediven', 'Mali', 'Malta', 'Marokko',
-        'Marshallinseln', 'Martinique', 'Mauretanien', 'Mauritius', 'Mayotte',
-        'Mazedonien', 'Mexiko', 'Mikronesien', 'Monaco', 'Mongolei',
-        'Montenegro', 'Montserrat', 'Mosambik', 'Myanmar', 'Namibia', 'Nauru',
-        'Nepal', 'Neukaledonien', 'Neuseeland', 'Nicaragua', 'Niederlande',
-        'Niederländische Antillen', 'Niger', 'Nigeria', 'Niue', 'Norfolkinsel',
-        'Norwegen', 'Nördliche Marianen', 'Oman', 'Osttimor', 'Pakistan',
-        'Palau', 'Palästinensische Gebiete', 'Panama', 'Papua-Neuguinea',
-        'Paraguay', 'Peru', 'Philippinen', 'Pitcairn', 'Polen', 'Portugal',
-        'Puerto Rico', 'Republik Korea', 'Republik Moldau', 'Ruanda',
-        'Rumänien', 'Russische Föderation', 'Réunion', 'Salomonen', 'Sambia',
-        'Samoa', 'San Marino', 'Saudi-Arabien', 'Schweden', 'Schweiz',
-        'Senegal', 'Serbien', 'Serbien und Montenegro', 'Seychellen',
-        'Sierra Leone', 'Simbabwe', 'Singapur', 'Slowakei', 'Slowenien',
-        'Somalia', 'Sonderverwaltungszone Hongkong',
-        'Sonderverwaltungszone Macao', 'Spanien', 'Sri Lanka',
-        'St. Barthélemy', 'St. Helena', 'St. Kitts und Nevis', 'St. Lucia',
-        'St. Martin', 'St. Pierre und Miquelon',
-        'St. Vincent und die Grenadinen', 'Sudan', 'Suriname',
-        'Svalbard und Jan Mayen', 'Swasiland', 'Syrien',
-        'São Tomé und Príncipe', 'Südafrika',
-        'Südgeorgien und die Südlichen Sandwichinseln', 'Tadschikistan',
-        'Taiwan', 'Tansania', 'Thailand', 'Togo', 'Tokelau', 'Tonga',
-        'Trinidad und Tobago', 'Tschad', 'Tschechische Republik', 'Tunesien',
-        'Turkmenistan', 'Turks- und Caicosinseln', 'Tuvalu', 'Türkei',
-        'Uganda', 'Ukraine', 'Ungarn', 'Uruguay', 'Usbekistan', 'Vanuatu',
-        'Vatikanstadt', 'Venezuela', 'Vereinigte Arabische Emirate',
-        'Vereinigte Staaten', 'Vereinigtes Königreich', 'Vietnam',
-        'Wallis und Futuna', 'Weihnachtsinsel', 'Westsahara',
-        'Zentralafrikanische Republik', 'Zypern', 'Ägypten',
-        'Äquatorialguinea', 'Äthiopien', 'Äußeres Ozeanien', 'Österreich',
-    )
-
     def street_suffix_short(self):
         return self.random_element(self.street_suffixes_short)
 
@@ -188,11 +128,6 @@ class Provider(AddressProvider):
     def state(self):
         return self.random_element(self.states)
 
-    def country(self):
-        return self.random_element(self.countries)
-
-    def postcode(self):
-        return self.bothify(self.random_element(self.postcode_formats))
-
     def city_with_postcode(self):
-        return self.postcode() + " " + self.random_element(self.cities)
+        pattern = self.random_element(self.city_with_postcode_formats)
+        return self.generator.parse(pattern)
diff --git a/faker/providers/address/en_US/__init__.py b/faker/providers/address/en_US/__init__.py
index 7f5eaf8d..3e15a838 100644
--- a/faker/providers/address/en_US/__init__.py
+++ b/faker/providers/address/en_US/__init__.py
@@ -279,6 +279,26 @@ class Provider(AddressProvider):
         'WV', 'WI', 'WY',
     )
 
+    states_postcode = {
+        'AL': (35004, 36925), 'AK': (99501, 99950), 'AZ': (85001, 86556),
+        'AR': (71601, 72959), 'CA': (90001, 96162), 'CO': (80001, 81658),
+        'CT': (6001, 6389), 'DE': (19701, 19980), 'DC': (20001, 20039),
+        'FL': (32004, 34997), 'GA': (30001, 31999), 'HI': (96701, 96898),
+        'ID': (83201, 83876), 'IL': (60001, 62999), 'IN': (46001, 47997),
+        'IA': (50001, 52809), 'KS': (66002, 67954), 'KY': (40003, 42788),
+        'LA': (70001, 71232), 'ME': (3901, 4992), 'MD': (20331, 20331),
+        'MA': (1001, 2791), 'MI': (48001, 49971), 'MN': (55001, 56763),
+        'MS': (38601, 39776), 'MO': (63001, 65899), 'MT': (59001, 59937),
+        'NE': (68001, 68118), 'NV': (88901, 89883), 'NH': (3031, 3897),
+        'NJ': (7001, 8989), 'NM': (87001, 88441), 'NY': (6390, 6390),
+        'NC': (27006, 28909), 'ND': (58001, 58856), 'OH': (43001, 45999),
+        'OK': (73001, 73199), 'OR': (97001, 97920), 'PA': (15001, 19640),
+        'RI': (2801, 2940), 'SC': (29001, 29948), 'SD': (57001, 57799),
+        'TN': (37010, 38589), 'TX': (73301, 73301), 'UT': (84001, 84784),
+        'VT': (5001, 5495), 'VA': (20040, 20041), 'WA': (98001, 99403),
+        'WV': (24701, 26886), 'WI': (53001, 54990), 'WY': (82001, 83128),
+    }
+
     territories_abbr = (
         'AS', 'FM', 'GU', 'MH', 'MP', 'PW', 'PR', 'VI',
     )
@@ -353,6 +373,28 @@ class Provider(AddressProvider):
         return "%s-%04d" % (self.zipcode(),
                             self.generator.random.randint(1, 9999))
 
+    def postcode_in_state(self, state_abbr=None):
+        """
+        :returns: A random postcode within the provided state abbreviation
+
+        :param state_abbr: A state abbreviation
+        """
+        if state_abbr is None:
+            state_abbr = self.random_element(self.states_abbr)
+
+        if state_abbr in self.states_abbr:
+            postcode = "%d" % (self.generator.random.randint(
+                            self.states_postcode[state_abbr][0],
+                            self.states_postcode[state_abbr][1]))
+
+            if len(postcode) == 4:
+                postcode = "0%s" % postcode
+
+            return postcode
+
+        else:
+            raise Exception('State Abbreviation not found in list')
+
     def military_ship(self):
         """
         :example 'USS'
@@ -381,8 +423,14 @@ class Provider(AddressProvider):
     def zipcode(self):
         return self.postcode()
 
+    def zipcode_in_state(self, state_abbr=None):
+        return self.postcode_in_state(state_abbr)
+
     def postalcode(self):
         return self.postcode()
 
+    def postalcode_in_state(self, state_abbr=None):
+        return self.postcode_in_state(state_abbr)
+
     def postalcode_plus4(self):
         return self.zipcode_plus4()
diff --git a/faker/providers/person/de_AT/__init__.py b/faker/providers/person/de_AT/__init__.py
index b11d15b9..35b5b57d 100644
--- a/faker/providers/person/de_AT/__init__.py
+++ b/faker/providers/person/de_AT/__init__.py
@@ -14,85 +14,29 @@ class Provider(PersonProvider):
         '{{first_name}} {{last_name}}',
         '{{prefix}} {{first_name}} {{last_name}}',
     )
-
     first_names = (
-        'Alexander',
-        'Alina',
-        'Andreas',
-        'Anna',
-        'Anton',
-        'Benjamin',
-        'Bernhard',
-        'Christian',
-        'Christop',
-        'Daniel',
-        'David',
-        'Dominik',
-        'Elena',
-        'Elias',
-        'Emil',
-        'Emilia',
-        'Fabian',
-        'Felix',
-        'Florian',
-        'Franz',
-        'Fransizka',
-        'Gabriel',
-        'Gernot',
+        'Alexander', 'Alina', 'Andreas', 'Anna', 'Anton',
+        'Benjamin', 'Bernhard',
+        'Christian', 'Christop',
+        'Daniel', 'David', 'Dominik',
+        'Elena', 'Elias', 'Emil', 'Emilia',
+        'Fabian', 'Felix', 'Florian', 'Franz', 'Fransizka',
+        'Gabriel', 'Gernot',
         'Hanna',
-        'Ingrid',
-        'Isabel'
-        'Jakob',
-        'Jana',
-        'Jasmin',
-        'Johanna',
-        'Johannes',
-        'Jonas',
-        'Julia',
-        'Julian',
-        'Katharinna',
-        'Konrad',
-        'Konstantin'
-        'Lara',
-        'Laura',
-        'Lena',
-        'Leo',
-        'Leon',
-        'Linda',
-        'Luca',
-        'Lukas',
-        'Marcel',
-        'Maria',
-        'Martin',
-        'Matthias',
-        'Max',
-        'Maximilian',
-        'Mia',
-        'Michael',
-        'Moritz',
-        'Nico',
-        'Niklas',
-        'Nina',
-        'Noah',
-        'Oliver',
-        'Olivia',
-        'Paul',
-        'Paula',
-        'Philipp',
-        'Pia',
-        'Raphael',
-        'Robert',
-        'Samuel',
-        'Sarah',
-        'Sebastian',
-        'Simon',
-        'Sophie',
-        'Theresa',
-        'Thomas',
-        'Tim',
+        'Ingrid', 'Isabel',
+        'Jakob', 'Jana', 'Jasmin', 'Johanna', 'Johannes', 'Jonas', 'Julia', 'Julian',
+        'Katharinna', 'Konrad', 'Konstantin',
+        'Lara', 'Laura', 'Lena', 'Leo', 'Leon', 'Linda', 'Luca', 'Lukas',
+        'Marcel', 'Maria', 'Martin', 'Matthias', 'Max', 'Maximilian', 'Mia', 'Michael', 'Moritz',
+        'Nico', 'Niklas', 'Nina', 'Noah',
+        'Oliver', 'Olivia',
+        'Paul', 'Paula', 'Philipp', 'Pia',
+        'Raphael', 'Robert',
+        'Samuel', 'Sarah', 'Sebastian', 'Simon', 'Sophie',
+        'Theresa', 'Thomas', 'Tim',
         'Tobias',
-        'Valentin')
-
+        'Valentin',
+    )
     last_names = (
         'Auer', 'Aigner',
         'Bauer', 'Baumgartner', 'Berger', 'Binder', 'Brunner',
diff --git a/faker/providers/person/zh_CN/__init__.py b/faker/providers/person/zh_CN/__init__.py
index 8e3f2f4d..8f6b324c 100644
--- a/faker/providers/person/zh_CN/__init__.py
+++ b/faker/providers/person/zh_CN/__init__.py
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
+from collections import OrderedDict
 from .. import Provider as PersonProvider
 
 
@@ -17,43 +18,409 @@ class Provider(PersonProvider):
         "桂芝", "岩", "杨", "小红", "金凤", "文", "利", "楠", "红霞", "建平", "瑜", "桂花", "璐", "凤兰",
     ]
 
-    last_names = [
-        "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "诸", "卫", "蒋", "沈", "韩", "杨",
-        "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜",
-        "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎",
-        "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐",
-        "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
-        "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄",
-        "和", "穆", "萧", "尹", "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧",
-        "计", "伏", "成", "戴", "谈", "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "粱",
-        "杜", "阮", "蓝", "闵", "席", "季", "麻", "强", "贾", "路", "娄", "危", "江", "童", "颜", "郭",
-        "梅", "盛", "林", "刁", "钟", "徐", "邱", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍",
-        "虞", "万", "支", "柯", "咎", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗",
-        "丁", "宣", "贲", "邓", "郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚",
-        "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁", "荀", "羊", "於", "惠", "甄", "魏", "家", "封",
-        "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫", "乌", "焦", "巴", "弓",
-        "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫",
-        "宁", "仇", "栾", "暴", "甘", "钭", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙",
-        "叶", "幸", "司", "韶", "郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂",
-        "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙", "池", "乔", "阴", "郁", "胥", "能", "苍", "双",
-        "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵", "冉", "宰", "郦", "雍",
-        "却", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农",
-        "温", "别", "庄", "晏", "柴", "翟", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容",
-        "向", "古", "易", "慎", "戈", "廖", "庚", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘",
-        "匡", "国", "文", "寇", "广", "禄", "阙", "东", "殴", "殳", "沃", "利", "蔚", "越", "夔", "隆",
-        "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚", "那", "简", "饶", "空",
-        "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "后", "荆", "红",
-        "游", "竺", "权", "逯", "盖", "益", "桓", "公", "万", "俟", "司", "马", "上", "官", "欧", "阳",
-        "夏", "侯", "诸", "葛", "闻", "人", "东", "方", "赫", "连", "皇", "甫", "尉", "迟", "公", "羊",
-        "澹", "台", "公", "冶", "宗", "政", "濮", "阳", "淳", "于", "单", "于", "太", "叔", "申", "屠",
-        "公", "孙", "仲", "孙", "轩", "辕", "令", "狐", "钟", "离", "宇", "文", "长", "孙", "慕", "容",
-        "鲜", "于", "闾", "丘", "司", "徒", "司", "空", "亓", "官", "司", "寇", "仉", "督", "子", "车",
-        "颛", "孙", "端", "木", "巫", "马", "公", "西", "漆", "雕", "乐", "正", "壤", "驷", "公", "良",
-        "拓", "跋", "夹", "谷", "宰", "父", "谷", "粱", "晋", "楚", "闫", "法", "汝", "鄢", "涂", "钦",
-        "段", "干", "百", "里", "东", "郭", "南", "门", "呼", "延", "归", "海", "羊", "舌", "微", "生",
-        "岳", "帅", "缑", "亢", "况", "后", "有", "琴", "梁", "丘", "左", "丘", "东", "门", "西", "门",
-        "商", "牟", "佘", "佴", "伯", "赏", "南", "宫", "墨", "哈", "谯", "笪", "年", "爱", "阳", "佟",
-    ]
+    # From https://zh.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E5%A7%93%E6%B0%8F%E6%8E%92%E5%90%8D
+    last_names = OrderedDict((
+        ('王', 7.170),
+        ('李', 7.000),
+        ('张', 6.740),
+        ('刘', 5.100),
+        ('陈', 4.610),
+        ('杨', 3.220),
+        ('黄', 2.450),
+        ('吴', 2.000),
+        ('赵', 2.000),
+        ('周', 1.900),
+        ('徐', 1.450),
+        ('孙', 1.380),
+        ('马', 1.290),
+        ('朱', 1.280),
+        ('胡', 1.160),
+        ('林', 1.130),
+        ('郭', 1.130),
+        ('何', 1.060),
+        ('高', 1.000),
+        ('罗', 0.950),
+        ('郑', 0.930),
+        ('梁', 0.850),
+        ('谢', 0.760),
+        ('宋', 0.700),
+        ('唐', 0.690),
+        ('许', 0.660),
+        ('邓', 0.620),
+        ('冯', 0.620),
+        ('韩', 0.610),
+        ('曹', 0.600),
+        ('曾', 0.580),
+        ('彭', 0.580),
+        ('萧', 0.560),
+        ('蔡', 0.530),
+        ('潘', 0.520),
+        ('田', 0.520),
+        ('董', 0.510),
+        ('袁', 0.500),
+        ('于', 0.480),
+        ('余', 0.480),
+        ('叶', 0.480),
+        ('蒋', 0.480),
+        ('杜', 0.470),
+        ('苏', 0.460),
+        ('魏', 0.450),
+        ('程', 0.450),
+        ('吕', 0.450),
+        ('丁', 0.430),
+        ('沈', 0.410),
+        ('任', 0.410),
+        ('姚', 0.400),
+        ('卢', 0.400),
+        ('傅', 0.400),
+        ('钟', 0.400),
+        ('姜', 0.390),
+        ('崔', 0.380),
+        ('谭', 0.380),
+        ('廖', 0.370),
+        ('范', 0.360),
+        ('汪', 0.360),
+        ('陆', 0.360),
+        ('金', 0.350),
+        ('石', 0.340),
+        ('戴', 0.340),
+        ('贾', 0.330),
+        ('韦', 0.320),
+        ('夏', 0.320),
+        ('邱', 0.320),
+        ('方', 0.310),
+        ('侯', 0.300),
+        ('邹', 0.300),
+        ('熊', 0.290),
+        ('孟', 0.290),
+        ('秦', 0.290),
+        ('白', 0.280),
+        ('江', 0.280),
+        ('阎', 0.270),
+        ('薛', 0.260),
+        ('尹', 0.260),
+        ('段', 0.240),
+        ('雷', 0.240),
+        ('黎', 0.220),
+        ('史', 0.210),
+        ('龙', 0.210),
+        ('陶', 0.210),
+        ('贺', 0.210),
+        ('顾', 0.200),
+        ('毛', 0.200),
+        ('郝', 0.200),
+        ('龚', 0.200),
+        ('邵', 0.200),
+        ('万', 0.190),
+        ('钱', 0.190),
+        ('严', 0.190),
+        ('赖', 0.180),
+        ('覃', 0.180),
+        ('洪', 0.180),
+        ('武', 0.180),
+        ('莫', 0.180),
+        ('孔', 0.170),
+        ('汤', 0.170),
+        ('向', 0.170),
+        ('常', 0.160),
+        ('温', 0.160),
+        ('康', 0.160),
+        ('施', 0.150),
+        ('文', 0.150),
+        ('牛', 0.150),
+        ('樊', 0.150),
+        ('葛', 0.150),
+        ('邢', 0.140),
+        ('安', 0.130),
+        ('齐', 0.130),
+        ('易', 0.130),
+        ('乔', 0.130),
+        ('伍', 0.130),
+        ('庞', 0.130),
+        ('颜', 0.120),
+        ('倪', 0.120),
+        ('庄', 0.120),
+        ('聂', 0.120),
+        ('章', 0.120),
+        ('鲁', 0.110),
+        ('岳', 0.110),
+        ('翟', 0.110),
+        ('殷', 0.110),
+        ('詹', 0.110),
+        ('申', 0.110),
+        ('欧', 0.110),
+        ('耿', 0.110),
+        ('关', 0.100),
+        ('兰', 0.100),
+        ('焦', 0.100),
+        ('俞', 0.100),
+        ('左', 0.100),
+        ('柳', 0.100),
+        ('甘', 0.095),
+        ('祝', 0.090),
+        ('包', 0.087),
+        ('宁', 0.083),
+        ('尚', 0.082),
+        ('符', 0.082),
+        ('舒', 0.082),
+        ('阮', 0.082),
+        ('柯', 0.080),
+        ('纪', 0.080),
+        ('梅', 0.079),
+        ('童', 0.079),
+        ('凌', 0.078),
+        ('毕', 0.078),
+        ('单', 0.076),
+        ('季', 0.076),
+        ('裴', 0.076),
+        ('霍', 0.075),
+        ('涂', 0.075),
+        ('成', 0.075),
+        ('苗', 0.075),
+        ('谷', 0.075),
+        ('盛', 0.074),
+        ('曲', 0.074),
+        ('翁', 0.073),
+        ('冉', 0.073),
+        ('骆', 0.073),
+        ('蓝', 0.072),
+        ('路', 0.072),
+        ('游', 0.071),
+        ('辛', 0.070),
+        ('靳', 0.069),
+        ('欧阳', 0.068),
+        ('管', 0.065),
+        ('柴', 0.065),
+        ('蒙', 0.062),
+        ('鲍', 0.062),
+        ('华', 0.061),
+        ('喻', 0.061),
+        ('祁', 0.061),
+        ('蒲', 0.056),
+        ('房', 0.056),
+        ('滕', 0.055),
+        ('屈', 0.055),
+        ('饶', 0.055),
+        ('解', 0.053),
+        ('牟', 0.053),
+        ('艾', 0.052),
+        ('尤', 0.052),
+        ('阳', 0.050),
+        ('时', 0.050),
+        ('穆', 0.048),
+        ('农', 0.047),
+        ('司', 0.044),
+        ('卓', 0.043),
+        ('古', 0.043),
+        ('吉', 0.043),
+        ('缪', 0.043),
+        ('简', 0.043),
+        ('车', 0.043),
+        ('项', 0.043),
+        ('连', 0.043),
+        ('芦', 0.042),
+        ('麦', 0.041),
+        ('褚', 0.041),
+        ('娄', 0.040),
+        ('窦', 0.040),
+        ('戚', 0.040),
+        ('岑', 0.039),
+        ('景', 0.039),
+        ('党', 0.039),
+        ('宫', 0.039),
+        ('费', 0.039),
+        ('卜', 0.038),
+        ('冷', 0.038),
+        ('晏', 0.038),
+        ('席', 0.036),
+        ('卫', 0.036),
+        ('米', 0.035),
+        ('柏', 0.035),
+        ('宗', 0.034),
+        ('瞿', 0.033),
+        ('桂', 0.033),
+        ('全', 0.033),
+        ('佟', 0.033),
+        ('应', 0.033),
+        ('臧', 0.032),
+        ('闵', 0.032),
+        ('苟', 0.032),
+        ('邬', 0.032),
+        ('边', 0.032),
+        ('卞', 0.032),
+        ('姬', 0.032),
+        ('师', 0.031),
+        ('和', 0.031),
+        ('仇', 0.030),
+        ('栾', 0.030),
+        ('隋', 0.030),
+        ('商', 0.030),
+        ('刁', 0.030),
+        ('沙', 0.030),
+        ('荣', 0.029),
+        ('巫', 0.029),
+        ('寇', 0.029),
+        ('桑', 0.028),
+        ('郎', 0.028),
+        ('甄', 0.027),
+        ('丛', 0.027),
+        ('仲', 0.027),
+        ('虞', 0.026),
+        ('敖', 0.026),
+        ('巩', 0.026),
+        ('明', 0.026),
+        ('佘', 0.025),
+        ('池', 0.025),
+        ('查', 0.025),
+        ('麻', 0.025),
+        ('苑', 0.025),
+        ('迟', 0.024),
+        ('邝', 0.024),
+        ('官', 0.023),
+        ('封', 0.023),
+        ('谈', 0.023),
+        ('匡', 0.023),
+        ('鞠', 0.230),
+        ('惠', 0.022),
+        ('荆', 0.022),
+        ('乐', 0.022),
+        ('冀', 0.021),
+        ('郁', 0.021),
+        ('胥', 0.021),
+        ('南', 0.021),
+        ('班', 0.021),
+        ('储', 0.021),
+        ('原', 0.020),
+        ('栗', 0.020),
+        ('燕', 0.020),
+        ('楚', 0.020),
+        ('鄢', 0.020),
+        ('劳', 0.019),
+        ('谌', 0.019),
+        ('奚', 0.017),
+        ('皮', 0.017),
+        ('粟', 0.017),
+        ('冼', 0.017),
+        ('蔺', 0.017),
+        ('楼', 0.017),
+        ('盘', 0.017),
+        ('满', 0.016),
+        ('闻', 0.016),
+        ('位', 0.016),
+        ('厉', 0.016),
+        ('伊', 0.016),
+        ('仝', 0.015),
+        ('区', 0.015),
+        ('郜', 0.015),
+        ('海', 0.015),
+        ('阚', 0.015),
+        ('花', 0.015),
+        ('权', 0.014),
+        ('强', 0.014),
+        ('帅', 0.014),
+        ('屠', 0.014),
+        ('豆', 0.014),
+        ('朴', 0.014),
+        ('盖', 0.014),
+        ('练', 0.014),
+        ('廉', 0.014),
+        ('禹', 0.014),
+        ('井', 0.013),
+        ('祖', 0.013),
+        ('漆', 0.013),
+        ('巴', 0.013),
+        ('丰', 0.013),
+        ('支', 0.013),
+        ('卿', 0.013),
+        ('国', 0.013),
+        ('狄', 0.013),
+        ('平', 0.013),
+        ('计', 0.012),
+        ('索', 0.012),
+        ('宣', 0.012),
+        ('晋', 0.012),
+        ('相', 0.012),
+        ('初', 0.012),
+        ('门', 0.012),
+        ('云', 0.012),
+        ('容', 0.012),
+        ('敬', 0.011),
+        ('来', 0.011),
+        ('扈', 0.011),
+        ('晁', 0.011),
+        ('芮', 0.011),
+        ('都', 0.011),
+        ('普', 0.011),
+        ('阙', 0.011),
+        ('浦', 0.011),
+        ('戈', 0.011),
+        ('伏', 0.011),
+        ('鹿', 0.011),
+        ('薄', 0.011),
+        ('邸', 0.011),
+        ('雍', 0.010),
+        ('辜', 0.010),
+        ('羊', 0.010),
+        ('阿', 0.010),
+        ('乌', 0.010),
+        ('母', 0.010),
+        ('裘', 0.010),
+        ('亓', 0.010),
+        ('修', 0.010),
+        ('邰', 0.010),
+        ('赫', 0.010),
+        ('杭', 0.010),
+        ('况', 0.0094),
+        ('那', 0.0093),
+        ('宿', 0.0093),
+        ('鲜', 0.0092),
+        ('印', 0.0091),
+        ('逯', 0.0091),
+        ('隆', 0.0090),
+        ('茹', 0.0090),
+        ('诸', 0.0089),
+        ('战', 0.0088),
+        ('慕', 0.0086),
+        ('危', 0.0084),
+        ('玉', 0.0084),
+        ('银', 0.0084),
+        ('亢', 0.0083),
+        ('嵇', 0.0082),
+        ('公', 0.0082),
+        ('哈', 0.0081),
+        ('湛', 0.0079),
+        ('宾', 0.0077),
+        ('戎', 0.0076),
+        ('勾', 0.0076),
+        ('茅', 0.0076),
+        ('利', 0.0076),
+        ('于', 0.0074),
+        ('呼', 0.0074),
+        ('居', 0.0074),
+        ('揭', 0.0073),
+        ('干', 0.0072),
+        ('但', 0.0072),
+        ('尉', 0.0071),
+        ('冶', 0.0071),
+        ('斯', 0.0070),
+        ('元', 0.0069),
+        ('束', 0.0068),
+        ('檀', 0.0068),
+        ('衣', 0.0067),
+        ('信', 0.0067),
+        ('展', 0.0067),
+        ('阴', 0.0067),
+        ('昝', 0.0066),
+        ('智', 0.0065),
+        ('幸', 0.0065),
+        ('奉', 0.0064),
+        ('植', 0.0064),
+        ('衡', 0.0063),
+        ('富', 0.0063),
+        ('尧', 0.0060),
+        ('闭', 0.0060),
+        ('由', 0.0060),
+    ))
 
     romanized_formats = (
         '{{first_romanized_name}} {{last_romanized_name}}',
diff --git a/faker/providers/phone_number/de_DE/__init__.py b/faker/providers/phone_number/de_DE/__init__.py
index bee09757..e9a7fdfa 100644
--- a/faker/providers/phone_number/de_DE/__init__.py
+++ b/faker/providers/phone_number/de_DE/__init__.py
@@ -5,6 +5,7 @@ from .. import Provider as PhoneNumberProvider
 
 
 class Provider(PhoneNumberProvider):
+    # https://de.wikipedia.org/wiki/Rufnummer#Schreibweisen
     formats = (
         '+49(0)##########',
         '+49(0)#### ######',


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
index 38c55398..f2eb0b85 100644
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -457,14 +457,34 @@ class TestEnUS(unittest.TestCase):
 
     def test_postcode(self):
         for _ in range(100):
-            postcode = self.factory.postcode()
-            assert re.match(r"\d{5}", postcode)
+            code = self.factory.postcode()
+            assert re.match(r"\d{5}", code)
+
+    def test_postcode_in_state(self):
+        for state_abbr in EnUsProvider.states_abbr:
+            code = self.factory.postcode_in_state(state_abbr)
+            assert re.match(r"\d{5}", code)
+            assert int(code) >= EnUsProvider.states_postcode[state_abbr][0]
+            assert int(code) <= EnUsProvider.states_postcode[state_abbr][1]
+
+        with self.assertRaises(Exception):
+            self.factory.postcode_in_state('XX')
 
     def test_zipcode(self):
         for _ in range(100):
             zipcode = self.factory.zipcode()
             assert re.match(r"\d{5}", zipcode)
 
+    def test_zipcode_in_state(self):
+        for state_abbr in EnUsProvider.states_abbr:
+            code = self.factory.zipcode_in_state(state_abbr)
+            assert re.match(r"\d{5}", code)
+            assert int(code) >= EnUsProvider.states_postcode[state_abbr][0]
+            assert int(code) <= EnUsProvider.states_postcode[state_abbr][1]
+
+        with self.assertRaises(Exception):
+            self.factory.zipcode_in_state('XX')
+
     def test_zipcode_plus4(self):
         for _ in range(100):
             zipcode_plus4 = self.factory.zipcode_plus4()
@@ -490,6 +510,21 @@ class TestEnUS(unittest.TestCase):
         military_dpo = self.factory.military_dpo()
         assert isinstance(military_dpo, string_types)
 
+    def test_postalcode(self):
+        for _ in range(100):
+            postalcode = self.factory.postalcode()
+            assert re.match(r"\d{5}", postalcode)
+
+    def test_postalcode_in_state(self):
+        for state_abbr in EnUsProvider.states_abbr:
+            code = self.factory.postalcode_in_state(state_abbr)
+            assert re.match(r"\d{5}", code)
+            assert int(code) >= EnUsProvider.states_postcode[state_abbr][0]
+            assert int(code) <= EnUsProvider.states_postcode[state_abbr][1]
+
+        with self.assertRaises(Exception):
+            self.factory.postalcode_in_state('XX')
+
 
 class TestHRHR(unittest.TestCase):
     """ Tests addresses in the hr_HR locale """
diff --git a/tests/providers/test_person.py b/tests/providers/test_person.py
index aaf22b29..a8c99e85 100644
--- a/tests/providers/test_person.py
+++ b/tests/providers/test_person.py
@@ -16,6 +16,7 @@ from faker.providers.person.cs_CZ import Provider as CsCZProvider
 from faker.providers.person.pl_PL import (
     checksum_identity_card_number as pl_checksum_identity_card_number,
 )
+from faker.providers.person.zh_CN import Provider as ZhCNProvider
 
 
 class TestAr(unittest.TestCase):
@@ -248,3 +249,83 @@ class TestCsCZ(unittest.TestCase):
                 last_name = name_parts[2]
         assert first_name in CsCZProvider.first_names_female
         assert last_name in CsCZProvider.last_names_female
+
+
+class TestZhCN(unittest.TestCase):
+
+    def setUp(self):
+        self.factory = Faker('zh_CN')
+
+    def test_last_name(self):
+        # There's no gender-specific last name in Chinese.
+        assert not hasattr(ZhCNProvider, 'last_names_male')
+        assert not hasattr(ZhCNProvider, 'last_names_female')
+        assert not hasattr(ZhCNProvider, 'last_romanized_names_male')
+        assert not hasattr(ZhCNProvider, 'last_romanized_names_female')
+        # All last names apply for all genders.
+        assert hasattr(ZhCNProvider, 'last_names')
+
+        # General first name.
+        name = self.factory.last_name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.last_names
+
+        # Females last name.
+        name = self.factory.last_name_female()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.last_names
+
+        # Male last name.
+        name = self.factory.last_name_male()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.last_names
+
+        # General last romanized name
+        name = self.factory.last_romanized_name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.last_romanized_names
+
+    def test_first_name(self):
+        # General first name
+        name = self.factory.first_name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.first_names
+
+        # Females first name
+        name = self.factory.first_name_female()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.first_names
+
+        # Male first name
+        name = self.factory.first_name_male()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.first_names
+
+        # General first romanized name
+        name = self.factory.first_romanized_name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name in ZhCNProvider.first_romanized_names
+
+    def test_name(self):
+        # Full name
+        name = self.factory.name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        assert name[0] in ZhCNProvider.last_names or name[:2] in ZhCNProvider.last_names
+        assert name[1:] in ZhCNProvider.first_names or name[2:] in ZhCNProvider.first_names
+
+        # Full romanized name
+        name = self.factory.romanized_name()
+        assert name
+        self.assertIsInstance(name, six.string_types)
+        first_romanized_name, last_romanized_name = name.split(' ')
+        assert first_romanized_name in ZhCNProvider.first_romanized_names
+        assert last_romanized_name in ZhCNProvider.last_romanized_names