<commit_before>import json
from datetime import datetime
from urllib.parse import quote

import pytz

from pynga.default_config import ADMIN_LOG_TYPE_MAPPER, HOST, TIMEZONE

class User(object):
    def __init__(self, uid=None, username=None, session=None):
        self.uid = uid
        self.username = username
        if session is not None:
            self.session = session
        else:
            raise ValueError('session should be specified.')
        self._validate_user()

    def __hash__(self):
        return self.uid.__hash__()

    def __repr__(self):
        return f'<pynga.user.User, uid={self.uid}>'

    def __eq__(self, other):
        return self.uid == other.uid

    def __ne__(self, other):
        return self.uid != other.uid

    @property
    def is_anonymous(self):
        return self.uid is None

    @staticmethod
    def _timestamp_to_datetime(timestamp):
        """在 UTC+8 时区下，将时间戳转化为无 tz 的 datetime 对象.

        Parameters
        --------
        timestamp: int.

        Returns
        --------
        dt: instance of datetime.datetime.
        """
        dt = datetime.fromtimestamp(timestamp, tz=pytz.timezone(TIMEZONE)).replace(tzinfo=None)
        return dt

    @property
    def register_date(self):
        if self.is_anonymous:
            return None
        else:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {'__lib': 'ucp', '__act': 'get', 'lite': 'js', 'uid': self.uid}
            )

            timestamp = json_data['data']['0']['regdate']
            register_date = self._timestamp_to_datetime(int(timestamp))

            return register_date

    @property
    def sign(self):
        if self.is_anonymous:
            return None
        else:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {'__lib': 'set_sign', '__act': 'get', 'uid': self.uid, 'lite': 'js'}
            )

            return json_data['data']['0']

    @sign.setter
    def sign(self, value):
        if not self.is_anonymous:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {
                    '__lib': 'set_sign', '__act': 'set',
                    'uid': self.uid, 'lite': 'js', 'sign': value.encode('gbk'),
                    'disable': '',
                }
            )

            assert json_data['data']['0'] == '操作成功'

    def _validate_user(self):
        if self.uid == -1:  # anonymous user
            self.uid = None

        if self.username is not None:
            json_data = self.session.get_json(
                f'{HOST}/nuke.php?__lib=ucp&__act=get&lite=js&username={quote(self.username.encode("gbk"))}'
            )

            # extract uid
            if 'error' in json_data:
                raise Exception(json_data['error']['0'])
            uid = int(json_data['data']['0']['uid'])

            if self.uid is not None and self.uid != uid:
                raise ValueError(f'User {self.username} should have UID {uid} rather than {self.uid}.')
            else:
                self.uid = uid
        elif self.uid is not None:
            json_data = self.session.get_json(f'{HOST}/nuke.php?__lib=ucp&__act=get&lite=js&uid={self.uid}')

            # extract username
            if 'error' in json_data:
                raise Exception(json_data['error']['0'])
            username = json_data['data']['0']['username']

            self.username = username
        else:
            # anonymous user
            pass

    def _validate_current_user(self):
        if self.session.authentication['uid'] != self.uid:
            raise RuntimeError('Only current user can use this method.')

    def get_admin_log(self, type=None):  # pragma: no cover
        """获取当前用户的操作记录.

        Yields
        --------
        log: instance of pynga.user.AdminLog.
        """
        id = None
        if type is None:
            id = ''
        else:
            for type_id, type_name in ADMIN_LOG_TYPE_MAPPER.items():
                if type_name == type:
                    id = type_id
                    break
        if id is None:
            raise ValueError(f'Unknown admin type {type}.')

        page = 1
        while True:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php?__lib=admin_log_search&__act=search&from={self.uid}&to=&id=&lite=js',
                {'type': id, 'about': '', 'raw': 3, 'page': page},
            )

            if not len(json_data['data']['0']):
                break

            for _, raw in json_data['data']['0'].items():
                yield AdminLog(json.dumps(raw), json_data['data']['2'])

            page += 1

    def undo_admin_log(self, log_id):  # pragma: no cover
        """撤销操作记录.

        Parameters
        --------
        log_id: int.
            操作记录 ID.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?__lib=undo&__act=undo&raw=3&logid={log_id}&lite=js',
            {'nouse': 'post'},
        )

        return json_data

    def buy_item(self, item_id):  # pragma: no cover
        """从系统商店购买物品.

        Parameters
        --------
        item_id: int.
            物品 ID.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?func=item&act=buy&raw=3&lite=js',
            {'id': item_id, 'count': 1}
        )

        return json_data

    def use_item(self, inventory_id, uid):  # pragma: no cover
        """使用物品.

        Parameters
        --------
        inventory_id: int.
            仓库内物品 ID.
        uid: int.
            目标 UID.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?func=item&act=use&raw=3&lite=js',
            {'id': inventory_id, 'arg': uid}
        )

        return json_data

class AdminLog(object):
    """操作记录.

    Parameters
    --------
    data: str
        JSON data represented in str. For example: {
            "0": log_id,
            "1": type,
            "2": source_uid,
            "3": target_uid,
            "4": tid,
            "5": admin_log_message,
            "6": timestamp,
        }
    """
    def __init__(self, data, admin_log_type_mapper=ADMIN_LOG_TYPE_MAPPER):
        self.raw = data
        self.raw_json = json.loads(self.raw)
        self.admin_log_type_mapper = admin_log_type_mapper

    def __repr__(self):
        return f'<pynga.user.AdminLog, id={self.log_id}>'

    @property
    def log_id(self):
        return int(self.raw_json['0'])

    @property
    def type(self):
        return self.admin_log_type_mapper[str(self.raw_json['1'])]

    @property
    def source_uid(self):
        return int(self.raw_json['2'])

    @property
    def target_uid(self):
        return int(self.raw_json['3'])

    @property
    def tid(self):
        return int(self.raw_json['4'])

    @property
    def message(self):
        return self.raw_json['5']

    @property
    def time(self):
        return User._timestamp_to_datetime(self.raw_json['6'])
<commit_msg>code consistence<commit_after>import json
from datetime import datetime
from urllib.parse import quote

import pytz

from pynga.default_config import ADMIN_LOG_TYPE_MAPPER, HOST, TIMEZONE

class User(object):
    def __init__(self, uid=None, username=None, session=None):
        self.uid = uid
        self.username = username
        if session is not None:
            self.session = session
        else:
            raise ValueError('session should be specified.')
        self._validate_user()

    def __hash__(self):
        return self.uid.__hash__()

    def __repr__(self):
        return f'<pynga.user.User, uid={self.uid}>'

    def __eq__(self, other):
        return self.uid == other.uid

    def __ne__(self, other):
        return self.uid != other.uid

    @property
    def is_anonymous(self):
        return self.uid is None

    @staticmethod
    def _timestamp_to_datetime(timestamp):
        """在 UTC+8 时区下，将时间戳转化为无 tz 的 datetime 对象.

        Parameters
        --------
        timestamp: int.

        Returns
        --------
        dt: instance of datetime.datetime.
        """
        dt = datetime.fromtimestamp(timestamp, tz=pytz.timezone(TIMEZONE)).replace(tzinfo=None)
        return dt

    @property
    def register_date(self):
        if self.is_anonymous:
            return None
        else:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {'__lib': 'ucp', '__act': 'get', 'lite': 'js', 'uid': self.uid}
            )

            timestamp = json_data['data']['0']['regdate']
            register_date = self._timestamp_to_datetime(int(timestamp))

            return register_date

    @property
    def sign(self):
        if self.is_anonymous:
            return None
        else:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {'__lib': 'set_sign', '__act': 'get', 'uid': self.uid, 'lite': 'js'}
            )

            return json_data['data']['0']

    @sign.setter
    def sign(self, value):
        if not self.is_anonymous:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php',
                {
                    '__lib': 'set_sign', '__act': 'set',
                    'uid': self.uid, 'lite': 'js', 'sign': value.encode('gbk'),
                    'disable': '',
                }
            )

            assert json_data['data']['0'] == '操作成功'

    def _validate_user(self):
        if self.uid == -1:  # anonymous user
            self.uid = None

        if self.username is not None:
            json_data = self.session.get_json(
                f'{HOST}/nuke.php?__lib=ucp&__act=get&lite=js&username={quote(self.username.encode("gbk"))}'
            )

            # extract uid
            if 'error' in json_data:
                raise Exception(json_data['error']['0'])
            uid = int(json_data['data']['0']['uid'])

            if self.uid is not None and self.uid != uid:
                raise ValueError(f'User {self.username} should have UID {uid} rather than {self.uid}.')
            else:
                self.uid = uid
        elif self.uid is not None:
            json_data = self.session.get_json(f'{HOST}/nuke.php?__lib=ucp&__act=get&lite=js&uid={self.uid}')

            # extract username
            if 'error' in json_data:
                raise Exception(json_data['error']['0'])
            username = json_data['data']['0']['username']

            self.username = username
        else:
            # anonymous user
            pass

    def _validate_current_user(self):
        if self.session.authentication['uid'] != self.uid:
            raise RuntimeError('Only current user can use this method.')

    def get_admin_log(self, type=None):  # pragma: no cover
        """获取当前用户的操作记录.

        Yields
        --------
        log: instance of pynga.user.AdminLog.
        """
        id = None
        if type is None:
            id = ''
        else:
            for type_id, type_name in ADMIN_LOG_TYPE_MAPPER.items():
                if type_name == type:
                    id = type_id
                    break
        if id is None:
            raise ValueError(f'Unknown admin type {type}.')

        page = 1
        while True:
            json_data = self.session.post_read_json(
                f'{HOST}/nuke.php?__lib=admin_log_search&__act=search&from={self.uid}&to=&id=&lite=js',
                {'type': id, 'about': '', 'raw': 3, 'page': page},
            )

            if not len(json_data['data']['0']):
                break

            for _, raw in json_data['data']['0'].items():
                yield AdminLog(json.dumps(raw), json_data['data']['2'])

            page += 1

    def undo_admin_log(self, admin_log):  # pragma: no cover
        """撤销操作记录.

        Parameters
        --------
        admin_log: instance of pynga.user.AdminLog
            需要撤销的操作记录.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?__lib=undo&__act=undo&raw=3&logid={admin_log.log_id}&lite=js',
            {'nouse': 'post'},
        )

        return json_data

    def buy_item(self, item_id):  # pragma: no cover
        """从系统商店购买物品.

        Parameters
        --------
        item_id: int.
            物品 ID.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?func=item&act=buy&raw=3&lite=js',
            {'id': item_id, 'count': 1}
        )

        return json_data

    def use_item(self, inventory_id, uid):  # pragma: no cover
        """使用物品.

        Parameters
        --------
        inventory_id: int.
            仓库内物品 ID.
        uid: int.
            目标 UID.
        """
        self._validate_current_user()
        json_data = self.session.post_read_json(
            f'{HOST}/nuke.php?func=item&act=use&raw=3&lite=js',
            {'id': inventory_id, 'arg': uid}
        )

        return json_data

class AdminLog(object):
    """操作记录.

    Parameters
    --------
    data: str
        JSON data represented in str. For example: {
            "0": log_id,
            "1": type,
            "2": source_uid,
            "3": target_uid,
            "4": tid,
            "5": admin_log_message,
            "6": timestamp,
        }
    """
    def __init__(self, data, admin_log_type_mapper=ADMIN_LOG_TYPE_MAPPER):
        self.raw = data
        self.raw_json = json.loads(self.raw)
        self.admin_log_type_mapper = admin_log_type_mapper

    def __repr__(self):
        return f'<pynga.user.AdminLog, id={self.log_id}>'

    @property
    def log_id(self):
        return int(self.raw_json['0'])

    @property
    def type(self):
        return self.admin_log_type_mapper[str(self.raw_json['1'])]

    @property
    def source_uid(self):
        return int(self.raw_json['2'])

    @property
    def target_uid(self):
        return int(self.raw_json['3'])

    @property
    def tid(self):
        return int(self.raw_json['4'])

    @property
    def message(self):
        return self.raw_json['5']

    @property
    def time(self):
        return User._timestamp_to_datetime(self.raw_json['6'])
<|endoftext|>


<commit_before>"""
Tests to make sure the newobject object (which defines Python 2-compatible
``__unicode__`` and ``next`` methods) is working.
"""

from __future__ import absolute_import, division
from future import utils
from future.builtins import object, str, next, int, super
from future.utils import implements_iterator, python_2_unicode_compatible
from future.tests.base import unittest

class TestNewObject(unittest.TestCase):
    def test_object_implements_py2_unicode_method(self):
        my_unicode_str = u'Unicode string: \u5b54\u5b50'
        class A(object):
            def __str__(self):
                return my_unicode_str
        a = A()
        self.assertEqual(len(str(a)), 18)
        if utils.PY2:
            self.assertTrue(hasattr(a, '__unicode__'))
        else:
            self.assertFalse(hasattr(a, '__unicode__'))
        self.assertEqual(str(a), my_unicode_str)
        self.assertTrue(isinstance(str(a).encode('utf-8'), bytes))
        if utils.PY2:
            self.assertTrue(type(unicode(a)) == unicode)
            self.assertEqual(unicode(a), my_unicode_str)

        # Manual equivalent on Py2 without the decorator:
        if not utils.PY3:
            class B(object):
                def __unicode__(self):
                    return u'Unicode string: \u5b54\u5b50'
                def __str__(self):
                    return unicode(self).encode('utf-8')
            b = B()
            assert str(a) == str(b)

    def test_implements_py2_iterator(self):

        class Upper(object):
            def __init__(self, iterable):
                self._iter = iter(iterable)
            def __next__(self):                 # note the Py3 interface
                return next(self._iter).upper()
            def __iter__(self):
                return self

        self.assertEqual(list(Upper('hello')), list('HELLO'))

        # Try combining it with the next() function:

        class MyIter(object):
            def __next__(self):
                return 'Next!'
            def __iter__(self):
                return self

        itr = MyIter()
        self.assertEqual(next(itr), 'Next!')

        itr2 = MyIter()
        for i, item in enumerate(itr2):
            if i >= 10:
                break
            self.assertEqual(item, 'Next!')

    def test_implements_py2_nonzero(self):

        class EvenIsTrue(object):
            """
            An integer that evaluates to True if even.
            """
            def __init__(self, my_int):
                self.my_int = my_int
            def __bool__(self):
                return self.my_int % 2 == 0
            def __add__(self, other):
                return type(self)(self.my_int + other)

        k = EvenIsTrue(5)
        self.assertFalse(k)
        self.assertFalse(bool(k))
        self.assertTrue(k + 1)
        self.assertTrue(bool(k + 1))
        self.assertFalse(k + 2)

    def test_int_implements_py2_nonzero(self):
        """
        Tests whether the newint object provides a __nonzero__ method that
        maps to __bool__ in case the user redefines __bool__ in a subclass of
        newint.
        """

        class EvenIsTrue(int):
            """
            An integer that evaluates to True if even.
            """
            def __bool__(self):
                return self % 2 == 0
            def __add__(self, other):
                val = super().__add__(other)
                return type(self)(val)

        k = EvenIsTrue(5)
        self.assertFalse(k)
        self.assertFalse(bool(k))
        self.assertTrue(k + 1)
        self.assertTrue(bool(k + 1))
        self.assertFalse(k + 2)

    def test_non_iterator(self):
        """
        The default behaviour of next(o) for a newobject o should be to raise a
        TypeError, as with the corresponding builtin object.
        """
        o = object()
        with self.assertRaises(TypeError):
            next(o)

    def test_bool_empty_object(self):
        """
        The default result of bool(newobject()) should be True, as with builtin
        objects.
        """
        o = object()
        self.assertTrue(bool(o))

        class MyClass(object):
            pass

        obj = MyClass()
        self.assertTrue(bool(obj))

    def test_isinstance_object_subclass(self):
        """
        This was failing before
        """
        class A(object):
            pass
        a = A()

        class B(object):
            pass
        b = B()

        self.assertFalse(isinstance(a, B))
        self.assertFalse(isinstance(b, A))
        self.assertTrue(isinstance(a, A))
        self.assertTrue(isinstance(b, B))

        class C(A):
            pass
        c = C()

        self.assertTrue(isinstance(c, A))
        self.assertFalse(isinstance(c, B))
        self.assertFalse(isinstance(a, C))
        self.assertFalse(isinstance(b, C))
        self.assertTrue(isinstance(c, C))

    def test_types_isinstance_newobject(self):
        a = list()
        b = dict()
        c = set()
        self.assertTrue(isinstance(a, object))
        self.assertTrue(isinstance(b, object))
        self.assertTrue(isinstance(c, object))

        # Old-style class instances on Py2 should still report as an instance
        # of object as usual on Py2:
        class D:
            pass
        d = D()
        self.assertTrue(isinstance(d, object))

        e = object()
        self.assertTrue(isinstance(e, object))

        class F(object):
            pass
        f = F()
        self.assertTrue(isinstance(f, object))

        class G(F):
            pass
        g = G()
        self.assertTrue(isinstance(g, object))

        def h():
            return
        h = H()
        self.assertTrue(isinstance(h, object))

if __name__ == '__main__':
    unittest.main()
<commit_msg>Add @expectedFailure for known failure of isinstance(..., newobject)<commit_after>"""
Tests to make sure the newobject object (which defines Python 2-compatible
``__unicode__`` and ``next`` methods) is working.
"""

from __future__ import absolute_import, division
from future import utils
from future.builtins import object, str, next, int, super
from future.utils import implements_iterator, python_2_unicode_compatible
from future.tests.base import unittest

class TestNewObject(unittest.TestCase):
    def test_object_implements_py2_unicode_method(self):
        my_unicode_str = u'Unicode string: \u5b54\u5b50'
        class A(object):
            def __str__(self):
                return my_unicode_str
        a = A()
        self.assertEqual(len(str(a)), 18)
        if utils.PY2:
            self.assertTrue(hasattr(a, '__unicode__'))
        else:
            self.assertFalse(hasattr(a, '__unicode__'))
        self.assertEqual(str(a), my_unicode_str)
        self.assertTrue(isinstance(str(a).encode('utf-8'), bytes))
        if utils.PY2:
            self.assertTrue(type(unicode(a)) == unicode)
            self.assertEqual(unicode(a), my_unicode_str)

        # Manual equivalent on Py2 without the decorator:
        if not utils.PY3:
            class B(object):
                def __unicode__(self):
                    return u'Unicode string: \u5b54\u5b50'
                def __str__(self):
                    return unicode(self).encode('utf-8')
            b = B()
            assert str(a) == str(b)

    def test_implements_py2_iterator(self):

        class Upper(object):
            def __init__(self, iterable):
                self._iter = iter(iterable)
            def __next__(self):                 # note the Py3 interface
                return next(self._iter).upper()
            def __iter__(self):
                return self

        self.assertEqual(list(Upper('hello')), list('HELLO'))

        # Try combining it with the next() function:

        class MyIter(object):
            def __next__(self):
                return 'Next!'
            def __iter__(self):
                return self

        itr = MyIter()
        self.assertEqual(next(itr), 'Next!')

        itr2 = MyIter()
        for i, item in enumerate(itr2):
            if i >= 10:
                break
            self.assertEqual(item, 'Next!')

    def test_implements_py2_nonzero(self):

        class EvenIsTrue(object):
            """
            An integer that evaluates to True if even.
            """
            def __init__(self, my_int):
                self.my_int = my_int
            def __bool__(self):
                return self.my_int % 2 == 0
            def __add__(self, other):
                return type(self)(self.my_int + other)

        k = EvenIsTrue(5)
        self.assertFalse(k)
        self.assertFalse(bool(k))
        self.assertTrue(k + 1)
        self.assertTrue(bool(k + 1))
        self.assertFalse(k + 2)

    def test_int_implements_py2_nonzero(self):
        """
        Tests whether the newint object provides a __nonzero__ method that
        maps to __bool__ in case the user redefines __bool__ in a subclass of
        newint.
        """

        class EvenIsTrue(int):
            """
            An integer that evaluates to True if even.
            """
            def __bool__(self):
                return self % 2 == 0
            def __add__(self, other):
                val = super().__add__(other)
                return type(self)(val)

        k = EvenIsTrue(5)
        self.assertFalse(k)
        self.assertFalse(bool(k))
        self.assertTrue(k + 1)
        self.assertTrue(bool(k + 1))
        self.assertFalse(k + 2)

    def test_non_iterator(self):
        """
        The default behaviour of next(o) for a newobject o should be to raise a
        TypeError, as with the corresponding builtin object.
        """
        o = object()
        with self.assertRaises(TypeError):
            next(o)

    def test_bool_empty_object(self):
        """
        The default result of bool(newobject()) should be True, as with builtin
        objects.
        """
        o = object()
        self.assertTrue(bool(o))

        class MyClass(object):
            pass

        obj = MyClass()
        self.assertTrue(bool(obj))

    def test_isinstance_object_subclass(self):
        """
        This was failing before
        """
        class A(object):
            pass
        a = A()

        class B(object):
            pass
        b = B()

        self.assertFalse(isinstance(a, B))
        self.assertFalse(isinstance(b, A))
        self.assertTrue(isinstance(a, A))
        self.assertTrue(isinstance(b, B))

        class C(A):
            pass
        c = C()

        self.assertTrue(isinstance(c, A))
        self.assertFalse(isinstance(c, B))
        self.assertFalse(isinstance(a, C))
        self.assertFalse(isinstance(b, C))
        self.assertTrue(isinstance(c, C))

    @unittest.expectedFailure
    def test_types_isinstance_newobject(self):
        a = list()
        b = dict()
        c = set()
        self.assertTrue(isinstance(a, object))
        self.assertTrue(isinstance(b, object))
        self.assertTrue(isinstance(c, object))

        # Old-style class instances on Py2 should still report as an instance
        # of object as usual on Py2:
        class D:
            pass
        d = D()
        self.assertTrue(isinstance(d, object))

        e = object()
        self.assertTrue(isinstance(e, object))

        class F(object):
            pass
        f = F()
        self.assertTrue(isinstance(f, object))

        class G(F):
            pass
        g = G()
        self.assertTrue(isinstance(g, object))

        def h():
            return
        h = H()
        self.assertTrue(isinstance(h, object))

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>import uuid
import json
from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title}"

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Осенний'), ('2', 'Весенний'), ('3', 'Любой'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True, blank=True)
    semester = models.ForeignKey("Semester", null=True, blank=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

    def get_diagram(self):
        return list(self.diagram)

class WorkingType(models.Model):
    title = models.CharField(_("Название вида работы"), max_length=512)
    color = models.CharField(_("Цвет вида работы"), max_length=16, blank=True, null=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<commit_msg>diagram_display#3<commit_after>import uuid
import json
from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title}"

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Осенний'), ('2', 'Весенний'), ('3', 'Любой'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True, blank=True)
    semester = models.ForeignKey("Semester", null=True, blank=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

    def get_diagram(self):
        return list(map(list, zip(*list(self.diagram))))

class WorkingType(models.Model):
    title = models.CharField(_("Название вида работы"), max_length=512)
    color = models.CharField(_("Цвет вида работы"), max_length=16, blank=True, null=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<|endoftext|>


<commit_before># Copyright (c) 2011 OpenStack, LLC.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from nova import log as logging
from nova.scheduler import filters
from nova import utils

LOG = logging.getLogger(__name__)

class ComputeFilter(filters.BaseHostFilter):
    """HostFilter hard-coded to work with InstanceType records."""

    def _satisfies_extra_specs(self, capabilities, instance_type):
        """Check that the capabilities provided by the compute service
        satisfy the extra specs associated with the instance type"""
        if 'extra_specs' not in instance_type:
            return True

        # NOTE(lorinh): For now, we are just checking exact matching on the
        # values. Later on, we want to handle numerical
        # values so we can represent things like number of GPU cards
        for key, value in instance_type['extra_specs'].iteritems():
            if capabilities.get(key, None) != value:
                return False
        return True

    def host_passes(self, host_state, filter_properties):
        """Return a list of hosts that can create instance_type."""
        instance_type = filter_properties.get('instance_type')
        if host_state.topic != 'compute' or not instance_type:
            return True
        capabilities = host_state.capabilities
        service = host_state.service

        if not utils.service_is_up(service) or service['disabled']:
            return False
        if not capabilities.get("enabled", True):
            return False
        if not self._satisfies_extra_specs(capabilities, instance_type):
            return False
        return True
<commit_msg>Add additional logging to compute filter<commit_after># Copyright (c) 2011 OpenStack, LLC.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from nova import log as logging
from nova.scheduler import filters
from nova import utils

LOG = logging.getLogger(__name__)

class ComputeFilter(filters.BaseHostFilter):
    """HostFilter hard-coded to work with InstanceType records."""

    def _satisfies_extra_specs(self, capabilities, instance_type):
        """Check that the capabilities provided by the compute service
        satisfy the extra specs associated with the instance type"""
        if 'extra_specs' not in instance_type:
            return True

        # NOTE(lorinh): For now, we are just checking exact matching on the
        # values. Later on, we want to handle numerical
        # values so we can represent things like number of GPU cards
        for key, value in instance_type['extra_specs'].iteritems():
            if capabilities.get(key, None) != value:
                return False
        return True

    def host_passes(self, host_state, filter_properties):
        """Return a list of hosts that can create instance_type."""
        instance_type = filter_properties.get('instance_type')
        if host_state.topic != 'compute' or not instance_type:
            return True
        capabilities = host_state.capabilities
        service = host_state.service

        if not utils.service_is_up(service) or service['disabled']:
            LOG.debug(_("%(host_state)s is disabled or has not been "
                    "heard from in a while"), locals())
            return False
        if not capabilities.get("enabled", True):
            LOG.debug(_("%(host_state)s is disabled via capabs"), locals())
            return False
        if not self._satisfies_extra_specs(capabilities, instance_type):
            LOG.debug(_("%(host_state)s fails instance_type extra_specs "
                    "requirements"), locals())
            return False
        return True
<|endoftext|>


<commit_before>"""
    Copyright (c) 2015-2016 Raj Patel(raj454raj@gmail.com), StopStalk

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
"""

import datetime
import utilities

# ----------------------------------------------------------------------------
def pie_chart_helper():
    """
        Helper function for populating pie chart with different
        submission status of a problem
    """

    problem_link = request.post_vars["plink"]
    global_submissions = False
    if request.post_vars["global"] == "True":
        global_submissions = True

    stable = db.submission
    count = stable.id.count()
    query = (stable.problem_link == problem_link)

    # Show stats only for friends and logged-in user
    if global_submissions is False:
        if session.user_id:
            friends, cusfriends = utilities.get_friends(session.user_id)
            # The Original IDs of duplicate custom_friends
            custom_friends = []
            for cus_id in cusfriends:
                if cus_id[1] is None:
                    custom_friends.append(cus_id[0])
                else:
                    custom_friends.append(cus_id[1])

            query &= (stable.user_id.belongs(friends)) | \
                     (stable.custom_user_id.belongs(custom_friends)) | \
                     (stable.user_id == session.user_id)
        else:
            query &= (1 == 0)

    row = db(query).select(stable.status,
                           count,
                           groupby=stable.status)
    return dict(row=row)

# ----------------------------------------------------------------------------
def index():
    """
        The main problem page
    """

    if request.vars.has_key("pname") is False or \
       request.vars.has_key("plink") is False:

        # Disables direct entering of a URL
        session.flash = "Please click on a Problem Link"
        redirect(URL("default", "index"))

    global_submissions = False
    if request.vars.has_key("global"):
        if request.vars["global"] == "True":
            global_submissions = True

    stable = db.submission
    ptable = db.problem_tags
    problem_name = request.vars["pname"]
    problem_link = request.vars["plink"]

    query = (stable.problem_link == problem_link)

    cusfriends = []

    if global_submissions is False:
        if auth.is_logged_in():
            friends, cusfriends = utilities.get_friends(session.user_id)
            # The Original IDs of duplicate custom_friends
            custom_friends = []
            for cus_id in cusfriends:
                if cus_id[1] is None:
                    custom_friends.append(cus_id[0])
                else:
                    custom_friends.append(cus_id[1])

            query &= (stable.user_id.belongs(friends)) | \
                     (stable.custom_user_id.belongs(custom_friends)) | \
                     (stable.user_id == session.user_id)
        else:
            session.flash = "Login to view Friends' Submissions"
            new_vars = request.vars
            new_vars["global"] = True
            redirect(URL("problems", "index",
                         vars=new_vars))

    submissions = db(query).select(orderby=~stable.time_stamp)
    try:
        query = (ptable.problem_link == problem_link)
        all_tags = db(query).select(ptable.tags).first()
        if all_tags:
            all_tags = eval(all_tags["tags"])
        else:
            all_tags = []
        if all_tags != [] and all_tags != ['-']:
            tags = DIV(_class="center")
            for tag in all_tags:
                tags.append(DIV(A(tag,
                                  _href=URL("problems",
                                            "tag",
                                            vars={"q": tag, "page": 1}),
                                  _style="color: white;",
                                  _target="_blank"),
                                _class="chip"))
                tags.append(" ")
        else:
            tags = DIV("No tags available")
    except AttributeError:
        tags = DIV("No tags available")

    site = utilities.urltosite(problem_link).capitalize()
    problem_details = TABLE(_style="font-size: 140%;")
    tbody = TBODY()
    tbody.append(TR(TD(),
                    TD(STRONG("Problem Name:")),
                    TD(problem_name,
                       _id="problem_name"),
                    TD(_id="chart_div",
                       _style="width: 50%; height: 30%;",
                       _rowspan="4")))
    tbody.append(TR(TD(),
                    TD(STRONG("Site:")),
                    TD(site)))
    tbody.append(TR(TD(),
                    TD(STRONG("Problem Link:")),
                    TD(A(I(_class="fa fa-link"), " Link",
                         _href=problem_link,
                         _target="_blank"))))
    tbody.append(TR(TD(),
                    TD(STRONG("Tags:")),
                    TD(tags)))
    problem_details.append(tbody)

    table = utilities.render_table(submissions, cusfriends)
    switch = DIV(LABEL(H6("Friends' Submissions",
                          INPUT(_type="checkbox", _id="submission-switch"),
                          SPAN(_class="lever pink accent-3"),
                          "Global Submissions")),
                 _class="switch")
    div = TAG[""](H4("Recent Submissions"), switch, table)

    return dict(site=site,
                problem_details=problem_details,
                problem_name=problem_name,
                problem_link=problem_link,
                global_submissions=global_submissions,
                div=div)

# ----------------------------------------------------------------------------
def tag():
    """
        Tag search page
    """

    table = TABLE(_class="striped centered")
    thead = THEAD(TR(TH("Problem Name"),
                     TH("Problem URL"),
                     TH("Site"),
                     TH("Tags")))
    table.append(thead)

    # If URL does not have vars containing q
    # then remain at the search page and return
    # an empty table
    if request.vars.has_key("q") is False:
        return dict(table=table)

    q = request.vars["q"]
    try:
        curr_page = int(request.vars["page"])
    except:
        curr_page = 1
    PER_PAGE = current.PER_PAGE

    # Enables multiple space seperated tag search
    q = q.split(" ")
    ptable = db.problem_tags

    query = None
    for tag in q:
        if query is not None:
            # Decision to make & or |
            # & => Search for problem containing all these tags
            # | => Search for problem containing one of the tags
            query &= ptable.tags.contains(tag)
        else:
            query = ptable.tags.contains(tag)

    total_problems = db(query).count()
    total_pages = total_problems / PER_PAGE
    if total_problems % PER_PAGE != 0:
        total_pages = total_problems / PER_PAGE + 1

    if request.extension == "json":
        return dict(total_pages=total_pages)

    all_problems = db(query).select(ptable.problem_name,
                                    ptable.problem_link,
                                    ptable.tags,
                                    distinct=True,
                                    limitby=((curr_page - 1) * PER_PAGE,
                                             curr_page * PER_PAGE))

    tbody = TBODY()
    for problem in all_problems:

        tr = TR()

        if problem["problem_link"] in current.solved_problems:
            link_class = "solved-problem"
        elif problem["problem_link"] in current.unsolved_problems:
            link_class = "unsolved-problem"
        else:
            link_class = "unattempted-problem"

        link_title = (" ".join(link_class.split("-"))).capitalize()

        tr.append(TD(A(problem["problem_name"],
                       _href=URL("problems",
                                 "index",
                                 vars={"pname": problem["problem_name"],
                                       "plink": problem["problem_link"]}),
                       _class=link_class,
                       _title=link_title,
                       _target="_blank")))
        tr.append(TD(A(I(_class="fa fa-link"),
                       _href=problem["problem_link"],
                       _target="_blank")))
        tr.append(TD(utilities.urltosite(problem["problem_link"]).capitalize()))
        all_tags = eval(problem["tags"])
        td = TD()
        for tag in all_tags:
            td.append(DIV(A(tag,
                            _href=URL("problems",
                                      "tag",
                                      vars={"q": tag, "page": 1}),
                            _style="color: white;",
                            _target="_blank"),
                          _class="chip"))
            td.append(" ")
        tr.append(td)
        tbody.append(tr)

    table.append(tbody)
    return dict(table=table)

# ----------------------------------------------------------------------------
def _render_trending(caption, problems, flag):
    """
        Create trending table from the rows
    """

    table = TABLE(_class="striped centered")
    thead = THEAD(TR(TH("Problem"),
                     TH("Recent Submissions"),
                     TH(flag)))
    table.append(thead)
    tbody = TBODY()

    for problem in problems:
        tr = TR()

        if problem[0] in current.solved_problems:
            link_class = "solved-problem"
        elif problem[0] in current.unsolved_problems:
            link_class = "unsolved-problem"
        else:
            link_class = "unattempted-problem"

        link_title = (" ".join(link_class.split("-"))).capitalize()

        tr.append(TD(A(problem[1]["name"],
                       _href=URL("problems", "index",
                                 vars={"pname": problem[1]["name"],
                                       "plink": problem[0]}),
                       _class=link_class,
                       _title=link_title,
                       _target="_blank")))
        tr.append(TD(problem[1]["total_submissions"]))
        tr.append(TD(len(problem[1]["users"]) + \
                     len(problem[1]["custom_users"])))
        tbody.append(tr)

    table.append(tbody)
    table = DIV(H4(caption, _class="center"), table)

    return table

# ----------------------------------------------------------------------------
def _get_total_users(trending_problems,
                     friends,
                     cusfriends,
                     start_date,
                     end_date):

    if friends == []:
        friends = ["-1"]
    if cusfriends == []:
        cusfriends = ["-1"]

    for problem in trending_problems:
        sql = """
                 SELECT COUNT(id)
                 FROM `submission`
                 WHERE ((problem_link = '%s')
                   AND ((user_id IN (%s))
                     OR (custom_user_id IN (%s)))
                   AND  ((time_stamp >= '%s')
                     AND (time_stamp <= '%s')))
                 GROUP BY user_id, custom_user_id
              """ % (problem["submission"]["problem_link"],
                     ", ".join(friends),
                     ", ".join(cusfriends),
                     start_date,
                     end_date)

        res = db.executesql(sql)
        problem["unique"] = len(res)

    return trending_problems

# ----------------------------------------------------------------------------
def trending():
    """
        Show trending problems globally and among friends
        @ToDo: Needs lot of comments explaining the code
    """

    stable = db.submission

    today = datetime.datetime.today()
    # Consider submissions only after PAST_DAYS(customizable)
    # for trending problems
    start_date = str(today - datetime.timedelta(days=current.PAST_DAYS))
    query = (stable.time_stamp >= start_date)
    last_submissions = db(query).select(stable.problem_name,
                                        stable.problem_link,
                                        stable.user_id,
                                        stable.custom_user_id)

    if auth.is_logged_in():
        friends, cusfriends = utilities.get_friends(session.user_id)

        # The Original IDs of duplicate custom_friends
        custom_friends = []
        for cus_id in cusfriends:
            if cus_id[1] is None:
                custom_friends.append(cus_id[0])
            else:
                custom_friends.append(cus_id[1])

    problems_dict = {}
    friends_problems_dict = {}
    for submission in last_submissions:
        plink = submission.problem_link
        pname = submission.problem_name
        uid = submission.user_id
        cid = submission.custom_user_id

        # @ToDo: Improve this code
        if problems_dict.has_key(plink):
            problems_dict[plink]["total_submissions"] += 1
        else:
            problems_dict[plink] = {"name": pname,
                                    "total_submissions": 1,
                                    "users": set([]),
                                    "custom_users": set([])}

        if auth.is_logged_in() and \
           ((uid and uid in friends) or \
            (cid and cid in custom_friends)):

            if friends_problems_dict.has_key(plink):
                friends_problems_dict[plink]["total_submissions"] += 1
            else:
                friends_problems_dict[plink] = {"name": pname,
                                                "total_submissions": 1,
                                                "users": set([]),
                                                "custom_users": set([])}
            if uid:
                friends_problems_dict[plink]["users"].add(uid)
            else:
                friends_problems_dict[plink]["custom_users"].add(cid)

        if uid:
            problems_dict[plink]["users"].add(uid)
        else:
            problems_dict[plink]["custom_users"].add(cid)

    # Sort the rows according to the number of users
    # who solved the problem in last PAST_DAYS
    custom_compare = lambda x: (len(x[1]["users"]) + \
                                len(x[1]["custom_users"]),
                                x[1]["total_submissions"])

    global_trending = sorted(problems_dict.items(),
                             key=custom_compare,
                             reverse=True)

    global_table = _render_trending("Trending Globally",
                                    global_trending[:current.PROBLEMS_PER_PAGE],
                                    "Users")
    if auth.is_logged_in():
        friends_trending = sorted(friends_problems_dict.items(),
                                  key=custom_compare,
                                  reverse=True)

        friend_table = _render_trending("Trending among friends",
                                        friends_trending[:current.PROBLEMS_PER_PAGE],
                                        "Friends")

        div = DIV(DIV(friend_table, _class="col s6"),
                  DIV(global_table, _class="col s6"),
                  _class="row col s12")
    else:
        div = DIV(global_table, _class="center")

    return dict(div=div)

# ==============================================================================
<commit_msg>[Issue #38]: Step 4: Done<commit_after>"""
    Copyright (c) 2015-2016 Raj Patel(raj454raj@gmail.com), StopStalk

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
"""

import datetime
import utilities

# ----------------------------------------------------------------------------
def pie_chart_helper():
    """
        Helper function for populating pie chart with different
        submission status of a problem
    """

    problem_link = request.post_vars["plink"]
    global_submissions = False
    if request.post_vars["global"] == "True":
        global_submissions = True

    stable = db.submission
    count = stable.id.count()
    query = (stable.problem_link == problem_link)

    # Show stats only for friends and logged-in user
    if global_submissions is False:
        if session.user_id:
            friends, cusfriends = utilities.get_friends(session.user_id)
            # The Original IDs of duplicate custom_friends
            custom_friends = []
            for cus_id in cusfriends:
                if cus_id[1] is None:
                    custom_friends.append(cus_id[0])
                else:
                    custom_friends.append(cus_id[1])

            query &= (stable.user_id.belongs(friends)) | \
                     (stable.custom_user_id.belongs(custom_friends)) | \
                     (stable.user_id == session.user_id)
        else:
            query &= (1 == 0)

    row = db(query).select(stable.status,
                           count,
                           groupby=stable.status)
    return dict(row=row)

# ----------------------------------------------------------------------------
def index():
    """
        The main problem page
    """

    if request.vars.has_key("pname") is False or \
       request.vars.has_key("plink") is False:

        # Disables direct entering of a URL
        session.flash = "Please click on a Problem Link"
        redirect(URL("default", "index"))

    global_submissions = False
    if request.vars.has_key("global"):
        if request.vars["global"] == "True":
            global_submissions = True

    stable = db.submission
    ptable = db.problem_tags
    petable = db.problem_editorial

    problem_name = request.vars["pname"]
    problem_link = request.vars["plink"]

    query = (stable.problem_link == problem_link)
    cusfriends = []

    if global_submissions is False:
        if auth.is_logged_in():
            friends, cusfriends = utilities.get_friends(session.user_id)
            # The Original IDs of duplicate custom_friends
            custom_friends = []
            for cus_id in cusfriends:
                if cus_id[1] is None:
                    custom_friends.append(cus_id[0])
                else:
                    custom_friends.append(cus_id[1])

            query &= (stable.user_id.belongs(friends)) | \
                     (stable.custom_user_id.belongs(custom_friends)) | \
                     (stable.user_id == session.user_id)
        else:
            session.flash = "Login to view Friends' Submissions"
            new_vars = request.vars
            new_vars["global"] = True
            redirect(URL("problems", "index",
                         vars=new_vars))

    submissions = db(query).select(orderby=~stable.time_stamp)

    try:
        query = (ptable.problem_link == problem_link)
        all_tags = db(query).select(ptable.tags).first()
        if all_tags:
            all_tags = eval(all_tags["tags"])
        else:
            all_tags = []
        if all_tags != [] and all_tags != ['-']:
            tags = DIV(_class="center")
            for tag in all_tags:
                tags.append(DIV(A(tag,
                                  _href=URL("problems",
                                            "tag",
                                            vars={"q": tag, "page": 1}),
                                  _style="color: white;",
                                  _target="_blank"),
                                _class="chip"))
                tags.append(" ")
        else:
            tags = DIV("No tags available")
    except AttributeError:
        tags = DIV("No tags available")

    site = utilities.urltosite(problem_link).capitalize()
    problem_details = TABLE(_style="font-size: 140%;")
    tbody = TBODY()
    tbody.append(TR(TD(),
                    TD(STRONG("Problem Name:")),
                    TD(problem_name,
                       _id="problem_name"),
                    TD(_id="chart_div",
                       _style="width: 50%; height: 30%;",
                       _rowspan="4")))
    tbody.append(TR(TD(),
                    TD(STRONG("Site:")),
                    TD(site)))

    links = DIV(DIV(A(I(_class="fa fa-link"), " Problem",
                      _href=problem_link,
                      _style="color: black;"),
                    _class="chip lime accent-3"),
                _class="center")

    row = db(petable.problem_link == problem_link).select().first()
    if row and row.editorial_link:
        links.append(" ")
        links.append(DIV(A(I(_class="fa fa-book"), " Editorial",
                           _href=row.editorial_link,
                           _style="color: white;",
                           _target="_blank"),
                         _class="chip deep-purple darken-1"))
    tbody.append(TR(TD(),
                    TD(STRONG("Links:")),
                    links))
    tbody.append(TR(TD(),
                    TD(STRONG("Tags:")),
                    TD(tags)))
    problem_details.append(tbody)

    table = utilities.render_table(submissions, cusfriends)
    switch = DIV(LABEL(H6("Friends' Submissions",
                          INPUT(_type="checkbox", _id="submission-switch"),
                          SPAN(_class="lever pink accent-3"),
                          "Global Submissions")),
                 _class="switch")
    div = TAG[""](H4("Recent Submissions"), switch, table)

    return dict(site=site,
                problem_details=problem_details,
                problem_name=problem_name,
                problem_link=problem_link,
                global_submissions=global_submissions,
                div=div)

# ----------------------------------------------------------------------------
def tag():
    """
        Tag search page
    """

    table = TABLE(_class="striped centered")
    thead = THEAD(TR(TH("Problem Name"),
                     TH("Problem URL"),
                     TH("Site"),
                     TH("Tags")))
    table.append(thead)

    # If URL does not have vars containing q
    # then remain at the search page and return
    # an empty table
    if request.vars.has_key("q") is False:
        return dict(table=table)

    q = request.vars["q"]
    try:
        curr_page = int(request.vars["page"])
    except:
        curr_page = 1
    PER_PAGE = current.PER_PAGE

    # Enables multiple space seperated tag search
    q = q.split(" ")
    ptable = db.problem_tags

    query = None
    for tag in q:
        if query is not None:
            # Decision to make & or |
            # & => Search for problem containing all these tags
            # | => Search for problem containing one of the tags
            query &= ptable.tags.contains(tag)
        else:
            query = ptable.tags.contains(tag)

    total_problems = db(query).count()
    total_pages = total_problems / PER_PAGE
    if total_problems % PER_PAGE != 0:
        total_pages = total_problems / PER_PAGE + 1

    if request.extension == "json":
        return dict(total_pages=total_pages)

    all_problems = db(query).select(ptable.problem_name,
                                    ptable.problem_link,
                                    ptable.tags,
                                    distinct=True,
                                    limitby=((curr_page - 1) * PER_PAGE,
                                             curr_page * PER_PAGE))

    tbody = TBODY()
    for problem in all_problems:

        tr = TR()

        if problem["problem_link"] in current.solved_problems:
            link_class = "solved-problem"
        elif problem["problem_link"] in current.unsolved_problems:
            link_class = "unsolved-problem"
        else:
            link_class = "unattempted-problem"

        link_title = (" ".join(link_class.split("-"))).capitalize()

        tr.append(TD(A(problem["problem_name"],
                       _href=URL("problems",
                                 "index",
                                 vars={"pname": problem["problem_name"],
                                       "plink": problem["problem_link"]}),
                       _class=link_class,
                       _title=link_title,
                       _target="_blank")))
        tr.append(TD(A(I(_class="fa fa-link"),
                       _href=problem["problem_link"],
                       _target="_blank")))
        tr.append(TD(utilities.urltosite(problem["problem_link"]).capitalize()))
        all_tags = eval(problem["tags"])
        td = TD()
        for tag in all_tags:
            td.append(DIV(A(tag,
                            _href=URL("problems",
                                      "tag",
                                      vars={"q": tag, "page": 1}),
                            _style="color: white;",
                            _target="_blank"),
                          _class="chip"))
            td.append(" ")
        tr.append(td)
        tbody.append(tr)

    table.append(tbody)
    return dict(table=table)

# ----------------------------------------------------------------------------
def _render_trending(caption, problems, flag):
    """
        Create trending table from the rows
    """

    table = TABLE(_class="striped centered")
    thead = THEAD(TR(TH("Problem"),
                     TH("Recent Submissions"),
                     TH(flag)))
    table.append(thead)
    tbody = TBODY()

    for problem in problems:
        tr = TR()

        if problem[0] in current.solved_problems:
            link_class = "solved-problem"
        elif problem[0] in current.unsolved_problems:
            link_class = "unsolved-problem"
        else:
            link_class = "unattempted-problem"

        link_title = (" ".join(link_class.split("-"))).capitalize()

        tr.append(TD(A(problem[1]["name"],
                       _href=URL("problems", "index",
                                 vars={"pname": problem[1]["name"],
                                       "plink": problem[0]}),
                       _class=link_class,
                       _title=link_title,
                       _target="_blank")))
        tr.append(TD(problem[1]["total_submissions"]))
        tr.append(TD(len(problem[1]["users"]) + \
                     len(problem[1]["custom_users"])))
        tbody.append(tr)

    table.append(tbody)
    table = DIV(H4(caption, _class="center"), table)

    return table

# ----------------------------------------------------------------------------
def _get_total_users(trending_problems,
                     friends,
                     cusfriends,
                     start_date,
                     end_date):

    if friends == []:
        friends = ["-1"]
    if cusfriends == []:
        cusfriends = ["-1"]

    for problem in trending_problems:
        sql = """
                 SELECT COUNT(id)
                 FROM `submission`
                 WHERE ((problem_link = '%s')
                   AND ((user_id IN (%s))
                     OR (custom_user_id IN (%s)))
                   AND  ((time_stamp >= '%s')
                     AND (time_stamp <= '%s')))
                 GROUP BY user_id, custom_user_id
              """ % (problem["submission"]["problem_link"],
                     ", ".join(friends),
                     ", ".join(cusfriends),
                     start_date,
                     end_date)

        res = db.executesql(sql)
        problem["unique"] = len(res)

    return trending_problems

# ----------------------------------------------------------------------------
def trending():
    """
        Show trending problems globally and among friends
        @ToDo: Needs lot of comments explaining the code
    """

    stable = db.submission

    today = datetime.datetime.today()
    # Consider submissions only after PAST_DAYS(customizable)
    # for trending problems
    start_date = str(today - datetime.timedelta(days=current.PAST_DAYS))
    query = (stable.time_stamp >= start_date)
    last_submissions = db(query).select(stable.problem_name,
                                        stable.problem_link,
                                        stable.user_id,
                                        stable.custom_user_id)

    if auth.is_logged_in():
        friends, cusfriends = utilities.get_friends(session.user_id)

        # The Original IDs of duplicate custom_friends
        custom_friends = []
        for cus_id in cusfriends:
            if cus_id[1] is None:
                custom_friends.append(cus_id[0])
            else:
                custom_friends.append(cus_id[1])

    problems_dict = {}
    friends_problems_dict = {}
    for submission in last_submissions:
        plink = submission.problem_link
        pname = submission.problem_name
        uid = submission.user_id
        cid = submission.custom_user_id

        # @ToDo: Improve this code
        if problems_dict.has_key(plink):
            problems_dict[plink]["total_submissions"] += 1
        else:
            problems_dict[plink] = {"name": pname,
                                    "total_submissions": 1,
                                    "users": set([]),
                                    "custom_users": set([])}

        if auth.is_logged_in() and \
           ((uid and uid in friends) or \
            (cid and cid in custom_friends)):

            if friends_problems_dict.has_key(plink):
                friends_problems_dict[plink]["total_submissions"] += 1
            else:
                friends_problems_dict[plink] = {"name": pname,
                                                "total_submissions": 1,
                                                "users": set([]),
                                                "custom_users": set([])}
            if uid:
                friends_problems_dict[plink]["users"].add(uid)
            else:
                friends_problems_dict[plink]["custom_users"].add(cid)

        if uid:
            problems_dict[plink]["users"].add(uid)
        else:
            problems_dict[plink]["custom_users"].add(cid)

    # Sort the rows according to the number of users
    # who solved the problem in last PAST_DAYS
    custom_compare = lambda x: (len(x[1]["users"]) + \
                                len(x[1]["custom_users"]),
                                x[1]["total_submissions"])

    global_trending = sorted(problems_dict.items(),
                             key=custom_compare,
                             reverse=True)

    global_table = _render_trending("Trending Globally",
                                    global_trending[:current.PROBLEMS_PER_PAGE],
                                    "Users")
    if auth.is_logged_in():
        friends_trending = sorted(friends_problems_dict.items(),
                                  key=custom_compare,
                                  reverse=True)

        friend_table = _render_trending("Trending among friends",
                                        friends_trending[:current.PROBLEMS_PER_PAGE],
                                        "Friends")

        div = DIV(DIV(friend_table, _class="col s6"),
                  DIV(global_table, _class="col s6"),
                  _class="row col s12")
    else:
        div = DIV(global_table, _class="center")

    return dict(div=div)

# ==============================================================================
<|endoftext|>


<commit_before>from django.conf import settings

PEOPLE_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_PEOPLE_DEFAULT_DIRECTORY',
    'people')

PEOPLE_DEFAULT_PICTURE = PEOPLE_DEFAULT_DIRECTORY + '/' + getattr(
    settings,
    'ACADEMIC_PEOPLE_DEFAULT_PICTURE',
    'default.jpg')

SPONSORS_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_SPONSORS_DEFAULT_DIRECTORY',
    'sponsors')

DOWNLOADS_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_DOWNLOADS_DEFAULT_DIRECTORY',
    'downloads')

PUBLISHING_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_PUBLISHING_DEFAULT_DIRECTORY',
    'publishing')

TINYMCE_MCE_JS = getattr(
    settings,
    'ACADEMIC_TINYMCE_JS',
    None)

TINYMCE_SETUP_JS = getattr(
    settings,
    'ACADEMIC_PEOPLE_DEFAULT_PICTURE',
    None)
<commit_msg>Fixed wrong setting ACADEMIC_TINYMCE_SETUP_JS was ACADEMIC_PEOPLE_DEFAULT_PICTURE<commit_after>from django.conf import settings

PEOPLE_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_PEOPLE_DEFAULT_DIRECTORY',
    'people')

PEOPLE_DEFAULT_PICTURE = PEOPLE_DEFAULT_DIRECTORY + '/' + getattr(
    settings,
    'ACADEMIC_PEOPLE_DEFAULT_PICTURE',
    'default.jpg')

SPONSORS_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_SPONSORS_DEFAULT_DIRECTORY',
    'sponsors')

DOWNLOADS_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_DOWNLOADS_DEFAULT_DIRECTORY',
    'downloads')

PUBLISHING_DEFAULT_DIRECTORY = getattr(
    settings,
    'ACADEMIC_PUBLISHING_DEFAULT_DIRECTORY',
    'publishing')

TINYMCE_MCE_JS = getattr(
    settings,
    'ACADEMIC_TINYMCE_JS',
    None)

TINYMCE_SETUP_JS = getattr(
    settings,
    'ACADEMIC_TINYMCE_SETUP_JS',
    None)
<|endoftext|>


<commit_before>import warnings
import numpy as np
from .num import peaks, numutils

def insul_diamond(mat, window=10, ignore_diags=2):
    """
    Calculates the insulation score of a Hi-C interaction matrix.

    Parameters
    ----------
    mat : numpy.array
        A dense square matrix of Hi-C interaction frequencies.
        May contain nans, e.g. in rows/columns excluded from the analysis.

    window : int
        The width of the window to calculate the insulation score.

    ignore_diags : int
        If > 0, the interactions at separations <= `ignore_diags` are ignored
        when calculating the insulation score.

    """
    if (ignore_diags):
        mat = mat.copy()
        for i in range(-ignore_diags, ignore_diags+1):
            numutils.set_diag(mat, np.nan, i)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")

        N = mat.shape[0]
        bad_bins = (np.nansum(mat, axis=0) == 0)
        score = np.nan * np.ones(N)
        norm = np.zeros(N)
        for i in range(0, N):
            lo = max(0, i-window)
            hi = min(i+window, N)
            # nanmean of interactions to reduce the effect of bad bins
            score[i] = np.nanmean(mat[lo:i, i:hi])
            norm[i] = (~np.isnan(mat[lo:i, i:hi])).sum()
        score = score / np.where(norm>0, norm, 1)
        score /= np.nanmedian(score)
    return score

def find_insulating_boundaries(
    c,
    window_bp = 100000,
    ignore_diags = 2,
    max_bad_bins = 2):
    '''Calculate insulating diamond scores and find boundaries.

    Parameters
    ----------
    c : cooler.Cooler
        A cooler with balanced Hi-C data.
    window_bp : int
        The size of the sliding diamond window used to calculate the insulation
        score.
    ignore_diags : int
        The number of diagonals in the Hi-C map which should be ignored due
        to contamination with Hi-C artifacts.
    max_bad_bins : int
        The maximal allowed number of bad bins in a sliding window.
    '''

    bin_size = c.info['bin-size']
    window_bins = window_bp // bin_size

    if (window_bp % bin_size !=0):
        raise Exception(
            'The window size ({}) has to be a multiple of the bin size {}'.format(
                window_bp, bin_size))

    ins_chrom_tables = []
    for chrom in c.chroms()[:]['name']:
        ins_chrom = c.bins().fetch(chrom)[['chrom', 'start', 'end']]
        is_bad_bin = np.isnan(c.bins().fetch(chrom)['weight'].values)
        bad_bins_u = is_bad_bin.astype(np.int)
        bad_bins_d = is_bad_bin.astype(np.int)
        for i in range(1, window_bins):
            bad_bins_u[i:] += is_bad_bin[:-i]
            bad_bins_u[:i] += 1

            bad_bins_d[:-i] += is_bad_bin[i:]
            bad_bins_u[-i:] += 1

        ins_chrom['n_bad_bins_upstream_{}'.format(window_bp)] = bad_bins_u
        ins_chrom['n_bad_bins_downstream_{}'.format(window_bp)] = bad_bins_d

        m=c.matrix(balance=True).fetch(chrom)

        with warnings.catch_warnings():
            warnings.simplefilter("ignore", RuntimeWarning)

            ins_track = np.log2(
                cooltools.insulation.insul_diamond(m, window_bins, ignore_diags))

        ins_track[is_bad_bin] = np.nan
        ins_track[bad_bins_u > max_bad_bins] = np.nan
        ins_track[bad_bins_d > max_bad_bins] = np.nan

        ins_chrom['log2_insulation_score_{}'.format(window_bp)] = ins_track

        poss, proms = cooltools.num.peaks.find_peak_prominence(-ins_track)
        ins_prom_track = np.zeros_like(ins_track) * np.nan
        ins_prom_track[poss] = proms
        ins_chrom['boundary_strength_{}'.format(window_bp)] = ins_prom_track

        ins_chrom_tables.append(ins_chrom)

    ins_chrom_table = pd.concat(ins_chrom_tables)
    return ins_chrom_table

<commit_msg>insulation.py: autodetect ignore_diags from cooler; update docstrings<commit_after>import warnings
import numpy as np
import pandas as pd
from .num import peaks, numutils

def insul_diamond(mat, window=10, ignore_diags=2):
    """
    Calculates the insulation score of a Hi-C interaction matrix.

    Parameters
    ----------
    mat : numpy.array
        A dense square matrix of Hi-C interaction frequencies.
        May contain nans, e.g. in rows/columns excluded from the analysis.

    window : int
        The width of the window to calculate the insulation score.

    ignore_diags : int
        If > 0, the interactions at separations <= `ignore_diags` are ignored
        when calculating the insulation score. Typically, a few first diagonals
        of the Hi-C map should be ignored due to contamination with Hi-C
        artifacts.

    """
    if (ignore_diags):
        mat = mat.copy()
        for i in range(-ignore_diags, ignore_diags+1):
            numutils.set_diag(mat, np.nan, i)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")

        N = mat.shape[0]
        bad_bins = (np.nansum(mat, axis=0) == 0)
        score = np.nan * np.ones(N)
        norm = np.zeros(N)
        for i in range(0, N):
            lo = max(0, i-window)
            hi = min(i+window, N)
            # nanmean of interactions to reduce the effect of bad bins
            score[i] = np.nanmean(mat[lo:i, i:hi])
            norm[i] = (~np.isnan(mat[lo:i, i:hi])).sum()
        score = score / np.where(norm>0, norm, 1)
        score /= np.nanmedian(score)
    return score

def find_insulating_boundaries(
    c,
    window_bp = 100000,
    max_bad_bins = 2):
    '''Calculate the diamond insulation scores and call insulating boundaries.

    Parameters
    ----------
    c : cooler.Cooler
        A cooler with balanced Hi-C data.

    window_bp : int
        The size of the sliding diamond window used to calculate the insulation
        score.

    max_bad_bins : int
        The maximal allowed number of bad bins on each side of a sliding window.

    Returns
    -------
    ins_table : pandas.DataFrame
        A table containing the insulation scores of the genomic bins and
        the insulating boundary strengths.
    '''

    bin_size = c.info['bin-size']
    ignore_diags = c._load_attrs('/bins/weight')['ignore_diags']
    window_bins = window_bp // bin_size

    if (window_bp % bin_size !=0):
        raise Exception(
            'The window size ({}) has to be a multiple of the bin size {}'.format(
                window_bp, bin_size))

    ins_chrom_tables = []
    for chrom in c.chroms()[:]['name']:
        ins_chrom = c.bins().fetch(chrom)[['chrom', 'start', 'end']]
        is_bad_bin = np.isnan(c.bins().fetch(chrom)['weight'].values)
        bad_bins_u = is_bad_bin.astype(np.int)
        bad_bins_d = is_bad_bin.astype(np.int)
        for i in range(1, window_bins):
            bad_bins_u[i:] += is_bad_bin[:-i]
            bad_bins_u[:i] += 1

            bad_bins_d[:-i] += is_bad_bin[i:]
            bad_bins_u[-i:] += 1

        ins_chrom['n_bad_bins_upstream_{}'.format(window_bp)] = bad_bins_u
        ins_chrom['n_bad_bins_downstream_{}'.format(window_bp)] = bad_bins_d

        m=c.matrix(balance=True).fetch(chrom)

        with warnings.catch_warnings():
            warnings.simplefilter("ignore", RuntimeWarning)

            ins_track = np.log2(
                insul_diamond(m, window_bins, ignore_diags))

        ins_track[is_bad_bin] = np.nan
        ins_track[bad_bins_u > max_bad_bins] = np.nan
        ins_track[bad_bins_d > max_bad_bins] = np.nan

        ins_chrom['log2_insulation_score_{}'.format(window_bp)] = ins_track

        poss, proms = peaks.find_peak_prominence(-ins_track)
        ins_prom_track = np.zeros_like(ins_track) * np.nan
        ins_prom_track[poss] = proms
        ins_chrom['boundary_strength_{}'.format(window_bp)] = ins_prom_track

        ins_chrom_tables.append(ins_chrom)

    ins_table = pd.concat(ins_chrom_tables)
    return ins_table

<|endoftext|>


<commit_before>import sys
from collections import OrderedDict

from wa import ComplexCommand, SubCommand, pluginloader
from wa.framework.target.descriptor import get_target_descriptions

from wa.utils.serializer import yaml

class CreateAgendaSubcommand(SubCommand):

    name = 'agenda'
    description = """
    Create an agenda with the specified extensions enabled. And parameters set
    to their default values.
    """

    def initialize(self, context):
        self.parser.add_argument('plugins', nargs='+',
                                 help='Plugins to be added to the agendas')
        self.parser.add_argument('-i', '--iterations', type=int, default=1,
                                 help='Sets the number of iterations for all workloads')
        self.parser.add_argument('-o', '--output', metavar='FILE',
                                 help='Output file. If not specfied, STDOUT will be used instead.')

    def execute(self, state, args):
        agenda = OrderedDict()
        agenda['config'] = OrderedDict(instrumentation=[], result_processors=[])
        agenda['global'] = OrderedDict(iterations=args.iterations)
        agenda['workloads'] = []
        target_desc = None

        targets = {td.name: td for td in get_target_descriptions()}

        for name in args.plugins:
            if name in targets:
                if target_desc is not None:
                    raise ConfigError('Specifying multiple devices: {} and {}'.format(target_desc.name, name))
                target_desc = targets[name]
                agenda['config']['device'] = name
                agenda['config']['device_config'] = target_desc.get_default_config()
                continue

            extcls = pluginloader.get_plugin_class(name)
            config = pluginloader.get_default_config(name)

            if extcls.kind == 'workload':
                entry = OrderedDict()
                entry['name'] = extcls.name
                if name != extcls.name:
                    entry['label'] = name
                entry['params'] = config
                agenda['workloads'].append(entry)
            else:
                if extcls.kind == 'instrument':
                    agenda['config']['instrumentation'].append(name)
                if extcls.kind == 'result_processor':
                    agenda['config']['result_processors'].append(name)
                agenda['config'][name] = config

        if args.output:
            wfh = open(args.output, 'w')
        else:
            wfh = sys.stdout
        yaml.dump(agenda, wfh, indent=4, default_flow_style=False)
        if args.output:
            wfh.close()

class CreateCommand(ComplexCommand):

    name = 'create'
    description = '''
    Used to create various WA-related objects (see positional arguments list
    for what objects may be created).\n\nUse "wa create <object> -h" for
    object-specific arguments.
    '''
    subcmd_classes = [
        #CreateWorkloadSubcommand,
        #CreatePackageSubcommand,
        CreateAgendaSubcommand,
    ]
<commit_msg>CreateCommand: Fix missing import<commit_after>import sys
from collections import OrderedDict

from wa import ComplexCommand, SubCommand, pluginloader
from wa.framework.target.descriptor import get_target_descriptions
from wa.framework.exception import ConfigError

from wa.utils.serializer import yaml

class CreateAgendaSubcommand(SubCommand):

    name = 'agenda'
    description = """
    Create an agenda with the specified extensions enabled. And parameters set
    to their default values.
    """

    def initialize(self, context):
        self.parser.add_argument('plugins', nargs='+',
                                 help='Plugins to be added to the agendas')
        self.parser.add_argument('-i', '--iterations', type=int, default=1,
                                 help='Sets the number of iterations for all workloads')
        self.parser.add_argument('-o', '--output', metavar='FILE',
                                 help='Output file. If not specfied, STDOUT will be used instead.')

    def execute(self, state, args):
        agenda = OrderedDict()
        agenda['config'] = OrderedDict(instrumentation=[], result_processors=[])
        agenda['global'] = OrderedDict(iterations=args.iterations)
        agenda['workloads'] = []
        target_desc = None

        targets = {td.name: td for td in get_target_descriptions()}

        for name in args.plugins:
            if name in targets:
                if target_desc is not None:
                    raise ConfigError('Specifying multiple devices: {} and {}'.format(target_desc.name, name))
                target_desc = targets[name]
                agenda['config']['device'] = name
                agenda['config']['device_config'] = target_desc.get_default_config()
                continue

            extcls = pluginloader.get_plugin_class(name)
            config = pluginloader.get_default_config(name)

            if extcls.kind == 'workload':
                entry = OrderedDict()
                entry['name'] = extcls.name
                if name != extcls.name:
                    entry['label'] = name
                entry['params'] = config
                agenda['workloads'].append(entry)
            else:
                if extcls.kind == 'instrument':
                    agenda['config']['instrumentation'].append(name)
                if extcls.kind == 'result_processor':
                    agenda['config']['result_processors'].append(name)
                agenda['config'][name] = config

        if args.output:
            wfh = open(args.output, 'w')
        else:
            wfh = sys.stdout
        yaml.dump(agenda, wfh, indent=4, default_flow_style=False)
        if args.output:
            wfh.close()

class CreateCommand(ComplexCommand):

    name = 'create'
    description = '''
    Used to create various WA-related objects (see positional arguments list
    for what objects may be created).\n\nUse "wa create <object> -h" for
    object-specific arguments.
    '''
    subcmd_classes = [
        #CreateWorkloadSubcommand,
        #CreatePackageSubcommand,
        CreateAgendaSubcommand,
    ]
<|endoftext|>