from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    try_get,
    unescapeHTML,
    url_or_none,
    urljoin,
)

class WWEBaseIE(InfoExtractor):
    _SUBTITLE_LANGS = {
        'English': 'en',
        'Deutsch': 'de',
    }

    def _extract_entry(self, data, url, video_id=None):
        video_id = compat_str(video_id or data['nid'])
        title = data['title'

        formats = self._extract_m3u8_formats(
            data['file'], video_id, 'mp4', entry_protocol='m3u8_native',
            m3u8_id='hls')

        description = data.get('description')
        thumbnail = urljoin(url, data.get('image'))
        series = data.get('show_name')
        episode = data.get('episode_name')

        subtitles = {}
        tracks = data.get('tracks')
        if isinstance(tracks, list):
            for track in tracks:
                if not isinstance(track, dict):
                    continue
                if track.get('kind') != 'captions':
                    continue
                track_file = url_or_none(track.get('file'))
                if not track_file:
                    continue
                label = track.get('label')
                lang = self._SUBTITLE_LANGS.get(label, label) or 'en'
                subtitles.setdefault(lang, []).append({
                    'url': track_file,
                })

        return {
            'id': video_id,
            'title': title,
            'description': description,
            'thumbnail': thumbnail,
            'series': series,
            'episode': episode,
            'formats': formats,
            'subtitles': subtitles,
        }

class WWEIE(WWEBaseIE):
    _VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*videos/(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'http://example.com',
        'md5': '92811c6a14bfc206f7a6a9c5d9140184',
        'info_dict': {
            'id': '40048199',
            'ext': 'mp4',
            'title': 'Daniel Bryan vs. Andrade "Cien" Almas: SmackDown LIVE, Sept. 4, 2018',
            'description': 'md5:2d7424dbc6755c61a0e649d2a8677f67',
            'thumbnail': r're:^https?://.*\.jpg$',
        }
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)

        landing = self._parse_json(
            self._html_search_regex(
                r'(?s)Drupal\.settings\s*,\s*({.+?})\s*\)\s*;',
                webpage, 'drupal settings'),
            display_id)['WWEVideoLanding']

        data = landing['initialVideo']['playlist'][0]
        video_id = landing.get('initialVideoId')

        info = self._extract_entry(data, url, video_id)
        info['display_id'] = display_id
        return info

class WWEPlaylistIE(WWEBaseIE):
    _VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'http://example.com',
        'info_dict': {
            'id': '2018-11-12',
        },
        'playlist_mincount': 11,
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }]

    @classmethod
    def suitable(cls, url):
        return False if WWEIE.suitable(url) else super(WWEPlaylistIE, cls).suitable(url)

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)

        entries = []
        for mobj in re.finditer(
                r'data-video\s*=\s*(["\'])(?P<data>{.+?})\1', webpage):
            video = self._parse_json(
                mobj.group('data'), display_id, transform_source=unescapeHTML,
                fatal=False)
            if not video:
                continue
            data = try_get(video, lambda x: x['playlist'][0], dict)
            if not data:
                continue
            try:
                entry = self._extract_entry(data, url)
            except Exception:
                continue
            entry['extractor_key'] = WWEIE.ie_key()
            entries.append(entry)

        return self.playlist_result(entries, display_id)


try:
                entry = self._extract_entry(data, url)
            except Exception:
                continue

from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..compat import compat_str
from ..utils import (
    try_get,
    unescapeHTML,
    url_or_none,
    urljoin,
)

class WWEBaseIE(InfoExtractor):
    _SUBTITLE_LANGS = {
        'English': 'en',
        'Deutsch': 'de',
    }

    def _extract_entry(self, data, url, video_id=None):
        video_id = compat_str(video_id or data['nid'])
        title = data['title']

        formats = self._extract_m3u8_formats(
            data['file'], video_id, 'mp4', entry_protocol='m3u8_native',
            m3u8_id='hls')

        description = data.get('description')
        thumbnail = urljoin(url, data.get('image'))
        series = data.get('show_name')
        episode = data.get('episode_name')

        subtitles = {}
        tracks = data.get('tracks')
        if isinstance(tracks, list):
            for track in tracks:
                if not isinstance(track, dict):
                    continue
                if track.get('kind') != 'captions':
                    continue
                track_file = url_or_none(track.get('file'))
                if not track_file:
                    continue
                label = track.get('label')
                lang = self._SUBTITLE_LANGS.get(label, label) or 'en'
                subtitles.setdefault(lang, []).append({
                    'url': track_file,
                })

        return {
            'id': video_id,
            'title': title,
            'description': description,
            'thumbnail': thumbnail,
            'series': series,
            'episode': episode,
            'formats': formats,
            'subtitles': subtitles,
        }

class WWEIE(WWEBaseIE):
    _VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*videos/(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'http://example.com',
        'md5': '92811c6a14bfc206f7a6a9c5d9140184',
        'info_dict': {
            'id': '40048199',
            'ext': 'mp4',
            'title': 'Daniel Bryan vs. Andrade "Cien" Almas: SmackDown LIVE, Sept. 4, 2018',
            'description': 'md5:2d7424dbc6755c61a0e649d2a8677f67',
            'thumbnail': r're:^https?://.*\.jpg$',
        }
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)

        landing = self._parse_json(
            self._html_search_regex(
                r'(?s)Drupal\.settings\s*,\s*({.+?})\s*\)\s*;',
                webpage, 'drupal settings'),
            display_id)['WWEVideoLanding']

        data = landing['initialVideo']['playlist'][0]
        video_id = landing.get('initialVideoId')

        info = self._extract_entry(data, url, video_id)
        info['display_id'] = display_id
        return info

class WWEPlaylistIE(WWEBaseIE):
    _VALID_URL = r'https?://(?:[^/]+\.)?wwe\.com/(?:[^/]+/)*(?P<id>[^/?#&]+)'
    _TESTS = [{
        'url': 'http://example.com',
        'info_dict': {
            'id': '2018-11-12',
        },
        'playlist_mincount': 11,
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }, {
        'url': 'http://example.com',
        'only_matching': True,
    }]

    @classmethod
    def suitable(cls, url):
        return False if WWEIE.suitable(url) else super(WWEPlaylistIE, cls).suitable(url)

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)

        entries = []
        for mobj in re.finditer(
                r'data-video\s*=\s*(["\'])(?P<data>{.+?})\1', webpage):
            video = self._parse_json(
                mobj.group('data'), display_id, transform_source=unescapeHTML,
                fatal=False)
            if not video:
                continue
            data = try_get(video, lambda x: x['playlist'][0], dict)
            if not data:
                continue

            entry['extractor_key'] = WWEIE.ie_key()
            entries.append(entry)

        return self.playlist_result(entries, display_id)


"""
This module contains a base type which provides list-style mutations
without specific data storage methods.

See also http://example.com

Author: Aryeh Leib Taurog.
"""
from functools import total_ordering

from django.utils import six
from django.utils.six.moves import range

@total_ordering
class ListMixin(object):
    """
    A base class which provides complete list interface.
    Derived classes must call ListMixin's __init__() function
    and implement the following:

    function _get_single_external(self, i):
        Return single item with index i for general use.
        The index i will always satisfy 0 <= i < len(self).

    function _get_single_internal(self, i):
        Same as above, but for use within the class [Optional]
        Note that if _get_single_internal and _get_single_internal return
        different types of objects, _set_list must distinguish
        between the two and handle each appropriately.

    function _set_list(self, length, items):
        Recreate the entire object.

        NOTE: items may be a generator which calls _get_single_internal.
        Therefore, it is necessary to cache the values in a temporary:
            temp = list(items)
        before clobbering the original storage.

    function _set_single(self, i, value):
        Set the single item at index i to value [Optional]
        If left undefined, all mutations will result in rebuilding
        the object using _set_list.

    function __len__(self):
        Return the length

    int _minlength:
        The minimum legal length [Optional]

    int _maxlength:
        The maximum legal length [Optional]

    type or tuple _allowed:
        A type or tuple of allowed item types [Optional]
    """

    _minlength = 0
    _maxlength = None

