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

# import sys
import os

import logging
logger = logging.getLogger(__name__)

import sys
import os.path
import numpy as np
from io import open

path_to_script = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(path_to_script, "./extern/sPickle"))

from .dili_subset import ndarray_to_list_in_structure

def old_str_format_to_new(string):
    """
    convert old format style to new style. Works for digits only
    %05d is converted to {:05d}
    :param string:
    :return:
    """
    import re
    return re.sub(r"%(\d*d)", r"{:\1}", string)

def suggest_filename(file_path, exists=None):
    """
    Try if exist path and append number to its end.
    For debug you can set as input if file exists or not.
    """
    import os.path
    import re
    if not isinstance(exists, bool):
        exists = os.path.exists(file_path)

    if exists:
        file_path, file_extension = os.path.splitext(file_path)
        # print(file_path)
        m = re.search(r"\d+$", file_path)
        if m is None:
            # cislo = 2
            new_cislo_str = "2"
        else:
            cislostr = (m.group())
            cislo = int(cislostr) + 1
            file_path = file_path[:-len(cislostr)]
            new_cislo_str = str(cislo)

        file_path = file_path + new_cislo_str + file_extension  # .zfill(2)
        # trorcha rekurze
        file_path = suggest_filename(file_path)

    return file_path

def obj_from_file(filename='annotation.yaml', filetype='auto'):
    ''' Read object from file '''

    if filetype == 'auto':
        _, ext = os.path.splitext(filename)
        filetype = ext[1:]

    if filetype in ('yaml', 'yml'):
        from ruamel.yaml import YAML
        yaml = YAML(typ="unsafe")
        with open(filename, encoding="utf-8") as f:
            obj = yaml.load(f)
        if obj is None:
            obj = {}
        # import yaml
        # with open(filename, encoding="utf-8") as f:
        #     intext = f.read()
        #     obj = yaml.load(intext)
    elif filetype in ('pickle', 'pkl', 'pklz', 'picklezip'):
        fcontent = read_pkl_and_pklz(filename)
        # import pickle
        if sys.version_info[0] < 3:
            import cPickle as pickle
        else:
            import _pickle as pickle
        # import sPickle as pickle
        if sys.version_info.major == 2:
            obj = pickle.loads(fcontent)
        else:
            obj = pickle.loads(fcontent, encoding="latin1")
    else:
        logger.error('Unknown filetype ' + filetype)
    return obj

def read_pkl_and_pklz(filename):
    """
    Try read zipped or not zipped pickle file
    """
    fcontent = None
    try:
        import gzip
        f = gzip.open(filename, 'rb')
        fcontent = f.read()
        f.close()
    except IOError as e:
        # if the problem is in not gzip file
        logger.info("Input gzip exception: " + str(e))
        f = open(filename, 'rb')
        fcontent = f.read()
        f.close()
    except Exception as e:
        # other problem
        import traceback
        logger.error("Input gzip exception: " + str(e))
        logger.error(traceback.format_exc())

    return fcontent

def obj_to_file(obj, filename, filetype='auto', ndarray_to_list=False, squeeze=True):
    '''Writes annotation in file.

    :param filetype:
        auto
        yaml
        pkl, pickle
        pklz, picklezip
    :param ndarray_to_list: convert ndarrays in obj to lists
    :param squeeze: squeeze ndarray

    '''
    # import json
    # with open(filename, mode='w') as f:
    #    json.dump(annotation,f)
    if ndarray_to_list:
        obj = ndarray_to_list_in_structure(obj, squeeze=squeeze)

    # write to yaml
    d = os.path.dirname(os.path.abspath(filename))
    if not os.path.exists(d):
        os.makedirs(d)

    if filetype == 'auto':
        _, ext = os.path.splitext(filename)
        filetype = ext[1:]

    if filetype in ('yaml', 'yml'):
        # import yaml
        from ruamel.yaml import YAML
        yaml = YAML(typ="unsafe")
        with open(filename, 'wt', encoding="utf-8") as f:
            yaml.dump(obj, f)
        # if sys.version_info.major == 2:
        #     with open(filename, 'wb') as f:
        #         yaml.dump(obj, f, encoding="utf-8")
        # else:
        #     with open(filename, "w", encoding="utf-8") as f:
        #         yaml.dump(obj, f)
    elif filetype in ('pickle', 'pkl'):
        f = open(filename, 'wb')
        logger.info("filename " + filename)
        # if sys.version_info[0] < 3: import cPickle as pickle
        # else: import _pickle as pickle
        import pickle
        pickle.dump(obj, f, -1)
        f.close
    elif filetype in ('streamingpicklezip', 'spklz'):
        # this is not working :-(
        import gzip
        import sPickle as pickle
        f = gzip.open(filename, 'wb', compresslevel=1)
        # f = open(filename, 'wb')
        pickle.s_dump(obj, f)
        f.close
    elif filetype in ('picklezip', 'pklz'):
        import gzip
        if sys.version_info[0] < 3: import cPickle as pickle
        else: import _pickle as pickle
        f = gzip.open(filename, 'wb', compresslevel=1)
        # f = open(filename, 'wb')
        pickle.dump(obj, f)
        f.close
    elif filetype in('mat'):

        import scipy.io as sio
        sio.savemat(filename, obj)
    else:
        logger.error('Unknown filetype ' + filetype)

def resize_to_shape(data, shape, zoom=None, mode='nearest', order=0):
    """
    Function resize input data to specific shape.

    :param data: input 3d array-like data
    :param shape: shape of output data
    :param zoom: zoom is used for back compatibility
    :mode: default is 'nearest'
    """
    # @TODO remove old code in except part

    try:
        # rint 'pred vyjimkou'
        # aise Exception ('test without skimage')
        # rint 'za vyjimkou'
        import skimage
        import skimage.transform
# Now we need reshape  seeds and segmentation to original size

        segm_orig_scale = skimage.transform.resize(
            data, shape, order=0,
            preserve_range=True,
            mode="constant",
        )

        segmentation = segm_orig_scale
        logger.debug('resize to orig with skimage')
    except:
        import scipy
        import scipy.ndimage
        dtype = data.dtype
        if zoom is None:
            zoom = shape / np.asarray(data.shape).astype(np.double)

        segm_orig_scale = scipy.ndimage.zoom(
            data,
            1.0 / zoom,
            mode=mode,
            order=order
        ).astype(dtype)
        logger.debug('resize to orig with scipy.ndimage')

# @TODO odstranit hack pro oříznutí na stejnou velikost
# v podstatě je to vyřešeno, ale nechalo by se to dělat elegantněji v zoom
# tam je bohužel patrně bug
        # rint 'd3d ', self.data3d.shape
        # rint 's orig scale shape ', segm_orig_scale.shape
        shp = [
            np.min([segm_orig_scale.shape[0], shape[0]]),
            np.min([segm_orig_scale.shape[1], shape[1]]),
            np.min([segm_orig_scale.shape[2], shape[2]]),
        ]
        # elf.data3d = self.data3d[0:shp[0], 0:shp[1], 0:shp[2]]
        # mport ipdb; ipdb.set_trace() # BREAKPOINT

        segmentation = np.zeros(shape, dtype=dtype)
        segmentation[
            0:shp[0],
            0:shp[1],
            0:shp[2]] = segm_orig_scale[0:shp[0], 0:shp[1], 0:shp[2]]

        del segm_orig_scale
    return segmentation

def resize_to_mm(data3d, voxelsize_mm, new_voxelsize_mm, mode='nearest'):
    """
    Function can resize data3d or segmentation to specifed voxelsize_mm
    :new_voxelsize_mm: requested voxelsize. List of 3 numbers, also
        can be a string 'orig', 'orgi*2' and 'orgi*4'.

    :voxelsize_mm: size of voxel
    :mode: default is 'nearest'
    """
    import scipy
    import scipy.ndimage

    if np.all(new_voxelsize_mm == 'orig'):
        new_voxelsize_mm = np.array(voxelsize_mm)

    elif np.all(new_voxelsize_mm == 'orig*2'):
        new_voxelsize_mm = np.array(voxelsize_mm) * 2
    elif np.all(new_voxelsize_mm == 'orig*4'):
        new_voxelsize_mm = np.array(voxelsize_mm) * 4
        # vx_size = np.array(metadata['voxelsize_mm']) * 4

    zoom = voxelsize_mm / (1.0 * np.array(new_voxelsize_mm))
    data3d_res = scipy.ndimage.zoom(
        data3d,
        zoom,
        mode=mode,
        order=1
    ).astype(data3d.dtype)
    return data3d_res

