<commit_before>import traceback

from django.http import HttpResponse

from tastypie import http
from tastypie.resources import Resource
from tastypie.authorization import Authorization
from tastypie.authentication import ApiKeyAuthentication, MultiAuthentication

from rhizome.api.serialize import CustomSerializer
from rhizome.api.custom_session_authentication import CustomSessionAuthentication
from rhizome.api.custom_cache import CustomCache
from rhizome.api.exceptions import RhizomeApiException

from rhizome.models import LocationPermission, Location

class BaseResource(Resource):
    '''
    https://github.com/django-tastypie/django-tastypie/blob/master/tastypie/resources.py
    '''

    class Meta:
        authentication = MultiAuthentication(
            CustomSessionAuthentication(), ApiKeyAuthentication())
        allowed_methods = ['get', 'post', 'patch']
        authorization = Authorization()
        always_return_data = True
        cache = CustomCache()
        serializer = CustomSerializer()

    ### Tastypie Methods ###
    def __init__(self, api_name=None):
        '''
        In Rhizome, all user permissinos are bound by the top level location
        that they can see.  For instance, if i am the head of Zika data analysis
        in the Bahia Province of Brazil, that woul be my top level location.

        The top_lvl_location_id is used in the `get_locations_to_return_from_url`
        function, so that for shapes, locatinos and datapoints the user only
        can see what they are permissioned to.

        This is an additional parameter needed by the rhizome API to behave
        properly.  This variable is set in the dispatch method.
        '''

        self.top_lvl_location_id = None

        return super(BaseResource, self).__init__(api_name=None)

    def apply_filters(self, request, applicable_filters):
        """
        An ORM-specific implementation of ``apply_filters``.
        The default simply applies the ``applicable_filters`` as ``**kwargs``,
        but should make it possible to do more advanced things.
        """
        return self.get_object_list(request).filter(**applicable_filters)

    def get_object_list(self, request):
        """
        An ORM-specific implementation of ``get_object_list``.
        Returns a queryset that may have been limited by other overrides.
        """
        return super(BaseResource, self).get_object_list(self, request)

    def obj_get_list(self, bundle, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.
        ``GET`` dictionary of bundle.request can be used to narrow the query.
        """
        return super(BaseResource, self).obj_get_list(bundle, **kwargs)

    def save(self, bundle, skip_errors=False):

        return super(BaseResoruce, self).save(bundle, skip_errors)

    def lookup_kwargs_with_identifiers(self, bundle, kwargs):
        """
        Kwargs here represent uri identifiers Ex: /repos/<user_id>/<repo_name>/
        We need to turn those identifiers into Python objects for generating
        lookup parameters that can find them in the DB
        """
        return super(BaseResource, self)\
            .lookup_kwargs_with_identifiers(bundle, kwargs)

    def rollback(self, bundles):
        """
        A ORM-specific implementation of ``rollback``.
        Given the list of bundles, delete all models pertaining to those
        bundles.
        """
        return super(BaseResource, self).rolback(bundles)

    def obj_update(self, bundle, skip_errors=False, **kwargs):
        """
        A ORM-specific implementation of ``obj_update``.
        """
        return super(BaseResource, self)\
            .obj_update(bundle, skip_errors=False, **kwargs)

    def obj_delete_list_for_update(self, bundle, **kwargs):
        """
        A ORM-specific implementation of ``obj_delete_list_for_update``.
        """
        return super(BaseResource, self)\
            .obj_delete_list_for_update(self, bundle, **kwargs)

    def detail_uri_kwargs(self, bundle_or_obj):
        """
        Given a ``Bundle`` or an object (typically a ``Model`` instance),
        it returns the extra kwargs needed to generate a detail URI.
        By default, it uses this resource's ``detail_uri_name`` in order to
        create the URI.
        """
        return super(BaseResource, self).detail_uri_kwargs(bundle_or_obj)

    ############################
    ## Custom Rhizome Methods ##
    ############################

    def validate_filters(self, request):
        '''
        Make sure that all required filters have been passed in
        '''

        filters = {}

        # Grab a mutable copy of the request#
        if hasattr(request, 'GET'):
            filters = request.GET.copy()

        # check required parameters and raise exception if one is missing #
        if hasattr(self._meta, 'GET_params_required'):
            keys_req = self._meta.GET_params_required
            missing_keys = list(set(keys_req).difference(set(filters.keys())))
            if len(missing_keys) > 0:
                msg = 'Missing required parameter %s' % missing_keys[0]
                raise RhizomeApiException(msg)

        return filters

    def dispatch(self, request_type, request, **kwargs):
        """
        Overrides Tastypie and calls get_list for GET, obj_create for POST,
        get_detail and obj_delete when fetching or delete an object with
        primary key requested
        """

        try:
            self.top_lvl_location_id = LocationPermission.objects.get(
                user_id=request.user.id).top_lvl_location_id
        except LocationPermission.DoesNotExist:
            self.top_lvl_location_id = Location.objects\
                .filter(parent_location_id=None)[0].id

        allowed_methods = getattr(
            self._meta, "%s_allowed_methods" % request_type, None)

        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            response = method(request, **kwargs)
        # except RhizomeApiException as error: ## use more specific exception.
        except Exception as error: ## use more specific exception.
            data = {
                'traceback': traceback.format_exc(),
                'error': error.message,
                # 'code': error.code
            }
            return self.error_response(
                request,
                data,
                response_class=http.HttpApplicationError
           )

        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response

    def get_response_meta(self, request, objects):
        '''
        needs to get cleaned up. need to be able to subclass this in
        order to add additional k,v pairs to the meta depending on
        which level we are att in the class heirarchy
        '''

        meta = {
            'top_lvl_location_id': self.top_lvl_location_id,
            'limit': None,  # paginator.get_limit(),
            'offset': None,  # paginator.get_offset(),
            'total_count': len(objects),
        }

        return meta
<commit_msg>rm obj_update / obj_delete from base_resource<commit_after>import traceback

from django.http import HttpResponse

from tastypie import http
from tastypie.resources import Resource
from tastypie.authorization import Authorization
from tastypie.authentication import ApiKeyAuthentication, MultiAuthentication

from rhizome.api.serialize import CustomSerializer
from rhizome.api.custom_session_authentication import CustomSessionAuthentication
from rhizome.api.custom_cache import CustomCache
from rhizome.api.exceptions import RhizomeApiException

from rhizome.models import LocationPermission, Location

class BaseResource(Resource):
    '''
    https://github.com/django-tastypie/django-tastypie/blob/master/tastypie/resources.py
    '''

    class Meta:
        authentication = MultiAuthentication(
            CustomSessionAuthentication(), ApiKeyAuthentication())
        allowed_methods = ['get', 'post', 'patch']
        authorization = Authorization()
        always_return_data = True
        cache = CustomCache()
        serializer = CustomSerializer()

    ### Tastypie Methods ###
    def __init__(self, api_name=None):
        '''
        In Rhizome, all user permissinos are bound by the top level location
        that they can see.  For instance, if i am the head of Zika data analysis
        in the Bahia Province of Brazil, that woul be my top level location.

        The top_lvl_location_id is used in the `get_locations_to_return_from_url`
        function, so that for shapes, locatinos and datapoints the user only
        can see what they are permissioned to.

        This is an additional parameter needed by the rhizome API to behave
        properly.  This variable is set in the dispatch method.
        '''

        self.top_lvl_location_id = None

        return super(BaseResource, self).__init__(api_name=None)

    def apply_filters(self, request, applicable_filters):
        """
        An ORM-specific implementation of ``apply_filters``.
        The default simply applies the ``applicable_filters`` as ``**kwargs``,
        but should make it possible to do more advanced things.
        """
        return self.get_object_list(request).filter(**applicable_filters)

    def get_object_list(self, request):
        """
        An ORM-specific implementation of ``get_object_list``.
        Returns a queryset that may have been limited by other overrides.
        """
        return super(BaseResource, self).get_object_list(self, request)

    def obj_get_list(self, bundle, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.
        ``GET`` dictionary of bundle.request can be used to narrow the query.
        """
        return super(BaseResource, self).obj_get_list(bundle, **kwargs)

    def save(self, bundle, skip_errors=False):

        return super(BaseResoruce, self).save(bundle, skip_errors)

    def lookup_kwargs_with_identifiers(self, bundle, kwargs):
        """
        Kwargs here represent uri identifiers Ex: /repos/<user_id>/<repo_name>/
        We need to turn those identifiers into Python objects for generating
        lookup parameters that can find them in the DB
        """
        return super(BaseResource, self)\
            .lookup_kwargs_with_identifiers(bundle, kwargs)

    def rollback(self, bundles):
        """
        A ORM-specific implementation of ``rollback``.
        Given the list of bundles, delete all models pertaining to those
        bundles.
        """
        return super(BaseResource, self).rolback(bundles)

    def detail_uri_kwargs(self, bundle_or_obj):
        """
        Given a ``Bundle`` or an object (typically a ``Model`` instance),
        it returns the extra kwargs needed to generate a detail URI.
        By default, it uses this resource's ``detail_uri_name`` in order to
        create the URI.
        """
        return super(BaseResource, self).detail_uri_kwargs(bundle_or_obj)

    ############################
    ## Custom Rhizome Methods ##
    ############################

    def validate_filters(self, request):
        '''
        Make sure that all required filters have been passed in
        '''

        filters = {}

        # Grab a mutable copy of the request#
        if hasattr(request, 'GET'):
            filters = request.GET.copy()

        # check required parameters and raise exception if one is missing #
        if hasattr(self._meta, 'GET_params_required'):
            keys_req = self._meta.GET_params_required
            missing_keys = list(set(keys_req).difference(set(filters.keys())))
            if len(missing_keys) > 0:
                msg = 'Missing required parameter %s' % missing_keys[0]
                raise RhizomeApiException(msg)

        return filters

    def dispatch(self, request_type, request, **kwargs):
        """
        Overrides Tastypie and calls get_list for GET, obj_create for POST,
        get_detail and obj_delete when fetching or delete an object with
        primary key requested
        """

        try:
            self.top_lvl_location_id = LocationPermission.objects.get(
                user_id=request.user.id).top_lvl_location_id
        except LocationPermission.DoesNotExist:
            self.top_lvl_location_id = Location.objects\
                .filter(parent_location_id=None)[0].id

        allowed_methods = getattr(
            self._meta, "%s_allowed_methods" % request_type, None)

        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            response = method(request, **kwargs)
        # except RhizomeApiException as error: ## use more specific exception.
        except Exception as error: ## use more specific exception.
            data = {
                'traceback': traceback.format_exc(),
                'error': error.message,
                # 'code': error.code
            }
            return self.error_response(
                request,
                data,
                response_class=http.HttpApplicationError
           )

        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response

    def get_response_meta(self, request, objects):
        '''
        needs to get cleaned up. need to be able to subclass this in
        order to add additional k,v pairs to the meta depending on
        which level we are att in the class heirarchy
        '''

        meta = {
            'top_lvl_location_id': self.top_lvl_location_id,
            'limit': None,  # paginator.get_limit(),
            'offset': None,  # paginator.get_offset(),
            'total_count': len(objects),
        }

        return meta
<|endoftext|>


<commit_before>"""Some helpers for loading war and piece as a dataset.
We assume it is a massive sequence (which it is) and chop it up into
whatever length the caller wants."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import collections
import csv
import itertools

import numpy as np

from six.moves import xrange
from six.moves import urllib
from io import open

from rnndatasets import helpers

FILENAME = 'warandpeace.txt'
URL = 'https://cs.stanford.edu/people/karpathy/char-rnn/warpeace_input.txt'

def _datapath():
    return os.path.join(
        os.path.dirname(
            os.path.realpath(__file__)),
        FILENAME)

def _get_big_string():
    """gets war and peace as a big string"""
    if not hasattr(_get_big_string, 'BIG_STRING'):
        with open(helpers.maybe_download(
                _datapath(), URL), encoding='utf-8') as datafile:
            _get_big_string.BIG_STRING = datafile.read()
    return _get_big_string.BIG_STRING

def _word_spliterator(data):
    """Splits a string into a sequence of words, just breaking on
    white space at this stage.

    Could insert something fancier potentially.
    """
    return data.split()

def _gen_vocab(data, splitter, filename, most_common=None, repeat_thresh=None):
    """generates vocab dict and writes it to file.
    Optionally only keep the `most_common` most common words or those with
    at least `repeat_thresh` repetitions, has to be one or the other,
    `most_common` takes priority.
    """
    # go through and count
    counter = collections.Counter(splitter(data))
    if most_common:
        symbols = counter.most_common(most_common)
    elif repeat_thresh:
        pass
    else:
        symbols = counter.most_common()  # may as well sort them

    # and now assign ids
    # we are also going to have a GO symbol
    symbols.append(['<GO>', 0])
    vocab = {symb[0]: i for i, symb in enumerate(symbols)}
    # now write it to the file
    with open(filename, 'w', encoding='utf-8') as f:
        csvwrite = csv.writer(f)
        for sym in vocab:
            csvwrite.writerow([sym, vocab[sym]])
    return vocab

def _load_vocab(filename):
    """reads in a vocab file"""
    vocab = {}
    with open(filename, 'r', newline='', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            vocab[row[0]] = row[1]
    return vocab

def get_vocab(level):
    """Gets the vocab as a dict of symbol -> int id.

    Args:
        level {`char` or `word`}: whether to get character or word
            level vocab.

    Returns:
        dict of all of the symbols.
    """
    filename = os.path.join(
        os.path.dirname(
            os.path.realpath(__file__)),
        '{}-vocab.txt'.format(level))
    if not os.path.exists(filename):
        print('{} not found, generating vocab'.format(filename))
        # grab it as a big string
        data = _get_big_string()
        if level == 'char':
            split_func = iter
        else:
            split_func = _word_spliterator
        vocab = _gen_vocab(data, split_func, filename)
    else:
        vocab = _load_vocab(filename)
    return vocab

def _get_sequence(level):
    """gets the sequence and the vocab"""
    data_str = _get_big_string()
    vocab = get_vocab(level)
    if level == 'char':
        seq = [vocab[c] for c in data_str]
    else:
        seq = [vocab[word] for word in _word_spliterator(data_str)]
    return seq, vocab

def get_char_iter(sequence_length, batch_size, report_progress=False):
    """Gets an iterator to batches of war and peace data.

    Args:
        sequence_length (int): the length of each chunk. This the maximum
            length you want to unroll your net for.
        batch_size (int): how many sequences to return at once.
        report_progress (bool): whether or not to report back about
            how far through the data you're getting.

    yields:
        list of `sequence_length` numpy int32 arrays, each with shape
            `[batch_size]`
        if `report_progress` is true, returns a tuple with the above as
            the second element and the fraction of progress through
            the data the first.
    """
    # first we actually have to load the data
    # w & p isn't huge, so the first thing we will do is just pull
    # the lot into memory
    wp_seq, _ = _get_sequence('char')
    num_chars = len(wp_seq)
    # this is potentially a little bit slow
    num_batches = num_chars // (sequence_length * batch_size)
    #print('enough data for {} batches'.format(num_batches))
    num_consumed = 0
    for seq_start in xrange(0, num_chars, sequence_length*batch_size):
        # gives us the starting position of the sequence
        batch = []
        if (num_chars - num_consumed) < sequence_length*batch_size:
            return
        for batch_num in xrange(batch_size):
            batch.append(np.array(wp_seq[seq_start+batch_num*batch_size:seq_start+batch_num*batch_size+sequence_length]))
        if len(batch) != batch_size:
            return
        if report_progress:
            yield seq_start / num_chars, batch
        else:
            yield batch
        num_consumed += batch_size * sequence_length
<commit_msg>make the char iter a bit more flexible<commit_after>"""Some helpers for loading war and piece as a dataset.
We assume it is a massive sequence (which it is) and chop it up into
whatever length the caller wants."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import collections
import csv
import itertools

import numpy as np

from six.moves import xrange
from six.moves import urllib
from io import open

from rnndatasets import helpers

FILENAME = 'warandpeace.txt'
URL = 'https://cs.stanford.edu/people/karpathy/char-rnn/warpeace_input.txt'

def _datapath():
    return os.path.join(
        os.path.dirname(
            os.path.realpath(__file__)),
        FILENAME)

def _get_big_string():
    """gets war and peace as a big string"""
    if not hasattr(_get_big_string, 'BIG_STRING'):
        with open(helpers.maybe_download(
                _datapath(), URL), encoding='utf-8') as datafile:
            _get_big_string.BIG_STRING = datafile.read()
    return _get_big_string.BIG_STRING

def _word_spliterator(data):
    """Splits a string into a sequence of words, just breaking on
    white space at this stage.

    Could insert something fancier potentially.
    """
    return data.split()

def _gen_vocab(data, splitter, filename, most_common=None, repeat_thresh=None):
    """generates vocab dict and writes it to file.
    Optionally only keep the `most_common` most common words or those with
    at least `repeat_thresh` repetitions, has to be one or the other,
    `most_common` takes priority.
    """
    # go through and count
    counter = collections.Counter(splitter(data))
    if most_common:
        symbols = counter.most_common(most_common)
    elif repeat_thresh:
        pass
    else:
        symbols = counter.most_common()  # may as well sort them

    # and now assign ids
    # we are also going to have a GO symbol
    symbols.append(['<GO>', 0])
    vocab = {symb[0]: i for i, symb in enumerate(symbols)}
    # now write it to the file
    with open(filename, 'w', encoding='utf-8') as f:
        csvwrite = csv.writer(f)
        for sym in vocab:
            csvwrite.writerow([sym, vocab[sym]])
    return vocab

def _load_vocab(filename):
    """reads in a vocab file"""
    vocab = {}
    with open(filename, 'r', newline='', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            vocab[row[0]] = row[1]
    return vocab

def get_vocab(level):
    """Gets the vocab as a dict of symbol -> int id.

    Args:
        level {`char` or `word`}: whether to get character or word
            level vocab.

    Returns:
        dict of all of the symbols.
    """
    filename = os.path.join(
        os.path.dirname(
            os.path.realpath(__file__)),
        '{}-vocab.txt'.format(level))
    if not os.path.exists(filename):
        print('{} not found, generating vocab'.format(filename))
        # grab it as a big string
        data = _get_big_string()
        if level == 'char':
            split_func = iter
        else:
            split_func = _word_spliterator
        vocab = _gen_vocab(data, split_func, filename)
    else:
        vocab = _load_vocab(filename)
    return vocab

def _get_sequence(level):
    """gets the sequence and the vocab"""
    data_str = _get_big_string()
    vocab = get_vocab(level)
    if level == 'char':
        seq = [vocab[c] for c in data_str]
    else:
        seq = [vocab[word] for word in _word_spliterator(data_str)]
    return seq, vocab

def get_char_iter(sequence_length, batch_size, report_progress=False,
                  sequential=True, overlap=1):
    """Gets an iterator to batches of war and peace data.

    Args:
        sequence_length (int): the length of each chunk. This the maximum
            length you want to unroll your net for.
        batch_size (int): how many sequences to return at once.
        report_progress (bool): whether or not to report back about
            how far through the data you're getting.
        sequential (bool): whether to make sure that each batch gets a
            consistent sequence. This is a good idea if you aren't resetting
            the state in between batches.
        overlap (int): overlap between sequences presented. Using an overlap
            of 1 can be handy if you need to use the shifted sequence as
            targets (which is likely to be most of the time).

    yields:
        list of `sequence_length` numpy int32 arrays, each with shape
            `[batch_size]`
        if `report_progress` is true, returns a tuple with the above as
            the second element and the fraction of progress through
            the data the first.
    """
    # first we actually have to load the data
    # w & p isn't huge, so the first thing we will do is just pull
    # the lot into memory
    wp_seq, _ = _get_sequence('char')
    num_chars = len(wp_seq)
    # this is potentially a little bit slow
    num_batches = num_chars // (sequence_length * batch_size)
    if sequential:
        step = sequence_length - overlap
    else:
        step = sequence_length * batch_size - overlap
    for seq_start in xrange(0, num_chars, step):
        # gives us the starting position of the first sequence
        batch = []
        for b in batch_size:
            if sequential:
                batch_offset = b * num_chars/num_batches
            else:
                batch_offset = b
            batch.append(wp_seq[seq_start + batch_offset:seq_start + batch_offset + sequence_length])
        if report_progress:
            yield (seq_start+sequence_length) / num_chars, batch
        else:
            yield batch
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
This script finds states that OU and HI are forked at,
using data that crawled by shogiwars.
'''

import os
import sys
sys.path.append('./../../')
import sqlite3
import pandas as pd

from pyogi.kifu import *

if __name__ == '__main__':

    dbpath = os.path.expanduser('~/data/sqlite3/shogiwars.sqlite3')
    con = sqlite3.connect(dbpath)

    query = 'SELECT * FROM kifu LIMIT 100;'
    df = pd.read_sql(query, con).drop_duplicates().reset_index()

    res_table = []

    for key, d in df.T.to_dict().items():
        kifu = Kifu(d['csa'])

        if not kifu.extracted:
            continue

        res = kifu.get_forking(['OU', 'HI'])

        if res[2] or res[3]:
            print(kifu.players)

        # Data
        #   fork: sente forked | gote forked
        #   forkandwin: (sente won & sente forked) | (gote won & gote forked)
        res_table.append(
            {
                'id': d['name'],
                'player0': kifu.players[0],
                'player1': kifu.players[1],
                'sente_won': kifu.sente_win,
                'sennichite': kifu.is_sennichite,
                'sente_forking': res[2] != [],
                'gote_forking': res[3] != [],
                'fork': res[2] != [] or res[3] != [],
                'forkandwin': ((kifu.sente_win and res[2]!=[]) or
                               (not kifu.sente_win and res[3]!=[]))
            }
        )

    # Output
    df_ct = pd.DataFrame(res_table)
    print(pd.crosstab(df_ct.loc[:, 'fork'], df_ct.loc[:, 'forkandwin']))
<commit_msg>Fix search_forking_wars.py<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
This script finds states that OU and HI are forked at,
using data that crawled by shogiwars.
'''

import os
import sys
sys.path.append('./../../')
import sqlite3
import pandas as pd

from pyogi.kifu import *

if __name__ == '__main__':

    dbpath = os.path.expanduser('~/data/sqlite3/shogiwars.sqlite3')
    con = sqlite3.connect(dbpath)

    query = 'SELECT * FROM kifu LIMIT 100;'
    df = pd.read_sql(query, con).drop_duplicates().reset_index()

    res_table = []

    for _, d in df.iterrows():
        kifu = Kifu()
        kifu.from_csa(d.csa)

        if not kifu.extracted:
            continue

        res = kifu.get_forking(['OU', 'HI'])

        if res[2] or res[3]:
            print(kifu.players)

        # Data
        #   fork: sente forked | gote forked
        #   forkandwin: (sente won & sente forked) | (gote won & gote forked)
        res_table.append(
            {
                'id': d.name,
                'player0': kifu.players[0],
                'player1': kifu.players[1],
                'sente_won': kifu.sente_win,
                'sennichite': kifu.is_sennichite,
                'sente_forking': res[2] != [],
                'gote_forking': res[3] != [],
                'fork': res[2] != [] or res[3] != [],
                'forkandwin': ((kifu.sente_win and res[2]!=[]) or
                               (not kifu.sente_win and res[3]!=[]))
            }
        )

    # Output
    df_ct = pd.DataFrame(res_table)
    print(pd.crosstab(df_ct.loc[:, 'fork'], df_ct.loc[:, 'forkandwin']))
<|endoftext|>


<commit_before># Copyright 2015 Dietrich Epp.
# This file is part of SGGL.  SGGL is licensed under the terms of the
# 2-clause BSD license.  For more information, see LICENSE.txt.
import argparse
import os
import platform
import sys
from . import Registry, API_LIST, parse_version, parse_api

def die(msg):
    """Show an error message and exit, indicating failure."""
    print('Error:', msg, file=sys.stderr)
    raise SystemExit(1)

_PLATFORMS = {'Darwin': 'osx', 'Linux': 'linux', 'Windows': 'windows'}
def get_platform():
    """Get the host platform."""
    s = platform.system()
    try:
        return _PLATFORMS[s]
    except KeyError:
        die('Unknown system {!r}, specify --platform.'.format(s))

def cmd_emit(reg, args):
    """Run the command-line 'emit' command."""
    import shutil
    platform = args.platform
    if platform is None:
        platform = get_platform()
    deps, data = reg.get_data(
        max_version=args.max_version,
        extensions=args.extensions,
        platform=platform)
    fnames = set(data.keys()).union(['opengl_load.c'])
    dirpath = os.path.dirname(__file__)
    for fname in sorted(fnames):
        path = os.path.join(args.out, fname)
        print('Creating {}...'.format(path))
        try:
            fdata = data[fname]
        except KeyError:
            shutil.copyfile(os.path.join(dirpath, fname), path)
        else:
            with open(path, 'wb') as fp:
                fp.write(fdata)

def library_functions(path):
    """Get a list of functions defined in a library."""
    import platform
    import subprocess
    strip_underscore = False
    args = ['nm']
    system = platform.system()
    print('System', system)
    if system == 'Darwin':
        strip_underscore = True
        args.append('-U')
    elif system == 'Linux':
        args.extend(('--dynamic', '--defined-only'))
    args.append(path)
    stdout = subprocess.check_output(args)
    for line in stdout.splitlines():
        fields = line.split()
        if fields[-2] != b'T':
            continue
        name = fields[2]
        if strip_underscore:
            if name.startswith(b'_'):
                name = name[1:]
            else:
                continue
        name = name.decode('ASCII')
        yield name

def cmd_scan(reg, args):
    """Run the command-line 'scan' command."""
    if args.library is None:
        path = ('/System/Library/Frameworks/OpenGL.framework/Versions'
                '/Current/Libraries/libGL.dylib')
    else:
        path = args.library
    functions = set()
    for func in library_functions(path):
        if func.startswith('gl'):
            functions.add(func[2:])
    dfunctions = set()
    max_version = 0, 0
    for version in sorted(reg.features):
        iface = reg._get_core(version, False)
        if not (functions >= iface.commands):
            break
        max_version = version
        dfunctions.update(iface.commands)
    print('Maximum version: {0[0]}.{0[1]}'.format(version))
    nsup, nuns, nzer, nred = 0, 0, 0, 0
    print('Extensions:')
    for ext in sorted(reg.extensions):
        iface = reg._get_extension(ext, False)
        if not iface.commands:
            nzer += 1
        elif dfunctions >= iface.commands:
            nred += 1
        elif not (functions >= iface.commands):
            nuns += 1
        else:
            nsup += 1
            print('  ' + ext)
    print('Extensions supported: {} ({} not redundant)'
          .format(nsup + nred, nsup))
    print('Extensions unsupported:', nuns)
    print('Extensions without entry points:', nzer)

def main():
    import argparse
    p = argparse.ArgumentParser()

    p.add_argument(
        '--reg-path',
        help='Path to the OpenGL XML registry file')
    p.add_argument(
        '--api',
        choices=API_LIST,
        default='gl:core',
        help='The OpenGL API')

    ss = p.add_subparsers()
    ss.required = True
    ss.dest = 'cmd'

    pp = ss.add_parser('emit', help='emit OpenGL headers and data')
    pp.add_argument(
        '--out', default='.',
        help='Output directory')
    pp.add_argument(
        '--platform', choices=('windows', 'osx', 'linux'))
    pp.add_argument(
        'max_version', type=parse_version,
        help='Maximum version to emit, e.g., 3.2')
    pp.add_argument(
        'extensions', nargs='*',
        help='Extensions to emit')
    pp.set_defaults(cmd=cmd_emit)

    pp = ss.add_parser('scan', help='calculate supported OpenGL version')
    pp.set_defaults(cmd=cmd_scan)
    pp.add_argument(
        '--library', help='library to scan')

    args = p.parse_args()
    api, profile = parse_api(args.api)
    reg_path = args.reg_path
    r = Registry.load(reg_path, api, profile)
    args.cmd(r, args)

if __name__ == '__main__':
    main()
<commit_msg>fix argument clash on Python 3.4<commit_after># Copyright 2015 Dietrich Epp.
# This file is part of SGGL.  SGGL is licensed under the terms of the
# 2-clause BSD license.  For more information, see LICENSE.txt.
import argparse
import os
import platform
import sys
from . import Registry, API_LIST, parse_version, parse_api

def die(msg):
    """Show an error message and exit, indicating failure."""
    print('Error:', msg, file=sys.stderr)
    raise SystemExit(1)

_PLATFORMS = {'Darwin': 'osx', 'Linux': 'linux', 'Windows': 'windows'}
def get_platform():
    """Get the host platform."""
    s = platform.system()
    try:
        return _PLATFORMS[s]
    except KeyError:
        die('Unknown system {!r}, specify --platform.'.format(s))

def cmd_emit(reg, args):
    """Run the command-line 'emit' command."""
    import shutil
    platform = args.platform
    if platform is None:
        platform = get_platform()
    deps, data = reg.get_data(
        max_version=args.max_version,
        extensions=args.extensions,
        platform=platform)
    fnames = set(data.keys()).union(['opengl_load.c'])
    dirpath = os.path.dirname(__file__)
    for fname in sorted(fnames):
        path = os.path.join(args.out, fname)
        print('Creating {}...'.format(path))
        try:
            fdata = data[fname]
        except KeyError:
            shutil.copyfile(os.path.join(dirpath, fname), path)
        else:
            with open(path, 'wb') as fp:
                fp.write(fdata)

def library_functions(path):
    """Get a list of functions defined in a library."""
    import platform
    import subprocess
    strip_underscore = False
    args = ['nm']
    system = platform.system()
    print('System', system)
    if system == 'Darwin':
        strip_underscore = True
        args.append('-U')
    elif system == 'Linux':
        args.extend(('--dynamic', '--defined-only'))
    args.append(path)
    stdout = subprocess.check_output(args)
    for line in stdout.splitlines():
        fields = line.split()
        if fields[-2] != b'T':
            continue
        name = fields[2]
        if strip_underscore:
            if name.startswith(b'_'):
                name = name[1:]
            else:
                continue
        name = name.decode('ASCII')
        yield name

def cmd_scan(reg, args):
    """Run the command-line 'scan' command."""
    if args.library is None:
        path = ('/System/Library/Frameworks/OpenGL.framework/Versions'
                '/Current/Libraries/libGL.dylib')
    else:
        path = args.library
    functions = set()
    for func in library_functions(path):
        if func.startswith('gl'):
            functions.add(func[2:])
    dfunctions = set()
    max_version = 0, 0
    for version in sorted(reg.features):
        iface = reg._get_core(version, False)
        if not (functions >= iface.commands):
            break
        max_version = version
        dfunctions.update(iface.commands)
    print('Maximum version: {0[0]}.{0[1]}'.format(version))
    nsup, nuns, nzer, nred = 0, 0, 0, 0
    print('Extensions:')
    for ext in sorted(reg.extensions):
        iface = reg._get_extension(ext, False)
        if not iface.commands:
            nzer += 1
        elif dfunctions >= iface.commands:
            nred += 1
        elif not (functions >= iface.commands):
            nuns += 1
        else:
            nsup += 1
            print('  ' + ext)
    print('Extensions supported: {} ({} not redundant)'
          .format(nsup + nred, nsup))
    print('Extensions unsupported:', nuns)
    print('Extensions without entry points:', nzer)

def main():
    import argparse
    p = argparse.ArgumentParser()

    p.add_argument(
        '--reg-path',
        help='Path to the OpenGL XML registry file')
    p.add_argument(
        '--api',
        choices=API_LIST,
        default='gl:core',
        help='The OpenGL API')

    ss = p.add_subparsers()
    ss.required = True
    ss.dest = 'cmd'

    pp = ss.add_parser('emit', help='emit OpenGL headers and data')
    pp.add_argument(
        '--out', default='.',
        help='Output directory')
    pp.add_argument(
        '--platform', choices=('windows', 'osx', 'linux'))
    pp.add_argument(
        'max_version', type=parse_version,
        help='Maximum version to emit, e.g., 3.2')
    pp.add_argument(
        'extensions', nargs='*',
        help='Extensions to emit')
    pp.set_defaults(cmd_func=cmd_emit)

    pp = ss.add_parser('scan', help='calculate supported OpenGL version')
    pp.set_defaults(cmd_func=cmd_scan)
    pp.add_argument(
        '--library', help='library to scan')

    args = p.parse_args()
    api, profile = parse_api(args.api)
    reg_path = args.reg_path
    r = Registry.load(reg_path, api, profile)
    args.cmd_func(r, args)

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


<commit_before>#
# Copyright 2015 Genymobile
#
# 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.

"""
Django settings for gm_pr project.

Generated by 'django-admin startproject' using Django 1.8.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from gm_pr.settings_projects import *

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'nny#i^ey9pbud@86s9p55r4k2fbd_0e+1#@h9+5z$+3nk2i&ml'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = [ "127.0.0.1" ]

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',
    'djcelery',
    'import_export',
    'gm_pr',
    'web',
    'bot',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'gm_pr.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'gm_pr.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'

CELERY_ACCEPT_CONTENT = ['json', 'yaml', 'pickle']
CELERY_TASK_SERIALIZER = 'json'
CELERY_IMPORTS = ("bot.tasks", "gm_pr.prfetcher")
BROKER_URL = 'amqp://gm_pr:gm_pr@localhost:5672/gm_pr'
CELERY_RESULT_BACKEND = 'amqp'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(asctime)s %(module)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'gm_pr.log',
            'maxBytes': 10000000,
            'backupCount': 5,
            'formatter' : 'verbose',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'gm_pr': {
            'handlers': ['file', 'console'],
            'level': 'DEBUG',
        },
    },
}
<commit_msg>add possibilty to use settings.ini to override settings<commit_after>#
# Copyright 2015 Genymobile
#
# 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.

"""
Django settings for gm_pr project.

Generated by 'django-admin startproject' using Django 1.8.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from gm_pr.settings_projects import *
import configparser

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# You can override some settings with a "settings.ini" file project root
# directory:
#
# [backend]
# BROKER_URL="mybrokerurl"
# ...
config = configparser.ConfigParser()
config.read(os.sep.join([BASE_DIR, "settings.ini"]))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'nny#i^ey9pbud@86s9p55r4k2fbd_0e+1#@h9+5z$+3nk2i&ml'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = [ "127.0.0.1" ]

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',
    'djcelery',
    'import_export',
    'gm_pr',
    'web',
    'bot',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'gm_pr.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'gm_pr.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'

CELERY_ACCEPT_CONTENT = ['json', 'yaml', 'pickle']
CELERY_TASK_SERIALIZER = 'json'
CELERY_IMPORTS = ("bot.tasks", "gm_pr.prfetcher")
BROKER_URL = config.get('backend', 'BROKER_URL',
                        fallback='amqp://gm_pr:gm_pr@localhost:5672/gm_pr')
CELERY_RESULT_BACKEND = 'amqp'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(asctime)s %(module)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'gm_pr.log',
            'maxBytes': 10000000,
            'backupCount': 5,
            'formatter' : 'verbose',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'gm_pr': {
            'handlers': ['file', 'console'],
            'level': 'DEBUG',
        },
    },
}
<|endoftext|>