if not hasattr(self, '_get_single_internal'):
            self._get_single_internal = self._get_single_external

        if not hasattr(self, '_set_single'):
            self._set_single = self._set_single_rebuild
            self._assign_extended_slice = self._assign_extended_slice_rebuild

        super(ListMixin, self).__init__(*args, **kwargs)

    def __getitem__(self, index):
        "Get the item(s) at the specified index/slice."
        if isinstance(index, slice):
            return [self._get_single_external(i) for i in range(*index.indices(len(self)))]
        else:
            index = self._checkindex(index)
            return self._get_single_external(index)

    def __delitem__(self, index):
        "Delete the item(s) at the specified index/slice."
        if not isinstance(index, six.integer_types + (slice,)):
            raise TypeError("%s is not a legal index" % index)

        # calculate new length and dimensions
        origLen = len(self)
        if isinstance(index, six.integer_types):
            index = self._checkindex(index)
            indexRange = [index]
        else:
            indexRange = range(*index.indices(origLen))

        newLen = origLen - len(indexRange)
        newItems = (self._get_single_internal(i)
                    for i in range(origLen)
                    if i not in indexRange)

        self._rebuild(newLen, newItems)

    def __setitem__(self, index, val):
        "Set the item(s) at the specified index/slice."
        if isinstance(index, slice):
            self._set_slice(index, val)
        else:
            index = self._checkindex(index)
            self._check_allowed((val,))
            self._set_single(index, val)

    def __add__(self, other):
        'add another list-like object'
        return self.__class__(list(self) + list(other))

    def __radd__(self, other):
        'add to another list-like object'
        return other.__class__(list(other) + list(self))

    def __iadd__(self, other):
        'add another list-like object to self'
        self.extend(list(other))
        return self

    def __mul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __rmul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __imul__(self, n):
        'multiply'
        if n <= 0:
            del self[:]
        else:
            cache = list(self)
            for i in range(n - 1):
                self.extend(cache)
        return self

    def __eq__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] == other[i]
            except IndexError:
                # self must be shorter
                return False
            if not c:
                return False
        return len(self) == olen

    def __lt__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] < other[i]
            except IndexError:
                # self must be shorter
                return True
            if c:
                return c
            elif other[i] < self[i]:
                return False
        return len(self) < olen

    def count(self, val):
        "Standard list count method"
        count = 0
        for i in self:
            if val == i:
                count += 1
        return count

    def index(self, val):
        "Standard list index method"
        for i in range(0, len(self)):
            if self[i] == val:
                return i
        raise ValueError('%s not found in object' % str(val))

    def append(self, val):
        "Standard list append method"
        self[len(self):] = [val]

    def extend(self, vals):
        "Standard list extend method"
        self[len(self):] = vals

    def insert(self, index, val):
        "Standard list insert method"
        if not isinstance(index, six.integer_types):
            raise TypeError("%s is not a legal index" % index)
        self[index:index] = [val]

    def pop(self, index=-1):
        "Standard list pop method"
        result = self[index]
        del self[index]
        return result

    def remove(self, val):
        "Standard list remove method"
        del self[self.index(val)]

    def reverse(self):
        "Standard list reverse method"
        self[:] = self[-1::-1]

    def sort(self, cmp=None, key=None, reverse=False):
        "Standard list sort method"
        if key:
            temp = [(key(v), v) for v in self]
            temp.sort(key=lambda x: x[0], reverse=reverse)
            self[:] = [v[1] for v in temp]
        else:
            temp = list(self)
            if cmp is not None:
                temp.sort(cmp=cmp, reverse=reverse)
            else:
                temp.sort(reverse=reverse)
            self[:] = temp

    def _rebuild(self, newLen, newItems):
        if newLen < self._minlength:
            raise ValueError('Must have at least %d items' % self._minlength)
        if self._maxlength is not None and newLen > self._maxlength:
            raise ValueError('Cannot have more than %d items' % self._maxlength)

        self._set_list(newLen, newItems)

    def _set_single_rebuild(self, index, value):
        self._set_slice(slice(index, index + 1, 1), [value])

    def _checkindex(self, index, correct=True):
        length = len(self)
        if 0 <= index < length:
            return index
        if correct and -length <= index < 0:
            return index + length
        raise IndexError('invalid index: %s' % str(index))

    def _check_allowed(self, items):
        if hasattr(self, '_allowed'):
            if False in [isinstance(val, self._allowed) for val in items]:
                raise TypeError('Invalid type encountered in the arguments.')

    def _set_slice(self, index, values):
        "Assign values to a slice of the object"
        try:
            iter(values)
        except TypeError:
            raise TypeError('can only assign an iterable to a slice')

        self._check_allowed(values)

        origLen = len(self)
        valueList = list(values)
        start, stop, step = index.indices(origLen)

        # CAREFUL: index.step and step are not the same!
        # step will never be None
        if index.step is None:
            self._assign_simple_slice(start, stop, valueList)
        else:
            self._assign_extended_slice(start, stop, step, valueList)

    def _assign_extended_slice_rebuild(self, start, stop, step, valueList):
        'Assign an extended slice by rebuilding entire list'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        # we're not changing the length of the sequence
        newLen = len(self)
        newVals = dict(zip(indexList, valueList))

        def newItems():
            for i in range(newLen):
                if i in newVals:
                    yield newVals[i]
                else:
                    yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())

    def _assign_extended_slice(self, start, stop, step, valueList):
        'Assign an extended slice by re-assigning individual items'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        for i, val in zip(indexList, valueList):
            self._set_single(i, val)

    def _assign_simple_slice(self, start, stop, valueList):
        'Assign a simple slice; Can assign slice of any length'
        origLen = len(self)
        stop = max(start, stop)
        newLen = origLen - stop + start + len(valueList)

        def newItems():
            for i in range(origLen + 1):
                if i == start:
                    for val in valueList:
                        yield val

                if i < origLen:
                    if i < start or i >= stop:
                        yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())


if not hasattr(self, '_get_single_internal'):
            self._get_single_internal = self._get_single_external

        if not hasattr(self, '_set_single'):
            self._set_single = self._set_single_rebuild
            self._assign_extended_slice = self._assign_extended_slice_rebuild

        super(ListMixin, self).__init__(*args, **kwargs)

"""
This module contains a base type which provides list-style mutations
without specific data storage methods.

See also http://example.com

Author: Aryeh Leib Taurog.
"""
from functools import total_ordering

from django.utils import six
from django.utils.six.moves import range

@total_ordering
class ListMixin(object):
    """
    A base class which provides complete list interface.
    Derived classes must call ListMixin's __init__() function
    and implement the following:

    function _get_single_external(self, i):
        Return single item with index i for general use.
        The index i will always satisfy 0 <= i < len(self).

    function _get_single_internal(self, i):
        Same as above, but for use within the class [Optional]
        Note that if _get_single_internal and _get_single_internal return
        different types of objects, _set_list must distinguish
        between the two and handle each appropriately.

    function _set_list(self, length, items):
        Recreate the entire object.

        NOTE: items may be a generator which calls _get_single_internal.
        Therefore, it is necessary to cache the values in a temporary:
            temp = list(items)
        before clobbering the original storage.

    function _set_single(self, i, value):
        Set the single item at index i to value [Optional]
        If left undefined, all mutations will result in rebuilding
        the object using _set_list.

    function __len__(self):
        Return the length

    int _minlength:
        The minimum legal length [Optional]

    int _maxlength:
        The maximum legal length [Optional]

    type or tuple _allowed:
        A type or tuple of allowed item types [Optional]
    """

    _minlength = 0
    _maxlength = None

    def __init__(self, *args, **kwargs):

    def __getitem__(self, index):
        "Get the item(s) at the specified index/slice."
        if isinstance(index, slice):
            return [self._get_single_external(i) for i in range(*index.indices(len(self)))]
        else:
            index = self._checkindex(index)
            return self._get_single_external(index)

    def __delitem__(self, index):
        "Delete the item(s) at the specified index/slice."
        if not isinstance(index, six.integer_types + (slice,)):
            raise TypeError("%s is not a legal index" % index)

        # calculate new length and dimensions
        origLen = len(self)
        if isinstance(index, six.integer_types):
            index = self._checkindex(index)
            indexRange = [index]
        else:
            indexRange = range(*index.indices(origLen))

        newLen = origLen - len(indexRange)
        newItems = (self._get_single_internal(i)
                    for i in range(origLen)
                    if i not in indexRange)

        self._rebuild(newLen, newItems)

    def __setitem__(self, index, val):
        "Set the item(s) at the specified index/slice."
        if isinstance(index, slice):
            self._set_slice(index, val)
        else:
            index = self._checkindex(index)
            self._check_allowed((val,))
            self._set_single(index, val)

    def __add__(self, other):
        'add another list-like object'
        return self.__class__(list(self) + list(other))

    def __radd__(self, other):
        'add to another list-like object'
        return other.__class__(list(other) + list(self))

    def __iadd__(self, other):
        'add another list-like object to self'
        self.extend(list(other))
        return self

    def __mul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __rmul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __imul__(self, n):
        'multiply'
        if n <= 0:
            del self[:]
        else:
            cache = list(self)
            for i in range(n - 1):
                self.extend(cache)
        return self

    def __eq__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] == other[i]
            except IndexError:
                # self must be shorter
                return False
            if not c:
                return False
        return len(self) == olen

    def __lt__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] < other[i]
            except IndexError:
                # self must be shorter
                return True
            if c:
                return c
            elif other[i] < self[i]:
                return False
        return len(self) < olen

    def count(self, val):
        "Standard list count method"
        count = 0
        for i in self:
            if val == i:
                count += 1
        return count

    def index(self, val):
        "Standard list index method"
        for i in range(0, len(self)):
            if self[i] == val:
                return i
        raise ValueError('%s not found in object' % str(val))

    def append(self, val):
        "Standard list append method"
        self[len(self):] = [val]

    def extend(self, vals):
        "Standard list extend method"
        self[len(self):] = vals

    def insert(self, index, val):
        "Standard list insert method"
        if not isinstance(index, six.integer_types):
            raise TypeError("%s is not a legal index" % index)
        self[index:index] = [val]

    def pop(self, index=-1):
        "Standard list pop method"
        result = self[index]
        del self[index]
        return result

    def remove(self, val):
        "Standard list remove method"
        del self[self.index(val)]

    def reverse(self):
        "Standard list reverse method"
        self[:] = self[-1::-1]

    def sort(self, cmp=None, key=None, reverse=False):
        "Standard list sort method"
        if key:
            temp = [(key(v), v) for v in self]
            temp.sort(key=lambda x: x[0], reverse=reverse)
            self[:] = [v[1] for v in temp]
        else:
            temp = list(self)
            if cmp is not None:
                temp.sort(cmp=cmp, reverse=reverse)
            else:
                temp.sort(reverse=reverse)
            self[:] = temp

    def _rebuild(self, newLen, newItems):
        if newLen < self._minlength:
            raise ValueError('Must have at least %d items' % self._minlength)
        if self._maxlength is not None and newLen > self._maxlength:
            raise ValueError('Cannot have more than %d items' % self._maxlength)

        self._set_list(newLen, newItems)

    def _set_single_rebuild(self, index, value):
        self._set_slice(slice(index, index + 1, 1), [value])

    def _checkindex(self, index, correct=True):
        length = len(self)
        if 0 <= index < length:
            return index
        if correct and -length <= index < 0:
            return index + length
        raise IndexError('invalid index: %s' % str(index))

    def _check_allowed(self, items):
        if hasattr(self, '_allowed'):
            if False in [isinstance(val, self._allowed) for val in items]:
                raise TypeError('Invalid type encountered in the arguments.')

    def _set_slice(self, index, values):
        "Assign values to a slice of the object"
        try:
            iter(values)
        except TypeError:
            raise TypeError('can only assign an iterable to a slice')

        self._check_allowed(values)

        origLen = len(self)
        valueList = list(values)
        start, stop, step = index.indices(origLen)

        # CAREFUL: index.step and step are not the same!
        # step will never be None
        if index.step is None:
            self._assign_simple_slice(start, stop, valueList)
        else:
            self._assign_extended_slice(start, stop, step, valueList)

    def _assign_extended_slice_rebuild(self, start, stop, step, valueList):
        'Assign an extended slice by rebuilding entire list'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        # we're not changing the length of the sequence
        newLen = len(self)
        newVals = dict(zip(indexList, valueList))

        def newItems():
            for i in range(newLen):
                if i in newVals:
                    yield newVals[i]
                else:
                    yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())

    def _assign_extended_slice(self, start, stop, step, valueList):
        'Assign an extended slice by re-assigning individual items'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        for i, val in zip(indexList, valueList):
            self._set_single(i, val)

    def _assign_simple_slice(self, start, stop, valueList):
        'Assign a simple slice; Can assign slice of any length'
        origLen = len(self)
        stop = max(start, stop)
        newLen = origLen - stop + start + len(valueList)

        def newItems():
            for i in range(origLen + 1):
                if i == start:
                    for val in valueList:
                        yield val

                if i < origLen:
                    if i < start or i >= stop:
                        yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())