def suits_with_dtype(mn, mx, dtype):
    """
    Check whether range of values can be stored into defined data type.
    :param mn: range minimum
    :param mx: range maximum
    :param dtype:
    :return:
    """
    type_info = np.iinfo(dtype)
    if mx <= type_info.max and mn >= type_info.min:
        return True
    else:
        return False

def use_economic_dtype(data3d, slope=1, inter=0, dtype=None):
    """ Use more economic integer-like dtype if it is possible.

    :param data3d:
    :param dtype: if dtype is not used, the automatic is used
    :return:
    """

    if dtype is None:
        dtype = data3d.dtype
        if issubclass(dtype.type, np.integer):
            mn = data3d.min() * slope + inter
            mx = data3d.max() * slope + inter
            if suits_with_dtype(mn, mx, dtype=np.uint8):
                dtype = np.uint8
            elif suits_with_dtype(mn, mx, dtype=np.int8):
                dtype = np.int8
            elif suits_with_dtype(mn, mx, dtype=np.uint16):
                dtype = np.uint16
            elif suits_with_dtype(mn, mx, dtype=np.int16):
                dtype = np.int16
            elif suits_with_dtype(mn, mx, dtype=np.uint32):
                dtype = np.uint32
            elif suits_with_dtype(mn, mx, dtype=np.int32):
                dtype = np.int32

    # new_data3d = ((np.float(slope) * data3d) + np.float(inter)).astype(dtype)
    if slope == 1 and inter == 0:
        # this can prevent out of memmory
        new_data3d = data3d.astype(dtype)
    else:
        new_data3d = ((slope * data3d) + inter).astype(dtype)
    return new_data3d

<commit_msg>fix warning elementwise comparison failed<commit_after>#! /usr/bin/env python
# -*- coding: utf-8 -*-

# import sys
import os

import logging
logger = logging.getLogger(__name__)

import sys
import os.path
import numpy as np
from io import open

path_to_script = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(path_to_script, "./extern/sPickle"))

from .dili_subset import ndarray_to_list_in_structure

def old_str_format_to_new(string):
    """
    convert old format style to new style. Works for digits only
    %05d is converted to {:05d}
    :param string:
    :return:
    """
    import re
    return re.sub(r"%(\d*d)", r"{:\1}", string)

def suggest_filename(file_path, exists=None):
    """
    Try if exist path and append number to its end.
    For debug you can set as input if file exists or not.
    """
    import os.path
    import re
    if not isinstance(exists, bool):
        exists = os.path.exists(file_path)

    if exists:
        file_path, file_extension = os.path.splitext(file_path)
        # print(file_path)
        m = re.search(r"\d+$", file_path)
        if m is None:
            # cislo = 2
            new_cislo_str = "2"
        else:
            cislostr = (m.group())
            cislo = int(cislostr) + 1
            file_path = file_path[:-len(cislostr)]
            new_cislo_str = str(cislo)

        file_path = file_path + new_cislo_str + file_extension  # .zfill(2)
        # trorcha rekurze
        file_path = suggest_filename(file_path)

    return file_path

def obj_from_file(filename='annotation.yaml', filetype='auto'):
    ''' Read object from file '''

    if filetype == 'auto':
        _, ext = os.path.splitext(filename)
        filetype = ext[1:]

    if filetype in ('yaml', 'yml'):
        from ruamel.yaml import YAML
        yaml = YAML(typ="unsafe")
        with open(filename, encoding="utf-8") as f:
            obj = yaml.load(f)
        if obj is None:
            obj = {}
        # import yaml
        # with open(filename, encoding="utf-8") as f:
        #     intext = f.read()
        #     obj = yaml.load(intext)
    elif filetype in ('pickle', 'pkl', 'pklz', 'picklezip'):
        fcontent = read_pkl_and_pklz(filename)
        # import pickle
        if sys.version_info[0] < 3:
            import cPickle as pickle
        else:
            import _pickle as pickle
        # import sPickle as pickle
        if sys.version_info.major == 2:
            obj = pickle.loads(fcontent)
        else:
            obj = pickle.loads(fcontent, encoding="latin1")
    else:
        logger.error('Unknown filetype ' + filetype)
    return obj

def read_pkl_and_pklz(filename):
    """
    Try read zipped or not zipped pickle file
    """
    fcontent = None
    try:
        import gzip
        f = gzip.open(filename, 'rb')
        fcontent = f.read()
        f.close()
    except IOError as e:
        # if the problem is in not gzip file
        logger.info("Input gzip exception: " + str(e))
        f = open(filename, 'rb')
        fcontent = f.read()
        f.close()
    except Exception as e:
        # other problem
        import traceback
        logger.error("Input gzip exception: " + str(e))
        logger.error(traceback.format_exc())

    return fcontent

def obj_to_file(obj, filename, filetype='auto', ndarray_to_list=False, squeeze=True):
    '''Writes annotation in file.

    :param filetype:
        auto
        yaml
        pkl, pickle
        pklz, picklezip
    :param ndarray_to_list: convert ndarrays in obj to lists
    :param squeeze: squeeze ndarray

    '''
    # import json
    # with open(filename, mode='w') as f:
    #    json.dump(annotation,f)
    if ndarray_to_list:
        obj = ndarray_to_list_in_structure(obj, squeeze=squeeze)

    # write to yaml
    d = os.path.dirname(os.path.abspath(filename))
    if not os.path.exists(d):
        os.makedirs(d)

    if filetype == 'auto':
        _, ext = os.path.splitext(filename)
        filetype = ext[1:]

    if filetype in ('yaml', 'yml'):
        # import yaml
        from ruamel.yaml import YAML
        yaml = YAML(typ="unsafe")
        with open(filename, 'wt', encoding="utf-8") as f:
            yaml.dump(obj, f)
        # if sys.version_info.major == 2:
        #     with open(filename, 'wb') as f:
        #         yaml.dump(obj, f, encoding="utf-8")
        # else:
        #     with open(filename, "w", encoding="utf-8") as f:
        #         yaml.dump(obj, f)
    elif filetype in ('pickle', 'pkl'):
        f = open(filename, 'wb')
        logger.info("filename " + filename)
        # if sys.version_info[0] < 3: import cPickle as pickle
        # else: import _pickle as pickle
        import pickle
        pickle.dump(obj, f, -1)
        f.close
    elif filetype in ('streamingpicklezip', 'spklz'):
        # this is not working :-(
        import gzip
        import sPickle as pickle
        f = gzip.open(filename, 'wb', compresslevel=1)
        # f = open(filename, 'wb')
        pickle.s_dump(obj, f)
        f.close
    elif filetype in ('picklezip', 'pklz'):
        import gzip
        if sys.version_info[0] < 3: import cPickle as pickle
        else: import _pickle as pickle
        f = gzip.open(filename, 'wb', compresslevel=1)
        # f = open(filename, 'wb')
        pickle.dump(obj, f)
        f.close
    elif filetype in('mat'):

        import scipy.io as sio
        sio.savemat(filename, obj)
    else:
        logger.error('Unknown filetype ' + filetype)

def resize_to_shape(data, shape, zoom=None, mode='nearest', order=0):
    """
    Function resize input data to specific shape.

    :param data: input 3d array-like data
    :param shape: shape of output data
    :param zoom: zoom is used for back compatibility
    :mode: default is 'nearest'
    """
    # @TODO remove old code in except part

    try:
        # rint 'pred vyjimkou'
        # aise Exception ('test without skimage')
        # rint 'za vyjimkou'
        import skimage
        import skimage.transform
# Now we need reshape  seeds and segmentation to original size

        segm_orig_scale = skimage.transform.resize(
            data, shape, order=0,
            preserve_range=True,
            mode="constant",
        )

        segmentation = segm_orig_scale
        logger.debug('resize to orig with skimage')
    except:
        import scipy
        import scipy.ndimage
        dtype = data.dtype
        if zoom is None:
            zoom = shape / np.asarray(data.shape).astype(np.double)

        segm_orig_scale = scipy.ndimage.zoom(
            data,
            1.0 / zoom,
            mode=mode,
            order=order
        ).astype(dtype)
        logger.debug('resize to orig with scipy.ndimage')

