prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  zh_CN (and possible other providers) return invalid results for domain_name
  Brief summary of the issue goes here.
  
  ### Steps to reproduce
  
  f = Faker('zh_CN')
  f.domain_name()
  >he.cn
  
  ### Expected behavior
  
  it should return valid domain names
  
  ### Actual behavior
  
  he.cn is not a valid domain. he is in the list of second-level domains (https://en.wikipedia.org/wiki/.cn#Second-level_domains_of_provinces) and will cause failures in places where domains are being validated.
  
  it's unclear where this change should/could be made after briefly reviewing the source code.
  
  
  </issue>
  <code>
  [start of faker/providers/internet/zh_CN/__init__.py]
  1 # coding=utf-8
  2 from __future__ import unicode_literals
  3 from .. import Provider as InternetProvider
  4 from faker.utils.decorators import slugify
  5 
  6 
  7 class Provider(InternetProvider):
  8     user_name_formats = (
  9         '{{last_romanized_name}}.{{first_romanized_name}}',
  10         '{{first_romanized_name}}.{{last_romanized_name}}',
  11         '{{first_romanized_name}}##',
  12         '?{{last_romanized_name}}',
  13     )
  14     tlds = ('com', 'com', 'com', 'net', 'org', 'cn', 'cn', 'cn')
  15 
  16     @slugify
  17     def domain_word(self):
  18         return self.generator.format('last_romanized_name')
  19
  [end of faker/providers/internet/zh_CN/__init__.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/faker/providers/internet/zh_CN/__init__.py b/faker/providers/internet/zh_CN/__init__.py
  --- a/faker/providers/internet/zh_CN/__init__.py
  +++ b/faker/providers/internet/zh_CN/__init__.py
  @@ -1,5 +1,6 @@
   # coding=utf-8
   from __future__ import unicode_literals
  +from collections import OrderedDict
   from .. import Provider as InternetProvider
   from faker.utils.decorators import slugify
   
  @@ -11,8 +12,54 @@
           '{{first_romanized_name}}##',
           '?{{last_romanized_name}}',
       )
  -    tlds = ('com', 'com', 'com', 'net', 'org', 'cn', 'cn', 'cn')
  +
  +    tlds = OrderedDict((
  +        ('cn', 0.8),
  +        ('net', 0.1),
  +        ('com', 0.05),
  +        ('org', 0.05),
  +    ))
  +
  +    second_level_domains = ('ac', 'com', 'edu', 'gov', 'mil', 'net', 'org',
  +                            'ah', 'bj', 'cq', 'fj', 'gd', 'gs', 'gz', 'gx',
  +                            'ha', 'hb', 'he', 'hi', 'hk', 'hl', 'hn', 'jl',
  +                            'js', 'jx', 'ln', 'mo', 'nm', 'nx', 'qh', 'sc',
  +                            'sd', 'sh', 'sn', 'sx', 'tj', 'xj', 'xz', 'yn', 'zj')
  +
  +    domain_formats = (
  +        '##', '??',
  +        '{{first_romanized_name}}',
  +        '{{last_romanized_name}}',
  +        '{{first_romanized_name}}{{last_romanized_name}}',
  +        '{{last_romanized_name}}{{last_romanized_name}}',
  +        '{{first_romanized_name}}{{first_romanized_name}}',
  +    )
   
       @slugify
       def domain_word(self):
  -        return self.generator.format('last_romanized_name')
  +        pattern = self.random_element(self.domain_formats)
  +        if '#' in pattern or '?' in pattern:
  +            return self.bothify(pattern)
  +        else:
  +            return self.generator.parse(pattern)
  +
  +    def domain_name(self, levels=1):
  +        if levels < 1:
  +            raise ValueError("levels must be greater than or equal to 1")
  +        if levels == 1:
  +            domain_word = self.domain_word()
  +            # Avoids he.cn as seen in issue #687
  +            while domain_word in self.second_level_domains:
  +                domain_word = self.domain_word()
  +            return domain_word + '.' + self.tld()
  +        elif levels == 2:
  +            my_tld = self.tld()
  +            my_second_level = ''
  +            if my_tld == 'cn':
  +                my_second_level = self.random_element(self.second_level_domains)
  +            else:
  +                my_second_level = self.domain_word()
  +            return self.domain_word() + '.' + my_second_level + '.' + my_tld
  +        else:
  +            return self.domain_word() + '.' + self.domain_name(levels - 1)
  +
  
verification_info: {"golden_diff": "diff --git a/faker/providers/internet/zh_CN/__init__.py b/faker/providers/internet/zh_CN/__init__.py\n--- a/faker/providers/internet/zh_CN/__init__.py\n+++ b/faker/providers/internet/zh_CN/__init__.py\n@@ -1,5 +1,6 @@\n # coding=utf-8\n from __future__ import unicode_literals\n+from collections import OrderedDict\n from .. import Provider as InternetProvider\n from faker.utils.decorators import slugify\n \n@@ -11,8 +12,54 @@\n         '{{first_romanized_name}}##',\n         '?{{last_romanized_name}}',\n     )\n-    tlds = ('com', 'com', 'com', 'net', 'org', 'cn', 'cn', 'cn')\n+\n+    tlds = OrderedDict((\n+        ('cn', 0.8),\n+        ('net', 0.1),\n+        ('com', 0.05),\n+        ('org', 0.05),\n+    ))\n+\n+    second_level_domains = ('ac', 'com', 'edu', 'gov', 'mil', 'net', 'org',\n+                            'ah', 'bj', 'cq', 'fj', 'gd', 'gs', 'gz', 'gx',\n+                            'ha', 'hb', 'he', 'hi', 'hk', 'hl', 'hn', 'jl',\n+                            'js', 'jx', 'ln', 'mo', 'nm', 'nx', 'qh', 'sc',\n+                            'sd', 'sh', 'sn', 'sx', 'tj', 'xj', 'xz', 'yn', 'zj')\n+\n+    domain_formats = (\n+        '##', '??',\n+        '{{first_romanized_name}}',\n+        '{{last_romanized_name}}',\n+        '{{first_romanized_name}}{{last_romanized_name}}',\n+        '{{last_romanized_name}}{{last_romanized_name}}',\n+        '{{first_romanized_name}}{{first_romanized_name}}',\n+    )\n \n     @slugify\n     def domain_word(self):\n-        return self.generator.format('last_romanized_name')\n+        pattern = self.random_element(self.domain_formats)\n+        if '#' in pattern or '?' in pattern:\n+            return self.bothify(pattern)\n+        else:\n+            return self.generator.parse(pattern)\n+\n+    def domain_name(self, levels=1):\n+        if levels < 1:\n+            raise ValueError(\"levels must be greater than or equal to 1\")\n+        if levels == 1:\n+            domain_word = self.domain_word()\n+            # Avoids he.cn as seen in issue #687\n+            while domain_word in self.second_level_domains:\n+                domain_word = self.domain_word()\n+            return domain_word + '.' + self.tld()\n+        elif levels == 2:\n+            my_tld = self.tld()\n+            my_second_level = ''\n+            if my_tld == 'cn':\n+                my_second_level = self.random_element(self.second_level_domains)\n+            else:\n+                my_second_level = self.domain_word()\n+            return self.domain_word() + '.' + my_second_level + '.' + my_tld\n+        else:\n+            return self.domain_word() + '.' + self.domain_name(levels - 1)\n+\n", "issue": "zh_CN (and possible other providers) return invalid results for domain_name\nBrief summary of the issue goes here.\r\n\r\n### Steps to reproduce\r\n\r\nf = Faker('zh_CN')\r\nf.domain_name()\r\n>he.cn\r\n\r\n### Expected behavior\r\n\r\nit should return valid domain names\r\n\r\n### Actual behavior\r\n\r\nhe.cn is not a valid domain. he is in the list of second-level domains (https://en.wikipedia.org/wiki/.cn#Second-level_domains_of_provinces) and will cause failures in places where domains are being validated.\r\n\r\nit's unclear where this change should/could be made after briefly reviewing the source code.\r\n\n", "before_files": [{"content": "# coding=utf-8\nfrom __future__ import unicode_literals\nfrom .. import Provider as InternetProvider\nfrom faker.utils.decorators import slugify\n\n\nclass Provider(InternetProvider):\n    user_name_formats = (\n        '{{last_romanized_name}}.{{first_romanized_name}}',\n        '{{first_romanized_name}}.{{last_romanized_name}}',\n        '{{first_romanized_name}}##',\n        '?{{last_romanized_name}}',\n    )\n    tlds = ('com', 'com', 'com', 'net', 'org', 'cn', 'cn', 'cn')\n\n    @slugify\n    def domain_word(self):\n        return self.generator.format('last_romanized_name')\n", "path": "faker/providers/internet/zh_CN/__init__.py"}]}