<commit_before>import numpy as np
import syft

__all__ = [
    'equal', 'TensorBase',
]

def _ensure_ndarray(arr):
    if not isinstance(arr, np.ndarray):
        arr = np.array(arr)

    return arr

def _ensure_tensorbase(tensor):
    if not isinstance(tensor, TensorBase):
        tensor = TensorBase(tensor)

    return tensor

def equal(tensor1, tensor2):
    """Checks if two tensors are equal.

    Two tensors are considered equal if they are the same size and contain the same elements.

    Assumption:
    tensor1 and tensor2 are of type TensorBase.
    Non-TensorBase objects will be converted to TensorBase objects.
    """

    tensor1 = _ensure_tensorbase(tensor1)
    tensor2 = _ensure_tensorbase(tensor2)

    if tensor1.encrypted or tensor2.encrypted:
        return NotImplemented

    return tensor1.data.shape == tensor2.data.shape and np.allclose(tensor1.data, tensor2.data)

class TensorBase(object):
    """
    A base tensor class that performs basic element-wise operation such as
    addition, subtraction, multiplication and division, and also dot and matrix products.
    """

    def __init__(self, arr_like, encrypted=False):
        self.data = _ensure_ndarray(arr_like)
        self.encrypted = encrypted

    def __add__(self, tensor):
        """Performs element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data + tensor.data)

    def __iadd__(self, tensor):
        """Performs in place element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data += tensor.data
        return self

    def __sub__(self, tensor):
        """Performs element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data - tensor.data)

    def __isub__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data -= tensor.data
        return self

    def __eq__(self, tensor):
        """Checks if two tensors are equal"""
        if self.encrypted:
            return NotImplemented

        return syft.equal(self, tensor)

    def dot(self, tensor):
        """Returns inner product of two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.dot(self, tensor)

    def __matmul__(self, tensor):
        """Performs matrix multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.matmul(self, tensor)

    def __mul__(self, tensor):
        """Performs element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data * tensor.data)

    def __imul__(self, tensor):
        """Performs in place element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data *= tensor.data
        return self

    def __truediv__(self, tensor):
        """Performs element-wise division between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data / tensor.data)

    def __itruediv__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data /= tensor.data
        return self

    def __getitem__(self, position):
        """Get value at a specific index."""
        if self.encrypted:
            return NotImplemented

        return TensorBase(self.data[position], self.encrypted)

    def abs(self):
        """Returns absolute value of tensor as a new tensor"""
        if self.encrypted:
            return NotImplemented
        return np.absolute(self.data)

    def abs_(self):
        """Replaces tensor values with its absolute value"""
        if self.encrypted:
            return NotImplemented
        self.data=np.absolute(self.data)
        return self.data

    def shape(self):
        """Returns a tuple of input array dimensions."""
        if self.encrypted:
            return NotImplemented

        return self.data.shape

    def dim(self):
        """Returns an integer of the number of dimensions of this tensor."""
        if self.encrypted:
            return NotImplemented

        return self.data.ndim

    def sum(self, dim=None):
        """Returns the sum of all elements in the input array."""
        if self.encrypted:
            return NotImplemented

        if dim is None:
            return self.data.sum()
        else:
            return self.data.sum(axis=dim)

  def ceil(self):
    """Returns the ceilling of the input tensor elementwise."""

        if self.encrypted:
            return NotImplemented
        return np.ceil(self.data)

    def addmm(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))

    def addmm_(self,tensor2,mat,beta=1,alpha=1):
        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
        """
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))
            return self

<commit_msg>Update tensor.py<commit_after>import numpy as np
import syft

__all__ = [
    'equal', 'TensorBase',
]

def _ensure_ndarray(arr):
    if not isinstance(arr, np.ndarray):
        arr = np.array(arr)

    return arr

def _ensure_tensorbase(tensor):
    if not isinstance(tensor, TensorBase):
        tensor = TensorBase(tensor)

    return tensor

def equal(tensor1, tensor2):
    """Checks if two tensors are equal.

    Two tensors are considered equal if they are the same size and contain the same elements.

    Assumption:
    tensor1 and tensor2 are of type TensorBase.
    Non-TensorBase objects will be converted to TensorBase objects.
    """

    tensor1 = _ensure_tensorbase(tensor1)
    tensor2 = _ensure_tensorbase(tensor2)

    if tensor1.encrypted or tensor2.encrypted:
        return NotImplemented

    return tensor1.data.shape == tensor2.data.shape and np.allclose(tensor1.data, tensor2.data)

class TensorBase(object):
    """
    A base tensor class that performs basic element-wise operation such as
    addition, subtraction, multiplication and division, and also dot and matrix products.
    """

    def __init__(self, arr_like, encrypted=False):
        self.data = _ensure_ndarray(arr_like)
        self.encrypted = encrypted

    def __add__(self, tensor):
        """Performs element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data + tensor.data)

    def __iadd__(self, tensor):
        """Performs in place element-wise addition between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data += tensor.data
        return self

    def __sub__(self, tensor):
        """Performs element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data - tensor.data)

    def __isub__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data -= tensor.data
        return self

    def __eq__(self, tensor):
        """Checks if two tensors are equal"""
        if self.encrypted:
            return NotImplemented

        return syft.equal(self, tensor)

    def dot(self, tensor):
        """Returns inner product of two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.dot(self, tensor)

    def __matmul__(self, tensor):
        """Performs matrix multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        return syft.matmul(self, tensor)

    def __mul__(self, tensor):
        """Performs element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data * tensor.data)

    def __imul__(self, tensor):
        """Performs in place element-wise multiplication between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data *= tensor.data
        return self

    def __truediv__(self, tensor):
        """Performs element-wise division between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        return TensorBase(self.data / tensor.data)

    def __itruediv__(self, tensor):
        """Performs in place element-wise subtraction between two tensors"""
        if self.encrypted:
            return NotImplemented

        tensor = _ensure_tensorbase(tensor)
        self.data /= tensor.data
        return self

    def __getitem__(self, position):
        """Get value at a specific index."""
        if self.encrypted:
            return NotImplemented

        return TensorBase(self.data[position], self.encrypted)

    def abs(self):
        """Returns absolute value of tensor as a new tensor"""
        if self.encrypted:
            return NotImplemented
        return np.absolute(self.data)

    def abs_(self):
        """Replaces tensor values with its absolute value"""
        if self.encrypted:
            return NotImplemented
        self.data=np.absolute(self.data)
        return self.data

    def shape(self):
        """Returns a tuple of input array dimensions."""
        if self.encrypted:
            return NotImplemented

        return self.data.shape

    def dim(self):
        """Returns an integer of the number of dimensions of this tensor."""
        if self.encrypted:
            return NotImplemented

        return self.data.ndim

    def sum(self, dim=None):
        """Returns the sum of all elements in the input array."""
        if self.encrypted:
            return NotImplemented

        if dim is None:
            return self.data.sum()
        else:
            return self.data.sum(axis=dim)

  def ceil(self):
    """Returns the ceilling of the input tensor elementwise."""

        if self.encrypted:
            return NotImplemented
        return np.ceil(self.data)

  def addmm(self, tensor2, mat, beta=1, alpha=1):
        """Performs ((Mat*Beta)+((Tensor1@Tensor2)*Alpha)) and  returns the result as a Tensor
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional, their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        return syft.addmm(self, tensor2, mat, beta, alpha)

    def addmm_(self, tensor2, mat, beta=1, alpha=1):
        """Performs ((Mat*Beta)+((Tensor1@Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
            *If both tensors are 1-dimensional,  their dot product is returned.
            *If both arguments are 2-D they are multiplied like conventional matrices.
            *If either argument is N-D,  N > 2,  it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
            *If the first argument is 1-D,  it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            *If the second argument is 1-D,  it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
            """
        _ensure_tensorbase(tensor2)
        _ensure_tensorbase(mat)
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data = np.array((np.matmul(self.data, tensor2.data)))
            self.data *= alpha
            mat.data *= beta
            self.data = self.data+mat.data
            return self

    def addcmul(self, tensor2, mat, value=1):
        """Performs the element-wise multiplication of tensor1 by tensor2,  multiply the result by the scalar value and add it to mat."""
        return syft.addcmul(self, tensor2, mat, value)

    def addcmul_(self, tensor2, mat, value=1):
        """Performs implace element-wise multiplication of tensor1 by tensor2,  multiply the result by the scalar value and add it to mat."""
        _ensure_tensorbase(tensor2)
        _ensure_tensorbase(mat)
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data *= tensor2.data
            self.data *= value
            self.data += mat.data
            return self

    def addcdiv(self, tensor2, mat, value=1):
        """Performs the element-wise division of tensor1 by tensor2,  multiply the result by the scalar value and add it to mat."""
        return syft.addcdiv(self, tensor2, mat, value)

    def addcdiv_(self, tensor2, mat, value=1):
        """Performs implace element-wise division of tensor1 by tensor2,  multiply the result by the scalar value and add it to mat."""
        _ensure_tensorbase(tensor2)
        _ensure_tensorbase(mat)
        if self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data = self.data/tensor2.data
            self.data *= value
            self.data += mat.data
            return self

    def addmv(self, mat, vec, beta=1, alpha=1):
        """"Performs a matrix-vector product of the matrix mat and the vector vec. The vector tensor is added to the final result.
              tensor1 and vec are 1d tensors
              out=(beta∗tensor)+(alpha∗(mat@vec2))"""
        return syft.addmv(self, mat, vec, beta, alpha)

    def addmv_(self, mat, vec, beta=1, alpha=1):
        """"Performs a inplace matrix-vector product of the matrix mat and the vector vec. The vector tensor is added to the final result.
              tensor1 and vec are 1d tensors
              out=(beta∗tensor)+(alpha∗(mat@vec2))"""
        _ensure_tensorbase(vec)
        _ensure_tensorbase(mat)
        if vec.data.ndim != 1:
            print("dimension of vec is not 1")
        elif self.data.ndim != 1:
            print("dimension of tensor is not 1")
        elif self.encrypted or vec.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self *= beta
            temp = np.matmul(mat.data, vec.data)*alpha
            self += temp
            return self

    def addbmm(self, tensor2, mat, beta=1, alpha=1):
        """Performs a batch matrix-matrix product of matrices stored in batch1(tensor1) and batch2(tensor2),
         with a reduced add step (all matrix multiplications get accumulated along the first dimension).
         mat is added to the final result.
         res=(beta∗M)+(alpha∗sum(batch1i@batch2i, i=0, b))
        * batch1 and batch2 must be 3D Tensors each containing the same number of matrices."""
        return syft.addbmm(self, tensor2, mat, beta, alpha)

    def  addbmm_(self, tensor2, mat, beta=1, alpha=1):
        """Performs a inplace batch matrix-matrix product of matrices stored in batch1(tensor1) and batch2(tensor2),
         with a reduced add step (all matrix multiplications get accumulated along the first dimension).
         mat is added to the final result.
         res=(beta∗M)+(alpha∗sum(batch1i@batch2i, i=0, b)
        * batch1 and batch2 must be 3D Tensors each containing the same number of matrices.)"""
        _ensure_tensorbase(tensor2)
        _ensure_tensorbase(mat)
        if tensor2.data.ndim != 3:
            print("dimension of tensor2 is not 3")
        elif self.data.ndim != 3:
            print("dimension of tensor1 is not 3")
        elif self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data = np.matmul(self.data, tensor2.data)
            sum = 0
            for i in range(len(self.data)):
                sum += self.data[i]
            self.data = (mat.data*beta)+(alpha*sum)
            return self

    def baddbmm(self, tensor2, mat, beta=1, alpha=1):
        """Performs a batch matrix-matrix product of matrices in batch1(tensor1) and batch2(tensor2). mat is added to the final result.
          resi=(beta∗Mi)+(alpha∗batch1i×batch2i)
          *batch1 and batch2 must be 3D Tensors each containing the same number of matrices."""
        return syft.baddbmm(self, tensor2, mat, beta, alpha)

    def  baddbmm_(self, tensor2, mat, beta=1, alpha=1):
        """Performs a batch matrix-matrix product of matrices in batch1(tensor1) and batch2(tensor2). mat is added to the final result.
          resi=(beta∗Mi)+(alpha∗batch1i×batch2i)
          *batch1 and batch2 must be 3D Tensors each containing the same number of matrices."""
        _ensure_tensorbase(tensor2)
        _ensure_tensorbase(mat)
        if tensor2.data.ndim != 3:
            print("dimension of tensor2 is not 3")
        elif self.data.ndim != 3:
            print("dimension of tensor1 is not 3")
        elif self.encrypted or tensor2.encrypted or mat.encrypted:
            return NotImplemented
        else:
            self.data = np.matmul(self.data, tensor2.data)
            self.data *= alpha
            self.data += (mat.data*beta)
            return self