# @TODO odstranit hack pro oříznutí na stejnou velikost
# v podstatě je to vyřešeno, ale nechalo by se to dělat elegantněji v zoom
# tam je bohužel patrně bug
        # rint 'd3d ', self.data3d.shape
        # rint 's orig scale shape ', segm_orig_scale.shape
        shp = [
            np.min([segm_orig_scale.shape[0], shape[0]]),
            np.min([segm_orig_scale.shape[1], shape[1]]),
            np.min([segm_orig_scale.shape[2], shape[2]]),
        ]
        # elf.data3d = self.data3d[0:shp[0], 0:shp[1], 0:shp[2]]
        # mport ipdb; ipdb.set_trace() # BREAKPOINT

        segmentation = np.zeros(shape, dtype=dtype)
        segmentation[
            0:shp[0],
            0:shp[1],
            0:shp[2]] = segm_orig_scale[0:shp[0], 0:shp[1], 0:shp[2]]

        del segm_orig_scale
    return segmentation

def resize_to_mm(data3d, voxelsize_mm, new_voxelsize_mm, mode='nearest'):
    """
    Function can resize data3d or segmentation to specifed voxelsize_mm
    :new_voxelsize_mm: requested voxelsize. List of 3 numbers, also
        can be a string 'orig', 'orgi*2' and 'orgi*4'.

    :voxelsize_mm: size of voxel
    :mode: default is 'nearest'
    """
    import scipy
    import scipy.ndimage

    if np.all(list(new_voxelsize_mm) == 'orig'):
        new_voxelsize_mm = np.array(voxelsize_mm)
    elif np.all(list(new_voxelsize_mm) == 'orig*2'):
        new_voxelsize_mm = np.array(voxelsize_mm) * 2
    elif np.all(list(new_voxelsize_mm) == 'orig*4'):
        new_voxelsize_mm = np.array(voxelsize_mm) * 4
        # vx_size = np.array(metadata['voxelsize_mm']) * 4

    zoom = voxelsize_mm / (1.0 * np.array(new_voxelsize_mm))
    data3d_res = scipy.ndimage.zoom(
        data3d,
        zoom,
        mode=mode,
        order=1
    ).astype(data3d.dtype)
    return data3d_res

def suits_with_dtype(mn, mx, dtype):
    """
    Check whether range of values can be stored into defined data type.
    :param mn: range minimum
    :param mx: range maximum
    :param dtype:
    :return:
    """
    type_info = np.iinfo(dtype)
    if mx <= type_info.max and mn >= type_info.min:
        return True
    else:
        return False

def use_economic_dtype(data3d, slope=1, inter=0, dtype=None):
    """ Use more economic integer-like dtype if it is possible.

    :param data3d:
    :param dtype: if dtype is not used, the automatic is used
    :return:
    """

    if dtype is None:
        dtype = data3d.dtype
        if issubclass(dtype.type, np.integer):
            mn = data3d.min() * slope + inter
            mx = data3d.max() * slope + inter
            if suits_with_dtype(mn, mx, dtype=np.uint8):
                dtype = np.uint8
            elif suits_with_dtype(mn, mx, dtype=np.int8):
                dtype = np.int8
            elif suits_with_dtype(mn, mx, dtype=np.uint16):
                dtype = np.uint16
            elif suits_with_dtype(mn, mx, dtype=np.int16):
                dtype = np.int16
            elif suits_with_dtype(mn, mx, dtype=np.uint32):
                dtype = np.uint32
            elif suits_with_dtype(mn, mx, dtype=np.int32):
                dtype = np.int32

    # new_data3d = ((np.float(slope) * data3d) + np.float(inter)).astype(dtype)
    if slope == 1 and inter == 0:
        # this can prevent out of memmory
        new_data3d = data3d.astype(dtype)
    else:
        new_data3d = ((slope * data3d) + inter).astype(dtype)
    return new_data3d

<|endoftext|>


<commit_before>#!/usr/bin/env python
from unittest import TestCase

from wtforms import Form, TextField
from wtforms.validators import ValidationError

class DummyPostData(dict):
    def getlist(self, key):
        return self[key]

class FormMetaTest(TestCase):
    def test_monkeypatch(self):
        class F(Form):
            a = TextField()

        self.assertEqual(F._unbound_fields, None)
        F()
        self.assertEqual(F._unbound_fields, [('a', F.a)])
        F.b = TextField()
        self.assertEqual(F._unbound_fields, None)
        F()
        self.assertEqual(F._unbound_fields, [('a', F.a), ('b', F.b)])
        del F.a
        self.assertRaises(AttributeError, lambda: F.a)
        F()
        self.assertEqual(F._unbound_fields, [('b', F.b)])
        F._m = TextField()
        self.assertEqual(F._unbound_fields, [('b', F.b)])

    def test_subclassing(self):
        class A(Form):
            a = TextField()
            c = TextField()
        class B(A):
            b = TextField()
            c = TextField()
        A(); B()
        self.assert_(A.a is B.a)
        self.assert_(A.c is not B.c)
        self.assertEqual(A._unbound_fields, [('a', A.a), ('c', A.c)])
        self.assertEqual(B._unbound_fields, [('a', B.a), ('b', B.b), ('c', B.c)])

class FormTest(TestCase):
    class F(Form):
        test = TextField()
        def validate_test(form, field):
            if field.data != 'foobar':
                raise ValidationError('error')

    def test_validate(self):
        form = self.F(test='foobar')
        self.assertEqual(form.validate(), True)

        form = self.F()
        self.assertEqual(form.validate(), False)

    def test_data_proxy(self):
        form = self.F(test='foo')
        self.assertEqual(form.data, {'test': 'foo'})

    def test_errors_proxy(self):
        form = self.F(test='foobar')
        form.validate()
        self.assertEqual(form.errors, {})

        form = self.F()
        form.validate()
        self.assertEqual(form.errors, {'test': ['error']})

    def test_contains(self):
        form = self.F()
        self.assert_('test' in form)
        self.assert_('abcd' not in form)

    def test_field_removal(self):
        form = self.F()
        del form.test
        self.assert_('test' not in form)
        self.assertEqual(form.test, None)

    def test_populate_obj(self):
        m = type('Model', (object, ), {})
        self.F(test='foobar').populate_obj(m)
        self.assertEqual(m.test, 'foobar')
        self.assertEqual([k for k in dir(m) if not k.startswith('_')], ['test'])

    def test_ordered_fields(self):
        class MyForm(Form):
            strawberry = TextField()
            banana     = TextField()
            kiwi       = TextField()

        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'banana', 'kiwi'])
        MyForm.apple = TextField()
        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'banana', 'kiwi', 'apple'])
        del MyForm.banana
        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'kiwi', 'apple'])
        MyForm.strawberry = TextField()
        self.assertEqual([x.name for x in MyForm()], ['kiwi', 'apple', 'strawberry'])
        # Ensure sort is stable: two fields with the same creation counter
        # should be subsequently sorted by name.
        MyForm.cherry = MyForm.kiwi
        self.assertEqual([x.name for x in MyForm()], ['cherry', 'kiwi', 'apple', 'strawberry'])

    def test_prefixes(self):
        self.assertEqual(self.F(prefix='foo').test.name, 'foo-test')
        self.assertEqual(self.F(prefix='foo').test.id, 'foo-test')
        form = self.F(DummyPostData({'foo-test': [u'hello'], 'test': [u'bye']}), prefix='foo')
        self.assertEqual(form.test.data, u'hello')

if __name__ == '__main__':
    from unittest import main
    main()
<commit_msg>Added tests for BaseForm<commit_after>#!/usr/bin/env python
from unittest import TestCase

from wtforms.form import BaseForm, Form
from wtforms.fields import TextField
from wtforms.validators import ValidationError

class DummyPostData(dict):
    def getlist(self, key):
        return self[key]

