<commit_before>#    Copyright 2012 Sebastien Maccagnoni-Munch
#
#    This file is part of OSPFM.
#
#    OSPFM is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    OSPFM is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with OSPFM.  If not, see <http://www.gnu.org/licenses/>.

import datetime, json

from flask import jsonify
from sqlalchemy import and_, or_, desc
from sqlalchemy.orm import joinedload

from ospfm import helpers
from ospfm.core import currency
from ospfm.core import models as core
from ospfm.transaction import models
from ospfm.database import session
from ospfm.objects import Object

class Transaction(Object):

    def __own_transaction(self, transactionid):
        return models.Transaction.query.options(
                          joinedload(models.Transaction.currency),
                          joinedload(models.Transaction.transaction_accounts),
                          joinedload(models.Transaction.transaction_categories)
               ).filter(
                    and_(
                        models.Transaction.owner_username == self.username,
                        models.Transaction.id == transactionid
                    )
               ).first()

    def list(self):
        # Transactions cannot be listed with the API
        self.forbidden()

    def create(self):
        if not (
            self.args.has_key('currency') and \
            self.args.has_key('date') and \
            self.args.has_key('description') and \
            self.args.has_key('amount')
        ):
            self.badrequest()
        # First, create the transaction object
        currency = core.Currency.query.filter(
            and_(
                core.Currency.isocode == self.args['currency'],
                or_(
                    core.Currency.owner_username == self.username,
                    core.Currency.owner == None
                )
            )
        ).first()
        if not currency:
            self.badrequest()
        date = helpers.date_from_string(self.args['date'])
        if not date:
            self.badrequest()
        description = self.args['description']
        if self.args.has_key('original_description'):
            original_description = self.args['original_description']
        else:
            original_description = description
        transaction = models.Transaction(
            owner_username = self.username,
            description = description,
            original_description = original_description,
            amount = self.args['amount'],
            currency = currency,
            date = date
        )
        session.add(transaction)

        # Next, create the links from the transaction to its accounts
        if self.args.has_key('accounts'):
            accounts = json.loads(self.args['accounts'])
            for accountdata in accounts:
                transaction_accounts = []
                if accountdata.has_key('amount'):
                    # If no amount is specified, do not associate the account
                    accountobject = models.Account.query.options(
                        joinedload(models.Account.account_owners)
                    ).filter(
                        and_(
                           models.Account.id == accountdata['account'],
                           models.AccountOwner.owner_username == self.username,
                        )
                    ).first()
                    if accountobject:
                        ta = models.TransactionAccount(
                                transaction = transaction,
                                account = accountobject,
                                amount = accountdata['amount'],
                                verified = False
                        )
                        session.add(ta)
                    self.add_to_response('accountbalance',
                                         accountdata['account'])
            self.add_to_response('totalbalance')

        # Next, create the links from the transaction to its categories
        if self.args.has_key('categories'):
            categories = json.loads(self.args['categories'])
            for categorydata in categories:
                transaction_categories = []
                if categorydata.has_key('transaction_amount') and \
                   categorydata.has_key('category_amount'):
                    # If no amount is specified, do not associate the category
                    categoryobject = models.Category.query.options(
                        joinedload(models.Category.currency)
                    ).filter(
                        and_(
                            models.Category.id == categorydata['category'],
                            models.Category.owner_username == self.username,
                        )
                    ).first()
                    if categoryobject:
                        tc = models.TransactionCategory(
                                transaction = transaction,
                                category = categoryobject,
                       transaction_amount = categorydata['transaction_amount'],
                              category_amount = categorydata['category_amount']
                        )
                        session.add(tc)
                    self.add_to_response('categorybalance',
                                         categorydata['category'])

        # Commit everything...
        session.commit()
        return transaction.as_dict()

    def read(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        if transaction:
            return transaction.as_dict()
        self.notfound()

    def update(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        if not transaction:
            self.notfound()

        # First, modifications on the Transaction object itself
        if self.args.has_key('description'):
            transaction.description = self.args['description']
        if self.args.has_key('amount'):
            transaction.amount = self.args['amount']
        if self.args.has_key('currency'):
            currency = core.Currency.query.filter(
                and_(
                    core.Currency.isocode == self.args['currency'],
                    or_(
                        core.Currency.owner_username == self.username,
                        core.Currency.owner == None
                    )
                )
            ).first()
            if currency:
                transaction.currency = currency
        if self.args.has_key('date'):
            date = helpers.date_from_string(self.args['date'])
            if date:
                transaction.date = date

        # Next, update accounts
        if self.args.has_key('accounts'):
            existing_accounts = dict([ta.as_tuple() for ta in
                                      transaction.transaction_accounts])
            new_accounts_data = json.loads(self.args['accounts'])
            for account_data in new_accounts_data:
                if account_data.has_key('amount') and \
                   account_data.has_key('account'):
                    amount = account_data['amount']
                    accountid = account_data['account']
                    if accountid in existing_accounts.keys():
                        # Account already linked...
                        if existing_accounts[accountid] != amount:
                            # ...but the amount is different
                            ta = models.TransactionAccount.query.filter(and_(
                          models.TransactionAccount.transaction == transaction,
                          models.TransactionAccount.account_id == accountid
                            )).one()
                            ta.amount = amount
                            ta.verified = False
                            self.add_to_response('accountbalance', accountid)
                        existing_accounts.pop(accountid)
                    else:
                        # Account is not already linked
                        # Verify the account is owned by the user
                        accountobject = models.Account.query.options(
                            joinedload(models.Account.account_owners)
                        ).filter(
                          and_(
                            models.Account.id == accountid,
                            models.AccountOwner.owner_username == self.username
                         )
                        ).first()
                        if accountobject:
                            ta = models.TransactionAccount(
                                    transaction = transaction,
                                    account = accountobject,
                                    amount = amount,
                                    verified = False
                            )
                            self.add_to_response('accountbalance', accountid)
                            session.add(ta)
            # All accounts to keep have been poped out from "existing_accounts"
            # Delete all links remaining from this transaction to accounts
            for accountid in existing_accounts.keys():
                ta = models.TransactionAccount.query.filter(and_(
                    models.TransactionAccount.transaction == transaction,
                    models.TransactionAccount.account_id == accountid
                )).one()
                self.add_to_response('accountbalance', accountid)
                session.delete(ta)

            self.add_to_response('totalbalance')

        # Then, update categories
        if self.args.has_key('categories'):
            existing_categories = dict([tc.as_tuple() for tc in
                                        transaction.transaction_categories])
            new_categories_data = json.loads(self.args['categories'])
            for category_data in new_categories_data:
                if category_data.has_key('transaction_amount') and \
                   category_data.has_key('category_amount') and \
                   category_data.has_key('category'):
                    transaction_amount = category_data['transaction_amount']
                    category_amount = category_data['category_amount']
                    categoryid = category_data['category']
                    if categoryid in existing_categories.keys():
                        # Category already linked...
                        if existing_categories[categoryid]['category_amount'] \
                           != category_amount:
                            # ...but the amount is different
                            tc = models.TransactionCategory.query.filter(and_(
                         models.TransactionCategory.transaction == transaction,
                         models.TransactionCategory.category_id == categoryid
                            )).one()
                            tc.transaction_amount = transaction_amount
                            tc.category_amount = category_amount
                            tc.verified = False
                            self.add_to_response('categorybalance', categoryid)
                        existing_categories.pop(categoryid)
                    else:
                        # Category is not already linked
                        # Verify the category is owned by the user
                        categoryobject = models.Category.query.filter(
                          and_(
                           models.Category.id == categoryid,
                           models.Category.owner_username == self.username
                         )
                        ).first()
                        if categoryobject:
                            tc = models.TransactionCategory(
                                    transaction = transaction,
                                    category = categoryobject,
                                    transaction_amount = transaction_amount,
                                    category_amount = category_amount
                            )
                            self.add_to_response('categorybalance', categoryid)
                            session.add(tc)
            # All categories to keep have been poped out from
            # "existing_categories"
            # Delete all links remaining from this transaction to categories
            for categoryid in existing_categories.keys():
                tc = models.TransactionCategory.query.filter(and_(
                    models.TransactionCategory.transaction == transaction,
                    models.TransactionCategory.category_id == categoryid
                )).one()
                self.add_to_response('categorybalance', categoryid)
                session.delete(tc)

        session.commit()
        return transaction.as_dict()

    def delete(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        # TODO: Additional info, account balance and total balance
        if not transaction:
            self.notfound()
        session.delete(transaction)
        session.commit()

    def http_filter(self):
        self._Object__init_http()
        return jsonify(status=200, response=self.__filter(self.args))

    def __filter(self, filter):
        filters = [
            models.Transaction.owner_username == self.username,
        ]
        limit = 100
        after = False
        for part in filter.items():
            if filter_functions.has_key(part[0]):
                filters.extend(
                    filter_functions[part[0]](part[1])
                )
            elif part[0] == 'limit':
                try:
                    limit = min(int(part[1]), 100)
                except:
                    pass
            elif part[0] == 'after':
                try:
                    after = int(part[1])
                except:
                    pass
        if after:
            # Get offset of the "from" transaction
            # XXX: Is there a more efficient way to do so ?
            all_transactions = session.query(models.Transaction.id).order_by(
                                desc(models.Transaction.date)
                           ).filter(
                                and_(
                                    *filters
                                )
                           )
            all_ids = [t.id for t in all_transactions]
            try:
                offset = all_ids.index(after) + 1
            except:
                offset = 0
            transactions = models.Transaction.query.options(
                        joinedload(models.Transaction.currency),
                        joinedload(models.Transaction.transaction_accounts),
                        joinedload(models.Transaction.transaction_categories)
                    ).order_by(
                        desc(models.Transaction.date)
                    ).filter(
                        and_(
                            *filters
                        )
                    ).offset(offset).limit(limit)
            return [t.as_dict() for t in transactions]
        else:
            transactions = models.Transaction.query.options(
                        joinedload(models.Transaction.currency),
                        joinedload(models.Transaction.transaction_accounts),
                        joinedload(models.Transaction.transaction_categories)
                    ).order_by(
                        desc(models.Transaction.date)
                    ).filter(
                        and_(
                            *filters
                        )
                    ).limit(limit)
            return [t.as_dict() for t in transactions]

def account_filter(value):
    return [
        models.Transaction.id == models.TransactionAccount.transaction_id,
        models.TransactionAccount.account_id == value
    ]
def category_filter(value):
    return [
        models.Transaction.id == models.TransactionCategory.transaction_id,
        models.TransactionCategory.category_id == value
    ]
def currency_filter(value):
    return [
        models.Transaction.currency_id == core.Currency.id,
        core.Currency.isocode == value
    ]
def dates_filter(value):
    try:
        f = []
        fromdate, todate = value.split('-')
        if fromdate:
            f.append(
                models.Transaction.date >= datetime.date(
                                                int(fromdate[:4]),
                                                int(fromdate[4:6]),
                                                int(fromdate[6:])
                                            )
            )
        if todate:
            f.append(
                models.Transaction.date <= datetime.date(
                                                int(todate[:4]),
                                                int(todate[4:6]),
                                                int(todate[6:])
                                            )
            )
        return f
    except:
        return []

filter_functions = {
    'account': account_filter,
    'category': category_filter,
    'currency': currency_filter,
    'dates': dates_filter
}
<commit_msg>Additional information : balances when deleting a transaction<commit_after>#    Copyright 2012 Sebastien Maccagnoni-Munch
#
#    This file is part of OSPFM.
#
#    OSPFM is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    OSPFM is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with OSPFM.  If not, see <http://www.gnu.org/licenses/>.

import datetime, json

from flask import jsonify
from sqlalchemy import and_, or_, desc
from sqlalchemy.orm import joinedload

from ospfm import helpers
from ospfm.core import currency
from ospfm.core import models as core
from ospfm.transaction import models
from ospfm.database import session
from ospfm.objects import Object

class Transaction(Object):

    def __own_transaction(self, transactionid):
        return models.Transaction.query.options(
                          joinedload(models.Transaction.currency),
                          joinedload(models.Transaction.transaction_accounts),
                          joinedload(models.Transaction.transaction_categories)
               ).filter(
                    and_(
                        models.Transaction.owner_username == self.username,
                        models.Transaction.id == transactionid
                    )
               ).first()

    def list(self):
        # Transactions cannot be listed with the API
        self.forbidden()

    def create(self):
        if not (
            self.args.has_key('currency') and \
            self.args.has_key('date') and \
            self.args.has_key('description') and \
            self.args.has_key('amount')
        ):
            self.badrequest()
        # First, create the transaction object
        currency = core.Currency.query.filter(
            and_(
                core.Currency.isocode == self.args['currency'],
                or_(
                    core.Currency.owner_username == self.username,
                    core.Currency.owner == None
                )
            )
        ).first()
        if not currency:
            self.badrequest()
        date = helpers.date_from_string(self.args['date'])
        if not date:
            self.badrequest()
        description = self.args['description']
        if self.args.has_key('original_description'):
            original_description = self.args['original_description']
        else:
            original_description = description
        transaction = models.Transaction(
            owner_username = self.username,
            description = description,
            original_description = original_description,
            amount = self.args['amount'],
            currency = currency,
            date = date
        )
        session.add(transaction)

        # Next, create the links from the transaction to its accounts
        if self.args.has_key('accounts'):
            accounts = json.loads(self.args['accounts'])
            for accountdata in accounts:
                transaction_accounts = []
                if accountdata.has_key('amount'):
                    # If no amount is specified, do not associate the account
                    accountobject = models.Account.query.options(
                        joinedload(models.Account.account_owners)
                    ).filter(
                        and_(
                           models.Account.id == accountdata['account'],
                           models.AccountOwner.owner_username == self.username,
                        )
                    ).first()
                    if accountobject:
                        ta = models.TransactionAccount(
                                transaction = transaction,
                                account = accountobject,
                                amount = accountdata['amount'],
                                verified = False
                        )
                        session.add(ta)
                    self.add_to_response('accountbalance',
                                         accountdata['account'])
            self.add_to_response('totalbalance')

        # Next, create the links from the transaction to its categories
        if self.args.has_key('categories'):
            categories = json.loads(self.args['categories'])
            for categorydata in categories:
                transaction_categories = []
                if categorydata.has_key('transaction_amount') and \
                   categorydata.has_key('category_amount'):
                    # If no amount is specified, do not associate the category
                    categoryobject = models.Category.query.options(
                        joinedload(models.Category.currency)
                    ).filter(
                        and_(
                            models.Category.id == categorydata['category'],
                            models.Category.owner_username == self.username,
                        )
                    ).first()
                    if categoryobject:
                        tc = models.TransactionCategory(
                                transaction = transaction,
                                category = categoryobject,
                       transaction_amount = categorydata['transaction_amount'],
                              category_amount = categorydata['category_amount']
                        )
                        session.add(tc)
                    self.add_to_response('categorybalance',
                                         categorydata['category'])

        # Commit everything...
        session.commit()
        return transaction.as_dict()

    def read(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        if transaction:
            return transaction.as_dict()
        self.notfound()

    def update(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        if not transaction:
            self.notfound()

        # First, modifications on the Transaction object itself
        if self.args.has_key('description'):
            transaction.description = self.args['description']
        if self.args.has_key('amount'):
            transaction.amount = self.args['amount']
        if self.args.has_key('currency'):
            currency = core.Currency.query.filter(
                and_(
                    core.Currency.isocode == self.args['currency'],
                    or_(
                        core.Currency.owner_username == self.username,
                        core.Currency.owner == None
                    )
                )
            ).first()
            if currency:
                transaction.currency = currency
        if self.args.has_key('date'):
            date = helpers.date_from_string(self.args['date'])
            if date:
                transaction.date = date

        # Next, update accounts
        if self.args.has_key('accounts'):
            existing_accounts = dict([ta.as_tuple() for ta in
                                      transaction.transaction_accounts])
            new_accounts_data = json.loads(self.args['accounts'])
            for account_data in new_accounts_data:
                if account_data.has_key('amount') and \
                   account_data.has_key('account'):
                    amount = account_data['amount']
                    accountid = account_data['account']
                    if accountid in existing_accounts.keys():
                        # Account already linked...
                        if existing_accounts[accountid] != amount:
                            # ...but the amount is different
                            ta = models.TransactionAccount.query.filter(and_(
                          models.TransactionAccount.transaction == transaction,
                          models.TransactionAccount.account_id == accountid
                            )).one()
                            ta.amount = amount
                            ta.verified = False
                            self.add_to_response('accountbalance', accountid)
                        existing_accounts.pop(accountid)
                    else:
                        # Account is not already linked
                        # Verify the account is owned by the user
                        accountobject = models.Account.query.options(
                            joinedload(models.Account.account_owners)
                        ).filter(
                          and_(
                            models.Account.id == accountid,
                            models.AccountOwner.owner_username == self.username
                         )
                        ).first()
                        if accountobject:
                            ta = models.TransactionAccount(
                                    transaction = transaction,
                                    account = accountobject,
                                    amount = amount,
                                    verified = False
                            )
                            self.add_to_response('accountbalance', accountid)
                            session.add(ta)
            # All accounts to keep have been poped out from "existing_accounts"
            # Delete all links remaining from this transaction to accounts
            for accountid in existing_accounts.keys():
                ta = models.TransactionAccount.query.filter(and_(
                    models.TransactionAccount.transaction == transaction,
                    models.TransactionAccount.account_id == accountid
                )).one()
                self.add_to_response('accountbalance', accountid)
                session.delete(ta)

            self.add_to_response('totalbalance')

        # Then, update categories
        if self.args.has_key('categories'):
            existing_categories = dict([tc.as_tuple() for tc in
                                        transaction.transaction_categories])
            new_categories_data = json.loads(self.args['categories'])
            for category_data in new_categories_data:
                if category_data.has_key('transaction_amount') and \
                   category_data.has_key('category_amount') and \
                   category_data.has_key('category'):
                    transaction_amount = category_data['transaction_amount']
                    category_amount = category_data['category_amount']
                    categoryid = category_data['category']
                    if categoryid in existing_categories.keys():
                        # Category already linked...
                        if existing_categories[categoryid]['category_amount'] \
                           != category_amount:
                            # ...but the amount is different
                            tc = models.TransactionCategory.query.filter(and_(
                         models.TransactionCategory.transaction == transaction,
                         models.TransactionCategory.category_id == categoryid
                            )).one()
                            tc.transaction_amount = transaction_amount
                            tc.category_amount = category_amount
                            tc.verified = False
                            self.add_to_response('categorybalance', categoryid)
                        existing_categories.pop(categoryid)
                    else:
                        # Category is not already linked
                        # Verify the category is owned by the user
                        categoryobject = models.Category.query.filter(
                          and_(
                           models.Category.id == categoryid,
                           models.Category.owner_username == self.username
                         )
                        ).first()
                        if categoryobject:
                            tc = models.TransactionCategory(
                                    transaction = transaction,
                                    category = categoryobject,
                                    transaction_amount = transaction_amount,
                                    category_amount = category_amount
                            )
                            self.add_to_response('categorybalance', categoryid)
                            session.add(tc)
            # All categories to keep have been poped out from
            # "existing_categories"
            # Delete all links remaining from this transaction to categories
            for categoryid in existing_categories.keys():
                tc = models.TransactionCategory.query.filter(and_(
                    models.TransactionCategory.transaction == transaction,
                    models.TransactionCategory.category_id == categoryid
                )).one()
                self.add_to_response('categorybalance', categoryid)
                session.delete(tc)

        session.commit()
        return transaction.as_dict()

    def delete(self, transactionid):
        transaction = self.__own_transaction(transactionid)
        if not transaction:
            self.notfound()
        self.add_to_response('totalbalance')
        for ta in transaction.transaction_accounts:
            self.add_to_response('accountbalance', ta.account_id)
        for tc in transaction.transaction_categories:
            self.add_to_response('categorybalance', tc.category_id)
        session.delete(transaction)
        session.commit()

    def http_filter(self):
        self._Object__init_http()
        return jsonify(status=200, response=self.__filter(self.args))

    def __filter(self, filter):
        filters = [
            models.Transaction.owner_username == self.username,
        ]
        limit = 100
        after = False
        for part in filter.items():
            if filter_functions.has_key(part[0]):
                filters.extend(
                    filter_functions[part[0]](part[1])
                )
            elif part[0] == 'limit':
                try:
                    limit = min(int(part[1]), 100)
                except:
                    pass
            elif part[0] == 'after':
                try:
                    after = int(part[1])
                except:
                    pass
        if after:
            # Get offset of the "from" transaction
            # XXX: Is there a more efficient way to do so ?
            all_transactions = session.query(models.Transaction.id).order_by(
                                desc(models.Transaction.date)
                           ).filter(
                                and_(
                                    *filters
                                )
                           )
            all_ids = [t.id for t in all_transactions]
            try:
                offset = all_ids.index(after) + 1
            except:
                offset = 0
            transactions = models.Transaction.query.options(
                        joinedload(models.Transaction.currency),
                        joinedload(models.Transaction.transaction_accounts),
                        joinedload(models.Transaction.transaction_categories)
                    ).order_by(
                        desc(models.Transaction.date)
                    ).filter(
                        and_(
                            *filters
                        )
                    ).offset(offset).limit(limit)
            return [t.as_dict() for t in transactions]
        else:
            transactions = models.Transaction.query.options(
                        joinedload(models.Transaction.currency),
                        joinedload(models.Transaction.transaction_accounts),
                        joinedload(models.Transaction.transaction_categories)
                    ).order_by(
                        desc(models.Transaction.date)
                    ).filter(
                        and_(
                            *filters
                        )
                    ).limit(limit)
            return [t.as_dict() for t in transactions]

def account_filter(value):
    return [
        models.Transaction.id == models.TransactionAccount.transaction_id,
        models.TransactionAccount.account_id == value
    ]
def category_filter(value):
    return [
        models.Transaction.id == models.TransactionCategory.transaction_id,
        models.TransactionCategory.category_id == value
    ]
def currency_filter(value):
    return [
        models.Transaction.currency_id == core.Currency.id,
        core.Currency.isocode == value
    ]
def dates_filter(value):
    try:
        f = []
        fromdate, todate = value.split('-')
        if fromdate:
            f.append(
                models.Transaction.date >= datetime.date(
                                                int(fromdate[:4]),
                                                int(fromdate[4:6]),
                                                int(fromdate[6:])
                                            )
            )
        if todate:
            f.append(
                models.Transaction.date <= datetime.date(
                                                int(todate[:4]),
                                                int(todate[4:6]),
                                                int(todate[6:])
                                            )
            )
        return f
    except:
        return []

filter_functions = {
    'account': account_filter,
    'category': category_filter,
    'currency': currency_filter,
    'dates': dates_filter
}
<|endoftext|>


<commit_before># coding=utf-8
# Copyright 2021 TF.Text Authors.
#
# 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.

"""TF.Text is a TensorFlow library of text related ops, modules, and subgraphs.

TF.Text is a TensorFlow library of text related ops, modules, and subgraphs. The
library can perform the preprocessing regularly required by text-based models,
and includes other features useful for sequence modeling not provided by core
TensorFlow.

See the README on GitHub for further documentation.
http://github.com/tensorflow/text
"""

import os

from setuptools import find_packages
from setuptools import setup
from setuptools.command.install import install
from setuptools.dist import Distribution

project_name = 'tensorflow-text'
project_version = '2.7.0'

class BinaryDistribution(Distribution):
  """This class is needed in order to create OS specific wheels."""

  def is_pure(self):
    return False

  def has_ext_modules(self):
    return True

class InstallPlatlib(install):
  """This is needed to set the library to platlib compliant."""

  def finalize_options(self):
    """For more info; see http://github.com/google/or-tools/issues/616 ."""
    install.finalize_options(self)
    self.install_lib = self.install_platlib
    self.install_libbase = self.install_lib
    self.install_lib = os.path.join(self.install_lib, self.extra_dirs)

DOCLINES = __doc__.split('\n')

setup(
    name=project_name,
    version=project_version.replace('-', ''),
    description=DOCLINES[0],
    long_description='\n'.join(DOCLINES[2:]),
    author='Google Inc.',
    author_email='packages@tensorflow.org',
    url='http://github.com/tensorflow/text',
    license='Apache 2.0',
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    cmdclass={'install': InstallPlatlib},
    distclass=BinaryDistribution,
    install_requires=[
        "tensorflow>=2.7.0, <2.8; platform_machine != 'arm64'",
        "tensorflow-macos>=2.6.0, <2.7; platform_system == 'Darwin' and platform_machine == 'arm64'",
        "tensorflow_hub>=0.8.0",
    ],
    extras_require={
        'tensorflow_cpu': ['tensorflow-cpu>=2.4.0rc0, <2.5',],
        'tests': [
            'absl-py',
            'pytest',
            'tensorflow-datasets>=3.2.0',
        ],
    },
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Intended Audience :: Education',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3 :: Only',
        'Topic :: Scientific/Engineering',
        'Topic :: Scientific/Engineering :: Artificial Intelligence',
        'Topic :: Software Development',
        'Topic :: Software Development :: Libraries',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
    keywords='tensorflow text machine learning',
)
<commit_msg>Remove requires<commit_after># coding=utf-8
# Copyright 2021 TF.Text Authors.
#
# 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.

"""TF.Text is a TensorFlow library of text related ops, modules, and subgraphs.

TF.Text is a TensorFlow library of text related ops, modules, and subgraphs. The
library can perform the preprocessing regularly required by text-based models,
and includes other features useful for sequence modeling not provided by core
TensorFlow.

See the README on GitHub for further documentation.
http://github.com/tensorflow/text
"""

import os

from setuptools import find_packages
from setuptools import setup
from setuptools.command.install import install
from setuptools.dist import Distribution

project_name = 'tensorflow-text'
project_version = '2.7.0'

class BinaryDistribution(Distribution):
  """This class is needed in order to create OS specific wheels."""

  def is_pure(self):
    return False

  def has_ext_modules(self):
    return True

class InstallPlatlib(install):
  """This is needed to set the library to platlib compliant."""

  def finalize_options(self):
    """For more info; see http://github.com/google/or-tools/issues/616 ."""
    install.finalize_options(self)
    self.install_lib = self.install_platlib
    self.install_libbase = self.install_lib
    self.install_lib = os.path.join(self.install_lib, self.extra_dirs)

DOCLINES = __doc__.split('\n')

setup(
    name=project_name,
    version=project_version.replace('-', ''),
    description=DOCLINES[0],
    long_description='\n'.join(DOCLINES[2:]),
    author='Google Inc.',
    author_email='packages@tensorflow.org',
    url='http://github.com/tensorflow/text',
    license='Apache 2.0',
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    cmdclass={'install': InstallPlatlib},
    distclass=BinaryDistribution,
    install_requires=[
        'tensorflow_hub>=0.8.0',
    ],
    extras_require={
        'tensorflow_cpu': ['tensorflow-cpu>=2.4.0rc0, <2.5',],
        'tests': [
            'absl-py',
            'pytest',
            'tensorflow-datasets>=3.2.0',
        ],
    },
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Intended Audience :: Education',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3 :: Only',
        'Topic :: Scientific/Engineering',
        'Topic :: Scientific/Engineering :: Artificial Intelligence',
        'Topic :: Software Development',
        'Topic :: Software Development :: Libraries',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
    keywords='tensorflow text machine learning',
)
<|endoftext|>


<commit_before>from django.db.models.fields import Field
from django.db import models
from django.contrib.gis.db import models
from django.urls import reverse

# Create your models here.

GREEN_ROOF_TYPES = (
	(1, 'intensive'),
    (2, 'semi-intensive'),
    (3, 'extensive'),
    (4, 'biosolar'),
	)

ACCESSABILITY = (
	(1, 'yes'),
	(2, 'no'),
)

OWNERSHIP = (
	(1, 'private'),
	(2, 'public'),
)

class City(models.Model):
	name = models.CharField(max_length=128)

	def __str__(self):
		return "City: ".format(self.name)

#Class with name of the district in specific city
class District(models.Model):
	name = models.CharField(max_length=256)
	city = models.ForeignKey(City, related_name='city') #+ on_delete=models.CASCADE???

	def __str__(self):
		return "District: {}".format(self.name)

class GreenRoof(models.Model):
    district = models.ForeignKey(District, related_name='district') #+ on_delete=models.CASCADE???
    roof_address = models.CharField(max_length=256)
    roof_type = models.IntegerField(choices=GREEN_ROOF_TYPES, verbose_name='Green roof type: ')
    area = models.FloatField()
    total_place_area = models.FloatField()
    access = models.IntegerField(choices=ACCESSABILITY, verbose_name='Accessability: ')
    ownership_type = models.IntegerField(choices=OWNERSHIP, verbose_name='Type of the building: ')
    additional_info = models.TextField(null=True)

    # GeoDjango-specific: a geometry field (MultiPolygonField)
    mpoly = models.MultiPolygonField()

    lon = models.FloatField()
    lat = models.FloatField()

    class Meta:
    	verbose_name='Green roof'
    	verbose_name_plural='Green roofs'

    def __str__(self):
        return "Green roof address: {}, type: {}, area: {}".format(self.roof_address, self.roof_type, self.area)

    # def get_absolute_url(self):
    #     return reverse('wola', kwargs={'pk' : self.id})<commit_msg>Updated models<commit_after>from django.db.models.fields import Field
from django.db import models
from django.contrib.gis.db import models
from django.urls import reverse

# Create your models here.

DISTRICTS = (
	(1, 'Wola'),
	(2, 'Śródmieście'),
	(3, 'Mokotów')
	)

GREEN_ROOF_TYPES = (
	(1, 'intensive'),
    (2, 'semi-intensive'),
    (3, 'extensive'),
    (4, 'biosolar'),
	)

ACCESSABILITY = (
	(1, 'yes'),
	(2, 'no'),
)

OWNERSHIP = (
	(1, 'private'),
	(2, 'public'),
)

class City(models.Model):
	name = models.CharField(max_length=128)

	def __str__(self):
		return "City: ".format(self.name)

#Class with name of the district in specific city
class District(models.Model):
	name = models.CharField(max_length=256)
	city = models.ForeignKey(City) #+ on_delete=models.CASCADE???

	def __str__(self):
		return "District: {}".format(self.name)

class GreenRoof(models.Model):
    district = models.ForeignKey(District) #+ on_delete=models.CASCADE???
    roof_address = models.CharField(max_length=256)
    roof_type = models.IntegerField(choices=GREEN_ROOF_TYPES, verbose_name='Green roof type: ')
    area = models.FloatField()
    total_place_area = models.FloatField()
    access = models.IntegerField(choices=ACCESSABILITY, verbose_name='Accessability: ')
    ownership_type = models.IntegerField(choices=OWNERSHIP, verbose_name='Type of the building: ')
    additional_info = models.CharField(max_length=1024, null=True)

    # GeoDjango-specific: a geometry field (MultiPolygonField)
    mpoly = models.MultiPolygonField()

    lon = models.FloatField()
    lat = models.FloatField()

    class Meta:
    	verbose_name='Green roof'
    	verbose_name_plural='Green roofs'

    def __str__(self):
        return "Green roof address: {}, type: {}, area: {}".format(self.roof_address, self.roof_type, self.area)

    # def get_absolute_url(self):
    #     return reverse('wola', kwargs={'pk' : self.id})<|endoftext|>


<commit_before># Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.

import logging
import requests
import time
from iris.constants import HIPCHAT_SUPPORT

logger = logging.getLogger(__name__)

class iris_hipchat(object):
    supports = frozenset([HIPCHAT_SUPPORT])

    def __init__(self, config):
        self.config = config
        self.modes = {
            'hipchat': self.send_message
        }
        self.proxy = None
        if 'proxy' in self.config:
            host = self.config['proxy']['host']
            port = self.config['proxy']['port']
            self.proxy = {'http': 'http://%s:%s' % (host, port),
                          'https': 'https://%s:%s' % (host, port)}
        self.token = self.config.get('auth_token')
        self.room_id = int(self.config.get('room_id'))
        self.debug = self.config.get('debug')
        self.endpoint_url = self.config.get('base_url')

        self.headers = {
            'Content-type': 'application/json',
        }

    def get_message_payload(self, message, mention):
        """Send notification to specified HipChat room"""
        clean_message = "{0} {1}".format(mention, message['body'])
        message_dict = {
            'message': clean_message,
            'color': 'red',
            'notify': 'true',
            'message_format': "text",
        }
        return message_dict

    def parse_destination(self, destination):
        """Determine room_id, token and user to mention
           We accept 3 formats:
             - Just a mention (@testuser)
             - Room_id and Token (12341;a20asdfgjahdASDfaskw)
             - Room_id, Token and mention (12341;a20asdfgjahdASDfaskw;@testuser)
        """
        room_id = self.room_id
        token = self.token
        mention = ""

        if destination.startswith("@"):
            mention = destination
        elif ";" in destination:
            dparts = destination.split(";")
            if len(dparts) == 3:
                try:
                    room_id = int(dparts[0])
                except ValueError:
                    logger.error("Invalid destination: %s. Using default room_id", destination)
                token = dparts[1]
                mention = dparts[2]
            elif len(dparts) == 2:
                try:
                    room_id = int(dparts[0])
                except ValueError:
                    logger.error("Invalid destination: %s. Using default room_id", destination)
                token = dparts[1]
            else:
                logger.error("Invalid destination: %s. Contains %s fields.", destination, len(dparts))
        else:
                logger.error("Invalid destination: %s. Neither @user or ; separated value.", destination)

        return room_id, token, mention

    def send_message(self, message):
        start = time.time()
        room_id, token, mention = self.parse_destination(message['destination'])

        payload = self.get_message_payload(message, mention)
        notification_url = '{0}/v2/room/{1}/notification'.format(self.endpoint_url, room_id)
        params = {'auth_token': token}

        if self.debug:
            logger.info('debug: %s', payload)
        else:
            try:
                response = requests.post(notification_url,
                                         headers=self.headers,
                                         params=params,
                                         json=payload,
                                         proxies=self.proxy)
                if response.status_code == 200 or response.status_code == 204:
                    return time.time() - start
                else:
                    logger.error('Failed to send message to hipchat: %d',
                                 response.status_code)
                    logger.error("Response: %s", response.content)
            except Exception as err:
                logger.exception('Hipchat post request failed: %s', err)

    def send(self, message, customizations=None):
        return self.modes[message['mode']](message)
<commit_msg>fix incorrect indenting<commit_after># Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.

import logging
import requests
import time
from iris.constants import HIPCHAT_SUPPORT

logger = logging.getLogger(__name__)

class iris_hipchat(object):
    supports = frozenset([HIPCHAT_SUPPORT])

    def __init__(self, config):
        self.config = config
        self.modes = {
            'hipchat': self.send_message
        }
        self.proxy = None
        if 'proxy' in self.config:
            host = self.config['proxy']['host']
            port = self.config['proxy']['port']
            self.proxy = {'http': 'http://%s:%s' % (host, port),
                          'https': 'https://%s:%s' % (host, port)}
        self.token = self.config.get('auth_token')
        self.room_id = int(self.config.get('room_id'))
        self.debug = self.config.get('debug')
        self.endpoint_url = self.config.get('base_url')

        self.headers = {
            'Content-type': 'application/json',
        }

    def get_message_payload(self, message, mention):
        """Send notification to specified HipChat room"""
        clean_message = "{0} {1}".format(mention, message['body'])
        message_dict = {
            'message': clean_message,
            'color': 'red',
            'notify': 'true',
            'message_format': "text",
        }
        return message_dict

    def parse_destination(self, destination):
        """Determine room_id, token and user to mention
           We accept 3 formats:
             - Just a mention (@testuser)
             - Room_id and Token (12341;a20asdfgjahdASDfaskw)
             - Room_id, Token and mention (12341;a20asdfgjahdASDfaskw;@testuser)
        """
        room_id = self.room_id
        token = self.token
        mention = ""

        if destination.startswith("@"):
            mention = destination
        elif ";" in destination:
            dparts = destination.split(";")
            if len(dparts) == 3:
                try:
                    room_id = int(dparts[0])
                except ValueError:
                    logger.error("Invalid destination: %s. Using default room_id", destination)
                token = dparts[1]
                mention = dparts[2]
            elif len(dparts) == 2:
                try:
                    room_id = int(dparts[0])
                except ValueError:
                    logger.error("Invalid destination: %s. Using default room_id", destination)
                token = dparts[1]
            else:
                logger.error("Invalid destination: %s. Contains %s fields.", destination, len(dparts))
        else:
            logger.error("Invalid destination: %s. Neither @user or ; separated value.", destination)

        return room_id, token, mention

    def send_message(self, message):
        start = time.time()
        room_id, token, mention = self.parse_destination(message['destination'])

        payload = self.get_message_payload(message, mention)
        notification_url = '{0}/v2/room/{1}/notification'.format(self.endpoint_url, room_id)
        params = {'auth_token': token}

        if self.debug:
            logger.info('debug: %s', payload)
        else:
            try:
                response = requests.post(notification_url,
                                         headers=self.headers,
                                         params=params,
                                         json=payload,
                                         proxies=self.proxy)
                if response.status_code == 200 or response.status_code == 204:
                    return time.time() - start
                else:
                    logger.error('Failed to send message to hipchat: %d',
                                 response.status_code)
                    logger.error("Response: %s", response.content)
            except Exception as err:
                logger.exception('Hipchat post request failed: %s', err)

    def send(self, message, customizations=None):
        return self.modes[message['mode']](message)
<|endoftext|>


<commit_before>"""
Filename:     calc_pe.py
Author:       Damien Irving, irving.damien@gmail.com
Description:  Calculate precipitation minus evaporation

"""

# Import general Python modules

import sys, os, pdb
import argparse
import numpy
import iris
from iris.experimental.equalise_cubes import equalise_attributes

# Import my modules

cwd = os.getcwd()
repo_dir = '/'
for directory in cwd.split('/')[1:]:
    repo_dir = os.path.join(repo_dir, directory)
    if directory == 'ocean-analysis':
        break

modules_dir = os.path.join(repo_dir, 'modules')
sys.path.append(modules_dir)

try:
    import general_io as gio
except ImportError:
    raise ImportError('Must run this script from anywhere within the ocean-analysis git repo')

# Define functions

history = []

def save_history(cube, field, filename):
    """Save the history attribute when reading the data.
    (This is required because the history attribute differs between input files
      and is therefore deleted upon equilising attributes)
    """

    history.append(cube.attributes['history'])

def get_file_names(precip_file, evap_dir, pe_dir):
    """Get evap and p-e file names corresponding to precip file."""

    precip_fname = precip_file.split('/')[-1]

    evap_fname = precip_fname.replace('pr_', 'evspsbl_')
    evap_file = evap_dir + '/' + evap_fname

    pe_fname = precip_fname.replace('pr_', 'pe_')
    pe_file = pe_dir + '/' + pe_fname

    return evap_file, pe_file

def main(inargs):
    """Run the program."""

    for precip_file in inargs.precip_files:
        precip_cube = iris.load_cube(precip_file, inargs.precip_var)
        evap_file, pe_file = get_file_names(precip_file, inargs.evap_dir, inargs.pe_dir)

        evap_cube = iris.load_cube(evap_file, inargs.evap_var)

        pe_cube = precip_cube - evap_cube

        pe_cube.metadata = precip_cube.metadata
        iris.std_names.STD_NAMES['precipitation_minus_evaporation_flux'] = {'canonical_units': pe_cube.units}
        pe_cube.standard_name = 'precipitation_minus_evaporation_flux'
        pe_cube.long_name = 'precipitation minus evaporation flux'
        pe_cube.var_name = 'pe'
        metadata_dict = {precip_file: precip_cube.attributes['history'],
                         evap_file: evap_cube.attributes['history']}
        pe_cube.attributes['history'] = gio.write_metadata(file_info=metadata_dict)

        assert pe_cube.data.dtype == numpy.float32
        iris.save(pe_cube, pe_file, netcdf_format='NETCDF3_CLASSIC')
        print(pe_file)
        del pe_cube

if __name__ == '__main__':

    extra_info ="""
example:

author:
    Damien Irving, irving.damien@gmail.com

"""

    description='Calculate the precipitation minus evaporation'
    parser = argparse.ArgumentParser(description=description,
                                     epilog=extra_info,
                                     argument_default=argparse.SUPPRESS,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument("precip_files", type=str, nargs='*', help="Precipitation file")
    parser.add_argument("precip_var", type=str, help="Precipitation standard_name")
    parser.add_argument("evap_dir", type=str, help="Evaporation directory")
    parser.add_argument("evap_var", type=str, help="Evaporation standard_name")
    parser.add_argument("pe_dir", type=str, help="Output p-e directory")

    args = parser.parse_args()

    main(args)
<commit_msg>Added handling for evs<commit_after>"""
Filename:     calc_pe.py
Author:       Damien Irving, irving.damien@gmail.com
Description:  Calculate precipitation minus evaporation

"""

# Import general Python modules

import sys, os, pdb
import argparse
import numpy
import iris
from iris.experimental.equalise_cubes import equalise_attributes

# Import my modules

cwd = os.getcwd()
repo_dir = '/'
for directory in cwd.split('/')[1:]:
    repo_dir = os.path.join(repo_dir, directory)
    if directory == 'ocean-analysis':
        break

modules_dir = os.path.join(repo_dir, 'modules')
sys.path.append(modules_dir)

try:
    import general_io as gio
except ImportError:
    raise ImportError('Must run this script from anywhere within the ocean-analysis git repo')

# Define functions

history = []

def save_history(cube, field, filename):
    """Save the history attribute when reading the data.
    (This is required because the history attribute differs between input files
      and is therefore deleted upon equilising attributes)
    """

    history.append(cube.attributes['history'])

def get_file_names(precip_file, evap_dir, pe_dir, evs=False):
    """Get evap and p-e file names corresponding to precip file."""

    precip_fname = precip_file.split('/')[-1]

    evap_var = 'evs_' if evs else 'evspsbl_'
    evap_fname = precip_fname.replace('pr_', evap_var)
    evap_file = evap_dir + '/' + evap_fname

    pe_fname = precip_fname.replace('pr_', 'pe_')
    pe_file = pe_dir + '/' + pe_fname

    return evap_file, pe_file

def main(inargs):
    """Run the program."""

    for precip_file in inargs.precip_files:
        precip_cube = iris.load_cube(precip_file, inargs.precip_var)
        evap_file, pe_file = get_file_names(precip_file, inargs.evap_dir, inargs.pe_dir, evs=inargs.evs)

        evap_cube = iris.load_cube(evap_file, inargs.evap_var)

        pe_cube = precip_cube - evap_cube

        pe_cube.metadata = precip_cube.metadata
        iris.std_names.STD_NAMES['precipitation_minus_evaporation_flux'] = {'canonical_units': pe_cube.units}
        pe_cube.standard_name = 'precipitation_minus_evaporation_flux'
        pe_cube.long_name = 'precipitation minus evaporation flux'
        pe_cube.var_name = 'pe'
        metadata_dict = {precip_file: precip_cube.attributes['history'],
                         evap_file: evap_cube.attributes['history']}
        pe_cube.attributes['history'] = gio.write_metadata(file_info=metadata_dict)

        assert pe_cube.data.dtype == numpy.float32
        iris.save(pe_cube, pe_file, netcdf_format='NETCDF3_CLASSIC')
        print(pe_file)
        del pe_cube

if __name__ == '__main__':

    extra_info ="""
example:

author:
    Damien Irving, irving.damien@gmail.com

"""

    description='Calculate the precipitation minus evaporation'
    parser = argparse.ArgumentParser(description=description,
                                     epilog=extra_info,
                                     argument_default=argparse.SUPPRESS,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument("precip_files", type=str, nargs='*', help="Precipitation file")
    parser.add_argument("precip_var", type=str, help="Precipitation standard_name")
    parser.add_argument("evap_dir", type=str, help="Evaporation directory")
    parser.add_argument("evap_var", type=str, help="Evaporation standard_name")
    parser.add_argument("pe_dir", type=str, help="Output p-e directory")

    parser.add_argument("--evs", action="store_true", default=False,
                        help="Evaporation variable is evs instead of evspsbl")

    args = parser.parse_args()

    main(args)
<|endoftext|>


<commit_before>from __future__ import absolute_import

from dependencies import this
from django.views.generic import FormView, View

def view(injector):
    """Create Django class-based view from injector class."""

    handler = create_handler(View)
    apply_http_methods(handler, injector)
    return injector.let(as_view=handler.as_view)

def form_view(injector):
    """Create Django form processing class-based view from injector class."""

    handler = create_handler(FormView)
    apply_form_methods(handler, injector)
    return injector.let(as_view=handler.as_view)

def create_handler(from_class):

    class Handler(from_class):
        pass

    return Handler

def apply_http_methods(handler, injector):

    for method in ["get", "post", "put", "patch", "delete", "head", "options", "trace"]:
        if method in injector:

            def __view(self, request, *args, **kwargs):
                ns = injector.let(
                    view=self,
                    request=request,
                    args=args,
                    kwargs=kwargs,
                    user=this.request.user,
                )
                return getattr(ns, __view.method)()

            __view.method = method
            setattr(handler, method, __view)

def apply_form_methods(handler, injector):

    handler.form_class = injector.form_cls
    handler.template_name = injector.template_name
    handler.success_url = injector.success_url

    for method in ["form_valid", "form_invalid"]:
        if method in injector:

            def __method(self, form):
                ns = injector.let(
                    view=self,
                    form=form,
                    request=this.view.request,
                    args=this.view.args,
                    kwargs=this.view.kwargs,
                    user=this.request.user,
                )
                return getattr(ns, __method.method)()

            __method.method = method
            setattr(handler, method, __method)
<commit_msg>Add developer notes.<commit_after>from __future__ import absolute_import

from dependencies import this
from django.views.generic import FormView, View

def view(injector):
    """Create Django class-based view from injector class."""

    handler = create_handler(View)
    apply_http_methods(handler, injector)
    return injector.let(as_view=handler.as_view)

def form_view(injector):
    """Create Django form processing class-based view from injector class."""

    handler = create_handler(FormView)
    apply_form_methods(handler, injector)
    return injector.let(as_view=handler.as_view)

def create_handler(from_class):

    class Handler(from_class):
        pass

    return Handler

def apply_http_methods(handler, injector):

    for method in ["get", "post", "put", "patch", "delete", "head", "options", "trace"]:
        if method in injector:

            def __view(self, request, *args, **kwargs):
                ns = injector.let(
                    view=self,
                    request=request,
                    args=args,
                    kwargs=kwargs,
                    user=this.request.user,
                )
                return getattr(ns, __view.method)()

            __view.method = method
            setattr(handler, method, __view)

# TODO: allow to override http_method_not_allowed?

def apply_form_methods(handler, injector):

    handler.form_class = injector.form_cls
    handler.template_name = injector.template_name
    handler.success_url = injector.success_url

    for method in ["form_valid", "form_invalid"]:
        if method in injector:

            def __method(self, form):
                ns = injector.let(
                    view=self,
                    form=form,
                    request=this.view.request,
                    args=this.view.args,
                    kwargs=this.view.kwargs,
                    user=this.request.user,
                )
                return getattr(ns, __method.method)()

            __method.method = method
            setattr(handler, method, __method)

# TODO:
#
# TemplateResponseMixin.template_name
# TemplateResponseMixin.template_engine
# TemplateResponseMixin.response_class
# TemplateResponseMixin.content_type
#
# FormMixin.initial
# FormMixin.form_class
# FormMixin.success_url
# FormMixin.prefix
#
# ContextMixin.extra_context
<|endoftext|>


<commit_before>
from sklearn.base import BaseEstimator, ClassifierMixin, clone
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import _name_estimators
import numpy as np
import operator

class MajorityVoteClassifier(BaseEstimator, ClassifierMixin):
    """ A Majority Vote Classifier"""

    def __init__(self, classifiers, vote='classlabel', weights=None):
        """ Init """
        self.classifiers = classifiers
        self.named_classifiers = {
            key: value for key, value in _name_estimators(classifiers)
        }
        self.vote = vote
        self.weights = weights

    def fit(self, X, y):
        """ Fit classifiers"""
        # Use LabelEncoder to encode target classes
        # from 0 to n
        self.lablenc_ = LabelEncoder()
        self.classes_ = []
        self.lablenc_.fit(y)
        self.classes_ = self.lablenc_.classes_
        self.classifiers_ = []
        for clf in self.classifiers:
            fitted_clf = clone(clf).fit(X, self.lablenc_.transform(y))
            self.classifiers_.append(fitted_clf)

        return self

def main():
    """ Main """
    print "Main"

if __name__ == "__main__":
    main()
<commit_msg>[Helper] Implemented Majority Vote Classifier<commit_after>
from sklearn.base import BaseEstimator, ClassifierMixin, clone
from sklearn.externals import six
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import _name_estimators
import numpy as np

class MajorityVoteClassifier(BaseEstimator, ClassifierMixin):
    """ A Majority Vote Classifier"""

    def __init__(self, classifiers, vote='classlabel', weights=None):
        """ Init """
        self.classifiers = classifiers
        self.named_classifiers = {
            key: value for key, value in _name_estimators(classifiers)
        }
        self.vote = vote
        self.weights = weights

    def fit(self, X, y):
        """ Fit classifiers"""
        # Use LabelEncoder to encode target classes
        # from 0 to n
        self.lablenc_ = LabelEncoder()
        self.classes_ = []
        self.lablenc_.fit(y)
        self.classes_ = self.lablenc_.classes_
        self.classifiers_ = []
        for clf in self.classifiers:
            fitted_clf = clone(clf).fit(X, self.lablenc_.transform(y))
            self.classifiers_.append(fitted_clf)

        return self

    def predict(self, X):
        """ Predict """
        if self.vote == 'classlabel':
            # Collect predictions from every Classifier
            predictions = np.asarray([clf.predict(X) for clf in self.classifiers_]).T
            maj_vote = np.apply_along_axis(lambda x: np.argmax(np.bincount(x,
                                                                           weights=self.weights)),
                                           axis=1,
                                           arr=predictions)
        elif self.vote == 'probability':
            maj_vote = np.argmax(self.predict_proba(X),
                                 axis=1)

        maj_vote = self.lablenc_.inverse_transform(maj_vote)
        return maj_vote

    def predict_proba(self, X):
        """ Predict probability """
        probas = np.asarray([clf.predict_proba(X) for clf in self.classifiers_])
        avg_probas = np.average(probas, axis=0, weights=self.weights)
        return avg_probas

    def get_params(self, deep=True):
        """ Get classifier parameter names for GridSearch"""
        if not deep:
            return super(MajorityVoteClassifier,
                         self).get_params(deep=False)
        else:
            out = self.named_classifiers.copy()
            for name, step in\
                    six.iteritems(self.named_classifiers):
                for key, value in six.iteritems(
                        step.get_params(deep=True)):
                    out['%s__%s' % (name, key)] = value

        return out

def main():
    """ Main """
    print "Main"

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