<|endoftext|>


<commit_before>import cairo
import numpy as np
import math

class Axes:
    def __init__(self, pixel_size, start, extent):
        self.pixel_size = pixel_size
        self.start = start
        self.extent = extent

    def axes_to_pixel(self, pos):
        px = (pos[0] - self.start[0])*self.pixel_size[0]/self.extent[0]
        py = self.pixel_size[1]-(pos[1] - self.start[1])*self.pixel_size[1]/self.extent[1]
        return px, py

    def draw_axes(self, ctx):
        for p in self.get_divs(self.pixel_size[0], self.start[0], self.extent[0]):
            ctx.move_to(*self.axes_to_pixel((p, self.start[1])))
            ctx.line_to(*self.axes_to_pixel((p, self.start[1]+self.extent[1])))
        for p in self.get_divs(self.pixel_size[1], self.start[1], self.extent[1]):
            ctx.move_to(*self.axes_to_pixel((self.start[0], p)))
            ctx.line_to(*self.axes_to_pixel((self.start[0]+self.extent[0], p)))
        ctx.set_source_rgb(.5, .5, 1)
        ctx.set_line_width(2)
        ctx.stroke()

        ctx.set_source_rgb(0.1, 0.1, 0.1)
        ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
        ctx.set_font_size(15)
        for p in self.get_divs(self.pixel_size[0], self.start[0], self.extent[0]):
            if p:
                ppx = self.axes_to_pixel((p, 0))
                x, y, width, height, dx, dy = ctx.text_extents(str(p))
                ctx.move_to(ppx[0]-width-4, ppx[1]+height+4)
                ctx.show_text(str(p))
        for p in self.get_divs(self.pixel_size[1], self.start[1], self.extent[1]):
            if p:
                ppx = self.axes_to_pixel((0, p))
                x, y, width, height, dx, dy = ctx.text_extents(str(p))
                ctx.move_to(ppx[0]-width-4, ppx[1]+height+4)
                ctx.show_text(str(p))

        ctx.move_to(*self.axes_to_pixel((self.start[0], 0)))
        ctx.line_to(*self.axes_to_pixel((self.start[0]+self.extent[0], 0)))
        ctx.move_to(*self.axes_to_pixel((0, self.start[1])))
        ctx.line_to(*self.axes_to_pixel((0, self.start[1]+self.extent[1])))
        ctx.set_source_rgb(0, 0, 0)
        ctx.set_line_width(2)
        ctx.stroke()
        p = self.axes_to_pixel((0, 0))
        ctx.arc(p[0], p[1], 8, 0, 2*math.pi)
        ctx.stroke()

    def get_divs(self, pixel_size, start, extent, div = 1):
        divs = []
        n = math.ceil(start/div)*div
        while n <= start + extent:
            divs.append(n)
            n += div
        return divs

def plot_curve(ctx, fn, axes, extent=None):
    points = []
    for x in np.linspace(axes.start[0], axes.start[0]+axes.extent[0], 100):
        if not extent or extent[0] < x < extent[1]:
            points.append((x, fn(x)))
    if points:
        ctx.move_to(*axes.axes_to_pixel(points[0]))
        for p in points[1:]:
            ctx.line_to(*axes.axes_to_pixel(p))

def attribution(ctx, size):
    ctx.set_source_rgb(0.5, 0, 0)
    ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    ctx.set_font_size(20)
    s = 'graphicmaths.com'
    x, y, width, height, dx, dy = ctx.text_extents(s)
    ctx.move_to(size[0]-width-4, size[1]-4)
    ctx.show_text(s)
<commit_msg>Add plot_yx function<commit_after>import cairo
import numpy as np
import math

class Axes:
    def __init__(self, pixel_size, start, extent):
        self.pixel_size = pixel_size
        self.start = start
        self.extent = extent

    def axes_to_pixel(self, pos):
        px = (pos[0] - self.start[0])*self.pixel_size[0]/self.extent[0]
        py = self.pixel_size[1]-(pos[1] - self.start[1])*self.pixel_size[1]/self.extent[1]
        return px, py

    def draw_axes(self, ctx, div=(1, 1)):
        for p in self.get_divs(self.pixel_size[0], self.start[0], self.extent[0], div[0]):
            ctx.move_to(*self.axes_to_pixel((p, self.start[1])))
            ctx.line_to(*self.axes_to_pixel((p, self.start[1]+self.extent[1])))
        for p in self.get_divs(self.pixel_size[1], self.start[1], self.extent[1], div[1]):
            ctx.move_to(*self.axes_to_pixel((self.start[0], p)))
            ctx.line_to(*self.axes_to_pixel((self.start[0]+self.extent[0], p)))
        ctx.set_source_rgb(.5, .5, 1)
        ctx.set_line_width(2)
        ctx.stroke()

        ctx.set_source_rgb(0.1, 0.1, 0.1)
        ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
        ctx.set_font_size(15)
        for p in self.get_divs(self.pixel_size[0], self.start[0], self.extent[0], div[0]):
            if p:
                ppx = self.axes_to_pixel((p, 0))
                x, y, width, height, dx, dy = ctx.text_extents(str(p))
                ctx.move_to(ppx[0]-width-4, ppx[1]+height+4)
                ctx.show_text(str(p))
        for p in self.get_divs(self.pixel_size[1], self.start[1], self.extent[1], div[1]):
            if p:
                ppx = self.axes_to_pixel((0, p))
                x, y, width, height, dx, dy = ctx.text_extents(str(p))
                ctx.move_to(ppx[0]-width-4, ppx[1]+height+4)
                ctx.show_text(str(p))

        ctx.move_to(*self.axes_to_pixel((self.start[0], 0)))
        ctx.line_to(*self.axes_to_pixel((self.start[0]+self.extent[0], 0)))
        ctx.move_to(*self.axes_to_pixel((0, self.start[1])))
        ctx.line_to(*self.axes_to_pixel((0, self.start[1]+self.extent[1])))
        ctx.set_source_rgb(0, 0, 0)
        ctx.set_line_width(2)
        ctx.stroke()
        p = self.axes_to_pixel((0, 0))
        ctx.arc(p[0], p[1], 8, 0, 2*math.pi)
        ctx.stroke()

    def get_divs(self, pixel_size, start, extent, div):
        divs = []
        n = math.ceil(start/div)*div
        while n <= start + extent:
            divs.append(n)
            n += div
        return divs