"""
This module contains a base type which provides list-style mutations
without specific data storage methods.

See also http://example.com

Author: Aryeh Leib Taurog.
"""
from functools import total_ordering

from django.utils import six
from django.utils.six.moves import range

@total_ordering
class ListMixin(object):
    """
    A base class which provides complete list interface.
    Derived classes must call ListMixin's __init__() function
    and implement the following:

    function _get_single_external(self, i):
        Return single item with index i for general use.
        The index i will always satisfy 0 <= i < len(self).

    function _get_single_internal(self, i):
        Same as above, but for use within the class [Optional]
        Note that if _get_single_internal and _get_single_internal return
        different types of objects, _set_list must distinguish
        between the two and handle each appropriately.

    function _set_list(self, length, items):
        Recreate the entire object.

        NOTE: items may be a generator which calls _get_single_internal.
        Therefore, it is necessary to cache the values in a temporary:
            temp = list(items)
        before clobbering the original storage.

    function _set_single(self, i, value):
        Set the single item at index i to value [Optional]
        If left undefined, all mutations will result in rebuilding
        the object using _set_list.

    function __len__(self):
        Return the length

    int _minlength:
        The minimum legal length [Optional]

    int _maxlength:
        The maximum legal length [Optional]

    type or tuple _allowed:
        A type or tuple of allowed item types [Optional]
    """

    _minlength = 0
    _maxlength = None

    def __init__(self, *args, **kwargs):
        if not hasattr(self, '_get_single_internal'):
            self._get_single_internal = self._get_single_external

        if not hasattr(self, '_set_single'):
            self._set_single = self._set_single_rebuild
            self._assign_extended_slice = self._assign_extended_slice_rebuild

        super(ListMixin, self).__init__(*args, **kwargs)

    def __getitem__(self, index):
        "Get the item(s) at the specified index/slice."
        if isinstance(index, slice):
            return [self._get_single_external(i) for i in range(*index.indices(len(self)))]
        else:
            index = self._checkindex(index)
            return self._get_single_external(index)

    def __delitem__(self, index):
        "Delete the item(s) at the specified index/slice."
        if not isinstance(index, six.integer_types + (slice,)):
            raise TypeError("%s is not a legal index" % index)

        # calculate new length and dimensions
        or

        if isinstance(index, six.integer_types):
            index = self._checkindex(index)
            indexRange = [index]
        else:
            indexRange = range(*index.indices(origLen))

        newLen = origLen - len(indexRange)
        newItems = (self._get_single_internal(i)
                    for i in range(origLen)
                    if i not in indexRange)

        self._rebuild(newLen, newItems)

    def __setitem__(self, index, val):
        "Set the item(s) at the specified index/slice."
        if isinstance(index, slice):
            self._set_slice(index, val)
        else:
            index = self._checkindex(index)
            self._check_allowed((val,))
            self._set_single(index, val)

    def __add__(self, other):
        'add another list-like object'
        return self.__class__(list(self) + list(other))

    def __radd__(self, other):
        'add to another list-like object'
        return other.__class__(list(other) + list(self))

    def __iadd__(self, other):
        'add another list-like object to self'
        self.extend(list(other))
        return self

    def __mul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __rmul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __imul__(self, n):
        'multiply'
        if n <= 0:
            del self[:]
        else:
            cache = list(self)
            for i in range(n - 1):
                self.extend(cache)
        return self

    def __eq__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] == other[i]
            except IndexError:
                # self must be shorter
                return False
            if not c:
                return False
        return len(self) == olen

    def __lt__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] < other[i]
            except IndexError:
                # self must be shorter
                return True
            if c:
                return c
            elif other[i] < self[i]:
                return False
        return len(self) < olen

    def count(self, val):
        "Standard list count method"
        count = 0
        for i in self:
            if val == i:
                count += 1
        return count

    def index(self, val):
        "Standard list index method"
        for i in range(0, len(self)):
            if self[i] == val:
                return i
        raise ValueError('%s not found in object' % str(val))

    def append(self, val):
        "Standard list append method"
        self[len(self):] = [val]

    def extend(self, vals):
        "Standard list extend method"
        self[len(self):] = vals

    def insert(self, index, val):
        "Standard list insert method"
        if not isinstance(index, six.integer_types):
            raise TypeError("%s is not a legal index" % index)
        self[index:index] = [val]

    def pop(self, index=-1):
        "Standard list pop method"
        result = self[index]
        del self[index]
        return result

    def remove(self, val):
        "Standard list remove method"
        del self[self.index(val)]

    def reverse(self):
        "Standard list reverse method"
        self[:] = self[-1::-1]

    def sort(self, cmp=None, key=None, reverse=False):
        "Standard list sort method"
        if key:
            temp = [(key(v), v) for v in self]
            temp.sort(key=lambda x: x[0], reverse=reverse)
            self[:] = [v[1] for v in temp]
        else:
            temp = list(self)
            if cmp is not None:
                temp.sort(cmp=cmp, reverse=reverse)
            else:
                temp.sort(reverse=reverse)
            self[:] = temp

    def _rebuild(self, newLen, newItems):
        if newLen < self._minlength:
            raise ValueError('Must have at least %d items' % self._minlength)
        if self._maxlength is not None and newLen > self._maxlength:
            raise ValueError('Cannot have more than %d items' % self._maxlength)

        self._set_list(newLen, newItems)

    def _set_single_rebuild(self, index, value):
        self._set_slice(slice(index, index + 1, 1), [value])

    def _checkindex(self, index, correct=True):
        length = len(self)
        if 0 <= index < length:
            return index
        if correct and -length <= index < 0:
            return index + length
        raise IndexError('invalid index: %s' % str(index))

    def _check_allowed(self, items):
        if hasattr(self, '_allowed'):
            if False in [isinstance(val, self._allowed) for val in items]:
                raise TypeError('Invalid type encountered in the arguments.')

    def _set_slice(self, index, values):
        "Assign values to a slice of the object"
        try:
            iter(values)
        except TypeError:
            raise TypeError('can only assign an iterable to a slice')

        self._check_allowed(values)

        origLen = len(self)
        valueList = list(values)
        start, stop, step = index.indices(origLen)

        # CAREFUL: index.step and step are not the same!
        # step will never be None
        if index.step is None:
            self._assign_simple_slice(start, stop, valueList)
        else:
            self._assign_extended_slice(start, stop, step, valueList)

    def _assign_extended_slice_rebuild(self, start, stop, step, valueList):
        'Assign an extended slice by rebuilding entire list'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        # we're not changing the length of the sequence
        newLen = len(self)
        newVals = dict(zip(indexList, valueList))

        def newItems():
            for i in range(newLen):
                if i in newVals:
                    yield newVals[i]
                else:
                    yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())

    def _assign_extended_slice(self, start, stop, step, valueList):
        'Assign an extended slice by re-assigning individual items'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        for i, val in zip(indexList, valueList):
            self._set_single(i, val)

    def _assign_simple_slice(self, start, stop, valueList):
        'Assign a simple slice; Can assign slice of any length'
        origLen = len(self)
        stop = max(start, stop)
        newLen = origLen - stop + start + len(valueList)

        def newItems():
            for i in range(origLen + 1):
                if i == start:
                    for val in valueList:
                        yield val

                if i < origLen:
                    if i < start or i >= stop:
                        yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())


        for i in range(0, len(self)):
            if self[i] == val:
                return i
        raise ValueError('%s not found in object' % str(val))

"""
This module contains a base type which provides list-style mutations
without specific data storage methods.

See also http://example.com

Author: Aryeh Leib Taurog.
"""
from functools import total_ordering

from django.utils import six
from django.utils.six.moves import range