class BaseFormTest(TestCase):
    def get_form(self, **kwargs):
        def validate_test(form, field):
            if field.data != 'foobar':
                raise ValidationError('error')

        return BaseForm({'test': TextField(validators=[validate_test])}, **kwargs)

    def test_data_proxy(self):
        form = self.get_form()
        form.process(test='foo')
        self.assertEqual(form.data, {'test': 'foo'})

    def test_errors_proxy(self):
        form = self.get_form()
        form.process(test='foobar')
        form.validate()
        self.assertEqual(form.errors, {})

        form = self.get_form()
        form.process()
        form.validate()
        self.assertEqual(form.errors, {'test': ['error']})

    def test_contains(self):
        form = self.get_form()
        self.assert_('test' in form)
        self.assert_('abcd' not in form)

    def test_field_removal(self):
        form = self.get_form()
        del form.test
        self.assert_('test' not in form)
        self.assertRaises(AttributeError, getattr, form, 'test')
        form = self.get_form()
        del form['test']
        self.assert_('test' not in form)

    def test_populate_obj(self):
        m = type('Model', (object, ), {})
        form = self.get_form()
        form.process(test='foobar')
        form.populate_obj(m)
        self.assertEqual(m.test, 'foobar')
        self.assertEqual([k for k in dir(m) if not k.startswith('_')], ['test'])

    def test_prefixes(self):
        self.assertEqual(self.get_form(prefix='foo').test.name, 'foo-test')
        self.assertEqual(self.get_form(prefix='foo').test.id, 'foo-test')
        form = self.get_form(prefix='foo')
        form.process(DummyPostData({'foo-test': [u'hello'], 'test': [u'bye']}))
        self.assertEqual(form.test.data, u'hello')

class FormMetaTest(TestCase):
    def test_monkeypatch(self):
        class F(Form):
            a = TextField()

        self.assertEqual(F._unbound_fields, None)
        F()
        self.assertEqual(F._unbound_fields, [('a', F.a)])
        F.b = TextField()
        self.assertEqual(F._unbound_fields, None)
        F()
        self.assertEqual(F._unbound_fields, [('a', F.a), ('b', F.b)])
        del F.a
        self.assertRaises(AttributeError, lambda: F.a)
        F()
        self.assertEqual(F._unbound_fields, [('b', F.b)])
        F._m = TextField()
        self.assertEqual(F._unbound_fields, [('b', F.b)])

    def test_subclassing(self):
        class A(Form):
            a = TextField()
            c = TextField()
        class B(A):
            b = TextField()
            c = TextField()
        A(); B()
        self.assert_(A.a is B.a)
        self.assert_(A.c is not B.c)
        self.assertEqual(A._unbound_fields, [('a', A.a), ('c', A.c)])
        self.assertEqual(B._unbound_fields, [('a', B.a), ('b', B.b), ('c', B.c)])

class FormTest(TestCase):
    class F(Form):
        test = TextField()
        def validate_test(form, field):
            if field.data != 'foobar':
                raise ValidationError('error')

    def test_validate(self):
        form = self.F(test='foobar')
        self.assertEqual(form.validate(), True)

        form = self.F()
        self.assertEqual(form.validate(), False)

    def test_field_removal(self):
        form = self.F()
        del form.test
        self.assert_('test' not in form)
        self.assertEqual(form.test, None)

    def test_ordered_fields(self):
        class MyForm(Form):
            strawberry = TextField()
            banana     = TextField()
            kiwi       = TextField()

        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'banana', 'kiwi'])
        MyForm.apple = TextField()
        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'banana', 'kiwi', 'apple'])
        del MyForm.banana
        self.assertEqual([x.name for x in MyForm()], ['strawberry', 'kiwi', 'apple'])
        MyForm.strawberry = TextField()
        self.assertEqual([x.name for x in MyForm()], ['kiwi', 'apple', 'strawberry'])
        # Ensure sort is stable: two fields with the same creation counter
        # should be subsequently sorted by name.
        MyForm.cherry = MyForm.kiwi
        self.assertEqual([x.name for x in MyForm()], ['cherry', 'kiwi', 'apple', 'strawberry'])

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


<commit_before>
from collections import defaultdict

from django.contrib.auth.decorators import login_required
from django.contrib.messages import info
from django.core.urlresolvers import get_callable, reverse
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.template import RequestContext
from django.template.defaultfilters import slugify
from django.template.loader import get_template
from django.utils import simplejson
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache

from mezzanine.conf import settings
from mezzanine.utils.importing import import_dotted_path
from mezzanine.utils.views import render, set_cookie, paginate

from cartridge.shop import checkout
from cartridge.shop.forms import AddProductForm, DiscountForm, CartItemFormSet
from cartridge.shop.models import Product, ProductVariation, Order, OrderItem
from cartridge.shop.models import DiscountCode
from cartridge.shop.utils import recalculate_discount, sign

# Set up checkout handlers.
handler = lambda s: import_dotted_path(s) if s else lambda *args: None
billship_handler = handler(settings.SHOP_HANDLER_BILLING_SHIPPING)
tax_handler = handler(settings.SHOP_HANDLER_TAX)
payment_handler = handler(settings.SHOP_HANDLER_PAYMENT)
order_handler = handler(settings.SHOP_HANDLER_ORDER)

def product(request, slug, template="shop/product.html"):
    """
    Display a product - convert the product variations to JSON as well as
    handling adding the product to either the cart or the wishlist.
    """
    published_products = Product.objects.published(for_user=request.user)
    product = get_object_or_404(published_products, slug=slug)
    fields = [f.name for f in ProductVariation.option_fields()]
    variations = product.variations.all()
    variations_json = simplejson.dumps([dict([(f, getattr(v, f))
                                        for f in fields + ["sku", "image_id"]])
                                        for v in variations])
    to_cart = (request.method == "POST" and
               request.POST.get("add_wishlist") is None)
    initial_data = {}
    if variations:
        initial_data = dict([(f, getattr(variations[0], f)) for f in fields])
    initial_data["quantity"] = 1
    add_product_form = AddProductForm(request.POST or None, product=product,
                                      initial=initial_data, to_cart=to_cart)
    if request.method == "POST":
        if add_product_form.is_valid():
            if to_cart:
                quantity = add_product_form.cleaned_data["quantity"]
                request.cart.add_item(add_product_form.variation, quantity)
                recalculate_discount(request)
                info(request, _("Item added to cart"))
                return redirect("shop_cart")
            else:
                skus = request.wishlist
                sku = add_product_form.variation.sku
                if sku not in skus:
                    skus.append(sku)
                info(request, _("Item added to wishlist"))
                response = redirect("shop_wishlist")
                set_cookie(response, "wishlist", ",".join(skus))
                return response
    context = {
        "product": product,
        "editable_obj": product,
        "images": product.images.all(),
        "variations": variations,
        "variations_json": variations_json,
        "has_available_variations": any([v.has_price() for v in variations]),
        "related_products": product.related_products.published(
                                                      for_user=request.user),
        "add_product_form": add_product_form
    }
    return render(request, template, context)

@never_cache
def wishlist(request, template="shop/wishlist.html"):
    """
    Display the wishlist and handle removing items from the wishlist and
    adding them to the cart.
    """

    skus = request.wishlist
    error = None
    if request.method == "POST":
        to_cart = request.POST.get("add_cart")
        add_product_form = AddProductForm(request.POST or None,
                                          to_cart=to_cart)
        if to_cart:
            if add_product_form.is_valid():
                request.cart.add_item(add_product_form.variation, 1)
                recalculate_discount(request)
                message = _("Item added to cart")
                url = "shop_cart"
            else:
                error = add_product_form.errors.values()[0]
        else:
            message = _("Item removed from wishlist")
            url = "shop_wishlist"
        sku = request.POST.get("sku")
        if sku in skus:
            skus.remove(sku)
        if not error:
            info(request, message)
            response = redirect(url)
            set_cookie(response, "wishlist", ",".join(skus))
            return response

    # Remove skus from the cookie that no longer exist.
    published_products = Product.objects.published(for_user=request.user)
    f = {"product__in": published_products, "sku__in": skus}
    wishlist = ProductVariation.objects.filter(**f).select_related(depth=1)
    wishlist = sorted(wishlist, key=lambda v: skus.index(v.sku))
    context = {"wishlist_items": wishlist, "error": error}
    response = render(request, template, context)
    if len(wishlist) < len(skus):
        skus = [variation.sku for variation in wishlist]
        set_cookie(response, "wishlist", ",".join(skus))
    return response