def plot_curve(ctx, fn, axes, color=(1, 0, 0), extent=None, lw=3):
    points = []
    for x in np.linspace(axes.start[0], axes.start[0]+axes.extent[0], 100):
        if not extent or extent[0] < x < extent[1]:
            points.append((x, fn(x)))
    if points:
        ctx.move_to(*axes.axes_to_pixel(points[0]))
        for p in points[1:]:
            ctx.line_to(*axes.axes_to_pixel(p))
    ctx.set_source_rgb(*color)
    ctx.set_line_width(lw)
    ctx.stroke()

def plot_yx_curve(ctx, fn, axes, color=(1, 0, 0), extent=None, lw=3):
    points = []
    for y in np.linspace(axes.start[1], axes.start[1]+axes.extent[1], 100):
        if not extent or extent[0] < y < extent[1]:
            points.append((fn(y), y))
    if points:
        ctx.move_to(*axes.axes_to_pixel(points[0]))
        for p in points[1:]:
            ctx.line_to(*axes.axes_to_pixel(p))
    ctx.set_source_rgb(*color)
    ctx.set_line_width(lw)
    ctx.stroke()

def attribution(ctx, size, text, color=(0.5, 0, 0)):
    ctx.set_source_rgb(*color)
    ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    ctx.set_font_size(20)
    x, y, width, height, dx, dy = ctx.text_extents(text)
    ctx.move_to(size[0]-width-4, size[1]-4)
    ctx.show_text(text)
<|endoftext|>


<commit_before>#!/usr/bin/python
# Copyright 2013 Russell Heilling
# pylint: disable=C0103,R0903
"""Sync items on toread list from calibre database into local folder.

Processes a toread file and exports the files for the first listed
titles listed into a local folder.

The toread file shold be in the format:

{comicvine_id} {title}

The content of the title field are not used.  This format is
compatible with todo.txt.
"""
import logging
import os
import re

from collections import OrderedDict

import args
from calibredb import CalibreDB, set_log_level
import logs

args.add_argument('--count', '-c', help='Number of issues to sync',
                  type=int, default='50')
args.add_argument('--toread', '-t', help='File containing issues to read',
                  type=bytes, default=None, required=True)
args.add_argument('--syncdir', '-d', help='Directory to sync issues to',
                  type=bytes, default=None, required=True)

ARGS = args.ARGS

class FormatChangeError(Exception):
  'Exception raised when attempt made to change format during rename'
  pass

class ToRead(OrderedDict):
  'Read matching lines from the toread file into an ordered dict'
  title_pattern = re.compile(r'^(\d+)\s+(.*)$')

  def __init__(self, toread_file, validator=None):
    super(ToRead, self).__init__()
    with open(toread_file, 'r') as toread:
      for title in toread:
        title_match = self.title_pattern.match(title)
        if title_match:
          if validator:
            try:
              validator(int(title_match.group(1)))
            except TypeError:
              # Raised when validator is not callable
              raise
            except Exception as err:
              logging.warn('IssueID not valid in line: %s', title)
              continue
          self[title_match.group(1)] = title_match.group(2)
          logging.debug('Found title %s(%s)', title_match.group(2),
                        title_match.group(1))
        else:
          logging.info('Unmatching toread line: %s', title)

class ExportDirectory(dict):
  'Files present in the export directory'
  title_pattern = re.compile(r'\((\d+)\).(cb[rz])')

  def __init__(self, directory):
    super(ExportDirectory, self).__init__()
    self.directory = directory
    self.format = {}
    self.scan()

  def __delitem__(self, key):
    if os.path.exists(os.path.join(self.directory, self[key])):
      try:
        os.remove(os.path.join(self.directory, self[key]))
      except OSError as err:
        logging.error('Error removing file %s: %s', self[key], err)
    super(ExportDirectory, self).__delitem__(key)
    del self.format[key]

  def __setitem__(self, key, value):
    title_match = self.title_pattern.search(value)
    if not title_match:
      raise ValueError('Cannot find ID and extension for file %s' % value)
    calibre_id = title_match.group(1)
    if key != calibre_id:
      raise KeyError(
        'Calibre ID in file(%s) does not match specified key(%s)' % (
          calibre_id, key))

    # Setting a key that exists should rename the file
    if key in self and os.path.exists(os.path.join(self.directory,
                                                   self[key])):
      if self[calibre_id] == value:
        logging.debug('Skipping rename, destination same as source: %s',
                      self[calibre_id])
        return
      if not value.endswith(self.format[calibre_id]):
        raise FormatChangeError(
          'Attempt to change format during rename (%s does not have '
          'format %s).', value, self.format[calibre_id])
      logging.debug('Renaming %s to %s', self[key], value)
      try:
        os.rename(os.path.join(self.directory, self[key]),
                  os.path.join(self.directory, value))
      except OSError as err:
        raise OSError ('Error renaming file %s -> %s: %s',
                       self[key], value, err)
    elif not os.path.exists(os.path.join(self.directory, value)):
      raise ValueError('File %s does not exist' % value)

    super(ExportDirectory, self).__setitem__(key, value)
    self.format[key] = title_match.group(2)

  def scan(self):
    'Scan the export directory for files'
    for key in self:
      if not os.path.exists(os.path.join(self.directory, self[key])):
        del self[key]
    for entry in os.listdir(self.directory):
      id_match = self.title_pattern.search(entry)
      if id_match:
        calibre_id = id_match.group(1)
        self[calibre_id] = entry
        logging.debug('Found file %s(%s)', entry, id_match.group(1))

  def keep_files(self, keep_ids):
    'Remove any files that are not in the list of ids to keep.'
    for calibre_id, filename in self.items():
      if calibre_id not in keep_ids:
        logging.info('Removing file %s', filename)
        del self[calibre_id]

  def find_missing(self, wanted):
    'Return list of ids from wanted list for which there are no files present.'
    return list(set(wanted) - set(self.keys()))

def rename_files(syncdir, toread):
  'Rename files so that the filenames sort in todolist order.'
  oldindex = re.compile(r'(\d{4}) ')
  index = 0
  seen_idx = []
  for title in toread:
    if title not in syncdir:
      break
    index += 1
    index_match = oldindex.match(syncdir[title])
    if index_match:
      file_index = int(index_match.group(1))
      if file_index >= index and file_index not in seen_idx:
        logging.debug('File has suitable index, ignoring %s (i:%d, s:%r)',
                      syncdir[title], index, seen_idx)
        seen_idx.append(file_index)
        index = file_index
        continue
      logging.debug('File has unsuitable index, renaming %s (i:%d, s:%r)',
                    syncdir[title], index, seen_idx)
    newname = '%04d %s (%s).%s' % (index, toread[title], title,
                                   syncdir.format[title])
    # Remove dangerous characters from title
    newname = re.sub(r'[\'/"!]', r'_', newname)
    logging.debug('Renaming %s to %s', syncdir[title], newname)
    try:
      syncdir[title] = newname
    except OSError:
      logging.warn(OSError)
    seen_idx.append(index)

def main():
  'Read the toread list'
  calibredb = CalibreDB()
  toread = ToRead(ARGS.toread, validator=calibredb.issue)
  syncdir = ExportDirectory(ARGS.syncdir)

  # Grab the ids of the first count entries
  wanted = toread.keys()[:ARGS.count]

  # Remove any files not in the list
  syncdir.keep_files(wanted)

  # Export any files not already present
  calibredb.export_files(wanted, syncdir)

  # Rename files so they sort in reading list order
  rename_files(syncdir, toread)

if __name__ == '__main__':
  args.parse_args()
  logs.set_logging()
  main()
<commit_msg>New and improved sync ordering code that uses difflib to minimise the number of files to rename.<commit_after>#!/usr/bin/python
# Copyright 2013 Russell Heilling
# pylint: disable=C0103,R0903
"""Sync items on toread list from calibre database into local folder.

Processes a toread file and exports the files for the first listed
titles listed into a local folder.

The toread file shold be in the format:

{comicvine_id} {title}

The content of the title field are not used.  This format is
compatible with todo.txt.
"""
from difflib import SequenceMatcher
import logging
from math import ceil
import os
import re

from collections import OrderedDict

import args
from calibredb import CalibreDB, set_log_level
import logs

args.add_argument('--count', '-c', help='Number of issues to sync',
                  type=int, default='50')
args.add_argument('--toread', '-t', help='File containing issues to read',
                  type=bytes, default=None, required=True)
args.add_argument('--syncdir', '-d', help='Directory to sync issues to',
                  type=bytes, default=None, required=True)

ARGS = args.ARGS

class FormatChangeError(Exception):
  'Exception raised when attempt made to change format during rename'
  pass

