<commit_before>import test_helper
from mockredis import MockRedis
from cartodb_services.metrics import UserMetricsService
from cartodb_services.metrics import GeocoderConfig
from datetime import datetime, date
from unittest import TestCase
from mock import Mock
from nose.tools import assert_raises
from datetime import timedelta
from freezegun import freeze_time

class TestUserService(TestCase):

    NOKIA_GEOCODER = 'geocoder_here'

    def setUp(self):
        self.redis_conn = MockRedis()

    def test_user_used_quota_for_a_day(self):
        us = self.__build_user_service('test_user')
        test_helper.increment_service_uses(self.redis_conn, 'test_user',
                                           amount=400)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400

    def test_org_used_quota_for_a_day(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        test_helper.increment_service_uses(self.redis_conn, 'test_user',
                                           orgname='test_org',
                                           amount=400)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400

    def test_user_not_amount_in_used_quota_for_month_should_be_0(self):
        us = self.__build_user_service('test_user')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 0

    def test_org_not_amount_in_used_quota_for_month_should_be_0(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 0

    def test_should_increment_user_used_quota_for_one_date(self):
        us = self.__build_user_service('test_user')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    def test_should_increment_org_used_quota(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    def test_should_increment_user_used_quota_in_for_multiples_dates(self):
        two_days_ago = datetime.today() - timedelta(days=2)
        one_day_ago = datetime.today() - timedelta(days=1)
        one_day_after = datetime.today() + timedelta(days=1)
        us = self.__build_user_service('test_user', end_date=one_day_ago)
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses',
                                 date=date.today())
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=one_day_ago)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=two_days_ago)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=one_day_after)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    @freeze_time("2015-06-01")
    def test_should_account_for_zero_paddded_keys(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '01', 400)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 400

    @freeze_time("2015-06-01")
    def test_should_account_for_wrongly_stored_non_padded_keys(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '1', 400)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 400

    @freeze_time("2015-06-01")
    def test_should_sum_amounts_from_both_key_formats(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506',  '1', 400)
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '01', 300)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 700

    @freeze_time("2015-06-15")
    def test_should_not_request_redis_twice_when_unneeded(self):
        class MockRedisWithCounter(MockRedis):
            def __init__(self):
                super(MockRedisWithCounter, self).__init__()
                self._zscore_counter = 0
            def zscore(self, *args):
                print args
                self._zscore_counter += 1
                return super(MockRedisWithCounter, self).zscore(*args)
            def zscore_counter(self):
                return self._zscore_counter
        self.redis_conn = MockRedisWithCounter()
        us = self.__build_user_service('test_user', end_date=date.today())
        us.used_quota(self.NOKIA_GEOCODER, date(2015, 6, 15))

        #('user:test_user:geocoder_here:success_responses:201506', 15)
        #('user:test_user:geocoder_here:empty_responses:201506', 15)
        #('user:test_user:geocoder_cache:success_responses:201506', 15)
        assert self.redis_conn.zscore_counter() == 3

    def test_should_write_zero_padded_dates(self):
        us = self.__build_user_service('test_user')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses',
                                 date=date(2015,6,1))
        assert self.redis_conn.zscore('user:test_user:geocoder_here:success_responses:201506', '01') == 1
        assert self.redis_conn.zscore('user:test_user:geocoder_here:success_responses:201506',  '1') == None

    def __build_user_service(self, username, quota=100, service='heremaps',
                             orgname=None, soft_limit=False,
                             end_date=date.today()):
        test_helper.build_redis_user_config(self.redis_conn, username,
                                            quota=quota, service=service,
                                            soft_limit=soft_limit,
                                            end_date=end_date)
        if orgname:
            test_helper.build_redis_org_config(self.redis_conn, orgname,
                                               quota=quota, end_date=end_date)
        plpy_mock = test_helper.build_plpy_mock()
        geocoder_config = GeocoderConfig(self.redis_conn, plpy_mock,
                                         username, orgname)
        return UserMetricsService(geocoder_config, self.redis_conn)
<commit_msg>Add test_orgs_should_write_zero_padded_dates #204<commit_after>import test_helper
from mockredis import MockRedis
from cartodb_services.metrics import UserMetricsService
from cartodb_services.metrics import GeocoderConfig
from datetime import datetime, date
from unittest import TestCase
from mock import Mock
from nose.tools import assert_raises
from datetime import timedelta
from freezegun import freeze_time