@total_ordering
class ListMixin(object):
    """
    A base class which provides complete list interface.
    Derived classes must call ListMixin's __init__() function
    and implement the following:

    function _get_single_external(self, i):
        Return single item with index i for general use.
        The index i will always satisfy 0 <= i < len(self).

    function _get_single_internal(self, i):
        Same as above, but for use within the class [Optional]
        Note that if _get_single_internal and _get_single_internal return
        different types of objects, _set_list must distinguish
        between the two and handle each appropriately.

    function _set_list(self, length, items):
        Recreate the entire object.

        NOTE: items may be a generator which calls _get_single_internal.
        Therefore, it is necessary to cache the values in a temporary:
            temp = list(items)
        before clobbering the original storage.

    function _set_single(self, i, value):
        Set the single item at index i to value [Optional]
        If left undefined, all mutations will result in rebuilding
        the object using _set_list.

    function __len__(self):
        Return the length

    int _minlength:
        The minimum legal length [Optional]

    int _maxlength:
        The maximum legal length [Optional]

    type or tuple _allowed:
        A type or tuple of allowed item types [Optional]
    """

    _minlength = 0
    _maxlength = None

    def __init__(self, *args, **kwargs):
        if not hasattr(self, '_get_single_internal'):
            self._get_single_internal = self._get_single_external

        if not hasattr(self, '_set_single'):
            self._set_single = self._set_single_rebuild
            self._assign_extended_slice = self._assign_extended_slice_rebuild

        super(ListMixin, self).__init__(*args, **kwargs)

    def __getitem__(self, index):
        "Get the item(s) at the specified index/slice."
        if isinstance(index, slice):
            return [self._get_single_external(i) for i in range(*index.indices(len(self)))]
        else:
            index = self._checkindex(index)
            return self._get_single_external(index)

    def __delitem__(self, index):
        "Delete the item(s) at the specified index/slice."
        if not isinstance(index, six.integer_types + (slice,)):
            raise TypeError("%s is not a legal index" % index)

        # calculate new length and dimensions
        origLen = len(self)
        if isinstance(index, six.integer_types):
            index = self._checkindex(index)
            indexRange = [index]
        else:
            indexRange = range(*index.indices(origLen))

        newLen = origLen - len(indexRange)
        newItems = (self._get_single_internal(i)
                    for i in range(origLen)
                    if i not in indexRange)

        self._rebuild(newLen, newItems)

    def __setitem__(self, index, val):
        "Set the item(s) at the specified index/slice."
        if isinstance(index, slice):
            self._set_slice(index, val)
        else:
            index = self._checkindex(index)
            self._check_allowed((val,))
            self._set_single(index, val)

    def __add__(self, other):
        'add another list-like object'
        return self.__class__(list(self) + list(other))

    def __radd__(self, other):
        'add to another list-like object'
        return other.__class__(list(other) + list(self))

    def __iadd__(self, other):
        'add another list-like object to self'
        self.extend(list(other))
        return self

    def __mul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __rmul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __imul__(self, n):
        'multiply'
        if n <= 0:
            del self[:]
        else:
            cache = list(self)
            for i in range(n - 1):
                self.extend(cache)
        return self

    def __eq__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] == other[i]
            except IndexError:
                # self must be shorter
                return False
            if not c:
                return False
        return len(self) == olen

    def __lt__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] < other[i]
            except IndexError:
                # self must be shorter
                return True
            if c:
                return c
            elif other[i] < self[i]:
                return False
        return len(self) < olen

    def count(self, val):
        "Standard list count method"
        count = 0
        for i in self:
            if val == i:
                count += 1
        return count

    def index(self, val):
        "Standard list index method"

    def append(self, val):
        "Standard list append method"
        self[len(self):] = [val]

    def extend(self, vals):
        "Standard list extend method"
        self[len(self):] = vals

    def insert(self, index, val):
        "Standard list insert method"
        if not isinstance(index, six.integer_types):
            raise TypeError("%s is not a legal index" % index)
        self[index:index] = [val]

    def pop(self, index=-1):
        "Standard list pop method"
        result = self[index]
        del self[index]
        return result

    def remove(self, val):
        "Standard list remove method"
        del self[self.index(val)]

    def reverse(self):
        "Standard list reverse method"
        self[:] = self[-1::-1]

    def sort(self, cmp=None, key=None, reverse=False):
        "Standard list sort method"
        if key:
            temp = [(key(v), v) for v in self]
            temp.sort(key=lambda x: x[0], reverse=reverse)
            self[:] = [v[1] for v in temp]
        else:
            temp = list(self)
            if cmp is not None:
                temp.sort(cmp=cmp, reverse=reverse)
            else:
                temp.sort(reverse=reverse)
            self[:] = temp

    def _rebuild(self, newLen, newItems):
        if newLen < self._minlength:
            raise ValueError('Must have at least %d items' % self._minlength)
        if self._maxlength is not None and newLen > self._maxlength:
            raise ValueError('Cannot have more than %d items' % self._maxlength)

        self._set_list(newLen, newItems)

    def _set_single_rebuild(self, index, value):
        self._set_slice(slice(index, index + 1, 1), [value])

    def _checkindex(self, index, correct=True):
        length = len(self)
        if 0 <= index < length:
            return index
        if correct and -length <= index < 0:
            return index + length
        raise IndexError('invalid index: %s' % str(index))

    def _check_allowed(self, items):
        if hasattr(self, '_allowed'):
            if False in [isinstance(val, self._allowed) for val in items]:
                raise TypeError('Invalid type encountered in the arguments.')

    def _set_slice(self, index, values):
        "Assign values to a slice of the object"
        try:
            iter(values)
        except TypeError:
            raise TypeError('can only assign an iterable to a slice')

        self._check_allowed(values)

        origLen = len(self)
        valueList = list(values)
        start, stop, step = index.indices(origLen)

        # CAREFUL: index.step and step are not the same!
        # step will never be None
        if index.step is None:
            self._assign_simple_slice(start, stop, valueList)
        else:
            self._assign_extended_slice(start, stop, step, valueList)

    def _assign_extended_slice_rebuild(self, start, stop, step, valueList):
        'Assign an extended slice by rebuilding entire list'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        # we're not changing the length of the sequence
        newLen = len(self)
        newVals = dict(zip(indexList, valueList))

        def newItems():
            for i in range(newLen):
                if i in newVals:
                    yield newVals[i]
                else:
                    yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())

    def _assign_extended_slice(self, start, stop, step, valueList):
        'Assign an extended slice by re-assigning individual items'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        for i, val in zip(indexList, valueList):
            self._set_single(i, val)

    def _assign_simple_slice(self, start, stop, valueList):
        'Assign a simple slice; Can assign slice of any length'
        origLen = len(self)
        stop = max(start, stop)
        newLen = origLen - stop + start + len(valueList)

        def newItems():
            for i in range(origLen + 1):
                if i == start:
                    for val in valueList:
                        yield val

                if i < origLen:
                    if i < start or i >= stop:
                        yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())


try:
                c = self[i] < other[i]
            except IndexError:
                # self must be shorter
                return True

"""
This module contains a base type which provides list-style mutations
without specific data storage methods.

See also http://example.com

Author: Aryeh Leib Taurog.
"""
from functools import total_ordering

from django.utils import six
from django.utils.six.moves import range

@total_ordering
class ListMixin(object):
    """
    A base class which provides complete list interface.
    Derived classes must call ListMixin's __init__() function
    and implement the following:

    function _get_single_external(self, i):
        Return single item with index i for general use.
        The index i will always satisfy 0 <= i < len(self).

    function _get_single_internal(self, i):
        Same as above, but for use within the class [Optional]
        Note that if _get_single_internal and _get_single_internal return
        different types of objects, _set_list must distinguish
        between the two and handle each appropriately.

    function _set_list(self, length, items):
        Recreate the entire object.

        NOTE: items may be a generator which calls _get_single_internal.
        Therefore, it is necessary to cache the values in a temporary:
            temp = list(items)
        before clobbering the original storage.

    function _set_single(self, i, value):
        Set the single item at index i to value [Optional]
        If left undefined, all mutations will result in rebuilding
        the object using _set_list.

    function __len__(self):
        Return the length

    int _minlength:
        The minimum legal length [Optional]

    int _maxlength:
        The maximum legal length [Optional]

    type or tuple _allowed:
        A type or tuple of allowed item types [Optional]
    """

    _minlength = 0
    _maxlength = None

    def __init__(self, *args, **kwargs):
        if not hasattr(self, '_get_single_internal'):
            self._get_single_internal = self._get_single_external

        if not hasattr(self, '_set_single'):
            self._set_single = self._set_single_rebuild
            self._assign_extended_slice = self._assign_extended_slice_rebuild

        super(ListMixin, self).__init__(*args, **kwargs)

    def __getitem__(self, index):
        "Get the item(s) at the specified index/slice."
        if isinstance(index, slice):
            return [self._get_single_external(i) for i in range(*index.indices(len(self)))]
        else:
            index = self._checkindex(index)
            return self._get_single_external(index)

    def __delitem__(self, index):
        "Delete the item(s) at the specified index/slice."
        if not isinstance(index, six.integer_types + (slice,)):
            raise TypeError("%s is not a legal index" % index)

        # calculate new length and dimensions
        origLen = len(self)
        if isinstance(index, six.integer_types):
            index = self._checkindex(index)
            indexRange = [index]
        else:
            indexRange = range(*index.indices(origLen))

        newLen = origLen - len(indexRange)
        newItems = (self._get_single_internal(i)
                    for i in range(origLen)
                    if i not in indexRange)

        self._rebuild(newLen, newItems)

    def __setitem__(self, index, val):
        "Set the item(s) at the specified index/slice."
        if isinstance(index, slice):
            self._set_slice(index, val)
        else:
            index = self._checkindex(index)
            self._check_allowed((val,))
            self._set_single(index, val)

    def __add__(self, other):
        'add another list-like object'
        return self.__class__(list(self) + list(other))

    def __radd__(self, other):
        'add to another list-like object'
        return other.__class__(list(other) + list(self))

    def __iadd__(self, other):
        'add another list-like object to self'
        self.extend(list(other))
        return self

    def __mul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __rmul__(self, n):
        'multiply'
        return self.__class__(list(self) * n)

    def __imul__(self, n):
        'multiply'
        if n <= 0:
            del self[:]
        else:
            cache = list(self)
            for i in range(n - 1):
                self.extend(cache)
        return self

    def __eq__(self, other):
        olen = len(other)
        for i in range(olen):
            try:
                c = self[i] == other[i]
            except IndexError:
                # self must be shorter
                return False
            if not c:
                return False
        return len(self) == olen

    def __lt__(self, other):
        olen = len(other)
        for i in range(olen):

            if c:
                return c
            elif other[i] < self[i]:
                return False
        return len(self) < olen

    def count(self, val):
        "Standard list count method"
        count = 0
        for i in self:
            if val == i:
                count += 1
        return count

    def index(self, val):
        "Standard list index method"
        for i in range(0, len(self)):
            if self[i] == val:
                return i
        raise ValueError('%s not found in object' % str(val))

    def append(self, val):
        "Standard list append method"
        self[len(self):] = [val]

    def extend(self, vals):
        "Standard list extend method"
        self[len(self):] = vals

    def insert(self, index, val):
        "Standard list insert method"
        if not isinstance(index, six.integer_types):
            raise TypeError("%s is not a legal index" % index)
        self[index:index] = [val]

    def pop(self, index=-1):
        "Standard list pop method"
        result = self[index]
        del self[index]
        return result

    def remove(self, val):
        "Standard list remove method"
        del self[self.index(val)]

    def reverse(self):
        "Standard list reverse method"
        self[:] = self[-1::-1]

    def sort(self, cmp=None, key=None, reverse=False):
        "Standard list sort method"
        if key:
            temp = [(key(v), v) for v in self]
            temp.sort(key=lambda x: x[0], reverse=reverse)
            self[:] = [v[1] for v in temp]
        else:
            temp = list(self)
            if cmp is not None:
                temp.sort(cmp=cmp, reverse=reverse)
            else:
                temp.sort(reverse=reverse)
            self[:] = temp

    def _rebuild(self, newLen, newItems):
        if newLen < self._minlength:
            raise ValueError('Must have at least %d items' % self._minlength)
        if self._maxlength is not None and newLen > self._maxlength:
            raise ValueError('Cannot have more than %d items' % self._maxlength)

        self._set_list(newLen, newItems)

    def _set_single_rebuild(self, index, value):
        self._set_slice(slice(index, index + 1, 1), [value])

    def _checkindex(self, index, correct=True):
        length = len(self)
        if 0 <= index < length:
            return index
        if correct and -length <= index < 0:
            return index + length
        raise IndexError('invalid index: %s' % str(index))

    def _check_allowed(self, items):
        if hasattr(self, '_allowed'):
            if False in [isinstance(val, self._allowed) for val in items]:
                raise TypeError('Invalid type encountered in the arguments.')

    def _set_slice(self, index, values):
        "Assign values to a slice of the object"
        try:
            iter(values)
        except TypeError:
            raise TypeError('can only assign an iterable to a slice')

        self._check_allowed(values)

        origLen = len(self)
        valueList = list(values)
        start, stop, step = index.indices(origLen)

        # CAREFUL: index.step and step are not the same!
        # step will never be None
        if index.step is None:
            self._assign_simple_slice(start, stop, valueList)
        else:
            self._assign_extended_slice(start, stop, step, valueList)

    def _assign_extended_slice_rebuild(self, start, stop, step, valueList):
        'Assign an extended slice by rebuilding entire list'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        # we're not changing the length of the sequence
        newLen = len(self)
        newVals = dict(zip(indexList, valueList))

        def newItems():
            for i in range(newLen):
                if i in newVals:
                    yield newVals[i]
                else:
                    yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())

    def _assign_extended_slice(self, start, stop, step, valueList):
        'Assign an extended slice by re-assigning individual items'
        indexList = range(start, stop, step)
        # extended slice, only allow assigning slice of same size
        if len(valueList) != len(indexList):
            raise ValueError('attempt to assign sequence of size %d '
                             'to extended slice of size %d'
                             % (len(valueList), len(indexList)))

        for i, val in zip(indexList, valueList):
            self._set_single(i, val)

    def _assign_simple_slice(self, start, stop, valueList):
        'Assign a simple slice; Can assign slice of any length'
        origLen = len(self)
        stop = max(start, stop)
        newLen = origLen - stop + start + len(valueList)

        def newItems():
            for i in range(origLen + 1):
                if i == start:
                    for val in valueList:
                        yield val

                if i < origLen:
                    if i < start or i >= stop:
                        yield self._get_single_internal(i)

        self._rebuild(newLen, newItems())