<commit_before># pylint: disable=missing-docstring, import-error
from __future__ import print_function
import sys
import numpy as np
import pandas as pd

def validate_is_data_frame(data):
    if not isinstance(data, pd.DataFrame):
        raise TypeError('data must be a pandas DataFrame.')

def nan_equal(arr1, arr2):
    return ((arr1 == arr2) | (np.isnan(arr1) & np.isnan(arr2))).all()

def _print(msg):
    print(msg, file=sys.stderr)
<commit_msg>Add ReplacementManager<commit_after># pylint: disable=missing-docstring, import-error
from __future__ import print_function
import sys
import numpy as np
import pandas as pd

def validate_is_data_frame(data):
    if not isinstance(data, pd.DataFrame):
        raise TypeError('data must be a pandas DataFrame.')

def nan_equal(arr1, arr2):
    return ((arr1 == arr2) | (np.isnan(arr1) & np.isnan(arr2))).all()

def _print(msg):
    print(msg, file=sys.stderr)

class ReplacementManager(object):
    # pylint: disable=too-few-public-methods
    def __init__(self, num_rpl, str_rpl):
        self.num_rpl = num_rpl
        self.str_rpl = str_rpl

    def get_rpl_for(self, series):
        if series.dtype == 'object':
            return self.str_rpl
        else:
            return self.num_rpl
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Author: Qiming Sun <osirpt.sun@gmail.com>
#