class TestUserService(TestCase):

    NOKIA_GEOCODER = 'geocoder_here'

    def setUp(self):
        self.redis_conn = MockRedis()

    def test_user_used_quota_for_a_day(self):
        us = self.__build_user_service('test_user')
        test_helper.increment_service_uses(self.redis_conn, 'test_user',
                                           amount=400)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400

    def test_org_used_quota_for_a_day(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        test_helper.increment_service_uses(self.redis_conn, 'test_user',
                                           orgname='test_org',
                                           amount=400)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 400

    def test_user_not_amount_in_used_quota_for_month_should_be_0(self):
        us = self.__build_user_service('test_user')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 0

    def test_org_not_amount_in_used_quota_for_month_should_be_0(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 0

    def test_should_increment_user_used_quota_for_one_date(self):
        us = self.__build_user_service('test_user')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    def test_should_increment_org_used_quota(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    def test_should_increment_user_used_quota_in_for_multiples_dates(self):
        two_days_ago = datetime.today() - timedelta(days=2)
        one_day_ago = datetime.today() - timedelta(days=1)
        one_day_after = datetime.today() + timedelta(days=1)
        us = self.__build_user_service('test_user', end_date=one_day_ago)
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses',
                                 date=date.today())
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 1
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=one_day_ago)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=two_days_ago)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'empty_responses',
                                 date=one_day_after)
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2
        us.increment_service_use(self.NOKIA_GEOCODER, 'fail_responses')
        assert us.used_quota(self.NOKIA_GEOCODER, date.today()) == 2

    @freeze_time("2015-06-01")
    def test_should_account_for_zero_paddded_keys(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '01', 400)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 400

    @freeze_time("2015-06-01")
    def test_should_account_for_wrongly_stored_non_padded_keys(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '1', 400)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 400

    @freeze_time("2015-06-01")
    def test_should_sum_amounts_from_both_key_formats(self):
        us = self.__build_user_service('test_user')
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506',  '1', 400)
        self.redis_conn.zincrby('user:test_user:geocoder_here:success_responses:201506', '01', 300)
        assert us.used_quota(self.NOKIA_GEOCODER, date(2015, 6,1)) == 700

    @freeze_time("2015-06-15")
    def test_should_not_request_redis_twice_when_unneeded(self):
        class MockRedisWithCounter(MockRedis):
            def __init__(self):
                super(MockRedisWithCounter, self).__init__()
                self._zscore_counter = 0
            def zscore(self, *args):
                print args
                self._zscore_counter += 1
                return super(MockRedisWithCounter, self).zscore(*args)
            def zscore_counter(self):
                return self._zscore_counter
        self.redis_conn = MockRedisWithCounter()
        us = self.__build_user_service('test_user', end_date=date.today())
        us.used_quota(self.NOKIA_GEOCODER, date(2015, 6, 15))

        #('user:test_user:geocoder_here:success_responses:201506', 15)
        #('user:test_user:geocoder_here:empty_responses:201506', 15)
        #('user:test_user:geocoder_cache:success_responses:201506', 15)
        assert self.redis_conn.zscore_counter() == 3

    def test_should_write_zero_padded_dates(self):
        us = self.__build_user_service('test_user')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses',
                                 date=date(2015,6,1))
        assert self.redis_conn.zscore('user:test_user:geocoder_here:success_responses:201506', '01') == 1
        assert self.redis_conn.zscore('user:test_user:geocoder_here:success_responses:201506',  '1') == None

    def test_orgs_should_write_zero_padded_dates(self):
        us = self.__build_user_service('test_user', orgname='test_org')
        us.increment_service_use(self.NOKIA_GEOCODER, 'success_responses',
                                 amount=400,
                                 date=date(2015,6,1))
        assert self.redis_conn.zscore('org:test_org:geocoder_here:success_responses:201506', '01') == 400
        assert self.redis_conn.zscore('org:test_org:geocoder_here:success_responses:201506',  '1') == None

    def __build_user_service(self, username, quota=100, service='heremaps',
                             orgname=None, soft_limit=False,
                             end_date=date.today()):
        test_helper.build_redis_user_config(self.redis_conn, username,
                                            quota=quota, service=service,
                                            soft_limit=soft_limit,
                                            end_date=end_date)
        if orgname:
            test_helper.build_redis_org_config(self.redis_conn, orgname,
                                               quota=quota, end_date=end_date)
        plpy_mock = test_helper.build_plpy_mock()
        geocoder_config = GeocoderConfig(self.redis_conn, plpy_mock,
                                         username, orgname)
        return UserMetricsService(geocoder_config, self.redis_conn)
<|endoftext|>


<commit_before># Python imports.
import numpy as np

# Other imports.
from simple_rl.abstraction.state_abs.StateAbstractionClass import StateAbstraction

class ProbStateAbstraction(StateAbstraction):

    def __init__(self, abstr_dist):
        '''
        Args:
            abstr_dist (dict): Represents Pr(s_phi | phi)
                Key: state
                Val: dict
                    Key: s_phi (simple_rl.State)
                    Val: probability (float)
        '''
        self.abstr_dist = abstr_dist

    def phi(self, state):
        '''
        Args:
            state (State)

        Returns:
            state (State)
        '''

        sampled_s_phi_index = np.random.multinomial(1, self.abstr_dist[state].values()).tolist().index(1)
        abstr_state = self.abstr_dist[state].keys()[sampled_s_phi_index]

        # abstr_state = State(self._phi[state])
        # abstr_state.set_terminal(state.is_terminal())

        return abstr_state
<commit_msg>Adding prob to crisp state abstr class<commit_after># Python imports.
import numpy as np

# Other imports.
from simple_rl.abstraction.state_abs.StateAbstractionClass import StateAbstraction

class ProbStateAbstraction(StateAbstraction):

    def __init__(self, abstr_dist):
        '''
        Args:
            abstr_dist (dict): Represents Pr(s_phi | phi)
                Key: state
                Val: dict
                    Key: s_phi (simple_rl.State)
                    Val: probability (float)
        '''
        self.abstr_dist = abstr_dist

    def phi(self, state):
        '''
        Args:
            state (State)

        Returns:
            state (State)
        '''

        sampled_s_phi_index = np.random.multinomial(1, self.abstr_dist[state].values()).tolist().index(1)
        abstr_state = self.abstr_dist[state].keys()[sampled_s_phi_index]

        # abstr_state = State(self._phi[state])
        # abstr_state.set_terminal(state.is_terminal())

        return abstr_state

def convert_prob_sa_to_sa(prob_sa):
    new_phi = {}

    for s_g in prob_sa.abstr_dist.keys():

        new_phi[s_g] = prob_sa.abstr_dist[s_g].keys()[prob_sa.abstr_dist[s_g].values().index(max(prob_sa.abstr_dist[s_g].values()))]

    return StateAbstraction(new_phi)
<|endoftext|>


<commit_before>import json
import re
from optparse import make_option

from django.conf import settings
from django.contrib.auth import get_user_model

from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ValidationError

import sys

from devilry.apps.core.models import PeriodTag, RelatedStudent