from flask import Flask, render_template

app = Flask(__name__)
posts = {
    0: {
        'title': 'Hello, world',
        'content': 'This is my first blog post!'
    }
}

@app.route('/')
def home():
    return 'Hello, world!'

@app.route('/post/<int:post_id>')

post = posts.get(post_id)
    # If the post was not found, then we can render a different page instead—the user will see an error page.
    if not post:
        # Here we pass another variable, the string `message`.
        # It can be used inside the jinja template.
        return render_template('404.jinja2', message=f'A post with id {post_id} was not found.')
    return render_template('post.jinja2', post=post)

if __name__ == '__main__':
    app.run(debug=True)


from flask import Flask, render_template

app = Flask(__name__)
posts = {
    0: {
        'title': 'Hello, world',
        'content': 'This is my first blog post!'
    }
}

@app.route('/')
def home():

@app.route('/post/<int:post_id>')
def post(post_id):
    post = posts.get(post_id)
    # If the post was not found, then we can render a different page instead—the user will see an error page.
    if not post:
        # Here we pass another variable, the string `message`.
        # It can be used inside the jinja template.
        return render_template('404.jinja2', message=f'A post with id {post_id} was not found.')
    return render_template('post.jinja2', post=post)

if __name__ == '__main__':
    app.run(debug=True)


from flask import Flask, render_template

app = Flask(__name__)
posts = {
    0: {
        'title': 'Hello, world',
        'content': 'This is my first blog post!'
    }
}

@app.route('/')
def home():
    re


#    documentation
from PIL import Image
import numpy as np
import pytest
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

from picasso import create_app

@pytest.fixture

_app = create_app()
    return _app

@pytest.fixture(scope='module')
def webdriver():
    options = Options()
    options.add_argument('-headless')
    driver = Firefox(firefox_options=options)
    yield driver
    driver.quit()


options = Options()
    options.add_argument('-headless')
    driver = Firefox(firefox_options=options)
    yield driver
    driver.quit()

#    documentation
from PIL import Image
import numpy as np
import pytest
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

from picasso import create_app

@pytest.fixture
def app():
    _app = create_app()
    return _app

@pytest.fixture(scope='module')
def webdriver():


#    documentation
from PIL import Image
import numpy as np
import pytest
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options

from picasso import create_app

@pytest.fixture
def app():
    _app = create_app()
    return _app

@pytest.fixture(scope='module')
def webdriver():
    options = Options()
    options.add_argument('-headless')
    driver = Firefox(firefox_options=options)
    yield driver
    dr


def _seek(
        self,
        source_database_config,
        tracker_database_config,
        allowed_event_types,
        position,
        only_tables
    ):

from __future__ import absolute_import
from __future__ import unicode_literals

import logging
import random

from data_pipeline.message import CreateMessage
from data_pipeline.message import DeleteMessage
from data_pipeline.message import RefreshMessage
from data_pipeline.message import UpdateMessage
from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.constants.BINLOG import DELETE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import UPDATE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import WRITE_ROWS_EVENT_V2
from pymysqlreplication.event import GtidEvent
from pymysqlreplication.event import QueryEvent
from pymysqlreplication.row_event import DeleteRowsEvent
from pymysqlreplication.row_event import UpdateRowsEvent
from pymysqlreplication.row_event import WriteRowsEvent

from replication_handler import config
from replication_handler.components.base_binlog_stream_reader_wrapper import BaseBinlogStreamReaderWrapper
from replication_handler.util.misc import DataEvent

log = logging.getLogger('replication_handler.components.low_level_binlog_stream_reader_wrapper')

message_type_map = {
    WRITE_ROWS_EVENT_V2: CreateMessage,
    UPDATE_ROWS_EVENT_V2: UpdateMessage,
    DELETE_ROWS_EVENT_V2: DeleteMessage,
}

class LowLevelBinlogStreamReaderWrapper(BaseBinlogStreamReaderWrapper):
    """ This class wraps pymysqlreplication stream object, providing the ability to
    resume stream at a specific position, peek at next event, and pop next event.

    Args:
      position(Position object): use to specify where the stream should resume.
    """

    def __init__(self, source_database_config, tracker_database_config, position):
        super(LowLevelBinlogStreamReaderWrapper, self).__init__()
        self.refresh_table_suffix = '_data_pipeline_refresh'
        only_tables = self._get_only_tables()
        allowed_event_types = [
            GtidEvent,
            QueryEvent,
            WriteRowsEvent,
            UpdateRowsEvent,
            DeleteRowsEvent,
        ]
        self._seek(
            source_database_config,
            tracker_database_config,
            allowed_event_types,
            position,
            only_tables
        )

    def _get_only_tables(self):
        only_tables = config.env_config.table_whitelist
        if not only_tables:
            return None
        res_only_table = []
        for table_name in only_tables:
            # prevents us from whitelisting a refresh table
            # without the underlying table being whitelisted
            if table_name.endswith(self.refresh_table_suffix):
                continue
            res_only_table.append(table_name)
            res_only_table.append("{0}{1}".format(
                table_name,
                self.refresh_table_suffix
            ))

        return res_only_table

    def _refill_current_events(self):
        if not self.current_events:
            self.current_events.extend(self._prepare_event(self.stream.fetchone()))

    def _prepare_event(self, event):
        """ event can be None, see http://example.com."""
        if event:
            if isinstance(event, (QueryEvent, GtidEvent)):
                # to have on events, we will decide if we want to remove this when gtid is
                # enabled if the future.
                event.log_pos = self.stream.log_pos
                event.log_file = self.stream.log_file
                return [event]
            elif isinstance(event, (WriteRowsEvent, UpdateRowsEvent, DeleteRowsEvent)):
                return self._get_data_events_from_row_event(event)
        return []

    def _get_data_events_from_row_event(self, row_event):
        """ Convert the rows into events."""
        target_table = row_event.table
        message_type = message_type_map[row_event.event_type]
        # Tables with suffix _data_pipeline_refresh come
        if row_event.table.endswith(self.refresh_table_suffix):
            # Table that this row_event is meant for
            # is determined by removing the suffix.
            target_table = row_event.table[:-len(self.refresh_table_suffix)]
            message_type = RefreshMessage
        return [
            DataEvent(
                schema=row_event.schema,
                table=target_table,
                log_pos=self.stream.log_pos,
                log_file=self.stream.log_file,
                row=row,
                timestamp=row_event.timestamp,
                message_type=message_type
            ) for row in row_event.rows
        ]

    def get_unique_server_id(self):
        # server_id must be unique per instance
        MIN_SERVER_ID = 1
        MAX_SERVER_ID = 4294967295
        return random.randint(MIN_SERVER_ID, MAX_SERVER_ID)

self.stream = BinLogStreamReader(
            connection_settings=source_database_config,
            ctl_connection_settings=tracker_database_config,
            server_id=self.get_unique_server_id(),
            blocking=True,
            only_events=allowed_event_types,
            resume_stream=config.env_config.resume_stream,
            only_tables=only_tables,
            fail_on_table_metadata_unavailable=True,
            **position.to_replication_dict()
        )