class ToRead(OrderedDict):
  'Read matching lines from the toread file into an ordered dict'
  title_pattern = re.compile(r'^(\d+)\s+(.*)$')

  def __init__(self, toread_file, validator=None):
    super(ToRead, self).__init__()
    with open(toread_file, 'r') as toread:
      for title in toread:
        title_match = self.title_pattern.match(title)
        if title_match:
          if validator:
            try:
              validator(int(title_match.group(1)))
            except TypeError:
              # Raised when validator is not callable
              raise
            except Exception as err:
              logging.warn('IssueID not valid in line: %s', title)
              continue
          self[title_match.group(1)] = title_match.group(2)
          logging.debug('Found title %s(%s)', title_match.group(2),
                        title_match.group(1))
        else:
          logging.info('Unmatching toread line: %s', title)

class ExportDirectory(dict):
  'Files present in the export directory'
  title_pattern = re.compile(r'\((\d+)\).(cb[rz])')

  def __init__(self, directory):
    super(ExportDirectory, self).__init__()
    self.directory = directory
    self.format = {}
    self.scan()

  def __delitem__(self, key):
    if os.path.exists(os.path.join(self.directory, self[key])):
      try:
        os.remove(os.path.join(self.directory, self[key]))
      except OSError as err:
        logging.error('Error removing file %s: %s', self[key], err)
    super(ExportDirectory, self).__delitem__(key)
    del self.format[key]

  def __setitem__(self, key, value):
    title_match = self.title_pattern.search(value)
    if not title_match:
      raise ValueError('Cannot find ID and extension for file %s' % value)
    calibre_id = title_match.group(1)
    if key != calibre_id:
      raise KeyError(
        'Calibre ID in file(%s) does not match specified key(%s)' % (
          calibre_id, key))

    # Setting a key that exists should rename the file
    if key in self and os.path.exists(os.path.join(self.directory,
                                                   self[key])):
      if self[calibre_id] == value:
        logging.debug('Skipping rename, destination same as source: %s',
                      self[calibre_id])
        return
      if not value.endswith(self.format[calibre_id]):
        raise FormatChangeError(
          'Attempt to change format during rename (%s does not have '
          'format %s).', value, self.format[calibre_id])
      logging.debug('Renaming %s to %s', self[key], value)
      try:
        os.rename(os.path.join(self.directory, self[key]),
                  os.path.join(self.directory, value))
      except OSError as err:
        raise OSError ('Error renaming file %s -> %s: %s',
                       self[key], value, err)
    elif not os.path.exists(os.path.join(self.directory, value)):
      raise ValueError('File %s does not exist' % value)

    super(ExportDirectory, self).__setitem__(key, value)
    self.format[key] = title_match.group(2)

  def scan(self):
    'Scan the export directory for files'
    for key in self:
      if not os.path.exists(os.path.join(self.directory, self[key])):
        del self[key]
    for entry in os.listdir(self.directory):
      id_match = self.title_pattern.search(entry)
      if id_match:
        calibre_id = id_match.group(1)
        self[calibre_id] = entry
        logging.debug('Found file %s(%s)', entry, id_match.group(1))

  def keep_files(self, keep_ids):
    'Remove any files that are not in the list of ids to keep.'
    for calibre_id, filename in self.items():
      if calibre_id not in keep_ids:
        logging.info('Removing file %s', filename)
        del self[calibre_id]

  def find_missing(self, wanted):
    'Return list of ids from wanted list for which there are no files present.'
    return list(set(wanted) - set(self.keys()))

def file_index(filename):
  'Find file index in filename if present.'
  index_match = re.match(r'(\d{4}(?:\.\d{2})?) ', filename)
  if index_match:
    index = index_match.group(1)
    return float(index)

def ordered_files(syncdir, toread):
  'Find the largest set of files in the correct order.'
  # Create a dict of files in syncdir with a valid index
  # In case of index clashes, the first candidate wins
  valid_files = {}
  for calibreid, filename in syncdir.items():
    index = file_index(filename)
    if index and index not in valid_files:
      valid_files[index] = calibreid
  # Create lists to compare to find the largest ordered subset
  synclist = [valid_files[index] for index in sorted(valid_files.keys())]
  toreadlist = toread.keys()[:ARGS.count]
  matcher = SequenceMatcher(None, toreadlist, synclist)
  ordered_ids = []
  for i, j, count in matcher.get_matching_blocks():
    ordered_ids.extend(toreadlist[i:i+count])
  logging.debug('Longest sorted subset: %r', [
      syncdir[title] for title in ordered_ids])
  return ordered_ids

def new_indexes(start, finish, titles):
  'Find new indexes for titles that fit between start and finish.'
  logging.debug('Inserting %d titles between %s and %s',
                len(titles), start, finish)
  indexes = []
  if not finish:
    # Simplest case - just append titles with increasing integer indexes
    logging.debug('Appending %d titles to end of list', len(titles))
    finish = int(start) + len(titles) + 1
  if int(finish) - int(start) > len(titles):
    # enough room between start and finish to give each title an integer index
    first_index = int(start) + 1
    indexes = ['%07.2f' % float(i) for i in range(
        first_index, first_index+len(titles))]
  else:
    # Fit the titles between the start and finish with even spacing.
    # Round issues that are near an integer to the whole number to try
    # and avoid everything going fractional...
    interval = (finish - start) / (len(titles)+1)
    logging.debug('Stepping from %r to %r with interval %r', start,
                  finish, interval)
    index = start
    for title in titles:
      index += interval
      int_next = int(index+interval)
      if index+interval > int_next and int_next > int(index):
        # We are just about to cross an integer boundary.  Put the
        # issue on the boundary rather than just past it.
        indexes.append('%07.2f' % float(int_next))
      else:
        indexes.append('%07.2f' % index)
  return zip(indexes, titles)

def rename_files(syncdir, toread):
  'Rename files so that the filenames sort in todolist order.'
  # Get ordered files
  good_files = ordered_files(syncdir, toread)
  # iterate through todo items
  last_index = 0
  rename_queue = []
  reindex_queue = []
  for title in toread.keys()[:ARGS.count]:
    #  if item in good_files reindex any pending files
    if title in good_files:
      current_index = file_index(syncdir[title])
      logging.debug('File has suitable index, ignoring %s (i:%d)',
                    syncdir[title], current_index)
      if last_index > current_index:
        logging.warn('something weird going on.. %f > %f',
                     last_index, current_index)
      if reindex_queue:
        rename_queue.extend(new_indexes(last_index, current_index,
                                        reindex_queue))
        reindex_queue = []
      last_index = current_index
      continue
    else:
      logging.debug('Adding %s to reindex queue', syncdir[title])
      reindex_queue.append(title)
  # Append any remaning files in the reindex queue to the rename queue
  # These are going after the issue so we can let new_indexes know
  # just to assign them integers
  if reindex_queue:
    rename_queue.extend(new_indexes(last_index, None, reindex_queue))

  for index, title in rename_queue:
    newname = '%s %s (%s).%s' % (index, toread[title], title,
                                 syncdir.format[title])
    # Remove dangerous characters from title
    newname = re.sub(r'[:\'/"!]', r'_', newname)
    if syncdir[title] == newname:
      continue
    logging.debug('Renaming %s to %s', syncdir[title], newname)
    try:
      syncdir[title] = newname
    except OSError:
      logging.warn(OSError)

def main():
  'Read the toread list'
  calibredb = CalibreDB()
  toread = ToRead(ARGS.toread, validator=calibredb.issue)
  syncdir = ExportDirectory(ARGS.syncdir)

  # Grab the ids of the first count entries
  wanted = toread.keys()[:ARGS.count]

  # Remove any files not in the list
  syncdir.keep_files(wanted)

  # Export any files not already present
  calibredb.export_files(wanted, syncdir)

  # Rename files so they sort in reading list order
  rename_files(syncdir, toread)

if __name__ == '__main__':
  args.parse_args()
  logs.set_logging()
  main()
<|endoftext|>


<commit_before>#!/usr/bin/env python

import unittest

import gui
import human_player
import rules
import game
#import profile

from ai_player import *

class AIPlayerTest(unittest.TestCase):

    def setUp(self):
        # TODO
        player1 = AIPlayer("Blomp", BLACK)
        player2 = human_player.HumanPlayer("Kubba", WHITE)
        r = rules.Rules(5, "standard")
        self.game = game.Game(r, player1, player2)
        self.gui = None

    def test_find_one_move(self):
        p = AIPlayer("Deep thunk")
        p.prompt_for_action(self.game, self.gui)
        ma = p.get_action(self.game, self.gui)
        self.assertEquals(ma, gui.MoveAction.create_from_tuple(2,2))

if __name__ == "__main__":
    unittest.main()

<commit_msg>Fixed.<commit_after>#!/usr/bin/env python

import unittest

import gui
import human_player
import rules
import game
#import profile

from ai_player import *

class AIPlayerTest(unittest.TestCase):

    def setUp(self):
        # TODO
        player1 = AIPlayer("Blomp", BLACK)
        player2 = human_player.HumanPlayer("Kubba", WHITE)
        r = rules.Rules(5, "standard")
        self.game = game.Game(r, player1, player2)
        self.gui = None

    def test_find_one_move(self):
        p = AIPlayer("Deep thunk", BLACK)
        p.attach_to_game(self.game)
        p.prompt_for_action(self.game, self.gui)
        ma = p.get_action(self.game, self.gui)
        self.assertEquals(ma, gui.MoveAction.create_from_tuple(2,2))

if __name__ == "__main__":
    unittest.main()

<|endoftext|>


<commit_before>import os
import sys

