def consume_cpu_time(self, seconds): t0 = time.clock() t1 = time.clock() while t1 - t0 < seconds: for i in pycompat.range(10000000): x = i * i t1 = time.clock() return True
def random_token(string=False): # the token has an entropy of about 120 bits (6 bits/char * 20 chars) chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' if string: return ''.join(random.SystemRandom().choice(chars) for _ in pycompat.range(20)) else: return random.choice(chars)
def pager(self, url, total, page=1, step=30, scope=5, url_args=None): """ Generate a dict with required value to render `website.pager` template. This method compute url, page range to display, ... in the pager. :param url : base url of the page link :param total : number total of item to be splitted into pages :param page : current page :param step : item per page :param scope : number of page to display on pager :param url_args : additionnal parameters to add as query params to page url :type url_args : dict :returns dict """ # Compute Pager page_count = int(math.ceil(float(total) / step)) page = max(1, min(int(page if str(page).isdigit() else 1), page_count)) scope -= 1 pmin = max(page - int(math.floor(scope/2)), 1) pmax = min(pmin + scope, page_count) if pmax - pmin < scope: pmin = pmax - scope if pmax - scope > 0 else 1 def get_url(page): _url = "%s/page/%s" % (url, page) if page > 1 else url if url_args: _url = "%s?%s" % (_url, werkzeug.url_encode(url_args)) return _url return { "page_count": page_count, "offset": (page - 1) * step, "page": { 'url': get_url(page), 'num': page }, "page_start": { 'url': get_url(pmin), 'num': pmin }, "page_previous": { 'url': get_url(max(pmin, page - 1)), 'num': max(pmin, page - 1) }, "page_next": { 'url': get_url(min(pmax, page + 1)), 'num': min(pmax, page + 1) }, "page_end": { 'url': get_url(pmax), 'num': pmax }, "pages": [ {'url': get_url(page), 'num': page} for page in pycompat.range(pmin, pmax+1) ] }
def crawl(self, url, seen=None, msg=''): if seen is None: seen = set() url_slug = re.sub(r"[/](([^/=?&]+-)?[0-9]+)([/]|$)", '/<slug>/', url) url_slug = re.sub(r"([^/=?&]+)=[^/=?&]+", '\g<1>=param', url_slug) if url_slug in seen: return seen else: seen.add(url_slug) _logger.info("%s %s", msg, url) r = self.url_open(url) code = r.getcode() self.assertIn(code, pycompat.range(200, 300), "%s Fetching %s returned error response (%d)" % (msg, url, code)) if r.info().gettype() == 'text/html': doc = lxml.html.fromstring(r.read()) for link in doc.xpath('//a[@href]'): href = link.get('href') parts = urlparse.urlsplit(href) # href with any fragment removed href = urlparse.urlunsplit(( parts.scheme, parts.netloc, parts.path, parts.query, '' )) # FIXME: handle relative link (not parts.path.startswith /) if parts.netloc or \ not parts.path.startswith('/') or \ parts.path == '/web' or\ parts.path.startswith('/web/') or \ parts.path.startswith('/en_US/') or \ (parts.scheme and parts.scheme not in ('http', 'https')): continue self.crawl(href, seen, msg) return seen
def crawl(self, url, seen=None, msg=''): if seen is None: seen = set() url_slug = re.sub(r"[/](([^/=?&]+-)?[0-9]+)([/]|$)", '/<slug>/', url) url_slug = re.sub(r"([^/=?&]+)=[^/=?&]+", '\g<1>=param', url_slug) if url_slug in seen: return seen else: seen.add(url_slug) _logger.info("%s %s", msg, url) r = self.url_open(url) code = r.getcode() self.assertIn( code, pycompat.range(200, 300), "%s Fetching %s returned error response (%d)" % (msg, url, code)) if r.info().gettype() == 'text/html': doc = lxml.html.fromstring(r.read()) for link in doc.xpath('//a[@href]'): href = link.get('href') parts = urlparse.urlsplit(href) # href with any fragment removed href = urlparse.urlunsplit( (parts.scheme, parts.netloc, parts.path, parts.query, '')) # FIXME: handle relative link (not parts.path.startswith /) if parts.netloc or \ not parts.path.startswith('/') or \ parts.path == '/web' or\ parts.path.startswith('/web/') or \ parts.path.startswith('/en_US/') or \ (parts.scheme and parts.scheme not in ('http', 'https')): continue self.crawl(href, seen, msg) return seen
def try_round(amount, expected, precision_digits=3): global count, errors count += 1 result = float_repr(float_round(amount, precision_digits=precision_digits), precision_digits=precision_digits) if result != expected: errors += 1 print('###!!! Rounding error: got %s , expected %s' % (result, expected)) # Extended float range test, inspired by Cloves Almeida's test on bug #882036. fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555] expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556'] precisions = [2, 2, 2, 2, 2, 2, 3, 4] for magnitude in pycompat.range(7): for frac, exp, prec in zip(fractions, expecteds, precisions): for sign in [-1, 1]: for x in pycompat.range(0, 10000, 97): n = x * 10**magnitude f = sign * (n + frac) f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp try_round(f, f_exp, precision_digits=prec) stop = time.time() # Micro-bench results: # 47130 round calls in 0.422306060791 secs, with Python 2.6.7 on Core i3 x64 # with decimal: # 47130 round calls in 6.612248100021 secs, with Python 2.6.7 on Core i3 x64
def test_rounding_03(self): """ Test rounding methods with 3 digits. """ def try_round(amount, expected, digits=3, method='HALF-UP'): value = float_round(amount, precision_digits=digits, rounding_method=method) result = float_repr(value, precision_digits=digits) self.assertEqual(result, expected, 'Rounding error: got %s, expected %s' % (result, expected)) try_round(2.6745, '2.675') try_round(-2.6745, '-2.675') try_round(2.6744, '2.674') try_round(-2.6744, '-2.674') try_round(0.0004, '0.000') try_round(-0.0004, '-0.000') try_round(357.4555, '357.456') try_round(-357.4555, '-357.456') try_round(457.4554, '457.455') try_round(-457.4554, '-457.455') # Try some rounding value with rounding method UP instead of HALF-UP # We use 8.175 because when normalizing 8.175 with precision_digits=3 it gives # us 8175,0000000001234 as value, and if not handle correctly the rounding UP # value will be incorrect (should be 8,175 and not 8,176) try_round(8.175, '8.175', method='UP') try_round(8.1751, '8.176', method='UP') try_round(-8.175, '-8.175', method='UP') try_round(-8.1751, '-8.176', method='UP') try_round(-6.000, '-6.000', method='UP') try_round(1.8, '2', 0, method='UP') try_round(-1.8, '-2', 0, method='UP') # Extended float range test, inspired by Cloves Almeida's test on bug #882036. fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555] expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556'] precisions = [2, 2, 2, 2, 2, 2, 3, 4] # Note: max precision for double floats is 53 bits of precision or # 17 significant decimal digits for magnitude in pycompat.range(7): for frac, exp, prec in zip(fractions, expecteds, precisions): for sign in [-1,1]: for x in pycompat.range(0, 10000, 97): n = x * 10 ** magnitude f = sign * (n + frac) f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp try_round(f, f_exp, digits=prec) def try_zero(amount, expected): self.assertEqual(float_is_zero(amount, precision_digits=3), expected, "Rounding error: %s should be zero!" % amount) try_zero(0.0002, True) try_zero(-0.0002, True) try_zero(0.00034, True) try_zero(0.0005, False) try_zero(-0.0005, False) try_zero(0.0008, False) try_zero(-0.0008, False) def try_compare(amount1, amount2, expected): self.assertEqual(float_compare(amount1, amount2, precision_digits=3), expected, "Rounding error, compare_amounts(%s,%s) should be %s" % (amount1, amount2, expected)) try_compare(0.0003, 0.0004, 0) try_compare(-0.0003, -0.0004, 0) try_compare(0.0002, 0.0005, -1) try_compare(-0.0002, -0.0005, 1) try_compare(0.0009, 0.0004, 1) try_compare(-0.0009, -0.0004, -1) try_compare(557.4555, 557.4556, 0) try_compare(-557.4555, -557.4556, 0) try_compare(657.4444, 657.445, -1) try_compare(-657.4444, -657.445, 1) # Rounding to unusual rounding units (e.g. coin values) def try_round(amount, expected, precision_rounding=None): value = float_round(amount, precision_rounding=precision_rounding) result = float_repr(value, precision_digits=2) self.assertEqual(result, expected, 'Rounding error: got %s, expected %s' % (result, expected)) try_round(-457.4554, '-457.45', precision_rounding=0.05) try_round(457.444, '457.50', precision_rounding=0.5) try_round(457.3, '455.00', precision_rounding=5) try_round(457.5, '460.00', precision_rounding=5) try_round(457.1, '456.00', precision_rounding=3)
count = 0 errors = 0 def try_round(amount, expected, precision_digits=3): global count, errors; count += 1 result = float_repr(float_round(amount, precision_digits=precision_digits), precision_digits=precision_digits) if result != expected: errors += 1 print('###!!! Rounding error: got %s , expected %s' % (result, expected)) # Extended float range test, inspired by Cloves Almeida's test on bug #882036. fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555] expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556'] precisions = [2, 2, 2, 2, 2, 2, 3, 4] for magnitude in pycompat.range(7): for frac, exp, prec in zip(fractions, expecteds, precisions): for sign in [-1,1]: for x in pycompat.range(0, 10000, 97): n = x * 10**magnitude f = sign * (n + frac) f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp try_round(f, f_exp, precision_digits=prec) stop = time.time() # Micro-bench results: # 47130 round calls in 0.422306060791 secs, with Python 2.6.7 on Core i3 x64 # with decimal: # 47130 round calls in 6.612248100021 secs, with Python 2.6.7 on Core i3 x64 print(count, " round calls, ", errors, "errors, done in ", (stop-start), 'secs')
def random_token(): # the token has an entropy of about 120 bits (6 bits/char * 20 chars) chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' return ''.join(random.SystemRandom().choice(chars) for _ in pycompat.range(20))