import sys
import time
import numpy
import scipy.linalg
from pyscf import lib
from pyscf.lib import logger

def expmat(a):
    return scipy.linalg.expm(a)

class CIAHOptimizer(lib.StreamObject):
    def __init__(self):
        self.conv_tol_grad = 1e-4
        self.max_stepsize = .05
        self.max_iters = 10
        self.kf_interval = 5
        self.kf_trust_region = 5
        self.ah_start_tol = 5.
        self.ah_start_cycle = 1
        self.ah_level_shift = 0#1e-4
        self.ah_conv_tol = 1e-12
        self.ah_lindep = 1e-14
        self.ah_max_cycle = 30
        self.ah_trust_region = 3.

    def gen_g_hop(self, u):
        pass

    def pack_uniq_var(self, mat):
        nmo = mat.shape[0]
        idx = numpy.tril_indices(nmo, -1)
        return mat[idx]

    def unpack_uniq_var(self, v):
        nmo = int(numpy.sqrt(v.size*2)) + 1
        idx = numpy.tril_indices(nmo, -1)
        mat = numpy.zeros((nmo,nmo))
        mat[idx] = v
        return mat - mat.T

    def extract_rotation(self, dr, u0=1):
        dr = self.unpack_uniq_var(dr)
        return numpy.dot(u0, expmat(dr))

    def get_grad(self, u):
        pass

    def cost_function(self, u):
        pass