PARENT_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
sys.path.append(PARENT_PATH)

from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker

from tailor.listeners.mainlistener import MainListener
from tailor.output.printer import Printer
from tailor.swift.swiftlexer import SwiftLexer
from tailor.swift.swiftparser import SwiftParser

def main(argv):
    infile = FileStream(argv[1])
    printer = Printer(filepath=argv[1])
    lexer = SwiftLexer(infile)
    stream = CommonTokenStream(lexer)
    parser = SwiftParser(stream)
    tree = parser.topLevel()
    listener = MainListener(printer)
    walker = ParseTreeWalker()
    walker.walk(listener, tree)

if __name__ == '__main__':
    main(sys.argv)
<commit_msg>Set up argparse to accept params and display usage<commit_after>"""Perform static analysis on a Swift source file."""

import argparse
import os
import sys

PARENT_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
sys.path.append(PARENT_PATH)

from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker

from tailor.listeners.mainlistener import MainListener
from tailor.output.printer import Printer
from tailor.swift.swiftlexer import SwiftLexer
from tailor.swift.swiftparser import SwiftParser

def parse_args():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('infile', type=os.path.abspath,
                        help='Swift source file')
    parser.add_argument('-l', '--max-lines', type=int, default=0,
                        help='maximum file line length')
    return parser.parse_args()

def main():
    args = parse_args()

    printer = Printer(filepath=args.infile)
    lexer = SwiftLexer(FileStream(args.infile))
    stream = CommonTokenStream(lexer)
    parser = SwiftParser(stream)
    tree = parser.topLevel()
    listener = MainListener(printer)
    walker = ParseTreeWalker()
    walker.walk(listener, tree)

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


<commit_before>#calculation for line interaction
import constants
import numpy as np
import initialize
import sqlite3

try:
    import sqlparse
    sqlparse_available = True
except ImportError:
    sqlparse_available = False

Bnu = lambda nu, t: (2 * constants.h * nu**3 / constants.c**2) / (np.exp(((constants.h * nu) / (constants.kb * t))) - 1)

def get_tau_line(nu, f_line, dens_line, t_exp):
    tau_line = constants.sobolev_coeff * f_line * (constants.c / nu) * dens_line * t_exp
    return tau_line

def convert_int_ndarray(sqlite_binary):
    if sqlite_binary == '-1':
        return np.array([], dtype=np.int64)
    else:
        return np.frombuffer(sqlite_binary, dtype=np.int64)

def convert_float_ndarray(sqlite_binary):
    if sqlite_binary == '-1.0':
        return np.array([], dtype=np.float64)
    else:
        return np.frombuffer(sqlite_binary, dtype=np.float64)

sqlite3.register_converter('int_ndarray', convert_int_ndarray)
sqlite3.register_converter('float_ndarray', convert_float_ndarray)

def read_line_list(conn, atoms=None, symbol2z=None, max_atom=50, max_ion=50):

    raw_data = []

    select_stmt = """SELECT
                        lines.id, wl, loggf, g_lower, g_upper, e_lower,
                        e_upper, level_id_lower, level_id_upper,
                        global_level_id_lower, global_level_id_upper,
                        lines.atom, lines.ion, metastable
                    FROM
                        lines
                    inner join
                        levels
                    ON
                        global_level_id_lower=levels.id

                    where
                        lines.atom < %(max_atom)d
                    and
                        lines.ion <  %(max_ion)d
                    %(select_atom_stmt)s
                    order by lines.id
                """

    if atoms is not None:
        if symbol2z is None:
            symbol2z = initialize.read_symbol2z()
            atom_list = ','.join([str(symbol2z[atom]) for atom in atoms])
            select_atom_stmt = """ and atom in (%s)""" % atom_list
    else:
        select_atom_stmt = ''

    line_select_stmt = select_stmt % dict(max_atom=max_atom, max_ion=max_ion, select_atom_stmt=select_atom_stmt)

    if sqlparse_available:
        print sqlparse.format(line_select_stmt, reindent=True)
    else:
        print line_select_stmt

    curs = conn.execute(line_select_stmt)

    for id, wl, loggf, g_lower, g_upper, e_lower, e_upper, level_id_lower, level_id_upper, global_level_id_lower, global_level_id_upper, atom, ion, metastable in curs:
        gf = 10**loggf
        f_lu = gf / g_lower
        f_ul = gf / g_upper
        raw_data.append((id, wl, g_lower, g_upper, f_lu, f_ul, e_lower, e_upper, level_id_lower, level_id_upper, global_level_id_lower, global_level_id_upper, atom, ion, metastable))

    line_list = np.array(raw_data, dtype = [('id', np.int64), ('wl', np.float64),
        ('g_lower', np.int64), ('g_upper', np.int64),
        ('f_lu', np.float64), ('f_ul', np.float64),
        ('e_lower', np.float64), ('e_upper', np.float64),
        ('level_id_lower', np.int64), ('level_id_upper', np.int64),
        ('global_level_id_lower', np.int64), ('global_level_id_upper', np.int64),
        ('atom', np.int64), ('ion', np.int64), ('metastable', np.bool)])

    return line_list

class MacroAtomData(object):
    pass

class SimpleMacroAtomData(MacroAtomData):

    @classmethod
    def fromdb(cls, conn):
        curs = conn.execute("""
        SELECT
            count_down,
            reference_down,
            line_id_down,
            p_internal_down,
            p_emission_down,
            count_up,
            reference_up,
            line_id_up,
            p_internal_up
        FROM
            macro_atom
        ORDER BY
            id""")

        (count_down, reference_down, line_id_down, p_internal_down, p_emission_down,
         count_up, reference_up, line_id_up, p_internal_up) = zip(*curs.fetchall())

        return cls(count_down, reference_down, line_id_down, p_internal_down, p_emission_down,
         count_up, reference_up, line_id_up, p_internal_up)

    def __init__(self,
                count_down, reference_down, line_id_down,
                p_internal_down, p_emission_down,
                count_up, reference_up, line_id_up, p_internal_up):
        self.count_down = np.array(count_down)
        self.target_level_id_down = np.array(reference_down)
        self.target_line_id_down = np.array(line_id_down)
        self.p_internal_down = np.array(p_internal_down)
        self.p_emission_down = np.array(p_emission_down)
        self.count_up = np.array(count_up)
        self.target_level_id_up = np.array(reference_up)
        self.target_line_id_up = np.array(line_id_up)
        self.p_internal_up = np.array(p_internal_up)

    def calculate_beta_sobolev(self, tau_sobolev):

        def safe_beta_sobolev(tau_sobolev):
            if tau_sobolev > 1e3:
                return 1 / tau_sobolev
            elif tau_sobolev < 1e-4:
                return 1 - 0.5 * tau_sobolev
            else:
                return (1 - np.exp(-tau_sobolev)) / tau_sobolev
        vec_safe_beta_sobolev = np.vectorize(safe_beta_sobolev)
        beta_sobolev = vec_safe_beta_sobolev(tau_sobolev)

        return beta_sobolev

    def calculate_jbar(self, tau_sobolev, nu, t_rad, w, beta_sobolev=None):
        if beta_sobolev is None: beta_sobolev = self.calculate_beta_sobolev(tau_sobolev)
        jbar = beta_sobolev * w * Bnu(nu, t_rad)
        return jbar

    def calculate_p_downs(self, beta_sobolev):

        def beta_update(p_internal_down, p_emission_down, target_line_id, target_level_id):
            p_down = np.hstack((p_internal_down * beta_sobolev[target_line_id - 1], p_emission_down * beta_sobolev[target_line_id - 1]))
            #type is emitting or not
            type_down = np.hstack((np.zeros_like(p_internal_down, dtype=np.int64),
                                   np.ones_like(p_emission_down, dtype=np.int64)))
            target_level_id_down = np.hstack((target_level_id, target_level_id))
            target_line_id_down = np.hstack((target_line_id, target_line_id))
            return p_down, type_down, target_level_id_down, target_line_id_down
        vec_beta_update = np.vectorize(beta_update, otypes = (np.ndarray, np.ndarray, np.ndarray, np.ndarray))
        return vec_beta_update(self.p_internal_down, self.p_emission_down, self.target_line_id_down, self.target_level_id_down)

    def calculate_p_ups(self, jbar):

        def jbar_update(p_internal_up, target_line_id):
            p_up = p_internal_up * jbar[target_line_id - 1]
            #type is emitting or not
            type_up = np.zeros_like(p_up, dtype=np.int64)
            return p_up, type_up

        vec_jbar_update = np.vectorize(jbar_update, otypes = (np.ndarray,np.ndarray))
        return vec_jbar_update(self.p_internal_up, self.target_line_id_up)

    def calculate_transition_probabilities(self, beta_sobolev, jbar):
        p_down, type_down, target_level_id_down, target_line_id_down = self.calculate_p_downs(beta_sobolev)
        p_up, type_up = self.calculate_p_ups(jbar)

        #merging probabilites
        def merge_probability (p_down_array, p_up_array,
                               type_down_array, type_up_array,
                               target_level_id_down_array, target_level_id_up_array,
                               target_line_id_down_array, target_line_id_up_array):
            p_array = np.hstack((p_up_array, p_down_array))
            norm_p_array = np.sum(p_array)
            if norm_p_array > 0.0:
                p_array = p_array / norm_p_array
            return (p_array,
                    np.hstack((type_up_array, type_down_array)),
                    np.hstack((target_level_id_up_array, target_level_id_down_array)),
                    np.hstack((target_line_id_up_array, target_line_id_down_array)))

        vec_merge_probability = np.vectorize(merge_probability, otypes=(np.ndarray, np.ndarray, np.ndarray, np.ndarray))
        p_transition, type_transition, target_level_id, target_line_id = \
                                    vec_merge_probability(p_down, p_up,
                                                          type_down, type_up,
                                                          target_level_id_down, self.target_level_id_up,
                                                          target_line_id_down, self.target_line_id_up)
        p_transition_merged = np.hstack(p_transition)
        type_transition_merged = np.hstack(type_transition)
        target_level_id_merged = np.hstack(target_level_id) - 1
        target_line_id_merged = np.hstack(target_line_id) - 1
        no_probabilities = self.count_down * 2 + self.count_up
        unroll_reference = np.hstack(([0], np.cumsum(no_probabilities)[:-1]))
        return p_transition_merged, type_transition_merged, target_line_id_merged, target_level_id_merged, no_probabilities, unroll_reference