class RelatedBaseCommand(BaseCommand):
    args = '<subject short name> <period short name>'

    def add_arguments(self, parser):
        parser.add_argument(
            '--clearall',
            action='store_true',
            dest='clearall',
            default=False,
            help='Alias for for --deactivate-missing for devilry 2.x compatibility.'
        )
        parser.add_argument(
            '--deactivate-missing',
            action='store_true',
            dest='deactivate_missing',
            default=False,
            help='Set all RelatedExaminers as active=False before adding '
                 'and updating the provided users. This is useful when importing a '
                 'complete list of users, since it means that the missing '
                 'users will be deactivated.'
        )
        parser.add_argument(
            '--tag-prefix',
            dest='tag_prefix',
            default=settings.DEVILRY_SYNCSYSTEM_SHORTNAME,
            help='The prefix to use for imported tags. Defaults '
                 'to the value of the DEVILRY_SYNCSYSTEM_SHORTNAME setting '
                 '(which is {!r}).'.format(settings.DEVILRY_SYNCSYSTEM_SHORTNAME)
        )

    @property
    def user_type(self):
        raise NotImplementedError()

    @property
    def related_user_model_class(self):
        raise NotImplementedError()

    def get_subject_and_period(self):
        """ Get the subject and period from args """
        from devilry.apps.core.models import Subject, Period
        if len(self.args) != 2:
            raise CommandError('Subject and period is required. See --help.')
        subject_short_name = self.args[0]
        period_short_name = self.args[1]
        # Get the subject and period
        try:
            self.subject = Subject.objects.get(short_name=subject_short_name)
        except Subject.DoesNotExist, e:
            raise CommandError('Subject with short name %s does not exist.' % subject_short_name)
        try:
            self.period = Period.objects.get(short_name=period_short_name, parentnode=self.subject)
        except Period.DoesNotExist, e:
            raise CommandError('Period with short name %s does not exist.' % period_short_name)

    def _deactivate_all(self):
        if self.related_user_model_class == RelatedStudent:
            queryset = self.period.relatedstudent_set
        else:
            queryset = self.period.relatedexaminer_set
        queryset.update(active=False)

    def add_users(self):
        """ Add the users read from stdin to the given relatedmanager """
        if self.deactivate_missing:
            self._deactivate_all()
        user_model = get_user_model()
        for kw in self.input_data:
            username = kw.pop('username', None)
            email = kw.pop('email', None)
            tags_string = kw.pop('tags', '').strip()
            kw.setdefault('active', True)
            user, created = user_model.objects.get_or_create_user(
                username=username, email=email)
            if not self._update_related_user(user, kw, tags_string):
                self._create_reluser(user, kw, tags_string)
        if self.verbosity > 0:
            print "Added/updated {count} related {user_type}s to {subject}.{period}".format(
                count=len(self.input_data), user_type=self.user_type,
                subject=self.subject.short_name, period=self.period.short_name)

    def _split_tags_string(self, tags_string):
        return re.split(r'\s*,\s*', tags_string)

    def _clear_tags_for_relateduser(self, relateduser):
        kwargs = {
            'periodtag__prefix': self.tag_prefix,
            'periodtag__period': self.period
        }
        if self.related_user_model_class == RelatedStudent:
            kwargs['relatedstudent'] = relateduser
            PeriodTag.relatedstudents.through.objects.filter(**kwargs).delete()
        else:
            kwargs['relatedexaminer'] = relateduser
            PeriodTag.relatedexaminers.through.objects.filter(**kwargs).delete()

    def _add_relateduser_to_tag(self, tag, relateduser):
        if self.related_user_model_class == RelatedStudent:
            tag.relatedstudents.add(relateduser)
        else:
            tag.relatedexaminers.add(relateduser)

    def _update_tags(self, relateduser, tags_string):
        self._clear_tags_for_relateduser(relateduser=relateduser)
        if not tags_string:
            return
        tags_string_list = self._split_tags_string(tags_string)
        for tagname in tags_string_list:
            tag, created = PeriodTag.objects.get_or_create(
                prefix=self.tag_prefix,
                tag=tagname,
                period=self.period)
            self._add_relateduser_to_tag(tag=tag, relateduser=relateduser)

    def _update_related_user(self, user, kw, tags_string):
        try:
            relateduser = self.related_user_model_class.objects.get(
                period=self.period, user=user)
        except self.related_user_model_class.DoesNotExist:
            return False
        else:
            for key, value in kw.iteritems():
                setattr(relateduser, key, value)
            self._save_related_user(relateduser, 'Updated')
            self._update_tags(relateduser, tags_string)
            return True

    def _create_reluser(self, user, kw, tags_string):
        relateduser = self.related_user_model_class(
            period=self.period, user=user, **kw)
        self._save_related_user(relateduser, 'Added')
        self._update_tags(relateduser, tags_string)

    def _save_related_user(self, relateduser, mode):
        try:
            relateduser.full_clean()
        except ValidationError:
            raise CommandError('Invalid related user: "{0}"'.format(relateduser))
        else:
            relateduser.save()
            if self.verbosity > 1:
                print "{0} {1} {2}".format(mode, self.user_type, relateduser)

    def handle(self, *args, **options):
        self.args = args
        self.options = options
        self.verbosity = int(options.get('verbosity', '1'))
        self.tag_prefix = options.get('tag_prefix')
        self.deactivate_missing = options.get('deactivate_missing') or options.get('clearall')
        jsondata = sys.stdin.read()
        self.input_data = json.loads(jsondata)

class Command(RelatedBaseCommand):
    help = 'Set related examiners on a period. Users are read from stdin, ' \
           'as a JSON encoded array of arguments to the RelatedExaminer model. ' \
           'See devilry/apps/superadmin/examples/relatedexaminers.json for an example.'

    @property
    def user_type(self):
        return "examiner"

    @property
    def related_user_model_class(self):
        from devilry.apps.core.models import RelatedExaminer
        return RelatedExaminer

    def handle(self, *args, **options):
        super(Command, self).handle(*args, **options)
        self.get_subject_and_period()
        self.add_users()
<commit_msg>devilry_superadmin/management/commands/devilry_periodsetrelatedexaminers.py: fix script after django update changed behaviour of BaseCommand argument parser.<commit_after>import json
import re
from optparse import make_option

from django.conf import settings
from django.contrib.auth import get_user_model

from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ValidationError

import sys

from devilry.apps.core.models import PeriodTag, RelatedStudent