@never_cache
def cart(request, template="shop/cart.html"):
    """
    Display cart and handle removing items from the cart.
    """
    cart_formset = CartItemFormSet(instance=request.cart)
    discount_form = DiscountForm(request, request.POST or None)
    if request.method == "POST":
        valid = True
        if request.POST.get("update_cart"):
            valid = request.cart.has_items()
            if not valid:
                # Session timed out.
                info(request, _("Your cart has expired"))
            else:
                cart_formset = CartItemFormSet(request.POST,
                                               instance=request.cart)
                valid = cart_formset.is_valid()
                if valid:
                    cart_formset.save()
                    recalculate_discount(request)
                    info(request, _("Cart updated"))
        else:
            valid = discount_form.is_valid()
            if valid:
                discount_form.set_discount()
        if valid:
            return redirect("shop_cart")
    context = {"cart_formset": cart_formset}
    settings.use_editable()
    if (settings.SHOP_DISCOUNT_FIELD_IN_CART and
        DiscountCode.objects.active().count() > 0):
        context["discount_form"] = discount_form
    return render(request, template, context)

@never_cache
def checkout_steps(request):
    """
    Display the order form and handle processing of each step.
    """

    # Do the authentication check here rather than using standard
    # login_required decorator. This means we can check for a custom
    # LOGIN_URL and fall back to our own login view.
    authenticated = request.user.is_authenticated()
    if settings.SHOP_CHECKOUT_ACCOUNT_REQUIRED and not authenticated:
        url = "%s?next=%s" % (settings.LOGIN_URL, reverse("shop_checkout"))
        return redirect(url)

    # Determine the Form class to use during the checkout process
    form_class = get_callable(settings.SHOP_CHECKOUT_FORM_CLASS)

    initial = checkout.initial_order_data(request, form_class)
    step = int(request.POST.get("step", None)
               or initial.get("step", None)
               or checkout.CHECKOUT_STEP_FIRST)
    form = form_class(request, step, initial=initial)
    data = request.POST
    checkout_errors = []

    if request.POST.get("back") is not None:
        # Back button in the form was pressed - load the order form
        # for the previous step and maintain the field values entered.
        step -= 1
        form = form_class(request, step, initial=initial)
    elif request.method == "POST" and request.cart.has_items():
        form = form_class(request, step, initial=initial, data=data)
        if form.is_valid():
            # Copy the current form fields to the session so that
            # they're maintained if the customer leaves the checkout
            # process, but remove sensitive fields from the session
            # such as the credit card fields so that they're never
            # stored anywhere.
            request.session["order"] = dict(form.cleaned_data)
            sensitive_card_fields = ("card_number", "card_expiry_month",
                                     "card_expiry_year", "card_ccv")
            for field in sensitive_card_fields:
                if field in request.session["order"]:
                    del request.session["order"][field]

            # FIRST CHECKOUT STEP - handle shipping and discount code.
            if step == checkout.CHECKOUT_STEP_FIRST:
                try:
                    billship_handler(request, form)
                    tax_handler(request, form)
                except checkout.CheckoutError, e:
                    checkout_errors.append(e)
                form.set_discount()

            # FINAL CHECKOUT STEP - handle payment and process order.
            if step == checkout.CHECKOUT_STEP_LAST and not checkout_errors:
                # Create and save the inital order object so that
                # the payment handler has access to all of the order
                # fields. If there is a payment error then delete the
                # order, otherwise remove the cart items from stock
                # and send the order reciept email.
                order = form.save(commit=False)
                order.setup(request)
                # Try payment.
                try:
                    transaction_id = payment_handler(request, form, order)
                except checkout.CheckoutError, e:
                    # Error in payment handler.
                    order.delete()
                    checkout_errors.append(e)
                    if settings.SHOP_CHECKOUT_STEPS_CONFIRMATION:
                        step -= 1
                else:
                    # Finalize order - ``order.complete()`` performs
                    # final cleanup of session and cart.
                    # ``order_handler()`` can be defined by the
                    # developer to implement custom order processing.
                    # Then send the order email to the customer.
                    order.transaction_id = transaction_id
                    order.complete(request)
                    order_handler(request, form, order)
                    checkout.send_order_email(request, order)
                    # Set the cookie for remembering address details
                    # if the "remember" checkbox was checked.
                    response = redirect("shop_complete")
                    if form.cleaned_data.get("remember") is not None:
                        remembered = "%s:%s" % (sign(order.key), order.key)
                        set_cookie(response, "remember", remembered,
                                   secure=request.is_secure())
                    else:
                        response.delete_cookie("remember")
                    return response

            # If any checkout errors, assign them to a new form and
            # re-run is_valid. If valid, then set form to the next step.
            form = form_class(request, step, initial=initial, data=data,
                             errors=checkout_errors)
            if form.is_valid():
                step += 1
                form = form_class(request, step, initial=initial)

    # Update the step so that we don't rely on POST data to take us back to
    # the same point in the checkout process.
    request.session["order"]["step"] = step

    step_vars = checkout.CHECKOUT_STEPS[step - 1]
    template = "shop/%s.html" % step_vars["template"]
    CHECKOUT_STEP_FIRST = step == checkout.CHECKOUT_STEP_FIRST
    context = {"form": form, "CHECKOUT_STEP_FIRST": CHECKOUT_STEP_FIRST,
               "step_title": step_vars["title"], "step_url": step_vars["url"],
               "steps": checkout.CHECKOUT_STEPS, "step": step}
    return render(request, template, context)

@never_cache
def complete(request, template="shop/complete.html"):
    """
    Redirected to once an order is complete - pass the order object
    for tracking items via Google Anayltics, and displaying in
    the template if required.
    """
    try:
        order = Order.objects.from_request(request)
    except Order.DoesNotExist:
        raise Http404
    items = order.items.all()
    # Assign product names to each of the items since they're not
    # stored.
    skus = [item.sku for item in items]
    variations = ProductVariation.objects.filter(sku__in=skus)
    names = {}
    for variation in variations.select_related(depth=1):
        names[variation.sku] = variation.product.title
    for i, item in enumerate(items):
        setattr(items[i], "name", names[item.sku])
    context = {"order": order, "items": items,
               "steps": checkout.CHECKOUT_STEPS}
    return render(request, template, context)

def invoice(request, order_id, template="shop/order_invoice.html"):
    """
    Display a plain text invoice for the given order. The order must
    belong to the user which is checked via session or ID if
    authenticated, or if the current user is staff.
    """
    lookup = {"id": order_id}
    if not request.user.is_authenticated():
        lookup["key"] = request.session.session_key
    elif not request.user.is_staff:
        lookup["user_id"] = request.user.id
    order = get_object_or_404(Order, **lookup)
    context = {"order": order}
    context.update(order.details_as_dict())
    context = RequestContext(request, context)
    if request.GET.get("format") == "pdf":
        response = HttpResponse(mimetype="application/pdf")
        name = slugify("%s-invoice-%s" % (settings.SITE_TITLE, order.id))
        response["Content-Disposition"] = "attachment; filename=%s.pdf" % name
        html = get_template(template).render(context)
        import ho.pisa
        ho.pisa.CreatePDF(html, response)
        return response
    return render(request, template, context)

@login_required
def order_history(request, template="shop/order_history.html"):
    """
    Display a list of the currently logged-in user's past orders.
    """
    all_orders = Order.objects.filter(user_id=request.user.id)
    orders = paginate(all_orders.order_by('-time'),
                      request.GET.get("page", 1),
                      settings.SHOP_PER_PAGE_CATEGORY,
                      settings.MAX_PAGING_LINKS)
    # Add the total quantity to each order - this can probably be
    # replaced with fetch_related and Sum when we drop Django 1.3
    order_quantities = defaultdict(int)
    for item in OrderItem.objects.filter(order__user_id=request.user.id):
        order_quantities[item.order_id] += item.quantity
    for order in orders.object_list:
        setattr(order, "quantity_total", order_quantities[order.id])
    context = {"orders": orders}
    return render(request, template, context)
<commit_msg>Handle exception when "order" isn't in session.<commit_after>
from collections import defaultdict

from django.contrib.auth.decorators import login_required
from django.contrib.messages import info
from django.core.urlresolvers import get_callable, reverse
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.template import RequestContext
from django.template.defaultfilters import slugify
from django.template.loader import get_template
from django.utils import simplejson
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache

from mezzanine.conf import settings
from mezzanine.utils.importing import import_dotted_path
from mezzanine.utils.views import render, set_cookie, paginate