def compile_sobolev_tau(line_list, partition_functions, ion_population, t_exp):
    tau_sobolev = []
    wl = line_list['wl'] * 1e-7
    C = 1 #supposed to be (pi*e**2)/(m_e * c)
    Z = partition_functions[line_list['ion'], line_list['atom']-1]
    g_lower = line_list['g_lower']
    e_lower = line_list['e_lower']
    n_lower = (g_lower / Z) * np.exp(-beta * e_lower) * ion_populations[line_list['ion'], line_list['atom']-1]
    tau_sobolev = C * line_list['f_lu'] * wl * t_exp * n_lower
    return tau_sobolev<commit_msg>first functions implemented to unroll the transition probability at read in. this should make it very fast to calculate them.<commit_after>#calculation for line interaction
import constants
import numpy as np
import initialize
import sqlite3

try:
    import sqlparse
    sqlparse_available = True
except ImportError:
    sqlparse_available = False

Bnu = lambda nu, t: (2 * constants.h * nu**3 / constants.c**2) / (np.exp(((constants.h * nu) / (constants.kb * t))) - 1)

def get_tau_line(nu, f_line, dens_line, t_exp):
    tau_line = constants.sobolev_coeff * f_line * (constants.c / nu) * dens_line * t_exp
    return tau_line

def convert_int_ndarray(sqlite_binary):
    if sqlite_binary == '-1':
        return np.array([], dtype=np.int64)
    else:
        return np.frombuffer(sqlite_binary, dtype=np.int64)

def convert_float_ndarray(sqlite_binary):
    if sqlite_binary == '-1.0':
        return np.array([], dtype=np.float64)
    else:
        return np.frombuffer(sqlite_binary, dtype=np.float64)

sqlite3.register_converter('int_ndarray', convert_int_ndarray)
sqlite3.register_converter('float_ndarray', convert_float_ndarray)

def read_line_list(conn, atoms=None, symbol2z=None, max_atom=50, max_ion=50):
    raw_data = []

    select_stmt = """SELECT
                        lines.id, wl, loggf, g_lower, g_upper, e_lower,
                        e_upper, level_id_lower, level_id_upper,
                        global_level_id_lower, global_level_id_upper,
                        lines.atom, lines.ion, metastable
                    FROM
                        lines
                    inner join
                        levels
                    ON
                        global_level_id_lower=levels.id

                    where
                        lines.atom < %(max_atom)d
                    and
                        lines.ion <  %(max_ion)d
                    %(select_atom_stmt)s
                    order by lines.id
                """

    if atoms is not None:
        if symbol2z is None:
            symbol2z = initialize.read_symbol2z()
            atom_list = ','.join([str(symbol2z[atom]) for atom in atoms])
            select_atom_stmt = """ and atom in (%s)""" % atom_list
    else:
        select_atom_stmt = ''

    line_select_stmt = select_stmt % dict(max_atom=max_atom, max_ion=max_ion, select_atom_stmt=select_atom_stmt)

    if sqlparse_available:
        print sqlparse.format(line_select_stmt, reindent=True)
    else:
        print line_select_stmt

    curs = conn.execute(line_select_stmt)

    for id, wl, loggf, g_lower, g_upper, e_lower, e_upper, level_id_lower, level_id_upper, global_level_id_lower, global_level_id_upper, atom, ion, metastable in curs:
        gf = 10**loggf
        f_lu = gf / g_lower
        f_ul = gf / g_upper
        raw_data.append((id, wl, g_lower, g_upper, f_lu, f_ul, e_lower, e_upper, level_id_lower, level_id_upper, global_level_id_lower, global_level_id_upper, atom, ion, metastable))

    line_list = np.array(raw_data, dtype = [('id', np.int64), ('wl', np.float64),
        ('g_lower', np.int64), ('g_upper', np.int64),
        ('f_lu', np.float64), ('f_ul', np.float64),
        ('e_lower', np.float64), ('e_upper', np.float64),
        ('level_id_lower', np.int64), ('level_id_upper', np.int64),
        ('global_level_id_lower', np.int64), ('global_level_id_upper', np.int64),
        ('atom', np.int64), ('ion', np.int64), ('metastable', np.bool)])

    return line_list

class MacroAtomData(object):
    pass

class SimpleMacroAtomData(MacroAtomData):

    @classmethod
    def fromdb(cls, conn):
        curs = conn.execute("""
        SELECT
            count_down,
            reference_down,
            line_id_down,
            p_internal_down,
            p_emission_down,
            count_up,
            reference_up,
            line_id_up,
            p_internal_up
        FROM
            macro_atom
        ORDER BY
            id""")

        (count_down, reference_down, line_id_down, p_internal_down, p_emission_down,
         count_up, reference_up, line_id_up, p_internal_up) = zip(*curs.fetchall())

        return cls(count_down, reference_down, line_id_down, p_internal_down, p_emission_down,
         count_up, reference_up, line_id_up, p_internal_up)

    def __init__(self,
                count_down, reference_down, line_id_down,
                p_internal_down, p_emission_down,
                count_up, reference_up, line_id_up, p_internal_up):
        self.count_down = np.array(count_down)
        self.target_level_id_down = np.array(reference_down)
        self.target_line_id_down = np.array(line_id_down)
        self.p_internal_down = np.array(p_internal_down)
        self.p_emission_down = np.array(p_emission_down)
        self.count_up = np.array(count_up)
        self.target_level_id_up = np.array(reference_up)
        self.target_line_id_up = np.array(line_id_up)
        self.p_internal_up = np.array(p_internal_up)

        self.count_total = 2 * self.count_down + self.count_up
        self.count_total_sum = np.sum(self.count_total)
        self.level_references = np.hstack(([0], np.cumsum(self.count_total)[:-1]))

    def merge_arrays(self):
        self.p_total = -1 * np.ones((self.count_total_sum), dtype=np.float64)
        self.transition_type_total = -1 * np.ones((self.count_total_sum), dtype=np.int64)
        self.target_line_total = -1 * np.ones((self.count_total_sum), dtype=np.int64)
        self.target_level_total = -1 * np.ones((self.count_total_sum), dtype=np.int64)
        for i, (ref, c_down, c_up, c_total) in enumerate(zip(self.level_references, self.count_down, self.count_up, self.count_total)):
            p_level_total = np.hstack((self.p_emission_down[i], self.p_internal_down[i], self.p_internal_up[i]))
            sort_probabilities = np.argsort(p_level_total)[::-1]
            transition_type_total = np.hstack((np.ones(c_down), np.zeros(c_down + c_up)))
            target_line_total = np.hstack((self.target_line_id_down[i], self.target_line_id_down[i], self.target_line_id_up[i]))
            target_level_total = np.hstack((self.target_level_id_down[i], self.target_level_id_down[i], self.target_level_id_up[i]))

            self.p_total[ref:ref + c_total] = p_level_total[sort_probabilities]
            self.transition_type_total[ref:ref + c_total] = transition_type_total[sort_probabilities]
            self.target_line_total[ref:ref + c_total] = target_line_total[sort_probabilities]
            self.target_level_total[ref:ref + c_total] = target_level_total[sort_probabilities]

        self.target_line_total -= 1
        self.target_level_total -= 1

    def calculate_beta_sobolev(self, tau_sobolev):

        def safe_beta_sobolev(tau_sobolev):
            if tau_sobolev > 1e3:
                return 1 / tau_sobolev
            elif tau_sobolev < 1e-4:
                return 1 - 0.5 * tau_sobolev
            else:
                return (1 - np.exp(-tau_sobolev)) / tau_sobolev
        vec_safe_beta_sobolev = np.vectorize(safe_beta_sobolev)
        beta_sobolev = vec_safe_beta_sobolev(tau_sobolev)

        return beta_sobolev

    def calculate_jbar(self, tau_sobolev, nu, t_rad, w, beta_sobolev=None):
        if beta_sobolev is None: beta_sobolev = self.calculate_beta_sobolev(tau_sobolev)
        jbar = beta_sobolev * w * Bnu(nu, t_rad)
        return jbar

    def calculate_p_downs(self, beta_sobolev):

        def beta_update(p_internal_down, p_emission_down, target_line_id, target_level_id):
            p_down = np.hstack((p_internal_down * beta_sobolev[target_line_id - 1], p_emission_down * beta_sobolev[target_line_id - 1]))
            #type is emitting or not
            type_down = np.hstack((np.zeros_like(p_internal_down, dtype=np.int64),
                                   np.ones_like(p_emission_down, dtype=np.int64)))
            target_level_id_down = np.hstack((target_level_id, target_level_id))
            target_line_id_down = np.hstack((target_line_id, target_line_id))
            return p_down, type_down, target_level_id_down, target_line_id_down
        vec_beta_update = np.vectorize(beta_update, otypes = (np.ndarray, np.ndarray, np.ndarray, np.ndarray))
        return vec_beta_update(self.p_internal_down, self.p_emission_down, self.target_line_id_down, self.target_level_id_down)

    def calculate_p_ups(self, jbar):

        def jbar_update(p_internal_up, target_line_id):
            p_up = p_internal_up * jbar[target_line_id - 1]
            #type is emitting or not
            type_up = np.zeros_like(p_up, dtype=np.int64)
            return p_up, type_up

        vec_jbar_update = np.vectorize(jbar_update, otypes = (np.ndarray,np.ndarray))
        return vec_jbar_update(self.p_internal_up, self.target_line_id_up)

    def calculate_transition_probabilities(self, beta_sobolev, jbar):
        p_down, type_down, target_level_id_down, target_line_id_down = self.calculate_p_downs(beta_sobolev)
        p_up, type_up = self.calculate_p_ups(jbar)

        #merging probabilites
        def merge_probability (p_down_array, p_up_array,
                               type_down_array, type_up_array,
                               target_level_id_down_array, target_level_id_up_array,
                               target_line_id_down_array, target_line_id_up_array):
            p_array = np.hstack((p_up_array, p_down_array))
            norm_p_array = np.sum(p_array)
            if norm_p_array > 0.0:
                p_array = p_array / norm_p_array
            return (p_array,
                    np.hstack((type_up_array, type_down_array)),
                    np.hstack((target_level_id_up_array, target_level_id_down_array)),
                    np.hstack((target_line_id_up_array, target_line_id_down_array)))

        vec_merge_probability = np.vectorize(merge_probability, otypes=(np.ndarray, np.ndarray, np.ndarray, np.ndarray))
        p_transition, type_transition, target_level_id, target_line_id = \
                                    vec_merge_probability(p_down, p_up,
                                                          type_down, type_up,
                                                          target_level_id_down, self.target_level_id_up,
                                                          target_line_id_down, self.target_line_id_up)
        p_transition_merged = np.hstack(p_transition)
        type_transition_merged = np.hstack(type_transition)
        target_level_id_merged = np.hstack(target_level_id) - 1
        target_line_id_merged = np.hstack(target_line_id) - 1
        no_probabilities = self.count_down * 2 + self.count_up
        unroll_reference = np.hstack(([0], np.cumsum(no_probabilities)[:-1]))
        return p_transition_merged, type_transition_merged, target_line_id_merged, target_level_id_merged, no_probabilities, unroll_reference

    <|endoftext|>