class RelatedBaseCommand(BaseCommand):
    args = '<subject short name> <period short name>'

    def add_arguments(self, parser):
        parser.add_argument(
            'subject_short_name',
            help='Positional argument for short name of the subject.'
        )
        parser.add_argument(
            'period_short_name',
            help='Positional argument for short name of the period.'
        )
        parser.add_argument(
            '--deactivate-missing',
            action='store_true',
            dest='deactivate_missing',
            default=False,
            help='Set all RelatedExaminers as active=False before adding '
                 'and updating the provided users. This is useful when importing a '
                 'complete list of users, since it means that the missing '
                 'users will be deactivated.'
        )
        parser.add_argument(
            '--tag-prefix',
            dest='tag_prefix',
            default=settings.DEVILRY_SYNCSYSTEM_SHORTNAME,
            help='The prefix to use for imported tags. Defaults '
                 'to the value of the DEVILRY_SYNCSYSTEM_SHORTNAME setting '
                 '(which is {!r}).'.format(settings.DEVILRY_SYNCSYSTEM_SHORTNAME)
        )

    @property
    def user_type(self):
        raise NotImplementedError()

    @property
    def related_user_model_class(self):
        raise NotImplementedError()

    def get_subject_and_period(self):
        """ Get the subject and period from args """
        from devilry.apps.core.models import Subject, Period
        if 'subject_short_name' not in self.options or 'period_short_name' not in self.options:
            raise CommandError('Subject and period is required. See --help.')
        subject_short_name = self.options.get('subject_short_name')
        period_short_name = self.options.get('period_short_name')

        # Get the subject and period
        try:
            self.subject = Subject.objects.get(short_name=subject_short_name)
        except Subject.DoesNotExist, e:
            raise CommandError('Subject with short name %s does not exist.' % subject_short_name)
        try:
            self.period = Period.objects.get(short_name=period_short_name, parentnode=self.subject)
        except Period.DoesNotExist, e:
            raise CommandError('Period with short name %s does not exist.' % period_short_name)

    def _deactivate_all(self):
        if self.related_user_model_class == RelatedStudent:
            queryset = self.period.relatedstudent_set
        else:
            queryset = self.period.relatedexaminer_set
        queryset.update(active=False)

    def add_users(self):
        """ Add the users read from stdin to the given relatedmanager """
        if self.deactivate_missing:
            self._deactivate_all()
        user_model = get_user_model()
        for kw in self.input_data:
            username = kw.pop('username', None)
            email = kw.pop('email', None)
            tags_string = kw.pop('tags', '').strip()
            kw.setdefault('active', True)
            user, created = user_model.objects.get_or_create_user(
                username=username, email=email)
            if not self._update_related_user(user, kw, tags_string):
                self._create_reluser(user, kw, tags_string)
        if self.verbosity > 0:
            print "Added/updated {count} related {user_type}s to {subject}.{period}".format(
                count=len(self.input_data), user_type=self.user_type,
                subject=self.subject.short_name, period=self.period.short_name)

    def _split_tags_string(self, tags_string):
        return re.split(r'\s*,\s*', tags_string)

    def _clear_tags_for_relateduser(self, relateduser):
        kwargs = {
            'periodtag__prefix': self.tag_prefix,
            'periodtag__period': self.period
        }
        if self.related_user_model_class == RelatedStudent:
            kwargs['relatedstudent'] = relateduser
            PeriodTag.relatedstudents.through.objects.filter(**kwargs).delete()
        else:
            kwargs['relatedexaminer'] = relateduser
            PeriodTag.relatedexaminers.through.objects.filter(**kwargs).delete()

    def _add_relateduser_to_tag(self, tag, relateduser):
        if self.related_user_model_class == RelatedStudent:
            tag.relatedstudents.add(relateduser)
        else:
            tag.relatedexaminers.add(relateduser)

    def _update_tags(self, relateduser, tags_string):
        self._clear_tags_for_relateduser(relateduser=relateduser)
        if not tags_string:
            return
        tags_string_list = self._split_tags_string(tags_string)
        for tagname in tags_string_list:
            tag, created = PeriodTag.objects.get_or_create(
                prefix=self.tag_prefix,
                tag=tagname,
                period=self.period)
            self._add_relateduser_to_tag(tag=tag, relateduser=relateduser)

    def _update_related_user(self, user, kw, tags_string):
        try:
            relateduser = self.related_user_model_class.objects.get(
                period=self.period, user=user)
        except self.related_user_model_class.DoesNotExist:
            return False
        else:
            for key, value in kw.iteritems():
                setattr(relateduser, key, value)
            self._save_related_user(relateduser, 'Updated')
            self._update_tags(relateduser, tags_string)
            return True

    def _create_reluser(self, user, kw, tags_string):
        relateduser = self.related_user_model_class(
            period=self.period, user=user, **kw)
        self._save_related_user(relateduser, 'Added')
        self._update_tags(relateduser, tags_string)

    def _save_related_user(self, relateduser, mode):
        try:
            relateduser.full_clean()
        except ValidationError:
            raise CommandError('Invalid related user: "{0}"'.format(relateduser))
        else:
            relateduser.save()
            if self.verbosity > 1:
                print "{0} {1} {2}".format(mode, self.user_type, relateduser)

    def handle(self, *args, **options):
        self.args = args
        self.options = options
        self.verbosity = int(options.get('verbosity', '1'))
        self.tag_prefix = options.get('tag_prefix')
        self.deactivate_missing = options.get('deactivate_missing')
        print(options)
        jsondata = sys.stdin.read()
        self.input_data = json.loads(jsondata)

class Command(RelatedBaseCommand):
    help = 'Set related examiners on a period. Users are read from stdin, ' \
           'as a JSON encoded array of arguments to the RelatedExaminer model. ' \
           'See devilry/apps/superadmin/examples/relatedexaminers.json for an example.'

    @property
    def user_type(self):
        return "examiner"

    @property
    def related_user_model_class(self):
        from devilry.apps.core.models import RelatedExaminer
        return RelatedExaminer

    def handle(self, *args, **options):
        super(Command, self).handle(*args, **options)
        self.get_subject_and_period()
        self.add_users()
<|endoftext|>


<commit_before>#! /usr/bin/env python
# -*- encoding: utf-8 -*-
"""
swapify - Adjust South migrations to work with custom user models.

Usage:
    swapify apply <DIR> [--model MODEL] [--var-name SWAPPABLE] [--dry-run]
    swapify list <DIR> [--model MODEL] [--var-name SWAPPABLE]

Options:
    --model         Name of the swappable model as '<app_label>.<model_name>',
                    e.g. 'auth.User'. Default: 'auth.User'
    --var-name      Variable name for the swappable model, e.g.
                    AUTH_USER_MODEL. If it is not specified it is generated
                    from the model name using <APP_LABEL>_<MODEL_NAME>_MODEL.
                    Default: AUTH_USER_MODEL.
    --dry-run       Run in test mode without changing files. Outputs to stdout.
"""
import os
import re
from docopt import docopt

SWAPIFY_MARKER = "# SWAPIFIED: {0.swappable_name}"

ENCODING_LINE_RE = re.compile(r'(# -\*- coding: utf-8 -\*-)')
MIGRATION_IMPORT_RE = re.compile(
    r'(from south.v2 import (Schema|Data)Migration)')
MIGRATION_CLASS_RE = re.compile(
    r'(class Migration\((Schema|Data)Migration\):)')
DEPENDS_ON_RE = re.compile(r'(depends_on = \()')