def rotate_orb_cc(iah, u0, conv_tol_grad=None, verbose=logger.NOTE):
    t2m = (time.clock(), time.time())
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(sys.stdout, verbose)

    if conv_tol_grad is None:
        conv_tol_grad = iah.conv_tol_grad

    g_orb, h_op, h_diag = iah.gen_g_hop(u0)
    g_kf = g_orb
    norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|= %4.3g (keyframe)', norm_gorb)
    t3m = log.timer('gen h_op', *t2m)

    if h_diag is None:
        def precond(x, e):
            return x
    else:
        def precond(x, e):
            hdiagd = h_diag-(e-iah.ah_level_shift)
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            x = x/hdiagd
            return x

    def scale_down_step(dxi, hdxi, norm_gorb):
        dxmax = abs(dxi).max()
        if dxmax > iah.max_stepsize:
            scale = iah.max_stepsize / dxmax
            log.debug1('Scale rotation by %g', scale)
            dxi *= scale
            hdxi *= scale
        return dxi, hdxi

    class Statistic:
        def __init__(self):
            self.imic = 0
            self.tot_hop = 0
            self.tot_kf = 0

    kf_trust_region = iah.kf_trust_region
    g_op = lambda: g_orb
    x0_guess = g_orb
    while True:
        g_orb0 = g_orb
        stat = Statistic()
        dr = 0
        ikf = 0

        for ah_conv, ihop, w, dxi, hdxi, residual, seig \
                in davidson_cc(h_op, g_op, precond, x0_guess,
                               tol=iah.ah_conv_tol, max_cycle=iah.ah_max_cycle,
                               lindep=iah.ah_lindep, verbose=log):
            stat.tot_hop = ihop
            norm_residual = numpy.linalg.norm(residual)
            if (ah_conv or ihop == iah.ah_max_cycle or # make sure to use the last step
                ((norm_residual < iah.ah_start_tol) and (ihop >= iah.ah_start_cycle)) or
                (seig < iah.ah_lindep)):
                stat.imic += 1
                dxmax = abs(dxi).max()
                dxi, hdxi = scale_down_step(dxi, hdxi, norm_gorb)

                dr = dr + dxi
                g_orb = g_orb + hdxi
                norm_dr = numpy.linalg.norm(dr)
                norm_gorb = numpy.linalg.norm(g_orb)
                log.debug('    imic %d(%d)  |g|= %4.3g  |dxi|= %4.3g  '
                          'max(|x|)= %4.3g  |dr|= %4.3g  eig= %4.3g  seig= %4.3g',
                          stat.imic, ihop, norm_gorb, numpy.linalg.norm(dxi),
                          dxmax, norm_dr, w, seig)

                max_cycle = max(iah.max_iters,
                                iah.max_iters-int(numpy.log(norm_gkf+1e-9)*2))
                log.debug1('Set max_cycle %d', max_cycle)
                ikf += 1
                if stat.imic > 3 and norm_gorb > norm_gkf*iah.ah_trust_region:
                    g_orb = g_orb - hdxi
                    dr = dr - dxi
                    norm_gorb = numpy.linalg.norm(g_orb)
                    log.debug('|g| >> keyframe, Restore previouse step')
                    break

                elif (stat.imic >= max_cycle or norm_gorb < conv_tol_grad*.2):
                    break

                elif (ikf > 2 and # avoid frequent keyframe
                      (ikf >= max(iah.kf_interval, iah.kf_interval-numpy.log(norm_dr+1e-9)) or
# Insert keyframe if the keyframe and the esitimated g_orb are too different
                       norm_gorb < norm_gkf/kf_trust_region)):
                    ikf = 0
                    g_kf1 = iah.get_grad(iah.extract_rotation(dr, u0))
                    stat.tot_kf += 1
                    norm_gkf1 = numpy.linalg.norm(g_kf1)
                    norm_dg = numpy.linalg.norm(g_kf1-g_orb)
                    log.debug('Adjust keyframe g_orb to |g|= %4.3g  '
                              '|g-correction|= %4.3g', norm_gkf1, norm_dg)

                    if (norm_dg < norm_gorb*iah.ah_trust_region  # kf not too diff
                        #or norm_gkf1 < norm_gkf  # grad is decaying
                        # close to solution
                        or norm_gkf1 < conv_tol_grad*iah.ah_trust_region):
                        kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), iah.kf_trust_region), 10)
                        log.debug1('Set kf_trust_region = %g', kf_trust_region)
                        g_orb = g_kf = g_kf1
                        norm_gorb = norm_gkf = norm_gkf1
                    else:
                        g_orb = g_orb - hdxi
                        dr = dr - dxi
                        norm_gorb = numpy.linalg.norm(g_orb)
                        log.debug('Out of trust region. Restore previouse step')
                        break

        u = iah.extract_rotation(dr)
        log.debug('    tot inner=%d  |g|= %4.3g  |u-1|= %4.3g',
                  stat.imic, norm_gorb, numpy.linalg.norm(numpy.tril(u,-1)))
        h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % stat.imic, *t3m)
        u0 = (yield u, g_kf, stat)

        g_kf, h_op, h_diag = iah.gen_g_hop(u0)
        norm_gkf = numpy.linalg.norm(g_kf)
        norm_dg = numpy.linalg.norm(g_kf-g_orb)
        log.debug('    |g|= %4.3g (keyframe), |g-correction|= %4.3g',
                  norm_gkf, norm_dg)
        kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), iah.kf_trust_region), 10)
        log.debug1('Set  kf_trust_region = %g', kf_trust_region)
        g_orb = g_kf
        norm_gorb = norm_gkf
        x0_guess = dxi

