<commit_before>
# -*- coding: utf-8 -*-
"""
Written by Daniel M. Aukes.
Email: danaukes<at>seas.harvard.edu.
Please see LICENSE.txt for full license.
"""

from popupcad.geometry import customshapely
from popupcad.geometry.vertex import ShapeVertex

import numpy
import PySide.QtCore as qc
import PySide.QtGui as qg
from dev_tools.enum import enum
from popupcad.filetypes.popupcad_file import popupCADFile
import popupcad

class ShapeInvalid(Exception):
    pass

class NotSimple(Exception):
    pass

class GenericShapeBase(popupCADFile):
    filetypes = {'shape': 'Shape File'}
    defaultfiletype = 'shape'

    display = ['construction', 'exterior', 'interiors']
    editable = ['construction']
    roundvalue = 5
    tolerance = 10.**-(roundvalue - 1)
    shapetypes = enum(
        line='line',
        polyline='polyline',
        polygon='polygon',
        circle='circle',
        rect2point='rect2point')
    deletable = []

    def __init__(
            self,
            exterior,
            interiors,
            construction=False,
            test_shapely=False):
        super(GenericShapeBase, self).__init__()
        self.exterior = exterior
        self.interiors = interiors

        self.exterior, self.interiors = self.condition_points(
            self.exterior, self.interiors)

        self.construction = construction

    def is_valid(self):
        shapely = self.outputshapely()
        if not shapely.is_simple:
            raise(NotSimple)
        if not shapely.is_valid:
            raise(ShapeInvalid)

    @classmethod
    def lastdir(cls):
        return popupcad.lastshapedir

    @classmethod
    def setlastdir(cls, directory):
        popupcad.lastshapedir = directory

    def isValid(self):
        notempty = len(self.get_exterior()) > 0
        return notempty

    def copy_data(self, new_type, identical=True):
        exterior = [vertex.copy(identical) for vertex in self.get_exterior()]
        interiors = [[vertex.copy(identical) for vertex in interior]
                     for interior in self.get_interiors()]
        new = new_type(exterior, interiors, self.is_construction())
        if identical:
            new.id = self.id
        self.copy_file_params(new, identical)
        return new

    def copy(self, identical=True):
        return self.copy_data(type(self), identical)

    def upgrade(self, identical=True):
        exterior = [vertex.upgrade(identical)
                    for vertex in self.get_exterior()]
        interiors = [[vertex.upgrade(
            identical) for vertex in interior] for interior in self.get_interiors()]
        new = type(self)(exterior, interiors, self.is_construction())
        if identical:
            new.id = self.id
        self.copy_file_params(new, identical)
        return new

    def get_exterior(self):
        return self.exterior

    def get_interiors(self):
        return self.interiors

    def is_construction(self):
        try:
            return self.construction
        except AttributeError:
            self.construction = False
            return self.construction

    def exteriorpoints(self, scaling=1):
        return [vertex.getpos(scaling) for vertex in self.get_exterior()]

    def interiorpoints(self, scaling=1):
        return [[vertex.getpos(scaling) for vertex in interior]
                for interior in self.get_interiors()]

    def exteriorpoints_3d(self, z=0):
        points = numpy.array([vertex.getpos() for vertex in self.get_exterior()])
        size = list(points.shape)
        size[1]+=1
        points2 = numpy.zeros(size)
        points2[:,:2] = points
        points2[:,2] = z
        return points2.tolist()

    def interiorpoints_3d(self, z=0):
        interiors2 = []
        for interior in self.get_interiors():
            points = numpy.array([vertex.getpos() for vertex in interior])
            size = list(points.shape)
            size[1]+=1
            points2 = numpy.zeros(size)
            points2[:,:2] = points
            points2[:,2] = z
            interiors2.append(points2.tolist())
        return interiors2

    def vertices(self):
        vertices = self.get_exterior()[:]
        [vertices.extend(interior) for interior in self.get_interiors()]
        return vertices

    def points(self, scaling=1):
        return [vertex.getpos(scaling) for vertex in self.vertices()]

    def segments_closed(self):
        points = self.get_exterior()
        segments = list(zip(points, points[1:] + points[:1]))
        for points in self.get_interiors():
            segments.extend(list(zip(points, points[1:] + points[:1])))
        return segments

    def segments_open(self):
        points = self.get_exterior()
        segments = list(zip(points[:-1], points[1:]))
        for points in self.get_interiors():
            segments.extend(list(zip(points[:-1], points[1:])))
        return segments

    def segmentpoints(self, scaling=1):
        segments = self.segments()
        segmentpoints = [
            (point1.getpos(scaling),
             point2.getpos(scaling)) for point1,
            point2 in segments]
        return segmentpoints

    def painterpath(self):
        exterior = self.exteriorpoints(scaling=popupcad.view_scaling)
        interiors = self.interiorpoints(scaling=popupcad.view_scaling)
        return self.gen_painterpath(exterior, interiors)

    def gen_painterpath(self, exterior, interiors):
        path = qg.QPainterPath()
        return path

    def properties(self):
        from dev_tools.propertyeditor import PropertyEditor
        return PropertyEditor(self)

    def addvertex_exterior(self, vertex, special=False):
        self.exterior.append(vertex)
        self.update_handles()

    def removevertex(self, vertex):
        if vertex in self.exterior:
            ii = self.exterior.index(vertex)
            self.exterior.pop(ii)
        for interior in self.interiors:
            if vertex in self.interior:
                ii = interior.index(vertex)
                interior.pop(ii)
        self.update_handles()

    def checkedge(self, edge):
        import popupcad.algorithms.points as points
        for pt1, pt2 in zip(edge[:-1], edge[1:]):
            if points.twopointsthesame(pt1, pt2, self.tolerance):
                raise Exception

    @classmethod
    def condition_points(cls, exterior, interiors):
        exterior = cls.remove_redundant_points(exterior)
        interiors = [
            cls.remove_redundant_points(interior) for interior in interiors]
        return exterior, interiors

    def remove_redundant_points(cls, points, scaling=1,loop_test = True):
        newpoints = []
        if len(points)>0:
            points = points[:]
            newpoints.append(points.pop(0))
            while not not points:
                newpoint = points.pop(0)
                if not cls.samepoint(newpoints[-1].getpos(scaling),newpoint.getpos(scaling)):
                    if len(points)==0 and loop_test:
                        if not cls.samepoint(newpoints[0].getpos(scaling),newpoint.getpos(scaling)):
                            newpoints.append(newpoint)
                    else:
                        newpoints.append(newpoint)
        return newpoints

    @classmethod
    def samepoint(cls, point1, point2):
        v = numpy.array(point2) - numpy.array(point1)
        l = v.dot(v)**.5
        return l < cls.tolerance

    @staticmethod
    def buildvertices(exterior_p, interiors_p):
        exterior = GenericShapeBase.buildvertexlist(exterior_p)
        interiors = []
        for interior_p in interiors_p:
            interiors.append(GenericShapeBase.buildvertexlist(interior_p))
        return exterior, interiors

    @staticmethod
    def buildvertexlist(points):
        exterior = []
        for point in points:
            v = ShapeVertex()
            v.setpos(point)
            exterior.append(v)
        return exterior

    @classmethod
    def genfromshapely(cls, obj):
        from popupcad.filetypes.genericshapes import GenericPoly, GenericPolyline
        exterior_p, interiors_p = obj.genpoints_generic()
        exterior, interiors = cls.buildvertices(exterior_p, interiors_p)
        if isinstance(obj, customshapely.ShapelyPolygon):
            subclass = GenericPoly
        elif isinstance(obj, customshapely.ShapelyLineString):
            subclass = GenericPolyline
        elif isinstance(obj, customshapely.ShapelyPoint):
            from popupcad.geometry.vertex import DrawnPoint
            s = DrawnPoint()
            s.setpos(exterior_p[0])
            return s
        else:
            raise Exception

        return subclass(exterior, interiors)

    @classmethod
    def gen_from_point_lists(cls, exterior_p, interiors_p, **kwargs):
        exterior, interiors = cls.buildvertices(exterior_p, interiors_p)
        return cls(exterior, interiors, **kwargs)

    def genInteractiveVertices(self):
        try:
            return self._exteriorhandles, self._interiorhandles
        except AttributeError:
            self.update_handles()
            return self._exteriorhandles, self._interiorhandles

    def update_handles(self):
        try:
            for handle in self._handles:
                handle.harddelete()
        except AttributeError:
            pass

        exterior = [vertex.gen_interactive() for vertex in self.get_exterior()]
        interiors = [[vertex.gen_interactive() for vertex in interior]
                     for interior in self.get_interiors()]

        handles = exterior[:]
        [handles.extend(interior) for interior in interiors]
        self._exteriorhandles = exterior
        self._interiorhandles = interiors
        self._handles = handles

    def len_exterior(self):
        return len(self.get_exterior())

    def get_handles(self):
        try:
            return self._handles
        except AttributeError:
            self.update_handles()
            return self._handles

    def get_exterior_handles(self):
        try:
            return self._exteriorhandles
        except AttributeError:
            self.update_handles()
            return self._exteriorhandles

    def triangles3(self):
        return []

    @staticmethod
    def generateQPolygon(points):
        poly = qg.QPolygonF([qc.QPointF(*(point))
                             for point in numpy.array(points)])
        return poly

    def shape_is_equal(self, other):
        if isinstance(self, type(other)):
            if len(
                self.get_exterior()) == len(
                other.get_exterior()) and len(
                self.get_interiors()) == len(
                    other.get_interiors()):
                for point1, point2 in zip(
                        self.get_exterior(), other.get_exterior()):
                    if not point1.is_equal(point2, self.tolerance):
                        return False
                for interior1, interior2 in zip(
                        self.get_interiors(), other.get_interiors()):
                    if len(interior1) != len(interior2):
                        return False
                    for point1, point2 in zip(interior1, interior2):
                        if not point1.is_equal(point2, self.tolerance):
                            return False
                return True
        return False

    def shift(self, dxdy):
        [item.shift(dxdy) for item in self.get_exterior()]
        [item.shift(dxdy) for interior in self.get_interiors()
         for item in interior]

    def transform(self, T):
        exteriorpoints = (T.dot(numpy.array(self.exteriorpoints_3d(z=1)).T)).T[:,:2].tolist()
        interiorpoints = [(T.dot(numpy.array(interior).T)).T[:,:2].tolist() for interior in self.interiorpoints_3d(z=1)]
        return self.gen_from_point_lists(exteriorpoints,interiorpoints)

    def constrained_shift(self, dxdy, constraintsystem):
        a = [(item, dxdy) for item in self.get_exterior()]
        a.extend([(item, dxdy) for interior in self.get_interiors()
                  for item in interior])
        constraintsystem.constrained_shift(a)

    def flip(self):
        self.exterior = self.get_exterior()[::-1]
        self.interiors = [interior[::-1] for interior in self.get_interiors()]

    def hollow(self):
        return [self]

    def fill(self):
        return [self]

    def insert_exterior_vertex(self, ii, vertex):
        self.exterior.insert(ii, vertex)

    def append_exterior_vertex(self, vertex):
        self.exterior.append(vertex)

    def output_dxf(self,model_space,layer = None):
        pass<commit_msg>missed that.<commit_after>