from cartridge.shop import checkout
from cartridge.shop.forms import AddProductForm, DiscountForm, CartItemFormSet
from cartridge.shop.models import Product, ProductVariation, Order, OrderItem
from cartridge.shop.models import DiscountCode
from cartridge.shop.utils import recalculate_discount, sign

# Set up checkout handlers.
handler = lambda s: import_dotted_path(s) if s else lambda *args: None
billship_handler = handler(settings.SHOP_HANDLER_BILLING_SHIPPING)
tax_handler = handler(settings.SHOP_HANDLER_TAX)
payment_handler = handler(settings.SHOP_HANDLER_PAYMENT)
order_handler = handler(settings.SHOP_HANDLER_ORDER)

def product(request, slug, template="shop/product.html"):
    """
    Display a product - convert the product variations to JSON as well as
    handling adding the product to either the cart or the wishlist.
    """
    published_products = Product.objects.published(for_user=request.user)
    product = get_object_or_404(published_products, slug=slug)
    fields = [f.name for f in ProductVariation.option_fields()]
    variations = product.variations.all()
    variations_json = simplejson.dumps([dict([(f, getattr(v, f))
                                        for f in fields + ["sku", "image_id"]])
                                        for v in variations])
    to_cart = (request.method == "POST" and
               request.POST.get("add_wishlist") is None)
    initial_data = {}
    if variations:
        initial_data = dict([(f, getattr(variations[0], f)) for f in fields])
    initial_data["quantity"] = 1
    add_product_form = AddProductForm(request.POST or None, product=product,
                                      initial=initial_data, to_cart=to_cart)
    if request.method == "POST":
        if add_product_form.is_valid():
            if to_cart:
                quantity = add_product_form.cleaned_data["quantity"]
                request.cart.add_item(add_product_form.variation, quantity)
                recalculate_discount(request)
                info(request, _("Item added to cart"))
                return redirect("shop_cart")
            else:
                skus = request.wishlist
                sku = add_product_form.variation.sku
                if sku not in skus:
                    skus.append(sku)
                info(request, _("Item added to wishlist"))
                response = redirect("shop_wishlist")
                set_cookie(response, "wishlist", ",".join(skus))
                return response
    context = {
        "product": product,
        "editable_obj": product,
        "images": product.images.all(),
        "variations": variations,
        "variations_json": variations_json,
        "has_available_variations": any([v.has_price() for v in variations]),
        "related_products": product.related_products.published(
                                                      for_user=request.user),
        "add_product_form": add_product_form
    }
    return render(request, template, context)

@never_cache
def wishlist(request, template="shop/wishlist.html"):
    """
    Display the wishlist and handle removing items from the wishlist and
    adding them to the cart.
    """

    skus = request.wishlist
    error = None
    if request.method == "POST":
        to_cart = request.POST.get("add_cart")
        add_product_form = AddProductForm(request.POST or None,
                                          to_cart=to_cart)
        if to_cart:
            if add_product_form.is_valid():
                request.cart.add_item(add_product_form.variation, 1)
                recalculate_discount(request)
                message = _("Item added to cart")
                url = "shop_cart"
            else:
                error = add_product_form.errors.values()[0]
        else:
            message = _("Item removed from wishlist")
            url = "shop_wishlist"
        sku = request.POST.get("sku")
        if sku in skus:
            skus.remove(sku)
        if not error:
            info(request, message)
            response = redirect(url)
            set_cookie(response, "wishlist", ",".join(skus))
            return response

    # Remove skus from the cookie that no longer exist.
    published_products = Product.objects.published(for_user=request.user)
    f = {"product__in": published_products, "sku__in": skus}
    wishlist = ProductVariation.objects.filter(**f).select_related(depth=1)
    wishlist = sorted(wishlist, key=lambda v: skus.index(v.sku))
    context = {"wishlist_items": wishlist, "error": error}
    response = render(request, template, context)
    if len(wishlist) < len(skus):
        skus = [variation.sku for variation in wishlist]
        set_cookie(response, "wishlist", ",".join(skus))
    return response

@never_cache
def cart(request, template="shop/cart.html"):
    """
    Display cart and handle removing items from the cart.
    """
    cart_formset = CartItemFormSet(instance=request.cart)
    discount_form = DiscountForm(request, request.POST or None)
    if request.method == "POST":
        valid = True
        if request.POST.get("update_cart"):
            valid = request.cart.has_items()
            if not valid:
                # Session timed out.
                info(request, _("Your cart has expired"))
            else:
                cart_formset = CartItemFormSet(request.POST,
                                               instance=request.cart)
                valid = cart_formset.is_valid()
                if valid:
                    cart_formset.save()
                    recalculate_discount(request)
                    info(request, _("Cart updated"))
        else:
            valid = discount_form.is_valid()
            if valid:
                discount_form.set_discount()
        if valid:
            return redirect("shop_cart")
    context = {"cart_formset": cart_formset}
    settings.use_editable()
    if (settings.SHOP_DISCOUNT_FIELD_IN_CART and
        DiscountCode.objects.active().count() > 0):
        context["discount_form"] = discount_form
    return render(request, template, context)

@never_cache
def checkout_steps(request):
    """
    Display the order form and handle processing of each step.
    """

    # Do the authentication check here rather than using standard
    # login_required decorator. This means we can check for a custom
    # LOGIN_URL and fall back to our own login view.
    authenticated = request.user.is_authenticated()
    if settings.SHOP_CHECKOUT_ACCOUNT_REQUIRED and not authenticated:
        url = "%s?next=%s" % (settings.LOGIN_URL, reverse("shop_checkout"))
        return redirect(url)

    # Determine the Form class to use during the checkout process
    form_class = get_callable(settings.SHOP_CHECKOUT_FORM_CLASS)

    initial = checkout.initial_order_data(request, form_class)
    step = int(request.POST.get("step", None)
               or initial.get("step", None)
               or checkout.CHECKOUT_STEP_FIRST)
    form = form_class(request, step, initial=initial)
    data = request.POST
    checkout_errors = []

    if request.POST.get("back") is not None:
        # Back button in the form was pressed - load the order form
        # for the previous step and maintain the field values entered.
        step -= 1
        form = form_class(request, step, initial=initial)
    elif request.method == "POST" and request.cart.has_items():
        form = form_class(request, step, initial=initial, data=data)
        if form.is_valid():
            # Copy the current form fields to the session so that
            # they're maintained if the customer leaves the checkout
            # process, but remove sensitive fields from the session
            # such as the credit card fields so that they're never
            # stored anywhere.
            request.session["order"] = dict(form.cleaned_data)
            sensitive_card_fields = ("card_number", "card_expiry_month",
                                     "card_expiry_year", "card_ccv")
            for field in sensitive_card_fields:
                if field in request.session["order"]:
                    del request.session["order"][field]

            # FIRST CHECKOUT STEP - handle shipping and discount code.
            if step == checkout.CHECKOUT_STEP_FIRST:
                try:
                    billship_handler(request, form)
                    tax_handler(request, form)
                except checkout.CheckoutError, e:
                    checkout_errors.append(e)
                form.set_discount()

            # FINAL CHECKOUT STEP - handle payment and process order.
            if step == checkout.CHECKOUT_STEP_LAST and not checkout_errors:
                # Create and save the inital order object so that
                # the payment handler has access to all of the order
                # fields. If there is a payment error then delete the
                # order, otherwise remove the cart items from stock
                # and send the order reciept email.
                order = form.save(commit=False)
                order.setup(request)
                # Try payment.
                try:
                    transaction_id = payment_handler(request, form, order)
                except checkout.CheckoutError, e:
                    # Error in payment handler.
                    order.delete()
                    checkout_errors.append(e)
                    if settings.SHOP_CHECKOUT_STEPS_CONFIRMATION:
                        step -= 1
                else:
                    # Finalize order - ``order.complete()`` performs
                    # final cleanup of session and cart.
                    # ``order_handler()`` can be defined by the
                    # developer to implement custom order processing.
                    # Then send the order email to the customer.
                    order.transaction_id = transaction_id
                    order.complete(request)
                    order_handler(request, form, order)
                    checkout.send_order_email(request, order)
                    # Set the cookie for remembering address details
                    # if the "remember" checkbox was checked.
                    response = redirect("shop_complete")
                    if form.cleaned_data.get("remember") is not None:
                        remembered = "%s:%s" % (sign(order.key), order.key)
                        set_cookie(response, "remember", remembered,
                                   secure=request.is_secure())
                    else:
                        response.delete_cookie("remember")
                    return response

            # If any checkout errors, assign them to a new form and
            # re-run is_valid. If valid, then set form to the next step.
            form = form_class(request, step, initial=initial, data=data,
                             errors=checkout_errors)
            if form.is_valid():
                step += 1
                form = form_class(request, step, initial=initial)

    # Update the step so that we don't rely on POST data to take us back to
    # the same point in the checkout process.
    try:
        request.session["order"]["step"] = step
    except KeyError:
        pass

    step_vars = checkout.CHECKOUT_STEPS[step - 1]
    template = "shop/%s.html" % step_vars["template"]
    CHECKOUT_STEP_FIRST = step == checkout.CHECKOUT_STEP_FIRST
    context = {"form": form, "CHECKOUT_STEP_FIRST": CHECKOUT_STEP_FIRST,
               "step_title": step_vars["title"], "step_url": step_vars["url"],
               "steps": checkout.CHECKOUT_STEPS, "step": step}
    return render(request, template, context)