def davidson_cc(h_op, g_op, precond, x0, tol=1e-10, xs=[], ax=[],
                max_cycle=30, lindep=1e-14, verbose=logger.WARN):

    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(sys.stdout, verbose)

    toloose = numpy.sqrt(tol)
    # the first trial vector is (1,0,0,...), which is not included in xs
    xs = list(xs)
    ax = list(ax)
    nx = len(xs)
    if nx == 0:
        xs.append(x0)
        ax.append(h_op(x0))
        nx = 1

    heff = numpy.zeros((max_cycle+nx+1,max_cycle+nx+1), dtype=x0.dtype)
    ovlp = numpy.eye(max_cycle+nx+1, dtype=x0.dtype)
    w_t = 0
    for istep in range(max_cycle):
        g = g_op()
        nx = len(xs)
        for i in range(nx):
            heff[i+1,0] = numpy.dot(xs[i].conj(), g)
            heff[nx,i+1] = numpy.dot(xs[nx-1].conj(), ax[i])
            ovlp[nx,i+1] = numpy.dot(xs[nx-1].conj(), xs[i])
        heff[0,:nx+1] = heff[:nx+1,0].conj()
        heff[:nx,nx] = heff[nx,:nx].conj()
        ovlp[:nx,nx] = ovlp[nx,:nx].conj()
        nvec = nx + 1
#        s0 = scipy.linalg.eigh(ovlp[:nvec,:nvec])[0][0]
#        if s0 < lindep:
#            yield True, istep, w_t, xtrial, hx, dx, s0
#            break
        wlast = w_t
        xtrial, w_t, v_t, index, seig = \
                _regular_step(heff[:nvec,:nvec], ovlp[:nvec,:nvec], xs,
                              lindep, log)
        s0 = seig[0]
        hx = _dgemv(v_t[1:], ax)
        # note g*v_t[0], as the first trial vector is (1,0,0,...)
        dx = hx + g*v_t[0] - w_t * v_t[0]*xtrial
        norm_dx = numpy.linalg.norm(dx)
        log.debug1('... AH step %d  index= %d  |dx|= %.5g  eig= %.5g  v[0]= %.5g  lindep= %.5g', \
                   istep+1, index, norm_dx, w_t, v_t[0], s0)
        hx *= 1/v_t[0] # == h_op(xtrial)
        if (abs(w_t-wlast) < tol and norm_dx < toloose) or s0 < lindep:
            # Avoid adding more trial vectors if hessian converged
            yield True, istep+1, w_t, xtrial, hx, dx, s0
            if s0 < lindep or norm_dx < lindep:# or numpy.linalg.norm(xtrial) < lindep:
                # stop the iteration because eigenvectors would be barely updated
                break
        else:
            yield False, istep+1, w_t, xtrial, hx, dx, s0
            x0 = precond(dx, w_t)
            xs.append(x0)
            ax.append(h_op(x0))