class Swapifier(object):

    def __init__(self, model, swappable_name=None):
        print model, swappable_name
        self.model = model  # auth.User
        self.app_label, self.model_name = self.model.split('.')

        if not swappable_name:
            swappable_name = u"{0.app_label}_{0.model_name}_MODEL".format(self)

        # e.g. AUTH_USER_MODEL
        self.swappable_name = swappable_name.upper()
        # e.g. AUTH_USER_APP_LABEL
        self.swappable_app_label = (
            u"{0.app_label}_{0.model_name}_APP_LABEL").format(self).upper()
        # e.g. AUTH_USER_MODEL_NAME
        self.swappable_model_name = u"{}_NAME".format(self.swappable_name)
        self.swapify_marker = SWAPIFY_MARKER.format(self)

        self.orm_search_string = r'u?"orm\[\'{}\'\]"'.format(self.model)

    def set_swapify_marker(self, data):
        data, __ = ENCODING_LINE_RE.subn(
            r"\1\n{}".format(self.swapify_marker), data)
        return data

    def is_swapified(self, data):
        return self.swapify_marker in data

    def add_settings_import(self, data):
        settings_import = r'from django.conf import settings'
        if settings_import in data:
            return data
        return MIGRATION_IMPORT_RE.sub(
            r"\1\n{}".format(settings_import), data)

    def add_swappable_constants(self, data):
        constants = '\n'.join([
            r"{sw_model} = getattr(settings, u'{sw_model}', u'{model}')",
            r"{sw_app_label}, {sw_model_name} = {sw_model}.split('.')"])
        constants = constants.format(
            sw_model=self.swappable_name, model=self.model,
            sw_app_label=self.swappable_app_label,
            sw_model_name=self.swappable_model_name)

        if constants in data:
            return data

        return MIGRATION_CLASS_RE.sub(
            r"{}\n\n\n\1".format(constants), data)

    def add_dependency(self, data):
        app_dependency = u"({}, u'0001_initial'),".format(
            self.swappable_app_label)

        if app_dependency in data:
            return data

        if not DEPENDS_ON_RE.search(data):
            data = MIGRATION_CLASS_RE.sub(
                r'\1\n\n    depends_on = (\n    )\n', data)

        data = DEPENDS_ON_RE.sub(
            r'\1\n        {}'.format(app_dependency), data)
        return data

    def replace_object_name(self, data):
        return data.replace(
            "'object_name': 'User'",
            "'object_name': {}".format(self.swappable_model_name))

    def replace_model(self, data):
        data, __ = re.subn(r'u?(\'|"){}(\'|")'.format(self.model),
                           self.swappable_name, data, flags=re.I)
        return data

    def replace_orm_string(self, data):
        data, __ = re.subn(
            self.orm_search_string,
            u'u"orm[\'{{}}\']".format({})'.format(self.swappable_name), data,
            flags=re.I)
        return data

    def swapify(self, data):
        if self.is_swapified(data):
            return data

        data = self.replace_orm_string(data)
        data = self.replace_model(data)
        data = self.replace_object_name(data)

        data = self.add_dependency(data)
        data = self.add_settings_import(data)
        data = self.add_swappable_constants(data)
        data = self.set_swapify_marker(data)

        return data

def get_unfixed_files(basedir, swapifier):
    unfixed_files = []
    for dirname, subdirs, files in os.walk(basedir):
        if not dirname.endswith('migrations'):
            continue

        for filename in files:
            if not filename.endswith('.py'):
                continue

            path = os.path.join(dirname, filename)
            with open(path) as infile:
                migration_data = infile.read()

            if swapifier.is_swapified(migration_data):
                continue

            if swapifier.model not in migration_data \
               or swapifier.orm_search_string in migration_data:
                continue

            unfixed_files.append(path)
    return unfixed_files

def main():
    arguments = docopt(__doc__)

    swappable_model = arguments.get('MODEL') or u'auth.User'
    var_name = arguments.get('SWAPPABLE') or None
    dirname = arguments.get('<DIR>')

    swapifier = Swapifier(swappable_model, var_name)
    unfixed_files = get_unfixed_files(dirname, swapifier)

    if arguments.get('list'):
        if not len(unfixed_files):
            print "All your migration files are good!"
            return

        print "The following files need fixing:"
        for path in unfixed_files:
            print "\t", path
        return

    for path in unfixed_files:
        with open(path) as infile:
            migration_data = infile.read()

        swapped_data = swapifier.swapify(migration_data)

        if not arguments['--dry-run']:
            print 'UPDATED:', path
            with open(path, 'w') as outfile:
                outfile.write(swapped_data)
        else:
            print '=' * 80
            print swapped_data
            print '=' * 80

if __name__ == '__main__':
    main()
<commit_msg>Remove debug print statement<commit_after>#! /usr/bin/env python
# -*- encoding: utf-8 -*-
"""
swapify - Adjust South migrations to work with custom user models.

Usage:
    swapify apply <DIR> [--model MODEL] [--var-name SWAPPABLE] [--dry-run]
    swapify list <DIR> [--model MODEL] [--var-name SWAPPABLE]

Options:
    --model         Name of the swappable model as '<app_label>.<model_name>',
                    e.g. 'auth.User'. Default: 'auth.User'
    --var-name      Variable name for the swappable model, e.g.
                    AUTH_USER_MODEL. If it is not specified it is generated
                    from the model name using <APP_LABEL>_<MODEL_NAME>_MODEL.
                    Default: AUTH_USER_MODEL.
    --dry-run       Run in test mode without changing files. Outputs to stdout.
"""
import os
import re
from docopt import docopt

SWAPIFY_MARKER = "# SWAPIFIED: {0.swappable_name}"

ENCODING_LINE_RE = re.compile(r'(# -\*- coding: utf-8 -\*-)')
MIGRATION_IMPORT_RE = re.compile(
    r'(from south.v2 import (Schema|Data)Migration)')
MIGRATION_CLASS_RE = re.compile(
    r'(class Migration\((Schema|Data)Migration\):)')
DEPENDS_ON_RE = re.compile(r'(depends_on = \()')