@never_cache
def complete(request, template="shop/complete.html"):
    """
    Redirected to once an order is complete - pass the order object
    for tracking items via Google Anayltics, and displaying in
    the template if required.
    """
    try:
        order = Order.objects.from_request(request)
    except Order.DoesNotExist:
        raise Http404
    items = order.items.all()
    # Assign product names to each of the items since they're not
    # stored.
    skus = [item.sku for item in items]
    variations = ProductVariation.objects.filter(sku__in=skus)
    names = {}
    for variation in variations.select_related(depth=1):
        names[variation.sku] = variation.product.title
    for i, item in enumerate(items):
        setattr(items[i], "name", names[item.sku])
    context = {"order": order, "items": items,
               "steps": checkout.CHECKOUT_STEPS}
    return render(request, template, context)

def invoice(request, order_id, template="shop/order_invoice.html"):
    """
    Display a plain text invoice for the given order. The order must
    belong to the user which is checked via session or ID if
    authenticated, or if the current user is staff.
    """
    lookup = {"id": order_id}
    if not request.user.is_authenticated():
        lookup["key"] = request.session.session_key
    elif not request.user.is_staff:
        lookup["user_id"] = request.user.id
    order = get_object_or_404(Order, **lookup)
    context = {"order": order}
    context.update(order.details_as_dict())
    context = RequestContext(request, context)
    if request.GET.get("format") == "pdf":
        response = HttpResponse(mimetype="application/pdf")
        name = slugify("%s-invoice-%s" % (settings.SITE_TITLE, order.id))
        response["Content-Disposition"] = "attachment; filename=%s.pdf" % name
        html = get_template(template).render(context)
        import ho.pisa
        ho.pisa.CreatePDF(html, response)
        return response
    return render(request, template, context)

@login_required
def order_history(request, template="shop/order_history.html"):
    """
    Display a list of the currently logged-in user's past orders.
    """
    all_orders = Order.objects.filter(user_id=request.user.id)
    orders = paginate(all_orders.order_by('-time'),
                      request.GET.get("page", 1),
                      settings.SHOP_PER_PAGE_CATEGORY,
                      settings.MAX_PAGING_LINKS)
    # Add the total quantity to each order - this can probably be
    # replaced with fetch_related and Sum when we drop Django 1.3
    order_quantities = defaultdict(int)
    for item in OrderItem.objects.filter(order__user_id=request.user.id):
        order_quantities[item.order_id] += item.quantity
    for order in orders.object_list:
        setattr(order, "quantity_total", order_quantities[order.id])
    context = {"orders": orders}
    return render(request, template, context)
<|endoftext|>


<commit_before># layer 5
#https://www.openstreetmap.org/way/122189460
test.assert_has_feature(
    16, 18819, 24980, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 122189460, "sort_rank": 447})

# layer 4
#https://www.openstreetmap.org/way/8918870
test.assert_has_feature(
    16, 10483, 25340, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 8918870, "sort_rank": 446})

# layer 3
#https://www.openstreetmap.org/way/29394019
test.assert_has_feature(
    16, 10479, 25341, "roads",
    {"kind": "highway", "kind_detail": "motorway_link", "is_bridge": True,
     "id": 29394019, "sort_rank": 445})

# layer 2
#https://www.openstreetmap.org/way/27651523
test.assert_has_feature(
    16, 10480, 25365, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 27651523, "sort_rank": 444})

# layer 1
#https://www.openstreetmap.org/way/28412298
test.assert_has_feature(
    16, 10472, 25323, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 28412298, "sort_rank": 443})

# layer -1
#https://www.openstreetmap.org/way/43685501
test.assert_has_feature(
    16, 10472, 25323, "roads",
    {"kind": "minor_road", "kind_detail": "service", "is_tunnel": True,
     "id": 43685501, "sort_rank": 304})

# layer -2
#https://www.openstreetmap.org/way/50691047
test.assert_has_feature(
    16, 10491, 25323, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_tunnel": True,
     "id": 50691047, "sort_rank": 303})
<commit_msg>Update osm way used in test<commit_after># layer 5
#https://www.openstreetmap.org/way/48474682
test.assert_has_feature(
    16, 10654, 25150, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 48474682, "sort_rank": 447})

# layer 4
#https://www.openstreetmap.org/way/8918870
test.assert_has_feature(
    16, 10483, 25340, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 8918870, "sort_rank": 446})

# layer 3
#https://www.openstreetmap.org/way/29394019
test.assert_has_feature(
    16, 10479, 25341, "roads",
    {"kind": "highway", "kind_detail": "motorway_link", "is_bridge": True,
     "id": 29394019, "sort_rank": 445})

# layer 2
#https://www.openstreetmap.org/way/27651523
test.assert_has_feature(
    16, 10480, 25365, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 27651523, "sort_rank": 444})

# layer 1
#https://www.openstreetmap.org/way/28412298
test.assert_has_feature(
    16, 10472, 25323, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_bridge": True,
     "id": 28412298, "sort_rank": 443})

# layer -1
#https://www.openstreetmap.org/way/43685501
test.assert_has_feature(
    16, 10472, 25323, "roads",
    {"kind": "minor_road", "kind_detail": "service", "is_tunnel": True,
     "id": 43685501, "sort_rank": 304})

# layer -2
#https://www.openstreetmap.org/way/50691047
test.assert_has_feature(
    16, 10491, 25323, "roads",
    {"kind": "highway", "kind_detail": "motorway", "is_tunnel": True,
     "id": 50691047, "sort_rank": 303})
<|endoftext|>


<commit_before>import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