def _regular_step(heff, ovlp, xs, lindep, log):
    w, v, seig = lib.safe_eigh(heff, ovlp, lindep)
    if log.verbose >= logger.DEBUG3:
        numpy.set_printoptions(3, linewidth=1000)
        log.debug3('v[0] %s', v[0])
        log.debug3('AH eigs %s', w)
        log.debug3('H eigs %s', scipy.linalg.eigh(heff[1:,1:])[0])
        numpy.set_printoptions(8, linewidth=75)

    idx = numpy.where(abs(v[0]) > 0.1)[0]
    sel = idx[0]
    #sel = 0

    if w[sel] < -1e-5:
        log.debug1('AH might follow negative hessians %s', w[:sel])

    w_t = w[sel]
    xtrial = _dgemv(v[1:,sel]/v[0,sel], xs)
    return xtrial, w_t, v[:,sel], sel, seig

def _dgemv(v, m):
    vm = v[0] * m[0]
    for i,vi in enumerate(v[1:]):
        vm += vi * m[i+1]
    return vm

<commit_msg>Check negative Hessians in newton solver<commit_after>#!/usr/bin/env python
#
# Author: Qiming Sun <osirpt.sun@gmail.com>
#

import sys
import time
import numpy
import scipy.linalg
from pyscf import lib
from pyscf.lib import logger

def expmat(a):
    return scipy.linalg.expm(a)

class CIAHOptimizer(lib.StreamObject):
    def __init__(self):
        self.conv_tol_grad = 1e-4
        self.max_stepsize = .05
        self.max_iters = 10
        self.kf_interval = 5
        self.kf_trust_region = 5
        self.ah_start_tol = 5.
        self.ah_start_cycle = 1
        self.ah_level_shift = 0#1e-4
        self.ah_conv_tol = 1e-12
        self.ah_lindep = 1e-14
        self.ah_max_cycle = 30
        self.ah_trust_region = 3.

    def gen_g_hop(self, u):
        pass

    def pack_uniq_var(self, mat):
        nmo = mat.shape[0]
        idx = numpy.tril_indices(nmo, -1)
        return mat[idx]

    def unpack_uniq_var(self, v):
        nmo = int(numpy.sqrt(v.size*2)) + 1
        idx = numpy.tril_indices(nmo, -1)
        mat = numpy.zeros((nmo,nmo))
        mat[idx] = v
        return mat - mat.T

    def extract_rotation(self, dr, u0=1):
        dr = self.unpack_uniq_var(dr)
        return numpy.dot(u0, expmat(dr))

    def get_grad(self, u):
        pass

    def cost_function(self, u):
        pass

def rotate_orb_cc(iah, u0, conv_tol_grad=None, verbose=logger.NOTE):
    t2m = (time.clock(), time.time())
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(sys.stdout, verbose)

    if conv_tol_grad is None:
        conv_tol_grad = iah.conv_tol_grad

    g_orb, h_op, h_diag = iah.gen_g_hop(u0)
    g_kf = g_orb
    norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|= %4.3g (keyframe)', norm_gorb)
    t3m = log.timer('gen h_op', *t2m)

    if h_diag is None:
        def precond(x, e):
            return x
    else:
        def precond(x, e):
            hdiagd = h_diag-(e-iah.ah_level_shift)
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            x = x/hdiagd
            return x

    def scale_down_step(dxi, hdxi, norm_gorb):
        dxmax = abs(dxi).max()
        if dxmax > iah.max_stepsize:
            scale = iah.max_stepsize / dxmax
            log.debug1('Scale rotation by %g', scale)
            dxi *= scale
            hdxi *= scale
        return dxi, hdxi

    class Statistic:
        def __init__(self):
            self.imic = 0
            self.tot_hop = 0
            self.tot_kf = 0

    kf_trust_region = iah.kf_trust_region
    g_op = lambda: g_orb
    x0_guess = g_orb
    while True:
        g_orb0 = g_orb
        stat = Statistic()
        dr = 0
        ikf = 0

        for ah_conv, ihop, w, dxi, hdxi, residual, seig \
                in davidson_cc(h_op, g_op, precond, x0_guess,
                               tol=iah.ah_conv_tol, max_cycle=iah.ah_max_cycle,
                               lindep=iah.ah_lindep, verbose=log):
            stat.tot_hop = ihop
            norm_residual = numpy.linalg.norm(residual)
            if (ah_conv or ihop == iah.ah_max_cycle or # make sure to use the last step
                ((norm_residual < iah.ah_start_tol) and (ihop >= iah.ah_start_cycle)) or
                (seig < iah.ah_lindep)):
                stat.imic += 1
                dxmax = abs(dxi).max()
                dxi, hdxi = scale_down_step(dxi, hdxi, norm_gorb)

                dr = dr + dxi
                g_orb = g_orb + hdxi
                norm_dr = numpy.linalg.norm(dr)
                norm_gorb = numpy.linalg.norm(g_orb)
                log.debug('    imic %d(%d)  |g|= %4.3g  |dxi|= %4.3g  '
                          'max(|x|)= %4.3g  |dr|= %4.3g  eig= %4.3g  seig= %4.3g',
                          stat.imic, ihop, norm_gorb, numpy.linalg.norm(dxi),
                          dxmax, norm_dr, w, seig)

                max_cycle = max(iah.max_iters,
                                iah.max_iters-int(numpy.log(norm_gkf+1e-9)*2))
                log.debug1('Set max_cycle %d', max_cycle)
                ikf += 1
                if stat.imic > 3 and norm_gorb > norm_gkf*iah.ah_trust_region:
                    g_orb = g_orb - hdxi
                    dr = dr - dxi
                    norm_gorb = numpy.linalg.norm(g_orb)
                    log.debug('|g| >> keyframe, Restore previouse step')
                    break

                elif (stat.imic >= max_cycle or norm_gorb < conv_tol_grad*.2):
                    break

                elif (ikf > 2 and # avoid frequent keyframe
                      (ikf >= max(iah.kf_interval, iah.kf_interval-numpy.log(norm_dr+1e-9)) or
# Insert keyframe if the keyframe and the esitimated g_orb are too different
                       norm_gorb < norm_gkf/kf_trust_region)):
                    ikf = 0
                    g_kf1 = iah.get_grad(iah.extract_rotation(dr, u0))
                    stat.tot_kf += 1
                    norm_gkf1 = numpy.linalg.norm(g_kf1)
                    norm_dg = numpy.linalg.norm(g_kf1-g_orb)
                    log.debug('Adjust keyframe g_orb to |g|= %4.3g  '
                              '|g-correction|= %4.3g', norm_gkf1, norm_dg)

                    if (norm_dg < norm_gorb*iah.ah_trust_region  # kf not too diff
                        #or norm_gkf1 < norm_gkf  # grad is decaying
                        # close to solution
                        or norm_gkf1 < conv_tol_grad*iah.ah_trust_region):
                        kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), iah.kf_trust_region), 10)
                        log.debug1('Set kf_trust_region = %g', kf_trust_region)
                        g_orb = g_kf = g_kf1
                        norm_gorb = norm_gkf = norm_gkf1
                    else:
                        g_orb = g_orb - hdxi
                        dr = dr - dxi
                        norm_gorb = numpy.linalg.norm(g_orb)
                        log.debug('Out of trust region. Restore previouse step')
                        break

        u = iah.extract_rotation(dr)
        log.debug('    tot inner=%d  |g|= %4.3g  |u-1|= %4.3g',
                  stat.imic, norm_gorb, numpy.linalg.norm(numpy.tril(u,-1)))
        h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % stat.imic, *t3m)
        u0 = (yield u, g_kf, stat)

        g_kf, h_op, h_diag = iah.gen_g_hop(u0)
        norm_gkf = numpy.linalg.norm(g_kf)
        norm_dg = numpy.linalg.norm(g_kf-g_orb)
        log.debug('    |g|= %4.3g (keyframe), |g-correction|= %4.3g',
                  norm_gkf, norm_dg)
        kf_trust_region = min(max(norm_gorb/(norm_dg+1e-9), iah.kf_trust_region), 10)
        log.debug1('Set  kf_trust_region = %g', kf_trust_region)
        g_orb = g_kf
        norm_gorb = norm_gkf
        x0_guess = dxi