class Swapifier(object):

    def __init__(self, model, swappable_name=None):
        self.model = model  # auth.User
        self.app_label, self.model_name = self.model.split('.')

        if not swappable_name:
            swappable_name = u"{0.app_label}_{0.model_name}_MODEL".format(self)

        # e.g. AUTH_USER_MODEL
        self.swappable_name = swappable_name.upper()
        # e.g. AUTH_USER_APP_LABEL
        self.swappable_app_label = (
            u"{0.app_label}_{0.model_name}_APP_LABEL").format(self).upper()
        # e.g. AUTH_USER_MODEL_NAME
        self.swappable_model_name = u"{}_NAME".format(self.swappable_name)
        self.swapify_marker = SWAPIFY_MARKER.format(self)

        self.orm_search_string = r'u?"orm\[\'{}\'\]"'.format(self.model)

    def set_swapify_marker(self, data):
        data, __ = ENCODING_LINE_RE.subn(
            r"\1\n{}".format(self.swapify_marker), data)
        return data

    def is_swapified(self, data):
        return self.swapify_marker in data

    def add_settings_import(self, data):
        settings_import = r'from django.conf import settings'
        if settings_import in data:
            return data
        return MIGRATION_IMPORT_RE.sub(
            r"\1\n{}".format(settings_import), data)

    def add_swappable_constants(self, data):
        constants = '\n'.join([
            r"{sw_model} = getattr(settings, u'{sw_model}', u'{model}')",
            r"{sw_app_label}, {sw_model_name} = {sw_model}.split('.')"])
        constants = constants.format(
            sw_model=self.swappable_name, model=self.model,
            sw_app_label=self.swappable_app_label,
            sw_model_name=self.swappable_model_name)

        if constants in data:
            return data

        return MIGRATION_CLASS_RE.sub(
            r"{}\n\n\n\1".format(constants), data)

    def add_dependency(self, data):
        app_dependency = u"({}, u'0001_initial'),".format(
            self.swappable_app_label)

        if app_dependency in data:
            return data

        if not DEPENDS_ON_RE.search(data):
            data = MIGRATION_CLASS_RE.sub(
                r'\1\n\n    depends_on = (\n    )\n', data)

        data = DEPENDS_ON_RE.sub(
            r'\1\n        {}'.format(app_dependency), data)
        return data

    def replace_object_name(self, data):
        return data.replace(
            "'object_name': 'User'",
            "'object_name': {}".format(self.swappable_model_name))

    def replace_model(self, data):
        data, __ = re.subn(r'u?(\'|"){}(\'|")'.format(self.model),
                           self.swappable_name, data, flags=re.I)
        return data

    def replace_orm_string(self, data):
        data, __ = re.subn(
            self.orm_search_string,
            u'u"orm[\'{{}}\']".format({})'.format(self.swappable_name), data,
            flags=re.I)
        return data

    def swapify(self, data):
        if self.is_swapified(data):
            return data

        data = self.replace_orm_string(data)
        data = self.replace_model(data)
        data = self.replace_object_name(data)

        data = self.add_dependency(data)
        data = self.add_settings_import(data)
        data = self.add_swappable_constants(data)
        data = self.set_swapify_marker(data)

        return data

def get_unfixed_files(basedir, swapifier):
    unfixed_files = []
    for dirname, subdirs, files in os.walk(basedir):
        if not dirname.endswith('migrations'):
            continue

        for filename in files:
            if not filename.endswith('.py'):
                continue

            path = os.path.join(dirname, filename)
            with open(path) as infile:
                migration_data = infile.read()

            if swapifier.is_swapified(migration_data):
                continue

            if swapifier.model not in migration_data \
               or swapifier.orm_search_string in migration_data:
                continue

            unfixed_files.append(path)
    return unfixed_files

def main():
    arguments = docopt(__doc__)

    swappable_model = arguments.get('MODEL') or u'auth.User'
    var_name = arguments.get('SWAPPABLE') or None
    dirname = arguments.get('<DIR>')

    swapifier = Swapifier(swappable_model, var_name)
    unfixed_files = get_unfixed_files(dirname, swapifier)

    if arguments.get('list'):
        if not len(unfixed_files):
            print "All your migration files are good!"
            return

        print "The following files need fixing:"
        for path in unfixed_files:
            print "\t", path
        return

    for path in unfixed_files:
        with open(path) as infile:
            migration_data = infile.read()

        swapped_data = swapifier.swapify(migration_data)

        if not arguments['--dry-run']:
            print 'UPDATED:', path
            with open(path, 'w') as outfile:
                outfile.write(swapped_data)
        else:
            print '=' * 80
            print swapped_data
            print '=' * 80

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


<commit_before>import numpy as np
import syft

__all__ = [
    'equal', 'TensorBase',
]

def _ensure_ndarray(arr):
    if not isinstance(arr, np.ndarray):
        arr = np.array(arr)

    return arr

def _ensure_tensorbase(tensor):
    if not isinstance(tensor, TensorBase):
        tensor = TensorBase(tensor)

    return tensor

def equal(tensor1, tensor2):
    """Checks if two tensors are equal.

    Two tensors are considered equal if they are the same size and contain the same elements.

    Assumption:
    tensor1 and tensor2 are of type TensorBase.
    Non-TensorBase objects will be converted to TensorBase objects.
    """

    tensor1 = _ensure_tensorbase(tensor1)
    tensor2 = _ensure_tensorbase(tensor2)

    if tensor1.encrypted is True or tensor2.encrypted is True:
        return NotImplemented

    return tensor1.data.shape == tensor2.data.shape and np.allclose(tensor1.data, tensor2.data)

class TensorBase(object):
    """
    A base tensor class that performs basic element-wise operation such as
    addition, subtraction, multiplication and division, and also dot and matrix products.
    """

    def __init__(self, arr_like, encrypted=False):
        self.data = _ensure_ndarray(arr_like)
        self.encrypted = encrypted

    def __add__(self, tensor):
        """Performs element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data + tensor.data)

    def __iadd__(self, tensor):
        """Performs in place element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data + tensor.data
        return self

    def __sub__(self, tensor):
        """Performs element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data - tensor.data)

    def __isub__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data - tensor.data
        return self

    def __eq__(self, tensor):
        """Checks if two tensors are equal"""
        if self.encrypted:
            return NotImplemented

        return syft.equal(self, tensor)

    def dot(self, tensor):
        """Returns inner product of two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.dot(self, tensor)

    def __matmul__(self, tensor):
        """Performs matrix multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.matmul(self, tensor)

    def __mul__(self, tensor):
        """Performs element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data * tensor.data)

    def __imul__(self, tensor):
        """Performs in place element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data * tensor.data
        return self

    def __truediv__(self, tensor):
        """Performs element-wise division between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data / tensor.data)

    def __itruediv__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data / tensor.data
        return self

    def abs(self):
        """Returns absolute value of tensor as a new tensor"""
        if self.encrypted:
            return NotImplemented
        return np.absolute(self.data)

    def abs_(self):
        """Replaces tensor values with its absolute value"""
        if self.encrypted:
            return NotImplemented
        self.data=np.absolute(self.data)
        return self.data

    def shape(self):
        """Returns a tuple of input array dimensions."""
        if self.encrypted:
            return NotImplemented

        return self.data.shape

    def dim(self):
        """Returns an integer of the number of dimensions of this tensor."""
        if self.encrypted:
            return NotImplemented

        return self.data.ndim

    def sum(self, dim=None):
        """Returns the sum of all elements in the input array."""
        if self.encrypted:
            return NotImplemented

        if dim is None:
            return self.data.sum()
        else:
            return self.data.sum(axis=dim)

     def addmm(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))

    def addmm_(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:
            return NotImplemented
        else:
            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))
            return self