def layout_setup(pairs):
    """
    This function returns a layout of the user interface

    pairs: pairs is a two_dimensional list. The first is the columns from pandas data frame,
           the second is the relative name for each column in the dropdown choices
    """

    lay = html.Div([
        html.Div([
            html.Br(),
            html.Br(),
            html.Center(html.H1("Find Your Dream City to Live in the US",
                                style={'color': 'lavender', 'fontFamily': 'Helvetica', 'fontSize': 50}),
                       ),
            html.Center(html.P("Powerd by City Fynders",
                               style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
                       ),
            html.Br(),
            html.Br()],
                style={'backgroundColor': 'FireBrick', 'margin': 0,'padding': 0}),

        html.Div([
            html.Br(),
            html.Br(),
            html.Center(html.Img(src="http://travelquaz.com/wp-content/uploads/2015/09/photo-travel-holidays-to-the-usa-america-visit-usa-images.jpg"))
        ]),

        html.Center(html.Div([html.P("Ranking by all the fators",
                           style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
        ])),

        html.Div([
           html.Center(html.Button('Total General Rank', id='Total',
                                style={'width': 200, 'color': 'white', 'backgroundColor': 'FireBrick', 'height': 70,'fontSize': 15})),
        ]),

        html.Center(html.Div([
            html.P("Ranking by four main factors separately",
                style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
        ])),

        html.Center(html.Div([
                html.Button('Human Related Rank', id='Hrank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Natural Rank', id='Nrank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Economy Rank', id='Erank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Teritary Industry Rank', id='Trank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15}),
        ])),
        # First important factor
        html.Div([
            html.P('Important No.1'),
            dcc.Dropdown(
                id='First-care',
                options=[ {'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%', 'fontFamily':'Helvetica','display': 'inline-block'}),
        # Second important factor
        html.Div([
            html.P('Important No.2'),
            dcc.Dropdown(
                id='Second-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Third important factor
        html.Div([
            html.P('Important No.3'),
            dcc.Dropdown(
                id='Third-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Fourth important factor
        html.Div([
            html.P('Important No.4'),
            dcc.Dropdown(
                id='Fourth-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Fifth important factor
        html.Div([
            html.P('Important No.5'),
            dcc.Dropdown(
                id='Fifth-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%', 'fontFamily':'Helvetica','display': 'inline-block'}),
        html.Br(),
        html.Br(),
        html.Br(),
        html.Center(html.Button('Go Searching!', id='Search',
            style={'width': 200, 'color': 'white', 'backgroundColor': 'FireBrick', 'height': 70,'fontSize': 20})),
        html.Div(dcc.Graph(id='User-graphic')),
        html.Div(dcc.Graph(id='Total-graphic')),
        html.Div(dcc.Graph(id='Human-graphic')),
        html.Div(dcc.Graph(id='Natural-graphic')),
        html.Div(dcc.Graph(id='Economic-graphic')),
        html.Div(dcc.Graph(id='Tertiary-graphic'))
    ])
    return lay

def newdf(rank, First_care, Second_care, Third_care, Fourth_care, Fifth_care):
    """
    This function returns a new data frame from user choices

    rank: pandas data frame
    First_care: the first care column name chose from rank
    Second_care: the second care column name chose from rank
    Third_care: the third care column name chose from rank
    Fourth_care: the fourth care column name chose from rank
    Fifth_care: the fifth care column name chose from rank
    """

    df = pd.DataFrame()
    df['City'] = rank['City']
    df['First'] = rank[First_care]
    df['Second'] = rank[Second_care]
    df['Third'] = rank[Third_care]
    df['Fourth'] = rank[Fourth_care]
    df['Fifth'] = rank[Fifth_care]
    df['Total'] = (df['First']*5+df['Second']*4+df['Third']*3+df['Fourth']*2+df['Fifth']*1).rank(ascending=1)
    df = df.sort_values('Total', ascending=1)
    df['reverse_rank'] = df['Total'].rank(ascending=0)
    df['longitude'] = rank['Longitude']
    df['latitude'] = rank['Latitude']
    df['text'] = df['City'] + '
# Final Rank ' + ': ' + (df['Total']).astype(str) +\
    '
# ' + First_care + ': ' + (df['First']).astype(str)+ '
# ' + Second_care +\
    ': ' + (df['Second']).astype(str) + '
# ' + Third_care + ': ' + (df['Third']).astype(str)+\
    '
# ' + Fourth_care + ': ' + (df['Fourth']).astype(str) + '
# '+ Fifth_care +\
    ': ' + (df['Fifth']).astype(str)
    return df
<commit_msg>UI set up file<commit_after>import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

def layout_setup(pairs, f):
    """
    This function returns a layout of the user interface

    pairs: pairs is a two_dimensional list. The first is the columns from pandas data frame,
           the second is the relative name for each column in the dropdown choices
    """

    lay = html.Div([
        html.Div([
            html.Br(),
            html.Br(),
            html.Center(html.H1("Find Your Dream City to Live in the US",
                                style={'color': 'lavender', 'fontFamily': 'Helvetica', 'fontSize': 50}),
                       ),
            html.Center(html.P("Powerd by City Fynders",
                               style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
                       ),
            html.Br(),
            html.Br()],
                style={'backgroundColor': 'FireBrick', 'margin': 0,'padding': 0}),

        html.Div([
            html.Br(),
            html.Br(),
            html.Center(html.Img(src="http://travelquaz.com/wp-content/uploads/2015/09/photo-travel-holidays-to-the-usa-america-visit-usa-images.jpg"))
        ]),

        html.Center(html.Div([html.P("Ranking by all the fators",
                           style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
        ])),

        html.Div([
           html.Center(html.Button('Total General Rank', id='Total',
                                style={'width': 200, 'color': 'white', 'backgroundColor': 'FireBrick', 'height': 70,'fontSize': 15})),
        ]),

        html.Center(html.Div([
            html.P("Ranking by four main factors separately",
                style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
        ])),

        html.Center(html.Div([
                html.Button('Human Related Rank', id='Hrank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Natural Rank', id='Nrank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Economy Rank', id='Erank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15,'marginRight':100}),
                html.Button('Teritary Industry Rank', id='Trank',
                                style={'width': 200, 'color': 'black', 'backgroundColor': 'lightblue', 'height': 70,'fontSize': 15}),
        ])),

        html.Center(html.Div([
            dcc.Graph(id='graph-with-slider'),
            dcc.Slider(
                id='factor',
                min=0,
                max=7,
                value=4,
                step=None,
                marks={i: f[i] for i in range(8)})
        ])),
        html.Br(),
        html.Br(),
        html.Center(html.Div([
            html.P("Now choose factors you care about",
                style={'color': 'black','fontFamily':'Helvetica', 'fontSize': 20}),
        ])),
        # First important factor
        html.Div([
            html.P('Important No.1'),
            dcc.Dropdown(
                id='First-care',
                options=[ {'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%', 'fontFamily':'Helvetica','display': 'inline-block'}),
        # Second important factor
        html.Div([
            html.P('Important No.2'),
            dcc.Dropdown(
                id='Second-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Third important factor
        html.Div([
            html.P('Important No.3'),
            dcc.Dropdown(
                id='Third-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Fourth important factor
        html.Div([
            html.P('Important No.4'),
            dcc.Dropdown(
                id='Fourth-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%','fontFamily':'Helvetica', 'display': 'inline-block'}),
        # Fifth important factor
        html.Div([
            html.P('Important No.5'),
            dcc.Dropdown(
                id='Fifth-care',
                options=[{'label': pairs[1][i],'value': pairs[0][i]} for i in range(19)],
            )
        ],
            style={'width': '20%', 'fontFamily':'Helvetica','display': 'inline-block'}),
        html.Br(),
        html.Br(),
        html.Br(),
        html.Center(html.Button('Go Searching!', id='Search',
            style={'width': 200, 'color': 'white', 'backgroundColor': 'FireBrick', 'height': 70,'fontSize': 20})),
        html.Div(dcc.Graph(id='User-graphic')),
        html.Div(dcc.Graph(id='Total-graphic')),
        html.Div(dcc.Graph(id='Human-graphic')),
        html.Div(dcc.Graph(id='Natural-graphic')),
        html.Div(dcc.Graph(id='Economic-graphic')),
        html.Div(dcc.Graph(id='Tertiary-graphic'))
    ])
    return lay

def newdf(rank, First_care, Second_care, Third_care, Fourth_care, Fifth_care):
    """
    This function returns a new data frame from user choices

    rank: pandas data frame
    First_care: the first care column name chose from rank
    Second_care: the second care column name chose from rank
    Third_care: the third care column name chose from rank
    Fourth_care: the fourth care column name chose from rank
    Fifth_care: the fifth care column name chose from rank
    """

    df = pd.DataFrame()
    df['City'] = rank['City']
    df['First'] = rank[First_care]
    df['Second'] = rank[Second_care]
    df['Third'] = rank[Third_care]
    df['Fourth'] = rank[Fourth_care]
    df['Fifth'] = rank[Fifth_care]
    df['Total'] = (df['First']*5+df['Second']*4+df['Third']*3+df['Fourth']*2+df['Fifth']*1).rank(ascending=1)
    df = df.sort_values('Total', ascending=1)
    df['reverse_rank'] = df['Total'].rank(ascending=0)
    df['longitude'] = rank['Longitude']
    df['latitude'] = rank['Latitude']
    df['text'] = df['City'] + '
# Final Rank ' + ': ' + (df['Total']).astype(str) +\
    '
# ' + First_care + ': ' + (df['First']).astype(str)+ '
# ' + Second_care +\
    ': ' + (df['Second']).astype(str) + '
# ' + Third_care + ': ' + (df['Third']).astype(str)+\
    '
# ' + Fourth_care + ': ' + (df['Fourth']).astype(str) + '
# '+ Fifth_care +\
    ': ' + (df['Fifth']).astype(str)
    return df
<|endoftext|>