<commit_before>from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError

from adhocracy4.actions.models import Action
from adhocracy4.actions.verbs import Verbs
from adhocracy4.comments.models import Comment
from adhocracy4.emails.mixins import SyncEmailMixin
from adhocracy4.projects.models import Project
from adhocracy4.reports import emails as reports_emails
from adhocracy4.reports.models import Report
from meinberlin.apps.bplan import emails as bplan_emails
from meinberlin.apps.bplan.models import Bplan
from meinberlin.apps.bplan.models import Statement
from meinberlin.apps.cms.models import EmailFormPage
from meinberlin.apps.contrib.emails import Email
from meinberlin.apps.ideas.models import Idea
from meinberlin.apps.notifications import emails as notification_emails
from meinberlin.apps.organisations.models import Organisation
from meinberlin.apps.projects import models as project_models

User = get_user_model()

class TestEmail(SyncEmailMixin, Email):
    def get_receivers(self):
        return self.kwargs['receiver']

    def dispatch(self, object, *args, **kwargs):
        self.template_name = kwargs.pop('template_name')
        print('Sending template: {} with object "{}"'.format(
            self.template_name,
            str(object)))
        super().dispatch(object, *args, **kwargs)

    def get_context(self):
        context = super().get_context()
        context['project'] = getattr(self.object, 'project', None)
        context['contact_email'] = settings.CONTACT_EMAIL
        return context

class Command(BaseCommand):
    help = 'Send test emails to a registered user.'

    def add_arguments(self, parser):
        parser.add_argument('email')

    def handle(self, *args, **options):
        self.user = User.objects.get(email=options['email'])

        self._send_notifications_create_idea()
        self._send_notifications_comment_idea()
        self._send_notification_phase()
        self._send_notification_project_created()
        self._send_bplan_statement()
        self._send_bplan_update()

        self._send_report_mails()

        self._send_allauth_email_confirmation()
        self._send_allauth_password_reset()

        self._send_invitation_private_project()
        self._send_invitation_moderator()
        self._send_initiator_request()

        self._send_form_mail()

    def _send_notifications_create_idea(self):
        # Send notification for a newly created item
        action = Action.objects.filter(
            verb=Verbs.ADD.value,
            obj_content_type=ContentType.objects.get_for_model(Idea)
        ).exclude(project=None).first()
        if not action:
            raise CommandError('At least one idea is required')

        self._send_notify_create_item(action)

    def _send_notifications_comment_idea(self):
        # Send notifications for a comment on a item
        action = Action.objects.filter(
            verb=Verbs.ADD.value,
            obj_content_type=ContentType.objects.get_for_model(Comment),
            target_content_type=ContentType.objects.get_for_model(Idea)
        ).exclude(project=None).first()
        if not action:
            raise CommandError('At least one idea with a comment is required')

        self._send_notify_create_item(action)

    def _send_notify_create_item(self, action):
        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyCreatorEmail.template_name)

        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyFollowersOnNewItemCreated.template_name)

        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyModeratorsEmail.template_name)

    def _send_notification_phase(self):
        action = Action.objects.filter(
            verb=Verbs.SCHEDULE.value
        ).first()
        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyFollowersOnPhaseIsOverSoonEmail.template_name
        )

    def _send_notification_project_created(self):
        project = Project.objects.first()
        TestEmail.send(
            project,
            project=project,
            creator=self.user,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyInitiatorsOnProjectCreatedEmail.template_name
        )

    def _send_bplan_statement(self):
        statement = Statement.objects.first()
        if not statement:
            raise CommandError('At least one bplan statement is required')

        TestEmail.send(
            statement,
            receiver=[self.user],
            template_name=bplan_emails.OfficeWorkerNotification.template_name
        )

        TestEmail.send(
            statement,
            receiver=[self.user],
            template_name=bplan_emails.SubmitterConfirmation.template_name
        )

    def _send_bplan_update(self):
        # Send notification for bplan update
        bplan = Bplan.objects.first()
        if not bplan:
            raise CommandError('At least one bplan field update is required')

        TestEmail.send(
            bplan,
            receiver=[self.user],
            template_name=bplan_emails.
            OfficeWorkerUpdateConfirmation.template_name
        )

    def _send_report_mails(self):
        report = Report.objects.first()
        if not report:
            raise CommandError('At least on report is required')

        TestEmail.send(
            report,
            receiver=[self.user],
            template_name=reports_emails.ReportCreatorEmail.template_name
        )

        TestEmail.send(
            report,
            receiver=[self.user],
            template_name=reports_emails.ReportModeratorEmail.template_name
        )

    def _send_allauth_password_reset(self):
        context = {"current_site": 'http://example.com/...',
                   "user": self.user,
                   "password_reset_url": 'http://example.com/...',
                   "request": None,
                   "username": self.user.username}

        TestEmail.send(self.user,
                       receiver=[self.user],
                       template_name='account/email/password_reset_key',
                       **context
                       )

    def _send_allauth_email_confirmation(self):
        context = {
            "user": self.user,
            "activate_url": 'http://example.com/...',
            "current_site": 'http://example.com/...',
            "key": 'the1454key',
        }

        TestEmail.send(
            self.user,
            receiver=[self.user],
            template_name='account/email/email_confirmation_signup',
            **context
        )

        TestEmail.send(
            self.user,
            receiver=[self.user],
            template_name='account/email/email_confirmation',
            **context
        )

    def _send_invitation_private_project(self):
        invite = project_models.ParticipantInvite.objects.first()
        if not invite:
            raise CommandError('At least one participant request is required')
        TestEmail.send(
            invite,
            receiver=[self.user],
            template_name='meinberlin_projects/emails/invite_participant'
        )

    def _send_invitation_moderator(self):
        invite = project_models.ModeratorInvite.objects.first()
        if not invite:
            raise CommandError('At least one moderator request is required')
        TestEmail.send(
            invite,
            receiver=[self.user],
            template_name='meinberlin_projects/emails/invite_moderator'
        )

    def _send_initiator_request(self):
        organisation = Organisation.objects.first()
        TestEmail.send(
            self.user,
            organisation=organisation,
            phone='01234567',
            receiver=[self.user],
            template_name='meinberlin_initiators/emails/initiator_request'
        )

    def _send_form_mail(self):
        emailformpage = EmailFormPage.objects.first()
        if not emailformpage:
            raise CommandError('At least one emailformpage obj is required')
        fields = {
            'Multi': 'some text with \n'
                     'newlines and \n'
                     'such things',
            'Single': 'just a single line of text that was entered',
            'More fields': 'more text',
            'No more fields': 'more text',
        }

        TestEmail.send(
            emailformpage,
            field_values=fields,
            receiver=[self.user],
            template_name='meinberlin_cms/emails/form_submission'
        )