<commit_msg>Remove redundant boolean checks<commit_after>import numpy as np
import syft

__all__ = [
    'equal', 'TensorBase',
]

def _ensure_ndarray(arr):
    if not isinstance(arr, np.ndarray):
        arr = np.array(arr)

    return arr

def _ensure_tensorbase(tensor):
    if not isinstance(tensor, TensorBase):
        tensor = TensorBase(tensor)

    return tensor

def equal(tensor1, tensor2):
    """Checks if two tensors are equal.

    Two tensors are considered equal if they are the same size and contain the same elements.

    Assumption:
    tensor1 and tensor2 are of type TensorBase.
    Non-TensorBase objects will be converted to TensorBase objects.
    """

    tensor1 = _ensure_tensorbase(tensor1)
    tensor2 = _ensure_tensorbase(tensor2)

    if tensor1.encrypted or tensor2.encrypted:
        return NotImplemented

    return tensor1.data.shape == tensor2.data.shape and np.allclose(tensor1.data, tensor2.data)

class TensorBase(object):
    """
    A base tensor class that performs basic element-wise operation such as
    addition, subtraction, multiplication and division, and also dot and matrix products.
    """

    def __init__(self, arr_like, encrypted=False):
        self.data = _ensure_ndarray(arr_like)
        self.encrypted = encrypted

    def __add__(self, tensor):
        """Performs element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data + tensor.data)

    def __iadd__(self, tensor):
        """Performs in place element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data + tensor.data
        return self

    def __sub__(self, tensor):
        """Performs element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data - tensor.data)

    def __isub__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data - tensor.data
        return self

    def __eq__(self, tensor):
        """Checks if two tensors are equal"""
        if self.encrypted:
            return NotImplemented

        return syft.equal(self, tensor)

    def dot(self, tensor):
        """Returns inner product of two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.dot(self, tensor)

    def __matmul__(self, tensor):
        """Performs matrix multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.matmul(self, tensor)

    def __mul__(self, tensor):
        """Performs element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data * tensor.data)

    def __imul__(self, tensor):
        """Performs in place element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data * tensor.data
        return self

    def __truediv__(self, tensor):
        """Performs element-wise division between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data / tensor.data)

    def __itruediv__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data = self.data / tensor.data
        return self

    def abs(self):
        """Returns absolute value of tensor as a new tensor"""
        if self.encrypted:
            return NotImplemented
        return np.absolute(self.data)

    def abs_(self):
        """Replaces tensor values with its absolute value"""
        if self.encrypted:
            return NotImplemented
        self.data=np.absolute(self.data)
        return self.data

    def shape(self):
        """Returns a tuple of input array dimensions."""
        if self.encrypted:
            return NotImplemented

        return self.data.shape

    def dim(self):
        """Returns an integer of the number of dimensions of this tensor."""
        if self.encrypted:
            return NotImplemented

        return self.data.ndim

    def sum(self, dim=None):
        """Returns the sum of all elements in the input array."""
        if self.encrypted:
            return NotImplemented

        if dim is None:
            return self.data.sum()
        else:
            return self.data.sum(axis=dim)

     def addmm(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))

    def addmm_(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))
            return self

<|endoftext|>


<commit_before>"""Symbolic variables for code generation."""

import collections
import inspect
import keyword

import jinja2
import numpy as np
import sympy

from . import utils

class Variable:
    """Represents a code generation variable."""

    def print_prepare_validate(self, printer):
        """Returns code to validate and prepare the variable from arguments."""
        return ''

    @property
    def broadcast_elements(self):
        """List of elements which should be broadcast to generate the output."""
        return []

    def subs_dict(self, value):
        """Dictionary of substitutions to evaluate with a given value."""
        return {self: value}

    @property
    def identifiers(self):
        """Set of identifiers defined in this variable's code."""
        return {self.name}

class SymbolArray(Variable, sympy.Array):
    """Represents array of symbols for code generation."""

    def __new__(cls, name, array_like=None, dtype='float64'):
        if array_like is None:
            array_like = name

        elements, shape = elements_and_shape(array_like)
        if all(utils.isstr(e) for e in elements):
            elements = [sympy.Symbol(n) for n in elements]

        if len(set(elements)) != len(elements):
            raise ValueError("elements of SymbolArray must be unique")

        obj = super().__new__(cls, elements, shape)
        return obj

    def __init__(self, name, array_like=None, dtype='float64'):
        if not isinstance(name, str):
            raise TypeError("expected str, but got {!r}".format(type(name)))
        if not utils.isidentifier(name):
            raise ValueError(
                "'{}' is not a valid python identifier".format(name)
            )
        self.name = name
        """Variable name"""

        self.dtype = dtype
        """Generated array dtype."""

        symbol_names = set(symbol.name for symbol in self)
        if len(self) > len(symbol_names):
            raise ValueError("symbol names in array must be unique")

        if self.rank() > 0 and self.name in symbol_names:
            raise ValueError("positive-rank array name and symbols must differ")

    def ndenumerate(self):
        for ind in np.ndindex(*self.shape):
            yield ind, self[ind]

    def __len__(self):
        """Overrides `sympy.Array.__len__` which fails for rank-0 Arrays"""
        if self.shape == ():
            return 1
        else:
            return super().__len__()

    @property
    def broadcast_elements(self):
        """List of elements which should be broadcast to generate the output."""
        return [self[(0,) * self.rank()]]

    def subs_dict(self, value):
        value_array = sympy.Array(value)
        if self.shape != value_array.shape:
            msg = "Invalid shape for argument, expected {} and got {}"
            raise ValueError(msg.format(self.shape, value_array.shape))

        subs = {}
        for i in np.ndindex(*self.shape):
            subs[self[i]] = value_array[i]
        return subs

    @utils.cached_class_property
    def prepare_validate_template(cls):
        return jinja2.Template(inspect.cleandoc("""
        {{v.name}} = {{np}}.asarray({{v.name}}, dtype={{np}}.{{v.dtype}})
        {% if v.rank() -%}
        if {{v.name}}.shape[-{{v.rank()}}:] != {{v.shape}}:
        {%- set expected %}(...,{{v.shape |join(",")}}){% endset %}
            msg = "invalid shape for {{v.name}}, expected {{expected}}, got {}"
            raise ValueError(msg.format({{v.name}}.shape))
        {% endif -%}
        {% if v.rank() != 0 or v.name != v[()].name -%}
        # unpack `{{v.name}}` array elements
        {% for ind, symb in v.ndenumerate() -%}
        {{symb}} = {{v.name}}[..., {{ ind | join(', ')}}]
        {% endfor %}
        {%- endif %}
        """))

    def print_prepare_validate(self, printer):
        """Construct variable from an array_like and check dimensions."""
        context = dict(v=self, np=printer.numpy_alias, printer=printer)
        return self.prepare_validate_template.render(context)

    @property
    def identifiers(self):
        """Set of identifiers defined in this variable's code."""
        return {self.name} | {elem.name for elem in self}