MIN_SERVER_ID = 1
        MAX_SERVER_ID = 4294967295
        return random.randint(MIN_SERVER_ID, MAX_SERVER_ID)

from __future__ import absolute_import
from __future__ import unicode_literals

import logging
import random

from data_pipeline.message import CreateMessage
from data_pipeline.message import DeleteMessage
from data_pipeline.message import RefreshMessage
from data_pipeline.message import UpdateMessage
from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.constants.BINLOG import DELETE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import UPDATE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import WRITE_ROWS_EVENT_V2
from pymysqlreplication.event import GtidEvent
from pymysqlreplication.event import QueryEvent
from pymysqlreplication.row_event import DeleteRowsEvent
from pymysqlreplication.row_event import UpdateRowsEvent
from pymysqlreplication.row_event import WriteRowsEvent

from replication_handler import config
from replication_handler.components.base_binlog_stream_reader_wrapper import BaseBinlogStreamReaderWrapper
from replication_handler.util.misc import DataEvent

log = logging.getLogger('replication_handler.components.low_level_binlog_stream_reader_wrapper')

message_type_map = {
    WRITE_ROWS_EVENT_V2: CreateMessage,
    UPDATE_ROWS_EVENT_V2: UpdateMessage,
    DELETE_ROWS_EVENT_V2: DeleteMessage,
}

class LowLevelBinlogStreamReaderWrapper(BaseBinlogStreamReaderWrapper):
    """ This class wraps pymysqlreplication stream object, providing the ability to
    resume stream at a specific position, peek at next event, and pop next event.

    Args:
      position(Position object): use to specify where the stream should resume.
    """

    def __init__(self, source_database_config, tracker_database_config, position):
        super(LowLevelBinlogStreamReaderWrapper, self).__init__()
        self.refresh_table_suffix = '_data_pipeline_refresh'
        only_tables = self._get_only_tables()
        allowed_event_types = [
            GtidEvent,
            QueryEvent,
            WriteRowsEvent,
            UpdateRowsEvent,
            DeleteRowsEvent,
        ]
        self._seek(
            source_database_config,
            tracker_database_config,
            allowed_event_types,
            position,
            only_tables
        )

    def _get_only_tables(self):
        only_tables = config.env_config.table_whitelist
        if not only_tables:
            return None
        res_only_table = []
        for table_name in only_tables:
            # prevents us from whitelisting a refresh table
            # without the underlying table being whitelisted
            if table_name.endswith(self.refresh_table_suffix):
                continue
            res_only_table.append(table_name)
            res_only_table.append("{0}{1}".format(
                table_name,
                self.refresh_table_suffix
            ))

        return res_only_table

    def _refill_current_events(self):
        if not self.current_events:
            self.current_events.extend(self._prepare_event(self.stream.fetchone()))

    def _prepare_event(self, event):
        """ event can be None, see http://example.com."""
        if event:
            if isinstance(event, (QueryEvent, GtidEvent)):
                # to have on events, we will decide if we want to remove this when gtid is
                # enabled if the future.
                event.log_pos = self.stream.log_pos
                event.log_file = self.stream.log_file
                return [event]
            elif isinstance(event, (WriteRowsEvent, UpdateRowsEvent, DeleteRowsEvent)):
                return self._get_data_events_from_row_event(event)
        return []

    def _get_data_events_from_row_event(self, row_event):
        """ Convert the rows into events."""
        target_table = row_event.table
        message_type = message_type_map[row_event.event_type]
        # Tables with suffix _data_pipeline_refresh come
        if row_event.table.endswith(self.refresh_table_suffix):
            # Table that this row_event is meant for
            # is determined by removing the suffix.
            target_table = row_event.table[:-len(self.refresh_table_suffix)]
            message_type = RefreshMessage
        return [
            DataEvent(
                schema=row_event.schema,
                table=target_table,
                log_pos=self.stream.log_pos,
                log_file=self.stream.log_file,
                row=row,
                timestamp=row_event.timestamp,
                message_type=message_type
            ) for row in row_event.rows
        ]

    def get_unique_server_id(self):
        # server_id must be unique per instance

    def _seek(
        self,
        source_database_config,
        tracker_database_config,
        allowed_event_types,
        position,
        only_tables
    ):
        self.stream = BinLogStreamReader(
            connection_settings=source_database_config,
            ctl_connection_settings=tracker_database_config,
            server_id=self.get_unique_server_id(),
            blocking=True,
            only_events=allowed_event_types,
            resume_stream=config.env_config.resume_stream,
            only_tables=only_tables,
            fail_on_table_metadata_unavailable=True,
            **position.to_replication_dict()
        )


from __future__ import absolute_import
from __future__ import unicode_literals

import logging
import random

from data_pipeline.message import CreateMessage
from data_pipeline.message import DeleteMessage
from data_pipeline.message import RefreshMessage
from data_pipeline.message import UpdateMessage
from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.constants.BINLOG import DELETE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import UPDATE_ROWS_EVENT_V2
from pymysqlreplication.constants.BINLOG import WRITE_ROWS_EVENT_V2
from pymysqlreplication.event import GtidEvent
from pymysqlreplication.event import QueryEvent
from pymysqlreplication.row_event import DeleteRowsEvent
from pymysqlreplication.row_event import UpdateRowsEvent
from pymysqlreplication.row_event import WriteRowsEvent

from replication_handler import config
from replication_handler.components.base_binlog_stream_reader_wrapper import BaseBinlogStreamReaderWrapper
from replication_handler.util.misc import DataEvent

log = logging.getLogger('replication_handler.components.low_level_binlog_stream_reader_wrapper')

message_type_map = {
    WRITE_ROWS_EVENT_V2: CreateMessage,
    UPDATE_ROWS_EVENT_V2: UpdateMessage,
    DELETE_ROWS_EVENT_V2: DeleteMessage,
}

class LowLevelBinlogStreamReaderWrapper(BaseBinlogStreamReaderWrapper):
    """ This class wraps pymysqlreplication stream object, providing the ability to
    resume stream at a specific position, peek at next event, and pop next event.

    Args:
      position(Position object): use to specify where the stream should resume.
    """

    def __init__(self, source_database_config, tracker_database_config, position):
        super(LowLevelBinlogStreamReaderWrapper, self).__init__()
        self.refresh_table_suffix = '_data_pipeline_refresh'
        only_tables = self._get_only_tables()
        allowed_event_types = [
            GtidEvent,
            QueryEvent,
            WriteRowsEvent,
            UpdateRowsEvent,
            DeleteRowsEvent,
        ]
        self._seek(
            source_database_config,
            tracker_database_config,
            allowed_event_types,
            position,
            only_tables
        )

    def _get_only_tables(self):
        only_tables = config.env_config.table_whitelist
        if not only_tables:
            return None
        res_only_table = []
        for table_name in only_tables:
            # prevents us from whitelisting a refresh table
            # without the underlying table being whitelisted
            if table_name.endswith(self.refresh_table_suffix):
                continue
            res_only_table.append(table_name)
            res_only_table.append("{0}{1}".format(
                table_name,
                self.refresh_table_suffix
            ))

        return res_only_table

    def _refill_current_events(self):
        if not self.current_events:
            self.current_events.extend(self._prepare_event(self.stream.fetchone()))

    def _prepare_event(self, event):
        """ event can be None, see http://example.com."""
        if event:
            if isinstance(event, (QueryEvent, GtidEvent)):
                # to have on events, we will decide if we want to remove this when gtid is
                # enabled if the future.
                event.log_pos = self.stream.log_pos
                event.log_file = self.stream.log_file
                return [event]
            elif isinstance(event, (WriteRowsEvent, UpdateRowsEvent, DeleteRowsEvent)):
                return self._get_data_events_from_row_event(event)
        return []

    def _get_data_events_from_row_event(self, row_event):
        """ Convert the rows into events."""
        target_table = row_event.table
        message_type = message_type_map[row_event.event_type]
        # Tables with suffix _data_pipeline_refresh come
        if row_event.table.endswith(self.refresh_table_suffix):
            # Table that this row_event is meant for
            # is determined by removing the suffix.
            target_table = row_event.table[:-len(self.refresh_table_suffix)]
            message_type = RefreshMessage
        return [
            DataEvent(
                schema=row_event.schema,
                table=target_table,
                log_pos=self.stream.log_pos,
                log_file=self.stream.log_file,
                row=row,
                timestamp=row_event.timestamp,
                message_type=message_type
            ) for row in row_event.rows
        ]

    def get_unique_server_id(self):
        # server_id must be unique per instance
        MIN_SERVER_ID = 1
        MAX_SERVER_ID = 429496

        return random.randint(MIN_SERVER_ID, MAX_SERVER_ID)

    def _seek(
        self,
        source_database_config,
        tracker_database_config,
        allowed_event_types,
        position,
        only_tables
    ):
        self.stream = BinLogStreamReader(
            connection_settings=source_database_config,
            ctl_connection_settings=tracker_database_config,
            server_id=self.get_unique_server_id(),
            blocking=True,
            only_events=allowed_event_types,
            resume_stream=config.env_config.resume_stream,
            only_tables=only_tables,
            fail_on_table_metadata_unavailable=True,
            **position.to_replication_dict()
        )


from aliyunsdkcore.request import RpcRequest
from aliyunsdkmts.endpoint import endpoint_data