<commit_msg>apps/notifications: remove nonexistent emails from email test management command<commit_after>from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError

from adhocracy4.actions.models import Action
from adhocracy4.actions.verbs import Verbs
from adhocracy4.comments.models import Comment
from adhocracy4.emails.mixins import SyncEmailMixin
from adhocracy4.projects.models import Project
from adhocracy4.reports import emails as reports_emails
from adhocracy4.reports.models import Report
from meinberlin.apps.bplan import emails as bplan_emails
from meinberlin.apps.bplan.models import Bplan
from meinberlin.apps.bplan.models import Statement
from meinberlin.apps.cms.models import EmailFormPage
from meinberlin.apps.contrib.emails import Email
from meinberlin.apps.ideas.models import Idea
from meinberlin.apps.notifications import emails as notification_emails
from meinberlin.apps.organisations.models import Organisation
from meinberlin.apps.projects import models as project_models

User = get_user_model()

class TestEmail(SyncEmailMixin, Email):
    def get_receivers(self):
        return self.kwargs['receiver']

    def dispatch(self, object, *args, **kwargs):
        self.template_name = kwargs.pop('template_name')
        print('Sending template: {} with object "{}"'.format(
            self.template_name,
            str(object)))
        super().dispatch(object, *args, **kwargs)

    def get_context(self):
        context = super().get_context()
        context['project'] = getattr(self.object, 'project', None)
        context['contact_email'] = settings.CONTACT_EMAIL
        return context

class Command(BaseCommand):
    help = 'Send test emails to a registered user.'

    def add_arguments(self, parser):
        parser.add_argument('email')

    def handle(self, *args, **options):
        self.user = User.objects.get(email=options['email'])

        self._send_notifications_create_idea()
        self._send_notifications_comment_idea()
        self._send_notification_phase()
        self._send_notification_project_created()
        self._send_bplan_statement()
        self._send_bplan_update()

        self._send_report_mails()

        self._send_allauth_email_confirmation()
        self._send_allauth_password_reset()

        self._send_invitation_private_project()
        self._send_invitation_moderator()
        self._send_initiator_request()

        self._send_form_mail()

    def _send_notifications_create_idea(self):
        # Send notification for a newly created item
        action = Action.objects.filter(
            verb=Verbs.ADD.value,
            obj_content_type=ContentType.objects.get_for_model(Idea)
        ).exclude(project=None).first()
        if not action:
            raise CommandError('At least one idea is required')

        self._send_notify_create_item(action)

    def _send_notifications_comment_idea(self):
        # Send notifications for a comment on a item
        action = Action.objects.filter(
            verb=Verbs.ADD.value,
            obj_content_type=ContentType.objects.get_for_model(Comment),
            target_content_type=ContentType.objects.get_for_model(Idea)
        ).exclude(project=None).first()
        if not action:
            raise CommandError('At least one idea with a comment is required')

        self._send_notify_create_item(action)

    def _send_notify_create_item(self, action):
        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyCreatorEmail.template_name)

        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyModeratorsEmail.template_name)

    def _send_notification_phase(self):
        action = Action.objects.filter(
            verb=Verbs.SCHEDULE.value
        ).first()
        TestEmail.send(
            action,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyFollowersOnPhaseIsOverSoonEmail.template_name
        )

    def _send_notification_project_created(self):
        project = Project.objects.first()
        TestEmail.send(
            project,
            project=project,
            creator=self.user,
            receiver=[self.user],
            template_name=notification_emails.
            NotifyInitiatorsOnProjectCreatedEmail.template_name
        )

    def _send_bplan_statement(self):
        statement = Statement.objects.first()
        if not statement:
            raise CommandError('At least one bplan statement is required')

        TestEmail.send(
            statement,
            receiver=[self.user],
            template_name=bplan_emails.OfficeWorkerNotification.template_name
        )

        TestEmail.send(
            statement,
            receiver=[self.user],
            template_name=bplan_emails.SubmitterConfirmation.template_name
        )

    def _send_bplan_update(self):
        # Send notification for bplan update
        bplan = Bplan.objects.first()
        if not bplan:
            raise CommandError('At least one bplan is required')

        TestEmail.send(
            bplan,
            receiver=[self.user],
            template_name=bplan_emails.
            OfficeWorkerUpdateConfirmation.template_name
        )

    def _send_report_mails(self):
        report = Report.objects.first()
        if not report:
            raise CommandError('At least on report is required')

        TestEmail.send(
            report,
            receiver=[self.user],
            template_name=reports_emails.ReportModeratorEmail.template_name
        )

    def _send_allauth_password_reset(self):
        context = {"current_site": 'http://example.com/...',
                   "user": self.user,
                   "password_reset_url": 'http://example.com/...',
                   "request": None,
                   "username": self.user.username}

        TestEmail.send(self.user,
                       receiver=[self.user],
                       template_name='account/email/password_reset_key',
                       **context
                       )

    def _send_allauth_email_confirmation(self):
        context = {
            "user": self.user,
            "activate_url": 'http://example.com/...',
            "current_site": 'http://example.com/...',
            "key": 'the1454key',
        }

        TestEmail.send(
            self.user,
            receiver=[self.user],
            template_name='account/email/email_confirmation_signup',
            **context
        )

        TestEmail.send(
            self.user,
            receiver=[self.user],
            template_name='account/email/email_confirmation',
            **context
        )

    def _send_invitation_private_project(self):
        invite = project_models.ParticipantInvite.objects.first()
        if not invite:
            raise CommandError('At least one participant request is required')
        TestEmail.send(
            invite,
            receiver=[self.user],
            template_name='meinberlin_projects/emails/invite_participant'
        )

    def _send_invitation_moderator(self):
        invite = project_models.ModeratorInvite.objects.first()
        if not invite:
            raise CommandError('At least one moderator request is required')
        TestEmail.send(
            invite,
            receiver=[self.user],
            template_name='meinberlin_projects/emails/invite_moderator'
        )

    def _send_initiator_request(self):
        organisation = Organisation.objects.first()
        TestEmail.send(
            self.user,
            organisation=organisation,
            phone='01234567',
            receiver=[self.user],
            template_name='meinberlin_initiators/emails/initiator_request'
        )

    def _send_form_mail(self):
        emailformpage = EmailFormPage.objects.first()
        if not emailformpage:
            raise CommandError('At least one emailformpage obj is required')
        fields = {
            'Multi': 'some text with \n'
                     'newlines and \n'
                     'such things',
            'Single': 'just a single line of text that was entered',
            'More fields': 'more text',
            'No more fields': 'more text',
        }

        TestEmail.send(
            emailformpage,
            field_values=fields,
            receiver=[self.user],
            template_name='meinberlin_cms/emails/form_submission'
        )
<|endoftext|>


<commit_before>from invoke import task, run as run_

from .base import BaseTest

class Rubyspecs(BaseTest):
    def __init__(self, files, options, untranslated=False):
        super(Rubyspecs, self).__init__()
        self.exe = "`pwd`/bin/%s" % ("topaz_untranslated.py" if untranslated else "topaz")
        self.files = files
        self.options = options
        self.download_mspec()
        self.download_rubyspec()

    def mspec(self, args):
        run_("../mspec/bin/mspec %s -t %s --config=topaz.mspec %s" % (args, self.exe, self.files))

    def run(self):
        self.mspec("run -G fails %s" % self.options)

    def tag(self):
        self.mspec("tag --add fails -G fails -f spec %s" % self.options)

    def untag(self):
        self.mspec("tag --del fails -g fails -f spec %s" % self.options)

def generate_spectask(taskname):
    def spectask(files="", options="", untranslated=False):
        runner = Rubyspecs(files, options, untranslated=untranslated)
        getattr(runner, taskname)()
    spectask.__name__ = taskname
    return task(spectask)

run = generate_spectask("run")
tag = generate_spectask("tag")
untag = generate_spectask("untag")
<commit_msg>temporary, for debgugging<commit_after>from invoke import task, run as run_

from .base import BaseTest

class Rubyspecs(BaseTest):
    def __init__(self, files, options, untranslated=False):
        super(Rubyspecs, self).__init__()
        self.exe = "`pwd`/bin/%s" % ("topaz_untranslated.py" if untranslated else "topaz")
        self.files = files
        self.options = options
        self.download_mspec()
        self.download_rubyspec()

    def mspec(self, args):
        run_("../mspec/bin/mspec %s -t %s --config=topaz.mspec %s" % (args, self.exe, self.files))

    def run(self):
        self.mspec("run -G fails %s -f spec" % self.options)

    def tag(self):
        self.mspec("tag --add fails -G fails -f spec %s" % self.options)

    def untag(self):
        self.mspec("tag --del fails -g fails -f spec %s" % self.options)

def generate_spectask(taskname):
    def spectask(files="", options="", untranslated=False):
        runner = Rubyspecs(files, options, untranslated=untranslated)
        getattr(runner, taskname)()
    spectask.__name__ = taskname
    return task(spectask)

run = generate_spectask("run")
tag = generate_spectask("tag")
untag = generate_spectask("untag")
<|endoftext|>