# -*- coding: utf-8 -*-
"""
Written by Daniel M. Aukes.
Email: danaukes<at>seas.harvard.edu.
Please see LICENSE.txt for full license.
"""

from popupcad.geometry import customshapely
from popupcad.geometry.vertex import ShapeVertex

import numpy
import PySide.QtCore as qc
import PySide.QtGui as qg
from dev_tools.enum import enum
from popupcad.filetypes.popupcad_file import popupCADFile
import popupcad

class ShapeInvalid(Exception):
    pass

class NotSimple(Exception):
    pass

class GenericShapeBase(popupCADFile):
    filetypes = {'shape': 'Shape File'}
    defaultfiletype = 'shape'

    display = ['construction', 'exterior', 'interiors']
    editable = ['construction']
    roundvalue = 5
    tolerance = 10.**-(roundvalue - 1)
    shapetypes = enum(
        line='line',
        polyline='polyline',
        polygon='polygon',
        circle='circle',
        rect2point='rect2point')
    deletable = []

    def __init__(
            self,
            exterior,
            interiors,
            construction=False,
            test_shapely=False):
        super(GenericShapeBase, self).__init__()
        self.exterior = exterior
        self.interiors = interiors

        self.exterior, self.interiors = self.condition_points(
            self.exterior, self.interiors)

        self.construction = construction

    def is_valid(self):
        shapely = self.outputshapely()
        if not shapely.is_simple:
            raise(NotSimple)
        if not shapely.is_valid:
            raise(ShapeInvalid)

    @classmethod
    def lastdir(cls):
        return popupcad.lastshapedir

    @classmethod
    def setlastdir(cls, directory):
        popupcad.lastshapedir = directory

    def isValid(self):
        notempty = len(self.get_exterior()) > 0
        return notempty

    def copy_data(self, new_type, identical=True):
        exterior = [vertex.copy(identical) for vertex in self.get_exterior()]
        interiors = [[vertex.copy(identical) for vertex in interior]
                     for interior in self.get_interiors()]
        new = new_type(exterior, interiors, self.is_construction())
        if identical:
            new.id = self.id
        self.copy_file_params(new, identical)
        return new

    def copy(self, identical=True):
        return self.copy_data(type(self), identical)

    def upgrade(self, identical=True):
        exterior = [vertex.upgrade(identical)
                    for vertex in self.get_exterior()]
        interiors = [[vertex.upgrade(
            identical) for vertex in interior] for interior in self.get_interiors()]
        new = type(self)(exterior, interiors, self.is_construction())
        if identical:
            new.id = self.id
        self.copy_file_params(new, identical)
        return new

    def get_exterior(self):
        return self.exterior

    def get_interiors(self):
        return self.interiors

    def is_construction(self):
        try:
            return self.construction
        except AttributeError:
            self.construction = False
            return self.construction

    def exteriorpoints(self, scaling=1):
        return [vertex.getpos(scaling) for vertex in self.get_exterior()]

    def interiorpoints(self, scaling=1):
        return [[vertex.getpos(scaling) for vertex in interior]
                for interior in self.get_interiors()]

    def exteriorpoints_3d(self, z=0):
        points = numpy.array([vertex.getpos() for vertex in self.get_exterior()])
        size = list(points.shape)
        size[1]+=1
        points2 = numpy.zeros(size)
        points2[:,:2] = points
        points2[:,2] = z
        return points2.tolist()

    def interiorpoints_3d(self, z=0):
        interiors2 = []
        for interior in self.get_interiors():
            points = numpy.array([vertex.getpos() for vertex in interior])
            size = list(points.shape)
            size[1]+=1
            points2 = numpy.zeros(size)
            points2[:,:2] = points
            points2[:,2] = z
            interiors2.append(points2.tolist())
        return interiors2

    def vertices(self):
        vertices = self.get_exterior()[:]
        [vertices.extend(interior) for interior in self.get_interiors()]
        return vertices

    def points(self, scaling=1):
        return [vertex.getpos(scaling) for vertex in self.vertices()]

    def segments_closed(self):
        points = self.get_exterior()
        segments = list(zip(points, points[1:] + points[:1]))
        for points in self.get_interiors():
            segments.extend(list(zip(points, points[1:] + points[:1])))
        return segments

    def segments_open(self):
        points = self.get_exterior()
        segments = list(zip(points[:-1], points[1:]))
        for points in self.get_interiors():
            segments.extend(list(zip(points[:-1], points[1:])))
        return segments

    def segmentpoints(self, scaling=1):
        segments = self.segments()
        segmentpoints = [
            (point1.getpos(scaling),
             point2.getpos(scaling)) for point1,
            point2 in segments]
        return segmentpoints

    def painterpath(self):
        exterior = self.exteriorpoints(scaling=popupcad.view_scaling)
        interiors = self.interiorpoints(scaling=popupcad.view_scaling)
        return self.gen_painterpath(exterior, interiors)

    def gen_painterpath(self, exterior, interiors):
        path = qg.QPainterPath()
        return path

    def properties(self):
        from dev_tools.propertyeditor import PropertyEditor
        return PropertyEditor(self)

    def addvertex_exterior(self, vertex, special=False):
        self.exterior.append(vertex)
        self.update_handles()

    def removevertex(self, vertex):
        if vertex in self.exterior:
            ii = self.exterior.index(vertex)
            self.exterior.pop(ii)
        for interior in self.interiors:
            if vertex in self.interior:
                ii = interior.index(vertex)
                interior.pop(ii)
        self.update_handles()

    def checkedge(self, edge):
        import popupcad.algorithms.points as points
        for pt1, pt2 in zip(edge[:-1], edge[1:]):
            if points.twopointsthesame(pt1, pt2, self.tolerance):
                raise Exception

    @classmethod
    def condition_points(cls, exterior, interiors):
        exterior = cls.remove_redundant_points(exterior)
        interiors = [
            cls.remove_redundant_points(interior) for interior in interiors]
        return exterior, interiors

    @classmethod
    def remove_redundant_points(cls, points, scaling=1,loop_test = True):
        newpoints = []
        if len(points)>0:
            points = points[:]
            newpoints.append(points.pop(0))
            while not not points:
                newpoint = points.pop(0)
                if not cls.samepoint(newpoints[-1].getpos(scaling),newpoint.getpos(scaling)):
                    if len(points)==0 and loop_test:
                        if not cls.samepoint(newpoints[0].getpos(scaling),newpoint.getpos(scaling)):
                            newpoints.append(newpoint)
                    else:
                        newpoints.append(newpoint)
        return newpoints

    @classmethod
    def samepoint(cls, point1, point2):
        v = numpy.array(point2) - numpy.array(point1)
        l = v.dot(v)**.5
        return l < cls.tolerance

    @staticmethod
    def buildvertices(exterior_p, interiors_p):
        exterior = GenericShapeBase.buildvertexlist(exterior_p)
        interiors = []
        for interior_p in interiors_p:
            interiors.append(GenericShapeBase.buildvertexlist(interior_p))
        return exterior, interiors

    @staticmethod
    def buildvertexlist(points):
        exterior = []
        for point in points:
            v = ShapeVertex()
            v.setpos(point)
            exterior.append(v)
        return exterior

    @classmethod
    def genfromshapely(cls, obj):
        from popupcad.filetypes.genericshapes import GenericPoly, GenericPolyline
        exterior_p, interiors_p = obj.genpoints_generic()
        exterior, interiors = cls.buildvertices(exterior_p, interiors_p)
        if isinstance(obj, customshapely.ShapelyPolygon):
            subclass = GenericPoly
        elif isinstance(obj, customshapely.ShapelyLineString):
            subclass = GenericPolyline
        elif isinstance(obj, customshapely.ShapelyPoint):
            from popupcad.geometry.vertex import DrawnPoint
            s = DrawnPoint()
            s.setpos(exterior_p[0])
            return s
        else:
            raise Exception

        return subclass(exterior, interiors)

    @classmethod
    def gen_from_point_lists(cls, exterior_p, interiors_p, **kwargs):
        exterior, interiors = cls.buildvertices(exterior_p, interiors_p)
        return cls(exterior, interiors, **kwargs)

    def genInteractiveVertices(self):
        try:
            return self._exteriorhandles, self._interiorhandles
        except AttributeError:
            self.update_handles()
            return self._exteriorhandles, self._interiorhandles

    def update_handles(self):
        try:
            for handle in self._handles:
                handle.harddelete()
        except AttributeError:
            pass

        exterior = [vertex.gen_interactive() for vertex in self.get_exterior()]
        interiors = [[vertex.gen_interactive() for vertex in interior]
                     for interior in self.get_interiors()]

        handles = exterior[:]
        [handles.extend(interior) for interior in interiors]
        self._exteriorhandles = exterior
        self._interiorhandles = interiors
        self._handles = handles

    def len_exterior(self):
        return len(self.get_exterior())

    def get_handles(self):
        try:
            return self._handles
        except AttributeError:
            self.update_handles()
            return self._handles

    def get_exterior_handles(self):
        try:
            return self._exteriorhandles
        except AttributeError:
            self.update_handles()
            return self._exteriorhandles

    def triangles3(self):
        return []

    @staticmethod
    def generateQPolygon(points):
        poly = qg.QPolygonF([qc.QPointF(*(point))
                             for point in numpy.array(points)])
        return poly

    def shape_is_equal(self, other):
        if isinstance(self, type(other)):
            if len(
                self.get_exterior()) == len(
                other.get_exterior()) and len(
                self.get_interiors()) == len(
                    other.get_interiors()):
                for point1, point2 in zip(
                        self.get_exterior(), other.get_exterior()):
                    if not point1.is_equal(point2, self.tolerance):
                        return False
                for interior1, interior2 in zip(
                        self.get_interiors(), other.get_interiors()):
                    if len(interior1) != len(interior2):
                        return False
                    for point1, point2 in zip(interior1, interior2):
                        if not point1.is_equal(point2, self.tolerance):
                            return False
                return True
        return False

    def shift(self, dxdy):
        [item.shift(dxdy) for item in self.get_exterior()]
        [item.shift(dxdy) for interior in self.get_interiors()
         for item in interior]

    def transform(self, T):
        exteriorpoints = (T.dot(numpy.array(self.exteriorpoints_3d(z=1)).T)).T[:,:2].tolist()
        interiorpoints = [(T.dot(numpy.array(interior).T)).T[:,:2].tolist() for interior in self.interiorpoints_3d(z=1)]
        return self.gen_from_point_lists(exteriorpoints,interiorpoints)

    def constrained_shift(self, dxdy, constraintsystem):
        a = [(item, dxdy) for item in self.get_exterior()]
        a.extend([(item, dxdy) for interior in self.get_interiors()
                  for item in interior])
        constraintsystem.constrained_shift(a)

    def flip(self):
        self.exterior = self.get_exterior()[::-1]
        self.interiors = [interior[::-1] for interior in self.get_interiors()]

    def hollow(self):
        return [self]

    def fill(self):
        return [self]

    def insert_exterior_vertex(self, ii, vertex):
        self.exterior.insert(ii, vertex)

    def append_exterior_vertex(self, vertex):
        self.exterior.append(vertex)

    def output_dxf(self,model_space,layer = None):
        pass<|endoftext|>