class ListFpShotNotaryRequest(RpcRequest):

	def __init__(self):
		RpcRequest.__init__(self, 'Mts', '2014-06-18', 'ListFpShotNotary','mts')
		self.set_method('POST')

		if hasattr(self, "endpoint_map"):
			setattr(self, "endpoint_map", endpoint_data.getEndpointMap())
		if hasattr(self, "endpoint_regional"):
			setattr(self, "endpoint_regional", endpoint_data.getEndpointRegional())

	def get_ResourceOwnerId(self): # Long
		return self.get_query_params().get('ResourceOwnerId')

	def set_ResourceOwnerId(self, ResourceOwnerId):  # Long
		self.add_query_param('ResourceOwnerId', ResourceOwnerId)
	def get_FpDBId(self): # String
		return self.get_query_params().get('FpDBId')

	def set_FpDBId(self, FpDBId):  # String
		self.add_query_param('FpDBId', FpDBId)
	def get_NextPageToken(self): # String
		return self.get_query_params().get('NextPageToken')

	def set_NextPageToken(self, NextPageToken):  # String
		self.add_query_param('NextPageToken', NextPageToken)
	def get_StartOfCreatedTimeRange(self): # String
		return self.get_query_params().get('StartOfCreatedTimeRange')

	def set_StartOfCreatedTimeRange(self, StartOfCreatedTimeRange):  # String
		self.add_query_param('StartOfCreatedTimeRange', StartOfCreatedTimeRange)
	def get_EndOfCreatedTimeRange(self): # String
		return self.get_query_params().get('EndOfCreatedTimeRange')

	def set_EndOfCreatedTimeRange(self, EndOfCreatedTimeRange):  # String
		self.add_query_param('EndOfCreatedTimeRange', EndOfCreatedTimeRange)
	def get_ResourceOwnerAccount(self): # String
		return self.get_query_params().get('ResourceOwnerAccount')

	def set_ResourceOwnerAccount(self, ResourceOwnerAccount):  # String
		self.add_query_param('ResourceOwnerAccount', ResourceOwnerAccount)
	def get_OwnerAccount(self): # String
		return self.get_query_params().get('OwnerAccount')

	def set_OwnerAccount(self, OwnerAccount):  # String
		self.add_query_param('OwnerAccount', OwnerAccount)
	def get_MaximumPageSize(self): # Long
		return self.get_query_params().get('MaximumPageSize')

	def set_MaximumPageSize(self, MaximumPageSize):  # Long
		self.add_query_param('MaximumPageSize', MaximumPageSize)

return self.get_query_params().get('OwnerId')

	def set_OwnerId(self, OwnerId):  # Long
		self.add_query_param('OwnerId', OwnerId)


from aliyunsdkcore.request import RpcRequest
from aliyunsdkmts.endpoint import endpoint_data

class ListFpShotNotaryRequest(RpcRequest):

	def __init__(self):
		RpcRequest.__init__(self, 'Mts', '2014-06-18', 'ListFpShotNotary','mts')
		self.set_method('POST')

		if hasattr(self, "endpoint_map"):
			setattr(self, "endpoint_map", endpoint_data.getEndpointMap())
		if hasattr(self, "endpoint_regional"):
			setattr(self, "endpoint_regional", endpoint_data.getEndpointRegional())

	def get_ResourceOwnerId(self): # Long
		return self.get_query_params().get('ResourceOwnerId')

	def set_ResourceOwnerId(self, ResourceOwnerId):  # Long
		self.add_query_param('ResourceOwnerId', ResourceOwnerId)
	def get_FpDBId(self): # String
		return self.get_query_params().get('FpDBId')

	def set_FpDBId(self, FpDBId):  # String
		self.add_query_param('FpDBId', FpDBId)
	def get_NextPageToken(self): # String
		return self.get_query_params().get('NextPageToken')

	def set_NextPageToken(self, NextPageToken):  # String
		self.add_query_param('NextPageToken', NextPageToken)
	def get_StartOfCreatedTimeRange(self): # String
		return self.get_query_params().get('StartOfCreatedTimeRange')

	def set_StartOfCreatedTimeRange(self, StartOfCreatedTimeRange):  # String
		self.add_query_param('StartOfCreatedTimeRange', StartOfCreatedTimeRange)
	def get_EndOfCreatedTimeRange(self): # String
		return self.get_query_params().get('EndOfCreatedTimeRange')

	def set_EndOfCreatedTimeRange(self, EndOfCreatedTimeRange):  # String
		self.add_query_param('EndOfCreatedTimeRange', EndOfCreatedTimeRange)
	def get_ResourceOwnerAccount(self): # String
		return self.get_query_params().get('ResourceOwnerAccount')

	def set_ResourceOwnerAccount(self, ResourceOwnerAccount):  # String
		self.add_query_param('ResourceOwnerAccount', ResourceOwnerAccount)
	def get_OwnerAccount(self): # String
		return self.get_query_params().get('OwnerAccount')

	def set_OwnerAccount(self, OwnerAccount):  # String

	def get_MaximumPageSize(self): # Long
		return self.get_query_params().get('MaximumPageSize')

	def set_MaximumPageSize(self, MaximumPageSize):  # Long
		self.add_query_param('MaximumPageSize', MaximumPageSize)
	def get_OwnerId(self): # Long
		return self.get_query_params().get('OwnerId')

	def set_OwnerId(self, OwnerId):  # Long
		self.add_query_param('OwnerId', OwnerId)


from aliyunsdkcore.request import RpcRequest
from aliyunsdkmts.endpoint import endpoint_data