def davidson_cc(h_op, g_op, precond, x0, tol=1e-10, xs=[], ax=[],
                max_cycle=30, lindep=1e-14, verbose=logger.WARN):

    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(sys.stdout, verbose)

    toloose = numpy.sqrt(tol)
    # the first trial vector is (1,0,0,...), which is not included in xs
    xs = list(xs)
    ax = list(ax)
    nx = len(xs)
    if nx == 0:
        xs.append(x0)
        ax.append(h_op(x0))
        nx = 1

    heff = numpy.zeros((max_cycle+nx+1,max_cycle+nx+1), dtype=x0.dtype)
    ovlp = numpy.eye(max_cycle+nx+1, dtype=x0.dtype)
    w_t = 0
    for istep in range(max_cycle):
        g = g_op()
        nx = len(xs)
        for i in range(nx):
            heff[i+1,0] = numpy.dot(xs[i].conj(), g)
            heff[nx,i+1] = numpy.dot(xs[nx-1].conj(), ax[i])
            ovlp[nx,i+1] = numpy.dot(xs[nx-1].conj(), xs[i])
        heff[0,:nx+1] = heff[:nx+1,0].conj()
        heff[:nx,nx] = heff[nx,:nx].conj()
        ovlp[:nx,nx] = ovlp[nx,:nx].conj()
        nvec = nx + 1
#        s0 = scipy.linalg.eigh(ovlp[:nvec,:nvec])[0][0]
#        if s0 < lindep:
#            yield True, istep, w_t, xtrial, hx, dx, s0
#            break
        wlast = w_t
        xtrial, w_t, v_t, index, seig = \
                _regular_step(heff[:nvec,:nvec], ovlp[:nvec,:nvec], xs,
                              lindep, log)
        s0 = seig[0]
        hx = _dgemv(v_t[1:], ax)
        # note g*v_t[0], as the first trial vector is (1,0,0,...)
        dx = hx + g*v_t[0] - w_t * v_t[0]*xtrial
        norm_dx = numpy.linalg.norm(dx)
        log.debug1('... AH step %d  index= %d  |dx|= %.5g  eig= %.5g  v[0]= %.5g  lindep= %.5g', \
                   istep+1, index, norm_dx, w_t, v_t[0], s0)
        hx *= 1/v_t[0] # == h_op(xtrial)
        if (abs(w_t-wlast) < tol and norm_dx < toloose) or s0 < lindep:
            # Avoid adding more trial vectors if hessian converged
            yield True, istep+1, w_t, xtrial, hx, dx, s0
            if s0 < lindep or norm_dx < lindep:# or numpy.linalg.norm(xtrial) < lindep:
                # stop the iteration because eigenvectors would be barely updated
                break
        else:
            yield False, istep+1, w_t, xtrial, hx, dx, s0
            x0 = precond(dx, w_t)
            xs.append(x0)
            ax.append(h_op(x0))

def _regular_step(heff, ovlp, xs, lindep, log):
    e,c = lib.safe_eigh(heff[1:,1:], ovlp[1:,1:], lindep)[:2]
    if e[0] < -1e-5:
        log.debug('Negative hessians found %s', e[e<0])
        log.debug('AH is shifted to avoid negative hessians')
        heff = heff.copy()
        sc = numpy.dot(ovlp[1:,1:], c)
        e[(-0.1<e) & (e<0)] = .1
        e = abs(e)
        heff[1:,1:] = numpy.dot(sc*e, sc.T.conj())

    w, v, seig = lib.safe_eigh(heff, ovlp, lindep)
    if log.verbose >= logger.DEBUG3:
        numpy.set_printoptions(3, linewidth=1000)
        log.debug3('v[0] %s', v[0])
        log.debug3('AH eigs %s', w)
        numpy.set_printoptions(8, linewidth=75)

    idx = numpy.where(abs(v[0]) > 0.1)[0]
    sel = idx[0]
    #sel = 0
    w_t = w[sel]
    xtrial = _dgemv(v[1:,sel]/v[0,sel], xs)
    return xtrial, w_t, v[:,sel], sel, seig

def _dgemv(v, m):
    vm = v[0] * m[0]
    for i,vi in enumerate(v[1:]):
        vm += vi * m[i+1]
    return vm

<|endoftext|>


<commit_before>from collections import defaultdict

from django.conf import settings
from django.contrib.auth import logout
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.shortcuts import render, redirect, get_object_or_404, render_to_response
from django.views.decorators.http import require_POST, require_GET
from paypal.standard.forms import PayPalPaymentsForm

from famille import forms
from famille.models import (
    Famille, Prestataire, get_user_related, UserInfo,
    has_user_related, FamilleRatings, PrestataireRatings,
    compute_user_visibility_filters, DownloadableFile
)
from famille.resources import PrestataireResource, FamilleResource
from famille.utils import get_context, get_result_template_from_user, payment
from famille.utils.http import require_related, login_required, assert_POST

__all__ = [
    "home", "search", "register", "account",
    "favorite", "profile", "premium",
    "tools", "advanced", "delete_account"
]

def home(request):
    """
    Home view. Rendering first forms.
    """
    search_form = forms.SimpleSearchForm()
    registration_form = forms.RegistrationForm()
    return render(
        request, "home.html",
        get_context(search_form=search_form, registration_form=registration_form)
    )

def search(request):
    """
    Search view.
    """
    data = request.POST if request.method == "POST" else request.GET
    search_type = data.get("type")
    search_type = "prestataire" if search_type not in ["famille", "prestataire"] else search_type
    if search_type == "famille":
        FormClass = forms.FamilleSearchForm
        objects = Famille.objects.filter(compute_user_visibility_filters(request.user))
        template = "search/famille.html"
    else:
        FormClass = forms.PrestataireSearchForm
        objects = Prestataire.objects.all()
        template = "search/prestataire.html"

    form = FormClass(data)
    if not form.is_valid():
        form = FormClass()

    # TODO: do location filtering, together with geolocation stuff ?
    objects = objects.order_by("-updated_at")
    total_search_results = objects.count()
    nb_search_results = min(settings.NB_SEARCH_RESULTS, total_search_results)
    objects = objects[:nb_search_results]
    result_template = get_result_template_from_user(request)
    if request.user.is_authenticated():
        favorites = get_user_related(request.user).favorites.all()
    else:
        favorites = []
    return render(
        request, template,
        get_context(
            search_form=form, results=objects, result_template=result_template,
            nb_search_results=nb_search_results, ordering=form.ordering_dict,
            favorites=favorites, user=request.user, search_type=search_type,
            max_nb_search_results=settings.NB_SEARCH_RESULTS,
            total_search_results=total_search_results
        )
    )

def register(request, social=None, type=None):
    """
    Register view. Allow user creation.
    """
    if not type:
        if request.method == "POST":
            form = forms.RegistrationForm(request.POST)
            if form.is_valid():
                form.save()
        else:
            form = forms.RegistrationForm()
        return render(request, "registration/register.html", get_context(social=social, form=form))
    else:
        if not has_user_related(request.user):
            UserInfo.create_user(dj_user=request.user, type=type)
        else:
            return redirect('account')

    return HttpResponseRedirect('/confirmation/')

# TODO: error handling for compte form
@login_required
@require_related
def account(request):
    url_hash = ""
    if request.method == "POST":
        account_forms = forms.AccountFormManager(instance=request.related_user, data=request.POST, files=request.FILES)
        url_hash = account_forms.form_submitted
        if account_forms.is_valid():
            account_forms.save()
            return HttpResponseRedirect('/mon-compte/?success#%s' % url_hash)
    else:
        account_forms = forms.AccountFormManager(instance=request.related_user)

    return render(
        request, 'account/%s.html' % account_forms.instance_type,
        get_context(related=request.related_user, url_hash=url_hash, **account_forms.forms)
    )

@login_required
@require_related
@require_POST
def favorite(request):
    """
    Mark an object as favorite. If action=remove is passed,
    the given object is removed from favorites.
    """
    resource_uri = request.POST["resource_uri"]
    action_name = request.POST.get("action", "add")
    user_related = request.related_user
    action = user_related.remove_favorite if action_name == "remove" else user_related.add_favorite
    action(resource_uri)

    return HttpResponse()

@login_required
@require_related
@require_GET
def profile(request, type, uid):
    """
    Display the profile of a user.
    """
    if type not in ("famille", "prestataire"):
        raise Http404

    context = {}

    if type == "famille":
        ModelClass = Famille
        RatingClass = FamilleRatings
        RatingFormClass = forms.RatingFamilleForm
    else:
        ModelClass = Prestataire
        RatingClass = PrestataireRatings
        RatingFormClass = forms.RatingPrestataireForm

    try:
        user = ModelClass.objects.get(pk=uid)
    except ModelClass.DoesNotExist:
        return render(request, "profile/404.html", status=404)

    if not user.profile_access_is_authorized(request):
        return render(request, "profile/401.html", status=401)

    if has_user_related(request.user):
        related_user = get_user_related(request.user)
        if not RatingClass.user_has_voted_for(related_user, user):
            rating = RatingClass(user=user, by=related_user.simple_id)
            context["rating_form"] = RatingFormClass(instance=rating)

    return render(request, "profile/base.html", get_context(profile=user, **context))

premium_dict = {
    "business": settings.PAYPAL_RECEIVER_EMAIL,
    "amount": settings.PREMIUM_PRICE,
    "item_name": "Compte premium Une vie de famille",
    "item_number": settings.PREMIUM_ID,
    "src": "1",
    "currency_code": "EUR"
}

@login_required
@require_related
@require_GET
def premium(request, action=None):
    """
    Page to become premium.
    """
    if request.related_user.is_premium:
        return render_to_response("account/already_premium.html")

    if action == "valider":
        return render(request, "account/premium.html", get_context(action=action))

    data = premium_dict.copy()
    data.update(
        invoice=payment.signer.sign_user(request.related_user),
        notify_url=request.build_absolute_uri(reverse('paypal-ipn')),
        return_url=request.build_absolute_uri('/devenir-premium/valider/'),
        cancel_return=request.build_absolute_uri('/devenir-premium/annuler/')
    )
    form = PayPalPaymentsForm(button_type=PayPalPaymentsForm.SUBSCRIBE, initial=data)
    return render(request, "account/premium.html", get_context(form=form, action=action))

@login_required
@require_related
def advanced(request):
    """
    Render the advanved settings view. It is called by several views.
    """
    FormClass = forms.PrestataireAdvancedForm
    if isinstance(request.related_user, Famille):
        FormClass = forms.FamilleAdvancedForm

    if request.method == "POST":
        form = FormClass(instance=request.related_user, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/mon-compte/parametres-avances/?success')
    else:
        form = FormClass(instance=request.related_user)

    return render(request, "account/advanced.html", get_context(form=form))

def tools(request):
    """
    Display the tools (DownloadableFile objects) to the user.
    """
    tool_files = defaultdict(list)
    for tool in DownloadableFile.objects.all():
        tool_files[tool.file_type].append(tool)

    return render(
        request, "espace/tools.html",
        get_context(tool_files=dict(tool_files), kinds=DownloadableFile.KINDS)
    )

@login_required
@require_related
@require_GET
def delete_account(request):
    """
    Mark an account as inactive.
    """
    request.user.is_active = False
    request.user.save()
    logout(request)
    return HttpResponseRedirect('/')
<commit_msg>basic user have no public profile, only premium<commit_after>from collections import defaultdict

from django.conf import settings
from django.contrib.auth import logout
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.shortcuts import render, redirect, get_object_or_404, render_to_response
from django.views.decorators.http import require_POST, require_GET
from paypal.standard.forms import PayPalPaymentsForm

from famille import forms
from famille.models import (
    Famille, Prestataire, get_user_related, UserInfo,
    has_user_related, FamilleRatings, PrestataireRatings,
    compute_user_visibility_filters, DownloadableFile
)
from famille.resources import PrestataireResource, FamilleResource
from famille.utils import get_context, get_result_template_from_user, payment
from famille.utils.http import require_related, login_required, assert_POST

__all__ = [
    "home", "search", "register", "account",
    "favorite", "profile", "premium",
    "tools", "advanced", "delete_account"
]

def home(request):
    """
    Home view. Rendering first forms.
    """
    search_form = forms.SimpleSearchForm()
    registration_form = forms.RegistrationForm()
    return render(
        request, "home.html",
        get_context(search_form=search_form, registration_form=registration_form)
    )

def search(request):
    """
    Search view.
    """
    data = request.POST if request.method == "POST" else request.GET
    search_type = data.get("type")
    search_type = "prestataire" if search_type not in ["famille", "prestataire"] else search_type
    if search_type == "famille":
        FormClass = forms.FamilleSearchForm
        objects = Famille.objects.filter(compute_user_visibility_filters(request.user))
        template = "search/famille.html"
    else:
        FormClass = forms.PrestataireSearchForm
        objects = Prestataire.objects.all()
        template = "search/prestataire.html"

    form = FormClass(data)
    if not form.is_valid():
        form = FormClass()

    # TODO: do location filtering, together with geolocation stuff ?
    objects = objects.order_by("-updated_at")
    total_search_results = objects.count()
    nb_search_results = min(settings.NB_SEARCH_RESULTS, total_search_results)
    objects = objects[:nb_search_results]
    result_template = get_result_template_from_user(request)
    if request.user.is_authenticated():
        favorites = get_user_related(request.user).favorites.all()
    else:
        favorites = []
    return render(
        request, template,
        get_context(
            search_form=form, results=objects, result_template=result_template,
            nb_search_results=nb_search_results, ordering=form.ordering_dict,
            favorites=favorites, user=request.user, search_type=search_type,
            max_nb_search_results=settings.NB_SEARCH_RESULTS,
            total_search_results=total_search_results
        )
    )

def register(request, social=None, type=None):
    """
    Register view. Allow user creation.
    """
    if not type:
        if request.method == "POST":
            form = forms.RegistrationForm(request.POST)
            if form.is_valid():
                form.save()
        else:
            form = forms.RegistrationForm()
        return render(request, "registration/register.html", get_context(social=social, form=form))
    else:
        if not has_user_related(request.user):
            UserInfo.create_user(dj_user=request.user, type=type)
        else:
            return redirect('account')

    return HttpResponseRedirect('/confirmation/')

# TODO: error handling for compte form
@login_required
@require_related
def account(request):
    url_hash = ""
    if request.method == "POST":
        account_forms = forms.AccountFormManager(instance=request.related_user, data=request.POST, files=request.FILES)
        url_hash = account_forms.form_submitted
        if account_forms.is_valid():
            account_forms.save()
            return HttpResponseRedirect('/mon-compte/?success#%s' % url_hash)
    else:
        account_forms = forms.AccountFormManager(instance=request.related_user)

    return render(
        request, 'account/%s.html' % account_forms.instance_type,
        get_context(related=request.related_user, url_hash=url_hash, **account_forms.forms)
    )

@login_required
@require_related
@require_POST
def favorite(request):
    """
    Mark an object as favorite. If action=remove is passed,
    the given object is removed from favorites.
    """
    resource_uri = request.POST["resource_uri"]
    action_name = request.POST.get("action", "add")
    user_related = request.related_user
    action = user_related.remove_favorite if action_name == "remove" else user_related.add_favorite
    action(resource_uri)

    return HttpResponse()

@login_required
@require_related
@require_GET
def profile(request, type, uid):
    """
    Display the profile of a user.
    A nice 404 view is shown to the user
    if the profile does not exist OR the profile
    is not premium.
    A nice 401 view is shown to the user if the
    profile didn't want to show itself to the user
    or globally.
    """
    if type not in ("famille", "prestataire"):
        raise Http404

    context = {}

    if type == "famille":
        ModelClass = Famille
        RatingClass = FamilleRatings
        RatingFormClass = forms.RatingFamilleForm
    else:
        ModelClass = Prestataire
        RatingClass = PrestataireRatings
        RatingFormClass = forms.RatingPrestataireForm

    try:
        user = ModelClass.objects.get(pk=uid)
    except ModelClass.DoesNotExist:
        return render(request, "profile/404.html", status=404)

    # the user can view its own profile but others cannot if he is not premium
    if request.related_user != user and not user.is_premium:
        return render(request, "profile/404.html", status=404)

    if not user.profile_access_is_authorized(request):
        return render(request, "profile/401.html", status=401)

    if has_user_related(request.user):
        related_user = get_user_related(request.user)
        if not RatingClass.user_has_voted_for(related_user, user):
            rating = RatingClass(user=user, by=related_user.simple_id)
            context["rating_form"] = RatingFormClass(instance=rating)

    return render(request, "profile/base.html", get_context(profile=user, **context))

premium_dict = {
    "business": settings.PAYPAL_RECEIVER_EMAIL,
    "amount": settings.PREMIUM_PRICE,
    "item_name": "Compte premium Une vie de famille",
    "item_number": settings.PREMIUM_ID,
    "src": "1",
    "currency_code": "EUR"
}

@login_required
@require_related
@require_GET
def premium(request, action=None):
    """
    Page to become premium.
    """
    if request.related_user.is_premium:
        return render_to_response("account/already_premium.html")

    if action == "valider":
        return render(request, "account/premium.html", get_context(action=action))

    data = premium_dict.copy()
    data.update(
        invoice=payment.signer.sign_user(request.related_user),
        notify_url=request.build_absolute_uri(reverse('paypal-ipn')),
        return_url=request.build_absolute_uri('/devenir-premium/valider/'),
        cancel_return=request.build_absolute_uri('/devenir-premium/annuler/')
    )
    form = PayPalPaymentsForm(button_type=PayPalPaymentsForm.SUBSCRIBE, initial=data)
    return render(request, "account/premium.html", get_context(form=form, action=action))

@login_required
@require_related
def advanced(request):
    """
    Render the advanved settings view. It is called by several views.
    """
    FormClass = forms.PrestataireAdvancedForm
    if isinstance(request.related_user, Famille):
        FormClass = forms.FamilleAdvancedForm

    if request.method == "POST":
        form = FormClass(instance=request.related_user, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/mon-compte/parametres-avances/?success')
    else:
        form = FormClass(instance=request.related_user)

    return render(request, "account/advanced.html", get_context(form=form))

def tools(request):
    """
    Display the tools (DownloadableFile objects) to the user.
    """
    tool_files = defaultdict(list)
    for tool in DownloadableFile.objects.all():
        tool_files[tool.file_type].append(tool)

    return render(
        request, "espace/tools.html",
        get_context(tool_files=dict(tool_files), kinds=DownloadableFile.KINDS)
    )

@login_required
@require_related
@require_GET
def delete_account(request):
    """
    Mark an account as inactive.
    """
    request.user.is_active = False
    request.user.save()
    logout(request)
    return HttpResponseRedirect('/')
<|endoftext|>