<commit_before>from scipy import special
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from porousmedialab.column import Column
import porousmedialab.desolver as desolver

sns.set_style("whitegrid")

def transport_equation_boundary_effect():
    '''Check the transport equation integrator'''

    w = 5
    tend = 5
    dx = 0.1
    length = 30
    phi = 1
    dt = 0.001
    lab = Column(length, dx, tend, dt, phi, w)
    D = 5
    lab.add_species(True, 'O2', D, 0, bc_top=1,
                    bc_top_type='dirichlet', bc_bot=0, bc_bot_type='flux')
    lab.solve()
    x = np.linspace(0, lab.length, lab.length / lab.dx + 1)
    sol = 1 / 2 * (special.erfc((
        x - lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)) +
        np.exp(lab.w * x / D) * special.erfc((
            x + lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)))

    plt.figure()
    plt.plot(x, sol, 'k', label='Analytical solution')
    plt.scatter(lab.x[::10], lab.species['O2'].concentration[
                :, -1][::10], marker='x', label='Numerical')
    plt.xlim([x[0], x[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()

def transport_equation_plot():
    '''Check the transport equation integrator'''

    w = 5
    tend = 5
    dx = 0.1
    length = 100
    phi = 1
    dt = 0.001
    lab = Column(length, dx, tend, dt, phi, w)
    D = 5
    lab.add_species(True, 'O2', D, 0, bc_top=1,
                    bc_top_type='dirichlet', bc_bot=0, bc_bot_type='dirichlet')
    lab.solve()
    x = np.linspace(0, lab.length, lab.length / lab.dx + 1)
    sol = 1 / 2 * (special.erfc((
        x - lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)) +
        np.exp(lab.w * x / D) * special.erfc((
            x + lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)))

    plt.figure()
    plt.plot(x, sol, 'k', label='Analytical solution')
    plt.scatter(lab.x[::10], lab.species['O2'].concentration[
                :, -1][::10], marker='x', label='Numerical')
    plt.xlim([x[0], x[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()

def reaction_equation_plot():
    '''Check the reaction equation integrator'''

    C0 = {'C': 1}
    coef = {'k': 2}
    rates = {'R': 'k*C'}
    dcdt = {'C': '-R'}
    dt = 0.001
    T = 10
    time = np.linspace(0, T, T / dt + 1)
    num_sol = np.array(C0['C'])
    for i in range(1, len(time)):
        C_new, _, _ = desolver.ode_integrate(
            C0, dcdt, rates, coef, dt, solver='rk4')
        C0['C'] = C_new['C']
        num_sol = np.append(num_sol, C_new['C'])
    assert max(num_sol - np.exp(-coef['k'] * time)) < 1e-5

    plt.figure()
    plt.plot(time, np.exp(-coef['k'] * time), 'k', label='Analytical solution')
    plt.scatter(time[::100], num_sol[::100], marker='x', label='Numerical')
    plt.xlim([time[0], time[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()
<commit_msg>analytical solutions<commit_after>from scipy import special
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from porousmedialab.column import Column
import porousmedialab.desolver as desolver

sns.set_style("whitegrid")

def transport_equation_boundary_effect():
    '''Check the transport equation integrator'''

    w = 5
    tend = 5
    dx = 0.1
    length = 30
    phi = 1
    dt = 0.001
    lab = Column(length, dx, tend, dt, w)
    D = 5
    lab.add_species(phi, 'O2', D, 0, bc_top=1,
                    bc_top_type='dirichlet', bc_bot=0, bc_bot_type='flux')
    lab.solve()
    x = np.linspace(0, lab.length, lab.length / lab.dx + 1)
    sol = 1 / 2 * (special.erfc((
        x - lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)) +
        np.exp(lab.w * x / D) * special.erfc((
            x + lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)))

    plt.figure()
    plt.plot(x, sol, 'k', label='Analytical solution')
    plt.scatter(lab.x[::10], lab.species['O2'].concentration[
                :, -1][::10], marker='x', label='Numerical')
    plt.xlim([x[0], x[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()

def transport_equation_plot():
    '''Check the transport equation integrator'''

    w = 5
    tend = 5
    dx = 0.1
    length = 100
    phi = 1
    dt = 0.001
    lab = Column(length, dx, tend, dt, w)
    D = 5
    lab.add_species(phi, 'O2', D, 0, bc_top=1,
                    bc_top_type='dirichlet', bc_bot=0, bc_bot_type='dirichlet')
    lab.solve()
    x = np.linspace(0, lab.length, lab.length / lab.dx + 1)
    sol = 1 / 2 * (special.erfc((
        x - lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)) +
        np.exp(lab.w * x / D) * special.erfc((
            x + lab.w * lab.tend) / 2 / np.sqrt(D * lab.tend)))

    plt.figure()
    plt.plot(x, sol, 'k', label='Analytical solution')
    plt.scatter(lab.x[::10], lab.species['O2'].concentration[
                :, -1][::10], marker='x', label='Numerical')
    plt.xlim([x[0], x[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()

def reaction_equation_plot():
    '''Check the reaction equation integrator'''

    C0 = {'C': 1}
    coef = {'k': 2}
    rates = {'R': 'k*C'}
    dcdt = {'C': '-R'}
    dt = 0.001
    T = 10
    time = np.linspace(0, T, T / dt + 1)
    num_sol = np.array(C0['C'])
    for i in range(1, len(time)):
        C_new, _, _ = desolver.ode_integrate(
            C0, dcdt, rates, coef, dt, solver='rk4')
        C0['C'] = C_new['C']
        num_sol = np.append(num_sol, C_new['C'])
    assert max(num_sol - np.exp(-coef['k'] * time)) < 1e-5

    plt.figure()
    plt.plot(time, np.exp(-coef['k'] * time), 'k', label='Analytical solution')
    plt.scatter(time[::100], num_sol[::100], marker='x', label='Numerical')
    plt.xlim([time[0], time[-1]])
    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)
    ax.grid(linestyle='-', linewidth=0.2)
    plt.legend()
    plt.tight_layout()
    plt.show()
<|endoftext|>


<commit_before>"""CommunicationRequest model"""
from flask import current_app
from datetime import datetime
from sqlalchemy import UniqueConstraint
from sqlalchemy.dialects.postgresql import ENUM

from .assessment_status import overall_assessment_status
from .communication import Communication
from ..database import db
from ..date_tools import RelativeDelta
from .identifier import Identifier
from .reference import Reference
from ..system_uri import TRUENTH_CR_NAME

# https://www.hl7.org/fhir/valueset-request-status.html
request_status_types = ENUM(
    'draft', 'active', 'suspended', 'cancelled', 'completed',
    'entered-in-error', 'unknown', name='request_statuses',
    create_type=False)

class CommunicationRequest(db.Model):
    """Model representing a FHIR-like CommunicationRequest

    CommunicationRequest is used to capture business rules surrounding
    messages, reminders and other forms of communications.

    As the base event which defines the time often moves due to
    procedures and diagnosis, time deltas are generally persisted
    within the CommunicationRequest rather than a static datetime.

    CommunicationRequests are associated with a set of users by a
    QuestionnaireBank, such that for any user for whom the
    QuestionnaireBank applies, send the communication (unless
    the QuestionnaireBank is completed or expired).

    NB - several exceptions from the FHIR spec exist for this model,
    as the FHIR doesn't well handle time deltas and associations as needed.

    """
    __tablename__ = 'communication_requests'
    id = db.Column(db.Integer, primary_key=True)
    identifiers = db.relationship(
        'Identifier', lazy='dynamic',
        secondary="communication_request_identifiers")
    status = db.Column('status', request_status_types, nullable=False)
    notify_post_qb_start = db.Column(
        db.Text, nullable=False,
        doc=("'relativedelta' value (i.e. {\"months\": 3, \"days\": -14}) "
             "from associated Questionnaire Bank start time"))

    questionnaire_bank_id = db.Column(
        db.ForeignKey('questionnaire_banks.id'), nullable=False)
    questionnaire_bank = db.relationship('QuestionnaireBank')
    qb_iteration = db.Column(
        db.Integer(), nullable=True,
        doc=("For recurring QuestionnaireBank association, the "
             "iteration_count this CommunicationRequest applies to"))
    lr_uuid = db.Column(db.Text, nullable=False)

    __table_args__ = (
        UniqueConstraint(
            questionnaire_bank_id, notify_post_qb_start, qb_iteration,
            name='_communication_request_qb_days'),
    )

    def __str__(self):
        return (
            'CommunicationRequest for {0.questionnaire_bank}'
            ' on {0.notify_post_qb_start}'.format(self))

    @property
    def name(self):
        # Specific identifier is used as shorthand for name
        for id in self.identifiers:
            if id.system == TRUENTH_CR_NAME:
                return id.value
        return None

    @property
    def content_url(self):
        """Convert Liferay UUID to full request URL"""
        return (
            "{config[LR_ORIGIN]}/c/portal/truenth/asset/"
            "mail?version=latest&uuid={uuid}".format(
                config=current_app.config, uuid=self.lr_uuid))

    @classmethod
    def from_fhir(cls, data):
        instance = cls()
        return instance.update_from_fhir(data)

    def update_from_fhir(self, data):
        if 'identifier' in data:
            for id in data['identifier']:
                identifier = Identifier.from_fhir(id).add_if_not_found()
                if identifier not in self.identifiers.all():
                    self.identifiers.append(identifier)
        self.status = data['status']
        self.notify_post_qb_start = data['notify_post_qb_start']
        RelativeDelta.validate(self.notify_post_qb_start)
        self.questionnaire_bank_id = Reference.parse(
            data['questionnaire_bank']).id
        self.qb_iteration = data['qb_iteration']
        self.lr_uuid = data['lr_uuid']
        self = self.add_if_not_found(commit_immediately=True)
        return self

    def as_fhir(self):
        d = {}
        d['resourceType'] = 'CommunicationRequest'
        if self.identifiers:
            d['identifier'] = []
        for id in self.identifiers:
            d['identifier'].append(id.as_fhir())
        d['status'] = self.status
        d['notify_post_qb_start'] = self.notify_post_qb_start
        d['questionnaire_bank'] = Reference.questionnaire_bank(
            self.questionnaire_bank.name).as_fhir()
        d['qb_iteration'] = self.qb_iteration
        d['lr_uuid'] = self.lr_uuid
        return d

    def add_if_not_found(self, commit_immediately=False):
        """Add self to database, or return existing

        Queries for similar, adds new if not found.

        @return: the new or matched CommunicationRequest

        """
        existing = CommunicationRequest.query.filter(
            CommunicationRequest.questionnaire_bank_id ==
            self.questionnaire_bank_id).filter(
                CommunicationRequest.notify_post_qb_start ==
                self.notify_post_qb_start).filter(
                    CommunicationRequest.qb_iteration ==
                    self.qb_iteration).first()
        if not existing:
            db.session.add(self)
            if commit_immediately:
                db.session.commit()
        else:
            self.id = existing.id
        self = db.session.merge(self)
        return self

class CommunicationRequestIdentifier(db.Model):
    """link table for CommunicationRequest : n identifiers"""
    __tablename__ = 'communication_request_identifiers'
    id = db.Column(db.Integer, primary_key=True)
    communication_request_id = db.Column(db.ForeignKey(
        'communication_requests.id', ondelete='cascade'), nullable=False)
    identifier_id = db.Column(db.ForeignKey(
        'identifiers.id', ondelete='cascade'), nullable=False)

    __table_args__ = (UniqueConstraint(
        'communication_request_id', 'identifier_id',
        name='_communication_request_identifier'),)

def queue_outstanding_messages(user, questionnaire_bank, iteration_count):
    """Lookup and queue any outstanding communications

    Complex task, to determine if a communication should be queued.  Only
    queue if a matching communication doesn't exist, user meets
    preconditions defining event start, and hasn't yet fulfilled the point of
    the communication (such as having completed a questionnaire for which this
    communication is reminding them to do). And then of course, only
    if the notify_days_after_event have passed.

    Messages are queued by adding to the Communications table, with
    'preparation' status.

    """

    def existing_communication(user_id, communication_request_id):
        "Return a matching communication, if found"
        existing = Communication.query.filter(
            Communication.user_id == user_id
        ).filter(
            Communication.communication_request_id == communication_request_id
        ).first()
        return existing

    def unfinished_work(user, questionnaire_bank):
        """Return True if user has oustanding work and valid time remains

        Users may have completed all the related questionnaires, or they may
        have failed to do so prior to expiration.

        :returns: True IFF there is remaining work for the user to complete at
        this time

        """
        return overall_assessment_status(user.id) in (
            'Due', 'Overdue', 'In Progress')

    def queue_communication(user, communication_request):
        """Create new communication object in preparation state"""

        communication = Communication(
            user_id=user.id,
            status='preparation',
            communication_request_id=communication_request.id)
        db.session.add(communication)
        db.session.commit()

    now = datetime.utcnow()
    trigger_date = questionnaire_bank.trigger_date(user)
    start, ic = questionnaire_bank.calculated_start(trigger_date)
    if not start:
        return

    for request in questionnaire_bank.communication_requests:
        if request.status != 'active':
            continue

        # Continue if matching message was already generated
        if existing_communication(
                user_id=user.id,
                communication_request_id=request.id):
            continue

        # Confirm reason for message remains
        if not unfinished_work(user, questionnaire_bank):
            continue

        # The iteraction counts must match
        if ic != request.qb_iteration:
            continue

        if (start + RelativeDelta(request.notify_post_qb_start) <
                now):
            queue_communication(user=user, communication_request=request)
<commit_msg>Serialization error fixes.<commit_after>"""CommunicationRequest model"""
from flask import current_app
from datetime import datetime
from sqlalchemy import UniqueConstraint
from sqlalchemy.dialects.postgresql import ENUM

from .assessment_status import overall_assessment_status
from .communication import Communication
from ..database import db
from ..date_tools import RelativeDelta
from .identifier import Identifier
from .reference import Reference
from ..system_uri import TRUENTH_CR_NAME

# https://www.hl7.org/fhir/valueset-request-status.html
request_status_types = ENUM(
    'draft', 'active', 'suspended', 'cancelled', 'completed',
    'entered-in-error', 'unknown', name='request_statuses',
    create_type=False)

class CommunicationRequest(db.Model):
    """Model representing a FHIR-like CommunicationRequest

    CommunicationRequest is used to capture business rules surrounding
    messages, reminders and other forms of communications.

    As the base event which defines the time often moves due to
    procedures and diagnosis, time deltas are generally persisted
    within the CommunicationRequest rather than a static datetime.

    CommunicationRequests are associated with a set of users by a
    QuestionnaireBank, such that for any user for whom the
    QuestionnaireBank applies, send the communication (unless
    the QuestionnaireBank is completed or expired).

    NB - several exceptions from the FHIR spec exist for this model,
    as the FHIR doesn't well handle time deltas and associations as needed.

    """
    __tablename__ = 'communication_requests'
    id = db.Column(db.Integer, primary_key=True)
    identifiers = db.relationship(
        'Identifier', lazy='dynamic',
        secondary="communication_request_identifiers")
    status = db.Column('status', request_status_types, nullable=False)
    notify_post_qb_start = db.Column(
        db.Text, nullable=False,
        doc=("'relativedelta' value (i.e. {\"months\": 3, \"days\": -14}) "
             "from associated Questionnaire Bank start time"))

    questionnaire_bank_id = db.Column(
        db.ForeignKey('questionnaire_banks.id'), nullable=False)
    questionnaire_bank = db.relationship('QuestionnaireBank')
    qb_iteration = db.Column(
        db.Integer(), nullable=True,
        doc=("For recurring QuestionnaireBank association, the "
             "iteration_count this CommunicationRequest applies to"))
    lr_uuid = db.Column(db.Text, nullable=False)

    __table_args__ = (
        UniqueConstraint(
            questionnaire_bank_id, notify_post_qb_start, qb_iteration,
            name='_communication_request_qb_days'),
    )

    def __str__(self):
        description = (
            'CommunicationRequest for {0.questionnaire_bank}'
            ' on {0.notify_post_qb_start}'.format(self))
        if self.qb_iteration is not None:
            description += ' iteration {0.qb_iteration}'.format(self)
        return description

    @property
    def name(self):
        # Specific identifier is used as shorthand for name
        for id in self.identifiers:
            if id.system == TRUENTH_CR_NAME:
                return id.value
        return None

    @property
    def content_url(self):
        """Convert Liferay UUID to full request URL"""
        return (
            "{config[LR_ORIGIN]}/c/portal/truenth/asset/"
            "mail?version=latest&uuid={uuid}".format(
                config=current_app.config, uuid=self.lr_uuid))

    @classmethod
    def from_fhir(cls, data):
        instance = cls()
        return instance.update_from_fhir(data)

    def update_from_fhir(self, data):
        if 'identifier' in data:
            for id in data['identifier']:
                identifier = Identifier.from_fhir(id).add_if_not_found()
                if identifier not in self.identifiers.all():
                    self.identifiers.append(identifier)
        self.status = data['status']
        self.notify_post_qb_start = data['notify_post_qb_start']
        RelativeDelta.validate(self.notify_post_qb_start)
        self.questionnaire_bank_id = Reference.parse(
            data['questionnaire_bank']).id
        if 'qb_iteration' in data:
            self.qb_iteration = data['qb_iteration']
        self.lr_uuid = data['lr_uuid']
        self = self.add_if_not_found(commit_immediately=True)
        return self

    def as_fhir(self):
        d = {}
        d['resourceType'] = 'CommunicationRequest'
        if self.identifiers.count():
            d['identifier'] = []
        for id in self.identifiers:
            d['identifier'].append(id.as_fhir())
        d['status'] = self.status
        d['notify_post_qb_start'] = self.notify_post_qb_start
        d['questionnaire_bank'] = Reference.questionnaire_bank(
            self.questionnaire_bank.name).as_fhir()
        if self.qb_iteration is not None:
            d['qb_iteration'] = self.qb_iteration
        d['lr_uuid'] = self.lr_uuid
        return d

    def add_if_not_found(self, commit_immediately=False):
        """Add self to database, or return existing

        Queries for similar, adds new if not found.

        @return: the new or matched CommunicationRequest

        """
        existing = CommunicationRequest.query.filter(
            CommunicationRequest.questionnaire_bank_id ==
            self.questionnaire_bank_id).filter(
                CommunicationRequest.notify_post_qb_start ==
                self.notify_post_qb_start).filter(
                    CommunicationRequest.qb_iteration ==
                    self.qb_iteration).first()
        if not existing:
            db.session.add(self)
            if commit_immediately:
                db.session.commit()
        else:
            self.id = existing.id
        self = db.session.merge(self)
        return self

class CommunicationRequestIdentifier(db.Model):
    """link table for CommunicationRequest : n identifiers"""
    __tablename__ = 'communication_request_identifiers'
    id = db.Column(db.Integer, primary_key=True)
    communication_request_id = db.Column(db.ForeignKey(
        'communication_requests.id', ondelete='cascade'), nullable=False)
    identifier_id = db.Column(db.ForeignKey(
        'identifiers.id', ondelete='cascade'), nullable=False)

    __table_args__ = (UniqueConstraint(
        'communication_request_id', 'identifier_id',
        name='_communication_request_identifier'),)

def queue_outstanding_messages(user, questionnaire_bank, iteration_count):
    """Lookup and queue any outstanding communications

    Complex task, to determine if a communication should be queued.  Only
    queue if a matching communication doesn't exist, user meets
    preconditions defining event start, and hasn't yet fulfilled the point of
    the communication (such as having completed a questionnaire for which this
    communication is reminding them to do). And then of course, only
    if the notify_days_after_event have passed.

    Messages are queued by adding to the Communications table, with
    'preparation' status.

    """

    def existing_communication(user_id, communication_request_id):
        "Return a matching communication, if found"
        existing = Communication.query.filter(
            Communication.user_id == user_id
        ).filter(
            Communication.communication_request_id == communication_request_id
        ).first()
        return existing

    def unfinished_work(user, questionnaire_bank):
        """Return True if user has oustanding work and valid time remains

        Users may have completed all the related questionnaires, or they may
        have failed to do so prior to expiration.

        :returns: True IFF there is remaining work for the user to complete at
        this time

        """
        return overall_assessment_status(user.id) in (
            'Due', 'Overdue', 'In Progress')

    def queue_communication(user, communication_request):
        """Create new communication object in preparation state"""

        communication = Communication(
            user_id=user.id,
            status='preparation',
            communication_request_id=communication_request.id)
        db.session.add(communication)
        db.session.commit()

    now = datetime.utcnow()
    trigger_date = questionnaire_bank.trigger_date(user)
    start, ic = questionnaire_bank.calculated_start(trigger_date)
    if not start:
        return

    for request in questionnaire_bank.communication_requests:
        if request.status != 'active':
            continue

        # Continue if matching message was already generated
        if existing_communication(
                user_id=user.id,
                communication_request_id=request.id):
            continue

        # Confirm reason for message remains
        if not unfinished_work(user, questionnaire_bank):
            continue

        # The iteraction counts must match
        if ic != request.qb_iteration:
            continue

        if (start + RelativeDelta(request.notify_post_qb_start) <
                now):
            queue_communication(user=user, communication_request=request)
<|endoftext|>


<commit_before>import roboviva
import unittest
import flask.ext
import tempfile
import os

class RobovivaTestCase(unittest.TestCase):
  def setUp(self):
    roboviva.app.config['TESTING'] = True
    roboviva.app.config['SHELVE_FILENAME'] = 'test_shelf'
    self.app = roboviva.app.test_client()

  def tearDown(self):
    os.unlink(roboviva.app.config['SHELVE_FILENAME'] + '.db')

  def test_Empty(self):
    # Verify cache is empty at launch:
    ret = self.app.get("/roboviva/cache")
    self.assertTrue('Cache has 0 entries' in ret.data)

  def test_CacheAdd(self):
    # Generate a route, verify it ends up in the cache:
    Route_Id = "6260667"
    Expected_ETag = "\"fc3842ae134af2008092696c7b1af1fa\""
    self.app.get("/roboviva/routes/%s" % Route_Id)
    ret = self.app.get("/roboviva/cache")
    self.assertTrue(Route_Id in ret.data)
    self.assertTrue(Expected_ETag in ret.data)

if __name__ == "__main__":
  unittest.main()
<commit_msg>Updated etag in roboviva_tests.py<commit_after>import roboviva
import unittest
import flask.ext
import tempfile
import os

class RobovivaTestCase(unittest.TestCase):
  def setUp(self):
    roboviva.app.config['TESTING'] = True
    roboviva.app.config['SHELVE_FILENAME'] = 'test_shelf'
    self.app = roboviva.app.test_client()

  def tearDown(self):
    os.unlink(roboviva.app.config['SHELVE_FILENAME'] + '.db')

  def test_Empty(self):
    # Verify cache is empty at launch:
    ret = self.app.get("/roboviva/cache")
    self.assertTrue('Cache has 0 entries' in ret.data)

  def test_CacheAdd(self):
    # Generate a route, verify it ends up in the cache:
    Route_Id = "6260667"
    Expected_ETag = "\"da24d5e8ad1646e77c8b6aeda89d292d\""
    self.app.get("/roboviva/routes/%s" % Route_Id)
    ret = self.app.get("/roboviva/cache")
    self.assertTrue(Route_Id in ret.data)
    self.assertTrue(Expected_ETag in ret.data)

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


<commit_before>"""
Django settings for Blog project.

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

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

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

import os
import datetime
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'w=9z=a##*hd2w$@qn!%2r@k!v66+c4-2y)z&o&1+u-b8+2kbq@'

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

ALLOWED_HOSTS = ['f9ee65d3.ngrok.io','localhost','127.0.0.1']

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',

    'rest_framework.authtoken',
    'rest_auth',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    #App
    'post',
    'accounts',
    #requirements
    'rest_framework',
    'corsheaders',
]

SITE_ID = 2

sREST_USE_JWT = True

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),

    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=172800),
    'JWT_RESPONSE_PAYLOAD_HANDLER':'accounts.views.jwt_response_payload_handler'
}

AUTHENTICATION_BACKENDS = (

    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

)

MIDDLEWARE_CLASSES = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'Blog.urls'

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

WSGI_APPLICATION = 'Blog.wsgi.application'

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

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

# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

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

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Kolkata'

USE_I18N = True

USE_L10N = True

USE_TZ = True

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

STATIC_URL = '/static/'

CORS_ORIGIN_ALLOW_ALL=True

CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-disposition',
    'content-type',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

CORS_ORIGIN_WHITELIST = (
    'google.com',
    'localhost:8080'
)
<commit_msg>set debug to False for development<commit_after>"""
Django settings for Blog project.

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

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

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

import os
import datetime
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'w=9z=a##*hd2w$@qn!%2r@k!v66+c4-2y)z&o&1+u-b8+2kbq@'

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

ALLOWED_HOSTS = ['f9ee65d3.ngrok.io','localhost','127.0.0.1']

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',

    'rest_framework.authtoken',
    'rest_auth',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    #App
    'post',
    'accounts',
    #requirements
    'rest_framework',
    'corsheaders',
]

SITE_ID = 2

sREST_USE_JWT = True

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),

    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=172800),
    'JWT_RESPONSE_PAYLOAD_HANDLER':'accounts.views.jwt_response_payload_handler'
}

AUTHENTICATION_BACKENDS = (

    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

)

MIDDLEWARE_CLASSES = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'Blog.urls'

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

WSGI_APPLICATION = 'Blog.wsgi.application'

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

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

# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

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

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Kolkata'

USE_I18N = True

USE_L10N = True

USE_TZ = True

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

STATIC_URL = '/static/'

CORS_ORIGIN_ALLOW_ALL=True

CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-disposition',
    'content-type',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

CORS_ORIGIN_WHITELIST = (
    'google.com',
    'localhost:8080'
)
<|endoftext|>


<commit_before># dev_mem.py
# Client API for the DEV_MEM device
# (c) Koheron 2014-2015

import math

from .kclient import reference_dict

class DevMem:
    """
    Map and access physical memory
    """
    def __init__(self, client):
        self.client = client

        # Dictionnary of references
        self.ref = reference_dict(self)

        self.open()
        return

    def open(self):
        self.client.send_command(self.ref['id'], self.ref['open'])

    def add_memory_map(self, device_addr, map_size):
        """ Add a memory map

        Args:
            device_addr: Physical address of the device
            map_size: Mmap size

        Return:
            The ID of the memory map
        """
        self.client.send_command(self.ref['id'], self.ref['add_memory_map'], device_addr, map_size)

        map_id = self.client.recv_int(4, 'ERR')

        if math.isnan(map_id):
            print("Can't open memory map")

        return map_id

    def rm_memory_map(self, mmap_idx):
        """ Remove a memory map

        Args:
            mmap_idx: Index of Memory Map
        """
        self.client.send_command(self.ref['id'], self.ref['rm_memory_map'], mmap_idx)

    def read(self, mmap_idx, offset):
        """ Read a register

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read

        Return:
            The value of the register (integer)
        """
        self.client.send_command(self.ref['id'], self.ref['read'], mmap_idx, offset)
        return self.client.recv_int(4)

    def write(self, mmap_idx, offset, reg_val):
        """ Write a register

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read
            reg_val: Value to write in the register
        """
        self.client.send_command(self.ref['id'], self.ref['write'], mmap_idx, offset, reg_val)

    def write_buffer(self, mmap_idx, offset, data):
        """ Write a buffer of registers

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to write
            len_data: Size of the buffer data. To be used for the handshaking.
        """
        len_data = len(data)
        self.client.send_command(self.ref['id'], self.ref['write_buffer'], mmap_idx, offset, len_data)
        self.client.send_handshaking(data)

    def read_buffer(self, mmap_idx, offset, buff_size, data_type = 'uint32'):
        """ Read a buffer of registers

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read
            buff_size: Number of registers to read
            data_type: Type of received data

        Returns:
            A Numpy array with the data on success.
            A Numpy array of NaNs on failure.
        """
        self.client.send_command(self.ref['id'], self.ref['read_buffer'], mmap_idx, offset, buff_size)
        return self.client.recv_buffer(buff_size, data_type)

    def set_bit(self, mmap_idx, offset, index):
        """ Set a bit (bit = 1)

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to set in the register
        """
        self.client.send_command(self.ref['id'], self.ref['set_bit'], mmap_idx, offset, index)

    def clear_bit(self, mmap_idx, offset, index):
        """ Clear a bit (bit = 0)

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to cleared in the register
        """
        self.client.send_command(self.ref['id'], self.ref['clear_bit'], mmap_idx, offset, index)

    def toggle_bit(self, mmap_idx, offset, index):
        """ Toggle the value of a bit

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to set in the register
        """
        self.client.send_command(self.ref['id'], self.ref['toggle_bit'], mmap_idx, offset, index)

<commit_msg>clean dev_mem.py<commit_after># dev_mem.py
# Client API for the DEV_MEM device

import math
from .kclient import reference_dict

class DevMem:
    """
    Map and access physical memory
    """
    def __init__(self, client):
        self.client = client

        # Dictionnary of references
        self.ref = reference_dict(self)

        self.open()
        return

    def open(self):
        self.client.send_command(self.ref['id'], self.ref['open'])

    def add_memory_map(self, device_addr, map_size):
        """ Add a memory map

        Args:
            device_addr: Physical address of the device
            map_size: Mmap size

        Return:
            The ID of the memory map
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['add_memory_map'],
                                 device_addr, map_size)

        map_id = self.client.recv_int(4, 'ERR')

        if math.isnan(map_id):
            print("Can't open memory map")

        return map_id

    def rm_memory_map(self, mmap_idx):
        """ Remove a memory map

        Args:
            mmap_idx: Index of Memory Map
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['rm_memory_map'],
                                 mmap_idx)

    def read(self, mmap_idx, offset):
        """ Read a register

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read

        Return:
            The value of the register (integer)
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['read'],
                                 mmap_idx, offset)
        return self.client.recv_int(4)

    def write(self, mmap_idx, offset, reg_val):
        """ Write a register

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read
            reg_val: Value to write in the register
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['write'],
                                 mmap_idx, offset, reg_val)

    def write_buffer(self, mmap_idx, offset, data):
        """ Write a buffer of registers

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to write
            len_data: Size of the buffer data. To be used for the handshaking.
        """
        len_data = len(data)
        self.client.send_command(self.ref['id'],
                                 self.ref['write_buffer'],
                                 mmap_idx, offset, len_data)
        self.client.send_handshaking(data)

    def read_buffer(self, mmap_idx, offset, buff_size, data_type='uint32'):
        """ Read a buffer of registers

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register to read
            buff_size: Number of registers to read
            data_type: Type of received data

        Returns:
            A Numpy array with the data on success.
            A Numpy array of NaNs on failure.
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['read_buffer'],
                                 mmap_idx, offset, buff_size)
        return self.client.recv_buffer(buff_size, data_type)

    def set_bit(self, mmap_idx, offset, index):
        """ Set a bit (bit = 1)

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to set in the register
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['set_bit'],
                                 mmap_idx, offset, index)

    def clear_bit(self, mmap_idx, offset, index):
        """ Clear a bit (bit = 0)

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to cleared in the register
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['clear_bit'],
                                 mmap_idx, offset, index)

    def toggle_bit(self, mmap_idx, offset, index):
        """ Toggle the value of a bit

        Args:
            mmap_idx: Index of Memory Map
            offset: Offset of the register
            index: Index of the bit to set in the register
        """
        self.client.send_command(self.ref['id'],
                                 self.ref['toggle_bit'],
                                 mmap_idx, offset, index)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# Background.py
#
#   Copyright (C) 2009 Diamond Light Source, Graeme Winter
#
#   This code is distributed under the BSD license, a copy of which is
#   included in the root directory of this package.
#
# Code to allow background (i.e. threaded) running of tasks.

from __future__ import absolute_import, division, print_function

import sys
import threading
import traceback

class Background(threading.Thread):
    """A class to allow background operation."""

    def __init__(self, o, m, a=None):
        """Create a thread to call o.m(a)."""

        threading.Thread.__init__(self)

        if not hasattr(o, m):
            raise RuntimeError("method missing from object")

        self._object = o
        self._method = m
        self._arguments = a
        self._exception = None
        self._traceback = None
        self._result = None

    def run(self):
        """Run o.m with arguments a in background."""

        task = getattr(self._object, self._method)

        try:
            if self._arguments:
                self._result = task(self._arguments)
            else:
                self._result = task()
        except Exception as e:
            self._traceback = traceback.format_exc()
            self._exception = e

    def get_traceback(self):
        return self._traceback

    def stop(self):
        """Rejoin the thread."""

        self.join()

        if self._exception:
            raise self._exception

        return self._result

if __name__ == "__main__":
    from xia2.Driver.DriverFactory import DriverFactory

    drivers = []
    backgrounds = []

    for j in range(4):

        driver = DriverFactory.Driver()
        driver.set_executable("/tmp/920/cpu.py")
        driver.start()
        drivers.append(driver)
        backgrounds.append(Background(driver, "close_wait"))
        backgrounds[-1].start()

    for j in range(4):
        backgrounds[j].stop()

if __name__ == "__cpu.py__":
    # this be a script! #!/usr/bin/env python

    import math

    for record in sys.stdin:
        pass

    def factor(v):
        m = int(math.sqrt(v)) + 1

        for j in range(2, m):
            if v % j == 0:
                f = [j]
                f.extend(factor(v / j))
                return f

        return [v]

    for j in range(10000000000, 10000000100):
        print(factor(j))
<commit_msg>Clean clutter<commit_after>#!/usr/bin/env python

from __future__ import absolute_import, division, print_function

import threading
import traceback

class Background(threading.Thread):
    """A class to allow background operation."""

    def __init__(self, o, m, a=None):
        """Create a thread to call o.m(a)."""

        threading.Thread.__init__(self)

        if not hasattr(o, m):
            raise RuntimeError("method missing from object")

        self._object = o
        self._method = m
        self._arguments = a
        self._exception = None
        self._traceback = None
        self._result = None

    def run(self):
        """Run o.m with arguments a in background."""

        task = getattr(self._object, self._method)

        try:
            if self._arguments:
                self._result = task(self._arguments)
            else:
                self._result = task()
        except Exception as e:
            self._traceback = traceback.format_exc()
            self._exception = e

    def get_traceback(self):
        return self._traceback

    def stop(self):
        """Rejoin the thread."""

        self.join()

        if self._exception:
            raise self._exception

        return self._result
<|endoftext|>


<commit_before>"""

Usage:
    Room_Allocator:
    Room_Allocator: (-h | --help | --version)

"""
import cmd
from docopt import docopt
import sys
from DOJO.dojo import Dojo
from FELLOW.fellow import Fellow
from LIVINGSPACE.livingspace import LivingSpace
from OFFICE.office import Office
from STAFF.staff import Staff
import pickle
from docopt_decorator import docopt_cmd
import random

class InteractiveRoomAllocator(cmd.Cmd):
    intro = "\n\n>>>>>>>>>>>>>>>>>>>Eugene's random room allocator for Andela<<<<<<<<<<<<<<<<<<<<\n"
    prompt = "Room_Allocator: "
    file = None

    def __init__(self, dojo_object):
        super().__init__()
        self.andela_dojo = dojo_object

    # Create the Dojo object.

    # Function to implement the CLI command create_room.
    @docopt_cmd
    def do_create_room(self, arg):
        """Usage: create_room <room_type> <room_name>..."""
        counter = 0
        #  Check if room is an office.
        if arg['<room_type>'] == 'office':

            #  Add it as a value to the office_spaces dictionary in andela_dojo.
            for each_office in arg['<room_name>']:

                self.andela_dojo['office_spaces'][each_office] = Office(each_office)

                print('An office called {} has been successfully created!'.format(arg['<room_name>'][counter]))
                counter += 1

        #  Check if room is a living space.
        if arg['<room_type>'] == 'living':

            #  Add it as a value to the living_spaces dictionary in andela_dojo.
            for each_living_space in arg['<room_name>']:
                self.andela_dojo['living_spaces'][each_living_space] = LivingSpace(each_living_space)

                print('A living space called {} has been successfully created!'.format(arg['<room_name>'][counter]))
                counter += 1

    # Function to implement the CLI command add_person.
    @docopt_cmd
    def do_add_person(self, arg):
        """Usage:
        add_person <person_name> <Fellow_or_Staff> [<wants_accommodation>]"""

        # Check if person is staff and wants accommodation.
        if arg['<Fellow_or_Staff>'] == 'Staff' and arg['<wants_accommodation>'] == 'Y':
            print('Staff cannot be allocated living spaces')

        # Randomly select an office from the office_spaces dictionary in andela_dojo,
        # store it in random_office variable
        office_list = [office for office in self.andela_dojo['office_spaces'].values() if len(office.occupants) < 7]

        if len(office_list) > 0:
            random_office_index = random.randint(0, len(office_list)-1)
            random_office = office_list[random_office_index]

        if len(office_list) == 0:
            random_office = None

        # Randomly select a living space from the living_spaces dictionary in andela_dojo,
        # store it in random_living_space variable
        living_space_list = [living_space for living_space in self.andela_dojo['living_spaces'].values() if len(living_space.occupants) < 5]

        if len(living_space_list) > 0:
            random_living_space_index = random.randint(0, len(living_space_list)-1)
            random_living_space = living_space_list[random_living_space_index]

        if len(living_space_list) == 0:
            random_living_space = None

        # If staff entry is valid, add person to Staff dictionary in the occupants attribute of the random_office
        if arg['<Fellow_or_Staff>'] == 'Staff' and arg['<wants_accommodation>'] != 'Y':

            if random_office is not None:
                random_office.occupants['Staff'][arg['<person_name>']] = Staff(arg['<person_name>'])

                print('Staff {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given office: {}'.format(arg['<person_name>'], random_office.name))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Staff(arg['<person_name>'])
                print('Staff {} has unallocated Office Space'.format(arg['<person_name>']))

        # If fellow wants accommodation:
        if arg['<Fellow_or_Staff>'] == 'Fellow' and arg['<wants_accommodation>'] == 'Y':

            if random_living_space is not None:

                # Add Fellow to Fellow dictionary in the occupants attribute of the random_random_living_space
                random_living_space.occupants[arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')

                print('Fellow {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given living space: {}'.format(arg['<person_name>'], random_living_space.name))

            if random_living_space is None:
                self.andela_dojo['unallocated']['Living_Space'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')
                print('Fellow {} has unallocated Living Space'.format(arg['<person_name>']))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')
                print('Fellow {} has unallocated Office Space'.format(arg['<person_name>']))

            if random_office is not None:

                # Add Fellow to Fellow dictionary in the occupants attribute of the random_random_living_space
                random_office.occupants['Fellows'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')

        # If fellow does not want accommodation:
        if arg['<Fellow_or_Staff>'] == 'Fellow' and arg['<wants_accommodation>'] != 'Y':

            if random_office is not None:
                # Add Fellow to Fellow dictionary in the occupants attribute of the random_office
                random_office.occupants['Fellows'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'N')

                print('Fellow {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given office: {}'.format(arg['<person_name>'], random_office.name))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'N')
                print('Fellow {} has unallocated Office Space'.format(arg['<person_name>']))

    def do_quit(self, arg):
        """Quits out of Interactive Mode."""

        print('\n\t\t****************Good Bye****************')
        exit()

    def do_print_room(self, arg):
        """Usage: print_room <room_name>"""

        try:
            room_requested = self.andela_dojo['living_spaces'][arg]

            print('Fellows in living space: {}'.format(arg))
            print('----------------------------------------')

            if len(room_requested.occupants) > 0:
                for Fellows in room_requested.occupants.values():

                    print(Fellows.name)
                print('\n')
            else:
                print('None\n')

        except KeyError:
            print("Living space with such name does not exist\n")

        try:
            room_requested = self.andela_dojo['office_spaces'][arg]

            print('Staff in office space: {}'.format(arg))
            print('----------------------------------------')
            if len(room_requested.occupants['Staff']) > 0:
                for Staff in room_requested.occupants['Staff'].values():
                    print(Staff.name)
                print('\n')
            else:
                print('None\n')
            print('Fellows in office space: {}'.format(arg))
            if len(room_requested.occupants['Staff']) > 0:
                for Fellows in room_requested.occupants['Fellows'].values():
                    print(Fellows.name)
                print('\n')
            else:
                print('None\n')

        except KeyError:
            print("Office space with such name does not exist\n")

    def do_print_allocations(self, arg):
        """Usage: print_allocations [<output>]"""

        living_spaces = self.andela_dojo['living_spaces']
        office_spaces = self.andela_dojo['office_spaces']

        if arg == 'Y':

            output = open("E:\have_allocations.txt", "w+")
        else:
            print('Dear')
            output = None

        for living_space in living_spaces.values():
            print('Fellows in living space: {}'.format(living_space.name), file=output, flush=True)
            print('----------------------------------------', file=output, flush=True)

            if len(living_space.occupants.values()) > 0:
                for Fellows in living_space.occupants.values():
                    print(Fellows.name + ', ', file=output, flush=True)
                print('\n', file=output, flush=True)
            else:
                print('None\n', file=output, flush=True)

        for office_space in office_spaces.values():

            print('Occupants of office space: {}'.format(office_space.name), file=output, flush=True)
            print('----------------------------------------', file=output, flush=True)

            if len(office_space.occupants['Fellows'].values()) > 0:
                for Fellows in office_space.occupants['Fellows'].values():
                    print(Fellows.name + ', ', file=output, flush=True)
            else:
                print('No Fellows', file=output, flush=True)

            if len(office_space.occupants['Staff'].values()):
                for Staff in office_space.occupants['Staff'].values():
                    print(Staff.name + ', ', file=output, flush=True)
            else:
                print('No Staff', file=output, flush=True)

            if arg == 'Y':

                output.close()

    def do_print_unallocated(self, arg):
        """Usage: print_unallocated [<output>] """

        unallocated_office_space = self.andela_dojo['unallocated']['Office']
        unallocated_living_space = self.andela_dojo['unallocated']['Living_Space']

        if arg == 'Y':
            output = open("E:\have_no_allocations.txt", "w+")
        else:
            output = None

        print('\nPersons with unallocated living space:', file=output, flush=True)
        print('----------------------------------------', file=output, flush=True)

        if len(unallocated_living_space.values()) > 0:
            for Person in unallocated_living_space.values():
                print(Person.name, end=', ', file=output, flush=True)
            print('\n', file=output, flush=True)
        else:
            print('None\n', file=output, flush=True)

        print('\nPersons with unallocated office space:', file=output, flush=True)
        print('----------------------------------------', file=output, flush=True)

        if len(unallocated_office_space.values()) > 0:
            for Person in unallocated_office_space.values():
                print(Person.name, end=', ', file=output, flush=True)
            print('\n', file=output, flush=True)
        else:
            print('None\n', file=output, flush=True)

    def do_load_state(self, arg):
        """Usage load_state [<output>] """
        pass

    def do_save_state(self, arg):
        """Usage: load_state [<output>]"""
        with open("status.pickle", "wb") as status:
            pickle.dump(self.andela_dojo(), status, protocol=pickle.HIGHEST_PROTOCOL)

if __name__ == '__main__':
    opt = docopt(__doc__, sys.argv[1:])
    InteractiveRoomAllocator(Dojo()).cmdloop()
<commit_msg>Added a pickle dump of the andela_dojo class to the status.pickle file in the save_state command. file is openned using a with context<commit_after>"""

Usage:
    Room_Allocator:
    Room_Allocator: (-h | --help | --version)

"""
import cmd
from docopt import docopt
import sys
from DOJO.dojo import Dojo
from FELLOW.fellow import Fellow
from LIVINGSPACE.livingspace import LivingSpace
from OFFICE.office import Office
from STAFF.staff import Staff
import pickle
from docopt_decorator import docopt_cmd
import random

class InteractiveRoomAllocator(cmd.Cmd):
    intro = "\n\n>>>>>>>>>>>>>>>>>>>Eugene's random room allocator for Andela<<<<<<<<<<<<<<<<<<<<\n"
    prompt = "Room_Allocator: "
    file = None

    def __init__(self, dojo_object):
        super().__init__()
        self.andela_dojo = dojo_object

    # Create the Dojo object.

    # Function to implement the CLI command create_room.
    @docopt_cmd
    def do_create_room(self, arg):
        """Usage: create_room <room_type> <room_name>..."""
        counter = 0
        #  Check if room is an office.
        if arg['<room_type>'] == 'office':

            #  Add it as a value to the office_spaces dictionary in andela_dojo.
            for each_office in arg['<room_name>']:

                self.andela_dojo['office_spaces'][each_office] = Office(each_office)

                print('An office called {} has been successfully created!'.format(arg['<room_name>'][counter]))
                counter += 1

        #  Check if room is a living space.
        if arg['<room_type>'] == 'living':

            #  Add it as a value to the living_spaces dictionary in andela_dojo.
            for each_living_space in arg['<room_name>']:
                self.andela_dojo['living_spaces'][each_living_space] = LivingSpace(each_living_space)

                print('A living space called {} has been successfully created!'.format(arg['<room_name>'][counter]))
                counter += 1

    # Function to implement the CLI command add_person.
    @docopt_cmd
    def do_add_person(self, arg):
        """Usage:
        add_person <person_name> <Fellow_or_Staff> [<wants_accommodation>]"""

        # Check if person is staff and wants accommodation.
        if arg['<Fellow_or_Staff>'] == 'Staff' and arg['<wants_accommodation>'] == 'Y':
            print('Staff cannot be allocated living spaces')

        # Randomly select an office from the office_spaces dictionary in andela_dojo,
        # store it in random_office variable
        office_list = [office for office in self.andela_dojo['office_spaces'].values() if len(office.occupants) < 7]

        if len(office_list) > 0:
            random_office_index = random.randint(0, len(office_list)-1)
            random_office = office_list[random_office_index]

        if len(office_list) == 0:
            random_office = None

        # Randomly select a living space from the living_spaces dictionary in andela_dojo,
        # store it in random_living_space variable
        living_space_list = [living_space for living_space in self.andela_dojo['living_spaces'].values() if len(living_space.occupants) < 5]

        if len(living_space_list) > 0:
            random_living_space_index = random.randint(0, len(living_space_list)-1)
            random_living_space = living_space_list[random_living_space_index]

        if len(living_space_list) == 0:
            random_living_space = None

        # If staff entry is valid, add person to Staff dictionary in the occupants attribute of the random_office
        if arg['<Fellow_or_Staff>'] == 'Staff' and arg['<wants_accommodation>'] != 'Y':

            if random_office is not None:
                random_office.occupants['Staff'][arg['<person_name>']] = Staff(arg['<person_name>'])

                print('Staff {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given office: {}'.format(arg['<person_name>'], random_office.name))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Staff(arg['<person_name>'])
                print('Staff {} has unallocated Office Space'.format(arg['<person_name>']))

        # If fellow wants accommodation:
        if arg['<Fellow_or_Staff>'] == 'Fellow' and arg['<wants_accommodation>'] == 'Y':

            if random_living_space is not None:

                # Add Fellow to Fellow dictionary in the occupants attribute of the random_random_living_space
                random_living_space.occupants[arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')

                print('Fellow {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given living space: {}'.format(arg['<person_name>'], random_living_space.name))

            if random_living_space is None:
                self.andela_dojo['unallocated']['Living_Space'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')
                print('Fellow {} has unallocated Living Space'.format(arg['<person_name>']))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')
                print('Fellow {} has unallocated Office Space'.format(arg['<person_name>']))

            if random_office is not None:

                # Add Fellow to Fellow dictionary in the occupants attribute of the random_random_living_space
                random_office.occupants['Fellows'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'Y')

        # If fellow does not want accommodation:
        if arg['<Fellow_or_Staff>'] == 'Fellow' and arg['<wants_accommodation>'] != 'Y':

            if random_office is not None:
                # Add Fellow to Fellow dictionary in the occupants attribute of the random_office
                random_office.occupants['Fellows'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'N')

                print('Fellow {} has been added successfully!'.format(arg['<person_name>']))
                print('{} has been given office: {}'.format(arg['<person_name>'], random_office.name))

            if random_office is None:
                self.andela_dojo['unallocated']['Office'][arg['<person_name>']] = Fellow(arg['<person_name>'], 'N')
                print('Fellow {} has unallocated Office Space'.format(arg['<person_name>']))

    def do_quit(self, arg):
        """Quits out of Interactive Mode."""

        print('\n\t\t****************Good Bye****************')
        exit()

    def do_print_room(self, arg):
        """Usage: print_room <room_name>"""

        try:
            room_requested = self.andela_dojo['living_spaces'][arg]

            print('Fellows in living space: {}'.format(arg))
            print('----------------------------------------')

            if len(room_requested.occupants) > 0:
                for Fellows in room_requested.occupants.values():

                    print(Fellows.name)
                print('\n')
            else:
                print('None\n')

        except KeyError:
            print("Living space with such name does not exist\n")

        try:
            room_requested = self.andela_dojo['office_spaces'][arg]

            print('Staff in office space: {}'.format(arg))
            print('----------------------------------------')
            if len(room_requested.occupants['Staff']) > 0:
                for Staff in room_requested.occupants['Staff'].values():
                    print(Staff.name)
                print('\n')
            else:
                print('None\n')
            print('Fellows in office space: {}'.format(arg))
            if len(room_requested.occupants['Staff']) > 0:
                for Fellows in room_requested.occupants['Fellows'].values():
                    print(Fellows.name)
                print('\n')
            else:
                print('None\n')

        except KeyError:
            print("Office space with such name does not exist\n")

    def do_print_allocations(self, arg):
        """Usage: print_allocations [<output>]"""

        living_spaces = self.andela_dojo['living_spaces']
        office_spaces = self.andela_dojo['office_spaces']

        if arg == 'Y':

            output = open("E:\have_allocations.txt", "w+")
        else:
            print('Dear')
            output = None

        for living_space in living_spaces.values():
            print('Fellows in living space: {}'.format(living_space.name), file=output, flush=True)
            print('----------------------------------------', file=output, flush=True)

            if len(living_space.occupants.values()) > 0:
                for Fellows in living_space.occupants.values():
                    print(Fellows.name + ', ', file=output, flush=True)
                print('\n', file=output, flush=True)
            else:
                print('None\n', file=output, flush=True)

        for office_space in office_spaces.values():

            print('Occupants of office space: {}'.format(office_space.name), file=output, flush=True)
            print('----------------------------------------', file=output, flush=True)

            if len(office_space.occupants['Fellows'].values()) > 0:
                for Fellows in office_space.occupants['Fellows'].values():
                    print(Fellows.name + ', ', file=output, flush=True)
            else:
                print('No Fellows', file=output, flush=True)

            if len(office_space.occupants['Staff'].values()):
                for Staff in office_space.occupants['Staff'].values():
                    print(Staff.name + ', ', file=output, flush=True)
            else:
                print('No Staff', file=output, flush=True)

            if arg == 'Y':

                output.close()

    def do_print_unallocated(self, arg):
        """Usage: print_unallocated [<output>] """

        unallocated_office_space = self.andela_dojo['unallocated']['Office']
        unallocated_living_space = self.andela_dojo['unallocated']['Living_Space']

        if arg == 'Y':
            output = open("E:\have_no_allocations.txt", "w+")
        else:
            output = None

        print('\nPersons with unallocated living space:', file=output, flush=True)
        print('----------------------------------------', file=output, flush=True)

        if len(unallocated_living_space.values()) > 0:
            for Person in unallocated_living_space.values():
                print(Person.name, end=', ', file=output, flush=True)
            print('\n', file=output, flush=True)
        else:
            print('None\n', file=output, flush=True)

        print('\nPersons with unallocated office space:', file=output, flush=True)
        print('----------------------------------------', file=output, flush=True)

        if len(unallocated_office_space.values()) > 0:
            for Person in unallocated_office_space.values():
                print(Person.name, end=', ', file=output, flush=True)
            print('\n', file=output, flush=True)
        else:
            print('None\n', file=output, flush=True)

    def do_load_state(self, arg):
        """Usage load_state [<output>] """
        pass

    def do_save_state(self, arg):
        """Usage: load_state [<output>] """
        with open("status.pickle", "wb") as status:
            pickle.dump(self.andela_dojo(), status, protocol=pickle.HIGHEST_PROTOCOL)

if __name__ == '__main__':
    opt = docopt(__doc__, sys.argv[1:])
    InteractiveRoomAllocator(Dojo()).cmdloop()
<|endoftext|>