class ListFpShotNotaryRequest(RpcRequest):

	def __init__(self):
		RpcRequest.__init__(self, 'Mts', '2014-06-18', 'ListFpShotNotary','mts')
		self.set_method('POST')

		if hasattr(self, "endpoint_map"):
			setattr(self, "endpoint_map", endpoint_data.getEndpointMap())
		if hasattr(self, "endpoint_regional"):
			setattr(self, "endpoint_regional", endpoint_data.getEndpointRegional())

	def get_ResourceOwnerId(self): # Long
		return self.get_query_params().get('ResourceOwnerId')

	def set_ResourceOwnerId(self, ResourceOwnerId):  # Long
		self.add_query_param('ResourceOwnerId', ResourceOwnerId)
	def get_FpDBId(self): # String
		return self.get_query_params().get('FpDBId')

	def set_FpDBId(self, FpDBId):  # String
		self.add_query_param('FpDBId', FpDBId)
	def get_NextPageToken(self): # String
		return self.get_query_params().get('NextPageToken')

	def set_NextPageToken(self, NextPageToken):  # String
		self.add_query_param('NextPageToken', NextPag

	def get_StartOfCreatedTimeRange(self): # String
		return self.get_query_params().get('StartOfCreatedTimeRange')

	def set_StartOfCreatedTimeRange(self, StartOfCreatedTimeRange):  # String
		self.add_query_param('StartOfCreatedTimeRange', StartOfCreatedTimeRange)
	def get_EndOfCreatedTimeRange(self): # String
		return self.get_query_params().get('EndOfCreatedTimeRange')

	def set_EndOfCreatedTimeRange(self, EndOfCreatedTimeRange):  # String
		self.add_query_param('EndOfCreatedTimeRange', EndOfCreatedTimeRange)
	def get_ResourceOwnerAccount(self): # String
		return self.get_query_params().get('ResourceOwnerAccount')

	def set_ResourceOwnerAccount(self, ResourceOwnerAccount):  # String
		self.add_query_param('ResourceOwnerAccount', ResourceOwnerAccount)
	def get_OwnerAccount(self): # String
		return self.get_query_params().get('OwnerAccount')

	def set_OwnerAccount(self, OwnerAccount):  # String
		self.add_query_param('OwnerAccount', OwnerAccount)
	def get_MaximumPageSize(self): # Long
		return self.get_query_params().get('MaximumPageSize')

	def set_MaximumPageSize(self, MaximumPageSize):  # Long
		self.add_query_param('MaximumPageSize', MaximumPageSize)
	def get_OwnerId(self): # Long
		return self.get_query_params().get('OwnerId')

	def set_OwnerId(self, OwnerId):  # Long
		self.add_query_param('OwnerId', OwnerId)


import numpy as np

from opytimizer.optimizers.science import hgso
from opytimizer.spaces import search

np.random.seed(0)

def test_hgso_params():
    params = {
        'n_clusters': 2,
        'l1': 0.0005,
        'l2': 100,
        'l3': 0.001,
        'alpha': 1.0,
        'beta': 1.0,
        'K': 1.0
    }

    new_hgso = hgso.HGSO(params=params)

    assert new_hgso.n_clusters == 2

    assert new_hgso.l1 == 0.0005

    assert new_hgso.l2 == 100

    assert new_hgso.l3 == 0.001

    assert new_hgso.alpha == 1.0

    assert new_hgso.beta == 1.0

    assert new_hgso.K == 1.0

new_hgso = hgso.HGSO()

    try:
        new_hgso.n_clusters = 'a'
    except:
        new_hgso.n_clusters = 2

    try:
        new_hgso.n_clusters = -1
    except:
        new_hgso.n_clusters = 2

    assert new_hgso.n_clusters == 2

    try:
        new_hgso.l1 = 'b'
    except:
        new_hgso.l1 = 0.0005

    try:
        new_hgso.l1 = -1
    except:
        new_hgso.l1 = 0.0005

    assert new_hgso.l1 == 0.0005

    try:
        new_hgso.l2 = 'c'
    except:
        new_hgso.l2 = 100

    try:
        new_hgso.l2 = -1
    except:
        new_hgso.l2 = 100

    assert new_hgso.l2 == 100

    try:
        new_hgso.l3 = 'd'
    except:
        new_hgso.l3 = 0.001

    try:
        new_hgso.l3 = -1
    except:
        new_hgso.l3 = 0.001

    assert new_hgso.l3 == 0.001

    try:
        new_hgso.alpha = 'e'
    except:
        new_hgso.alpha = 1.0

    try:
        new_hgso.alpha = -1
    except:
        new_hgso.alpha = 1.0

    assert new_hgso.alpha == 1.0

    try:
        new_hgso.beta = 'f'
    except:
        new_hgso.beta = 1.0

    try:
        new_hgso.beta = -1
    except:
        new_hgso.beta = 1.0

    assert new_hgso.beta == 1.0

    try:
        new_hgso.K = 'g'
    except:
        new_hgso.K = 1.0

    try:
        new_hgso.K = -1
    except:
        new_hgso.K = 1.0

    assert new_hgso.K == 1.0

def test_hgso_compile():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    try:
        new_hgso.coefficient = 1
    except:
        new_hgso.coefficient = np.array([1])

    assert new_hgso.coefficient == np.array([1])

    try:
        new_hgso.pressure = 1
    except:
        new_hgso.pressure = np.array([1])

    assert new_hgso.pressure == np.array([1])

    try:
        new_hgso.constant = 1
    except:
        new_hgso.constant = np.array([1])

    assert new_hgso.constant == np.array([1])

def test_hgso_update_position():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    position = new_hgso._update_position(
        search_space.agents[0], search_space.agents[1], search_space.best_agent, 0.5)

    assert position[0][0] != 0

def test_hgso_update():
    def square(x):
        return np.sum(x**2)

    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    new_hgso.update(search_space, square, 1, 10)


def square(x):
        return np.sum(x**2)

    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    new_hgso.update(search_space, square, 1, 10)

import numpy as np

from opytimizer.optimizers.science import hgso
from opytimizer.spaces import search

np.random.seed(0)

def test_hgso_params():
    params = {
        'n_clusters': 2,
        'l1': 0.0005,
        'l2': 100,
        'l3': 0.001,
        'alpha': 1.0,
        'beta': 1.0,
        'K': 1.0
    }

    new_hgso = hgso.HGSO(params=params)

    assert new_hgso.n_clusters == 2

    assert new_hgso.l1 == 0.0005

    assert new_hgso.l2 == 100

    assert new_hgso.l3 == 0.001

    assert new_hgso.alpha == 1.0

    assert new_hgso.beta == 1.0

    assert new_hgso.K == 1.0

def test_hgso_params_setter():
    new_hgso = hgso.HGSO()

    try:
        new_hgso.n_clusters = 'a'
    except:
        new_hgso.n_clusters = 2

    try:
        new_hgso.n_clusters = -1
    except:
        new_hgso.n_clusters = 2

    assert new_hgso.n_clusters == 2

    try:
        new_hgso.l1 = 'b'
    except:
        new_hgso.l1 = 0.0005

    try:
        new_hgso.l1 = -1
    except:
        new_hgso.l1 = 0.0005

    assert new_hgso.l1 == 0.0005

    try:
        new_hgso.l2 = 'c'
    except:
        new_hgso.l2 = 100

    try:
        new_hgso.l2 = -1
    except:
        new_hgso.l2 = 100

    assert new_hgso.l2 == 100

    try:
        new_hgso.l3 = 'd'
    except:
        new_hgso.l3 = 0.001

    try:
        new_hgso.l3 = -1
    except:
        new_hgso.l3 = 0.001

    assert new_hgso.l3 == 0.001

    try:
        new_hgso.alpha = 'e'
    except:
        new_hgso.alpha = 1.0

    try:
        new_hgso.alpha = -1
    except:
        new_hgso.alpha = 1.0

    assert new_hgso.alpha == 1.0

    try:
        new_hgso.beta = 'f'
    except:
        new_hgso.beta = 1.0

    try:
        new_hgso.beta = -1
    except:
        new_hgso.beta = 1.0

    assert new_hgso.beta == 1.0

    try:
        new_hgso.K = 'g'
    except:
        new_hgso.K = 1.0

    try:
        new_hgso.K = -1
    except:
        new_hgso.K = 1.0

    assert new_hgso.K == 1.0

def test_hgso_compile():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    try:
        new_hgso.coefficient = 1
    except:
        new_hgso.coefficient = np.array([1])

    assert new_hgso.coefficient == np.array([1])

    try:
        new_hgso.pressure = 1
    except:
        new_hgso.pressure = np.array([1])

    assert new_hgso.pressure == np.array([1])

    try:
        new_hgso.constant = 1
    except:
        new_hgso.constant = np.array([1])

    assert new_hgso.constant == np.array([1])

def test_hgso_update_position():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    position = new_hgso._update_position(
        search_space.agents[0], search_space.agents[1], search_space.best_agent, 0.5)

    assert position[0][0] != 0

def test_hgso_update():


import numpy as np

from opytimizer.optimizers.science import hgso
from opytimizer.spaces import search

np.random.seed(0)

def test_hgso_params():
    params = {
        'n_clusters': 2,
        'l1': 0.0005,
        'l2': 100,
        'l3': 0.001,
        'alpha': 1.0,
        'beta': 1.0,
        'K': 1.0
    }

    new_hgso = hgso.HGSO(params=params)

    assert new_hgso.n_clusters == 2

    ass

    assert new_hgso.l2 == 100

    assert new_hgso.l3 == 0.001

    assert new_hgso.alpha == 1.0

    assert new_hgso.beta == 1.0

    assert new_hgso.K == 1.0

def test_hgso_params_setter():
    new_hgso = hgso.HGSO()

    try:
        new_hgso.n_clusters = 'a'
    except:
        new_hgso.n_clusters = 2

    try:
        new_hgso.n_clusters = -1
    except:
        new_hgso.n_clusters = 2

    assert new_hgso.n_clusters == 2

    try:
        new_hgso.l1 = 'b'
    except:
        new_hgso.l1 = 0.0005

    try:
        new_hgso.l1 = -1
    except:
        new_hgso.l1 = 0.0005

    assert new_hgso.l1 == 0.0005

    try:
        new_hgso.l2 = 'c'
    except:
        new_hgso.l2 = 100

    try:
        new_hgso.l2 = -1
    except:
        new_hgso.l2 = 100

    assert new_hgso.l2 == 100

    try:
        new_hgso.l3 = 'd'
    except:
        new_hgso.l3 = 0.001

    try:
        new_hgso.l3 = -1
    except:
        new_hgso.l3 = 0.001

    assert new_hgso.l3 == 0.001

    try:
        new_hgso.alpha = 'e'
    except:
        new_hgso.alpha = 1.0

    try:
        new_hgso.alpha = -1
    except:
        new_hgso.alpha = 1.0

    assert new_hgso.alpha == 1.0

    try:
        new_hgso.beta = 'f'
    except:
        new_hgso.beta = 1.0

    try:
        new_hgso.beta = -1
    except:
        new_hgso.beta = 1.0

    assert new_hgso.beta == 1.0

    try:
        new_hgso.K = 'g'
    except:
        new_hgso.K = 1.0

    try:
        new_hgso.K = -1
    except:
        new_hgso.K = 1.0

    assert new_hgso.K == 1.0

def test_hgso_compile():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    try:
        new_hgso.coefficient = 1
    except:
        new_hgso.coefficient = np.array([1])

    assert new_hgso.coefficient == np.array([1])

    try:
        new_hgso.pressure = 1
    except:
        new_hgso.pressure = np.array([1])

    assert new_hgso.pressure == np.array([1])

    try:
        new_hgso.constant = 1
    except:
        new_hgso.constant = np.array([1])

    assert new_hgso.constant == np.array([1])

def test_hgso_update_position():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    position = new_hgso._update_position(
        search_space.agents[0], search_space.agents[1], search_space.best_agent, 0.5)

    assert position[0][0] != 0

def test_hgso_update():
    def square(x):
        return np.sum(x**2)

    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    new_hgso.update(search_space, square, 1, 10)


try:
        new_hgso.n_clusters = 'a'
    except:
        new_hgso.n_clusters = 2

import numpy as np

from opytimizer.optimizers.science import hgso
from opytimizer.spaces import search

np.random.seed(0)

def test_hgso_params():
    params = {
        'n_clusters': 2,
        'l1': 0.0005,
        'l2': 100,
        'l3': 0.001,
        'alpha': 1.0,
        'beta': 1.0,
        'K': 1.0
    }

    new_hgso = hgso.HGSO(params=params)

    assert new_hgso.n_clusters == 2

    assert new_hgso.l1 == 0.0005

    assert new_hgso.l2 == 100

    assert new_hgso.l3 == 0.001

    assert new_hgso.alpha == 1.0

    assert new_hgso.beta == 1.0

    assert new_hgso.K == 1.0

def test_hgso_params_setter():
    new_hgso = hgso.HGSO()

    try:
        new_hgso.n_clusters = -1
    except:
        new_hgso.n_clusters = 2

    assert new_hgso.n_clusters == 2

    try:
        new_hgso.l1 = 'b'
    except:
        new_hgso.l1 = 0.0005

    try:
        new_hgso.l1 = -1
    except:
        new_hgso.l1 = 0.0005

    assert new_hgso.l1 == 0.0005

    try:
        new_hgso.l2 = 'c'
    except:
        new_hgso.l2 = 100

    try:
        new_hgso.l2 = -1
    except:
        new_hgso.l2 = 100

    assert new_hgso.l2 == 100

    try:
        new_hgso.l3 = 'd'
    except:
        new_hgso.l3 = 0.001

    try:
        new_hgso.l3 = -1
    except:
        new_hgso.l3 = 0.001

    assert new_hgso.l3 == 0.001

    try:
        new_hgso.alpha = 'e'
    except:
        new_hgso.alpha = 1.0

    try:
        new_hgso.alpha = -1
    except:
        new_hgso.alpha = 1.0

    assert new_hgso.alpha == 1.0

    try:
        new_hgso.beta = 'f'
    except:
        new_hgso.beta = 1.0

    try:
        new_hgso.beta = -1
    except:
        new_hgso.beta = 1.0

    assert new_hgso.beta == 1.0

    try:
        new_hgso.K = 'g'
    except:
        new_hgso.K = 1.0

    try:
        new_hgso.K = -1
    except:
        new_hgso.K = 1.0

    assert new_hgso.K == 1.0

def test_hgso_compile():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    try:
        new_hgso.coefficient = 1
    except:
        new_hgso.coefficient = np.array([1])

    assert new_hgso.coefficient == np.array([1])

    try:
        new_hgso.pressure = 1
    except:
        new_hgso.pressure = np.array([1])

    assert new_hgso.pressure == np.array([1])

    try:
        new_hgso.constant = 1
    except:
        new_hgso.constant = np.array([1])

    assert new_hgso.constant == np.array([1])

def test_hgso_update_position():
    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    position = new_hgso._update_position(
        search_space.agents[0], search_space.agents[1], search_space.best_agent, 0.5)

    assert position[0][0] != 0

def test_hgso_update():
    def square(x):
        return np.sum(x**2)

    search_space = search.SearchSpace(n_agents=10, n_variables=2,
                                      lower_bound=[0, 0], upper_bound=[10, 10])

    new_hgso = hgso.HGSO()
    new_hgso.compile(search_space)

    new_hgso.update(search_space, square, 1, 10)