def elements_and_shape(array_like):
    """Return flat list of elements and shape from array-like nested iterable.

    Based on `sympy.tensor.array.ndim_array.NDimArray._scan_iterable_shape`.
    """
    #Detect if we are at a scalar element
    if (utils.isstr(array_like) or not utils.isiterable(array_like)):
        return [array_like], ()

    #We have an iterable, apply self to its elements
    subelements, subshapes = zip(*[elements_and_shape(e) for e in array_like])

    #Check if all subelements have the same shape
    if len(set(subshapes)) != 1:
        raise ValueError("could not determine shape unambiguously")

    #Create outputs
    elements = []
    for subelement in subelements:
        elements.extend(subelement)
    shape = (len(subelements),) + subshapes[0]
    return elements, shape
<commit_msg>Fix errors for empty vector variables.<commit_after>"""Symbolic variables for code generation."""

import collections
import inspect
import keyword

import jinja2
import numpy as np
import sympy

from . import utils

class Variable:
    """Represents a code generation variable."""

    def print_prepare_validate(self, printer):
        """Returns code to validate and prepare the variable from arguments."""
        return ''

    @property
    def broadcast_elements(self):
        """List of elements which should be broadcast to generate the output."""
        return []

    def subs_dict(self, value):
        """Dictionary of substitutions to evaluate with a given value."""
        return {self: value}

    @property
    def identifiers(self):
        """Set of identifiers defined in this variable's code."""
        return {self.name}

class SymbolArray(Variable, sympy.Array):
    """Represents array of symbols for code generation."""

    def __new__(cls, name, array_like=None, dtype='float64'):
        if array_like is None:
            array_like = name

        elements, shape = elements_and_shape(array_like)
        if all(utils.isstr(e) for e in elements):
            elements = [sympy.Symbol(n) for n in elements]

        if len(set(elements)) != len(elements):
            raise ValueError("elements of SymbolArray must be unique")

        obj = super().__new__(cls, elements, shape)
        return obj

    def __init__(self, name, array_like=None, dtype='float64'):
        if not isinstance(name, str):
            raise TypeError("expected str, but got {!r}".format(type(name)))
        if not utils.isidentifier(name):
            raise ValueError(
                "'{}' is not a valid python identifier".format(name)
            )
        self.name = name
        """Variable name"""

        self.dtype = dtype
        """Generated array dtype."""

        symbol_names = set(symbol.name for symbol in self)
        if len(self) > len(symbol_names):
            raise ValueError("symbol names in array must be unique")

        if self.rank() > 0 and self.name in symbol_names:
            raise ValueError("positive-rank array name and symbols must differ")

    def ndenumerate(self):
        for ind in np.ndindex(*self.shape):
            yield ind, self[ind]

    def __len__(self):
        """Overrides `sympy.Array.__len__` which fails for rank-0 Arrays"""
        if self.shape == ():
            return 1
        else:
            return super().__len__()

    @property
    def broadcast_elements(self) -> list:
        """List of elements which should be broadcast to generate the output."""
        return [] if len(self) == 0 else [self[(0,) * self.rank()]]

    def subs_dict(self, value):
        value_array = sympy.Array(value)
        if self.shape != value_array.shape:
            msg = "Invalid shape for argument, expected {} and got {}"
            raise ValueError(msg.format(self.shape, value_array.shape))

        subs = {}
        for i in np.ndindex(*self.shape):
            subs[self[i]] = value_array[i]
        return subs

    @utils.cached_class_property
    def prepare_validate_template(cls):
        return jinja2.Template(inspect.cleandoc("""
        {{v.name}} = {{np}}.asarray({{v.name}}, dtype={{np}}.{{v.dtype}})
        {% if v.rank() -%}
        if {{v.name}}.shape[-{{v.rank()}}:] != {{v.shape}}:
        {%- set expected %}(...,{{v.shape |join(",")}}){% endset %}
            msg = "invalid shape for {{v.name}}, expected {{expected}}, got {}"
            raise ValueError(msg.format({{v.name}}.shape))
        {% endif -%}
        {% if v.rank() != 0 or v.name != v[()].name -%}
        # unpack `{{v.name}}` array elements
        {% for ind, symb in v.ndenumerate() -%}
        {{symb}} = {{v.name}}[..., {{ ind | join(', ')}}]
        {% endfor %}
        {%- endif %}
        """))

    def print_prepare_validate(self, printer):
        """Construct variable from an array_like and check dimensions."""
        context = dict(v=self, np=printer.numpy_alias, printer=printer)
        return self.prepare_validate_template.render(context)

    @property
    def identifiers(self):
        """Set of identifiers defined in this variable's code."""
        return {self.name} | {elem.name for elem in self}

def elements_and_shape(array_like):
    """Return flat list of elements and shape from array-like nested iterable.

    Based on `sympy.tensor.array.ndim_array.NDimArray._scan_iterable_shape`.
    """
    #Detect if we are at a scalar element
    if (utils.isstr(array_like) or not utils.isiterable(array_like)):
        return [array_like], ()

    #Detect empty iterable
    array_like = list(array_like)
    if len(array_like) == 0:
        return [], (0,)

    #We have an iterable, apply self to its elements
    subelements, subshapes = zip(*[elements_and_shape(e) for e in array_like])

    #Check if all subelements have the same shape
    if len(set(subshapes)) != 1:
        raise ValueError("could not determine shape unambiguously")

    #Create outputs
    elements = []
    for subelement in subelements:
        elements.extend(subelement)
    shape = (len(subelements),) + subshapes[0]
    return elements, shape
<|endoftext|>