Repository: joke2k/faker

Issue:
Rep. of Korea use 5-digit postcode
Long time a go, Korea used `###--###` format zipcode.
[But since 2015-07-31, 96% of sender in Korea use 5-digit postcode(note: it is korean news article)](http://weekly.khan.co.kr/khnm.html?mode=view&code=114&artid=201608161714581)

I want to make PR for changing from `###-###` to `#####`, but I mind old-style zipcode user.

If I was maintainer of this project, I will provide `length` parameter like this.

``` pycon
>>> fake.postcode()
12345
>>> fake.postcode(length=5)
12345
>>> fake.postcode(length=6)
123-456
```

How do you think about this?



Discussion:
Hi @item4 

do the two differnet standards have different names? In that case I'd rather use the standard name (via a constant) rather than the length

@fcurella I'll research it soon

@fcurella I had research and check with goverment department.

Reference: [Official Confirmation Prividing that Old and New Addresses are Identical (warn: cert error)](https://www.juso.go.kr/addridentity/AddrIdentityHelp.htm) (thanks to @minieetea to help)

Korea has two address and postal code system.

### Address
- Address based on land parcel numbers (`지번 주소`, OLD, but someone use consistently)
- Address based on road names and building numbers (`도로명 주소`, NEW)

### Postal code
- Old postal code (6-digit, OLD and dead)
- New postal code (5-digit, New)

---

I want refactoring not only post code methods but also address-related methods. They have many confusion.

For example

``` pycon
>>> fake.address()
'서울특별시 성두마을 \n 승윤로 831 516-538'
>>> fake.address()
'경상북도 광원군 \n 화완선거리 6 433-113'
>>> fake.address()
'대전광역시 세열구 상철온군 4 (422-981)'
>>> fake.address()
'부산광역시 원주훈군 완의경군 0 (270-305)'
>>> fake.address()
'전라남도 문리슬시 야통선거리 319 1-7 (136-551)'
>>> fake.address()
'인천광역시 맹가도군 태성로 7071 96-5 (814-857)'
>>> fake.address()
'서울특별시 윤정광구 \n 다도동 0100 009동 696호 019-910'
>>> fake.address()
'울산광역시 유근선구 \n 범균동 5227 1-0 082-219'
```
1. Why address contain `\n` character?
2. Why address contain post code?
3. They mixed two address system.

I want to seperate and refector address methods.

### land address

``` pycon
>>> fake.land_parcel_address()
'세종특별자치시 어진동 507'
```

### road address

``` pycon
>>> fake.road_address()
'세종특별자치시 도움5로 19 (어진동)'
>>> fake.street_name()
'도움5로'
```

### address commons

``` pycon
>>> fake.address_detail()
'ㅇㅇ아파트 ㅁ동 102호'
>>> [fake.metropolitan_city() for x in range(2)
['서울특별시', '부산광역시']
>>>  [fake.province() for x in range(3)]
['경기도',  '강원도',  '경상남도']
>>>  [fake.city() for x in range(2)]  # API break
['고양시',  'ㅇㅇ시']
>>>  [fake.borough() for x in range(2)]
['ㅇㅇ구',  'ㅁㅁ구']
>>> [fake.town() for x in range(3)]
['어진동', 'ㅇㅇ리',  'ㅇㅇ마을']
>>> [fake.building_name() for x in range(2)]
['ㅇㅇ빌라',  'ㅇㅇ아파트']
```

### postal code

``` pycon
>>> fake.old_postal_code()
'123-456'
>>> fake.postcode()
'123-456'
>>> fake.postal_code()
'30114'
```


Resolving patch:
diff --git a/faker/providers/address/ko_KR/__init__.py b/faker/providers/address/ko_KR/__init__.py
--- a/faker/providers/address/ko_KR/__init__.py
+++ b/faker/providers/address/ko_KR/__init__.py
@@ -4,14 +4,183 @@
 
 
 class Provider(AddressProvider):
-    city_suffixes = ('마을', '시', '군', '구')
-    building_number_formats = ('#', '####', '###')
-    street_suffixes = ('동', '로', '거리')
-    postcode_formats = ('###-###', '###-###')
-    states = (
-        '서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시', '울산광역시',
-        '세종특별자치시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도', '경상북도',
-        '경상남도', '제주특별자치도')
+    """
+    Koran Address Provider
+    ======================
+
+    Korea has two address and postal code system.
+
+    Address
+    -------
+
+    - Address based on land parcel numbers
+      (지번 주소, OLD, but someone use consistently)
+    - Address based on road names and building numbers (도로명 주소, NEW)
+
+    :meth:`land_address` generate Address based on land parcel numbers and
+    :meth:`road_address` generate Address based on road names and building
+    numbers.
+
+    Postal code
+    -----------
+
+    - Old postal code (6-digit, OLD and dead)
+    - New postal code (5-digit, New)
+
+    :meth:`old_postal_code` and :meth:`postcode` generate old 6-digit code
+    and :meth:`postal_code` generate newer 5-digit code.
+
+    Reference
+    ---------
+
+    - `Official Confirmation Prividing that Old and New Addresses are Identical`__
+      (warn: cert error)
+
+    __ https://www.juso.go.kr/addridentity/AddrIdentityHelp.htm
+
+    """
+
+    building_suffixes = (
+        '빌라',
+        '아파트',
+        '연립',
+        '마을',
+        '타운',
+        '타워',
+    )
+    road_suffixes = ('로', '길', '거리', '가')
+    town_suffixes = ('동', '리', '마을')
+    postcode_formats = ('###-###',)
+    new_postal_code_formats = ('#####',)
+    metropolitan_cities = (
+        '서울특별시',
+        '부산광역시',
+        '대구광역시',
+        '인천광역시',
+        '광주광역시',
+        '대전광역시',
+        '울산광역시',
+        '세종특별자치시',
+    );
+    provinces = (
+        '경기도',
+        '강원도',
+        '충청북도',
+        '충청남도',
+        '전라북도',
+        '전라남도',
+        '경상북도',
+        '경상남도',
+        '제주특별자치도',
+    )
+    cities = (
+        '파주시',
+        '수원시',
+        '수원시 권선구',
+        '수원시 팔달구',
+        '수원시 영통구',
+        '성남시',
+        '성남시 수정구',
+        '성남시 중원구',
+        '화성시',
+        '성남시 분당구',
+        '안양시',
+        '안양시 만안구',
+        '안양시 동안구',
+        '부천시',
+        '부천시 원미구',
+        '부천시 소사구',
+        '부천시 오정구',
+        '광명시',
+        '평택시',
+        '이천시',
+        '동두천시',
+        '안산시',
+        '안산시 상록구',
+        '안산시 단원구',
+        '안성시',
+        '고양시',
+        '고양시 덕양구',
+        '고양시 일산동구',
+        '고양시 일산서구',
+        '과천시',
+        '구리시',
+        '남양주시',
+        '오산시',
+        '시흥시',
+        '군포시',
+        '의왕시',
+        '하남시',
+        '김포시',
+        '용인시',
+        '용인시 처인구',
+        '용인시 기흥구',
+        '용인시 수지구',
+        '연천군',
+        '가평군',
+        '양평군',
+        '광주시',
+        '포천시',
+        '양주시',
+        '수원시 장안구',
+        '의정부시',
+        '여주시',
+    )
+    road_names = (
+        '압구정',
+        '도산대',
+        '학동',
+        '봉은사',
+        '테헤란',
+        '역삼',
+        '논현',
+        '언주',
+        '강남대',
+        '양재천',
+        '삼성',
+        '영동대',
+        '개포',
+        '선릉',
+        '반포대',
+        '서초중앙',
+        '서초대',
+        '잠실',
+        '석촌호수',
+        '백제고분',
+        '가락',
+        '오금',
+    )
+    boroughs = (
+        '종로구',
+        '중구',
+        '용산구',
+        '성동구',
+        '광진구',
+        '동대문구',
+        '중랑구',
+        '성북구',
+        '강북구',
+        '도봉구',
+        '노원구',
+        '은평구',
+        '서대문구',
+        '마포구',
+        '양천구',
+        '강서구',
+        '구로구',
+        '금천구',
+        '영등포구',
+        '동작구',
+        '관악구',
+        '서초구',
+        '강남구',
+        '송파구',
+        '강동구',
+        '동구',
+        '서구',
+        '남구',
+        '북구',
+    )
     countries = ('가나', '가봉', '가이아나', '감비아', '과테말라', '그레나다', '그리스', '기니', '기니비사우',
                  '나미비아', '나우루', '나이지리아', '남수단', '남아프리카 공화국', '네덜란드 왕국', '네팔',
                  '노르웨이', '뉴질랜드', '니제르', '니카라과', '대한민국', '덴마크', '도미니카 공화국',
@@ -40,31 +209,192 @@ class Provider(AddressProvider):
                  '파라과이', '파키스탄', '파푸아 뉴기니', '팔라우', '페루', '포르투갈', '폴란드', '프랑스',
                  '피지', '핀란드', '필리핀', '헝가리'
     )
+    building_dongs = (
+        '가',
+        '나',
+        '다',
+        '라',
+        '마',
+        '바',
+        '##',
+        '###',
+    )
+    land_numbers = (
+        '###',
+        '###-#',
+        '###-##',
+    )
+    road_numbers = (
+        '#',
+        '##',
+        '###',
+    )
 
-    city_formats = (
-        '{{last_name}}{{last_name}}{{city_suffix}}',
-        '{{first_name}}{{last_name}}{{last_name}}{{city_suffix}}'
+    town_formats = (
+        '{{first_name}}{{last_name}}{{town_suffix}}',
+        '{{first_name}}{{last_name}}{{last_name}}{{town_suffix}}',
+    )
+    building_name_formats = (
+        '{{first_name}}{{last_name}}{{building_suffix}}',
+        '{{first_name}}{{last_name}}{{last_name}}{{building_suffix}}',
+    )
+    address_detail_formats = (
+        '{{building_name}}',
+        '{{building_name}} ###호',
+        '{{building_name}} {{building_dong}}동 ###호',
     )
-    street_name_formats = (
-        '{{last_name}}{{last_name}}{{last_name}}{{city_suffix}}',
-        '{{last_name}}{{last_name}}{{last_name}}{{street_suffix}}',
-        '{{first_name}}{{last_name}}{{last_name}}{{street_suffix}}',
-        '{{last_name}}{{last_name}}{{street_suffix}}'
+    road_formats = (
+        '{{road_name}}{{road_suffix}}',
+        '{{road_name}}{{road_number}}{{road_suffix}}',
     )
-    street_address_formats = (
-        '{{street_name}} {{building_number}}',
-        '{{street_name}} {{building_number}} {{secondary_address}}'
+    road_address_formats = (
+        '{{metropolitan_city}} {{borough}} {{road}}',
+        '{{province}} {{city}} {{road}}',
+        '{{metropolitan_city}} {{borough}} {{road}} ({{town}})',
+        '{{province}} {{city}} {{road}} ({{town}})',
     )
-    address_formats = (
-        "{{state}} {{city}} {{street_address}} ({{postcode}})",
-        "{{state}} {{city}} \n {{street_address}} {{postcode}}"
+    land_address_formats = (
+        '{{metropolitan_city}} {{borough}} {{town}} {{land_number}}',
+        '{{province}} {{city}} {{town}} {{land_number}}',
     )
-    secondary_address_formats = ('###동 ###호', '#-#', '###', '###-#', '##-#')
+
+    # Keep backward compatibility
+    city_suffixes = ('시',)
+    street_suffixes = road_suffixes
+    street_name_formats = ('{{road_name}}',)
+    street_address_formats = road_address_formats
+    address_formats = road_address_formats
+
+    @classmethod
+    def land_number(cls):
+        """
+        :example 507
+        """
+        return cls.bothify(cls.random_element(cls.land_numbers))
+
+    def land_address(self):
+        """
+        :example 세종특별자치시 어진동 507
+        """
+        pattern = self.random_element(self.land_address_formats)
+        return self.generator.parse(pattern)
+
+    @classmethod
+    def road_number(cls):
+        """
+        :example 24
+        """
+        return cls.bothify(cls.random_element(cls.road_numbers))
+
+    def road_address(self):
+        """
+        :example 세종특별자치시 도움5로 19 (어진동)
+        """
+        pattern = self.random_element(self.road_address_formats)
+        return self.generator.parse(pattern)
+
+    def address_detail(self):
+        """
+        :example 가나아파트 가동 102호
+        """
+        pattern = self.bothify(self.random_element(
+            self.address_detail_formats))
+        return self.generator.parse(pattern)
+
+    def road(self):
+        """
+        :example 도움5로
+        """
+        pattern = self.random_element(self.road_formats)
+        return self.generator.parse(pattern)
+
+    @classmethod
+    def road_name(cls):
+        """
+        :example 압구정
+        """
+        return cls.random_element(cls.road_names)
+
+    @classmethod
+    def road_suffix(cls):
+        """
+        :example 길
+        """
+        return cls.random_element(cls.road_suffixes)
+
+    @classmethod
+    def metropolitan_city(cls):
+        """
+        :example 서울특별시
+        """
+        return cls.random_element(cls.metropolitan_cities)
+
+    @classmethod
+    def province(cls):
+        """
+        :example 경기도
+        """
+        return cls.random_element(cls.provinces)
+
+    def city(self):
+        """
+        :example 고양시
+        """
+        pattern = self.random_element(self.cities)
+        return self.generator.parse(pattern)
+
+    @classmethod
+    def borough(cls):
+        """
+        :example 중구
+        """
+        return cls.random_element(cls.boroughs)
+
+    def town(self):
+        """
+        :example 가나동
+        """
+        pattern = self.random_element(self.town_formats)
+        return self.generator.parse(pattern)
+
+    @classmethod
+    def town_suffix(cls):
+        """
+        :example 동
+        """
+        return cls.random_element(cls.town_suffixes)
+
+    def building_name(self):
+        """
+        :example 김구아파트
+        """
+        pattern = self.random_element(self.building_name_formats)
+        return self.generator.parse(pattern)
+
+    @classmethod
+    def building_suffix(cls):
+        """
+        :example 아파트
+        """
+        return cls.random_element(cls.building_suffixes)
+
+    @classmethod
+    def building_dong(cls):
+        """
+        :example 가
+        """
+        return cls.bothify(cls.random_element(cls.building_dongs))
 
     @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def old_postal_code(cls):
+        """
+        :example 123-456
+        """
+        return cls.bothify(cls.random_element(cls.postcode_formats))
 
     @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def postal_code(cls):
+        """
+        :example 12345
+        """
+        return cls.bothify(cls.random_element(cls.new_postal_code_formats))


Test patch: