<commit_before># -*- coding: utf-8 -*-

"""

ZUGBRUECKE
Calling routines in Windows DLLs from Python scripts running on unixlike systems
https://github.com/pleiszenburg/zugbruecke

	src/zugbruecke/core/session.py: A user-facing ctypes-drop-in-replacement session

	Required to run on platform / side: [UNIX]

	Copyright (C) 2017-2019 Sebastian M. Ernst <ernst@pleiszenburg.de>

<LICENSE_BLOCK>
The contents of this file are subject to the GNU Lesser General Public License
Version 2.1 ("LGPL" or "License"). You may not use this file except in
compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
https://github.com/pleiszenburg/zugbruecke/blob/master/LICENSE

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
specific language governing rights and limitations under the License.
</LICENSE_BLOCK>

"""

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members required by wrapper
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import (
	_FUNCFLAG_CDECL,
	DEFAULT_MODE
	)

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members, which will exported as they are
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import LibraryLoader # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members, which will be modified
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import CDLL as __ctypes_CDLL_class__

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: zugbruecke core and missing ctypes flags
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from .session_client import __session_client_class__
from .const import _FUNCFLAG_STDCALL # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# SESSION CTYPES-DROP-IN-REPLACEMENT CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class session_class:

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# static
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	LibraryLoader = LibraryLoader
	_FUNCFLAG_STDCALL = _FUNCFLAG_STDCALL

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# constructor
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	def __init__(self):

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# zugbruecke session client
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		# Start new zugbruecke session
		self._zb_current_session = __session_client_class__() # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows - accessed via server
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		self.FormatError = self._zb_current_session.ctypes_FormatError # EXPORT

		self.get_last_error = self._zb_current_session.ctypes_get_last_error # EXPORT

		self.GetLastError = self._zb_current_session.ctypes_GetLastError # EXPORT

		self.set_last_error = self._zb_current_session.ctypes_set_last_error # EXPORT

		self.WinError = self._zb_current_session.ctypes_WinError # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# CFUNCTYPE & WINFUNCTYPE
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		# CFUNCTYPE and WINFUNCTYPE function pointer factories
		self.CFUNCTYPE = self._zb_current_session.ctypes_CFUNCTYPE # EXPORT
		self.WINFUNCTYPE = self._zb_current_session.ctypes_WINFUNCTYPE # EXPORT

		# Used as cache by CFUNCTYPE and WINFUNCTYPE
		self._c_functype_cache = self._zb_current_session.data.cache_dict['func_type'][_FUNCFLAG_CDECL] # EXPORT
		self._win_functype_cache = self._zb_current_session.data.cache_dict['func_type'][_FUNCFLAG_STDCALL] # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Wine-related stuff
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		self._zb_path_unix_to_wine = self._zb_current_session.path_unix_to_wine
		self._zb_path_wine_to_unix = self._zb_current_session.path_wine_to_unix

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows, currently stubbed in zugbruecke
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	@staticmethod
	def DllCanUnloadNow(): # EXPORT
		pass # TODO stub - required for COM

	@staticmethod
	def DllGetClassObject(rclsid, riid, ppv): # EXPORT
		pass # TODO stub - required for COM

	@staticmethod
	class HRESULT: # EXPORT
		pass # TODO stub - special form of c_long, will require changes to argument parser

	@staticmethod
	def _check_HRESULT(result): # EXPORT
		pass # TODO stub - method for HRESULT, checks error bit, raises error if true. Needs reimplementation.

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows, provided via zugbruecke
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# EXPORT: Wrapper for CDLL class
def CDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	):

	# If there is a handle to a zugbruecke session, return session
	if handle is not None:

		# Handle zugbruecke handle
		if type(handle).__name__ == 'dll_client_class':

			# Return it as-is TODO what about a new name?
			return handle

		# Handle ctypes handle
		else:

			# Return ctypes DLL class instance, let it handle the handle as it would
			return __ctypes_CDLL_class__(name, mode, handle, use_errno, use_last_error)

	# If no handle was passed, it's a new library
	else:

		# Let's try the Wine side first
		try:

			# Return a handle on dll_client object
			return _zb_current_session.load_library(
				dll_name = name, dll_type = 'cdll', dll_param = {
					'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
					}
				)

		# Well, it might be a Unix library after all
		except:

			# If Unix library, return CDLL class instance
			return __ctypes_CDLL_class__(name, mode, handle, use_errno, use_last_error)

def WinDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	): # EXPORT

	return _zb_current_session.load_library(
		dll_name = name, dll_type = 'windll', dll_param = {
			'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
			}
		)

def OleDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	): # EXPORT

	return _zb_current_session.load_library(
		dll_name = name, dll_type = 'oledll', dll_param = {
			'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
			}
		)

# Set up and expose dll library loader objects
cdll = LibraryLoader(CDLL) # EXPORT
windll = LibraryLoader(WinDLL) # EXPORT
oledll = LibraryLoader(OleDLL) # EXPORT
<commit_msg>removed obsolete comments<commit_after># -*- coding: utf-8 -*-

"""

ZUGBRUECKE
Calling routines in Windows DLLs from Python scripts running on unixlike systems
https://github.com/pleiszenburg/zugbruecke

	src/zugbruecke/core/session.py: A user-facing ctypes-drop-in-replacement session

	Required to run on platform / side: [UNIX]

	Copyright (C) 2017-2019 Sebastian M. Ernst <ernst@pleiszenburg.de>

<LICENSE_BLOCK>
The contents of this file are subject to the GNU Lesser General Public License
Version 2.1 ("LGPL" or "License"). You may not use this file except in
compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
https://github.com/pleiszenburg/zugbruecke/blob/master/LICENSE

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
specific language governing rights and limitations under the License.
</LICENSE_BLOCK>

"""

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members required by wrapper
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import (
	_FUNCFLAG_CDECL,
	DEFAULT_MODE
	)

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members, which will exported as they are
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import LibraryLoader # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: Unix ctypes members, which will be modified
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from ctypes import CDLL as __ctypes_CDLL_class__

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# IMPORT: zugbruecke core and missing ctypes flags
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

from .session_client import __session_client_class__
from .const import _FUNCFLAG_STDCALL # EXPORT

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# SESSION CTYPES-DROP-IN-REPLACEMENT CLASS
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

class session_class:

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# static
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	LibraryLoader = LibraryLoader
	_FUNCFLAG_STDCALL = _FUNCFLAG_STDCALL

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# constructor
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	def __init__(self):

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# zugbruecke session client
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		# Start new zugbruecke session
		self._zb_current_session = __session_client_class__()

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows - accessed via server
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		self.FormatError = self._zb_current_session.ctypes_FormatError

		self.get_last_error = self._zb_current_session.ctypes_get_last_error

		self.GetLastError = self._zb_current_session.ctypes_GetLastError

		self.set_last_error = self._zb_current_session.ctypes_set_last_error

		self.WinError = self._zb_current_session.ctypes_WinError

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# CFUNCTYPE & WINFUNCTYPE
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		# CFUNCTYPE and WINFUNCTYPE function pointer factories
		self.CFUNCTYPE = self._zb_current_session.ctypes_CFUNCTYPE
		self.WINFUNCTYPE = self._zb_current_session.ctypes_WINFUNCTYPE

		# Used as cache by CFUNCTYPE and WINFUNCTYPE
		self._c_functype_cache = self._zb_current_session.data.cache_dict['func_type'][_FUNCFLAG_CDECL]
		self._win_functype_cache = self._zb_current_session.data.cache_dict['func_type'][_FUNCFLAG_STDCALL]

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Wine-related stuff
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		self._zb_path_unix_to_wine = self._zb_current_session.path_unix_to_wine
		self._zb_path_wine_to_unix = self._zb_current_session.path_wine_to_unix

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows, currently stubbed in zugbruecke
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	@staticmethod
	def DllCanUnloadNow(): # EXPORT
		pass # TODO stub - required for COM

	@staticmethod
	def DllGetClassObject(rclsid, riid, ppv): # EXPORT
		pass # TODO stub - required for COM

	@staticmethod
	class HRESULT: # EXPORT
		pass # TODO stub - special form of c_long, will require changes to argument parser

	@staticmethod
	def _check_HRESULT(result): # EXPORT
		pass # TODO stub - method for HRESULT, checks error bit, raises error if true. Needs reimplementation.

# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Routines only availabe on Wine / Windows, provided via zugbruecke
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# EXPORT: Wrapper for CDLL class
def CDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	):

	# If there is a handle to a zugbruecke session, return session
	if handle is not None:

		# Handle zugbruecke handle
		if type(handle).__name__ == 'dll_client_class':

			# Return it as-is TODO what about a new name?
			return handle

		# Handle ctypes handle
		else:

			# Return ctypes DLL class instance, let it handle the handle as it would
			return __ctypes_CDLL_class__(name, mode, handle, use_errno, use_last_error)

	# If no handle was passed, it's a new library
	else:

		# Let's try the Wine side first
		try:

			# Return a handle on dll_client object
			return _zb_current_session.load_library(
				dll_name = name, dll_type = 'cdll', dll_param = {
					'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
					}
				)

		# Well, it might be a Unix library after all
		except:

			# If Unix library, return CDLL class instance
			return __ctypes_CDLL_class__(name, mode, handle, use_errno, use_last_error)

def WinDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	): # EXPORT

	return _zb_current_session.load_library(
		dll_name = name, dll_type = 'windll', dll_param = {
			'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
			}
		)

def OleDLL(
	name, mode = DEFAULT_MODE, handle = None,
	use_errno = False,
	use_last_error = False
	): # EXPORT

	return _zb_current_session.load_library(
		dll_name = name, dll_type = 'oledll', dll_param = {
			'mode': mode, 'use_errno': use_errno, 'use_last_error': use_last_error
			}
		)

# Set up and expose dll library loader objects
cdll = LibraryLoader(CDLL) # EXPORT
windll = LibraryLoader(WinDLL) # EXPORT
oledll = LibraryLoader(OleDLL) # EXPORT
<|endoftext|>


<commit_before>from glgm import *
from itertools import product
import time, timeit
from numpy import (sin, cos, amax)
from numpy.testing import (assert_array_almost_equal,
                           assert_almost_equal)

def testFA(d = 10, N = 5000, k = 4, min_iter_nr = 20):
    """
    The present test code comes from Modular toolkit for Data Processing (MDP)
    source file test_FANode.py, slightly adapted to work with glgm.fa.
    """

    print "Input: dim, samples nr = %d, %d - Output: latent factors nr = %d" % (d, N, k)
    mu = uniform(1, d)*3.+2.
    sigma = uniform((d,))*0.01
    A = normal(size=(k,d))

    # latent variables
    y = normal(0., 1., size=(N, k))
    # observations
    noise = normal(0., 1., size=(N, d)) * sigma
    x = dot(y, A) + mu + noise

    for _b, _n in product((True, False), (min_iter_nr, min_iter_nr*3)):
        t_start = time.time()
        FA = fa(x.T, k = k)
        FA.InferandLearn(max_iter_nr = _n, inferwithLemma = _b)
        print "Model FA(max_iter_nr=%d, inferwithLemma=%s) learned in %.5f seconds" \
            % (_n, str(_b), time.time() - t_start)

        # compare estimates to real parameters
        assert_array_almost_equal(FA.mu_y(), mean(x, axis=0).reshape(d, 1), 5)
        assert_array_almost_equal(FA.R, std(noise, axis=0)**2, 2)

        # FA finds C only up to a rotation. here we verify that the
        # C and its estimation span the same subspace
        CC = concatenate((A,FA.C.T),axis=0)
        u,s,vh = svd(CC)
        assert sum(s / max(s) > 1e-2) == k, 'C and its estimation do not span the same subspace'

        y = FA.get_expected_latent(x.T)
        xn = FA.get_new_observed(10000)
        xn = FA.get_new_observed(10000, noised = True)
        xn = FA.get_new_observed(y)
        xn = FA.get_new_observed(y, noised = True)

        # test that noise has the right mean and variance
        est = FA.get_new_observed(zeros((k, 10*N)), noised = True)
        est -= FA.mu_y()
        assert_array_almost_equal(diag(cov(est, rowvar=1)), FA.R, 3)
        assert_almost_equal(amax(abs(mean(est, axis=1)), axis=None), 0., 2)

        est = FA.get_new_observed(100000).T
        assert_array_almost_equal(cov(est, rowvar=0), dot(FA.C, FA.C.T), 1)

def testFA_singularCov():

    x = array([[ 1., 1., 0., 0., 0.],
               [ 0., 1., 1., 0., 0.],
               [ 0., 1., 0., 0., 0.],
               [ 0., 1., 1., 0., 0.],
               [ 0., 1., 0., 0., 1.],
               [ 0., 1., 0., 1., 0.],
               [ 0., 1., 0., 0., 0.],
               [ 1., 1., 0., 0., 0.],
               [ 1., 1., 0., 0., 0.],
               [ 0., 1., 0., 1., 1.]])

    FA = fa(x.T, k = 3)
    FA.InferandLearn()

if __name__ == '__main__':

    testFA()
    testFA(k=3)
    #testFA(100, 20000, 10, 50)
    #testFA_singularCov()
<commit_msg>New test: from 30-D input to 5-D output<commit_after>from glgm import *
from itertools import product
import time, timeit
from numpy import (sin, cos, amax)
from numpy.testing import (assert_array_almost_equal,
                           assert_almost_equal)

def testFA(d = 10, N = 5000, k = 4, min_iter_nr = 20):
    """
    The present test code comes from Modular toolkit for Data Processing (MDP)
    source file test_FANode.py, slightly adapted to work with glgm.fa.
    """

    print "Input: dim, samples nr = %d, %d - Output: latent factors nr = %d" % (d, N, k)
    mu = uniform(1, d)*3.+2.
    sigma = uniform((d,))*0.01
    A = normal(size=(k,d))

    # latent variables
    y = normal(0., 1., size=(N, k))
    # observations
    noise = normal(0., 1., size=(N, d)) * sigma
    x = dot(y, A) + mu + noise

    for _b, _n in product((True, False), (min_iter_nr, min_iter_nr*3)):
        t_start = time.time()
        FA = fa(x.T, k = k)
        FA.InferandLearn(max_iter_nr = _n, inferwithLemma = _b)
        print "Model FA(max_iter_nr=%d, inferwithLemma=%s) learned in %.5f seconds" \
            % (_n, str(_b), time.time() - t_start)

        # compare estimates to real parameters
        assert_array_almost_equal(FA.mu_y(), mean(x, axis=0).reshape(d, 1), 5)
        assert_array_almost_equal(FA.R, std(noise, axis=0)**2, 2)

        # FA finds C only up to a rotation. here we verify that the
        # C and its estimation span the same subspace
        CC = concatenate((A,FA.C.T),axis=0)
        u,s,vh = svd(CC)
        assert sum(s / max(s) > 1e-2) == k, 'C and its estimation do not span the same subspace'

        y = FA.get_expected_latent(x.T)
        xn = FA.get_new_observed(10000)
        xn = FA.get_new_observed(10000, noised = True)
        xn = FA.get_new_observed(y)
        xn = FA.get_new_observed(y, noised = True)

        # test that noise has the right mean and variance
        est = FA.get_new_observed(zeros((k, 10*N)), noised = True)
        est -= FA.mu_y()
        assert_array_almost_equal(diag(cov(est, rowvar=1)), FA.R, 3)
        assert_almost_equal(amax(abs(mean(est, axis=1)), axis=None), 0., 2)

        est = FA.get_new_observed(100000).T
        assert_array_almost_equal(cov(est, rowvar=0), dot(FA.C, FA.C.T), 1)

def testFA_singularCov():

    x = array([[ 1., 1., 0., 0., 0.],
               [ 0., 1., 1., 0., 0.],
               [ 0., 1., 0., 0., 0.],
               [ 0., 1., 1., 0., 0.],
               [ 0., 1., 0., 0., 1.],
               [ 0., 1., 0., 1., 0.],
               [ 0., 1., 0., 0., 0.],
               [ 1., 1., 0., 0., 0.],
               [ 1., 1., 0., 0., 0.],
               [ 0., 1., 0., 1., 1.]])

    FA = fa(x.T, k = 3)
    FA.InferandLearn()

if __name__ == '__main__':

    testFA()
    testFA(k=3)
    testFA(d=30, N=20000, k=5)
    #testFA(100, 20000, 10, 50)
    #testFA_singularCov()
<|endoftext|>


<commit_before>from unittest import TestCase

import pydbc
import json
import random

class SelectBaseTestCase(object):
    """
    Children are expected to provide the following attributes:

    self.dsn
    self.supports_row_count
    """

    def setUp(self):
        self.connection = pydbc.connect(self.dsn)
        self.cursor = self.connection.cursor()

    def tearDown(self):
        self.cursor.close()
        self.connection.close()

    def _test_single_row_result_set(self, query, expected_row):
        self.cursor.execute(query)

        if self.supports_row_count:
            self.assertEqual(self.cursor.rowcount, 1)
        else:
            self.assertEqual(self.cursor.rowcount, -1)

        row = self.cursor.fetchone()
        self.assertItemsEqual(row, expected_row)

        row = self.cursor.fetchone()
        self.assertIsNone(row)

    def test_single_row_NULL_result(self):
        self._test_single_row_result_set("SELECT NULL", [None])

    def test_single_row_integer_result(self):
        self._test_single_row_result_set("SELECT 42", [42])

    def test_single_row_string_result(self):
        self._test_single_row_result_set("SELECT 'value'", ["value"])

    def test_single_row_unicode_result(self):
        self._test_single_row_result_set(u"SELECT 'value \u2665'", [u"value \u2665"])

    def test_single_row_large_numeric_result_as_string(self):
        self._test_single_row_result_set("SELECT -1234567890123.123456789", ['-1234567890123.123456789'])

    def test_single_row_multiple_integer_result(self):
        self._test_single_row_result_set("SELECT 40, 41, 42, 43", [40, 41, 42, 43])

    def test_single_row_double_table(self):
        with open(self.schema_file, 'r') as file:
            db_queries = json.load(file)['SELECT DOUBLE']
            table_name = table_name = 'test_{}'.format(random.randint(0, 1000000000))

            for query in db_queries['setup']:
                self.cursor.execute(query.format(table_name=table_name))

            self.cursor.execute(db_queries['payload'].format(table_name=table_name))
            row = self.cursor.fetchone()
            self.assertItemsEqual(row, [3.14])

            for query in db_queries['teardown']:
                self.cursor.execute(query.format(table_name=table_name))

    def test_single_row_double_result(self):
        self.cursor.execute("select a from test_read_double")
        self.assertIn(self.cursor.rowcount, [-1, 1])
        row = self.cursor.fetchone()
        self.assertItemsEqual(row, [3.14])
        row = self.cursor.fetchone()
        self.assertIsNone(row)

    def test_multiple_row_iterate_result(self):
        self.cursor.execute("delete from test_integer")
        for i in xrange(1,10):
            self.cursor.execute("insert into test_integer values("+str(i)+")")
        self.cursor.execute("select * from test_integer order by a")
        for element in enumerate(self.cursor, start=1):
            self.assertItemsEqual([element[0]], element[1])

# Actual test cases

class TestSelectExasol(SelectBaseTestCase, TestCase):
    dsn = "Exasol R&D test database"
    supports_row_count = True
    schema_file = 'db_scripts_exasol.json'

class TestSelectPostgreSQL(SelectBaseTestCase, TestCase):
    dsn = "PostgreSQL R&D test database"
    supports_row_count = False
    schema_file = 'db_scripts_postgresql.json'

class TestSelectMySQL(SelectBaseTestCase, TestCase):
    dsn = "MySQL R&D test database"
    supports_row_count = True
    schema_file = 'db_scripts_mysql.json'
<commit_msg>Extract query fixture to context manager<commit_after>from unittest import TestCase

from contextlib import contextmanager

import pydbc
import json
import random

@contextmanager
def query_fixture(cursor, file_name, fixture_key):
    """
    Context manager used to set up fixtures for setting up queries.
    :param file_name: Name of file which contains fixtures in JSON format
    :param fixture_key: Identifies the fixture

    The context manager performs the following tasks:
    * Execute all queries listed in the fixture's "setup" section
    * Return the query listed in the fixture's "payload" section
    * Execute all queries listed in the fixture's "teardown" section

    The fixture file should have the following format:

    {
        "my_fixture_key": {
            "setup": ["A POTENTIALLY EMPTY LIST OF SQL QUERIES"],
            "payload": "SELECT 42",
            "teardown": ["MAY INCLUDE", "MULTIPLE QUERIES"]
        }
    }

    Setup and teardown sections are optional. Queries may contain
    "{table_name}" to be replaced with a random table name.
    """
    with open(file_name, 'r') as file:
        fixture = json.load(file)[fixture_key]

    table_name = table_name = 'test_{}'.format(random.randint(0, 1000000000))

    def _execute_queries(section_key):
        queries = fixture.get(section_key, [])
        if not isinstance(queries, list):
            queries = [queries]

        for query in queries:
            try:
                cursor.execute(query.format(table_name=table_name))
            except Exception as error:
                raise type(error)('Error during {} of query fixture "{}": {}'.format(section_key, fixture_key, error))

    _execute_queries("setup")
    try:
        yield fixture['payload'].format(table_name=table_name)
    finally:
        _execute_queries("teardown")

class SelectBaseTestCase(object):
    """
    Children are expected to provide the following attributes:

    self.dsn
    self.supports_row_count
    """

    def setUp(self):
        self.connection = pydbc.connect(self.dsn)
        self.cursor = self.connection.cursor()

    def tearDown(self):
        self.cursor.close()
        self.connection.close()

    def _test_single_row_result_set(self, query, expected_row):
        self.cursor.execute(query)

        if self.supports_row_count:
            self.assertEqual(self.cursor.rowcount, 1)
        else:
            self.assertEqual(self.cursor.rowcount, -1)

        row = self.cursor.fetchone()
        self.assertItemsEqual(row, expected_row)

        row = self.cursor.fetchone()
        self.assertIsNone(row)

    def test_single_row_NULL_result(self):
        self._test_single_row_result_set("SELECT NULL", [None])

    def test_single_row_integer_result(self):
        self._test_single_row_result_set("SELECT 42", [42])

    def test_single_row_string_result(self):
        self._test_single_row_result_set("SELECT 'value'", ["value"])

    def test_single_row_unicode_result(self):
        self._test_single_row_result_set(u"SELECT 'value \u2665'", [u"value \u2665"])

    def test_single_row_large_numeric_result_as_string(self):
        self._test_single_row_result_set("SELECT -1234567890123.123456789", ['-1234567890123.123456789'])

    def test_single_row_multiple_integer_result(self):
        self._test_single_row_result_set("SELECT 40, 41, 42, 43", [40, 41, 42, 43])

    def test_single_row_double_result(self):
        with query_fixture(self.cursor, self.schema_file, 'SELECT DOUBLE') as query:
            self.cursor.execute(query)
            row = self.cursor.fetchone()
            self.assertItemsEqual(row, [3.14])

    def test_multiple_row_iterate_result(self):
        self.cursor.execute("delete from test_integer")
        for i in xrange(1,10):
            self.cursor.execute("insert into test_integer values("+str(i)+")")
        self.cursor.execute("select * from test_integer order by a")
        for element in enumerate(self.cursor, start=1):
            self.assertItemsEqual([element[0]], element[1])

# Actual test cases

class TestSelectExasol(SelectBaseTestCase, TestCase):
    dsn = "Exasol R&D test database"
    supports_row_count = True
    schema_file = 'db_scripts_exasol.json'

class TestSelectPostgreSQL(SelectBaseTestCase, TestCase):
    dsn = "PostgreSQL R&D test database"
    supports_row_count = False
    schema_file = 'db_scripts_postgresql.json'

class TestSelectMySQL(SelectBaseTestCase, TestCase):
    dsn = "MySQL R&D test database"
    supports_row_count = True
    schema_file = 'db_scripts_mysql.json'
<|endoftext|>


<commit_before>#!/usr/bin/python

import socket
import struct
import PiVisConstants

class PiVisClient:
    def __init__(self, scheduler, portNo, imageSize):
        self.serviceNo = -1
        self.portNo = portNo
        self.serviceNo = PiVisConstants.DISCOVER_IMAGE_DATA_SERVICE
        self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serviceDiscoverySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        self.serviceDiscoverySocket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
        self.stateIndex = 0
        self.states = [self.findService, self.connect, self.connected]
        self.piVisServerAddress = ""
        self.imageSize = imageSize
        self.data = []
        scheduler.registerRunnable(self.run)

    def findService(self):
        data = bytearray()
        address = bytearray()
        data.extend(map(ord, PiVisConstants.SERVICE_DISCOVER_REQUEST_HEADER + str(self.portNo)))
        self.serviceDiscoverySocket.sendto(data,  ("224.1.1.1", self.serviceNo))
        self.serviceDiscoverySocket.settimeout(1)
        try:
            address = self.serviceDiscoverySocket.recv(13)
        except socket.timeout:
            pass
        except:
            raise
        else:
            self.serviceDiscoverySocket.close()
            self.piVisServerAddress = str(address, 'utf-8').split('\x00')[0]
            print("PiVisServer service found at " + self.piVisServerAddress)
            self.stateIndex += 1

    def connect(self):
        try:
            print("Attempting to connect to " + self.piVisServerAddress + " " + str(self.portNo))
            self.serverSocket.connect((self.piVisServerAddress, self.portNo))
        except:
            raise
        else:
            print("Connection established to PiVision server")
            self.stateIndex = self.stateIndex + 1

    def connected(self):
        self.receive()

    def getData(self):
        retVal = self.data
        return retVal

    def __receiveInternal(self, numBytes):
        data = []
        while len(data) < numBytes:
            try:
                packet = self.serverSocket.recv(numBytes - len(data))
                if not packet:
                    continue
                data += packet
            except socket.timeout:
                pass
        return data

    def receive(self):
        headerSize = 9 #1 byte image type, 4 bytes image size, 2 bytes xSize, 2 bytes ySize

        header = self.__receiveInternal(headerSize)

        imageSize = bytearray(header[1:5])
        imageSize = struct.unpack("<L", imageSize)[0]

        imageType = header[0:1]

        receiveBuf = self.__receiveInternal(imageSize)

        tmpBuf = []
        tmpBuf += imageType
        tmpBuf += receiveBuf
        self.data = tmpBuf

    def send(self, data):
        self.serverSocket.sendall(data)

    def run(self):
        self.states[self.stateIndex]()
<commit_msg>Improved ugly hack fix<commit_after>#!/usr/bin/python

import socket
import struct
import PiVisConstants

class PiVisClient:
    def __init__(self, scheduler, portNo, imageSize):
        self.serviceNo = -1
        self.portNo = portNo
        self.serviceNo = PiVisConstants.DISCOVER_IMAGE_DATA_SERVICE
        self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serviceDiscoverySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        self.serviceDiscoverySocket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
        self.stateIndex = 0
        self.states = [self.findService, self.connect, self.connected]
        self.piVisServerAddress = ""
        self.imageSize = imageSize
        self.data = []
        scheduler.registerRunnable(self.run)

    def findService(self):
        data = bytearray()
        address = bytearray()
        data.extend(map(ord, PiVisConstants.SERVICE_DISCOVER_REQUEST_HEADER + str(self.portNo)))
        self.serviceDiscoverySocket.sendto(data,  ("224.1.1.1", self.serviceNo))
        self.serviceDiscoverySocket.settimeout(1)
        try:
            address = self.serviceDiscoverySocket.recv(13)
        except socket.timeout:
            pass
        except:
            raise
        else:
            self.serviceDiscoverySocket.close()
            self.piVisServerAddress = str(address, 'utf-8').split('\x00')
            if len(self.piVisServerAddress):
                self.piVisServerAddress = self.piVisServerAddress[0]
            print("PiVisServer service found at " + self.piVisServerAddress)
            self.stateIndex += 1

    def connect(self):
        try:
            print("Attempting to connect to " + self.piVisServerAddress + " " + str(self.portNo))
            self.serverSocket.connect((self.piVisServerAddress, self.portNo))
        except:
            raise
        else:
            print("Connection established to PiVision server")
            self.stateIndex = self.stateIndex + 1

    def connected(self):
        self.receive()

    def getData(self):
        retVal = self.data
        return retVal

    def __receiveInternal(self, numBytes):
        data = []
        while len(data) < numBytes:
            try:
                packet = self.serverSocket.recv(numBytes - len(data))
                if not packet:
                    continue
                data += packet
            except socket.timeout:
                pass
        return data

    def receive(self):
        headerSize = 9 #1 byte image type, 4 bytes image size, 2 bytes xSize, 2 bytes ySize

        header = self.__receiveInternal(headerSize)

        imageSize = bytearray(header[1:5])
        imageSize = struct.unpack("<L", imageSize)[0]

        imageType = header[0:1]

        receiveBuf = self.__receiveInternal(imageSize)

        tmpBuf = []
        tmpBuf += imageType
        tmpBuf += receiveBuf
        self.data = tmpBuf

    def send(self, data):
        self.serverSocket.sendall(data)

    def run(self):
        self.states[self.stateIndex]()
<|endoftext|>


<commit_before># coding=utf8

# Python2 Mandelbrot.
#
# Usage: python2.7 mandelbrot.py <image_width> <image_height> <max_iterations> <repetitions (1+)> <center x> <center y> <section height> <gradient filename> <output filename>
# Example: python2.7 mandelbrot.py 320 200 20 1 -0.5 0.0 2.0 blue.gradient mandelbrot.raw
#
# Gradient file example:
#   0.0: 0.0, 0.0, 0.0
#   0.5: 0.0, 0.0, 1.0
#   1.0: 1.0, 1.0, 1.0
#
# Tobias Brückner, 2016

from __future__ import print_function

import re
import sys
import math

from time import time
from math import log, sqrt

REGEXP_GRADIENT_LINE = re.compile(r'([0-9]*\.?[0-9]+):\s*([0-9]*\.?[0-9]+),\s*([0-9]*\.?[0-9]+),\s*([0-9]*\.?[0-9]+)')

class GradientColor:
    def __init__(self, pos, r, g, b):
        self.pos = float(pos)
        self.update_colors(r, g, b)

    def update_colors(self, r, g, b):
        self.r = float(r)
        self.g = float(g)
        self.b = float(b)

    def __cmp__(self, other):
        if equal_enough(self.pos, other.pos):
            return 0
        elif self.pos < other.pos:
            return -1
        else:
            return 1

class Gradient:
    def __init__(self):
        self.colors = []

def lerp(a, b, t):
    return (1.0 - t) * a + t * b

def cumsum(hist):
    cdf = [0] * len(hist)
    total = 0
    for i, n in enumerate(hist):
        total += n
        cdf[i] = total
    return cdf

# Compare two float values for "enough" equality.
float_epsilon = sys.float_info.epsilon

def equal_enough(a, b):
    a = abs(a)
    b = abs(b)
    return abs(a - b) <= max(a, b) * float_epsilon

def gradient_get_color_at_position(gradient, pos):
    return next(iter(filter(lambda col: equal_enough(col.pos, pos), gradient.colors)), None)

def load_gradient(filename):
    gradient = Gradient()
    gradient.colors.append(GradientColor(0.0, 0.0, 0.0, 0.0))
    gradient.colors.append(GradientColor(1.0, 1.0, 1.0, 1.0))

    with open(filename, "r") as f:
        for line in f:
            match = REGEXP_GRADIENT_LINE.match(line)
            if match:
                data = match.groups()
                col = gradient_get_color_at_position(gradient, float(data[0]))
                if col:
                    col.update_colors(data[1], data[2], data[3])
                else:
                    gradient.colors.append(GradientColor(data[0], data[1], data[2], data[3]))
    gradient.colors.sort()
    return gradient

def color_from_gradient_range(left_color, right_color, pos):
    pos2 = (pos - left_color.pos) / (right_color.pos - left_color.pos)
    r = (right_color.r - left_color.r) * pos2 + left_color.r
    g = (right_color.g - left_color.g) * pos2 + left_color.g
    b = (right_color.b - left_color.b) * pos2 + left_color.b
    return r, g, b

def color_from_gradient(gradient, pos):
    for colors in zip(gradient.colors[:-1], gradient.colors[1:]):
        if pos >= colors[0].pos and pos <= colors[1].pos:
            return color_from_gradient_range(colors[0], colors[1], pos)
    return None

def mandelbrot_calc(image_width, image_height, max_iterations, center_x, center_y, height, iterations_per_pixel, distances_to_next_iteration_per_pixel):
    width = height * (float(image_width) / float(image_height))
    x_left = center_x - width / 2.0
    # x_right = center_x + width / 2.0
    y_top = center_y + height / 2.0
    # y_bottom = center_y - height / 2.0

    bailout = 20.0
    bailout_squared = bailout * bailout
    log_log_bailout = log(log(bailout))
    log_2 = log(2.0)

    # for simplicity we only use indices [1] .. [max_iterations], [0] is unused
    iterations_histogram = [0] * (max_iterations + 1)

    for pixel_y in xrange(image_height):
        y0 = y_top - height * (float(pixel_y) / float(image_height))

        for pixel_x in xrange(image_width):
            x0 = x_left + width * (float(pixel_x) / float(image_width))

            x = 0.0
            y = 0.0

            x_squared = 0.0
            y_squared = 0.0

            # iteration, will be from 1 .. max_iterations once the loop is done
            iter = 0

            for iter in xrange(max_iterations + 1):
                x_squared = x * x
                y_squared = y * y

                if x_squared + y_squared >= bailout_squared:
                    break

                y = 2.0 * x * y + y0
                x = x_squared - y_squared + x0

            if iter < max_iterations:
                final_magnitude = sqrt(x_squared + y_squared)
                distances_to_next_iteration_per_pixel[pixel_y * image_width + pixel_x] = 1.0 - min(1.0, (log(log(final_magnitude)) - log_log_bailout) / log_2)
                iterations_histogram[iter] += 1  # no need to count histogram[max_iterations]

            iterations_per_pixel[pixel_y * image_width + pixel_x] = iter  # 1 .. max_iterations
    return iterations_histogram

def equalize_histogram(iterations_histogram, max_iterations):
    # Calculate the CDF (Cumulative Distribution Function) by accumulating all iteration counts.
    # Element [0] is unused and iterations_histogram[max_iterations] should be zero (as we do not count
    # the iterations of the points inside the Mandelbrot Set).
    cdf = cumsum(iterations_histogram)

    # Get the minimum value in the CDF that is bigger than zero and the sum of all iteration counts
    # from iterations_histogram (which is the last value of the CDF).
    cdf_min = next(iter(filter(lambda x: x > 0, cdf)))
    total_iterations = cdf[-1]

    # normalize all values from the CDF that are bigger than zero to a range of 0.0 .. max_iterations
    f = max_iterations / float(total_iterations - cdf_min)
    return list(map(lambda c: (c - cdf_min) * f if c > 0 else 0, cdf))

def mandelbrot_colorize(image_width, image_height, max_iterations, gradient, image_data, iterations_histogram, iterations_per_pixel, distances_to_next_iteration_per_pixel):
    equalized_iterations = equalize_histogram(iterations_histogram, max_iterations)

    for pixel in xrange(image_width * image_height):
        iter = iterations_per_pixel[pixel]  # 1 .. max_iterations

        if iter == max_iterations:
            # points inside the Mandelbrot Set are always painted black
            image_data[3 * pixel + 0] = 0
            image_data[3 * pixel + 1] = 0
            image_data[3 * pixel + 2] = 0
        else:
            # The equalized iteration value (in the range of 0 .. max_iterations) represents the
            # position of the pixel color in the color gradiant and needs to be mapped to 0.0 .. 1.0.
            # To achieve smooth coloring we need to edge the equalized iteration towards the next
            # iteration, determined by the distance between the two iterations.
            iter_curr = equalized_iterations[iter]
            iter_next = equalized_iterations[iter + 1]

            smoothed_iteration = lerp(iter_curr, iter_next, distances_to_next_iteration_per_pixel[pixel])
            pos_in_gradient = smoothed_iteration / max_iterations

            r, g, b = color_from_gradient(gradient, pos_in_gradient)

            image_data[3 * pixel + 0] = int(255.0 * r)
            image_data[3 * pixel + 1] = int(255.0 * g)
            image_data[3 * pixel + 2] = int(255.0 * b)

def save_image(filename, image_data):
    with open(filename, "wb") as f:
        f.write(image_data)

def mean(values):
    return math.fsum(values) / len(values)

def median(values):
    values = sorted(values)
    count = len(values)
    if count % 2 == 1:
        return values[int((count-1) / 2)]
    else:
        return (values[int(count/2 - 1)] + values[int(count/2)]) / 2.0

def show_summary(durations):
    if len(durations) == 1:
        print("%f s" % durations[0])
    else:
        print("mean: %f s, median: %f s (repetitions=%d) %s" % (mean(durations), median(durations), len(durations), str(sorted(durations))))

def eval_int_arg(s, min, max):
    value = int(s)
    if value < min or value > max:
        raise ValueError("invalid value %s" % s)
    return value

def eval_float_arg(s, min, max):
    value = float(s)
    if value < min or value > max or math.isnan(value) or math.isinf(value):
        raise ValueError("invalid value %s" % s)
    return value

def eval_args():
    if len(sys.argv) < 10:
        raise RuntimeError("invalid number of arguments")

    image_width    = eval_int_arg(sys.argv[1], 1, 100000)
    image_height   = eval_int_arg(sys.argv[2], 1, 100000)
    max_iterations = eval_int_arg(sys.argv[3], 1, 1000000000)
    repetitions    = eval_int_arg(sys.argv[4], 1, 1000000)
    center_x       = eval_float_arg(sys.argv[5], -100.0, 100.0)
    center_y       = eval_float_arg(sys.argv[6], -100.0, 100.0)
    height         = eval_float_arg(sys.argv[7], -100.0, 100.0)
    colors         = sys.argv[8]
    filename       = sys.argv[9]

    return image_width, image_height, max_iterations, repetitions, center_x, center_y, height, colors, filename

def go(image_width, image_height, max_iterations, center_x, center_y, height, gradient, image_data, durations, repetitions):
    iterations_per_pixel = [0] * (image_width * image_height)
    distances_to_next_iteration_per_pixel = [0.0] * (image_width * image_height)

    for _ in xrange(repetitions):
        t1 = time()
        iterations_histogram = mandelbrot_calc(image_width, image_height, max_iterations, center_x, center_y, height, iterations_per_pixel, distances_to_next_iteration_per_pixel)
        mandelbrot_colorize(image_width, image_height, max_iterations, gradient, image_data, iterations_histogram, iterations_per_pixel, distances_to_next_iteration_per_pixel)
        t2 = time()
        durations.append(t2 - t1)

def main():
    image_width, image_height, max_iterations, repetitions, center_x, center_y, height, gradient_filename, filename = eval_args()
    gradient = load_gradient(gradient_filename)
    image_data = bytearray([0] * (image_width * image_height * 3))
    durations = []

    go(image_width, image_height, max_iterations, center_x, center_y, height, gradient, image_data, durations, repetitions)

    save_image(filename, image_data)
    show_summary(durations)

if __name__ == "__main__":
    main()
<commit_msg>[Python2] No need to calculate the pixel position<commit_after># coding=utf8

# Python2 Mandelbrot.
#
# Usage: python2.7 mandelbrot.py <image_width> <image_height> <max_iterations> <repetitions (1+)> <center x> <center y> <section height> <gradient filename> <output filename>
# Example: python2.7 mandelbrot.py 320 200 20 1 -0.5 0.0 2.0 blue.gradient mandelbrot.raw
#
# Gradient file example:
#   0.0: 0.0, 0.0, 0.0
#   0.5: 0.0, 0.0, 1.0
#   1.0: 1.0, 1.0, 1.0
#
# Tobias Brückner, 2016

from __future__ import print_function

import re
import sys
import math

from time import time
from math import log, sqrt

REGEXP_GRADIENT_LINE = re.compile(r'([0-9]*\.?[0-9]+):\s*([0-9]*\.?[0-9]+),\s*([0-9]*\.?[0-9]+),\s*([0-9]*\.?[0-9]+)')

class GradientColor:
    def __init__(self, pos, r, g, b):
        self.pos = float(pos)
        self.update_colors(r, g, b)

    def update_colors(self, r, g, b):
        self.r = float(r)
        self.g = float(g)
        self.b = float(b)

    def __cmp__(self, other):
        if equal_enough(self.pos, other.pos):
            return 0
        elif self.pos < other.pos:
            return -1
        else:
            return 1

class Gradient:
    def __init__(self):
        self.colors = []

def lerp(a, b, t):
    return (1.0 - t) * a + t * b

def cumsum(hist):
    cdf = [0] * len(hist)
    total = 0
    for i, n in enumerate(hist):
        total += n
        cdf[i] = total
    return cdf

# Compare two float values for "enough" equality.
float_epsilon = sys.float_info.epsilon

def equal_enough(a, b):
    a = abs(a)
    b = abs(b)
    return abs(a - b) <= max(a, b) * float_epsilon

def gradient_get_color_at_position(gradient, pos):
    return next(iter(filter(lambda col: equal_enough(col.pos, pos), gradient.colors)), None)

def load_gradient(filename):
    gradient = Gradient()
    gradient.colors.append(GradientColor(0.0, 0.0, 0.0, 0.0))
    gradient.colors.append(GradientColor(1.0, 1.0, 1.0, 1.0))

    with open(filename, "r") as f:
        for line in f:
            match = REGEXP_GRADIENT_LINE.match(line)
            if match:
                data = match.groups()
                col = gradient_get_color_at_position(gradient, float(data[0]))
                if col:
                    col.update_colors(data[1], data[2], data[3])
                else:
                    gradient.colors.append(GradientColor(data[0], data[1], data[2], data[3]))
    gradient.colors.sort()
    return gradient

def color_from_gradient_range(left_color, right_color, pos):
    pos2 = (pos - left_color.pos) / (right_color.pos - left_color.pos)
    r = (right_color.r - left_color.r) * pos2 + left_color.r
    g = (right_color.g - left_color.g) * pos2 + left_color.g
    b = (right_color.b - left_color.b) * pos2 + left_color.b
    return r, g, b

def color_from_gradient(gradient, pos):
    for colors in zip(gradient.colors[:-1], gradient.colors[1:]):
        if pos >= colors[0].pos and pos <= colors[1].pos:
            return color_from_gradient_range(colors[0], colors[1], pos)
    return None

def mandelbrot_calc(image_width, image_height, max_iterations, center_x, center_y, height, iterations_per_pixel, distances_to_next_iteration_per_pixel):
    width = height * (float(image_width) / float(image_height))
    x_left = center_x - width / 2.0
    # x_right = center_x + width / 2.0
    y_top = center_y + height / 2.0
    # y_bottom = center_y - height / 2.0

    bailout = 20.0
    bailout_squared = bailout * bailout
    log_log_bailout = log(log(bailout))
    log_2 = log(2.0)

    # for simplicity we only use indices [1] .. [max_iterations], [0] is unused
    iterations_histogram = [0] * (max_iterations + 1)

    pixel = 0

    for pixel_y in xrange(image_height):
        y0 = y_top - height * (float(pixel_y) / float(image_height))

        for pixel_x in xrange(image_width):
            x0 = x_left + width * (float(pixel_x) / float(image_width))

            x = 0.0
            y = 0.0

            x_squared = 0.0
            y_squared = 0.0

            # iteration, will be from 1 .. max_iterations once the loop is done
            iter = 0

            for iter in xrange(max_iterations + 1):
                x_squared = x * x
                y_squared = y * y

                if x_squared + y_squared >= bailout_squared:
                    break

                y = 2.0 * x * y + y0
                x = x_squared - y_squared + x0

            if iter < max_iterations:
                final_magnitude = sqrt(x_squared + y_squared)
                distances_to_next_iteration_per_pixel[pixel] = 1.0 - min(1.0, (log(log(final_magnitude)) - log_log_bailout) / log_2)
                iterations_histogram[iter] += 1  # no need to count histogram[max_iterations]

            iterations_per_pixel[pixel] = iter
            pixel += 1
    return iterations_histogram

def equalize_histogram(iterations_histogram, max_iterations):
    # Calculate the CDF (Cumulative Distribution Function) by accumulating all iteration counts.
    # Element [0] is unused and iterations_histogram[max_iterations] should be zero (as we do not count
    # the iterations of the points inside the Mandelbrot Set).
    cdf = cumsum(iterations_histogram)

    # Get the minimum value in the CDF that is bigger than zero and the sum of all iteration counts
    # from iterations_histogram (which is the last value of the CDF).
    cdf_min = next(iter(filter(lambda x: x > 0, cdf)))
    total_iterations = cdf[-1]

    # normalize all values from the CDF that are bigger than zero to a range of 0.0 .. max_iterations
    f = max_iterations / float(total_iterations - cdf_min)
    return list(map(lambda c: (c - cdf_min) * f if c > 0 else 0, cdf))

def mandelbrot_colorize(image_width, image_height, max_iterations, gradient, image_data, iterations_histogram, iterations_per_pixel, distances_to_next_iteration_per_pixel):
    equalized_iterations = equalize_histogram(iterations_histogram, max_iterations)

    for pixel in xrange(image_width * image_height):
        iter = iterations_per_pixel[pixel]  # 1 .. max_iterations

        if iter == max_iterations:
            # points inside the Mandelbrot Set are always painted black
            image_data[3 * pixel + 0] = 0
            image_data[3 * pixel + 1] = 0
            image_data[3 * pixel + 2] = 0
        else:
            # The equalized iteration value (in the range of 0 .. max_iterations) represents the
            # position of the pixel color in the color gradiant and needs to be mapped to 0.0 .. 1.0.
            # To achieve smooth coloring we need to edge the equalized iteration towards the next
            # iteration, determined by the distance between the two iterations.
            iter_curr = equalized_iterations[iter]
            iter_next = equalized_iterations[iter + 1]

            smoothed_iteration = lerp(iter_curr, iter_next, distances_to_next_iteration_per_pixel[pixel])
            pos_in_gradient = smoothed_iteration / max_iterations

            r, g, b = color_from_gradient(gradient, pos_in_gradient)

            image_data[3 * pixel + 0] = int(255.0 * r)
            image_data[3 * pixel + 1] = int(255.0 * g)
            image_data[3 * pixel + 2] = int(255.0 * b)

def save_image(filename, image_data):
    with open(filename, "wb") as f:
        f.write(image_data)

def mean(values):
    return math.fsum(values) / len(values)

def median(values):
    values = sorted(values)
    count = len(values)
    if count % 2 == 1:
        return values[int((count-1) / 2)]
    else:
        return (values[int(count/2 - 1)] + values[int(count/2)]) / 2.0

def show_summary(durations):
    if len(durations) == 1:
        print("%f s" % durations[0])
    else:
        print("mean: %f s, median: %f s (repetitions=%d) %s" % (mean(durations), median(durations), len(durations), str(sorted(durations))))

def eval_int_arg(s, min, max):
    value = int(s)
    if value < min or value > max:
        raise ValueError("invalid value %s" % s)
    return value

def eval_float_arg(s, min, max):
    value = float(s)
    if value < min or value > max or math.isnan(value) or math.isinf(value):
        raise ValueError("invalid value %s" % s)
    return value

def eval_args():
    if len(sys.argv) < 10:
        raise RuntimeError("invalid number of arguments")

    image_width    = eval_int_arg(sys.argv[1], 1, 100000)
    image_height   = eval_int_arg(sys.argv[2], 1, 100000)
    max_iterations = eval_int_arg(sys.argv[3], 1, 1000000000)
    repetitions    = eval_int_arg(sys.argv[4], 1, 1000000)
    center_x       = eval_float_arg(sys.argv[5], -100.0, 100.0)
    center_y       = eval_float_arg(sys.argv[6], -100.0, 100.0)
    height         = eval_float_arg(sys.argv[7], -100.0, 100.0)
    colors         = sys.argv[8]
    filename       = sys.argv[9]

    return image_width, image_height, max_iterations, repetitions, center_x, center_y, height, colors, filename

def go(image_width, image_height, max_iterations, center_x, center_y, height, gradient, image_data, durations, repetitions):
    iterations_per_pixel = [0] * (image_width * image_height)
    distances_to_next_iteration_per_pixel = [0.0] * (image_width * image_height)

    for _ in xrange(repetitions):
        t1 = time()
        iterations_histogram = mandelbrot_calc(image_width, image_height, max_iterations, center_x, center_y, height, iterations_per_pixel, distances_to_next_iteration_per_pixel)
        mandelbrot_colorize(image_width, image_height, max_iterations, gradient, image_data, iterations_histogram, iterations_per_pixel, distances_to_next_iteration_per_pixel)
        t2 = time()
        durations.append(t2 - t1)

def main():
    image_width, image_height, max_iterations, repetitions, center_x, center_y, height, gradient_filename, filename = eval_args()
    gradient = load_gradient(gradient_filename)
    image_data = bytearray([0] * (image_width * image_height * 3))
    durations = []

    go(image_width, image_height, max_iterations, center_x, center_y, height, gradient, image_data, durations, repetitions)

    save_image(filename, image_data)
    show_summary(durations)

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


<commit_before>import re

from trac.core import *
from trac.config import BoolOption, Option
from trac.resource import ResourceNotFound
from trac.ticket import model
from trac.util.text import to_unicode
from trac.util.translation import _
from trac.web.chrome import add_warning

from announcerplugin.api import IAnnouncementSubscriber, istrue
from announcerplugin.api import IAnnouncementPreferenceProvider

class StaticTicketSubscriber(Component):
    """The static ticket subscriber implements a policy to -always- send an
    email to a certain address. Controlled via the smtp_always_bcc option in
    the announcer section of the trac.ini"""

    implements(IAnnouncementSubscriber)

    smtp_always_cc = Option("announcer", "smtp_always_cc",
        doc="""Email addresses specified here will always
               be cc'd on all notifications.""")

    smtp_always_bcc = Option("announcer", "smtp_always_bcc",
        doc="""Email addresses specified here will always
               be cc'd on all notifications.  With announce,
               bcc is unneccesary since users can't see
               each others email addresses.""")

    def get_subscription_realms(self):
        return (self.smtp_always_bcc or self.smtp_always_cc) and \
                ('*',) or tuple()

    def get_subscription_categories(self, realm):
        return (self.smtp_always_bcc or self.smtp_always_cc) and \
                ('*',) or tuple()

    def get_subscriptions_for_event(self, event):
        if self.smtp_always_cc:
            for s in self.smtp_always_cc.split(','):
                self.log.debug(_("StaticTicketSubscriber added '%s' " \
                        "because of rule: smtp_always_cc"%s))
                yield ('email', None, False, s.strip())
        if self.smtp_always_bcc:
            for s in self.smtp_always_bcc.split(','):
                self.log.debug(_("StaticTicketSubscriber added '%s' " \
                        "because of rule: smtp_always_bcc"%s))
                yield ('email', None, False, s.strip())

class LegacyTicketSubscriber(Component):
    implements(IAnnouncementSubscriber, IAnnouncementPreferenceProvider)

    always_notify_owner = BoolOption("announcer", "always_notify_owner", False,
        """The always_notify_owner option mimics the option of the same name
        in the notification section, except users can opt-out in their
        preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_reporter = BoolOption("announcer", "always_notify_reporter",
        False, """The always_notify_reporter option mimics the option of the
        same name in the notification section, except users can opt-out in
        their preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_updater = BoolOption("announcer", "always_notify_updater",
        False, """The always_notify_updater option mimics the option of the
        same name in the notification section, except users can opt-out in
        their preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_component_owner = BoolOption("announcer",
            "always_notify_component_owner", True,
            """Whether or not to notify the owner of the ticket's
            component.""")

    def get_announcement_preference_boxes(self, req):
        yield "legacy", "Ticket Notifications"

    def render_announcement_preference_box(self, req, panel):
        if req.method == "POST":
            for attr in ('component_owner', 'owner', 'reporter', 'updater'):
                if self.__getattribute__('always_notify_%s'%attr):
                    val = req.args.get('legacy_notify_%s'%attr, '0')
                    req.session['announcer_legacy_notify_%s'%attr] = val
        data = dict(
            always_notify_component_owner = self.always_notify_component_owner,
            always_notify_owner = self.always_notify_owner,
            always_notify_reporter = self.always_notify_reporter,
            always_notify_updater = self.always_notify_updater,
            legacy_notify_component_owner = req.session.get(
                'announcer_legacy_notify_component_owner', '0') == '1' or None,
            legacy_notify_owner = req.session.get(
                'announcer_legacy_notify_owner', '0') == '1' or None,
            legacy_notify_reporter = req.session.get(
                'announcer_legacy_notify_reporter', '0') == '1' or None,
            legacy_notify_updater = req.session.get(
                'announcer_legacy_notify_updater', '0') == '1' or None,
        )
        return "prefs_announcer_legacy.html", data

    def get_subscription_realms(self):
        return ('ticket',)

    def get_subscription_categories(self, realm):
        if realm == 'ticket':
            return ('created', 'changed', 'attachment added')
        else:
            return tuple()

    def get_subscriptions_for_event(self, event):
        if event.realm == "ticket":
            if event.category in ('created', 'changed', 'attachment added'):
                ticket = event.target
                subs = filter(lambda a: a, (
                    self._always_notify_component_owner(ticket),
                    self._always_notify_ticket_owner(ticket),
                    self._always_notify_ticket_reporter(ticket),
                    self._always_notify_ticket_updater(event, ticket)
                ))
                for s in subs:
                    yield s

    def _always_notify_component_owner(self, ticket):
        try:
            component = model.Component(self.env, ticket['component'])
        except ResourceNotFound, message:
            self.log.warn(_("LegacyTicketSubscriber couldn't add " \
                    "component owner because component was not found, " \
                    "message: '%s'"%(message,)))
            return
        if self.always_notify_component_owner and component.owner and not \
                self._check_opt_out('notify_component_owner', component.owner):
            self._log_sub(component.owner, True,
                    'always_notify_component_owner')
            return ('email', component.owner, True, None)

    def _always_notify_ticket_owner(self, ticket):
        if self.always_notify_owner and ticket['owner'] and not \
            self._check_opt_out('notify_owner', ticket['owner']):
            owner = ticket['owner']
            if '@' in owner:
                name, authenticated, address = None, False, owner
            else:
                name, authenticated, address = owner, True, None
            self._log_sub(owner, authenticated, 'always_notify_owner')
            return ('email', name, authenticated, address)

    def _always_notify_ticket_reporter(self, ticket):
        if self.always_notify_reporter and ticket['reporter'] and not \
            self._check_opt_out('notify_reporter', ticket['reporter']):
            reporter = ticket['reporter']
            if '@' in reporter:
                name, authenticated, address = None, False, reporter
            else:
                name, authenticated, address = reporter, True, None
            self._log_sub(reporter, authenticated, 'always_notify_reporter')
            return ('email', name, authenticated, address)

    def _always_notify_ticket_updater(self, event, ticket):
        if self.always_notify_updater and event.author and not \
            self._check_opt_out('notify_updater', event.author):
            self._log_sub(event.author, True, 'always_notify_updater')
            return ('email', event.author, True, None)

    def _log_sub(self, author, authenticated, rule):
        "Log subscriptions"
        auth = authenticated and 'authenticated' or 'not authenticated'
        self.log.debug(_("LegacyTicketSubscriber added '%s " \
            "(%s)' because of rule: %s"%(author, auth, rule)))

    def _check_opt_out(self, preference, sid):
        "Check if user has opted out of notification"
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("""
            SELECT value
              FROM session_attribute
             WHERE sid=%s
               AND authenticated=1
               AND name=%s
        """, (sid, 'announcer_legacy_' + preference))
        result = cursor.fetchone()
        if result:
            optout = (result[0] == '0')
            if optout:
                self.log.debug(_("LegacyTicketSubscriber excluded '%s' " \
                        "because of opt-out rule: %s"%(sid,preference)))
                return True
        return False

class CarbonCopySubscriber(Component):
    implements(IAnnouncementSubscriber)

    def get_subscription_realms(self):
        return ('ticket',)

    def get_subscription_categories(self, realm):
        if realm == 'ticket':
            return ('created', 'changed', 'attachment added')
        else:
            return tuple()

    def get_subscriptions_for_event(self, event):
        if event.realm == 'ticket':
            if event.category in ('created', 'changed', 'attachment added'):
                cc = event.target['cc']
                for chunk in re.split('\s|,', cc):
                    chunk = chunk.strip()
                    if not chunk or chunk.startswith('@'):
                        continue
                    if '@' in chunk:
                        address = chunk
                        name = None
                    else:
                        name = chunk
                        address = None
                    if name or address:
                        self.log.debug(_("CarbonCopySubscriber added '%s " \
                            "<%s>' because of rule: carbon copied" \
                            %(name,address)))
                        yield ('email', name, name and True or False, address)

<commit_msg>fix for missing cc field<commit_after>import re

from trac.core import *
from trac.config import BoolOption, Option
from trac.resource import ResourceNotFound
from trac.ticket import model
from trac.util.text import to_unicode
from trac.util.translation import _
from trac.web.chrome import add_warning

from announcerplugin.api import IAnnouncementSubscriber, istrue
from announcerplugin.api import IAnnouncementPreferenceProvider

class StaticTicketSubscriber(Component):
    """The static ticket subscriber implements a policy to -always- send an
    email to a certain address. Controlled via the smtp_always_bcc option in
    the announcer section of the trac.ini"""

    implements(IAnnouncementSubscriber)

    smtp_always_cc = Option("announcer", "smtp_always_cc",
        doc="""Email addresses specified here will always
               be cc'd on all notifications.""")

    smtp_always_bcc = Option("announcer", "smtp_always_bcc",
        doc="""Email addresses specified here will always
               be cc'd on all notifications.  With announce,
               bcc is unneccesary since users can't see
               each others email addresses.""")

    def get_subscription_realms(self):
        return (self.smtp_always_bcc or self.smtp_always_cc) and \
                ('*',) or tuple()

    def get_subscription_categories(self, realm):
        return (self.smtp_always_bcc or self.smtp_always_cc) and \
                ('*',) or tuple()

    def get_subscriptions_for_event(self, event):
        if self.smtp_always_cc:
            for s in self.smtp_always_cc.split(','):
                self.log.debug(_("StaticTicketSubscriber added '%s' " \
                        "because of rule: smtp_always_cc"%s))
                yield ('email', None, False, s.strip())
        if self.smtp_always_bcc:
            for s in self.smtp_always_bcc.split(','):
                self.log.debug(_("StaticTicketSubscriber added '%s' " \
                        "because of rule: smtp_always_bcc"%s))
                yield ('email', None, False, s.strip())

class LegacyTicketSubscriber(Component):
    implements(IAnnouncementSubscriber, IAnnouncementPreferenceProvider)

    always_notify_owner = BoolOption("announcer", "always_notify_owner", False,
        """The always_notify_owner option mimics the option of the same name
        in the notification section, except users can opt-out in their
        preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_reporter = BoolOption("announcer", "always_notify_reporter",
        False, """The always_notify_reporter option mimics the option of the
        same name in the notification section, except users can opt-out in
        their preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_updater = BoolOption("announcer", "always_notify_updater",
        False, """The always_notify_updater option mimics the option of the
        same name in the notification section, except users can opt-out in
        their preferences. Used only if LegacyTicketSubscriber is enabled.""")

    always_notify_component_owner = BoolOption("announcer",
            "always_notify_component_owner", True,
            """Whether or not to notify the owner of the ticket's
            component.""")

    def get_announcement_preference_boxes(self, req):
        yield "legacy", "Ticket Notifications"

    def render_announcement_preference_box(self, req, panel):
        if req.method == "POST":
            for attr in ('component_owner', 'owner', 'reporter', 'updater'):
                if self.__getattribute__('always_notify_%s'%attr):
                    val = req.args.get('legacy_notify_%s'%attr, '0')
                    req.session['announcer_legacy_notify_%s'%attr] = val
        data = dict(
            always_notify_component_owner = self.always_notify_component_owner,
            always_notify_owner = self.always_notify_owner,
            always_notify_reporter = self.always_notify_reporter,
            always_notify_updater = self.always_notify_updater,
            legacy_notify_component_owner = req.session.get(
                'announcer_legacy_notify_component_owner', '0') == '1' or None,
            legacy_notify_owner = req.session.get(
                'announcer_legacy_notify_owner', '0') == '1' or None,
            legacy_notify_reporter = req.session.get(
                'announcer_legacy_notify_reporter', '0') == '1' or None,
            legacy_notify_updater = req.session.get(
                'announcer_legacy_notify_updater', '0') == '1' or None,
        )
        return "prefs_announcer_legacy.html", data

    def get_subscription_realms(self):
        return ('ticket',)

    def get_subscription_categories(self, realm):
        if realm == 'ticket':
            return ('created', 'changed', 'attachment added')
        else:
            return tuple()

    def get_subscriptions_for_event(self, event):
        if event.realm == "ticket":
            if event.category in ('created', 'changed', 'attachment added'):
                ticket = event.target
                subs = filter(lambda a: a, (
                    self._always_notify_component_owner(ticket),
                    self._always_notify_ticket_owner(ticket),
                    self._always_notify_ticket_reporter(ticket),
                    self._always_notify_ticket_updater(event, ticket)
                ))
                for s in subs:
                    yield s

    def _always_notify_component_owner(self, ticket):
        try:
            component = model.Component(self.env, ticket['component'])
        except ResourceNotFound, message:
            self.log.warn(_("LegacyTicketSubscriber couldn't add " \
                    "component owner because component was not found, " \
                    "message: '%s'"%(message,)))
            return
        if self.always_notify_component_owner and component.owner and not \
                self._check_opt_out('notify_component_owner', component.owner):
            self._log_sub(component.owner, True,
                    'always_notify_component_owner')
            return ('email', component.owner, True, None)

    def _always_notify_ticket_owner(self, ticket):
        if self.always_notify_owner and ticket['owner'] and not \
            self._check_opt_out('notify_owner', ticket['owner']):
            owner = ticket['owner']
            if '@' in owner:
                name, authenticated, address = None, False, owner
            else:
                name, authenticated, address = owner, True, None
            self._log_sub(owner, authenticated, 'always_notify_owner')
            return ('email', name, authenticated, address)

    def _always_notify_ticket_reporter(self, ticket):
        if self.always_notify_reporter and ticket['reporter'] and not \
            self._check_opt_out('notify_reporter', ticket['reporter']):
            reporter = ticket['reporter']
            if '@' in reporter:
                name, authenticated, address = None, False, reporter
            else:
                name, authenticated, address = reporter, True, None
            self._log_sub(reporter, authenticated, 'always_notify_reporter')
            return ('email', name, authenticated, address)

    def _always_notify_ticket_updater(self, event, ticket):
        if self.always_notify_updater and event.author and not \
            self._check_opt_out('notify_updater', event.author):
            self._log_sub(event.author, True, 'always_notify_updater')
            return ('email', event.author, True, None)

    def _log_sub(self, author, authenticated, rule):
        "Log subscriptions"
        auth = authenticated and 'authenticated' or 'not authenticated'
        self.log.debug(_("LegacyTicketSubscriber added '%s " \
            "(%s)' because of rule: %s"%(author, auth, rule)))

    def _check_opt_out(self, preference, sid):
        "Check if user has opted out of notification"
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute("""
            SELECT value
              FROM session_attribute
             WHERE sid=%s
               AND authenticated=1
               AND name=%s
        """, (sid, 'announcer_legacy_' + preference))
        result = cursor.fetchone()
        if result:
            optout = (result[0] == '0')
            if optout:
                self.log.debug(_("LegacyTicketSubscriber excluded '%s' " \
                        "because of opt-out rule: %s"%(sid,preference)))
                return True
        return False

class CarbonCopySubscriber(Component):
    implements(IAnnouncementSubscriber)

    def get_subscription_realms(self):
        return ('ticket',)

    def get_subscription_categories(self, realm):
        if realm == 'ticket':
            return ('created', 'changed', 'attachment added')
        else:
            return tuple()

    def get_subscriptions_for_event(self, event):
        if event.realm == 'ticket':
            if event.category in ('created', 'changed', 'attachment added'):
                cc = event.target['cc'] or ''
                for chunk in re.split('\s|,', cc):
                    chunk = chunk.strip()
                    if not chunk or chunk.startswith('@'):
                        continue
                    if '@' in chunk:
                        address = chunk
                        name = None
                    else:
                        name = chunk
                        address = None
                    if name or address:
                        self.log.debug(_("CarbonCopySubscriber added '%s " \
                            "<%s>' because of rule: carbon copied" \
                            %(name,address)))
                        yield ('email', name, name and True or False, address)

<|endoftext|>


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

from reporter.reports import Report, Schedule
from reporter import get_contact_link, RECIPIENT_IT_DQ

class CivicrmContactsWithoutSubtypes(Report):
    def __init__(self):
        super().__init__(
            introduction=("The following contacts do not have "
                          "a subtype"),
            recipients=[RECIPIENT_IT_DQ],
            sql='''
SELECT
    id AS contact_id,
    contact_type
FROM STG_CiviCRM.dbo.civicrm_contact
WHERE LTRIM(RTRIM(ISNULL(contact_sub_type, ''))) = ''
    AND is_deleted = 0
;
                ''',
                schedule=Schedule.daily
        )

    def get_report_line(self, row):
        return '- {}\r\n'.format(
            get_contact_link(row['contact_type'], row['contact_id'])
        )
<commit_msg>Ignore LCBRU in organisations without a subtype<commit_after>#!/usr/bin/env python3

from reporter.reports import Report, Schedule
from reporter import get_contact_link, RECIPIENT_IT_DQ

class CivicrmContactsWithoutSubtypes(Report):
    def __init__(self):
        super().__init__(
            introduction=("The following contacts do not have "
                          "a subtype"),
            recipients=[RECIPIENT_IT_DQ],
            sql='''
SELECT
    id AS contact_id,
    contact_type
FROM STG_CiviCRM.dbo.civicrm_contact
WHERE LTRIM(RTRIM(ISNULL(contact_sub_type, ''))) = ''
    AND is_deleted = 0
    AND id NOT IN (
        7981 -- LCBRU
    );
                ''',
                schedule=Schedule.daily
        )

    def get_report_line(self, row):
        return '- {}\r\n'.format(
            get_contact_link(row['contact_type'], row['contact_id'])
        )

r = CivicrmContactsWithoutSubtypes()
r.run()
<|endoftext|>


<commit_before>import numpy as np
import pyexotica as exo
import unittest
from numpy import testing as nptest
from scipy.optimize import minimize

class TestBoxQP(unittest.TestCase):
    """Tests BoxQP implementation against scipy."""

    def test_zero_q(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(100):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H)
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0.0, 0.0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_zero_h(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(10):
            H = np.array([[0.,0.], [0.,0.]])

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.random.normal(size=(2,1), loc=0, scale=10)

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_big_numbers(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(100):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H) * 1e20
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0, 0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_small_numbers(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(10):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H) * 1e-20
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0, 0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

if __name__ == '__main__':
    unittest.main()
<commit_msg>Fix boxqp test<commit_after>import numpy as np
import pyexotica as exo
import unittest
from numpy import testing as nptest
from scipy.optimize import minimize

class TestBoxQP(unittest.TestCase):
    """Tests BoxQP implementation against scipy."""

    def test_zero_q(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(100):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H)
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0.0, 0.0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_zero_h(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(10):
            H = np.array([[0.,0.], [0.,0.]])

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.random.normal(size=(2,1), loc=0, scale=10)

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_big_numbers(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(100):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H) * 1e20
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0, 0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

    def test_small_numbers(self):
        np.random.seed(100)

        # check against 100 state,control pairs
        for i in range(10):
            H = np.random.normal(
                size=(2, 2), loc=0, scale=10
            )
            H = np.abs(H) * 1e-20
            H[0, 1] = H[1,0] = 0

            b_low = np.array([-5., -5.])
            b_high = np.array([5., 5.])
            x_init = np.array([-3., 2.])
            q = np.array([0, 0])

            sol = exo.box_qp(H, q, b_low, b_high, x_init, 0.1, 100, 1e-5, 1e-5)

            def cost(x):
                return .5 * np.matmul(np.matmul(x.T, H), x) + np.matmul(q.T, x)

            sp_sol = minimize(cost, x_init, method='TNC', bounds=[
                (b_low[0], b_high[0]),
                (b_low[1], b_high[1]),
            ])

            nptest.assert_allclose(sp_sol.x, sol.x.T[0], rtol=1, atol=1e-4, err_msg="BoxQP and scipy differ!")

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


<commit_before>import datetime
import sys
import pytz

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

from registrations.models import Registration
from registrations import handlers

class Command(BaseCommand):

    def handle(self, *args, **options):

        if len(args) < 2:
            sys.exit("Please provide an email address and zip code.")
        else:
            email = args[0]
            zip_code = args[1]

        registration = Registration.signup(email, zip_code)

        if not registration:
            sys.exit("Error: that account is already registered.")

        handlers.geocode_registration(registration)

        registration.confirmation_email_sent = True
        registration.email_is_confirmed = True
        registration.confirmed_at = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
        registration.updated_at = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
        registration.save()

        print "Done."
<commit_msg>Fixed the geocode task in the create_account management command.<commit_after>import datetime
import sys
import pytz

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

from registrations.models import Registration
from registrations import handlers

class Command(BaseCommand):

    def handle(self, *args, **options):

        if len(args) < 2:
            sys.exit("Please provide an email address and zip code.")
        else:
            email = args[0]
            zip_code = args[1]

        registration = Registration.signup(email, zip_code)

        if not registration:
            sys.exit("Error: that account is already registered.")

        #handlers.geocode_registration(registration)
        registration.fire_geocode_registration_task()

        registration.confirmation_email_sent = True
        registration.email_is_confirmed = True
        registration.confirmed_at = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
        registration.updated_at = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
        registration.save()

        print "Done."
<|endoftext|>