Skip to content

Instantly share code, notes, and snippets.

@trsqxyz
Last active October 29, 2015 06:23
Show Gist options
  • Save trsqxyz/11f90b64b9e517645d31 to your computer and use it in GitHub Desktop.
Save trsqxyz/11f90b64b9e517645d31 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals, print_function
from collections import defaultdict
from contextlib import contextmanager
import random
_MIN_BASE = 10000000000
_MAX_BASE = 99999999999
class MyNumber(object):
def __iter__(self):
"""
return My Number Duplicate Yes
:rtype :int
"""
cls = MyNumber
while True:
seed = random.randint(_MIN_BASE, _MAX_BASE)
yield seed * 10 + cls.get_check_sum(int(str(seed)[::-1]))
@classmethod
def gets(cls, count):
"""
return My Number Duplicate No
:param count:
:return:
"""
limit = 10000000
if count > limit:
raise ValueError
# generate My Number by Duplicate No
result = defaultdict(int)
depth = 0
for number in cls():
result[number] += 1
if len(result) >= count:
return result
if depth > limit * 100:
raise ValueError
else:
depth += 1
@classmethod
def validate(cls, number):
"""
validate number
# My Number System Laws #5
http://www.soumu.go.jp/main_content/000327387.pdf
:param number: int
:rtype : bool
"""
try:
with cls._check(number) as (inspection, check_sum):
return cls.get_check_sum(inspection) == check_sum
except (TypeError, ValueError):
print("number must be 12-digit:{}".format(str(number)))
@classmethod
def get_check_sum(cls, inspection):
"""
calc check sum from inspection
:param inspection: int
:rtype : int
"""
def q(_n):
if 1 <= _n <= 6:
return _n + 1
if 7 <= _n <= 11:
return _n - 5
n = 12 - len(str(inspection))
_result = 0
for p in str(inspection):
_result += int(p) * q(n)
n += 1
surplus = _result % 11
if surplus <= 1:
return 0
return 11 - surplus
@classmethod
def divide(cls, number):
"""
Divide My Number to inspection and check sum
:param number: int
:rtype : tuple(int, int)
"""
check_sum = int(str(number)[-1])
inspection = int(str(number)[:11][::-1])
return inspection, check_sum
@classmethod
@contextmanager
def _check(cls, number):
if not isinstance(number, int):
raise TypeError
if len(str(number)) != 12:
raise ValueError
yield cls.divide(number)
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals, print_function
from mynumber import MyNumber
def test_divide():
num = 123456789018
inspection, check_sum = MyNumber.divide(num)
assert inspection == 10987654321
assert check_sum == 8
def test_validate():
num_group = [
123456789018,
190852597007,
664559681879,
317115269465,
636234891610,
759492641118,
653148356959,
712502608231,
845344637296,
626150900081,
250059391352,
220009988475,
518472892796,
971973656959,
142943093120,
661945516417,
275391807883,
422468354448,
345381273668,
282612367782,
993274102186,
101951472043,
288204947884,
459810701741,
673630519726,
428367052872,
656861725106,
559958524339,
727514382775,
858986774968,
633284231620,
457474026230,
]
for num in num_group:
assert MyNumber.validate(num), MyNumber.validate(num)
def test_iter():
ct = 1
for m in MyNumber():
ct += 1
assert MyNumber.validate(m), m
if ct > 1000:
return
raise
def test_gets():
count = 1000
numbers = MyNumber.gets(count)
assert len(numbers) == count
for num in numbers:
print(num)
assert MyNumber.validate(num), num
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment