<commit_before>#!/usr/bin/python
'''
Generate a single card
'''
import argparse
import base64
import traceback
import sys
import urllib
import requests
import TSSSF_CardGen
import json
import imgur_auth
import re
from StringIO import StringIO

def SaveCardToFile(image_object, location):
    image_object.save(location, format="PNG", dpi=(300, 300))
    return location

def SaveCardToURL(image_object):
    fileobj = StringIO()
    image_object.save(fileobj, format="PNG", dpi=(300, 300))
    encoded_image = fileobj.getvalue().encode("base64")
    return("data:image/png;base64," + urllib.quote(encoded_image))

def GetImgurCredits():
    credits = requests.get(
        'https://api.imgur.com/3/credits.json',
        headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID},
        data={'key': imgur_auth.CLIENT_SECRET}
    )
    return json.loads(credits.text)["data"]["ClientRemaining"]

def SaveCardToImgur(image_object, title=None, desc=None):
    #Make sure we have the budget to do this
    if GetImgurCredits() < 10:
        raise ValueError("Insufficient imgur credits remaining")
    fileobj = StringIO()
    image_object.save(fileobj, format="PNG", dpi=(300, 300))

    img_json = requests.post(
        'https://api.imgur.com/3/upload.json',
        headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID},
        data={
            'key': imgur_auth.CLIENT_SECRET,
            'title': base64.b64decode(title) if title else 'Card generated with TSSSF Card Generator',
            'description': base64.b64decode(desc) if desc else '',
            'type': 'base64',
            'image': fileobj.getvalue().encode("base64")
        }
    )
    #return img_json.text
    return json.loads(img_json.text)["data"]["id"]

def SaveCard(image, save_type, location=None, imgurtitle=None, imgurdesc=None):
    if save_type == "file":
        retval = SaveCardToFile(image, location)
    elif save_type == "encoded_url":
        retval = SaveCardToURL(image)
    elif save_type == "imgur":
        retval = SaveCardToImgur(image, imgurtitle, imgurdesc)
    else:
        raise ValueError("save type not recognized")
    return retval

def make_single_card(encoded_line, output_file, image_type, save_type,
                     imgurtitle, imgurdesc):
    im = {}

    try:
        card_line = base64.b64decode(encoded_line).decode('utf-8')
        print("Attempting to build card %r" % card_line)
        (im["bleed"],
         im["cropped"],
         im["vassal"]) = TSSSF_CardGen.BuildSingleCard(card_line)

        outstr = SaveCard(im[image_type], save_type, output_file, imgurtitle,
                          imgurdesc)
        print >> ACTUAL_STDOUT, outstr
    except Exception:
        print("Failed to build single card %r" % card_line)
        print(traceback.format_exc())
        sys.exit(1)
    print("Success!")
    sys.exit(0)

if __name__ == '__main__':
    ACTUAL_STDOUT = sys.stdout
    sys.stdout = sys.stderr
    parser = argparse.ArgumentParser(prog="single_card.py")

    parser.add_argument('-c', '--card_line',
                        help="Base64-encoded single-line card definition",
                        required=True)
    parser.add_argument('-o', '--output',
                        help="File to write card to",
                        default=None)
    parser.add_argument('-i', '--imagetype',
                        help="Set image type to output",
                        choices=("bleed", "cropped", "vassal"),
                        default="cropped")
    parser.add_argument('-r', '--returntype',
                        help="Output format",
                        choices=("file", "encoded_url", "imgur"),
                        default="cropped")
    parser.add_argument('-t', '--imgurtitle',
                        help="Base64-encoded alternate imgur title",
                        default=None)
    parser.add_argument('-d', '--imgurdesc',
                        help="Base64-encoded alternate imgur description",
                        default=None)

    args = parser.parse_args()

    if args.returntype == "file" and args.output is None:
        parser.error("--output must be defined if --returntype is set to file")

    make_single_card(args.card_line, args.output, args.imagetype,
                     args.returntype, args.imgurtitle, args.imgurdesc)
<commit_msg>Ensure we get an accurate exception log when failing.<commit_after>#!/usr/bin/python
'''
Generate a single card
'''
import argparse
import base64
import traceback
import sys
import urllib
import requests
import TSSSF_CardGen
import json
import imgur_auth
import re
from StringIO import StringIO

def SaveCardToFile(image_object, location):
    image_object.save(location, format="PNG", dpi=(300, 300))
    return location

def SaveCardToURL(image_object):
    fileobj = StringIO()
    image_object.save(fileobj, format="PNG", dpi=(300, 300))
    encoded_image = fileobj.getvalue().encode("base64")
    return("data:image/png;base64," + urllib.quote(encoded_image))

def GetImgurCredits():
    credits = requests.get(
        'https://api.imgur.com/3/credits.json',
        headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID},
        data={'key': imgur_auth.CLIENT_SECRET}
    )
    return json.loads(credits.text)["data"]["ClientRemaining"]

def SaveCardToImgur(image_object, title=None, desc=None):
    #Make sure we have the budget to do this
    if GetImgurCredits() < 10:
        raise ValueError("Insufficient imgur credits remaining")
    fileobj = StringIO()
    image_object.save(fileobj, format="PNG", dpi=(300, 300))

    img_json = requests.post(
        'https://api.imgur.com/3/upload.json',
        headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID},
        data={
            'key': imgur_auth.CLIENT_SECRET,
            'title': base64.b64decode(title) if title else 'Card generated with TSSSF Card Generator',
            'description': base64.b64decode(desc) if desc else '',
            'type': 'base64',
            'image': fileobj.getvalue().encode("base64")
        }
    )
    #return img_json.text
    return json.loads(img_json.text)["data"]["id"]

def SaveCard(image, save_type, location=None, imgurtitle=None, imgurdesc=None):
    if save_type == "file":
        retval = SaveCardToFile(image, location)
    elif save_type == "encoded_url":
        retval = SaveCardToURL(image)
    elif save_type == "imgur":
        retval = SaveCardToImgur(image, imgurtitle, imgurdesc)
    else:
        raise ValueError("save type not recognized")
    return retval

def make_single_card(encoded_line, output_file, image_type, save_type,
                     imgurtitle, imgurdesc):
    im = {}

    try:
        card_line = base64.b64decode(encoded_line).decode('utf-8')
        print("Attempting to build card %r" % card_line)
        (im["bleed"],
         im["cropped"],
         im["vassal"]) = TSSSF_CardGen.BuildSingleCard(card_line)

        outstr = SaveCard(im[image_type], save_type, output_file, imgurtitle,
                          imgurdesc)
        print >> ACTUAL_STDOUT, outstr
    except Exception:
        print(traceback.format_exc())
        print("Failed to build single card %r" % card_line)
        sys.exit(1)
    print("Success!")
    sys.exit(0)

if __name__ == '__main__':
    ACTUAL_STDOUT = sys.stdout
    sys.stdout = sys.stderr
    parser = argparse.ArgumentParser(prog="single_card.py")

    parser.add_argument('-c', '--card_line',
                        help="Base64-encoded single-line card definition",
                        required=True)
    parser.add_argument('-o', '--output',
                        help="File to write card to",
                        default=None)
    parser.add_argument('-i', '--imagetype',
                        help="Set image type to output",
                        choices=("bleed", "cropped", "vassal"),
                        default="cropped")
    parser.add_argument('-r', '--returntype',
                        help="Output format",
                        choices=("file", "encoded_url", "imgur"),
                        default="cropped")
    parser.add_argument('-t', '--imgurtitle',
                        help="Base64-encoded alternate imgur title",
                        default=None)
    parser.add_argument('-d', '--imgurdesc',
                        help="Base64-encoded alternate imgur description",
                        default=None)

    args = parser.parse_args()

    if args.returntype == "file" and args.output is None:
        parser.error("--output must be defined if --returntype is set to file")

    make_single_card(args.card_line, args.output, args.imagetype,
                     args.returntype, args.imgurtitle, args.imgurdesc)
<|endoftext|>


<commit_before>
#
# spyne - Copyright (C) Spyne contributors.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
#

"""The ``spyne.error`` module contains various common exceptions that the user
code can throw.
"""

from spyne.model.fault import Fault

class InvalidCredentialsError(Fault):
    """Raised when requested resource is forbidden."""

    CODE = 'Client.InvalidCredentialsError'
    STR = "You do not have permission to access this resource."

    def __init__(self, fault_string=STR, params=None):
        super(InvalidCredentialsError, self) \
                               .__init__(self.CODE, fault_string, detail=params)

class RequestTooLongError(Fault):
    """Raised when request is too long."""

    CODE = 'Client.RequestTooLong'

    def __init__(self, faultstring="Request too long"):
        super(RequestTooLongError, self).__init__(self.CODE, faultstring)

class RequestNotAllowed(Fault):
    """Raised when request is incomplete."""

    CODE = 'Client.RequestNotAllowed'

    def __init__(self, faultstring=""):
        super(RequestNotAllowed, self).__init__(self.CODE, faultstring)

class ArgumentError(Fault):
    """Raised when there is a general problem with input data."""

    CODE = 'Client.ArgumentError'

    def __init__(self, faultstring=""):
        super(ArgumentError, self).__init__(self.CODE, faultstring)

class InvalidInputError(Fault):
    """Raised when there is a general problem with input data."""

    def __init__(self, faultstring="", data=""):
        super(InvalidInputError, self) \
                     .__init__('Client.InvalidInput', repr((faultstring, data)))

InvalidRequestError = InvalidInputError

class MissingFieldError(InvalidInputError):
    """Raised when a mandatory value is missing."""

    CODE = 'Client.InvalidInput'

    def __init__(self, field_name, message="Field '%s' is missing."):
        try:
            message = message % (field_name,)
        except TypeError:
            pass

        super(MissingFieldError, self).__init__(self.CODE, message)

class ValidationError(Fault):
    """Raised when the input stream does not adhere to type constraints."""

    CODE = 'Client.ValidationError'

    def __init__(self, obj, custom_msg='The value %r could not be validated.'):
        try:
            msg = custom_msg % (obj,)
        except TypeError:
            msg = custom_msg

        super(ValidationError, self).__init__(self.CODE, msg)

class InternalError(Fault):
    """Raised to communicate server-side errors."""

    CODE = 'Server'

    def __init__(self, error):
        super(InternalError, self)\
            .__init__(self.CODE, "InternalError: An unknown error has occured.")

class ResourceNotFoundError(Fault):
    """Raised when requested resource is not found."""

    CODE = 'Client.ResourceNotFound'

    def __init__(self, fault_object,
                                fault_string="Requested resource %r not found"):
        super(ResourceNotFoundError, self) \
                            .__init__(self.CODE, fault_string % (fault_object,))

class RespawnError(ResourceNotFoundError):
    pass

class ResourceAlreadyExistsError(Fault):
    """Raised when requested resource already exists on server side."""

    CODE = 'Client.ResourceAlreadyExists'

    def __init__(self, fault_object, fault_string="Resource %r already exists"):
        super(ResourceAlreadyExistsError, self) \
                               .__init__(self.CODE, fault_string % fault_object)

class Redirect(Fault):
    """Raised when client needs to make another request for the same
    resource."""

    CODE = 'Client.Redirect'

    def __init__(self, ctx, location, orig_exc=None):
        super(Redirect, self).__init__(self.CODE, faultstring=location)

        self.ctx = ctx
        self.location = location
        self.orig_exc = orig_exc

    def do_redirect(self):
        raise NotImplementedError()
<commit_msg>minor<commit_after>
#
# spyne - Copyright (C) Spyne contributors.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
#

"""The ``spyne.error`` module contains various common exceptions that the user
code can throw.
"""

from spyne.model.fault import Fault

class InvalidCredentialsError(Fault):
    """Raised when requested resource is forbidden."""

    CODE = 'Client.InvalidCredentialsError'
    STR = "You do not have permission to access this resource."

    def __init__(self, fault_string=STR, params=None):
        super(InvalidCredentialsError, self) \
                               .__init__(self.CODE, fault_string, detail=params)

class RequestTooLongError(Fault):
    """Raised when request is too long."""

    CODE = 'Client.RequestTooLong'

    def __init__(self, faultstring="Request too long"):
        super(RequestTooLongError, self).__init__(self.CODE, faultstring)

class RequestNotAllowed(Fault):
    """Raised when request is incomplete."""

    CODE = 'Client.RequestNotAllowed'

    def __init__(self, faultstring=""):
        super(RequestNotAllowed, self).__init__(self.CODE, faultstring)

class ArgumentError(Fault):
    """Raised when there is a general problem with input data."""

    CODE = 'Client.ArgumentError'

    def __init__(self, faultstring=""):
        super(ArgumentError, self).__init__(self.CODE, faultstring)

class InvalidInputError(Fault):
    """Raised when there is a general problem with input data."""

    def __init__(self, faultstring="", data=""):
        super(InvalidInputError, self) \
                     .__init__('Client.InvalidInput', repr((faultstring, data)))

InvalidRequestError = InvalidInputError

class MissingFieldError(InvalidInputError):
    """Raised when a mandatory value is missing."""

    CODE = 'Client.InvalidInput'

    def __init__(self, field_name, message="Field '%s' is missing."):
        try:
            message = message % (field_name,)
        except TypeError:
            pass

        super(MissingFieldError, self).__init__(self.CODE, message)

class ValidationError(Fault):
    """Raised when the input stream does not adhere to type constraints."""

    CODE = 'Client.ValidationError'

    def __init__(self, obj, custom_msg='The value %r could not be validated.'):
        try:
            msg = custom_msg % (obj,)
        except TypeError:
            msg = custom_msg

        super(ValidationError, self).__init__(self.CODE, msg)

class InternalError(Fault):
    """Raised to communicate server-side errors."""

    CODE = 'Server'

    def __init__(self, error):
        super(InternalError, self) \
            .__init__(self.CODE, "InternalError: An unknown error has occured.")

class ResourceNotFoundError(Fault):
    """Raised when requested resource is not found."""

    CODE = 'Client.ResourceNotFound'

    def __init__(self, fault_object,
                                fault_string="Requested resource %r not found"):
        super(ResourceNotFoundError, self) \
                            .__init__(self.CODE, fault_string % (fault_object,))

class RespawnError(ResourceNotFoundError):
    pass

class ResourceAlreadyExistsError(Fault):
    """Raised when requested resource already exists on server side."""

    CODE = 'Client.ResourceAlreadyExists'

    def __init__(self, fault_object, fault_string="Resource %r already exists"):
        super(ResourceAlreadyExistsError, self) \
                               .__init__(self.CODE, fault_string % fault_object)

class Redirect(Fault):
    """Raised when client needs to make another request for the same
    resource."""

    CODE = 'Client.Redirect'

    def __init__(self, ctx, location, orig_exc=None):
        super(Redirect, self).__init__(self.CODE, faultstring=location)

        self.ctx = ctx
        self.location = location
        self.orig_exc = orig_exc

    def do_redirect(self):
        raise NotImplementedError()
<|endoftext|>


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

import os
import logging

import yaml

from skew.exception import ConfigNotFoundError

LOG = logging.getLogger(__name__)

_config = None

def get_config():
    global _config
    if _config is None:
        path = os.environ.get('SKEW_CONFIG', os.path.join('~', '.skew'))
        path = os.path.expanduser(path)
        path = os.path.expandvars(path)
        if not os.path.exists(path):
            raise ConfigNotFoundError('Unable to find skew config file')
        with open(path) as config_file:
            _config = yaml.load(config_file)
    return _config
<commit_msg>Use yaml.safe_load (#137)<commit_after># Copyright 2015 Mitch Garnaat
#
# 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.

import os
import logging

import yaml

from skew.exception import ConfigNotFoundError

LOG = logging.getLogger(__name__)

_config = None

def get_config():
    global _config
    if _config is None:
        path = os.environ.get('SKEW_CONFIG', os.path.join('~', '.skew'))
        path = os.path.expanduser(path)
        path = os.path.expandvars(path)
        if not os.path.exists(path):
            raise ConfigNotFoundError('Unable to find skew config file')
        with open(path) as config_file:
            _config = yaml.safe_load(config_file)
    return _config
<|endoftext|>


<commit_before>"""
The :mod:`sklearn.lda` module implements Linear Discriminant Analysis (LDA).
"""
# Authors: Matthieu Perrot
#          Mathieu Blondel

import warnings

import numpy as np
from scipy import linalg

from .base import BaseEstimator, ClassifierMixin, TransformerMixin
from .utils.extmath import logsumexp
from .utils.fixes import unique
from .utils import check_arrays, array2d

__all__ = ['LDA']

class LDA(BaseEstimator, ClassifierMixin, TransformerMixin):
    """
    Linear Discriminant Analysis (LDA)

    A classifier with a linear decision boundary, generated
    by fitting class conditional densities to the data
    and using Bayes' rule.

    The model fits a Gaussian density to each class, assuming that
    all classes share the same covariance matrix.

    The fitted model can also be used to reduce the dimensionality
    of the input, by projecting it to the most discriminative
    directions.

    Parameters
    ----------
    n_components: int
        Number of components (< n_classes - 1) for dimensionality reduction

    priors : array, optional, shape = [n_classes]
        Priors on classes

    Attributes
    ----------
    `coef_` : array-like, shape = [n_features,]
        Coefficients of the features in the linear decision function.

    `covariance_` : array-like, shape = [n_features, n_features]
        Covariance matrix (shared by all classes).

    `means_` : array-like, shape = [n_classes, n_features]
        Class means.

    `priors_` : array-like, shape = [n_classes]
        Class priors (sum to 1).

    `scalings_` : array-like, shape = [feature_rank, n_classes - 1]
        Scaling of the features in the space spanned by the class
        centroids.

    `xbar_` : float, shape = [n_features]
        Overall mean.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.lda import LDA
    >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
    >>> y = np.array([1, 1, 1, 2, 2, 2])
    >>> clf = LDA()
    >>> clf.fit(X, y)
    LDA(n_components=None, priors=None)
    >>> print(clf.predict([[-0.8, -1]]))
    [1]

    See also
    --------
    sklearn.qda.QDA: Quadratic discriminant analysis

    """

    def __init__(self, n_components=None, priors=None):
        self.n_components = n_components
        self.priors = np.asarray(priors) if priors is not None else None

        if self.priors is not None:
            if (self.priors < 0).any():
                raise ValueError('priors must be non-negative')
            if self.priors.sum() != 1:
                print 'warning: the priors do not sum to 1. Renormalizing'
                self.priors = self.priors / self.priors.sum()

    def fit(self, X, y, store_covariance=False, tol=1.0e-4):
        """
        Fit the LDA model according to the given training data and parameters.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]
            Training vector, where n_samples in the number of samples and
            n_features is the number of features.

        y : array, shape = [n_samples]
            Target values (integers)

        store_covariance : boolean
            If True the covariance matrix (shared by all classes) is computed
            and stored in `self.covariance_` attribute.
        """
        X, y = check_arrays(X, y, sparse_format='dense')
        self.classes_, y = unique(y, return_inverse=True)
        n_samples, n_features = X.shape
        n_classes = len(self.classes_)
        if n_classes < 2:
            raise ValueError('y has less than 2 classes')
        if self.priors is None:
            self.priors_ = np.bincount(y) / float(n_samples)
        else:
            self.priors_ = self.priors

        # Group means n_classes*n_features matrix
        means = []
        Xc = []
        cov = None
        if store_covariance:
            cov = np.zeros((n_features, n_features))
        for ind in xrange(n_classes):
            Xg = X[y == ind, :]
            meang = Xg.mean(0)
            means.append(meang)
            # centered group data
            Xgc = Xg - meang
            Xc.append(Xgc)
            if store_covariance:
                cov += np.dot(Xgc.T, Xgc)
        if store_covariance:
            cov /= (n_samples - n_classes)
            self.covariance_ = cov

        self.means_ = np.asarray(means)
        Xc = np.concatenate(Xc, 0)

        # ----------------------------
        # 1) within (univariate) scaling by with classes std-dev
        std = Xc.std(axis=0)
        # avoid division by zero in normalization
        std[std == 0] = 1.
        fac = float(1) / (n_samples - n_classes)
        # ----------------------------
        # 2) Within variance scaling
        X = np.sqrt(fac) * (Xc / std)
        # SVD of centered (within)scaled data
        U, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol)
        if rank < n_features:
            warnings.warn("Variables are collinear")
        # Scaling of within covariance is: V' 1/S
        scalings = (V[:rank] / std).T / S[:rank]

        ## ----------------------------
        ## 3) Between variance scaling
        # Overall mean
        xbar = np.dot(self.priors_, self.means_)
        # Scale weighted centers
        X = np.dot(((np.sqrt((n_samples * self.priors_) * fac)) *
                    (means - xbar).T).T, scalings)
        # Centers are living in a space with n_classes-1 dim (maximum)
        # Use svd to find projection in the space spanned by the
        # (n_classes) centers
        _, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol * S[0])
        # compose the scalings
        self.scalings_ = np.dot(scalings, V.T[:, :rank])
        self.xbar_ = xbar
        # weight vectors / centroids
        self.coef_ = np.dot(self.means_ - self.xbar_, self.scalings_)
        self.intercept_ = (-0.5 * np.sum(self.coef_ ** 2, axis=1) +
                           np.log(self.priors_))
        return self

    @property
    def classes(self):
        warnings.warn("LDA.classes is deprecated and will be removed in 0.14. "
                      "Use LDA.classes_ instead.", DeprecationWarning,
                      stacklevel=2)
        return self.classes_

    @property
    def scaling(self):  # pragma: no cover
        warnings.warn("LDA.scaling is deprecated and will be removed in 0.15."
                      " Use LDA.scalings_ instead.", DeprecationWarning,
                      stacklevel=2)
        return self.scalings_

    def _decision_function(self, X):
        X = array2d(X)
        # center and scale data
        X = np.dot(X - self.xbar_, self.scalings_)
        return np.dot(X, self.coef_.T) + self.intercept_

    def decision_function(self, X):
        """
        This function return the decision function values related to each
        class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes] or [n_samples,]
            Decision function values related to each class, per sample.
            In the two-class case, the shape is [n_samples,], giving the
            log likelihood ratio of the positive class.
        """
        dec_func = self._decision_function(X)
        if len(self.classes_) == 2:
            return dec_func[:, 1] - dec_func[:, 0]
        return dec_func

    def transform(self, X):
        """
        Project the data so as to maximize class separation (large separation
        between projected class means and small variance within each class).

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        X_new : array, shape = [n_samples, n_components]
        """
        X = array2d(X)
        # center and scale data
        X = np.dot(X - self.xbar_, self.scalings_)
        n_comp = X.shape[1] if self.n_components is None else self.n_components
        return np.dot(X, self.coef_[:n_comp].T)

    def predict(self, X):
        """
        This function does classification on an array of test vectors X.

        The predicted class C for each sample in X is returned.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples]
        """
        d = self._decision_function(X)
        y_pred = self.classes_.take(d.argmax(1))
        return y_pred

    def predict_proba(self, X):
        """
        This function return posterior probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        # compute the likelihood of the underlying gaussian models
        # up to a multiplicative constant.
        likelihood = np.exp(values - values.max(axis=1)[:, np.newaxis])
        # compute posterior probabilities
        return likelihood / likelihood.sum(axis=1)[:, np.newaxis]

    def predict_log_proba(self, X):
        """
        This function return posterior log-probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        loglikelihood = (values - values.max(axis=1)[:, np.newaxis])
        normalization = logsumexp(loglikelihood, axis=1)
        return loglikelihood - normalization[:, np.newaxis]
<commit_msg>DOC fix shape of coef_ for LDA.<commit_after>"""
The :mod:`sklearn.lda` module implements Linear Discriminant Analysis (LDA).
"""
# Authors: Matthieu Perrot
#          Mathieu Blondel

import warnings

import numpy as np
from scipy import linalg

from .base import BaseEstimator, ClassifierMixin, TransformerMixin
from .utils.extmath import logsumexp
from .utils.fixes import unique
from .utils import check_arrays, array2d

__all__ = ['LDA']

class LDA(BaseEstimator, ClassifierMixin, TransformerMixin):
    """
    Linear Discriminant Analysis (LDA)

    A classifier with a linear decision boundary, generated
    by fitting class conditional densities to the data
    and using Bayes' rule.

    The model fits a Gaussian density to each class, assuming that
    all classes share the same covariance matrix.

    The fitted model can also be used to reduce the dimensionality
    of the input, by projecting it to the most discriminative
    directions.

    Parameters
    ----------
    n_components: int
        Number of components (< n_classes - 1) for dimensionality reduction

    priors : array, optional, shape = [n_classes]
        Priors on classes

    Attributes
    ----------
    `coef_` : array-like, shape = [rank, n_classes - 1]
        Coefficients of the features in the linear decision function.
        rank is min(rank_features, n_classes) where rank_features
        is the dimensionality of the spaces spanned by the features
        (i.e. excluding redundant features).

    `covariance_` : array-like, shape = [n_features, n_features]
        Covariance matrix (shared by all classes).

    `means_` : array-like, shape = [n_classes, n_features]
        Class means.

    `priors_` : array-like, shape = [n_classes]
        Class priors (sum to 1).

    `scalings_` : array-like, shape = [rank, n_classes - 1]
        Scaling of the features in the space spanned by the class
        centroids.

    `xbar_` : float, shape = [n_features]
        Overall mean.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.lda import LDA
    >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
    >>> y = np.array([1, 1, 1, 2, 2, 2])
    >>> clf = LDA()
    >>> clf.fit(X, y)
    LDA(n_components=None, priors=None)
    >>> print(clf.predict([[-0.8, -1]]))
    [1]

    See also
    --------
    sklearn.qda.QDA: Quadratic discriminant analysis

    """

    def __init__(self, n_components=None, priors=None):
        self.n_components = n_components
        self.priors = np.asarray(priors) if priors is not None else None

        if self.priors is not None:
            if (self.priors < 0).any():
                raise ValueError('priors must be non-negative')
            if self.priors.sum() != 1:
                print 'warning: the priors do not sum to 1. Renormalizing'
                self.priors = self.priors / self.priors.sum()

    def fit(self, X, y, store_covariance=False, tol=1.0e-4):
        """
        Fit the LDA model according to the given training data and parameters.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]
            Training vector, where n_samples in the number of samples and
            n_features is the number of features.

        y : array, shape = [n_samples]
            Target values (integers)

        store_covariance : boolean
            If True the covariance matrix (shared by all classes) is computed
            and stored in `self.covariance_` attribute.
        """
        X, y = check_arrays(X, y, sparse_format='dense')
        self.classes_, y = unique(y, return_inverse=True)
        n_samples, n_features = X.shape
        n_classes = len(self.classes_)
        if n_classes < 2:
            raise ValueError('y has less than 2 classes')
        if self.priors is None:
            self.priors_ = np.bincount(y) / float(n_samples)
        else:
            self.priors_ = self.priors

        # Group means n_classes*n_features matrix
        means = []
        Xc = []
        cov = None
        if store_covariance:
            cov = np.zeros((n_features, n_features))
        for ind in xrange(n_classes):
            Xg = X[y == ind, :]
            meang = Xg.mean(0)
            means.append(meang)
            # centered group data
            Xgc = Xg - meang
            Xc.append(Xgc)
            if store_covariance:
                cov += np.dot(Xgc.T, Xgc)
        if store_covariance:
            cov /= (n_samples - n_classes)
            self.covariance_ = cov

        self.means_ = np.asarray(means)
        Xc = np.concatenate(Xc, 0)

        # ----------------------------
        # 1) within (univariate) scaling by with classes std-dev
        std = Xc.std(axis=0)
        # avoid division by zero in normalization
        std[std == 0] = 1.
        fac = float(1) / (n_samples - n_classes)
        # ----------------------------
        # 2) Within variance scaling
        X = np.sqrt(fac) * (Xc / std)
        # SVD of centered (within)scaled data
        U, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol)
        if rank < n_features:
            warnings.warn("Variables are collinear")
        # Scaling of within covariance is: V' 1/S
        scalings = (V[:rank] / std).T / S[:rank]

        ## ----------------------------
        ## 3) Between variance scaling
        # Overall mean
        xbar = np.dot(self.priors_, self.means_)
        # Scale weighted centers
        X = np.dot(((np.sqrt((n_samples * self.priors_) * fac)) *
                    (means - xbar).T).T, scalings)
        # Centers are living in a space with n_classes-1 dim (maximum)
        # Use svd to find projection in the space spanned by the
        # (n_classes) centers
        _, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol * S[0])
        # compose the scalings
        self.scalings_ = np.dot(scalings, V.T[:, :rank])
        self.xbar_ = xbar
        # weight vectors / centroids
        self.coef_ = np.dot(self.means_ - self.xbar_, self.scalings_)
        self.intercept_ = (-0.5 * np.sum(self.coef_ ** 2, axis=1) +
                           np.log(self.priors_))
        return self

    @property
    def classes(self):
        warnings.warn("LDA.classes is deprecated and will be removed in 0.14. "
                      "Use LDA.classes_ instead.", DeprecationWarning,
                      stacklevel=2)
        return self.classes_

    @property
    def scaling(self):  # pragma: no cover
        warnings.warn("LDA.scaling is deprecated and will be removed in 0.15."
                      " Use LDA.scalings_ instead.", DeprecationWarning,
                      stacklevel=2)
        return self.scalings_

    def _decision_function(self, X):
        X = array2d(X)
        # center and scale data
        X = np.dot(X - self.xbar_, self.scalings_)
        return np.dot(X, self.coef_.T) + self.intercept_

    def decision_function(self, X):
        """
        This function return the decision function values related to each
        class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes] or [n_samples,]
            Decision function values related to each class, per sample.
            In the two-class case, the shape is [n_samples,], giving the
            log likelihood ratio of the positive class.
        """
        dec_func = self._decision_function(X)
        if len(self.classes_) == 2:
            return dec_func[:, 1] - dec_func[:, 0]
        return dec_func

    def transform(self, X):
        """
        Project the data so as to maximize class separation (large separation
        between projected class means and small variance within each class).

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        X_new : array, shape = [n_samples, n_components]
        """
        X = array2d(X)
        # center and scale data
        X = np.dot(X - self.xbar_, self.scalings_)
        n_comp = X.shape[1] if self.n_components is None else self.n_components
        return np.dot(X, self.coef_[:n_comp].T)

    def predict(self, X):
        """
        This function does classification on an array of test vectors X.

        The predicted class C for each sample in X is returned.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples]
        """
        d = self._decision_function(X)
        y_pred = self.classes_.take(d.argmax(1))
        return y_pred

    def predict_proba(self, X):
        """
        This function return posterior probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        # compute the likelihood of the underlying gaussian models
        # up to a multiplicative constant.
        likelihood = np.exp(values - values.max(axis=1)[:, np.newaxis])
        # compute posterior probabilities
        return likelihood / likelihood.sum(axis=1)[:, np.newaxis]

    def predict_log_proba(self, X):
        """
        This function return posterior log-probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        loglikelihood = (values - values.max(axis=1)[:, np.newaxis])
        normalization = logsumexp(loglikelihood, axis=1)
        return loglikelihood - normalization[:, np.newaxis]
<|endoftext|>


<commit_before>"""
Linear Discriminant Analysis (LDA)
"""

# Authors: Clemens Brunner
#          Martin Billinger
#          Matthieu Perrot
#          Mathieu Blondel

# License: BSD 3-Clause

from __future__ import print_function
import warnings

import numpy as np
from scipy import linalg

from .base import BaseEstimator, ClassifierMixin, TransformerMixin
from .covariance import ledoit_wolf, empirical_covariance
from .utils.extmath import logsumexp
from .utils.multiclass import unique_labels
from .utils import check_array, check_X_y
from .preprocessing import StandardScaler

def _cov(X, estimator):
    if estimator == 'ledoit_wolf':
        # standardize features because ledoit_wolf() does not support other shrinkage targets yet
        sc = StandardScaler()
        X = sc.fit_transform(X)
        std = np.diag(sc.std_)
        s = std.dot(ledoit_wolf(X)[0]).dot(std)  # rescale covariance matrix
    elif estimator == 'empirical':
        s = empirical_covariance(X)
    else:
        raise ValueError('unknown covariance estimation method')
    return s

class LDA(BaseEstimator, ClassifierMixin, TransformerMixin):
    """
    Linear Discriminant Analysis (LDA)

    A classifier with a linear decision boundary, generated by fitting class
    conditional densities to the data and using Bayes' rule.

    The model fits a Gaussian density to each class, assuming that all classes
    share the same covariance matrix.

    The fitted model can also be used to reduce the dimensionality of the input
    by projecting it to the most discriminative directions.

    Parameters
    ----------
    n_components : int
        Number of components (< n_classes - 1) for dimensionality reduction

    priors : array, optional, shape = [n_classes]
        Priors on classes

    use_covariance : string, optional
        Compute LDA based on covariance estimation, default None (uses SVD).
        Possible values are 'ledoit_wolf', which employs analytic shrinkage based
        on Ledoit-Wolf, and 'empirical' (no shrinkage).

    Attributes
    ----------
    coef_ : array-like, shape = [rank, n_classes - 1]
        Coefficients of the features in the linear decision
        function. rank is min(rank_features, n_classes) where
        rank_features is the dimensionality of the spaces spanned
        by the features (i.e. n_features excluding redundant features).

    covariance_ : array-like, shape = [n_features, n_features]
        Covariance matrix (shared by all classes).

    means_ : array-like, shape = [n_classes, n_features]
        Class means.

    priors_ : array-like, shape = [n_classes]
        Class priors (sum to 1).

    scalings_ : array-like, shape = [rank, n_classes - 1]
        Scaling of the features in the space spanned by the class
        centroids.

    xbar_ : float, shape = [n_features]
        Overall mean.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.lda import LDA
    >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
    >>> y = np.array([1, 1, 1, 2, 2, 2])
    >>> clf = LDA()
    >>> clf.fit(X, y)
    LDA(n_components=None, priors=None, use_covariance=None)
    >>> print(clf.predict([[-0.8, -1]]))
    [1]

    See also
    --------
    sklearn.qda.QDA: Quadratic discriminant analysis

    """

    def __init__(self, solver='svd', alpha=None, priors=None):
        self.solver = solver
        self.alpha = alpha
        self.priors = priors

    def _solve_lsqr(self, X, y, cov_estimator):
        classes = unique_labels(y)
        means = []
        covs = []
        for group in classes:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            covg = _cov(Xg, cov_estimator)
            covg = np.atleast_2d(covg)
            covs.append(covg)

        self.covariance_ = np.mean(covs, 0)
        means = np.asarray(means)
        self.xbar_ = np.dot(self.priors, means)

        # TODO: weight covariances with priors?
        Sw = np.mean(covs, 0)  # Within-class scatter
        means = means - self.xbar_

        self.coef_ = np.linalg.lstsq(Sw, means.T, rcond=1e-11)[0].T
        self.intercept_ = (-0.5 * np.diag(np.dot(means, self.coef_.T))
                           + np.log(self.priors))

    def _solve_eigen(self, X, y, cov_estimator):
        classes = unique_labels(y)
        means = []
        covs = []
        for group in classes:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            covg = _cov(Xg, cov_estimator)
            covg = np.atleast_2d(covg)
            covs.append(covg)

        self.covariance_ = np.mean(covs, 0)
        means = np.asarray(means)
        self.xbar_ = np.dot(self.priors, means)

        # TODO: weight covariances with priors?
        Sw = np.mean(covs, 0)  # Within-class scatter
        St = _cov(X, cov_estimator)
        Sb = St - Sw
        means = means - self.xbar_

        _, self.scalings_ = linalg.eigh(Sb, Sw)

        coef = np.dot(means, self.scalings_)
        self.coef_ = np.dot(coef, self.scalings_.T)
        self.intercept_ = (-0.5 * np.diag(np.dot(means, coef.T))
                           + np.log(self.priors))

    def _solve_svd(self, X, y, alpha, tol=1.0e-4):
        n_samples, n_features = X.shape
        n_classes = len(self.classes_)

        # compute class means and covariance matrix
        means = []
        # covs = []
        Xc = []
        for group in self.classes_:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            Xgc = Xg - meang
            Xc.append(Xgc)
            # covg = _cov(Xg, self.estimator)
            # covg = np.atleast_2d(covg)
            # covs.append(covg)
        means = np.asarray(means)
        self.xbar_ = np.dot(self.priors, means)
        # cov_ = np.mean(covs, 0)

        Xc = np.concatenate(Xc, axis=0)

        # 1) within (univariate) scaling by with classes std-dev
        std = Xc.std(axis=0)
        # avoid division by zero in normalization
        std[std == 0] = 1.
        fac = 1. / (n_samples - n_classes)

        # 2) Within variance scaling
        X = np.sqrt(fac) * (Xc / std)
        # SVD of centered (within)scaled data
        U, S, V = linalg.svd(X, full_matrices=False)

        rank = np.sum(S > tol)
        if rank < n_features:
            warnings.warn("variables are collinear")
        # Scaling of within covariance is: V' 1/S
        scalings = (V[:rank] / std).T / S[:rank]

        # 3) Between variance scaling
        # Scale weighted centers
        X = np.dot(((np.sqrt((n_samples * self.priors) * fac)) *
                    (means - self.xbar_).T).T, scalings)
        # Centers are living in a space with n_classes-1 dim (maximum)
        # Use SVD to find projection in the space spanned by the
        # (n_classes) centers
        _, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol * S[0])
        self.scalings_ = np.dot(scalings, V.T[:, :rank])
        coef = np.dot(means - self.xbar_, self.scalings_)
        self.intercept_ = (-0.5 * np.sum(coef**2, axis=1) + np.log(self.priors))
        self.coef_ = np.dot(coef, self.scalings_.T)

    def fit(self, X, y):
        """
        Fit the LDA model according to the given training data and parameters.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]
            Training vector, where n_samples in the number of samples and
            n_features is the number of features.

        y : array, shape = [n_samples]
            Target values (integers)

        store_covariance : boolean
            If True the covariance matrix (shared by all classes) is computed
            and stored in `self.covariance_` attribute.

        tol : float
            Threshold used for rank estimation (for LDA implemented with SVD).
        """
        X, y = check_X_y(X, y)
        self.classes_ = unique_labels(y)
        n_samples, n_features = X.shape
        self.priors = np.bincount(y) / float(n_samples)

        if self.solver == 'svd':
            self._solve_svd(X, y, self.alpha)
        elif self.solver == 'lsqr':
            self._solve_lsqr(X, y, self.alpha)
        elif self.solver == 'eigen':
            self._solve_eigen(X, y, self.alpha)

    def _decision_function(self, X):
        X = check_array(X)
        return np.dot(X - self.xbar_, self.coef_.T) + self.intercept_

    def decision_function(self, X):
        """
        This function returns the decision function values related to each
        class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes] or [n_samples,]
            Decision function values related to each class, per sample.
            In the two-class case, the shape is [n_samples,], giving the
            log likelihood ratio of the positive class.
        """
        dec_func = self._decision_function(X)
        if len(self.classes_) == 2:
            return dec_func[:, 1] - dec_func[:, 0]
        return dec_func

    def transform(self, X):
        """
        Project the data so as to maximize class separation (large separation
        between projected class means and small variance within each class).

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        X_new : array, shape = [n_samples, n_components]
        """
        X = check_array(X)
        # center and scale data
        X_new = np.dot(X - self.xbar_, self.scalings_)
        n_components = X.shape[1] if self.n_components is None \
            else self.n_components
        return X_new[:, :n_components]

    def predict(self, X):
        """
        This function does classification on an array of test vectors X.

        The predicted class C for each sample in X is returned.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples]
        """
        d = self._decision_function(X)
        y_pred = self.classes_.take(d.argmax(1))
        return y_pred

    def predict_proba(self, X):
        """
        This function returns posterior probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        # compute the likelihood of the underlying gaussian models
        # up to a multiplicative constant.
        likelihood = np.exp(values - values.max(axis=1)[:, np.newaxis])
        # compute posterior probabilities
        return likelihood / likelihood.sum(axis=1)[:, np.newaxis]

    def predict_log_proba(self, X):
        """
        This function returns posterior log-probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        loglikelihood = (values - values.max(axis=1)[:, np.newaxis])
        normalization = logsumexp(loglikelihood, axis=1)
        return loglikelihood - normalization[:, np.newaxis]
<commit_msg>Added LabelEncoder and updated most of the docstrings<commit_after>"""
Linear Discriminant Analysis (LDA)
"""

# Authors: Clemens Brunner
#          Martin Billinger
#          Matthieu Perrot
#          Mathieu Blondel

# License: BSD 3-Clause

from __future__ import print_function
import warnings

import numpy as np
from scipy import linalg

from .base import BaseEstimator, ClassifierMixin, TransformerMixin
from .covariance import ledoit_wolf, empirical_covariance
from .utils.extmath import logsumexp
from .utils.multiclass import unique_labels
from .utils import check_array, check_X_y
from .preprocessing import StandardScaler, LabelEncoder

def _cov(X, estimator='empirical'):
    """
    Estimate the covariance matrix using a specified estimator.

    Parameters
    ----------
    X : array-like, shape = [n_samples, n_features]
        Data vector

    estimator : string
        Covariance estimator, possible values:
          - 'empirical': empirical covariance matrix (default)
          - 'ledoit_wolf': shrunk covariance matrix using the Ledoit-Wolf lemma

    Returns
    -------
    s : array-like, shape = [n_features, n_features]
        Estimated covariance matrix
    """
    if estimator == 'ledoit_wolf':
        # standardize features
        sc = StandardScaler()
        X = sc.fit_transform(X)
        std = np.diag(sc.std_)
        s = std.dot(ledoit_wolf(X)[0]).dot(std)  # rescale covariance matrix
    elif estimator == 'empirical':
        s = empirical_covariance(X)
    else:
        raise ValueError('unknown covariance estimation method')
    return s

class LDA(BaseEstimator, ClassifierMixin, TransformerMixin):
    """
    Linear Discriminant Analysis (LDA)

    A classifier with a linear decision boundary, generated by fitting class
    conditional densities to the data and using Bayes' rule.

    The model fits a Gaussian density to each class, assuming that all classes
    share the same covariance matrix.

    The fitted model can also be used to reduce the dimensionality of the input
    by projecting it to the most discriminative directions.

    Parameters
    ----------
    solver : string, optional
        Solver to use, possible values:
          - 'svd': Singular value decomposition (default). Does not need to
                   compute the covariance matrix, therefore this solver is
                   recommended for very large feature dimensions.
          - 'lsqr': Least squares solution, can be combined with shrinkage (see
                    below)
          - 'eigen': Eigenvalue decomposition, can be combined with shrinkage
                    (see below)

    alpha : string or float, optional
        Shrinkage parameter, possible values:
          - None: No shrinkage (default)
          - 'ledoit_wolf': Ledoit-Wolf shrinkage (determines optimal shrinkage
                           parameter analytically)
          - 'empirical': Equivalent with no shrinkage (or a value of 0)
          - 0..1: If set to a number between 0 and 1, the shrinkage parameter is
                  set to this value (0 means no shrinkage)

    priors : array, optional, shape = [n_classes]
        Priors on classes

    n_comps : int
        Number of components (< n_classes - 1) for dimensionality reduction

    Attributes
    ----------
    coef_ : array, shape = [n_features] or [n_classes, n_features]
        Weight vector(s)

    intercept_ : array, shape = [n_features]
        Intercept term

    cov_ : array-like, shape = [n_features, n_features]
        Covariance matrix (shared by all classes)

    means_ : array-like, shape = [n_classes, n_features]
        Class means

    priors_ : array-like, shape = [n_classes]
        Class priors (sum to 1)

    scalings_ : array-like, shape = [rank, n_classes - 1]
        Scaling of the features in the space spanned by the class centroids

    xbar_ : array-like, shape = [n_features]
        Overall mean

    classes_ : array-like, shape = [n_classes]
        Unique class labels

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.lda import LDA
    >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
    >>> y = np.array([1, 1, 1, 2, 2, 2])
    >>> clf = LDA()
    >>> clf.fit(X, y)
    >>> print(clf.predict([[-0.8, -1]]))
    [0]

    See also
    --------
    sklearn.qda.QDA: Quadratic discriminant analysis
    """

    def __init__(self, solver='svd', alpha=None, priors=None, n_comps=None):
        self.solver = solver
        self.alpha = alpha
        self.priors = priors
        self.n_comps = n_comps

    def _solve_lsqr(self, X, y, cov_estimator):
        classes = unique_labels(y)
        means = []
        covs = []
        for group in classes:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            covg = _cov(Xg, cov_estimator)
            covg = np.atleast_2d(covg)
            covs.append(covg)

        self.cov_ = np.mean(covs, 0)
        self.means_ = np.asarray(means)
        self.xbar_ = np.dot(self.priors_, self.means_)

        # TODO: weight covariances with priors?
        Sw = np.mean(covs, 0)  # Within-class scatter
        means = self.means_ - self.xbar_

        self.coef_ = np.linalg.lstsq(Sw, means.T, rcond=1e-11)[0].T
        self.intercept_ = (-0.5 * np.diag(np.dot(means, self.coef_.T))
                           + np.log(self.priors_))

    def _solve_eigen(self, X, y, cov_estimator):
        classes = unique_labels(y)
        means = []
        covs = []
        for group in classes:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            covg = _cov(Xg, cov_estimator)
            covg = np.atleast_2d(covg)
            covs.append(covg)

        self.cov_ = np.mean(covs, 0)
        self.means_ = np.asarray(means)
        self.xbar_ = np.dot(self.priors_, means)

        # TODO: weight covariances with priors?
        Sw = np.mean(covs, 0)  # Within-class scatter
        St = _cov(X, cov_estimator)
        Sb = St - Sw
        means = self.means_ - self.xbar_

        _, self.scalings_ = linalg.eigh(Sb, Sw)

        coef = np.dot(means, self.scalings_)
        self.coef_ = np.dot(coef, self.scalings_.T)
        self.intercept_ = (-0.5 * np.diag(np.dot(means, coef.T))
                           + np.log(self.priors_))

    def _solve_svd(self, X, y, alpha, tol=1.0e-4):
        n_samples, n_features = X.shape
        n_classes = len(self.classes_)

        # compute class means and covariance matrix
        means = []
        # covs = []
        Xc = []
        for group in self.classes_:
            Xg = X[y == group, :]
            meang = Xg.mean(0)
            means.append(meang)
            Xgc = Xg - meang
            Xc.append(Xgc)
            # covg = _cov(Xg, self.estimator)
            # covg = np.atleast_2d(covg)
            # covs.append(covg)
        self.means_ = np.asarray(means)
        self.xbar_ = np.dot(self.priors_, self.means_)
        # cov_ = np.mean(covs, 0)

        Xc = np.concatenate(Xc, axis=0)

        # 1) within (univariate) scaling by with classes std-dev
        std = Xc.std(axis=0)
        # avoid division by zero in normalization
        std[std == 0] = 1.
        fac = 1. / (n_samples - n_classes)

        # 2) Within variance scaling
        X = np.sqrt(fac) * (Xc / std)
        # SVD of centered (within)scaled data
        U, S, V = linalg.svd(X, full_matrices=False)

        rank = np.sum(S > tol)
        if rank < n_features:
            warnings.warn("variables are collinear")
        # Scaling of within covariance is: V' 1/S
        scalings = (V[:rank] / std).T / S[:rank]

        # 3) Between variance scaling
        # Scale weighted centers
        X = np.dot(((np.sqrt((n_samples * self.priors_) * fac)) *
                    (self.means_ - self.xbar_).T).T, scalings)
        # Centers are living in a space with n_classes-1 dim (maximum)
        # Use SVD to find projection in the space spanned by the
        # (n_classes) centers
        _, S, V = linalg.svd(X, full_matrices=0)

        rank = np.sum(S > tol * S[0])
        self.scalings_ = np.dot(scalings, V.T[:, :rank])
        coef = np.dot(self.means_ - self.xbar_, self.scalings_)
        self.intercept_ = (-0.5 * np.sum(coef**2, axis=1)
                           + np.log(self.priors_))
        self.coef_ = np.dot(coef, self.scalings_.T)

    def fit(self, X, y):
        """
        Fit the LDA model according to the given training data and parameters.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]
            Training vector, where n_samples in the number of samples and
            n_features is the number of features.

        y : array, shape = [n_samples]
            Target values (integers)

        store_covariance : boolean
            If True the covariance matrix (shared by all classes) is computed
            and stored in `self.covariance_` attribute.

        tol : float
            Threshold used for rank estimation (for LDA implemented with SVD).
        """
        X, y = check_X_y(X, y)
        le = LabelEncoder()
        y = le.fit_transform(y)
        self.classes_ = unique_labels(y)
        n_samples, n_features = X.shape

        # TODO: support equal priors (should probably be the default)
        if self.priors is None:
            self.priors_ = np.bincount(y) / float(n_samples)
        else:
            self.priors_ = self.priors

        if self.alpha is None:
            self.alpha = 'empirical'

        if self.solver == 'svd':
            self._solve_svd(X, y, self.alpha)
        elif self.solver == 'lsqr':
            self._solve_lsqr(X, y, self.alpha)
        elif self.solver == 'eigen':
            self._solve_eigen(X, y, self.alpha)

    def _decision_function(self, X):
        X = check_array(X)
        return np.dot(X - self.xbar_, self.coef_.T) + self.intercept_

    def decision_function(self, X):
        """
        This function returns the decision function values related to each
        class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes] or [n_samples,]
            Decision function values related to each class, per sample.
            In the two-class case, the shape is [n_samples,], giving the
            log likelihood ratio of the positive class.
        """
        dec_func = self._decision_function(X)
        if len(self.classes_) == 2:
            return dec_func[:, 1] - dec_func[:, 0]
        return dec_func

    def transform(self, X):
        """
        Project the data so as to maximize class separation (large separation
        between projected class means and small variance within each class).

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        X_new : array, shape = [n_samples, n_components]
        """
        X = check_array(X)
        # center and scale data
        X_new = np.dot(X - self.xbar_, self.scalings_)
        n_components = X.shape[1] if self.n_components is None \
            else self.n_components
        return X_new[:, :n_components]

    def predict(self, X):
        """
        This function does classification on an array of test vectors X.

        The predicted class C for each sample in X is returned.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples]
        """
        d = self._decision_function(X)
        y_pred = self.classes_.take(d.argmax(1))
        return y_pred

    def predict_proba(self, X):
        """
        This function returns posterior probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        # compute the likelihood of the underlying gaussian models
        # up to a multiplicative constant.
        likelihood = np.exp(values - values.max(axis=1)[:, np.newaxis])
        # compute posterior probabilities
        return likelihood / likelihood.sum(axis=1)[:, np.newaxis]

    def predict_log_proba(self, X):
        """
        This function returns posterior log-probabilities of classification
        according to each class on an array of test vectors X.

        Parameters
        ----------
        X : array-like, shape = [n_samples, n_features]

        Returns
        -------
        C : array, shape = [n_samples, n_classes]
        """
        values = self._decision_function(X)
        loglikelihood = (values - values.max(axis=1)[:, np.newaxis])
        normalization = logsumexp(loglikelihood, axis=1)
        return loglikelihood - normalization[:, np.newaxis]
<|endoftext|>


<commit_before>from functools import wraps
from flask import Flask, request, redirect
from models import Memegen, Slack

app = Flask(__name__)

def ssl_required(fn):
    @wraps(fn)
    def decorated_view(*args, **kwargs):
        if not any([app.debug, request.is_secure, request.headers.get("X-Forwarded-Proto", "") == "https"]):
            return redirect(request.url.replace("http://", "https://"))
        else:
            return fn(*args, **kwargs)

    return decorated_view

@ssl_required
@app.route("/")
def meme():
    meme = Memegen()
    slack = Slack()

    token = request.args["token"]

    if token != slack.SLASH_COMMAND_TOKEN:
        return "Unauthorized."

    text = request.args["text"]

    if text[:9] == "templates":
        return meme.get_help()

    try:
        template, top, bottom = meme.parse_text_into_params(text)
    except:
        return "Your syntax should be in the form `/meme [template]; [top]; [bottom];. Type `/meme templates` to see valid templates."

    valid_templates = [x["name"] for x in meme.get_templates()]

    if template not in valid_templates:
        return "That template doesn't exist. Type `/meme templates` to see valid templates."

    meme_url = meme.build_url(template, top, bottom)
    channel_id = request.args["channel_id"]

    payload = {"text": meme_url, "channel": channel_id}

    user_id = request.args["user_id"]
    user = slack.find_user_info(user_id)

    payload.update(user)
    slack.post_meme_to_webhook(payload)

    return "Success!", 200<commit_msg>Memegen.parst_text_into_params isn't going to throw an exception.<commit_after>from functools import wraps
from flask import Flask, request, redirect
from models import Memegen, Slack

app = Flask(__name__)

def ssl_required(fn):
    @wraps(fn)
    def decorated_view(*args, **kwargs):
        if not any([app.debug, request.is_secure, request.headers.get("X-Forwarded-Proto", "") == "https"]):
            return redirect(request.url.replace("http://", "https://"))
        else:
            return fn(*args, **kwargs)

    return decorated_view

@ssl_required
@app.route("/")
def meme():
    meme = Memegen()
    slack = Slack()

    token = request.args["token"]

    if token != slack.SLASH_COMMAND_TOKEN:
        return "Unauthorized."

    text = request.args["text"]

    if text[:9] == "templates":
        return meme.get_help()

    template, top, bottom = meme.parse_text_into_params(text)

    valid_templates = [x["name"] for x in meme.get_templates()]

    if template not in valid_templates:
        return "That template doesn't exist. Type `/meme templates` to see valid templates."

    meme_url = meme.build_url(template, top, bottom)
    channel_id = request.args["channel_id"]

    payload = {"text": meme_url, "channel": channel_id}

    user_id = request.args["user_id"]
    user = slack.find_user_info(user_id)

    payload.update(user)
    slack.post_meme_to_webhook(payload)

    return "Success!", 200<|endoftext|>


<commit_before>from django.template import RequestContext
from django.template.loader import render_to_string
from django.http import *
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.core import serializers
from django.db.models import Q
from django.core.exceptions import *

from sleep.models import *
from sleep.forms import *

import datetime
import pytz

def home(request):
    return render(request, 'index.html')

def faq(request):
    return render(request, 'faq.html')

@login_required
def mysleep(request):
    return HttpResponse(render_to_string('sleep/mysleep.html',{},context_instance=RequestContext(request)))

@login_required
def editOrCreateSleep(request,sleep = None,success=False):
    context = {'success': success}
    prof = request.user.sleeperprofile
    defaulttz = prof.timezone
    if prof.use12HourTime:
        fmt = "%I:%M %p %x"
    else:
        fmt = "%H:%M %x"
    if sleep: # we're editing a sleep
        try:
            s = Sleep.objects.get(pk=sleep)
            if s.user != request.user:
                raise PermissionDenied
            context['sleep'] = s
        except Sleep.MultipleObjectsReturned:
            return HttpResponseBadRequest('')
        except Sleep.DoesNotExist:
            raise Http404
        if request.method == 'POST':
            form = SleepForm(request.user, fmt, request.POST, instance=s)
        else:
            initial = {
                    "start_time" : s.start_local_time().strftime(fmt),
                    "end_time" : s.end_local_time().strftime(fmt),
                    "date" : s.date.strftime("%x"),
                    }
            form = SleepForm(request.user, fmt, instance=s, initial=initial)
        context.update({"start": s.start_local_time().strftime(fmt), "end": s.end_local_time().strftime(fmt), "tz": s.timezone})
    else: # we're creating a new sleep
        if request.method == 'POST':
            form = SleepForm(request.user, fmt, request.POST, instance=Sleep(user=request.user))
        else:
            today = pytz.utc.localize(datetime.datetime.utcnow()).astimezone(pytz.timezone(defaulttz)).replace(hour=0,minute=0,second=0,microsecond=0)
            initial = {
                    "start_time" : today.strftime(fmt),
                    "end_time" : today.strftime(fmt),
                    "date" : today.date().strftime("%x"),
                    "timezone" : defaulttz,
                    }
            form = SleepForm(request.user, fmt, initial=initial)
    if request.method == 'POST':
        if form.is_valid():
            new = form.save(commit=False)
            if sleep == None:
                new.user = request.user
                new.save()
                form = SleepForm(request.user, fmt, instance=new)
                return HttpResponseRedirect('/sleep/simple/success/')
            else:
                new.save()
                return HttpResponseRedirect('/mysleep/')
    context['form']=form
    return HttpResponse(render_to_string('editsleep.html', context, context_instance=RequestContext(request)))

def leaderboard(request,sortBy='zScore'):
    if sortBy not in ['zScore','avg','avgSqrt','avgLog','avgRecip','stDev']:
        sortBy='zScore'
    ss = Sleeper.objects.sorted_sleepers(sortBy,request.user)
    top = [ s for s in ss if s['rank']<=10 or request.user.is_authenticated() and s['user'].pk==request.user.pk ]
    now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
    lastDayWinner = Sleeper.objects.bestByTime(now-datetime.timedelta(1),now,request.user)[0]
    context = {
            'top' : top,
            'lastDayWinner' : lastDayWinner,
            'total' : Sleep.objects.totalSleep(),
            'number' : Sleep.objects.all().values_list('user').distinct().count(),
            }
    return HttpResponse(render_to_string('leaderboard.html',context,context_instance=RequestContext(request)))

def creep(request,username=None, asOther=None):
    if not username:
        if request.user.is_anonymous():
            creepable=Sleeper.objects.filter(sleeperprofile__privacy__gte=SleeperProfile.PRIVACY_STATS)
            followed = []
        else:
            creepable=Sleeper.objects.filter(
                    Q(sleeperprofile__privacyLoggedIn__gte=SleeperProfile.PRIVACY_STATS) |
                    (
                        Q(sleeperprofile__privacyFriends__gte=SleeperProfile.PRIVACY_STATS) &
                        Q(sleeperprofile__friends=request.user)
                    )
                )
            followed = request.user.sleeperprofile.follows.order_by('username')
        total=creepable.distinct().count()
        if request.method == 'POST':
            form=CreepSearchForm(request.POST)
            if form.is_valid():
                users = creepable.filter(username__icontains=form.cleaned_data['username']).distinct()
                count = users.count()
                if count==1:
                    return HttpResponseRedirect('/creep/%s/' % users[0].username)
                else:
                    context = {
                            'results' : users,
                            'count' : count,
                            'form' : form,
                            'new' : False,
                            'total' : total,
                            'followed' : followed,
                            }
                    return HttpResponse(render_to_string('creepsearch.html',context,context_instance=RequestContext(request)))
        else:
            form = CreepSearchForm()
        context = {
                'form' : form,
                'new' : True,
                'total' : total,
                'followed' : followed,
                }
        return HttpResponse(render_to_string('creepsearch.html',context,context_instance=RequestContext(request)))
    else:
        context = {}
        try:
            user=Sleeper.objects.get(username=username)
            p = user.sleeperprofile
            if user.is_anonymous():
                priv = p.privacy
            elif request.user.pk == user.pk:
                priv = p.PRIVACY_PUBLIC
                context["isself"] =True
            elif request.user in p.friends.all():
                priv = p.privacyFriends
            else:
                priv = p.privacyLoggedIn
            if asOther:
                otherD = {"friends":p.privacyFriends, "user": p.privacyLoggedIn,"anon": p.privacy}
                if asOther in otherD: priv = min(priv, otherD[asOther])
            if priv<=p.PRIVACY_NORMAL:
                return HttpResponse(render_to_string('creepfailed.html',{},context_instance=RequestContext(request)))
        except:
            return HttpResponse(render_to_string('creepfailed.html',{},context_instance=RequestContext(request)))
        context.update({'user' : user,'global' : user.decayStats()})
        if priv>=p.PRIVACY_PUBLIC:
            context['sleeps']=user.sleep_set.all().order_by('-end_time')
        return HttpResponse(render_to_string('creep.html',context,context_instance=RequestContext(request)))

@login_required
def editProfile(request):
    p = request.user.sleeperprofile
    if request.method == 'POST':
        form = SleeperProfileForm(request.POST, instance=p)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/editprofile/')
    else:
        form = SleeperProfileForm(instance=p)

    return HttpResponse(render_to_string('editprofile.html', {'form': form},context_instance=RequestContext(request)))

@login_required
def friends(request):
    prof = request.user.sleeperprofile
    friendfollow = (prof.friends.all() | prof.follows.all()).distinct().order_by('username')
    requests = sleeper.requests.filter(friendrequest__accepted=None).order_by('user__username')
    if request.method == 'POST':
        form=FriendSearchForm(request.POST)
        if form.is_valid():
            users = User.objects.filter(username__icontains=form.cleaned_data['username']).exclude(pk=request.user.pk).distinct()
            count = users.count()
            context = {
                    'results' : users,
                    'count' : count,
                    'form' : form,
                    'new' : False,
                    'friendfollow' : friendfollow,
                    'requests' : requests,
                    }
            return HttpResponse(render_to_string('friends.html',context,context_instance=RequestContext(request)))
    else:
        form = FriendSearchForm()
    context = {
            'form' : form,
            'new' : True,
            'friendfollow' : friendfollow,
            'requests' : requests,
            }
    return HttpResponse(render_to_string('friends.html',context,context_instance=RequestContext(request)))

@login_required
def requestFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        them = Sleeper.objects.get(pk=i)
        if not FriendRequest.objects.filter(requestor=request.user.sleeperprofile,requestee=them):
            if request.user in them.sleeperprofile.friends.all():
                accept = True
            else:
                accept = None
            FriendRequest.objects.create(requestor=prof,requestee=them,accepted=accept)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def hideRequest(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        frs = FriendRequest.objects.filter(requestor__user__pk=i,requestee=request.user)
        for fr in frs:
            fr.accepted=False
            fr.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def addFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.friends.add(i)
        prof.save()
        frs = FriendRequest.objects.filter(requestor__user__pk=i,requestee=request.user)
        for fr in frs:
            fr.accepted=True
            fr.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def removeFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.friends.remove(i)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def follow(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.follows.add(i)
        prof.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def unfollow(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.follows.remove(i)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def createSleep(request):
    # Date-ify start, end, and center
    timezone = pytz.timezone(request.POST['timezone'])
    start = datetime.datetime(*(map(int, request.POST.getlist("start[]"))))
    start=timezone.localize(start)
    end = datetime.datetime(*(map(int, request.POST.getlist("end[]"))))
    end=timezone.localize(end)
    date = datetime.date(*(map(int, request.POST.getlist("date[]"))[:3]))
    # Pull out comments
    if "comments" in request.POST:
        comments = request.POST["comments"]
    else:
        comments = ""
    # Create the Sleep instance
    Sleep.objects.create(user=request.user, start_time=start, end_time=end, comments=comments, date=date,timezone=timezone)
    return HttpResponse('')

@login_required
def deleteSleep(request):
    if 'id' in request.POST:
        i = request.POST['id']
        s = Sleep.objects.filter(pk=i)
        if len(s) == 0:
            raise Http404
        s = s[0]
        if s.user != request.user:
            raise PermissionDenied
        s.delete()
        return HttpResponse('')
    return HttpResponseBadRequest('')

@login_required
def getSleepsJSON(request):
    u = request.user
    sleeps = list(Sleep.objects.filter(user=u))
    for sleep in sleeps:
        tz = pytz.timezone(sleep.timezone)
        #warning: the following is kind of hacky but it's better than dealing with the timezones in JS.  JS doesn't understand timezones, so we convert the timezone server-side, then pass it through to JS without telling the JS what timezone it's in.  JS interprets it as local time, which is slightly incorrect but works since all we want to do is get the hours/minutes/seconds back out as local time.
        sleep.start_time=sleep.start_time.astimezone(tz).replace(tzinfo=None)
        sleep.end_time=sleep.end_time.astimezone(tz).replace(tzinfo=None)
    data = serializers.serialize('json', sleeps)
    return HttpResponse(data, mimetype='application/json')
<commit_msg>Fix error in friends page.<commit_after>from django.template import RequestContext
from django.template.loader import render_to_string
from django.http import *
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.core import serializers
from django.db.models import Q
from django.core.exceptions import *

from sleep.models import *
from sleep.forms import *

import datetime
import pytz

def home(request):
    return render(request, 'index.html')

def faq(request):
    return render(request, 'faq.html')

@login_required
def mysleep(request):
    return HttpResponse(render_to_string('sleep/mysleep.html',{},context_instance=RequestContext(request)))

@login_required
def editOrCreateSleep(request,sleep = None,success=False):
    context = {'success': success}
    prof = request.user.sleeperprofile
    defaulttz = prof.timezone
    if prof.use12HourTime:
        fmt = "%I:%M %p %x"
    else:
        fmt = "%H:%M %x"
    if sleep: # we're editing a sleep
        try:
            s = Sleep.objects.get(pk=sleep)
            if s.user != request.user:
                raise PermissionDenied
            context['sleep'] = s
        except Sleep.MultipleObjectsReturned:
            return HttpResponseBadRequest('')
        except Sleep.DoesNotExist:
            raise Http404
        if request.method == 'POST':
            form = SleepForm(request.user, fmt, request.POST, instance=s)
        else:
            initial = {
                    "start_time" : s.start_local_time().strftime(fmt),
                    "end_time" : s.end_local_time().strftime(fmt),
                    "date" : s.date.strftime("%x"),
                    }
            form = SleepForm(request.user, fmt, instance=s, initial=initial)
        context.update({"start": s.start_local_time().strftime(fmt), "end": s.end_local_time().strftime(fmt), "tz": s.timezone})
    else: # we're creating a new sleep
        if request.method == 'POST':
            form = SleepForm(request.user, fmt, request.POST, instance=Sleep(user=request.user))
        else:
            today = pytz.utc.localize(datetime.datetime.utcnow()).astimezone(pytz.timezone(defaulttz)).replace(hour=0,minute=0,second=0,microsecond=0)
            initial = {
                    "start_time" : today.strftime(fmt),
                    "end_time" : today.strftime(fmt),
                    "date" : today.date().strftime("%x"),
                    "timezone" : defaulttz,
                    }
            form = SleepForm(request.user, fmt, initial=initial)
    if request.method == 'POST':
        if form.is_valid():
            new = form.save(commit=False)
            if sleep == None:
                new.user = request.user
                new.save()
                form = SleepForm(request.user, fmt, instance=new)
                return HttpResponseRedirect('/sleep/simple/success/')
            else:
                new.save()
                return HttpResponseRedirect('/mysleep/')
    context['form']=form
    return HttpResponse(render_to_string('editsleep.html', context, context_instance=RequestContext(request)))

def leaderboard(request,sortBy='zScore'):
    if sortBy not in ['zScore','avg','avgSqrt','avgLog','avgRecip','stDev']:
        sortBy='zScore'
    ss = Sleeper.objects.sorted_sleepers(sortBy,request.user)
    top = [ s for s in ss if s['rank']<=10 or request.user.is_authenticated() and s['user'].pk==request.user.pk ]
    now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
    lastDayWinner = Sleeper.objects.bestByTime(now-datetime.timedelta(1),now,request.user)[0]
    context = {
            'top' : top,
            'lastDayWinner' : lastDayWinner,
            'total' : Sleep.objects.totalSleep(),
            'number' : Sleep.objects.all().values_list('user').distinct().count(),
            }
    return HttpResponse(render_to_string('leaderboard.html',context,context_instance=RequestContext(request)))

def creep(request,username=None, asOther=None):
    if not username:
        if request.user.is_anonymous():
            creepable=Sleeper.objects.filter(sleeperprofile__privacy__gte=SleeperProfile.PRIVACY_STATS)
            followed = []
        else:
            creepable=Sleeper.objects.filter(
                    Q(sleeperprofile__privacyLoggedIn__gte=SleeperProfile.PRIVACY_STATS) |
                    (
                        Q(sleeperprofile__privacyFriends__gte=SleeperProfile.PRIVACY_STATS) &
                        Q(sleeperprofile__friends=request.user)
                    )
                )
            followed = request.user.sleeperprofile.follows.order_by('username')
        total=creepable.distinct().count()
        if request.method == 'POST':
            form=CreepSearchForm(request.POST)
            if form.is_valid():
                users = creepable.filter(username__icontains=form.cleaned_data['username']).distinct()
                count = users.count()
                if count==1:
                    return HttpResponseRedirect('/creep/%s/' % users[0].username)
                else:
                    context = {
                            'results' : users,
                            'count' : count,
                            'form' : form,
                            'new' : False,
                            'total' : total,
                            'followed' : followed,
                            }
                    return HttpResponse(render_to_string('creepsearch.html',context,context_instance=RequestContext(request)))
        else:
            form = CreepSearchForm()
        context = {
                'form' : form,
                'new' : True,
                'total' : total,
                'followed' : followed,
                }
        return HttpResponse(render_to_string('creepsearch.html',context,context_instance=RequestContext(request)))
    else:
        context = {}
        try:
            user=Sleeper.objects.get(username=username)
            p = user.sleeperprofile
            if user.is_anonymous():
                priv = p.privacy
            elif request.user.pk == user.pk:
                priv = p.PRIVACY_PUBLIC
                context["isself"] =True
            elif request.user in p.friends.all():
                priv = p.privacyFriends
            else:
                priv = p.privacyLoggedIn
            if asOther:
                otherD = {"friends":p.privacyFriends, "user": p.privacyLoggedIn,"anon": p.privacy}
                if asOther in otherD: priv = min(priv, otherD[asOther])
            if priv<=p.PRIVACY_NORMAL:
                return HttpResponse(render_to_string('creepfailed.html',{},context_instance=RequestContext(request)))
        except:
            return HttpResponse(render_to_string('creepfailed.html',{},context_instance=RequestContext(request)))
        context.update({'user' : user,'global' : user.decayStats()})
        if priv>=p.PRIVACY_PUBLIC:
            context['sleeps']=user.sleep_set.all().order_by('-end_time')
        return HttpResponse(render_to_string('creep.html',context,context_instance=RequestContext(request)))

@login_required
def editProfile(request):
    p = request.user.sleeperprofile
    if request.method == 'POST':
        form = SleeperProfileForm(request.POST, instance=p)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/editprofile/')
    else:
        form = SleeperProfileForm(instance=p)

    return HttpResponse(render_to_string('editprofile.html', {'form': form},context_instance=RequestContext(request)))

@login_required
def friends(request):
    prof = request.user.sleeperprofile
    friendfollow = (prof.friends.all() | prof.follows.all()).distinct().order_by('username')
    requests = request.user.requests.filter(friendrequest__accepted=None).order_by('user__username')
    if request.method == 'POST':
        form=FriendSearchForm(request.POST)
        if form.is_valid():
            users = User.objects.filter(username__icontains=form.cleaned_data['username']).exclude(pk=request.user.pk).distinct()
            count = users.count()
            context = {
                    'results' : users,
                    'count' : count,
                    'form' : form,
                    'new' : False,
                    'friendfollow' : friendfollow,
                    'requests' : requests,
                    }
            return HttpResponse(render_to_string('friends.html',context,context_instance=RequestContext(request)))
    else:
        form = FriendSearchForm()
    context = {
            'form' : form,
            'new' : True,
            'friendfollow' : friendfollow,
            'requests' : requests,
            }
    return HttpResponse(render_to_string('friends.html',context,context_instance=RequestContext(request)))

@login_required
def requestFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        them = Sleeper.objects.get(pk=i)
        if not FriendRequest.objects.filter(requestor=request.user.sleeperprofile,requestee=them):
            if request.user in them.sleeperprofile.friends.all():
                accept = True
            else:
                accept = None
            FriendRequest.objects.create(requestor=prof,requestee=them,accepted=accept)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def hideRequest(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        frs = FriendRequest.objects.filter(requestor__user__pk=i,requestee=request.user)
        for fr in frs:
            fr.accepted=False
            fr.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def addFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.friends.add(i)
        prof.save()
        frs = FriendRequest.objects.filter(requestor__user__pk=i,requestee=request.user)
        for fr in frs:
            fr.accepted=True
            fr.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def removeFriend(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.friends.remove(i)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def follow(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.follows.add(i)
        prof.save()
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def unfollow(request):
    if 'id' in request.POST:
        i = request.POST['id']
        if i==request.user.pk or len(User.objects.filter(pk=i))!=1:
            raise Http404
        prof = request.user.sleeperprofile
        prof.follows.remove(i)
        return HttpResponse('')
    else:
        return HttpResponseBadRequest('')

@login_required
def createSleep(request):
    # Date-ify start, end, and center
    timezone = pytz.timezone(request.POST['timezone'])
    start = datetime.datetime(*(map(int, request.POST.getlist("start[]"))))
    start=timezone.localize(start)
    end = datetime.datetime(*(map(int, request.POST.getlist("end[]"))))
    end=timezone.localize(end)
    date = datetime.date(*(map(int, request.POST.getlist("date[]"))[:3]))
    # Pull out comments
    if "comments" in request.POST:
        comments = request.POST["comments"]
    else:
        comments = ""
    # Create the Sleep instance
    Sleep.objects.create(user=request.user, start_time=start, end_time=end, comments=comments, date=date,timezone=timezone)
    return HttpResponse('')

@login_required
def deleteSleep(request):
    if 'id' in request.POST:
        i = request.POST['id']
        s = Sleep.objects.filter(pk=i)
        if len(s) == 0:
            raise Http404
        s = s[0]
        if s.user != request.user:
            raise PermissionDenied
        s.delete()
        return HttpResponse('')
    return HttpResponseBadRequest('')

@login_required
def getSleepsJSON(request):
    u = request.user
    sleeps = list(Sleep.objects.filter(user=u))
    for sleep in sleeps:
        tz = pytz.timezone(sleep.timezone)
        #warning: the following is kind of hacky but it's better than dealing with the timezones in JS.  JS doesn't understand timezones, so we convert the timezone server-side, then pass it through to JS without telling the JS what timezone it's in.  JS interprets it as local time, which is slightly incorrect but works since all we want to do is get the hours/minutes/seconds back out as local time.
        sleep.start_time=sleep.start_time.astimezone(tz).replace(tzinfo=None)
        sleep.end_time=sleep.end_time.astimezone(tz).replace(tzinfo=None)
    data = serializers.serialize('json', sleeps)
    return HttpResponse(data, mimetype='application/json')
<|endoftext|>